tidy up

git-svn-id: https://svn.apache.org/repos/asf/cocoon/tags/cocoon-22@505988 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/non-releases/trunk_before_flattening/CREDITS.txt b/non-releases/trunk_before_flattening/CREDITS.txt
new file mode 100644
index 0000000..d5d7e02
--- /dev/null
+++ b/non-releases/trunk_before_flattening/CREDITS.txt
@@ -0,0 +1,102 @@
+
+                                C R E D I T S
+                                 
+This is the file where major donations to the Cocoon project are listed and it
+should be used to give appropriate visibility to those inviduals, organizations
+or companies that donated resources to the effort. This file wants to be one of
+the ways the Cocoon community pays back.
+
+
+ Community Credits
+ -----------------
+                                   
+The Cocoon project was originally created, proposed and bootstrapped by
+Stefano Mazzocchi (http://www.betaversion.org/~stefano/)
+
+The web application framework consisting of the session handling (aka sunShine),
+the authentication framework (aka sunRise) and the portal engine (aka sunSpot)
+was created and developed by the Open Source Competence Center of 
+s&n AG (http://www.s-und-n.de), Paderborn, Germany.
+
+The interpreted sitemap engine and other contributions from Sylvain Wallez are
+made possible by the time donated by his company, Anyware Technologies 
+(http://www.anyware-tech.com).
+
+The flow control layer, the SOAP and XScript logicsheets, and other
+changes were contributed by Ovidiu Predescu and donated by the Hewlett
+Packard Company (http://www.hp.com/).
+
+The DELI implementation was contributed by Mark Butler, and donated to
+Cocoon by the Hewlett Packard Company (http://www.hp.com/).
+
+The initial code of the new portal framework is a donation by a joined development
+effort of BASF IT-Services (http://www.basf-it-services.com) 
+and s&n AG (http://www.s-und-n.de). This initial version has been developed by
+Volker Schmitt (volker.schmitt@basf-it-services.com), 
+Juergen Seitz (juergen.seitz@basf-it-services.com),
+Bjoern Luetkemeier (bluetkemeier@s-und-n.de) and Carsten Ziegeler (cziegeler@s-und-n.de).
+
+The initial code of the new ojb block and other contributions from Antonio Gallardo
+and Carlos Chávez are made posible by the time donated by AG Software, S. A.
+(http://www.agssa.net).
+
+The initial code of the official Cocoon form handling block (CForms) 
+evolved from the Woody donation made by Outerthought
+(http://outerthought.org).
+
+
+ Credits of included software
+ ----------------------------
+
+This product includes software developed by the Apache Software Foundation 
+(http://www.apache.org/).
+
+This product includes software developed by the XML:DB Initiative 
+(http://www.xmldb.org/).
+
+This product includes software developed by the IronSmith Project 
+(http://www.ironsmith.org/).
+
+This product includes software developed by the jfor Project 
+(http://www.jfor.org).
+
+This product includes software developed by the JDOM Project 
+(http://www.jdom.org/).
+
+This product includes software developed by the OpenORB Community Project 
+(http://sourceforge.net/projects/openorb/).
+
+This product includes software developed by the Chaperon Project
+(http://www.sourceforge.net/projects/chaperon/).
+
+This product includes software developed by the Exolab Project
+(http://www.exolab.org/).
+
+This product includes software developed by ANTLR Project
+(http://www.antlr.org/)
+
+
+Portions are Copyright (c) 2001 Tivano Software GmbH
+(http://www.tivano.de). All Rights Reserved.
+
+Portions are Copyright (c) 1998-2000 World Wide Web Consortium 
+(Massachusetts Institute of Technology, Institut National de Recherche en
+Informatique et en Automatique, Keio University). All Rights Reserved.
+
+Portions are Copyright (c) 2001 Scott Robert Ladd. All rights reserved.
+
+Portions are Copyright (c) 2001, 2002 Thai Open Source Software Center Ltd.
+All rights reserved.
+
+Portions are Copyright (c) Mort Bay Consulting Pty. Ltd. All rights reserved.
+
+Portions are Copyright (c) Hewlett-Packard Company 2002. All rights reserved.
+
+Schematron portions are Copyright (c) 2000,2001 Rick Jelliffe and Academia
+Sinica Computing Center, Taiwan
+
+
+
+
+                                                 The Apache Cocoon Community
+                                                  http://cocoon.apache.org/
diff --git a/non-releases/trunk_before_flattening/DESKTOP.INI b/non-releases/trunk_before_flattening/DESKTOP.INI
new file mode 100644
index 0000000..7b5a1d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/DESKTOP.INI
@@ -0,0 +1,6 @@
+; see http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp
+[.ShellClassInfo]
+IconFile=src\documentation\src\content\xdocs\images\cocoon.ico
+IconIndex=0
+ConfirmFileOp=0
+InfoTip=Apache Cocoon, the XML application framework!
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/INSTALL.txt b/non-releases/trunk_before_flattening/INSTALL.txt
new file mode 100644
index 0000000..b80dbb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/INSTALL.txt
@@ -0,0 +1,145 @@
+
+
+                      +-----------------------------+
+                      |     I  N  S  T  A  L  L     |
+                      +-----------------------------+
+
+
+  Let me guess: you don't like to read verbose docs, right?
+  
+  Great, this file is for you.
+  
+ 1) Unpack the distribution
+  Obviously you've done this already, but if you got errors when unpacking
+  the archive with tar, you might need to use gnutar instead. Our archives
+  contain long paths and filenames which cause problems with some versions
+  of the tar command.
+ 
+ 2) Set your JAVA_HOME environment
+  
+  You have to set your JAVA_HOME environment to point to the root directory of
+  the Java Virtual Machine (JDK 1.3.x or later) installed on your machine. 
+
+  To do this simply type:
+  
+    [unix] JAVA_HOME=/path/to/java/
+    [win32] SET JAVA_HOME=c:\path\to\java
+
+  your mileage may vary depending on your shell, but you know how to setup 
+  environments, right?
+  
+ 3) Build Cocoon by typing "build" or "./build.sh"
+
+ 4) Run Cocoon by typing "cocoon servlet" or "./cocoon.sh servlet"
+ 
+ 5) Open http://localhost:8888/ with your browser
+
+
+That's it!  
+
+
+Now, you have two choices:
+
+  a) close this file and try to hack something out by yourself
+  
+  b) keep reading
+
+Go ahead and choose option a), but don't complain if you can't figure out how
+to use the cocoon build system for your needs.
+
+
+
+Still here? good. You won't regret it.
+
+
+Reading the documentation
+--------------------------
+
+This directory contains the full Cocoon documentation (as xml documents).
+You can either browse the documentation when you start Cocoon as described
+above and go to the documentation section: http://localhost:8888/docs/index.html.
+Or you can build the docs your self by running "build.bat docs" or
+"./build.sh docs". If you want to build the docs yourself, you need
+an installed version of Forrest (http://xml.apache.org/forrest).
+
+Of course you can also read the documentation at the website
+http://cocoon.apache.org/
+
+Updating
+--------
+
+If you are updating from a previous release of Cocoon, make sure
+that you read the installation instructions on updating first.
+
+
+Choosing the blocks
+-------------------
+
+Cocoon is composed by its 'core' and several 'blocks'.
+
+The core (a.k.a. naked cocoon') contains the system with services that
+are needed to all cocoon users. Blocks provide services that you might not need,
+therefore the build system allows you to remove them from the build.
+
+Now, do the following steps to configure the blocks you want in your cocoon:
+
+ 1) cp blocks.properties local.blocks.properties
+ 2) edit local.blocks.properties
+ 3) rebuild (do a "build clean" first if you deactivated some blocks)
+ 
+do not modify blocks.properties directly!
+
+
+Tuning the build
+----------------
+
+Ok, now that you told the build system what services you want assembled
+into your distribution, you can tune the build for your personal needs:
+
+ 1) cp build.properties local.build.properties
+ 2) edit local.build.properties
+
+do not modify build.properties directly!
+ 
+An example of a local.build.properties is the following:
+ 
+  compiler=jikes
+  compiler.debug=off
+  build.webapp=/path/to/where/to/build/the/webapp
+
+where you override default compilation parameters and tell the build system
+where to place the generated cocoon webapp. Look into build.properties to find
+out what you might want to modify for your own personal needs.
+
+
+Running Cocoon as a servlet
+---------------------------
+
+When you do 'cocoon servlet', the servlet container (jetty) is started and Cocoon
+loaded into it. By default, this is attached to port 8888, but you can change
+this by setting the "JETTY_PORT" environment property before launching cocoon.
+
+Other properties that you can change are:
+
+ JETTY_ADMIN_PORT (defaults to 8889): is the port where the jetty web 
+     administration is connected to. This is available when you launch 
+     "cocoon servlet-admin", otherwise its disabled.
+     
+ JETTY_WEBAPP (defaults to build/webapp): is the location of the webapp
+     that jetty has to execute. modify this to match your local.build.properties
+     if you modified where the build system creates your webapp
+     
+ JAVA_DEBUG_PORT (defaults to 8000): is the port where the JVM over-the-wire
+     debug interface connects to. This is available only if you launch 
+     "cocoon servlet-debug", otherwise is disabled. This is used by remote
+     debuggers (for example, Eclipse's).
+
+
+Note that the "standalone-demo" build target prepares a directory that you can
+move elsewhere to run "cocoon servlet" outside of the build tree.
+
+
+
+All right, that's it for now. 
+
+Happy hacking with Cocoon.  
diff --git a/non-releases/trunk_before_flattening/KEYS b/non-releases/trunk_before_flattening/KEYS
new file mode 100644
index 0000000..5f98416
--- /dev/null
+++ b/non-releases/trunk_before_flattening/KEYS
@@ -0,0 +1,655 @@
+(instructions copied from forrest's KEYS file)
+
+This file contains the PGP keys of various developers.
+Please don't use them for email unless you have to. Their main
+purpose is code signing.
+
+Users: pgp < KEYS
+Developers:
+        pgp -kxa <your name> and append it to this file.
+        (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+        (gpg --list-sigs <your name>
+             && gpg --armor --export <your name>) >> this file.
+
+-----------------------------------------------------------------------------------
+pub   1024D/E41EDC7E 2003-09-26
+uid                  Carsten Ziegeler <cziegeler@apache.org>
+sig 3        E41EDC7E 2003-09-26  Carsten Ziegeler <cziegeler@apache.org>
+sig 3        EE56550E 2003-12-01  Cliff Schmidt <cliff@alum.mit.edu>
+sig 3        CC78C893 2003-11-18  Rich Bowen <rbowen@rcbowen.com>
+sig 3        EE65E321 2003-11-24  Martin Kraemer <martin@apache.org>
+sig          40581837 2003-11-27  Nick Kew <nick@webthing.com>
+sig 3        142B509B 2003-11-25  Glenn L. Nielsen <glenn@mail.more.net>
+sig 3        CE19D5C6 2003-11-18  Jamie Wallingford (legobuff) <jamie@legobuff.com>
+sig 3        D147B776 2003-11-28  Mitch Comstock (RAID) <mcomstock@raidworks.com>
+sig 2        65FDCDEE 2003-11-20  James Howison <james@freelancepropaganda.com>
+sig          FD093C41 2003-11-23  James M. Turner <turner@blackbear.com>
+sig 2        A1D69759 2003-11-24  Michael Kellen
+sig 2        76D83CC6 2003-11-22  Manoj Kasichainula <manoj@apache.org>
+sig 3        A54DA2DF 2003-11-18  Erin Mulder <meara@alumni.princeton.edu>
+sig          152924AF 2003-11-22  Sander Temme <sander@temme.net>
+sig          964F31D9 2003-11-22  Sander Temme <sctemme@covalent.net>
+sig          B6B45F1F 2003-11-19  Chengetai Masango <chengetai@masango.net>
+sig 2        4C9165B6 2003-11-18  Aaron Mulder <ammulder@alumni.princeton.edu>
+sig 3        F5FC4B42 2003-11-21  Theodore W. Leung <twl@sauria.com>
+sig 2        F88341D9 2003-11-30  Lars Eilebrecht <lars@eilebrecht.org>
+sig 3        A11D56FB 2003-12-03  Geoffrey Young (http://www.modperlcookbook.org/~geoff/) <geoff@modperlcookbook.org>
+sig 3        ADBF9E1A 2003-12-05  Santiago Gala (Santiago Juan Gala Perez) <sgala@apache.org>
+sig          E76CF6D0 2004-03-22  Stas Bekman <stas@stason.org>
+sig 3        75A67692 2004-01-27  Erik Abele <erik@codefaktor.de>
+sig 2        7C200941 2004-10-18  Torsten Curdt <tcurdt@apache.org>
+sig 3        E2D774DF 2004-10-28  Sylvain Wallez <sylvain@apache.org>
+sig 3        E04F9A89 2004-11-08  Roy T. Fielding <fielding@gbiv.com>
+sig 2        CC69CEED 2004-02-16  Thomas DeWeese <deweese@apache.org>
+sig          8103A37E 2005-07-20  Andre Malo <nd@apache.org>
+sig          5793498F 2005-07-21  Tim Ellison <tim@ellison.name>
+sig          C4C57B42 2005-07-21  Marcus Crafter <crafterm@debian.org>
+sig          E4136392 2005-07-21  Noel J. Bergman <noel@apache.org>
+sig          1CD4861F 2005-07-22  Eran Chinthaka <chinthaka@apache.org>
+sig 2        FC243F3C 2005-07-20  Henk P. Penning <penning@cs.uu.nl>
+sig 3        EC140B81 2005-07-20  Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3        A99F75DD 2005-07-21  Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3        21D0A71B 2005-07-20  Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3        3642CB4B 2005-07-20  Martin Kraemer <martin@apache.org>
+sig 3        2261D073 2005-07-20  Astrid Kessler (Kess) <kess@kess-net.de>
+sig 3        302DA568 2005-07-21  Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3        2C312D2F 2005-07-21  Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3        015AFC8A 2005-07-22  Bertrand Delacretaz <bdelacretaz@apache.org>
+sig 3        87315C31 2005-07-23  Raphael Luta <raphael.luta@aptiwan.com>
+sig          FA32C576 2005-07-24  Carsten Ziegeler <cziegeler@apache.org>
+sig 3        F39B3750 2005-07-24  Colm MacCarthaigh <colm@stdlib.net>
+sig          EA1BA38D 2005-07-24  Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig          333E4E84 2005-07-25  Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig 3        9C85222B 2005-07-24  Henning Schmiedehausen <hps@intermeta.de>
+sig 3        E9415E36 2005-07-25  Johannes Schaefer <josch@apache.org>
+sig 3        9978AF86 2005-07-25  Christoph Probst <chris@netzpunkt.org>
+sig 3        2A623F72 2005-07-25  Christoph Probst <chris@netzpunkt.org>
+sub   1024g/0F6ED732 2003-09-26
+sig          E41EDC7E 2003-09-26  Carsten Ziegeler <cziegeler@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.0 (MingW32)
+
+mQGiBD90V4MRBAC1lbNdQ9fvvooWXlFx9u/C3Vtsgc+ZsukqBRQRuSEBNZKQr3XC
+NmOy6rlLKan0brlr8L+6xmkQgJCgsNGnjqwIHRe8irMLEqK+uGhpoQ9z4zgc6JVl
+CLarZPvqe7GOifOKlheadWrkkRQMOuKjDF8Nuy10S4jaIEVMhPcorakbYwCgqXzA
+GD/327IVU2SEfL2ezVC1nc0D/Rj43bqn/GzB6pBUIaG2LNAfPtVfdmnqjKa/0PDF
+/hxyGN2Pb5BBlBAZe/ysNRNpGi+kVqGxweccugco6atDRv/INPVQ1dSKAoX/zuuE
+rMeTCaXYE45uBXYhvSsGM2iNJYcS/VW10ZW5RD3F5eWVSo50Xin4obmJmlfr8BTp
+VoxNBACjYrCo9f2MI30fxCgKu9ugyz/rFA7Zja/Hq18jyUWUA8oIQ6VonNvnEu80
+9jf1c23HtKQu+f4yHBDKR6RKsas5kCQDZJncQCn8PHRqSkLWRsAnl2e8fY72QnVI
+pSL7HZ4AnOAaO9sMONQMADq3q9muQofNQDS79IRAWXP7kDT5pbQnQ2Fyc3RlbiBa
+aWVnZWxlciA8Y3ppZWdlbGVyQGFwYWNoZS5vcmc+iF4EExECAB4FAj90V4MCGwMG
+CwkIBwMCAxUCAwMWAgECHgECF4AACgkQEy5J1OQe3H4aLwCdEP8ARIZxOvFITQ7I
+nee1qC85BbsAnjnKXQaUm1unAnNHwN7fNyZnnIuEiEYEExECAAYFAj/K5J0ACgkQ
+aFp3yu5WVQ43XwCfahn9RObiYcvqRFXPtze303XMRQIAoIvStwGIypv7YrjeS/70
+EpaQMPn5iEYEExECAAYFAj+6hk0ACgkQXP03+sx4yJOqUwCg17eCYJCnmzDw9GTe
+/BKGPZj12LYAoMnIahWcyIFLlLOP9ISlMKlr5EkWiJwEEwECAAYFAj/Cd1AACgkQ
+N+P0X+5l4yE+dQQArTUZsgHjZE1M9DRQhZQkU20/WzW4NVxWaYdW2/tIy/a293Zd
+RWG9QDe1VPT7KUoAT306N5HqM4TUjg2QjAyg6ou6J76yk62j1Hsj0RJskf0IMXiF
+NZICn7z+y6FsCI60flgpOKI11GZeAI6FLGppcsF5NCnAP9PKv20EQ07kUeqIRgQQ
+EQIABgUCP8YSFAAKCRBtC8c6QFgYN2IOAJ4lgeI6pvXBeEM13xq9WSplyS9z7gCc
+CO/dGO4i7M9rcDp9B79sy/Qpnk6IRgQTEQIABgUCP8OFGQAKCRD6PI0mFCtQm93V
+AKCMJi0mWq0PLehrhpGwJKrzdt6DSgCgiRqkfD1u4lj6rezjCxH9GR6b9HqIRgQT
+EQIABgUCP7mp+AAKCRCoHuZJzhnVxkHGAJ4moSSBBtV6ynXFk+k26ca1M5Lx5QCd
+G8MrlXJ5ThRD4ZecP79x5x8CmTeIRgQTEQIABgUCP8e9LgAKCRCkdA850Ue3dsVa
+AJ9h8CF7Tj68kwbzhY0/RjkA2pA94gCfQH1azsf2LYhOvObOrknpk1ZALOGIRgQS
+EQIABgUCP7xjvgAKCRDsmT1jZf3N7jUmAJ41pjcLgAkHvGnfv9jZYz4CqvrGfgCd
+ERE/EX2IX0bYOraPIcuhcHaHCQ2IRgQQEQIABgUCP8BjyAAKCRAaCdGD/Qk8QVAN
+AKCMesKnneWni3IardexYlkChRaLXACgtmgMT0KWnWAwk3zji3zkVgk72HqIRgQS
+EQIABgUCP8FOvQAKCRDMITAgodaXWbO0AKCPOmm3BjK/OrGzsu+04g6SfuV8fQCf
+b0SDGLgnslcqkzU02ZxT+hHWAbCJARwEEgECAAYFAj+/wxYACgkQBurPqnbYPMbJ
+ugf/X7I18RgC6uFsPXsCMQh/EQdDO3Cll8SnmCmNz08jlE89cDiHAgJZ6b7n+p+G
+v44DaO5Ofkb+iwtTHuFuvG50qY45X2/oyBJHllXlbxMEyjWfhny6hD84WYnM7PS2
+a6gww0+beCz77ESw6RdHgIFNvZnn0Ca58QLKixlKfNxqaqrR6EG6zUI9qdNX1XVc
+Wfu70EZfaZ0Kx5jTDz4h7TGw59oH+NBDRpGvU213NFyckbcGav11GgLBCwR6Iyzx
+nFTrowWXR2QXfX8akSFg6Oz1k818Pjwolr1l3JF5YAaDxwJ4qZo/ldHSF4/+fAmC
+JLJfRco6ndv8rFr6FV0+SVv5dIhGBBMRAgAGBQI/uaDwAAoJEBD6TIilTaLfcHoA
+oOl0OsrJQ1JAgtyCXTs0VxJAXshnAKDXdDvK0ZevnovRoZvMW6RYv0+STYhGBBAR
+AgAGBQI/v6F3AAoJELK+vEAVKSSvF/8AnjieEHBnFWQQNrZtknhXQeyzkS9eAJ9U
+I6CHLstOQAIQj6dgQIfXS6oaHohGBBARAgAGBQI/v6OIAAoJEMEee0eWTzHZlWIA
+oLPh3TMdnARqbnzFpHQV0BN1Y+53AKDm7WOQM+PUUOcXrlYw63CVC9QPP4hGBBAR
+AgAGBQI/u6D5AAoJEKRZJPC2tF8fWigAoMOg9N7DfgZCaMDH/uiZPeVDYLx1AKD4
+H4Cv3wOrBC9gsfOz8vPc+psGu4hGBBIRAgAGBQI/uc+fAAoJELkkUqxMkWW2D0oA
+nilUs/fdruISz7OcUHSYoFb5lxxpAJ0SbzM82p96RMGjtMtLWdDNm3AKz4hGBBMR
+AgAGBQI/vcjeAAoJEL66K4f1/EtCILwAn2x9+QkXNkfTt5LEHmJAXXzkr2aFAJ9l
+vz17ctX04GyH0E2p7lMU9qJvWoiZBBIBAgAGBQI/ym6tAAoJED6Pt/L4g0HZKPED
+51Q8rmnCha+FQi8+42sTbBjWSkYmsB/84mjddFlK40AfmKpXNnF5lpHCPBfdtuG7
+/r3mnQrT/T5PBlWA088zyQhzBTsCNObNQE/5cwoKv2sOuWMZ/HW5JFYJgfQoqb4b
+hTkSy7d0ncIW4Rq+heZc/E8xWmUpQH1CrFzvB2bsiEYEExECAAYFAj/N+agACgkQ
+CVpF3KEdVvtdTwCgtbh65s6vDfxmgVqxdkqsi3Nak20AmgM7hfMHhUcn+Y8PAyYv
+0OrVvODkiEYEExECAAYFAj/QnmMACgkQZAeG2a2/nhq54wCff4Pqt5SN093nJovx
+DlbDYaOfKOQAoIyGXGz47PIq/a+Iz4xQUhIeccERiD8DBRBAX08pzLLrRuds9tAR
+An93AKDyrgyVQtB1W++4OHFG/z1q7CH+wACgwZvoITrGdxYl0AkQl4vBlfCA+l6I
+RgQTEQIABgUCQBXODQAKCRAVP6DNdaZ2ko3BAJ9nNTEMZoAm8u1mLbT6js+0AbdG
+1ACfQ9N4my3CjFtkbKlZJQbX21RbMXGIRgQSEQIABgUCQXOcJwAKCRAEYzpXfCAJ
+QVLzAJ0UEZDEppRkLJ4kBLocODBxDIE6GQCfXzuLIP8d4f69n7+mEQ53oXl731KI
+RgQTEQIABgUCQYEokQAKCRDJtabs4td036n2AJ4uEXDUohTWekkekOJADd9OnmF+
+HACggroXsTFhgTo4Jfp3PlbjbMPzZB6IRgQTEQIABgUCQY7i0wAKCRBbloAQ4E+a
+ib6AAJ4s4LLTmFEs8WPdzEsJP1l4zxOrLACfYh2WW5PBK/mXzpyuHaAdiTUvBwiI
+RgQSEQIABgUCQDAZbAAKCRAui9CAzGnO7W+3AJ9Wd5/O4+HWnFX7HIjiLfgztLYf
+ogCeNd3AIrpBeMc/VsaCq9FMSyWTGW+IRgQQEQIABgUCQt7UfAAKCRDKaTl0gQOj
+ftBoAJ9fvoRB0focT55ahIMuOxHatkG+3wCeLoi4Bi/7H2oCLo0KnzEhxG2ub+GI
+RgQQEQIABgUCQt9B2QAKCRBB6gmgV5NJjzzaAKDSUhQNlW06s0xC6R9TEwpv4ua7
+4gCgioFShMWUF9nK//rtJY4UPuqUrfuIRgQQEQIABgUCQt94ZQAKCRA5TS/jxMV7
+QjiTAKCkPiaOaMxlwljTlZ5P2+hj9mnrGwCfS+FLvDtG8aQNe0cBtJh/Nd8lU06I
+RgQQEQIABgUCQt+SXQAKCRABBWa85BNjktEiAJ0aQvskonbB6x4YiHMke9aRg78Y
+dACghDjWChAcnC8auG68FXz7qhpogYSIRgQQEQIABgUCQuDX5QAKCRCM43a4HNSG
+Hz7MAKCyLte/wmVglcJ/lCbAO7YYwSX0qACfaJsVj14g1n+yx9hg6NYp4lLQvEyI
+RgQSEQIABgUCQt6naAAKCRCLlilD/CQ/PNufAJ4mOXxDVN43PKWZ4mGp4Pi9UQCT
+SgCeJyKLABUdcMP0X06zFZXXIFttRp2InAQTAQIABgUCQt6uWQAKCRAxpj2W7BQL
+gS1ABACYB+R8EkzBwPbLCgLM0pLvgeI6CYwRUukB5nYirnemHXEp9xn5/WomNFQ7
+ATfLNx62xi2LmndsVx111lbalMFw1rXtB0f9ANqrV5CmSMsJsLRh1oxxBTx2jl/U
+xRuwNoUsfZH3KQSBPNv8jd4m3swBEDEYcA3y3mrQ1+nxYBvYpYicBBMBAgAGBQJC
+32zyAAoJEJrNPMCpn3XdYdsEALKyrvzmP5KpXNr4Mi6hdD7OponkH2kJ76QF1x5V
+kWgNhkPvs8jbKYKkuE5W/nPYWuTAzbUH48oRfflhbflFqRmFmrUwkWlhzGFskhwS
+BefKpBkKa0r5arXf/9vstJ0tsw4cTU0hGFXRnHvJu9m800syUF3QvWPIKaqJQDsX
+ZVFTiEYEExECAAYFAkLer/4ACgkQ/W+IxiHQpxtzDwCgvgnfzIPIPkXeHcsPqGkN
+ssq3ge0AoJYUFNF5dyHSl0P7/Yy/eMxdhjBFiEYEExECAAYFAkLeuigACgkQMsnk
+zjZCy0tkJwCfVJIRe63tico6mL3E99vHOk3DhgAAoIIJj2+LVNokVfvNwtf1vHO6
+G2e1iEYEExECAAYFAkLe1O8ACgkQ7tHqOSJh0HOfaQCfViDjq8s/OskL1DPYgutX
+Rr6LmIUAnjZnuAfms9kJB+ikDGJ8BMDZquCUiEYEExECAAYFAkLfbPQACgkQUI6u
+xTAtpWg/XACgk6arXvIS/rlg9lRczNWHFk/l2VgAoJiflbfbXqaqwup+plh79i9K
+8hXDiEYEExECAAYFAkLfbPUACgkQ3bpkuiwxLS8gJwCfaNtNOjwUHn/E65LrGQL6
+343crB8AoNHSuf5hMIr9uMxmzT6f77UXy2xtiEYEExECAAYFAkLg7OwACgkQN/aP
+9QFa/IqxywCfTjZhztlMB2IXA+s7zipSLpcDZ9kAn3FrS0VNRdofLFAgCSnIkigz
+ruociEYEExECAAYFAkLiYfsACgkQbZiNF4cxXDFy3ACgmhl+8zPWDD5xpIT4Oj+H
+QM2PtDsAninAakLy5J40Lq7s1wg86a0FanHziEYEEBECAAYFAkLjZWwACgkQ/YmK
+mPoyxXYOPQCfRobP3JgS8vGMXwaAldIqIPm9hV4AoJXKkqFykKWia8XUF8yC8EUb
+2UyOiEUEExECAAYFAkLjZKoACgkQdcqio/ObN1D2VQCgsEyTmI7uHVIwmD6tlgv4
+aW8y9eIAmL6+a9i6vDLlwYIEDuWAFDV19jyIRgQQEQIABgUCQuOlyQAKCRAEkTRC
+6hujjYccAJ4o5U0iMZ5lDD9lkZz0ZBPb010USwCfTUGQigP7p7cxCq9XvqTkphEr
+61aIRgQQEQIABgUCQuR/YwAKCRBhGWouMz5OhOlhAJ41jeirjoHV2HseF2zyNult
+Qe1IywCgmdpswo2DSfdEW4YsKgA2I8YyT/+IRgQTEQIABgUCQuPrkgAKCRAyhk5B
+nIUiK9kZAJ9N6JzhxlcbQdzIg/NmECmuhN4C1ACeJ74oo5EI5LVVLZt6SbRL/D0X
+YyGIRgQTEQIABgUCQuTmuAAKCRBIsnaA6UFeNmB4AJ9T/IU8IW6qfJh5ocqCH4+5
+cp/sKACeKvrv2/I+HqBPJUf2C55wNEloIMuIRgQTEQIABgUCQuUQfgAKCRBSeS+v
+mXivhlOAAJ9H8d4LY+N/k5Vs3ClpozSbQld3KQCgvZoQMy36M7b2VlOevYNYCJx5
+wY2IRgQTEQIABgUCQuURdgAKCRBrc6EGKmI/ciAZAKD3tU2ZQMZ+GPzYErMe0UVX
+O5441ACcDvgnvNqRi58R/Tj29xZ7aK+hVO+5AQ0EP3RXhBAEAI0GKzWN6/91sg6Z
+UfDT3o47an9HS25dLHarTB+NG0SqQE4HP9Z2vSAJMkww5YBiUqEzdk9uzdtytPwd
+dgrkYKm9ZCPlIZ7YT8yt6iW+X6LVTgYaFlVUNDOJl0iaZIOyoIc+PizkpYmGeRKs
+TdqxZ6ediosAS6/rZIX+s5rAR+vbAAMFA/0SZUkQb2YOnCPhJnSQVsFtupzq3We1
+GPHw+Rbj3OdTQ04IzaUho4zeV4zxubnOBucPiRLuAMi07DM9od6kuuHtrs5VROl/
+8fFSC0sCNrMXjjmaMqTX8pDuhTlJHmPeclnBojrBMGgj3h+T8EFm3FngRx2BwmFA
+AEj0ugqv69NrZ4hJBBgRAgAJBQI/dFeEAhsMAAoJEBMuSdTkHtx+BYwAn3D8hfQX
+DHI6HAK94zU8OtVbFPh1AJ9obbY8MZoEVaxQjJANQZLnp2QLSQ==
+=Jvfd
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub  1024D/154462C0 2003-09-24 Steven Noels <stevenn@apache.org>
+sig 3       154462C0 2003-09-24   Steven Noels <stevenn@apache.org>
+uid                            Steven Noels <stevenn@cocoondev.org>
+sig 3       154462C0 2003-09-24   Steven Noels <stevenn@apache.org>
+uid                            Steven Noels <stevenn@outerthought.org>
+sig 3       154462C0 2003-09-24   Steven Noels <stevenn@apache.org>
+sub  1024g/DEB50537 2003-09-24
+sig         154462C0 2003-09-24   Steven Noels <stevenn@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.2 (Darwin)
+
+mQGiBD9x7i4RBACh9zAGHT/Pk0cLhHBG6J7hkbrRoir6m2BbMAEVqpghT9F4kjxq
+Fuj8adWi3Ui7F1MVSrGR4mAWnYvS5KixKhsu0HQPwwqO593v+rxISSS752D59Ewq
+rWxW7rgDd+L3FdhVPHOYOcDLPitNesSU03/95XyDvfm/Z+WakAMfCIkoywCgydm0
+eL0VnZowR94zngfVW/rfpScD/iG6H9f0Yif0qG34iAuzzouyyPBkqKWLvjH8/nSU
+wmOhE0PZCb7sNSQBLtfhce5sPiRan7Rntf6cThY9vVLqx5CK59rYkxoXmM4RZeaE
+6rufSd6lWV2Cg+wRNVpr699n+A7oCPRUokFecvh+FfN9n9wjvv+F1+YHjSd0jnju
+1tdOA/9yh8mwdicvFlJmBPKM/kW6k4kTu2DmiMe2kCD+Z5iBeR1jTWMnDs0C7tcQ
+Lddhl775KftqgOQisXovmwWkHHN+uSJStqkQpXuv+v0lEVMSe7H2CQjSrmxlczWZ
+2e9bqxrF4Oq3ZpNpifqZAdJ8uBrION/Ir6KFqqUbeP6SaVaqMLQkU3RldmVuIE5v
+ZWxzIDxzdGV2ZW5uQGNvY29vbmRldi5vcmc+iF4EExECAB4FAj9x8x8CGwMGCwkI
+BwMCAxUCAwMWAgECHgECF4AACgkQMIHvjhVEYsCkWgCfaTKWN/gokK8+qWqvVixL
+kx7dPVsAnRDo9+oaJ6tqIomDc84P0wMzmKu+tCFTdGV2ZW4gTm9lbHMgPHN0ZXZl
+bm5AYXBhY2hlLm9yZz6IXgQTEQIAHgYLCQgHAwIDFQIDAxYCAQIeAQIXgAUCP3H0
+fAIZAQAKCRAwge+OFURiwBzWAJ92ldSiOyiEvx1T0h4r7Wn8MHmfUACdEon19pnF
+hfm0fm9bSPjGb4Kcoia0J1N0ZXZlbiBOb2VscyA8c3RldmVubkBvdXRlcnRob3Vn
+aHQub3JnPoheBBMRAgAeBQI/cfL+AhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJ
+EDCB744VRGLA6wEAoK8oR/uUTCqA63yT2IWiGVSRLHZ5AKCp3D1azq5LtHRGILOR
+HVlgJH5JZ7kBDQQ/ce40EAQA1ZSZ6NcOMNoDTXyGnJpKp1AOCdqGvh/V5LzIqekX
+0I2++TOYJ0nINT30zeXJl2zDw3l5gzasl3FtfD8Oq/7MuMRFN2iOoFwef8/bGwTS
+Sll4QL24MCN2jjyaGjvUIDG0pp7bwbJO26giQ25Xd/zDePcyPVvFoG2h21gxu2Ry
+px8AAwUEANAgbxio4jClRl9QsQOFR/jdi6E1hC33ApfoEgsIlr1w3MhezwvhDJD8
+dpv1CvHGfkdYrDiOIhPz0UfOOszfGh3ItmHbhKt68c7zUujVDpvBPWS3RVyoPMVQ
+yIQaXNu76CJMk9S641yfLEZANqWPK9jjnOUJWs53+TAsUHKdz7ztiEYEGBECAAYF
+Aj9x7jQACgkQMIHvjhVEYsDVYACgnuuUwKhLCHYMCBi5B5+p1/LhrmEAn3CKf5E/
+OSMKxqUanA0+hCP5QSK3
+=bmPL
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub  1024D/23CB7A2A 2004-04-17 David Crossley <crossley@apache.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+
+mQGiBECAyjURBADmJ6lx3nq7Chjk4xuLxJW8Jnt53a+alQJe7eQPTHaiwXHMVG3N
+woA3BA+5Ceg5S8jE3/1HpEyjG6tIi/P/O7JbRp1GnNAuPzwLvjUQrq8UpzGFZziy
+6eVkEhphh5jaEDSotQY7zkmXCPeVJFr4Kfm++TItDZrHv4Lr4lt1HsfLfwCgjJZ8
+0js5OYuAXi8qI6LDQKxEK2EEAIz+iMJnFZ9n07XZFnliO0U3oS20qZH4V0Ulr6MZ
+hJB4JAcqhp0SP23qCXTpTZq/nE0lg5FosBkwnyxsefEy8oO6h5VKNkHJH1HsCQge
+3kagwNgfKvb5IR3VTwdm+LscQK8omdngC8c7L4g5LUZguDIWmFW/gueTjIgPtG1V
+uIktA/95sS1InaDfu3NplUR1bN+/r6ZZdh30oGxVlfgEfQkGN/8lh0n6JWFGhfZZ
+xkp6A0UNhOCJK6gMfkylXRNyLnkKUFgk5SpLPjhmbA34sexMe5nPDA/VRQyT1wml
+ZsmbU+s9fSYoOiwLZAa944PI9xLHsD65AFQApPWWk9R14REqzLQkRGF2aWQgQ3Jv
+c3NsZXkgPGNyb3NzbGV5QGFwYWNoZS5vcmc+iFkEExECABkFAkCAyjUECwcDAgMV
+AgMDFgIBAh4BAheAAAoJEME58VMjy3oqJKIAn17b13eo2uN81+UYLPPf+jN/Du1D
+AJ9Hj3IS8voY3o5qNZRRqjfOu76PYYhGBBMRAgAGBQJAjaIvAAoJEARjOld8IAlB
+n0MAoIKjPJQm2BukjeZukgfWkiYWfrdQAJ4t2qEHudtpdKEaZo3YlLnwgpmvNYhG
+BBMRAgAGBQJBHwQdAAoJEDm+UaEITJETAPsAoIUl1BXOxf5R3Sghw80xK1LIGDkB
+AKCrh21pNIgWaU06NKj0hRRe2aPCyIhGBBMRAgAGBQJBKZHaAAoJEDf2j/UBWvyK
+bcIAn2SNhLZo068xmflhuiJbukEBj4b8AJwLWN5VMlkOLceqrlWxxHUGm+lIT7Qq
+RGF2aWQgQ3Jvc3NsZXkgPGRjcm9zc2xleUBpbmRleGdlby5jb20uYXU+iFwEExEC
+ABwFAkCNFIUCGwMECwcDAgMVAgMDFgIBAh4BAheAAAoJEME58VMjy3oqzuoAnjm4
+yuR3urHOzPH5OJaWz9Dl1AfAAJ0SF4scmOEFaO3sP94ycLQN6/cP+4hGBBMRAgAG
+BQJBHwQYAAoJEDm+UaEITJET2RcAoIWrz1BeS5unSuH9//NIYwmvDqkmAJ4wwm52
+WwSRg5ttVMNL0Bv24/XgzIhGBBMRAgAGBQJBKZHQAAoJEDf2j/UBWvyKlkYAn2D0
+jMFnrjjFXpFRq4NyN/3gPF8aAJ9HToEvWEUsgmUZlePs2LsGn/XBN7kBDQRAgMo4
+EAQAo4MUVKU/V11pIXCFzt7V8MFu/k4702CNmpo5JMHQxtPhfc2Y254aPFgarZBi
+uttB/+iH4+BMMItSDVu7T+l89hfmzy277oV9QkwouSTLLK+g6ansueA+JTLXoiEb
+WIAkK+DAXTztvaixPq8rAfHvyFLFl2cUfvk2wJNW9aZPcccABA0D/31AixMfHl5b
+e054qWxkjcZJBNs/SkjQvOGgYLpf3qzP1YwYjjP1EJa4MEPeWTggu3yk6xtbexK4
+ujzLZZ9XjiCk3x6yfoF4nNb3cIuA2xMkDU8/qhGtbM9+J3qQArCVBF0MUelJXHCM
+T3rs8e0pd5LmNqJpWLOjihNLPWpC1PrMiEYEGBECAAYFAkCAyjgACgkQwTnxUyPL
+eipZzgCeIaSVLRsyuTVMbAjdxKnRoyp0F08An1kkI/x5gP0X4cHbcUAGTbLqdzJP
+=wNYp
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub  1024D/7C200941 2004-04-24 Torsten Curdt <tcurdt@apache.org>
+sig 3       7C200941 2004-09-25   Torsten Curdt <tcurdt@apache.org>
+sig 3       23CB7A2A 2004-04-27   David Crossley <dcrossley@indexgeo.com.au>
+sig         C4C57B42 2004-06-23   Marcus Crafter <crafterm@debian.org>
+sig 3       7C200941 2004-04-24   Torsten Curdt <tcurdt@apache.org>
+sig 3       015AFC8A 2004-10-16   Bertrand Delacretaz <bdelacretaz@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+sig 3       E41EDC7E 2004-10-30   Carsten Ziegeler <cziegeler@apache.org>
+uid                            Torsten Curdt <tcurdt@vafer.org>
+sig 3       7C200941 2004-09-25   Torsten Curdt <tcurdt@apache.org>
+sig 3       7C200941 2004-06-23   Torsten Curdt <tcurdt@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+sig 3       E41EDC7E 2004-10-30   Carsten Ziegeler <cziegeler@apache.org>
+uid                            Torsten Curdt <tcurdt@web.de>
+sig 3       7C200941 2004-06-23   Torsten Curdt <tcurdt@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+uid                            Torsten Curdt <tcurdt@managesoft.com>
+sig 3       7C200941 2004-06-23   Torsten Curdt <tcurdt@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+sig 3       E41EDC7E 2004-10-30   Carsten Ziegeler <cziegeler@apache.org>
+sub  1024g/87C5307C 2004-04-24
+sig         7C200941 2004-04-24   Torsten Curdt <tcurdt@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.4 (GNU/Linux)
+
+mQGiBECJuNYRBADaat2HMyxurx2WP1A30fBMrQSR+oUkmgb3bxcNthX5Ak/l88Ue
+r5t/fXzBCMT8FOakMYotcDF05SYW6eB4fUk6IgGRr0qNdoPOnggYpJlFt0jogS9I
+ZSuWi1wg0Ky8wXxSwXbza88k2zymeaJDAw6MkGZU6OJIfLqqMZxAINqJowCgmlg8
+MlrLmLoZe8mM3VWYNjOvne8D/iovOI/CNNoIcUBBK5zjnKjUow0J53r47CzlCq7Y
+UWwgbkia547s5C1OD77vuhcL2yhSe+boamslGuUiFEjZlazsrdnFmveNt15QHS6F
+enDnoAYvBEybiwgISfWslaMIXB8VzKjd2CxzOjqW+U4Zb8Eju7zHaS0T/W158dEg
+xrsTA/9uI2BJsESYeDiTyEdKrkVbbp4r6INBaT2oUjV3O1l1KBwa1G24RaBV/TgW
+7cUzTSNtwcPiOcqMK23JwjRIA4LNGTtXY2hALmVADFlxHVUasKBgUQyepnl1z0ow
+uGOxV9CENgtv8nE8ToXnfUcNfrclFO+ryGwYPhC9yp9CgRxvQLYAAAAgVG9yc3Rl
+biBDdXJkdCA8dGN1cmR0QHZhZmVyLm9yZz6IXgQTEQIAHgIbAwYLCQgHAwIDFQID
+AxYCAQIeAQIXgAUCQVXMfgAKCRAEYzpXfCAJQfXEAJ4m56jBmINsMcQbdNEhl4ul
+LveyzACfRSeYaw1UsRgnkWkxlmezDgq1CvuIYQQTEQIAIQIbAwYLCQgHAwIDFQID
+AxYCAQIeAQIXgAUCQNmEuwIZAQAKCRAEYzpXfCAJQZ9jAKCVtsFC+qDxeao78KbA
+2sNgdTKf0wCff8dHT4E+Ur2TiLRsWHPltjOEAM+IRgQTEQIABgUCQYEl1gAKCRDJ
+tabs4td03wRvAJ9ZIk8uYySZGmY1tzgLybzP36ktUgCeOpggcNMfTN0pANjaT3MW
+9zhduUOIRgQTEQIABgUCQYNe9AAKCRATLknU5B7cfvrJAJ9ZyY06/sMdi9j6n4rS
+OG2YkrrgkACfU7i4q9rpcBQwY0uSbhqSgMIRpH22AAAAHVRvcnN0ZW4gQ3VyZHQg
+PHRjdXJkdEB3ZWIuZGU+iF4EExECAB4FAkDZg3sCGwMGCwkIBwMCAxUCAwMWAgEC
+HgECF4AACgkQBGM6V3wgCUEhCgCdGgxRir3XiY5o37WiiUVdMoqjWGoAmwZRiLSf
+AVvRJkqh1HsGXDNcBPeQiEYEExECAAYFAkGBJdwACgkQybWm7OLXdN992QCggsKb
+JcybrVFAI4jybEXA1bUqj78AoJhNFXD22z0Xs/9LFX/rHMttaVUltgAAACFUb3Jz
+dGVuIEN1cmR0IDx0Y3VyZHRAYXBhY2hlLm9yZz6IXgQTEQIAHgYLCQgHAwIDFQID
+AxYCAQIeAQIXgAUCQVXMowIZAQAKCRAEYzpXfCAJQfG4AJsFGIbCiVCa4ZNR6iuQ
+wMju/3160QCcCt5RYIJPND8xxY8SSJJWeeM73FCIRgQTEQIABgUCQI3ozQAKCRDB
+OfFTI8t6KhxuAKCJo9eAGdQY0Z3tO72pgc0PahmWYgCfYvGzyrSSYdj/FZYxBbRz
+IFnoxJ2IRgQQEQIABgUCQNmAvwAKCRA5TS/jxMV7Qi/BAJ4/eAIG3ZSGane2hQg7
+6JT1L/igVACgghZ3v1fy2hPGGSMOKUjCi1JRrMeIWwQTEQIAGwUCQIm41gYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRAEYzpXfCAJQW3hAJ47cOXJCX6s6I5a1/0pdPbt
+ZpuK5QCfc7GuWcGNKfoZ21G5+A1yQwyc4SmIRgQTEQIABgUCQXDcNAAKCRA39o/1
+AVr8ig05AJ0WRwZRTHHYzOb/3ZdSxZrBdq32+QCgr0aLjrzlkQQlEm39FTraYz5V
+3zKIRgQTEQIABgUCQYEl3AAKCRDJtabs4td038yUAKCK7Z0Qj2e9byHm4QWBlee6
+HDb0VQCdEOBfjvgjSm6mfsdpQ0gIfcLx5OuIRgQTEQIABgUCQYNe+AAKCRATLknU
+5B7cfuNHAJ9gvGnPpatxrHTYcK6HOiakDe7g/gCdHY/sdkOcR9PJfOGDcmoBn4NZ
+dRS2AAAAJVRvcnN0ZW4gQ3VyZHQgPHRjdXJkdEBtYW5hZ2Vzb2Z0LmNvbT6IXgQT
+EQIAHgUCQNmDPQIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAEYzpXfCAJQXDl
+AJ0Y8rIlcxDWwVVMhvGBVkiKqFIbDwCfecXl2t5aEkaSB3d04XGjnWoeS2aIRgQT
+EQIABgUCQYEl3AAKCRDJtabs4td03ym0AJ9jgM4Gm/KYo1CLRctueUP2CjQ89QCf
+ebUk34caPWQOY4GEaRJaL/odahuIRgQTEQIABgUCQYNe+AAKCRATLknU5B7cfikO
+AKCLJNSL05Jqrjf6UaMXnSLOekphAACfet1nzXOCqMM861g6XBlpb/NXY7y5AQ0E
+QIm42BAEALcvuUrhKXZedRYWw7dwTxk1DvJTS2OeSF2Pw+l3gsXM1aZSgkQl2amB
+FHkW3tNso5Yg2tlRyZ4qxHVth9uPoOUpiHFM4QBwBF5v88H4xOsB0Jb+ez6Pp9n1
+fgXqE7M22b3qyoycS35qt1n+L70YeDAkn1Ynn0cOGLYTlwBf+MWnAAMFA/42WTed
+sywafZYmXx6SfQBEATGVoccK3WOosboJFGUwtMqf9hAeLFMVGFTI52V1mgXBlrRB
+5slqly+6BDsi9c+8mk2K7fRewrWFkcMqeS+cRzm8cREvd6O7oV8Zv21xboz9UghO
+lxE+EFODe8xxLDaTtCVGMfprA1R6iZgZ8WXBrohGBBgRAgAGBQJAibjYAAoJEARj
+Old8IAlBgQcAnA/hSn5cyQKieputYs0N9DYZ/w+4AJ47a6aNvCM6fZLrvN71RcEA
+SaIPhA==
+=ruBc
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub   1024D/2BF3F720 2003-09-02
+uid                  Vadim Gritsenko (CODE SIGNING KEY) <vgritsenko@apache.org>
+sig 3        2BF3F720 2003-09-02  Vadim Gritsenko (CODE SIGNING KEY) <vgritsenko@apache.org>
+sig          873CF1AD 2004-11-19  Cory Friend <cory.friend@atmosenergy.com>
+sig 3        E0D4776D 2004-11-22  Ilkka Tammela (illord) <ilkka.tammela@iki.fi>
+sig 2        E580B363 2004-11-16  Theo Van Dinter <felicity@kluge.net>
+sig 3        E04F9A89 2004-11-17  Roy T. Fielding <fielding@gbiv.com>
+sig 3        EC140B81 2004-11-16  Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3        298BC7D0 2004-11-16  Justin Mason <jm@jmason.org>
+sig 3        12BFE79A 2004-11-22  Kevin L. Collins (General Purpose Key) <kcollins@klcollins.org>
+sig 3        2C312D2F 2004-11-23  Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3        302DA568 2004-11-23  Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3        D1AA8962 2004-11-24  Brian Behlendorf <brian@collab.net>
+sig 3        A99F75DD 2004-11-23  Rodent of Unusual Size <coar@OpenSource.Org>
+sig 2        F5FC4B42 2004-11-24  Theodore W. Leung <twl@sauria.com>
+sig 3        2D2DAA52 2004-11-25  Kevin Crowston <crowston@syr.edu>
+sig 3        CC78C893 2004-11-17  Rich Bowen <rbowen@rcbowen.com>
+sig          6C7C4F5D 2004-11-17  Robyn Wagner, Esq. <robyn@rwlaw.us>
+sig          152924AF 2004-12-03  Sander Temme <sander@temme.net>
+sig 2        E4136392 2004-12-11  Noel J. Bergman <noel@apache.org>
+sig 3        1C43D850 2004-11-29  Heather Stephens <heathers@apache.org>
+sig 3        16A8D3AB 2004-12-14  Julie MacNaught <jmacna@apache.org>
+sig 3        23CB7A2A 2004-12-26  David Crossley <crossley@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.0 (Cygwin)
+
+mQGiBD9UwcMRBACxv2mkAbB8aVPsqL3U3MzqCziNNLD0//a2mb6OrpemwuoZZ6Ut
+YfXblzJVqrW0UrMcNIeiPphA2nXfSwaRcBnIn8B8A2NMrZU/fLQVvVi7oiEEBQUl
+q5mePVU159RPvMZqtOiuLY7dL0bRTqS57QTYU6mCbFkQ0EWS8xULCaUeXwCgmxPB
+RclsZYOw2+10qj8ur+3Q+5kD/jMIs/hh1b9O2Y41be2CYIfCX6rA7T8OsKcA2LI9
++PKf2CC8TA/gQkbiQ/e4ebludpIDRtskHA8sav+0T+WMQJuVNh9Xwyb22LkoJqK+
+YDVlQVLDWCa8er4mHZfMdEfhqNcdW4/heK3vkiB9cexHdKiVaaSVVsvhL48JtWbn
+tbktA/4jsy8yE6l/CBERY74Apo0FND0ZrIzqW5U3aUOOq1yI1mObAEcnEv0GpRzo
+DqHVric+xj/2YGkXf+OMq2uzkLO76m2R3Pv1t5iF6lifyAAZ4FhbCuxa1kwis5cP
+/6iMLzyRRpoCrknYoDnh5YwkQ7kLY6QFLK7gcNI6OJvFx/M4OrQ6VmFkaW0gR3Jp
+dHNlbmtvIChDT0RFIFNJR05JTkcgS0VZKSA8dmdyaXRzZW5rb0BhcGFjaGUub3Jn
+PohbBBMRAgAbBQI/VMHDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEONvYBIr8/cg
+MCUAn1CWzWGRL3CNbBZ3BAnz9MZYoFrAAJ9Nu7aH6YGnEeqYBlDaWSMhvFUk9YhG
+BBARAgAGBQJBnhF6AAoJECdGoiSHPPGtqOIAoOezCp9QdcYmJOz5euviJJKyF+wt
+AKDgR/FefZL5um55yUX2SKIzrAP2g4hGBBMRAgAGBQJBoX4PAAoJEMu5UGPg1Hdt
+QI4An0IUG7F34gCLbrafOlVlUr8hwSjaAJ4vFL5UQ2PVHpmXwvlZmRXEATa1F4hG
+BBIRAgAGBQJBmcAvAAoJEALjkFHlgLNjz/oAoJ0XWzQypbcLGPooGjCbdzIEPCH8
+AJ45LjUCtrc4bypN1Rv783VMOGBTwIhGBBMRAgAGBQJBmrulAAoJEFuWgBDgT5qJ
+yn4AoJAb27QPENJUpM3NfYgZJmqPtDxoAJoC05gcaydN5+ane9MDYWK2WOmhCoic
+BBMBAgAGBQJBmYIpAAoJEDGmPZbsFAuBT7QD/3IxwrkchVbqWk6jmvVQBoSVeGqJ
+0c4u7+Dtu/nQ08gGn0oN4qVdWbcSPhPYF9uQEWMJbYKxCj8SKusuYS2om7Y7I//l
+IWgPrGwD4LCY5CVbMYlPqQJ7Nv5C3DjpklafqlsaH+7DHjHAP4dlCg7mQ/p+sZ9L
+GyMFBfMCiFQNx3cQiEYEExECAAYFAkGaiFgACgkQMJF5cimLx9AXlQCguELfg+0Y
+OJaNLUc54G2vS4CxI2IAoJ8kbPlSNujiHn9BR7RdIIXcIa44iEYEExECAAYFAkGi
+Wr4ACgkQBJfVkRK/55ptjQCcCG7xAbOCrihTI9GtxcK1EX52PNwAoKVJOBZNmfse
+NsF6FzsbOT2e0wrriEYEExECAAYFAkGjTO0ACgkQ3bpkuiwxLS9spACg7SNlREVg
+Pc9ad/rSbXm2vSsSx9QAn2L8KBueeDn5mDQlcRpkB0pVrgDpiEYEExECAAYFAkGj
+TPQACgkQUI6uxTAtpWg6aACfTqADnccVYwnY7cb9sdYRUbQRyWgAoKbaqlojKZpe
+GbiKgGnPprzr4GUZiEYEExECAAYFAkGkMNAACgkQF2rZyNGqiWL65QCguKPA58A3
++2D/wNDbTYIaKK61H+gAn0UhXBfn4LeavGqxCdRBeZGM7dnbiJwEEwEBAAYFAkGj
+TOcACgkQms08wKmfdd0A3QQAlLmaULDusZKBNy9O9WeCwcrFLb/ddZNF+1TT8fxS
+DEyBO7IM5B2GYYa3UVytYK4hmUrfkHO5cfpM/1Z5crJT5wH4RkLCEcL4PNuZIWCE
+7nVzsInVUkB6sVxu8LG3EKIXpXDoNJ54zPhQxx/hZ0YqSv/e/7XqT4pQfnvb2kzv
+qD2IRgQSEQIABgUCQaRSkAAKCRC+uiuH9fxLQjWrAJ9rOY3dJMEEQ9JosIQuuuCl
+ql9CSACg996RxlIrFnNmgx1PgQIz6ZB4+uiIRgQTEQIABgUCQaVROQAKCRCXZ4py
+LS2qUhgDAKDK94kYfxtcjUZQxAuHS39VIK+QDgCfci2/qitpbtj7ssXsl/lU8uL9
+OpOIRgQTEQIABgUCQZqkYQAKCRBc/Tf6zHjIkyyfAKCYa1ROPKHMJiqinjNxqbz+
+HynHWgCg92JWSbzk/othxkztD2j7iRON722JAhwEEAECAAYFAkGa7MkACgkQJPjf
+wmx8T12evA/+PxLrl0sm0OCBKvMzZB9Ko2nMcXTHvCwB1sOdHBnd4AV2Hlc4jp8O
+m4wJ4so43zXphmCGPJbyM+sOkGYk2VOvi/pWm09uR7/NvlNVRI5gobgKuM8QYSjG
+/grFPxa/0Y3MG+65L7k4+p81MfzZfUkTgrvuUgmPD0OcoVf7Dep5dmdZl+QNAwf+
+bmdjLa5wJ7UGM5hxqpuV00dRr/0hH/b419dOWITVvgYbvqGsgfmwYRZq3csSzFIT
+DDInLxqjpMJscE89b+P09AjeJqgHCseFKYGSB8bJKPTzvsRSYI3iyPPeChKDQpYs
+E7sZvEILNLMORl6+rvlp6CC5lOrFC8riCgIznZcLoTCllpOaRPYVePLebN28nSp9
+mjbb9ZSRKw3OxJdjYsvkIZR9C8j8D40cfm/jNjXIce4Su7pbtcPHBWe2YeSfJehZ
+AWfch5h4vMOI3yhI/yzPrYtzElUPZSKe3WPOdcbNZTX0RU9W0iGOeLFzvE6AOmfv
+3VGASpRZj1ytad5TJPFkDj6YaVgOxAE8964FI9fuTa8HxveFr79ZZqqHlc1rmcBI
+tqQQKaNLjcyQCBWJNQpgPYkyxeRsDL5xDNL+Pn7m/msjt5CfPNw4V94uB0bXKoMR
+PgfBhFKUHdrTN5Z7+BPdUr4NX74wnFKLQdCm00UsoDI3XlHKmdTBuzeIRgQQEQIA
+BgUCQbAbXwAKCRCyvrxAFSkkr07UAJ9C4VtzBtdhyg3xQAPvSyyF+FgDkACg1gE5
+DhGrfgLZxf3FnamABh6p80GIRgQSEQIABgUCQbo8XwAKCRABBWa85BNjkqZ2AKCO
+psq+5CF9zCHd8J8IHUlhAAIEqQCgjRMOX5BEN8uGkxKblwcfAdBWvo+IRgQTEQIA
+BgUCQat7CwAKCRDOAaR+HEPYUMtUAJ9ptxPH8dm7ZGvfnLhjL0UZmj9uFQCfbRlr
+YprjALzUrVhj/jcYoPq7oyCIRgQTEQIABgUCQb44bgAKCRDoMBhIFqjTqxeJAJsF
+AhC3+wBh+t75eCk9QIoJ+Xu9yACgz7AAoeP9m7zbJtlBkGGY7Gt3b7qIRgQTEQIA
+BgUCQc5gZQAKCRDBOfFTI8t6Kh82AJ0XQH1YA7k8nMZfBmYPank3D6fzVACfayqs
+eHc62wC/YF3pEMiPhkJsJwk=
+=7zZh
+-----END PGP PUBLIC KEY BLOCK-----
+pub  1024D/015AFC8A 2004-06-18 Bertrand Delacretaz <bdelacretaz@apache.org>
+sig 3       015AFC8A 2004-06-18   Bertrand Delacretaz <bdelacretaz@apache.org>
+sig       X CA57AD7C 2005-07-01   PGP Global Directory Verification Key
+sig 3       E41EDC7E 2004-10-30   Carsten Ziegeler <cziegeler@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+sig 3       7C200941 2004-10-18   Torsten Curdt <tcurdt@apache.org>
+sig 3       23CB7A2A 2004-08-19   David Crossley <crossley@apache.org>
+sig       X CA57AD7C 2005-07-14   PGP Global Directory Verification Key
+sig         5793498F 2005-07-20   Tim Ellison <tim@ellison.name>
+sig         8103A37E 2005-07-20   Andre Malo <nd@apache.org>
+sig         C4C57B42 2005-07-21   Marcus Crafter <crafterm@debian.org>
+sig         E4136392 2005-07-21   Noel J. Bergman <noel@apache.org>
+sig         5C1C3AD7 2005-07-24   David Reid <mail@david-reid.com>
+sig         1CD4861F 2005-07-25   Eran Chinthaka <chinthaka@apache.org>
+sig         333E4E84 2005-07-25   Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig         EA1BA38D 2005-07-25   Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig         152924AF 2005-07-29   Sander Temme <sander@temme.net>
+sig 2       FC243F3C 2005-07-20   Henk P. Penning <penning@cs.uu.nl>
+sig 3       EC140B81 2005-07-20   Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3       EE65E321 2005-07-20   Martin Kraemer <martin@apache.org>
+sig 3       A99F75DD 2005-07-21   Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3       21D0A71B 2005-07-20   Dirk-Willem van Gulik <dirkx@asemantics.com>
+sig 3       3642CB4B 2005-07-20   Martin Kraemer <martin@apache.org>
+sig 3       2261D073 2005-07-20   Astrid Kessler (Kess) <kess@kess-net.de>
+sig 3       2C312D2F 2005-07-21   Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3       302DA568 2005-07-21   Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3       E04F9A89 2005-07-22   Roy T. Fielding <fielding@gbiv.com>
+sig 3       5F6B8B72 2005-07-22   Stefan Bodewig <bodewig@apache.org>
+sig 3       87315C31 2005-07-23   Raphaël Luta <raphael.luta@aptiwan.com>
+sig 3       F39B3750 2005-07-24   Colm MacCarthaigh <colm.maccarthaigh@heanet.ie>
+sig 3       40581837 2005-07-24   Nick Kew <nick@webthing.com>
+sig 3       9C85222B 2005-07-24   Henning Schmiedehausen <hps@intermeta.de>
+sig 3       9978AF86 2005-07-25   Christoph Probst <chris@netzpunkt.org>
+sig 3       2A623F72 2005-07-25   Christoph Probst <chris@netzpunkt.org>
+sig 3       F8EA2967 2005-07-26   Brian McCallister <brianm@apache.org>
+sig 3       C152431A 2005-07-27   Steve Loughran <stevel@apache.org>
+sig 3       CC78C893 2005-08-01   Rich Bowen <rbowen@rcbowen.com>
+uid                            Bertrand Delacretaz <bdelacretaz@codeconsult.ch>
+sig 3       015AFC8A 2004-06-18   Bertrand Delacretaz <bdelacretaz@apache.org>
+sig       X CA57AD7C 2005-07-01   PGP Global Directory Verification Key
+sig 3       E41EDC7E 2004-10-30   Carsten Ziegeler <cziegeler@apache.org>
+sig 3       E2D774DF 2004-10-28   Sylvain Wallez <sylvain@apache.org>
+sig 3       7C200941 2004-10-18   Torsten Curdt <tcurdt@apache.org>
+sig 3       23CB7A2A 2004-08-19   David Crossley <crossley@apache.org>
+sig       X CA57AD7C 2005-07-14   PGP Global Directory Verification Key
+sig         5793498F 2005-07-20   Tim Ellison <tim@ellison.name>
+sig         8103A37E 2005-07-20   Andre Malo <nd@apache.org>
+sig         C4C57B42 2005-07-21   Marcus Crafter <crafterm@debian.org>
+sig         5C1C3AD7 2005-07-24   David Reid <mail@david-reid.com>
+sig         1CD4861F 2005-07-25   Eran Chinthaka <chinthaka@apache.org>
+sig         333E4E84 2005-07-25   Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig         EA1BA38D 2005-07-25   Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig         152924AF 2005-07-29   Sander Temme <sander@temme.net>
+sig 3       EC140B81 2005-07-20   Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3       EE65E321 2005-07-20   Martin Kraemer <martin@apache.org>
+sig 3       A99F75DD 2005-07-21   Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3       21D0A71B 2005-07-20   Dirk-Willem van Gulik <dirkx@asemantics.com>
+sig 3       3642CB4B 2005-07-20   Martin Kraemer <martin@apache.org>
+sig 3       2261D073 2005-07-20   Astrid Kessler (Kess) <kess@kess-net.de>
+sig 3       2C312D2F 2005-07-21   Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3       302DA568 2005-07-21   Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3       E04F9A89 2005-07-22   Roy T. Fielding <fielding@gbiv.com>
+sig 3       5F6B8B72 2005-07-22   Stefan Bodewig <bodewig@apache.org>
+sig 3       87315C31 2005-07-23   Raphaël Luta <raphael.luta@aptiwan.com>
+sig 3       F39B3750 2005-07-24   Colm MacCarthaigh <colm.maccarthaigh@heanet.ie>
+sig 3       40581837 2005-07-24   Nick Kew <nick@webthing.com>
+sig 3       9C85222B 2005-07-24   Henning Schmiedehausen <hps@intermeta.de>
+sig 3       9978AF86 2005-07-25   Christoph Probst <chris@netzpunkt.org>
+sig 3       2A623F72 2005-07-25   Christoph Probst <chris@netzpunkt.org>
+sig 3       F8EA2967 2005-07-26   Brian McCallister <brianm@apache.org>
+sig 3       C152431A 2005-07-27   Steve Loughran <stevel@apache.org>
+sig 3       CC78C893 2005-08-01   Rich Bowen <rbowen@rcbowen.com>
+sub  2048g/AC136A02 2004-06-18
+sig         015AFC8A 2004-06-18   Bertrand Delacretaz <bdelacretaz@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.4 (Darwin)
+
+mQGiBEDSjpsRBAC6qu/5vv5ETRaTEwrZI1gbepp2tNNBqIVfYEZlF8jnWhUk1sdm
++bvqNMPf1B+ZQqjmctLoa+OKVd4vQEgdxclUYCkjuk2iWRX/iRJ61Zm1myuaBfhN
+v0mRBduoSG+2+cIBq3ODQld/BPFotfL+giLdHF6SMjMl0BYcCOqZZGhhGwCg88wL
+wNpY/ZPBtiUXzozD0wCDs6MD/ApczG73dG9H3BCPmp7y41ZbYZHpxiS9Mz9mLJNk
+HMcx4iOzZnptX71UGG58nnBc+VDPooJdzzZywYhHhyz4uSrvMqS5DYquH5HEzMLE
+jKNf0EGay9SHbpbT808YJIKogLgUhuUXe/MrzOdhEEfj+c8Q0iLEmOnNYjFRvakV
+ei8gA/wKwnnQbQvgHyanZsus4WQRRRhbIZFM/qsmM4+McnI9TveDRYjoNwI5tbwY
+aKF+FS9XAbMTBfXZggdjlyYy7J8LZyfm/yyb7BBq6++Owpj3Y/6DPgg1jqJ9Lenc
+04uJATQiXNFS4k38eUtxWQ8lutc4W+3gy4M86mTFwfYVikRr7rQwQmVydHJhbmQg
+RGVsYWNyZXRheiA8YmRlbGFjcmV0YXpAY29kZWNvbnN1bHQuY2g+iF4EExECAB4F
+AkDSjpsCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQN/aP9QFa/Ip0DwCgyqeU
+b6ClVLmPOnsHeikXUeyuHOYAn2WW/Gq9kk5vOfJ2bv/lS5sH+lRgiQEiBBABAgAM
+BQJCxTKzBQMAEnUAAAoJEJcQuJvKV618ckwH/j9H7+w45cbGAkqkbwWLQMAzHng+
+9wgJdoITY9KR2j0c3Vr8M70rwB9HINxSR2j9DdNceS5qSzLZTH/gJqQ+EKb8B925
+mGI7s1K8BpGAR2ipZukqxIJdyNcT4UQ85YxDSwyMfCnQhdaK2Ic+Eziu8Hd32pMW
+bNhckxMux1eJst6ix0jka/yKXu2JJ/MsmJ/0S78DKw0Mf4vIL4YBH14n+hHoXaAk
+YCH4wdKOVvd+Nu5PGgQxVsrIOQMGc5w+/vBDgq3Q4rUs5g4v3zPDm9wDaGLiMwyn
+GY/pOqDx2nnWso35G74ALDRJ2mVdC2sk0CPfrhhQjLgDUSPAGI5cQyeNgG+IRgQT
+EQIABgUCQYNhrgAKCRATLknU5B7cfqtLAJ9P3jDLqH6q3er+ClAsNRaDNOnhsQCf
+Y05hAt5Y7oBb0RHW82wajc6GZGuIRgQTEQIABgUCQYEoJgAKCRDJtabs4td03+bs
+AJsHWq/6YVYrp64UsJgAN/oohtP1iACfXgL6CHe5RvWW3UuGtUsZCevkhoGIRgQT
+EQIABgUCQXObygAKCRAEYzpXfCAJQRSxAJ98Mk2gIBEcxdCt6XL1qhg2BHvJ9gCd
+Gii992d6EggkXgF096dxT1yCfaCIRgQTEQIABgUCQSQRSQAKCRDBOfFTI8t6Kl4A
+AJ4slc4BUEF636i0TWS9YKxrAA4mNQCfd3Mk8LSqOtC6y7HoF6AFvkoKA5qJASIE
+EAECAAwFAkLWuS4FAwASdQAACgkQlxC4m8pXrXxktwf+J7v3DG0t0zetgH8Ifm7c
+JD1O6aLKgHoqSLol+/XU39DHfkouFl5SifUhszzpVa5ek8kvfmY4KAjxYHYDrWXJ
+eWiDhmcrLNWWK5VqIuJqsdYugP3WQuS3GVeufqv/da9a7/1BZQP4l3Mi3HGuqApI
+It1ZoIqBX3mupESg/HTOFMhSvkHHpFwjUb4rLlHqBHCXoMoYe5I9JTF55mcJyDpj
+KasMO+2kTeVPEwYvbdpdnnElRucQRT+gbxOhiDLxvvUnV0pD4hgzUpiTHueOAOVE
+MAdloQbYYG2QaZJo67h7AMeZgnE275QHqDYZRJPhbyKLp3f9tlkZ6Dhx8E0YUgZp
+JohGBBARAgAGBQJC3ta4AAoJEEHqCaBXk0mPOgAAoLzhTcsB2EB77taLCBFl8Nhh
+cOrKAKCywO74xPLFEpe5b8osxreCHhLCdYhGBBARAgAGBQJC3tr9AAoJEMppOXSB
+A6N+gF0AoKBcgIUWC+2i6LezOPp6JJN7Wy6WAKCXTxLqNduBwpeUh1OIYf3mEAmJ
+fohGBBARAgAGBQJC333lAAoJEDlNL+PExXtCzBwAnjK5DG5LuANHdISaIRKXBuZG
+zI4pAJ9AOuX3bR5mHvqpKkapFrikOULDG4hGBBARAgAGBQJC44WjAAoJEMl8UJZc
+HDrXln0AoMJuj6pqvkjchV1iqCsCi3b4CGRqAKCoss+9L68xBcyR+dj6oXvQU5NJ
+D4hGBBARAgAGBQJC5HKyAAoJEIzjdrgc1IYfvegAnRD7Xr2DzpZmKbDrgW+ROPAE
+OoSbAJ9DJlWq9J6vSKprccCu9eZeVZxENIhGBBARAgAGBQJC5H1nAAoJEGEZai4z
+Pk6E4vAAoKNEr9XS4K0y6qTc7FHfhwNoG1l1AJ97ZJZFp1djyfwJGq5OQuPLzSoP
+B4hGBBARAgAGBQJC5JNXAAoJEASRNELqG6ON5UEAn2UgTiqDJbFcCW4tweKmBE37
+42TdAJ9+ur+rt7eCSeOVinE0IgPma7/0cIhGBBARAgAGBQJC6mQzAAoJELK+vEAV
+KSSv88QAnA114d+qT3DSiK5030OjwBSLfOzuAKD1ZpFkDjmfkgDnWPAU4tSJAAI1
+P4icBBMBAgAGBQJC3qyqAAoJEDGmPZbsFAuB7DED/AqX7JLVRmj2GnWEsBi1i7+a
+ZglkgxQhqCzraNzOivIEkZ6dtOTiHT466r57P7ezUrCMpJxvhlHVCUK5q/PioE55
+HLmS9JsVONfozOMArAhkpp1QdgWMTv6rvz7ssE2jX1gOllr4mt4WK3sow8TiRTKZ
+K7v1BVlTyg9+XELCwoKkiJwEEwECAAYFAkLeyAQACgkQN+P0X+5l4yGHTQQA6q55
+2r/LhhuFWJGgyw19UKs51q/Rm+fVXT8M3fuJBE4dE39Zkgo8J58134/fm+VNJ7dk
+J1xqF5jvTS6rCAM3L9MNRvt6YhKYxoH6YDcMkNJqs1zTzHM/EDKI3GRukG03vX/l
+L7UxtuvtV7RnlRS/dlhvG40dODQqok3fO4/C6QeInAQTAQIABgUCQt9pHwAKCRCa
+zTzAqZ913YDfA/wJapKu9EC6SnFdpuaLhOL3mogkGjTURib96y0Tf1yYObmJhcs5
+/lJjMT8cePR3uGeeiVrpdaMlsjBGYO30KwG7UCJYOw1oZ+ueqKN3Tk7/fLOiV/5j
+2RcGCFo0bISjJAMTG4h7RQVydIgYVg/5x8LCIvDYjgXg4dPKblCJyChUm4hGBBMR
+AgAGBQJC3rP7AAoJEP1viMYh0KcbRzQAoLXGj1B1Df/COcpjhVbkB/aWMUZCAJ9U
+4uCV91iNY79gUs3WQEkS8j7+5IhGBBMRAgAGBQJC3rs4AAoJEDLJ5M42QstLdNAA
+nAvT7s31lr6Md8T3nsrLPh6fPH+RAJwMZgmm/JRnoZIaUON6SNNlv1kboohGBBMR
+AgAGBQJC3tfbAAoJEO7R6jkiYdBzuIAAnj9z0TACmzHiWSbyqiIewJLW/wv9AJ47
+jRln1u9mvi9192cwqfF01jcLzohGBBMRAgAGBQJC32oRAAoJEN26ZLosMS0v9RAA
+n2h23ZqXNLsOgZUCWfgm5MTy3HcyAKCIjCEVisaSHtA2sO6cGJSV9mANEohGBBMR
+AgAGBQJC32qpAAoJEFCOrsUwLaVojyYAn0XkNbiULXmEaa/wZsefVW7ghEOxAJ9d
+Hdk8IKfbSusfh2KF8MozvXqyqYhGBBMRAgAGBQJC4O5HAAoJEFuWgBDgT5qJhz0A
+mgNmDpUgiOOxbN7yevi8gFZ0HhDsAJ0VTF10Ci/DoLGa5dddrwIejazAbIhGBBMR
+AgAGBQJC4TZ5AAoJEKIRWuFfa4tyHXoAoItZqmv8WICsMwqtF0QOku2qDgmsAKDI
+qM50egV4ibXB0ds5xhIvVHHAh4hGBBMRAgAGBQJC4lyJAAoJEG2YjReHMVwxqXkA
+nRQuML7MHsp5MtEgsR9Vahi4JBukAKDtrfB6Ev9GoSpqlj98Sjfr/dasTYhFBBMR
+AgAGBQJC42T0AAoJEHXKoqPzmzdQE/IAl3tHNQ4ginBdWovyH/WNxjSD7NgAnRbR
+KTISG6pO5eNOX6DU98/qQyzWiEYEExECAAYFAkLjtIEACgkQbQvHOkBYGDcnZQCf
+Wg7cSWMBOlu+FLW2Q20lqdZCdAkAn3e0tTiyn0gokU7/wyfHWGju4upqiEYEExEC
+AAYFAkLj7aEACgkQMoZOQZyFIivS2gCcCIah919Iy+ASvjk5EWks8jOksykAmgP5
+drcHNsRsPUfYnrSUzD1zVmCViEYEExECAAYFAkLlEMIACgkQUnkvr5l4r4aXkACe
+KCpZspIEttLdnatEIypxfhX0YIMAn2EI3RrbgHmXHkhaIUFyVhjz7eEyiEYEExEC
+AAYFAkLlEbAACgkQa3OhBipiP3IZTgCg6xsI8+ftGOokb8y+3mCLc9lMSPQAn0A6
+N49Kci+/FiLY0pOVFysbuRu4iEYEExECAAYFAkLmmXYACgkQaOuMdvjqKWfXGACe
+Ihm4NjT3xPTyyH7aDPmBObVozt0AnAgRnpnVmyCuUnGXjtcytZ0eDX/siEYEExEC
+AAYFAkLnYXYACgkQbpR1lMFSQxoQKQCeLYJR57+5bDPECNN4oLKLUZ8WeYoAoJCu
+P4o/4roo7fTc9X7j+sVX1BQdiEYEExECAAYFAkLul5sACgkQXP03+sx4yJN7NgCf
+XJDAjCStOu3mJ9q50+GtkhytGXUAoPzkoZFGC8QjBxOB5t+WmTXZuW/xtCxCZXJ0
+cmFuZCBEZWxhY3JldGF6IDxiZGVsYWNyZXRhekBhcGFjaGUub3JnPoheBBMRAgAe
+BQJA0o/yAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEDf2j/UBWvyKoVIAoLZI
+jDpTDUQb99MWGAIhd5hKbwlGAJ9QG+DT2qEF1vtgOHucWg1ljhPpUYkBIgQQAQIA
+DAUCQsUyswUDABJ1AAAKCRCXELibyletfDA1CACcdUjrLC24oOo9mCPcgp5z85mQ
+FsNdeYGiQDpvss8viILtaBSi5T/eyrnFQCLe267s2+f/Blinz5zYZCKvO0KCs/s2
+SqXytCqTV4KSc/0Efo7th7PXaB/VTxUP31hG4jU9i+6NYXosavieQiWnn4ghsl9u
+gwXTzu1LbGdKbAXmbCJex9uKNdXdcUni89je4oOiUcyh+9BaMl70PLjl1dAyE6yC
+CYhXrHW+n6Yye2Aw+sTzMMjLIphnJLAdsDKB9iIyUWzJCllwyWOJZk2paKPPgCEK
+IaBVsPwoDy3Dbs8X88Kn993B35VwFf0qGXLWh6kRNatLsEtGcE9PkUFjdBcqiEYE
+ExECAAYFAkGDYawACgkQEy5J1OQe3H4voQCePL2c6muDRVZ98rTaVLGEiwqVgnYA
+n2cPs1VLsS/oVqOtCwCUgydKHeVviEYEExECAAYFAkGBKCMACgkQybWm7OLXdN9c
+ugCgy89zOXdMOhVncxKRbt1YqeiXikMAoKk5BioFVyFxv6zGpF5+KYVl9ZkGiEYE
+ExECAAYFAkFzm7wACgkQBGM6V3wgCUH68gCgmAEnlUseKreWdrEoA1INqjoc0U0A
+njEXpxW1cEW/Hord0MZjY09GUQ1niEYEExECAAYFAkEkEZoACgkQwTnxUyPLeipG
+2gCdHKKBCHqONngx3Bpycj/XZ8JRH4IAniMz1bPFDFLrPTtGQcB7GJSeeUqliQEi
+BBABAgAMBQJC1rkuBQMAEnUAAAoJEJcQuJvKV618CbAH/3RmNilwoXS+Q6su8Wj2
+X9u26HhqzSecHhiY5rRGaQewe69I4VoCCHVLuWUMAF2IIawm03ka59YbU+rpIXS4
+f3vmAZVfGIo2vbDfufyFjPbQUHfekR/GnJL1xEHAfAwWp/jpnniWjsgRr6eAwlZN
+UNCzPyXPikuktjZBZ2JONAae/vuXwP0zkdEtc4WCP1BzMmU8athZ4hZxzp+VtC1g
+57jluoS4iw0vEIgXRgrcm3fLE8OArzhPac5o9XK1dTx40wHL+U3fhyvYuJ2FrOWT
++BO0UP7e1wUI6+ITxoCTZHxW8FE+RUtmPigtMKNu3cowEftVgqfSQnZv+YwhRsgj
+3HeIRgQQEQIABgUCQt7WrwAKCRBB6gmgV5NJj0w1AKCKKt5D8mxvkCobaj+ZyPgN
+/YcecwCeIQeJ6tSp5G9MBgUO7upvG1BzMaWIRgQQEQIABgUCQt7a/QAKCRDKaTl0
+gQOjfraJAJ4sJyjcjMnMr9n4+ZJY64a2j+tdBwCggw0NTw3PN01CRM6hXQoaLGZb
+mmmIRgQQEQIABgUCQt994gAKCRA5TS/jxMV7QknsAJ9ylXueE5pHqVP5UPGEWIVk
+P74IBgCeJcsKsjkfZq6uVP/gozUCgjf2B5eIRgQQEQIABgUCQt+SugAKCRABBWa8
+5BNjko0BAKCQUONymYbUGYWDLxId5b3NXB5QrgCaAuW0RWV6oauWNtRrvoucRy9Z
+/syIRgQQEQIABgUCQuOFngAKCRDJfFCWXBw614hNAJ4qp8uDW7ESMQRPfqSruu4d
+3I5tcQCgxfQWli4MAf0G0ZEjNiEkeL2AQgWIRgQQEQIABgUCQuRypgAKCRCM43a4
+HNSGH7jxAJ45jrVG9EiDuryEdkW/1X16vsY61wCgopPFmYKmCm4k2lZy5hyAojIL
+uemIRgQQEQIABgUCQuR9WAAKCRBhGWouMz5OhDjEAKCbyBQG0FGJjMTUqCeEaXGs
+rlkMoACfVLnLYLICywWclOPGb9xCTTDQnkuIRgQQEQIABgUCQuSTVAAKCRAEkTRC
+6hujjWwLAKCClSiaCm/rsCoFSMG9HPnElkWNqwCgpUqniJ+Q587c/ee2MJMfP9Rj
+2ZeIRgQQEQIABgUCQupkLwAKCRCyvrxAFSkkr2r+AJ4pBWxHy+8mERcd2w3WpHD9
+aV2oRACg0MhVy92t2ElFxPrLeTs0anzkNv2IRgQSEQIABgUCQt6xAAAKCRCLlilD
+/CQ/PImUAKChHoZ3OostKM+vXf4HzC3EobFkyQCgjw+gHlrMtOZ7/jyNEuBKt6ao
+XQiInAQTAQIABgUCQt6spwAKCRAxpj2W7BQLgTCaA/99LRrKrSFFlRFJaPYms9Li
+Jn+FDYLan3Lj6gA04cCXC3nr0yUEYVP0nex08yge5NEkbV4xOV3sDCrMjjSFYTRk
+CjvhUm9KiqrHl9MSFbflaoSj4hLDFvL3GrlycCnk4p9MnHkdE8BfRxuSqts9aUSx
+uKHIkNwI4jjGo58Ctc07BYicBBMBAgAGBQJC3sf+AAoJEDfj9F/uZeMhIGQEAOh7
+dNsTwWuMPGzK+KyAD97Ah3C1eQwgnifuI7LTt46t1iDHC//EmWY6Fl6wmrPDjUXl
+n5JozJEOMzTVdc1bHaaGJh1PlmNGROIpGWf6AykGiIM6AiCN/6Oforfh1oGf1hro
+blYZX1ykJmcnJA5eX9n80dx1/M75PgKvlH28wV5fiJwEEwECAAYFAkLfaRcACgkQ
+ms08wKmfdd1djgP/UQ29LZrKtFY51K0Kb4s4x9V2JU3eolLbVaeW4yvjENBy0pqs
+9WAe4fTCzPRcA82JzXdahbofQ6G+cuV1IARtaL6qQA/NLriv0u2s2W0KF8kSvu5W
+DJcYs0sClls3jC0S+GGvgM+DOiDWV3o8uNsMewTxSKziJwEG9haQ5wjt6LWIRgQT
+EQIABgUCQt6z+gAKCRD9b4jGIdCnG1wcAJ9mLJiUi9BKxWwEpImpYEttV44kpQCg
++VeKf+9Mmb03YV5iwqmxLPi+EyuIRgQTEQIABgUCQt67MgAKCRAyyeTONkLLS0Q1
+AJ4lH6xITtr//6aWwIAaShLB6ere8QCgziP6JRCDHIv37sqFuCXl24+roRSIRgQT
+EQIABgUCQt7X2AAKCRDu0eo5ImHQcy7YAJ9Y4wqukDN6g3o3trqgxk/LkD/EeACf
+aCEsB7OwTw4nTbYiYlyj7Q6xcX+IRgQTEQIABgUCQt9qCgAKCRDdumS6LDEtL/fk
+AJ9i3H2oakGBDrEWQTaYuQcYK7nddwCeKLYEhCx+TrXKFKjLDwUxJMrVYkGIRgQT
+EQIABgUCQt9qowAKCRBQjq7FMC2laB//AKCCrmQysq3yGjonfumvnQQb8cS/RwCf
+eGsAFVbvGJkyNwcst3o9yF0sVjqIRgQTEQIABgUCQuDuQwAKCRBbloAQ4E+aiWn8
+AJsEK2PGchbc0YD6orPtNYC/34kUgACeKFFFAHOFRXStc5KZLmJBSbT8OACIRgQT
+EQIABgUCQuE2cwAKCRCiEVrhX2uLco1lAKC72f8hMpjsNUE85l0vlSP+ROD32wCd
+G66V3/14h7LMoqTgkYCh7L+PjmCIRgQTEQIABgUCQuJciQAKCRBtmI0XhzFcMU9N
+AKCoHx9H4WPuUkaG3nBWOX5sfqD49gCfcqT97X3EUVi/6wB/ypFEDbgSN7iIRgQT
+EQIABgUCQuNk8wAKCRB1yqKj85s3UFUiAJ41Jh3QzVaoB7kZLbfguRdu0LWolACe
+O7vrJoYM2RRCnuvCYcnvoO8H3Z6IRgQTEQIABgUCQuO0fQAKCRBtC8c6QFgYNzPv
+AJ0XgXiLYp9yQgnH+CzBfEhESMoD/QCbB+sSYX4sAlHqsP4ZDlo09zxSjn2IRgQT
+EQIABgUCQuPtnQAKCRAyhk5BnIUiK7KXAJsHwl80HSVOBabaxUJIiOueq0APCwCb
+BjqwtPDB7LsJmSMvI+VZD05pqjuIRgQTEQIABgUCQuUQwgAKCRBSeS+vmXivhgSo
+AKDWgoqYC+uVRHriBrOyoogiolgwXQCg5RNcb9RBU6K2nz3fVTXH+jqbvO6IRgQT
+EQIABgUCQuURsAAKCRBrc6EGKmI/co9aAKC3ye4ZnztAud5KP0HjLUqePJtlEgCf
+WSjOL3180YiroT0w18UYpVIvzFKIRgQTEQIABgUCQuaZdgAKCRBo64x2+OopZ+q4
+AJ9JYfPM/UjftfzMUgGtPvExe+yPGACePJbwo67cI8FG9dzQaK2VgWAo3WaIRgQT
+EQIABgUCQudhcwAKCRBulHWUwVJDGtgWAKCzyBiSi8UPv0qarURcDvbrv3/g1ACe
+M+nakste8unr4BsbOnB8wPsEGUOIRgQTEQIABgUCQu6XmAAKCRBc/Tf6zHjIk/fp
+AKC0jvC+7cXMhTomdHPRbDITuCfS1gCgj7zDVMw9Y6g2woQ2NM+scLkt6iO5Ag0E
+QNKOqxAIAPD9YvaFIx80FX53jYFgN0E7lsG35nejioD0exR5Jj6WQTgpjW8uuZQf
+UrdWkMbafYwZtk48jvCQ2ycy9Stk2F0SOohNZYdm7aAp4O7+o6/JV8iZGLVQeCGX
+vZeZp7JUkWte2rHfvGiUqmOL8/r1T/XJ4Nkl6cVgGhI68Lo8rj2KsvWlLWPy/XkD
+bgPpynLxZYsAhyYX1KjGGineyFKM+Xz+Fz5IuZLi729FU7wXKu2qpq/UjMY4ZFCN
+Io2hhpO9rSnYBymq7AHJefwWYqEbcYgJTPFS8/rcnMXMW9dnvki29wRPhq4Oikqi
+tz7oR57H++6xcBBbrr7WWmyCGKu5emMAAwYH/R+Ozt7WlG/VRZolew+o+2I3MZGt
+qm7buzSHRl8BpWy7bOs6As6DsBWj28PSHqN1LHMOY55m/sJGmV5M+VKwozm7B2lt
+Ff65tl1b43YIp7vCAwpZsCtavIn2GOKHOu9T65vwdZrNUappv3blRc0kp3FCuWLI
+gtkCdvX/nCVOT626vi2h4qR6FT4OfX5t4cTM2tZrW3hciCMiEgT2sBAA+LbtEgEb
+AHLzRCpALq+gq/wWdQtjD5HOdZCVQX9BBzvu26aCZg3hvWWd5Z3yqNXIk512zrwD
+u8/wDtIuBuLST8Ra6NOuYpxk9RjMMRFsmPn2B4lZXO0QgdlgRmt+OxSnuT6ISQQY
+EQIACQUCQNKOqwIbDAAKCRA39o/1AVr8ikVrAKDMUsQGX1u8ZLsuUs6d8wsFdFwq
+uACcDJAVc3KuTVrTWNn0Bdptwn2QKvI=
+=K6aG
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/non-releases/trunk_before_flattening/LICENSE.txt b/non-releases/trunk_before_flattening/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/NOTICE.txt b/non-releases/trunk_before_flattening/NOTICE.txt
new file mode 100644
index 0000000..3f59805
--- /dev/null
+++ b/non-releases/trunk_before_flattening/NOTICE.txt
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/non-releases/trunk_before_flattening/README.blocksmode b/non-releases/trunk_before_flattening/README.blocksmode
new file mode 100644
index 0000000..bc88029
--- /dev/null
+++ b/non-releases/trunk_before_flattening/README.blocksmode
@@ -0,0 +1,17 @@
+Info about the Cocoon "blocks mode".
+
+From http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=113645993019371&w=2
+
+The block mode is currently in a state of flux. You could use Cocoon in blocks 
+mode a month ago by running "./cocoon.sh blocks". That worked by making the root 
+Processor pluggable in the CocoonServlet and using the BlocksManager instead 
+of Cocoon.
+
+To make that possible, I had to have a rather complicated initalization sequence 
+for the blocks. After the NG discussions I decided to simplify the architecture 
+by refactoring the block architecture so that the BlocksManager becomes a top 
+level servlet instead. And so that the ServiceManager and Avalon context 
+creation happen locally at the block level instead of globaly.
+
+This is ongoing work and currently the blockmode is only usable from the test 
+cases.
diff --git a/non-releases/trunk_before_flattening/README.osgi b/non-releases/trunk_before_flattening/README.osgi
new file mode 100644
index 0000000..ccef362
--- /dev/null
+++ b/non-releases/trunk_before_flattening/README.osgi
@@ -0,0 +1,47 @@
+#  Copyright 1999-2005 The Apache Software Foundation

+#

+#  Licensed 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

+

+Cocoon can be run based on OSGi. You have to build Cocoon, start the OSGI 

+framework and finally you should be able to access Cocoon from within your 

+favorite webbrowser.

+

+*****************************************************************************

+This is experimental, see http://wiki.apache.org/cocoon/osgi for more info.

+*****************************************************************************

+

+To build and start under OSGI do:

+

+  build osgi

+  cocoon osgi or ./cocoon.sh osgi

+  http://localhost:8888 and http://localhost:8888/samples/

+

+Note that once the (Knopflerfish) OSGI framework starts, you can press

+enter on the console to access the framework command line:

+

+  ./cocoon.sh osgi

+  ...

+  Knopflerfish OSGi framework, version 3.3.6

+  ...

+  Started: file:build/osgi/org.apache.cocoon_servlet_1.0.0.jar (id#10)

+

+now type enter to get the prompt:

+

+  > help

+  Available command groups (type 'enter' to enter a group):

+  session - Session commands built into the console

+  logconfig - Configuration commands for the log.

+  ...

+

+To stop the framework use the "shutdown" command.

+

diff --git a/non-releases/trunk_before_flattening/README.txt b/non-releases/trunk_before_flattening/README.txt
new file mode 100644
index 0000000..51667c5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/README.txt
@@ -0,0 +1,90 @@
+
+                  A  P  A  C  H  E     C  O  C  O  O  N
+
+                                @version@
+  
+
+  What is it?
+  -----------
+
+  Apache Cocoon is a web development framework built around the concepts of
+  separation of concerns (making sure people can interact and collaborate on a
+  project, without stepping on each other toes) and component-based web
+  development.
+
+  Cocoon implements these concepts around the notion of 'component pipelines',
+  each component on the pipeline specializing on a particular operation. This
+  makes it possible to use a Lego(tm)-like approach in building web solutions,
+  hooking together components into pipelines without any required programming.
+
+  Cocoon is "web glue for your web application development needs". It is a glue
+  that keeps concerns separate and allows parallel evolution of all aspects of
+  a web application, improving development pace and reducing the chance of
+  conflicts.
+
+
+
+
+  Requirements
+  ------------
+
+  Cocoon has been designed to coexist and interoperate side-by-side with your
+  existing J2EE solutions or to give them new functionality without requiring
+  any change in the existing infrastructure.
+
+  Cocoon is implemented both as a Java servlet and a Java command line
+  application. The following requirements exist for installing it:
+
+   o  A Java 1.3 or later compatible virtual machine for your operating system.
+
+   o  A Servlet API 2.3 compatible Servlet Engine or J2EE Application Server. 
+      [not required for command line operation]
+
+
+
+
+  Installation Instructions and Documentation
+  -------------------------------------------
+
+  Read the INSTALL.txt file in this directory for the installation instructions.
+
+  The documentation available as of the date of this release is included in this
+  directory. Read the INSTALL.txt for more information.
+
+  If you are updating from a previous release of Cocoon, make sure
+  that you read the installation instructions on updating first.
+  
+  Look for the most updated documentation on the Apache Cocoon web site
+  (http://cocoon.apache.org/).
+
+
+
+
+  Licensing and legal issues
+  --------------------------
+
+  Cocoon is licensed under the Apache Software License, a license of the BSD
+  family, and contains software which is compatible with the BSD licensing style.
+
+  For more information, please read the LICENSE files in the /legal directory.
+
+
+
+
+  Credits
+  -------
+
+  For more information on credits and due reference to included software, please
+  read the CREDITS.txt file in this directory.
+
+
+
+  Thanks for using Apache Cocoon.
+
+
+
+
+
+                                           The Apache Cocoon Project
+                                           http://cocoon.apache.org/
+
diff --git a/non-releases/trunk_before_flattening/TO-SYNC-FROM-BRANCH.txt b/non-releases/trunk_before_flattening/TO-SYNC-FROM-BRANCH.txt
new file mode 100644
index 0000000..2c37a84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/TO-SYNC-FROM-BRANCH.txt
@@ -0,0 +1,20 @@
+--------------------------------------------------------------------------------
+Use this file to list stuff that must be synced from BRANCH_2_1_X to the trunk,
+or the opposite.
+
+See http://marc.theaimsgroup.com/?t=112322817300004&r=1&w=2
+
+There are sometimes good reasons to keep some code unsynchronized for some time,
+but we don't want to forget about it, so it can be listed here.
+--------------------------------------------------------------------------------
+
+Slop block: @doktor comments will be added in trunk only as part of the refdoc
+GSoC project. We're still experimenting with this and it might still change,
+so there's no hurry to sync, or maybe we won't sync at all.
+
+Xsltal block is in branch only for now, it can wait for more examples before
+"porting" to trunk.
+
+HtmlUnit test framework is in branch only.
+
+Tour block has been updated for 2.1.8, need to be synced and tested in trunk.
diff --git a/non-releases/trunk_before_flattening/announcement.xml b/non-releases/trunk_before_flattening/announcement.xml
new file mode 100644
index 0000000..cc93894
--- /dev/null
+++ b/non-releases/trunk_before_flattening/announcement.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--
+  Release Announcement Template
+  CVS $Id: announcement.xml,v 1.5 2004/03/08 06:07:14 antonio Exp $
+-->
+
+<announcement site="http://cocoon.apache.org">
+  <project>Apache Cocoon @version@</project>
+  <abstract>
+   The Apache Cocoon Community is proud to announce the new release
+   of Apache Cocoon.
+  </abstract>
+  <body>
+  
+<p>
+  Apache Cocoon is a web development framework built around the concept
+  of separation of concerns (that is: allowing people to do their job
+  without having to step on each other toes) and component-oriented web 
+  RAD.
+</p>
+
+<p>
+  Cocoon implements these concepts around the notion of 'component
+  pipelines' modelled after the 'process chain' concept where each 
+  worker specializes on a particular operation. This makes it possible
+  to use a Lego(tm)-like approach in building web solutions where
+  these components can be hooked together into pipelines without
+  requiring further programming.
+</p>
+
+<p>
+  We like to think at Cocoon as "web glue" for your web application
+  development needs. But most important, a glue that can keep 
+  concerns separate and allow parallel evolution of the two sides, 
+  improving development pace and reducing the chance of conflicts.    
+</p>
+
+  </body>
+  <changes version="@version@" file="status.xml"/>
+</announcement>
+
diff --git a/non-releases/trunk_before_flattening/blocks.properties b/non-releases/trunk_before_flattening/blocks.properties
new file mode 100644
index 0000000..4859aec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/blocks.properties
@@ -0,0 +1,191 @@
+
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+
+#------------------------------------------------------------------------------#
+#                             Cocoon Blocks                                    #
+#------------------------------------------------------------------------------#
+
+# Remove blocks from your cocoon distribution by setting the corresponding
+# include property to true or false. The blocks are included by default, i.e. if
+# no property was set.
+
+# NOTE: Don't modify this file directly but make a copy named
+# 'local.blocks.properties' and modify that. The build system will first load
+# 'local.blocks.properties' and properties are immutable in Ant.
+
+# For most cases it is enough that you exclude all blocks and include only those
+# few you want, example:
+# exclude.all.blocks=true
+# include.block.forms=true
+# include.block.template=true
+
+# The opposite is also allowed:
+# include.all.blocks=true
+# exclude.block.scratchpad=true
+
+# If there is a conflict on the same level of granularity:
+# include.block.template=true vs. exclude.block.template=true, 
+# include.all.blocks=true vs. exclude.all.blocks=true
+# it is always resolved in favour of include.* properties. 
+
+# NOTE: "[dependency]" indicates blocks that are required by other blocks.
+# Disabling batik, for example, will result in a RuntimeException when using
+# fop. Dependencies only needed for the block's samples are marked explicitely.
+# This latter information was introduced only short time ago, so do not expect
+# it to be complete.
+
+# NOTE: (to Cocoon committers): blocks.properties is generated from gump.xml
+# using "build generate-blocks.properties". Any changes to blocks definitions
+# must be made in gump.xml, not here.
+
+# All blocks -------------------------------------------------------------------
+
+# Use this property to exclude all blocks at once
+# exclude.all.blocks=true
+
+# Use this property to include all blocks at once
+# include.all.blocks=true
+
+
+# Stable blocks ----------------------------------------------------------------
+
+# Stable blocks are those that can be considered ready for production and
+# will contain components and API that will remain stable and where
+# developers are committed to back compatibility. In short, stuff that you
+# can depend on.
+
+#-----[dependency]: "authentication-fw" depends on "session-fw".
+#-----[dependency]: "authentication-fw" is needed by "portal", "portal-sample".
+#include.block.authentication-fw=false
+#-----[dependency]: "batik" is needed by "fop", "scratchpad", "tour".
+#include.block.batik=false
+#include.block.bsf=false
+#-----[dependency]: "chaperon" depends on "template" (for samples).
+#include.block.chaperon=false
+#include.block.core-samples-additional=false
+#-----[dependency]: "core-samples-main" depends on "xsp" (for samples).
+#include.block.core-samples-main=false
+#-----[dependency]: "databases" depends on "hsqldb" (for samples).
+#-----[dependency]: "databases" is needed by "jms", "ojb", "petstore", "repository", "xmldb", "xsp".
+#include.block.databases=false
+#-----[dependency]: "fop" depends on "batik".
+#-----[dependency]: "fop" is needed by "tour".
+#include.block.fop=false
+#-----[dependency]: "hsqldb" is needed by "databases", "jms", "ojb", "petstore".
+#include.block.hsqldb=false
+#include.block.html=false
+#-----[dependency]: "itext" depends on "xsp" (for samples).
+#include.block.itext=false
+#include.block.jfor=false
+#include.block.jsp=false
+#include.block.linkrewriter=false
+#-----[dependency]: "lucene" depends on "template" (for samples).
+#-----[dependency]: "lucene" is needed by "querybean".
+#include.block.lucene=false
+#include.block.midi=false
+#include.block.naming=false
+#-----[dependency]: "ojb" depends on "databases" (for samples), "forms" (for samples), "hsqldb" (for samples).
+#-----[dependency]: "ojb" is needed by "portal-sample", "querybean".
+#include.block.ojb=false
+#include.block.paranoid=false
+#include.block.poi=false
+#-----[dependency]: "portal" depends on "ajax", "authentication-fw", "cron", "forms", "session-fw".
+#-----[dependency]: "portal" is needed by "faces", "portal-sample".
+#include.block.portal=false
+#-----[dependency]: "portal-sample" depends on "authentication-fw", "cron", "forms", "ojb", "portal", "session-fw", "template" (for samples).
+#include.block.portal-sample=false
+#include.block.profiler=false
+#-----[dependency]: "python" depends on "xsp".
+#include.block.python=false
+#-----[dependency]: "session-fw" is needed by "authentication-fw", "portal", "portal-sample", "xsp".
+#include.block.session-fw=false
+#-----[dependency]: "velocity" is needed by "petstore", "scratchpad".
+#include.block.velocity=false
+#include.block.web3=false
+#-----[dependency]: "xmldb" depends on "databases".
+#include.block.xmldb=false
+#-----[dependency]: "xsp" depends on "databases", "session-fw".
+#-----[dependency]: "xsp" is needed by "core-samples-main", "itext", "mail", "python", "scratchpad".
+#include.block.xsp=false
+
+# Unstable blocks --------------------------------------------------------------
+
+# Unstable blocks are currently under development and do not guarantee that the
+# contracts they expose (API, xml schema, properties, behavior) will remain
+# constant in time. Developers are not committed to back-compatibility just yet.
+# This doesn't necessarily mean the blocks implementation is unstable or
+# the code can't be trusted for production, but use with care and watch
+# its development as things might change over time before they are marked
+# stable.
+
+#-----[dependency]: "ajax" is needed by "forms", "portal".
+#include.block.ajax=false
+#-----[dependency]: "apples" depends on "forms" (for samples).
+#include.block.apples=false
+#-----[dependency]: "asciiart" is needed by "mail".
+#include.block.asciiart=false
+#-----[dependency]: "axis" is needed by "scratchpad".
+#include.block.axis=false
+#include.block.captcha=false
+#-----[dependency]: "cron" depends on "template" (for samples).
+#-----[dependency]: "cron" is needed by "jms", "portal", "portal-sample", "scratchpad".
+#include.block.cron=false
+#include.block.deli=false
+#-----[dependency]: "eventcache" depends on "jms", "template" (for samples).
+#-----[dependency]: "eventcache" is needed by "repository".
+#include.block.eventcache=false
+#-----[dependency]: "faces" depends on "portal", "taglib".
+#-----[dependency]: "faces" is needed by "scratchpad".
+#include.block.faces=false
+#-----[dependency]: "forms" depends on "ajax", "template".
+#-----[dependency]: "forms" is needed by "apples", "javaflow", "ojb", "petstore", "portal", "portal-sample", "querybean", "tour".
+#include.block.forms=false
+#-----[dependency]: "javaflow" depends on "forms", "template" (for samples).
+#-----[dependency]: "javaflow" is needed by "scratchpad".
+#include.block.javaflow=false
+#include.block.jcr=false
+#-----[dependency]: "jms" depends on "cron", "databases" (for samples), "hsqldb" (for samples).
+#-----[dependency]: "jms" is needed by "eventcache", "slide".
+#include.block.jms=false
+#-----[dependency]: "mail" depends on "asciiart" (for samples), "xsp" (for samples).
+#include.block.mail=false
+#-----[dependency]: "petstore" depends on "databases", "forms", "hsqldb", "template", "velocity".
+#include.block.petstore=false
+#include.block.proxy=false
+#include.block.qdox=false
+#-----[dependency]: "querybean" depends on "forms" (for samples), "lucene", "ojb", "template" (for samples).
+#include.block.querybean=false
+#-----[dependency]: "repository" depends on "databases" (for samples), "eventcache".
+#-----[dependency]: "repository" is needed by "scratchpad", "slide", "webdav".
+#include.block.repository=false
+#-----[dependency]: "scratchpad" depends on "axis" (for samples), "batik" (for samples), "cron", "faces" (for samples), "javaflow", "repository", "template" (for samples), "velocity" (for samples), "xsp".
+#include.block.scratchpad=false
+#include.block.serializers=false
+#-----[dependency]: "slide" depends on "jms", "repository", "template" (for samples).
+#include.block.slide=false
+#-----[dependency]: "slop" is needed by "tour".
+#include.block.slop=false
+#include.block.spring-app=false
+#include.block.stx=false
+#-----[dependency]: "taglib" is needed by "faces".
+#include.block.taglib=false
+#-----[dependency]: "template" is needed by "chaperon", "cron", "eventcache", "forms", "javaflow", "lucene", "petstore", "portal-sample", "querybean", "scratchpad", "slide", "tour", "webdav".
+#include.block.template=false
+#-----[dependency]: "tour" depends on "batik", "fop", "forms", "slop", "template".
+#include.block.tour=false
+#include.block.validation=false
+#-----[dependency]: "webdav" depends on "repository", "template" (for samples).
+#include.block.webdav=false
diff --git a/non-releases/trunk_before_flattening/build.bat b/non-releases/trunk_before_flattening/build.bat
new file mode 100644
index 0000000..a5b8b22
--- /dev/null
+++ b/non-releases/trunk_before_flattening/build.bat
@@ -0,0 +1,39 @@
+@echo off
+rem  Copyright 1999-2004 The Apache Software Foundation
+rem
+rem  Licensed under the Apache License, Version 2.0 (the "License");
+rem  you may not use this file except in compliance with the License.
+rem  You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem  Unless required by applicable law or agreed to in writing, software
+rem  distributed under the License is distributed on an "AS IS" BASIS,
+rem  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem  See the License for the specific language governing permissions and
+rem  limitations under the License.
+rem
+rem ----------------------------------------------------------------------------
+rem build.bat - Win32 Build Script for Apache Cocoon
+rem
+rem $Id$
+rem ----------------------------------------------------------------------------
+
+rem ----- Ignore system CLASSPATH variable
+set OLD_CLASSPATH=%CLASSPATH%
+set CLASSPATH=
+for %%i in (lib\endorsed\*.jar) do call tools\bin\appendcp.bat %%i
+
+rem ----- Use Ant shipped with Cocoon. Ignore installed in the system Ant
+set OLD_ANT_HOME=%ANT_HOME%
+set ANT_HOME=tools
+
+call %ANT_HOME%\bin\ant -Djava.endorsed.dirs=lib\endorsed -logger org.apache.tools.ant.NoBannerLogger -emacs %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+rem ----- Restore ANT_HOME and ANT_OPTS
+set ANT_HOME=%OLD_ANT_HOME%
+set OLD_ANT_HOME=
+
+rem ----- Restore CLASSPATH
+set CLASSPATH=%OLD_CLASSPATH%
+set OLD_CLASSPATH=
diff --git a/non-releases/trunk_before_flattening/build.properties b/non-releases/trunk_before_flattening/build.properties
new file mode 100644
index 0000000..b793830
--- /dev/null
+++ b/non-releases/trunk_before_flattening/build.properties
@@ -0,0 +1,186 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+#----------------------------------------------
+#  Cocoon Build Properties
+#----------------------------------------------
+
+# NOTE: don't modify this file directly but copy the properties you need
+# to modify over to a file named 'local.build.properties' and modify that. 
+# The build system will override these properties with the ones in the 
+# 'local.build.properties' file.
+
+# ---- Webapp ------------------------------------------------------------------
+
+#exclude.webapp.samples=true
+#exclude.webapp.test-suite=true
+
+# ---- Build Exclusions --------------------------------------------------------
+
+#exclude.deprecated=true
+#exclude.javadocs=true
+# Include Java source code into the binary jar files
+#include.sources-in-jars=true
+# Include Java source code into separate, source only jar files
+#include.sources-jars=true
+
+# ---- Configuration -----------------------------------------------------------
+
+#include.driver.oracle=true
+#include.driver.postgre=true
+#include.driver.odbc=true
+#config.allow-reloads=true
+#config.enable-uploads=true
+
+# ---- Validation --------------------------------------------------------------
+
+#exclude.validate.config=true
+#exclude.validate.jars=true
+
+# ---- Anteater ----------------------------------------------------------------
+
+anteater.home = /default-from-build.properties/anteater-0.9.16
+anteater.target.host = localhost
+anteater.target.port = 8888
+anteater.target.base.path = /
+anteater.option.haltonerror = true
+
+# disable some long-running tests by default
+# anteater.test.bug26186InternalRequestMemoryLeak.enabled = true
+
+# ---- JUnit -------------------------------------------------------------------
+
+junit.test.debugport=8000
+#junit.testcase=org.apache.cocoon.util.test.NetUtilsTestCase
+junit.test.loglevel=1
+
+# Optionally enable remote debugging when running the JUnit tests.
+# Uncomment one of the following lines only, the property must be present even if empty.
+# Note that setting suspend=y might cause the JVM to stop several times when running the
+# tests, as the build forks a new JVM at several points.
+# This is most useful together with the junit.test.include.* properties below
+#junit.test.jvmargs=-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n
+junit.test.jvmargs=
+
+# Define which JUnit tests to run - useful to run a subset of tests
+junit.test.include.1=**/*TestCase.class
+junit.test.include.2=**/*Test.class
+
+# ---- IDE ---------------------------------------------------------------------
+
+ide.eclipse.outputdir=${build.root}/eclipse/classes
+ide.eclipse.export.libs=false
+
+# ---- Build -------------------------------------------------------------------
+
+build.root=build
+build=${build.root}/${name}
+build.dest=${build}/classes
+build.mocks=${build}/mocks
+build.test=${build}/test
+build.test.output=${build.test}/output
+build.test.report=${build.test}/report
+build.javadocs=${build}/javadocs
+build.context=${build}/documentation
+build.blocks=${build}/blocks
+build.deprecated=${build}/deprecated
+build.samples=${build}/samples
+build.temp=${build}/temp
+build.mounttable=../../mount-table.xml
+
+# ---- Webapp Build Properties -------------------------------------------------
+
+build.webapp=${build.root}/webapp
+build.webapp.webinf=${build.webapp}/WEB-INF
+build.webapp.classes=${build.webapp.webinf}/classes
+build.webapp.lib=${build.webapp.webinf}/lib
+build.webapp.samples=${build.webapp}/samples
+build.webapp.test-suite=${build.webapp}/test-suite
+build.webapp.loglevel=INFO
+build.webapp.logappend=false
+build.war=${build}/${name}.war
+
+# ---- Standalone-demo Build Properties ----------------------------------------
+
+build.standalone.demo=${build.root}/standalone-demo
+
+# ---- Compilation -------------------------------------------------------------
+
+compiler=modern
+compiler.debug=on
+compiler.optimize=on
+compiler.deprecation=off
+compiler.nowarn=on
+source.vm=1.4
+
+# ---- System Properties -------------------------------------------------------
+
+# WARNING: you shouldn't need to modify anything below here since there is a
+# very high change of breaking the build system. Do it only if you know what
+# you're doing.
+
+packages=org.apache
+
+# Project descriptor
+gump.descriptor=src/gump/module.xml
+
+# Directory Layout
+src=src
+java=${src}/java
+mocks=${src}/mocks
+test=${src}/test
+resources=${src}/resources
+resources.styles=${resources}/styles
+resources.logos=${resources}/logos
+resources.javadoc=${resources}/javadoc
+blocks=${src}${file.separator}blocks
+samples=${src}/samples
+webapp=${src}/webapp
+webapp.samples=${webapp}/samples
+webapp.test-suite=${webapp}/test-suite
+customconf=${src}/confpatch
+
+# Deprecated Stuff
+deprecated=${src}/deprecated
+deprecated.src=${deprecated}/java
+deprecated.conf=${deprecated}/conf
+
+# Tools
+tools=tools
+tools.lib=${tools}/lib
+tools.src=${tools}/src
+tools.tasks.src=${tools.src}/anttasks
+tools.tasks.dest=${tools}/anttasks
+tools.loader.src=${tools.src}/loader
+tools.loader.dest=${tools}/loader
+tools.jetty=${tools}/jetty
+
+# Libraries
+lib=lib
+lib.core=${lib}/core
+lib.endorsed=${lib}/endorsed
+lib.optional=${lib}/optional
+lib.local=${lib}/local
+
+# Distribution Directories
+dist.root=dist
+dist=${dist.root}/${name}-${version}
+dist.name=${name}-${version}
+dist.target=${dist.root}
+
+# Site Directory
+site=../cocoon-site/site/2.1
+
+# Legal
+legal=legal
diff --git a/non-releases/trunk_before_flattening/build.sh b/non-releases/trunk_before_flattening/build.sh
new file mode 100755
index 0000000..e674809
--- /dev/null
+++ b/non-releases/trunk_before_flattening/build.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+#  Copyright 1999-2004 The Apache Software Foundation
+#
+#  Licensed 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.
+
+# ----- Set path to our tools, overridable  -----------------------------------
+if [ "$COCOON_TOOLS" = "" ] 
+then
+  COCOON_TOOLS="./tools"
+fi
+
+chmod u+x $COCOON_TOOLS/bin/antRun
+chmod u+x $COCOON_TOOLS/bin/ant
+
+# ----- Verify and Set Required Environment Variables -------------------------
+
+S=":";
+case "`uname`" in
+   CYGWIN*) S=";" ;;
+esac
+
+# ----- Ignore system CLASSPATH variable
+OLD_CLASSPATH="$CLASSPATH"
+unset CLASSPATH
+CLASSPATH="`echo lib/endorsed/*.jar | tr ' ' $S`"
+export CLASSPATH
+
+# ----- Use Ant shipped with Cocoon. Ignore installed in the system Ant
+OLD_ANT_HOME="$ANT_HOME"
+ANT_HOME=$COCOON_TOOLS
+OLD_ANT_OPTS="$ANT_OPTS"
+ANT_OPTS="-Xms32M -Xmx512M -Djava.endorsed.dirs=lib/endorsed"
+export ANT_HOME ANT_OPTS
+
+"$ANT_HOME/bin/ant" -logger org.apache.tools.ant.NoBannerLogger --noconfig -emacs  $@
+ERR=$?
+
+# ----- Restore ANT_HOME and ANT_OPTS
+ANT_HOME="$OLD_ANT_HOME"
+ANT_OPTS="$OLD_ANT_OPTS"
+export ANT_HOME ANT_OPTS
+unset OLD_ANT_HOME
+unset OLD_ANT_OPTS
+
+# ----- Restore CLASSPATH
+CLASSPATH="$OLD_CLASSPATH"
+export CLASSPATH
+unset OLD_CLASSPATH
+exit $ERR
diff --git a/non-releases/trunk_before_flattening/build.xml b/non-releases/trunk_before_flattening/build.xml
new file mode 100644
index 0000000..64d3fb5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/build.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===========================================================================
+
+                       * =========================== *
+                       |  Apache Cocoon Build System |
+                       * =========================== *
+
+       $Id$:
+
+============================================================================ -->
+
+<project default="webapp" basedir="." name="Apache Cocoon">
+
+  <!-- ==================  Apache Cocoon targets  ======================== -->
+
+  <!-- =================================================================== -->
+  <!-- Initialization targets  -->
+  <import file="tools/targets/init-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Compile targets         -->
+  <import file="tools/targets/compile-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Validation targets      -->
+  <import file="tools/targets/validate-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Samples targets         -->
+  <import file="tools/targets/samples-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Web application targets -->
+  <import file="tools/targets/webapp-build.xml" />
+  <!-- =================================================================== -->
+  <!-- IDE targets             -->
+  <import file="tools/targets/ide-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Testcases targets       -->
+  <import file="tools/targets/test-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Documentation targets   -->
+  <import file="tools/targets/docs-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Distribution targets    -->
+  <import file="tools/targets/dist-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Administration targets  -->
+  <import file="tools/targets/admin-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Standalone-demo targets -->
+  <import file="tools/targets/standalone-demo-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Upgrade targets -->
+  <import file="tools/targets/upgrade-build.xml" />
+  <!-- =================================================================== -->
+  <!-- Tools targets -->
+  <import file="tools/targets/tools-build.xml" />
+  <!-- =================================================================== -->
+  <!-- OSGi targets -->
+  <import file="tools/targets/osgi-build.xml" />
+  <!-- =================================================================== -->   
+
+</project>
diff --git a/non-releases/trunk_before_flattening/cli.xconf b/non-releases/trunk_before_flattening/cli.xconf
new file mode 100644
index 0000000..157769f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/cli.xconf
@@ -0,0 +1,314 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    |  This is the Apache Cocoon command line configuration file. 
+    |  Here you give the command line interface details of where
+    |  to find various aspects of your Cocoon installation.
+    |
+    |  If you wish, you can also use this file to specify the URIs
+    |  that you wish to generate.
+    |
+    |  The current configuration information in this file is for
+    |  building the Cocoon documentation. Therefore, all links here 
+    |  are relative to the build context dir, which, in the build.xml 
+    |  file, is set to ${build.context} 
+    |
+    |  Options:
+    |    verbose:            increase amount of information presented
+    |                        to standard output (default: false)
+    |    follow-links:       whether linked pages should also be 
+    |                        generated (default: true)
+    |    precompile-only:    precompile sitemaps and XSP pages, but 
+    |                        do not generate any pages (default: false)
+    |    confirm-extensions: check the mime type for the generated page
+    |                        and adjust filename and links extensions
+    |                        to match the mime type 
+    |                        (e.g. text/html->.html)
+    |
+    |  Note: Whilst using an xconf file to configure the Cocoon 
+    |        Command Line gives access to more features, the use of 
+    |        command line parameters is more stable, as there are 
+    |        currently plans to improve the xconf format to allow 
+    |        greater flexibility. If you require a stable and
+    |        consistent method for accessing the CLI, it is recommended 
+    |        that you use the command line parameters to configure 
+    |        the CLI. See documentation at:
+    |        /userdocs/offline/index.html and Wiki:CommandLine
+    |
+    | CVS: $Id: cli.xconf,v 1.12 2004/03/08 06:07:14 antonio Exp $
+    +-->
+    
+<cocoon verbose="true"  
+        follow-links="true" 
+        precompile-only="false" 
+        confirm-extensions="true">
+
+   <!--+
+       |  The context directory is usually the webapp directory
+       |  containing the sitemap.xmap file.
+       |
+       |  The config file is the cocoon.xconf file.
+       |
+       |  The work directory is used by Cocoon to store temporary
+       |  files and cache files.
+       |
+       |  The destination directory is where generated pages will
+       |  be written (assuming the 'simple' mapper is used, see 
+       |  below)
+       +-->
+   <context-dir>build/webapp</context-dir>
+   <config-file>WEB-INF/cocoon.xconf</config-file>
+   <work-dir>build/work</work-dir>
+   <dest-dir>build/dest</dest-dir>
+   
+   <!--+
+       |  A checksum file can be used to store checksums for pages
+       |  as they are generated. When the site is next generated, 
+       |  files will not be written if their checksum has not changed.
+       |  This means that it will be easier to detect which files 
+       |  need to be uploaded to a server, using the timestamp.
+       +-->
+   <!--   <checksums-uri>build/work/checksums</checksums-uri>-->
+
+   <!--+
+       | Broken link reporting options:
+       |   Report into a text file, one link per line:
+       |     <broken-links type="text" report="filename"/>
+       |   Report into an XML file:
+       |     <broken-links type="xml" report="filename"/>
+       |   Ignore broken links (default):
+       |     <broken-links type="none"/>
+       |
+       |   Two attributes to this node specify whether a page should
+       |   be generated when an error has occured. 'generate' specifies 
+       |   whether a page should be generated (default: true) and
+       |   extension specifies an extension that should be appended
+       |   to the generated page's filename (default: none)
+       |
+       |   Using this, a quick scan through the destination directory
+       |   will show broken links, by their filename extension.
+       +-->
+   <broken-links type="xml" 
+                 file="brokenlinks.xml"
+                 generate="false"
+                 extension=".error"/>
+   
+   <!--+
+       |  Load classes at startup. This is necessary for generating
+       |  from sites that use SQL databases and JDBC.
+       |  The <load-class> element can be repeated if multiple classes
+       |  are needed.
+       +-->
+   <!--
+   <load-class>org.firebirdsql.jdbc.Driver</load-class>
+   -->
+
+   <!--+
+       |  Configures logging. 
+       |  The 'log-kit' parameter specifies the location of the log kit 
+       |  configuration file (usually called logkit.xconf. 
+       | 
+       |  Logger specifies the logging category (for all logging prior 
+       |  to other Cocoon logging categories taking over)
+       |
+       |  Available log levels are:
+       |    DEBUG:        prints all level of log messages.
+       |    INFO:         prints all level of log messages except DEBUG 
+       |                  ones.
+       |    WARN:         prints all level of log messages except DEBUG 
+       |                  and INFO ones.
+       |    ERROR:        prints all level of log messages except DEBUG, 
+       |                  INFO and WARN ones.
+       |    FATAL_ERROR:  prints only log messages of this level
+       +-->
+   <logging log-kit="build/webapp/WEB-INF/logkit.xconf" logger="cli" level="DEBUG" />
+
+   <!--+
+       |  Specifies the filename to be appended to URIs that
+       |  refer to a directory (i.e. end with a forward slash).
+       +-->
+   <default-filename>index.html</default-filename>
+
+   <!--+
+       |  Specifies a user agent string to the sitemap when
+       |  generating the site.
+       |
+       |  A generic term for a web browser is "user agent". Any 
+       |  user agent, when connecting to a web server, will provide
+       |  a string to identify itself (e.g. as Internet Explorer or
+       |  Mozilla). It is possible to have Cocoon serve different
+       |  content depending upon the user agent string provided by
+       |  the browser. If your site does this, then you may want to
+       |  use this <user-agent> entry to provide a 'fake' user agent
+       |  to Cocoon, so that it generates the correct version of your
+       |  site.
+       | 
+       |  For most sites, this can be ignored.
+       +-->
+   <!--
+   <user-agent>Cocoon Command Line Environment 2.1</user-agent>
+   -->
+
+   <!--+
+       |  Specifies an accept string to the sitemap when generating
+       |  the site.
+       |  User agents can specify to an HTTP server what types of content
+       |  (by mime-type) they are able to receive. E.g. a browser may be 
+       |  able to handle jpegs, but not pngs. The HTTP accept header 
+       |  allows the server to take the browser's capabilities into account,
+       |  and only send back content that it can handle.
+       |
+       |  For most sites, this can be ignored.
+       +-->
+   
+   <accept>*/*</accept>
+   
+   <!--+
+       | Specifies which URIs should be included or excluded, according
+       | to wildcard patterns. 
+       | 
+       | These includes/excludes are only relevant when you are following
+       | links. A link URI must match an include pattern (if one is given) 
+       | and not match an exclude pattern, if it is to be followed by
+       | Cocoon. It can be useful, for example, where there are links in
+       | your site to pages that are not generated by Cocoon, such as 
+       | references to api-documentation.
+       | 
+       | By default, all URIs are included. If both include and exclude
+       | patterns are specified, a URI is first checked against the 
+       | include patterns, and then against the exclude patterns.
+       | 
+       | Multiple patterns can be given, using muliple include or exclude
+       | nodes. 
+       | 
+       | The order of the elements is not significant, as only the first 
+       | successful match of each category is used.
+       | 
+       | Currently, only the complete source URI can be matched (including
+       | any URI prefix). Future plans include destination URI matching 
+       | and regexp matching. If you have requirements for these, contact
+       | dev@cocoon.apache.org.
+       +-->
+
+   <include pattern="**"/>
+   <exclude pattern="docs/apidocs/**"/>
+   
+   <!--   <include-links extension=".html"/>-->
+   
+   <!--+
+       |  <uri> nodes specify the URIs that should be generated, and 
+       |  where required, what should be done with the generated pages.
+       |  They describe the way the URI of the generated file is created
+       |  from the source page's URI. There are three ways that a generated
+       |  file URI can be created: append, replace and insert.
+       |
+       |  The "type" attribute specifies one of (append|replace|insert):
+       |
+       |  append:
+       |  Append the generated page's URI to the end of the source URI:
+       |
+       |   <uri type="append" src-prefix="documents/" src="index.html"
+       |   dest="build/dest/"/>
+       |
+       |  This means that 
+       |   (1) the "documents/index.html" page is generated
+       |   (2) the file will be written to "build/dest/documents/index.html"
+       |
+       |  replace:
+       |  Completely ignore the generated page's URI - just 
+       |  use the destination URI:
+       |
+       |   <uri type="replace" src-prefix="documents/" src="index.html" 
+       |   dest="build/dest/docs.html"/>
+       |  
+       |  This means that 
+       |   (1) the "documents/index.html" page is generated
+       |   (2) the result is written to "build/dest/docs.html"
+       |   (3) this works only for "single" pages - and not when links
+       |       are followed
+       |
+       |  insert:
+       |  Insert generated page's URI into the destination 
+       |  URI at the point marked with a * (example uses fictional 
+       |  zip protocol)
+       |
+       |   <uri type="insert" src-prefix="documents/" src="index.html" 
+       |   dest="zip://*.zip/page.html"/>
+       |
+       |  This means that 
+       |   (1)
+       |
+       |  In any of these scenarios, if the dest attribute is omitted,
+       |  the value provided globally using the <dest-dir> node will 
+       |  be used instead.
+       +-->
+
+   <uri type="replace" 
+        src-prefix="samples/" 
+        src="hello-world/hello.html"
+        dest="build/dest/hello-world.html"/>
+    
+   <!--+
+       | <uri> nodes can be grouped together in a <uris> node. This 
+       | enables a group of URIs to share properties. The following
+       | properties can be set for a group of URIs:
+       |   * follow-links:       should pages be crawled for links
+       |   * confirm-extensions: should file extensions be checked
+       |                         for the correct mime type
+       |   * src-prefix:         all source URIs should be 
+       |                         pre-pended with this prefix before
+       |                         generation. The prefix is not 
+       |                         included when calculating the 
+       |                         destination URI
+       |   * dest:               the base destination URI to be
+       |                         shared by all pages in this group
+       |   * type:               the method to be used to calculate
+       |                         the destination URI. See above 
+       |                         section on <uri> node for details.
+       | 
+       | Each <uris> node can have a name attribute. When a name
+       | attribute has been specified, the -n switch on the command
+       | line can be used to tell Cocoon to only process the URIs
+       | within this URI group. When no -n switch is given, all 
+       | <uris> nodes are processed. Thus, one xconf file can be 
+       | used to manage multiple sites.
+       +-->
+   
+   <uris name="docs" follow-links="true">
+     <uri type="append" src-prefix="docs/" src="index.html"
+          dest="build/dest/" />
+   </uris>
+   
+   <uris name="samples" 
+         follow-links="false"
+         src-prefix="samples/"
+         dest="build/dest/examples/"
+         type="append"
+         >
+      <uri src="hello-world/hello.html"/>
+      <uri src="hello-world/hello.xml"/>
+   </uris>
+
+   <!--+
+       |  File containing URIs (plain text, one per line).
+       +-->
+   <!--
+   <uri-file>uris.txt</uri-file>
+   -->
+</cocoon>
+
+
diff --git a/non-releases/trunk_before_flattening/cocoon.bat b/non-releases/trunk_before_flattening/cocoon.bat
new file mode 100644
index 0000000..f99f69e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/cocoon.bat
@@ -0,0 +1,193 @@
+@echo off
+rem  Copyright 1999-2005 The Apache Software Foundation
+rem
+rem  Licensed under the Apache License, Version 2.0 (the "License");
+rem  you may not use this file except in compliance with the License.
+rem  You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem  Unless required by applicable law or agreed to in writing, software
+rem  distributed under the License is distributed on an "AS IS" BASIS,
+rem  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem  See the License for the specific language governing permissions and
+rem  limitations under the License.
+rem
+:: -----------------------------------------------------------------------------
+:: Cocoon Win32 Shell Script
+::
+:: $Id$
+:: -----------------------------------------------------------------------------
+
+:: Configuration variables
+::
+:: COCOON_HOME
+::   Folder that points to the root of the Cocoon distribution
+::
+:: COCOON_LIB
+::   Folder containing all the library files needed by the Cocoon CLI
+::
+:: JAVA_HOME
+::   Home of Java installation.
+::
+:: JAVA_OPTIONS
+::   Extra options to pass to the JVM
+::
+:: JAVA_DEBUG_PORT
+::   The location where the JVM debug server should listen to
+::
+:: JETTY_PORT
+::   Override the default port for Jetty
+::
+:: JETTY_ADMIN_PORT
+::   The port where the jetty web administration should bind
+::
+:: JETTY_WEBAPP
+::   The directory where the webapp that jetty has to execute is located
+::
+
+:: ----- Verify and Set Required Environment Variables -------------------------
+
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+echo You must set JAVA_HOME to point at your Java Development Kit installation
+goto end
+:gotJavaHome
+
+:: ----- Check System Properties -----------------------------------------------
+
+if not "%JETTY_LOGGING%" == "" goto gotJettyLogging
+set JETTY_LOGGING=-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.LogKitLogger
+:gotJettyLogging
+
+if not "%EXEC%" == "" goto gotExec
+if not "%OS%" == "Windows_NT" goto noExecNT
+set EXEC=start "Cocoon" /D.
+goto gotExec
+:noExecNT
+set EXEC=
+:gotExec
+
+if not "%COCOON_HOME%" == "" goto gotHome
+set COCOON_HOME=.
+:gotHome
+
+if not "%COCOON_LIB%" == "" goto gotLib
+set COCOON_LIB=%COCOON_HOME%\build\webapp\WEB-INF\lib
+:gotLib
+
+if not "%JETTY_PORT%" == "" goto gotJettyPort
+set JETTY_PORT=8888
+:gotJettyPort
+
+if not "%JETTY_ADMIN_PORT%" == "" goto gotJettyAdminPort
+set JETTY_ADMIN_PORT=8889
+:gotJettyAdminPort
+
+if not "%JETTY_WEBAPP%" == "" goto gotWebapp
+set DEMO_WEBAPP=..\webapp
+if not exist %DEMO_WEBAPP% goto standardWebapp
+set JETTY_WEBAPP=%DEMO_WEBAPP%
+goto gotWebapp
+:standardWebapp
+set JETTY_WEBAPP=%COCOON_HOME%\build\webapp
+:gotWebapp
+echo cocoon.bat: using %JETTY_WEBAPP% as the webapp directory
+
+if not "%JAVA_DEBUG_PORT%" == "" goto gotDebugPort
+set JAVA_DEBUG_PORT=8000
+:gotDebugPort
+
+:: ----- Ensure desktop.ini is activated ---------------------------------------
+
+attrib +s %COCOON_HOME%
+
+:: ----- Set Up The Classpath --------------------------------------------------
+
+set CP=%COCOON_HOME%\tools\loader
+
+:: ----- Check action ----------------------------------------------------------
+if ""%1"" == """" goto doServlet
+if ""%1"" == ""cli"" goto doCli
+if ""%1"" == ""servlet"" goto doServlet
+if ""%1"" == ""servlet-admin"" goto doAdmin
+if ""%1"" == ""servlet-debug"" goto doDebug
+IF ""%1"" == ""servlet-profile"" goto doProfile
+IF ""%1"" == ""yourkit-profile"" goto doYourkitProfile
+IF ""%1"" == ""osgi"" goto doOsgiKnopflerfish
+IF ""%1"" == ""osgi-debug"" goto doOsgiKnopflerfishDebug
+
+echo Usage: cocoon (action)
+echo actions:
+echo   cli             Run Cocoon from command line
+echo   servlet         Run Cocoon in a servlet container (default)
+echo   servlet-admin   Run Cocoon in a servlet container and turn container web administration on
+echo   servlet-debug   Run Cocoon in a servlet container and turn on remote JVM debug
+echo   servlet-profile Run Cocoon in a servlet container and turn on JVM profiling
+echo   yourkit-profile Run Cocoon in a servlet container and turn on Yourkit JVM profiling
+echo   osgi            Run Cocoon within OSGi
+echo   osgi-debug      Run Cocoon within OSGi and turn on remote JVM debug
+goto end
+
+:: ----- Cli -------------------------------------------------------------------
+
+:doCli
+set param=
+shift
+:cliLoop
+if "%1"=="" goto cliLoopEnd
+if not "%1"=="" set param=%param% %1
+shift
+goto cliLoop
+
+:cliLoopEnd
+
+"%JAVA_HOME%\bin\java.exe" %JAVA_OPTIONS% -classpath "%CP%" -Djava.endorsed.dirs=lib\endorsed "-Dloader.jar.repositories=%COCOON_LIB%" -Dloader.main.class=org.apache.cocoon.Main Loader %param%
+goto end
+
+:: ----- Servlet ---------------------------------------------------------------
+
+:doServlet
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JETTY_LOGGING% %JAVA_OPTIONS% -classpath "%CP%" "-Djava.endorsed.dirs=%COCOON_HOME%\lib\endorsed" "-DSTART=%COCOON_HOME%\tools\jetty\conf\jetty-start.config" "-Dwebapp=%JETTY_WEBAPP%" -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser -Djetty.port=%JETTY_PORT% -Djetty.admin.port=%JETTY_ADMIN_PORT% "-Dhome=%COCOON_HOME%" "-Dloader.jar.repositories=%COCOON_HOME%\tools\jetty\lib;%COCOON_HOME%\lib\endorsed" -Dloader.main.class=org.mortbay.jetty.Server -jar "%COCOON_HOME%\tools\jetty\jetty-start-5.1.8.jar" "%COCOON_HOME%\tools\jetty\conf\main.xml"
+goto end
+
+:: ----- Servlet with Administration Web Interface -----------------------------
+
+:doAdmin
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JETTY_LOGGING% %JAVA_OPTIONS% -classpath "%CP%" "-Djava.endorsed.dirs=%COCOON_HOME%\lib\endorsed" "-DSTART=%COCOON_HOME%\tools\jetty\conf\jetty-start.config" "-Dwebapp=%JETTY_WEBAPP%" -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser -Djetty.port=%JETTY_PORT% -Djetty.admin.port=%JETTY_ADMIN_PORT% "-Dhome=%COCOON_HOME%" "-Dloader.jar.repositories=%COCOON_HOME%\tools\jetty\lib;%COCOON_HOME%\lib\endorsed" -Dloader.main.class=org.mortbay.jetty.Server -jar "%COCOON_HOME%\tools\jetty\jetty-start-5.1.8.jar"  "%COCOON_HOME%\tools\jetty\conf\main.xml" "%COCOON_HOME%\tools\jetty\conf\admin.xml"
+goto end
+
+:: ----- Servlet Debug ---------------------------------------------------------
+
+:doDebug
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JETTY_LOGGING% %JAVA_OPTIONS% -Xdebug -Xrunjdwp:transport=dt_socket,address=%JAVA_DEBUG_PORT%,server=y,suspend=n  -classpath "%CP%" "-Djava.endorsed.dirs=%COCOON_HOME%\lib\endorsed" "-DSTART=%COCOON_HOME%\tools\jetty\conf\jetty-start.config" "-Dwebapp=%JETTY_WEBAPP%" "-Dhome=%COCOON_HOME%" -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser -Djetty.port=%JETTY_PORT% -Djetty.admin.port=%JETTY_ADMIN_PORT% "-Dloader.jar.repositories=%COCOON_HOME%\tools\jetty\lib;%COCOON_HOME%\lib\endorsed" -Dloader.main.class=org.mortbay.jetty.Server -jar "%COCOON_HOME%\tools\jetty\jetty-start-5.1.8.jar"  "%COCOON_HOME%\tools\jetty\conf\main.xml"
+goto end
+
+:: ----- Servlet Profile ---------------------------------------------------------
+
+:doProfile
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JETTY_LOGGING% %JAVA_OPTIONS% -Xrunhprof:heap=all,cpu=samples,thread=y,depth=3 -classpath "%CP%" "-Djava.endorsed.dirs=%COCOON_HOME%\lib\endorsed" "-DSTART=%COCOON_HOME%\tools\jetty\conf\jetty-start.config" "-Dwebapp=%JETTY_WEBAPP%" "-Dhome=%COCOON_HOME%" -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser -Djetty.port=%JETTY_PORT% -Djetty.admin.port=%JETTY_ADMIN_PORT% "-Dloader.jar.repositories=%COCOON_HOME%\tools\jetty\lib;%COCOON_HOME%\lib\endorsed" -Dloader.main.class=org.mortbay.jetty.Server -jar "%COCOON_HOME%\tools\jetty\jetty-start-5.1.8.jar"  "%COCOON_HOME%\tools\jetty\conf\main.xml"
+goto end
+
+:: ----- Yourkit Profile --------------------------------------------------------
+
+:doYourkitProfile
+echo %EXEC%
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JETTY_LOGGING% %JAVA_OPTIONS% -Xrunyjpagent:port=10000 -classpath "%CP%" "-Djava.endorsed.dirs=%COCOON_HOME%\lib\endorsed" "-DSTART=%COCOON_HOME%\tools\jetty\conf\jetty-start.config" "-Dwebapp=%JETTY_WEBAPP%" "-Dhome=%COCOON_HOME%" -Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser -Djetty.port=%JETTY_PORT% -Djetty.admin.port=%JETTY_ADMIN_PORT% "-Dloader.jar.repositories=%COCOON_HOME%\tools\jetty\lib;%COCOON_HOME%\lib\endorsed" -Dloader.main.class=org.mortbay.jetty.Server -jar "%COCOON_HOME%\tools\jetty\jetty-start-5.1.8.jar"  "%COCOON_HOME%\tools\jetty\conf\main.xml"
+goto end
+
+:: ----- OSGi --------------------------------------------------------
+
+:doOsgiKnopflerfish
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JAVA_OPTIONS% -jar lib/core/knopflerfish-framework-1.3.3.jar -init %2 %3 %4 %5 %6 %7 %8 %9
+goto end
+
+:doOsgiKnopflerfishDebug
+%EXEC% "%JAVA_HOME%\bin\java.exe" %JAVA_OPTIONS% -Xdebug -Xrunjdwp:transport=dt_socket,address=%JAVA_DEBUG_PORT%,server=y,suspend=n -jar lib/core/knopflerfish-framework-1.3.3.jar -init %2 %3 %4 %5 %6 %7 %8 %9
+goto end
+
+:: ----- End -------------------------------------------------------------------
+
+:end
+set CP=
+set EXEC=
+
diff --git a/non-releases/trunk_before_flattening/cocoon.sh b/non-releases/trunk_before_flattening/cocoon.sh
new file mode 100755
index 0000000..d6928f2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/cocoon.sh
@@ -0,0 +1,240 @@
+#!/bin/sh
+#  Copyright 1999-2004 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+# -----------------------------------------------------------------------------
+# Cocoon Unix Shell Script
+#
+# $Id$
+# -----------------------------------------------------------------------------
+
+# Configuration variables
+#
+# COCOON_HOME
+#   The root of the Cocoon distribution
+#
+# COCOON_WEBAPP_HOME
+#   The root of the Cocoon web application
+#
+# COCOON_LIB
+#   Folder containing all the library files needed by the Cocoon CLI
+#
+# JAVA_HOME
+#   Home of Java installation.
+#
+# JAVA_OPTIONS
+#   Extra options to pass to the JVM
+#
+# JAVA_DEBUG_ARGS
+#   The command line arguments for the internal JVM debugger
+#
+# JAVA_PROFILE_ARGS
+#   The command line arguments for the internal JVM profiler
+#
+# JETTY_PORT
+#   Override the default port for Jetty
+# 
+# JETTY_ADMIN_PORT
+#   The port where the jetty web administration should bind
+# 
+# JETTY_JMX_PORT
+#   The port where the jetty JMX HTTP Adapter should bind
+#
+
+
+usage()
+{
+    echo "Usage: $0 (action)"
+    echo "actions:"
+    echo "  cli               Run Cocoon from the command line"
+    echo "  servlet           Run Cocoon in a servlet container (default)"
+    echo "  servlet-admin     Run Cocoon in a servlet container and turn on container web administration"
+    echo "  servlet-jmx       Run Cocoon in a servlet container and turn on container web JMX adapter"
+    echo "  servlet-admin-jmx Run Cocoon in a servlet container and turn on container web administration and JMX adapter"
+    if [ "$JAVA_VERSION" -gt 4 ];then
+      echo "  servlet-pms       Run Cocoon in a servlet container and turn on platform MBean server"
+      echo "  servlet-admin-pms Run Cocoon in a servlet container and turn on container web administration and platform MBean server"
+    fi
+    echo "  servlet-debug     Run Cocoon in a servlet container and turn on JVM remote debug"
+    echo "  servlet-profile   Run Cocoon in a servlet container and turn on JVM profiling"
+    echo "  osgi              Run Cocoon with the experimental OSGI kernel"
+    echo "  osgi-debug        Run Cocoon with the experimental OSGI kernel and turn on JVM remote debug"
+    exit 1
+}
+
+# ----- Handle action parameter ------------------------------------------------
+DEFAULT_ACTION="servlet"
+ACTION="$1"
+if [ -n "$ACTION" ]
+then
+  shift
+else
+  ACTION=$DEFAULT_ACTION
+  echo "$0: executing default action '$ACTION', use -h to see other actions"
+fi
+ARGS="$*"
+
+# ----- Verify and Set Required Environment Variables -------------------------
+
+if [ "$JAVA_HOME" = "" ] ; then
+  echo You must set JAVA_HOME to point at your Java Development Kit installation
+  exit 1
+fi
+
+if [ "$JAVA_OPTIONS" = "" ] ; then
+#  JAVA_OPTIONS='-Xms32M -Xmx512M'
+  JAVA_OPTIONS='-Xms32M -Xmx512M -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.LogKitLogger'
+#  JAVA_OPTIONS='-Xms32M -Xmx512M -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog'
+fi
+
+if [ "$COCOON_HOME" = "" ] ; then
+  COCOON_HOME='.'
+fi
+
+if [ "$COCOON_WEBAPP_HOME" = "" ] ; then
+  STANDALONE_WEBAPP=../webapp
+  if [ -d $STANDALONE_WEBAPP ] ; then
+    # for standalone-webapp setup
+    COCOON_WEBAPP_HOME=$STANDALONE_WEBAPP
+  else
+    # when in the build environment
+    COCOON_WEBAPP_HOME="$COCOON_HOME/build/webapp"
+  fi
+fi
+echo "$0: using $COCOON_WEBAPP_HOME as the webapp directory"
+
+if [ "$COCOON_LIB" = "" ] ; then
+  COCOON_LIB="$COCOON_WEBAPP_HOME/WEB-INF/lib"
+fi
+
+if [ "$JETTY_PORT" = "" ] ; then
+  JETTY_PORT='8888'
+fi
+
+if [ "$JETTY_ADMIN_PORT" = "" ] ; then
+  JETTY_ADMIN_PORT='8889'
+fi
+
+if [ "$JETTY_JMX_PORT" = "" ] ; then
+  JETTY_JMX_PORT='8890'
+fi
+
+if [ "$JAVA_DEBUG_ARGS" = "" ] ; then
+  JAVA_DEBUG_ARGS='-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n'
+fi
+
+if [ "$JAVA_PROFILE_ARGS" = "" ] ; then
+  JAVA_PROFILE_ARGS='-Xrunhprof:heap=all,cpu=samples,thread=y,depth=3'
+fi
+
+
+# ----- Set platform specific variables
+
+PATHSEP=":";
+case "`uname`" in
+   CYGWIN*) PATHSEP=";" ;;
+esac
+
+# ----- Set Local Variables ( used to minimize cut/paste) ---------------------
+
+JAVA="$JAVA_HOME/bin/java"
+JAVA_VERSION=`$JAVA -version 2>&1 | awk '/java version/ {print substr($3,4,1)}'`
+if [ "$JAVA_VERSION" -gt 4 ]; then
+  JAVA_PLATFORM_SERVER="-Dcom.sun.management.jmxremote"
+fi
+ENDORSED_LIBS="$COCOON_HOME/lib/endorsed"
+ENDORSED="-Djava.endorsed.dirs=$ENDORSED_LIBS"
+PARSER=-Dorg.xml.sax.parser=org.apache.xerces.parsers.SAXParser
+LOADER=Loader
+LOADER_LIB="${COCOON_HOME}/tools/loader"
+BLOCKS="-Dorg.apache.cocoon.processor=org.apache.cocoon.blocks.BlocksManager -Dorg.apache.cocoon.configuration=/wiring.xml"
+
+CLI=-Dloader.main.class=org.apache.cocoon.Main
+CLI_LIBRARIES="-Dloader.jar.repositories=$COCOON_LIB"
+
+JETTY=-Dloader.main.class=org.mortbay.jetty.Server
+JETTY_CONF="$COCOON_HOME/tools/jetty/conf"
+JETTY_MAIN="$JETTY_CONF/main.xml"
+JETTY_JMX_MAIN="$JETTY_CONF/main-jmx.xml"
+JETTY_ADMIN="$JETTY_CONF/admin.xml"
+JETTY_JMX_ADMIN="$JETTY_CONF/admin-jmx.xml"
+JETTY_WEBAPP="-Dwebapp=$COCOON_WEBAPP_HOME"
+JETTY_HOME="-Dhome=$COCOON_HOME"
+JETTY_PORT_ARGS="-Djetty.port=$JETTY_PORT"
+JETTY_ADMIN_ARGS="-Djetty.admin.port=$JETTY_ADMIN_PORT"
+JETTY_JMX_ARGS="-Djetty.jmx.port=$JETTY_JMX_PORT"
+JETTY_START_CONF="-DSTART=$COCOON_HOME/tools/jetty/conf/jetty-start.config"
+JETTY_START="-jar $COCOON_HOME/tools/jetty/jetty-start-5.1.8.jar"
+
+# ----- Do the action ----------------------------------------------------------
+
+case "$ACTION" in
+  cli)
+        $JAVA $JAVA_OPTIONS -cp $LOADER_LIB $ENDORSED $CLI_LIBRARIES $CLI $LOADER $ARGS
+        ;;
+
+  servlet)
+        $JAVA $JAVA_OPTIONS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN
+        ;;
+
+  servlet-admin)
+        $JAVA $JAVA_OPTIONS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_ADMIN_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN $JETTY_ADMIN
+        ;;
+
+  servlet-jmx)
+        $JAVA $JAVA_OPTIONS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_JMX_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_JMX_MAIN
+        ;;
+
+  servlet-pms)
+        $JAVA $JAVA_OPTIONS $JAVA_PLATFORM_SERVER $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_JMX_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN
+        ;;
+
+  servlet-admin-jmx)
+        $JAVA $JAVA_OPTIONS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_ADMIN_ARGS $JETTY_JMX_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_JMX_ADMIN
+        ;;
+
+  servlet-admin-pms)
+        $JAVA $JAVA_OPTIONS $JAVA_PLATFORM_SERVER $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_ADMIN_ARGS $JETTY_JMX_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN $JETTY_ADMIN
+        ;;
+
+  servlet-debug)
+        $JAVA $JAVA_OPTIONS $JAVA_DEBUG_ARGS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN
+        ;;
+
+  servlet-profile)
+        $JAVA $JAVA_OPTIONS $JAVA_PROFILE_ARGS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN
+        ;;
+
+  blocks)
+        $JAVA $JAVA_OPTIONS $BLOCKS $ENDORSED $PARSER $JETTY_PORT_ARGS $JETTY_START_CONF $JETTY_WEBAPP $JETTY_HOME $JETTY $JETTY_START $JETTY_MAIN
+        ;;
+
+  osgi)
+        # -init prevents knopflerfish from using its persistent info about bundles, seems safer for now
+        KNOP_OPTIONS="-init"
+        $JAVA $JAVA_OPTIONS -jar lib/core/knopflerfish-framework-1.3.3.jar $KNOP_OPTIONS $ARGS
+        ;;
+
+  osgi-debug)
+        # -init prevents knopflerfish from using its persistent info about bundles, seems safer for now
+        KNOP_OPTIONS="-init"
+        $JAVA $JAVA_OPTIONS $JAVA_DEBUG_ARGS -jar lib/core/knopflerfish-framework-1.3.3.jar $KNOP_OPTIONS $ARGS
+        ;;
+
+  *)
+        usage
+        ;;
+esac
+
+exit 0
diff --git a/non-releases/trunk_before_flattening/core/pom.xml b/non-releases/trunk_before_flattening/core/pom.xml
new file mode 100644
index 0000000..75c1a37
--- /dev/null
+++ b/non-releases/trunk_before_flattening/core/pom.xml
@@ -0,0 +1,389 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+  | @version $Id$
+  |
+  +-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.cocoon</groupId>
+    <artifactId>cocoon</artifactId>
+    <version>2.2.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>cocoon-core</artifactId>
+  <version>2.2.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+  <name>Cocoon Core</name>
+  <build>
+    <sourceDirectory>../src/java</sourceDirectory>
+    <!-- 
+    <testSourceDirectory>../src/test</testSourceDirectory>
+     -->
+    <resources>
+      <resource>
+        <directory>../src/java</directory>
+        <excludes>
+          <exclude>**/*.java</exclude>
+        </excludes>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>../src/test</directory>
+        <excludes>
+          <exclude>**/*.java</exclude>
+        </excludes>
+      </testResource>
+    </testResources>
+    <plugins>
+    <!-- 
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include implementation="java.lang.String">**/*TestCase.class</include>
+            <include implementation="java.lang.String">**/*Test.class</include>
+          </includes>
+          <excludes>
+            <exclude implementation="java.lang.String">**/AllTest.class</exclude>
+            <exclude implementation="java.lang.String">**/CocoonBeanTestCase.class</exclude>
+            <exclude implementation="java.lang.String">**/*$$*Test.class</exclude>
+            <exclude implementation="java.lang.String">**/Abstract*.class</exclude>
+            <exclude implementation="java.lang.String">**/SitemapComponentTestCase*</exclude>
+            <exclude implementation="java.lang.String">**/SitemapTestCase*</exclude>
+            <exclude implementation="java.lang.String">**/ContainerTestCase*</exclude>
+            <exclude implementation="java.lang.String">**/CocoonTestCase*</exclude>
+            <exclude implementation="java.lang.String">**/VirtualPipelineGeneratorTestCase*</exclude>
+          </excludes>
+          <systemProperties>
+            <property>
+              <name>junit.test.loglevel</name>
+              <value>3</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+       -->
+    </plugins>
+  </build>
+  <dependencies>
+
+    <!--  excalibur -->
+    <dependency>
+      <groupId>org.apache.excalibur.components.pool</groupId>
+      <artifactId>excalibur-pool-impl</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.components.sourceresolve</groupId>
+      <artifactId>excalibur-sourceresolve</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.containerkit.logger</groupId>
+      <artifactId>excalibur-logger</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.components.pool</groupId>
+      <artifactId>excalibur-pool-instrumented</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.components.store</groupId>
+      <artifactId>excalibur-store</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.containerkit.instrument</groupId>
+      <artifactId>excalibur-instrument-api</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.excalibur.components.xmlutil</groupId>
+      <artifactId>excalibur-xmlutil</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.avalon.framework</groupId>
+      <artifactId>avalon-framework-impl</artifactId>
+      <version>4.3</version>
+    </dependency>
+    <dependency>
+      <groupId>excalibur-naming</groupId>
+      <artifactId>excalibur-naming</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>excalibur-i18n</groupId>
+      <artifactId>excalibur-i18n</artifactId>
+      <version>1.1</version>
+    </dependency>
+    
+    <!-- commons -->
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+      <version>3.1</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-javaflow</groupId>
+      <artifactId>commons-javaflow</artifactId>
+      <version>r306555</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-jxpath</groupId>
+      <artifactId>commons-jxpath</artifactId>
+      <version>1.2</version>
+      <exclusions>
+        <exclusion>
+          <artifactId>ant-optional</artifactId>
+          <groupId>ant-optional</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>commons-beanutils</artifactId>
+          <groupId>commons-beanutils</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>jdom</artifactId>
+          <groupId>jdom</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>servletapi</artifactId>
+          <groupId>servletapi</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>xerces</artifactId>
+          <groupId>xerces</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-jci</groupId>
+      <artifactId>commons-jci</artifactId>
+      <version>r306555</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.4</version>
+      <exclusions>
+        <exclusion>
+          <artifactId>logkit</artifactId>
+          <groupId>logkit</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>avalon-framework</artifactId>
+          <groupId>avalon-framework</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+      <version>2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-jexl</groupId>
+      <artifactId>commons-jexl</artifactId>
+      <version>1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-httpclient</groupId>
+      <artifactId>commons-httpclient</artifactId>
+      <version>2.0.2</version>
+    </dependency>
+        
+    <!-- osgi -->
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-console_all</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-cm_api</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-consoletty</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-logcommands</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-log_all</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-frameworkcommands</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-http_all</artifactId>
+      <version>1.1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>knopflerfish</groupId>
+      <artifactId>knopflerfish-framework</artifactId>
+      <version>1.3.3</version>
+    </dependency>
+            
+    <!--  test dependencies  -->
+    <dependency>
+      <groupId>xmlunit</groupId>
+      <artifactId>xmlunit</artifactId>
+      <version>0.8</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>jmock</groupId>
+      <artifactId>jmock</artifactId>
+      <version>1.0.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <version>1.1</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>jcs</groupId>
+      <artifactId>jcs</artifactId>
+      <version>1.2.5-dev-20050313</version>
+    </dependency>
+    <dependency>
+      <groupId>xalan</groupId>
+      <artifactId>xalan</artifactId>
+      <version>2.7.0</version>
+    </dependency>
+    <dependency>
+      <groupId>xerces</groupId>
+      <artifactId>xercesImpl</artifactId>
+      <version>2.7.1</version>
+    </dependency>
+    <dependency>
+      <groupId>concurrent</groupId>
+      <artifactId>concurrent</artifactId>
+      <version>1.3.4</version>
+    </dependency>
+    <dependency>
+      <groupId>xml-resolver</groupId>
+      <artifactId>xml-resolver</artifactId>
+      <version>1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.3</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>rhino</groupId>
+      <artifactId>js</artifactId>
+      <version>1.6R1</version>
+    </dependency>
+    <dependency>
+      <groupId>ant</groupId>
+      <artifactId>ant-trax</artifactId>
+      <version>1.6.5</version>
+    </dependency>
+    <dependency>
+      <groupId>ehcache</groupId>
+      <artifactId>ehcache</artifactId>
+      <version>1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>jakarta-regexp</groupId>
+      <artifactId>jakarta-regexp</artifactId>
+      <version>1.4</version>
+    </dependency>
+    <dependency>
+      <groupId>xml-apis</groupId>
+      <artifactId>xml-apis</artifactId>
+      <version>1.3.02</version>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>1.2.12</version>
+    </dependency>
+    <dependency>
+      <groupId>xmlbeans</groupId>
+      <artifactId>xmlbeans</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>ant</groupId>
+      <artifactId>ant-launcher</artifactId>
+      <version>1.6.5</version>
+    </dependency>
+    <dependency>
+      <groupId>ant</groupId>
+      <artifactId>ant-trax</artifactId>
+      <version>1.6.5</version>
+    </dependency>
+    <dependency>
+      <groupId>ant</groupId>
+      <artifactId>ant</artifactId>
+      <version>1.6.5</version>
+    </dependency>    
+    <dependency>
+      <groupId>jakarta-bcel</groupId>
+      <artifactId>jakarta-bcel</artifactId>
+      <version>20040329</version>
+    </dependency>
+    <dependency>
+      <groupId>mx4j</groupId>
+      <artifactId>mx4j-jmx</artifactId>
+      <version>3.0.1</version>
+      <!-- <scope>provided</scope> -->
+    </dependency>
+    <dependency>
+      <groupId>jetty</groupId>
+      <artifactId>org.mortbay.jmx</artifactId>
+      <version>5.1.8</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/non-releases/trunk_before_flattening/core/src/site/site.xml b/non-releases/trunk_before_flattening/core/src/site/site.xml
new file mode 100644
index 0000000..35f2bc5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/core/src/site/site.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Cocoon">
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/" />
+      <item name="Cocoon" href="http://cocoon.apache.org/"/>
+    </links>
+
+    ${reports}
+  </body>
+</project>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/core/test-core/pom.xml b/non-releases/trunk_before_flattening/core/test-core/pom.xml
new file mode 100644
index 0000000..cc8fdb1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/core/test-core/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | @version $Id$
+    |
+    +-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.cocoon</groupId>
+    <artifactId>cocoon</artifactId>
+    <version>2.2.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>cocoon-test-core</artifactId>
+  <packaging>jar</packaging>
+  <name>Core Tests</name>
+  <build>
+    <sourceDirectory>../../src/test</sourceDirectory>
+    <resources>
+      <resource>
+        <directory>../../src/test</directory>
+        <excludes>
+          <exclude>**/*.java</exclude>
+        </excludes>
+      </resource>
+    </resources>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cocoon</groupId>
+      <artifactId>cocoon-core</artifactId>
+      <version>2.2.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <version>1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>jmock</groupId>
+      <artifactId>jmock</artifactId>
+      <version>1.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+    </dependency>
+    <dependency>
+      <groupId>xmlunit</groupId>
+      <artifactId>xmlunit</artifactId>
+      <version>0.8</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/non-releases/trunk_before_flattening/init.xargs b/non-releases/trunk_before_flattening/init.xargs
new file mode 100644
index 0000000..8445697
--- /dev/null
+++ b/non-releases/trunk_before_flattening/init.xargs
@@ -0,0 +1,72 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+
+# ------------------------------------------------------------------------
+# Knopflerfish OSGI initialization file
+# This defines which packages to load at startup, options, etc.
+# ------------------------------------------------------------------------
+
+# load common properties
+-xargs props.xargs
+
+# Prefix for searching for bundle URLs from console or command line
+-Dorg.knopflerfish.gosg.jars=file:.
+
+-init
+
+# A minimal set of bundles to get the framework running and a tty console to interact with it
+
+## Basic KF bundles
+-initlevel 1
+-install lib/core/knopflerfish-log_all-1.0.0.jar
+-install lib/core/knopflerfish-cm_api-1.0.0.jar
+-install lib/core/knopflerfish-console_all-1.0.0.jar
+
+## Some library bundles
+-initlevel 2
+-install build/osgi/org.apache.cocoon_1.0.0.jar
+-install build/osgi/org.apache.cocoon.template_1.0.0.jar
+
+## HTTP Service
+-initlevel 4
+-install lib/core/knopflerfish-http_all-1.1.0.jar
+
+## console command bundles
+-initlevel 5
+-install lib/core/knopflerfish-frameworkcommands-1.0.0.jar
+-install lib/core/knopflerfish-logcommands-1.0.0.jar
+-install lib/core/knopflerfish-consoletty-1.0.0.jar
+
+-initlevel 7
+-install build/osgi/org.apache.cocoon_webapp_1.0.0.jar
+
+-initlevel 8
+-install build/osgi/org.apache.cocoon_servlet_1.0.0.jar
+
+-startlevel 9
+
+-launch
+
+# Start of these bundles are delayed since thise makes start
+# order dependencies much easier
+
+-start lib/core/knopflerfish-log_all-1.0.0.jar
+-start lib/core/knopflerfish-cm_api-1.0.0.jar
+-start lib/core/knopflerfish-console_all-1.0.0.jar
+-start lib/core/knopflerfish-consoletty-1.0.0.jar
+-start lib/core/knopflerfish-frameworkcommands-1.0.0.jar
+-start lib/core/knopflerfish-logcommands-1.0.0.jar
+-start lib/core/knopflerfish-http_all-1.1.0.jar
+-start build/osgi/org.apache.cocoon_webapp_1.0.0.jar
+-start build/osgi/org.apache.cocoon_servlet_1.0.0.jar
diff --git a/non-releases/trunk_before_flattening/legal/ant-contrib-0.6.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant-contrib-0.6.jar.license.txt
new file mode 100644
index 0000000..4d8c2fb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant-contrib-0.6.jar.license.txt
@@ -0,0 +1,47 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 Ant-Contrib project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Ant-Contrib project (http://sourceforge.net/projects/ant-contrib)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The name Ant-Contrib must not be used to endorse or promote products 
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact
+ *    ant-contrib-developers@lists.sourceforge.net.
+ *
+ * 5. Products derived from this software may not be called "Ant-Contrib"
+ *    nor may "Ant-Contrib" appear in their names without prior written
+ *    permission of the Ant-Contrib project.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE ANT-CONTRIB PROJECT OR ITS
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ */
diff --git a/non-releases/trunk_before_flattening/legal/ant-junit.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant-junit.jar.license.txt
new file mode 100644
index 0000000..f820d4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant-junit.jar.license.txt
@@ -0,0 +1,203 @@
+/*
+ *                                 Apache License
+ *                           Version 2.0, January 2004
+ *                        http://www.apache.org/licenses/
+ *
+ *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ *   1. Definitions.
+ *
+ *      "License" shall mean the terms and conditions for use, reproduction,
+ *      and distribution as defined by Sections 1 through 9 of this document.
+ *
+ *      "Licensor" shall mean the copyright owner or entity authorized by
+ *      the copyright owner that is granting the License.
+ *
+ *      "Legal Entity" shall mean the union of the acting entity and all
+ *      other entities that control, are controlled by, or are under common
+ *      control with that entity. For the purposes of this definition,
+ *      "control" means (i) the power, direct or indirect, to cause the
+ *      direction or management of such entity, whether by contract or
+ *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ *      outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ *      "You" (or "Your") shall mean an individual or Legal Entity
+ *      exercising permissions granted by this License.
+ *
+ *      "Source" form shall mean the preferred form for making modifications,
+ *      including but not limited to software source code, documentation
+ *      source, and configuration files.
+ *
+ *      "Object" form shall mean any form resulting from mechanical
+ *      transformation or translation of a Source form, including but
+ *      not limited to compiled object code, generated documentation,
+ *      and conversions to other media types.
+ *
+ *      "Work" shall mean the work of authorship, whether in Source or
+ *      Object form, made available under the License, as indicated by a
+ *      copyright notice that is included in or attached to the work
+ *      (an example is provided in the Appendix below).
+ *
+ *      "Derivative Works" shall mean any work, whether in Source or Object
+ *      form, that is based on (or derived from) the Work and for which the
+ *      editorial revisions, annotations, elaborations, or other modifications
+ *      represent, as a whole, an original work of authorship. For the purposes
+ *      of this License, Derivative Works shall not include works that remain
+ *      separable from, or merely link (or bind by name) to the interfaces of,
+ *      the Work and Derivative Works thereof.
+ *
+ *      "Contribution" shall mean any work of authorship, including
+ *      the original version of the Work and any modifications or additions
+ *      to that Work or Derivative Works thereof, that is intentionally
+ *      submitted to Licensor for inclusion in the Work by the copyright owner
+ *      or by an individual or Legal Entity authorized to submit on behalf of
+ *      the copyright owner. For the purposes of this definition, "submitted"
+ *      means any form of electronic, verbal, or written communication sent
+ *      to the Licensor or its representatives, including but not limited to
+ *      communication on electronic mailing lists, source code control systems,
+ *      and issue tracking systems that are managed by, or on behalf of, the
+ *      Licensor for the purpose of discussing and improving the Work, but
+ *      excluding communication that is conspicuously marked or otherwise
+ *      designated in writing by the copyright owner as "Not a Contribution."
+ *
+ *      "Contributor" shall mean Licensor and any individual or Legal Entity
+ *      on behalf of whom a Contribution has been received by Licensor and
+ *      subsequently incorporated within the Work.
+ *
+ *   2. Grant of Copyright License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      copyright license to reproduce, prepare Derivative Works of,
+ *      publicly display, publicly perform, sublicense, and distribute the
+ *      Work and such Derivative Works in Source or Object form.
+ *
+ *   3. Grant of Patent License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      (except as stated in this section) patent license to make, have made,
+ *      use, offer to sell, sell, import, and otherwise transfer the Work,
+ *      where such license applies only to those patent claims licensable
+ *      by such Contributor that are necessarily infringed by their
+ *      Contribution(s) alone or by combination of their Contribution(s)
+ *      with the Work to which such Contribution(s) was submitted. If You
+ *      institute patent litigation against any entity (including a
+ *      cross-claim or counterclaim in a lawsuit) alleging that the Work
+ *      or a Contribution incorporated within the Work constitutes direct
+ *      or contributory patent infringement, then any patent licenses
+ *      granted to You under this License for that Work shall terminate
+ *      as of the date such litigation is filed.
+ *
+ *   4. Redistribution. You may reproduce and distribute copies of the
+ *      Work or Derivative Works thereof in any medium, with or without
+ *      modifications, and in Source or Object form, provided that You
+ *      meet the following conditions:
+ *
+ *      (a) You must give any other recipients of the Work or
+ *          Derivative Works a copy of this License; and
+ *
+ *      (b) You must cause any modified files to carry prominent notices
+ *          stating that You changed the files; and
+ *
+ *      (c) You must retain, in the Source form of any Derivative Works
+ *          that You distribute, all copyright, patent, trademark, and
+ *          attribution notices from the Source form of the Work,
+ *          excluding those notices that do not pertain to any part of
+ *          the Derivative Works; and
+ *
+ *      (d) If the Work includes a "NOTICE" text file as part of its
+ *          distribution, then any Derivative Works that You distribute must
+ *          include a readable copy of the attribution notices contained
+ *          within such NOTICE file, excluding those notices that do not
+ *          pertain to any part of the Derivative Works, in at least one
+ *          of the following places: within a NOTICE text file distributed
+ *          as part of the Derivative Works; within the Source form or
+ *          documentation, if provided along with the Derivative Works; or,
+ *          within a display generated by the Derivative Works, if and
+ *          wherever such third-party notices normally appear. The contents
+ *          of the NOTICE file are for informational purposes only and
+ *          do not modify the License. You may add Your own attribution
+ *          notices within Derivative Works that You distribute, alongside
+ *          or as an addendum to the NOTICE text from the Work, provided
+ *          that such additional attribution notices cannot be construed
+ *          as modifying the License.
+ *
+ *      You may add Your own copyright statement to Your modifications and
+ *      may provide additional or different license terms and conditions
+ *      for use, reproduction, or distribution of Your modifications, or
+ *      for any such Derivative Works as a whole, provided Your use,
+ *      reproduction, and distribution of the Work otherwise complies with
+ *      the conditions stated in this License.
+ *
+ *   5. Submission of Contributions. Unless You explicitly state otherwise,
+ *      any Contribution intentionally submitted for inclusion in the Work
+ *      by You to the Licensor shall be under the terms and conditions of
+ *      this License, without any additional terms or conditions.
+ *      Notwithstanding the above, nothing herein shall supersede or modify
+ *      the terms of any separate license agreement you may have executed
+ *      with Licensor regarding such Contributions.
+ *
+ *   6. Trademarks. This License does not grant permission to use the trade
+ *      names, trademarks, service marks, or product names of the Licensor,
+ *      except as required for reasonable and customary use in describing the
+ *      origin of the Work and reproducing the content of the NOTICE file.
+ *
+ *   7. Disclaimer of Warranty. Unless required by applicable law or
+ *      agreed to in writing, Licensor provides the Work (and each
+ *      Contributor provides its Contributions) on an "AS IS" BASIS,
+ *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *      implied, including, without limitation, any warranties or conditions
+ *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ *      PARTICULAR PURPOSE. You are solely responsible for determining the
+ *      appropriateness of using or redistributing the Work and assume any
+ *      risks associated with Your exercise of permissions under this License.
+ *
+ *   8. Limitation of Liability. In no event and under no legal theory,
+ *      whether in tort (including negligence), contract, or otherwise,
+ *      unless required by applicable law (such as deliberate and grossly
+ *      negligent acts) or agreed to in writing, shall any Contributor be
+ *      liable to You for damages, including any direct, indirect, special,
+ *      incidental, or consequential damages of any character arising as a
+ *      result of this License or out of the use or inability to use the
+ *      Work (including but not limited to damages for loss of goodwill,
+ *      work stoppage, computer failure or malfunction, or any and all
+ *      other commercial damages or losses), even if such Contributor
+ *      has been advised of the possibility of such damages.
+ *
+ *   9. Accepting Warranty or Additional Liability. While redistributing
+ *      the Work or Derivative Works thereof, You may choose to offer,
+ *      and charge a fee for, acceptance of support, warranty, indemnity,
+ *      or other liability obligations and/or rights consistent with this
+ *      License. However, in accepting such obligations, You may act only
+ *      on Your own behalf and on Your sole responsibility, not on behalf
+ *      of any other Contributor, and only if You agree to indemnify,
+ *      defend, and hold each Contributor harmless for any liability
+ *      incurred by, or claims asserted against, such Contributor by reason
+ *      of your accepting any such warranty or additional liability.
+ *
+ *   END OF TERMS AND CONDITIONS
+ *
+ *   APPENDIX: How to apply the Apache License to your work.
+ *
+ *      To apply the Apache License to your work, attach the following
+ *      boilerplate notice, with the fields enclosed by brackets "[]"
+ *      replaced with your own identifying information. (Don't include
+ *      the brackets!)  The text should be enclosed in the appropriate
+ *      comment syntax for the file format. We also recommend that a
+ *      file or class name and description of purpose be included on the
+ *      same "printed page" as the copyright notice for easier
+ *      identification within third-party archives.
+ *
+ *   Copyright [yyyy] [name of copyright owner]
+ *
+ *   Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/ant-launcher.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant-launcher.jar.license.txt
new file mode 100644
index 0000000..f820d4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant-launcher.jar.license.txt
@@ -0,0 +1,203 @@
+/*
+ *                                 Apache License
+ *                           Version 2.0, January 2004
+ *                        http://www.apache.org/licenses/
+ *
+ *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ *   1. Definitions.
+ *
+ *      "License" shall mean the terms and conditions for use, reproduction,
+ *      and distribution as defined by Sections 1 through 9 of this document.
+ *
+ *      "Licensor" shall mean the copyright owner or entity authorized by
+ *      the copyright owner that is granting the License.
+ *
+ *      "Legal Entity" shall mean the union of the acting entity and all
+ *      other entities that control, are controlled by, or are under common
+ *      control with that entity. For the purposes of this definition,
+ *      "control" means (i) the power, direct or indirect, to cause the
+ *      direction or management of such entity, whether by contract or
+ *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ *      outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ *      "You" (or "Your") shall mean an individual or Legal Entity
+ *      exercising permissions granted by this License.
+ *
+ *      "Source" form shall mean the preferred form for making modifications,
+ *      including but not limited to software source code, documentation
+ *      source, and configuration files.
+ *
+ *      "Object" form shall mean any form resulting from mechanical
+ *      transformation or translation of a Source form, including but
+ *      not limited to compiled object code, generated documentation,
+ *      and conversions to other media types.
+ *
+ *      "Work" shall mean the work of authorship, whether in Source or
+ *      Object form, made available under the License, as indicated by a
+ *      copyright notice that is included in or attached to the work
+ *      (an example is provided in the Appendix below).
+ *
+ *      "Derivative Works" shall mean any work, whether in Source or Object
+ *      form, that is based on (or derived from) the Work and for which the
+ *      editorial revisions, annotations, elaborations, or other modifications
+ *      represent, as a whole, an original work of authorship. For the purposes
+ *      of this License, Derivative Works shall not include works that remain
+ *      separable from, or merely link (or bind by name) to the interfaces of,
+ *      the Work and Derivative Works thereof.
+ *
+ *      "Contribution" shall mean any work of authorship, including
+ *      the original version of the Work and any modifications or additions
+ *      to that Work or Derivative Works thereof, that is intentionally
+ *      submitted to Licensor for inclusion in the Work by the copyright owner
+ *      or by an individual or Legal Entity authorized to submit on behalf of
+ *      the copyright owner. For the purposes of this definition, "submitted"
+ *      means any form of electronic, verbal, or written communication sent
+ *      to the Licensor or its representatives, including but not limited to
+ *      communication on electronic mailing lists, source code control systems,
+ *      and issue tracking systems that are managed by, or on behalf of, the
+ *      Licensor for the purpose of discussing and improving the Work, but
+ *      excluding communication that is conspicuously marked or otherwise
+ *      designated in writing by the copyright owner as "Not a Contribution."
+ *
+ *      "Contributor" shall mean Licensor and any individual or Legal Entity
+ *      on behalf of whom a Contribution has been received by Licensor and
+ *      subsequently incorporated within the Work.
+ *
+ *   2. Grant of Copyright License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      copyright license to reproduce, prepare Derivative Works of,
+ *      publicly display, publicly perform, sublicense, and distribute the
+ *      Work and such Derivative Works in Source or Object form.
+ *
+ *   3. Grant of Patent License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      (except as stated in this section) patent license to make, have made,
+ *      use, offer to sell, sell, import, and otherwise transfer the Work,
+ *      where such license applies only to those patent claims licensable
+ *      by such Contributor that are necessarily infringed by their
+ *      Contribution(s) alone or by combination of their Contribution(s)
+ *      with the Work to which such Contribution(s) was submitted. If You
+ *      institute patent litigation against any entity (including a
+ *      cross-claim or counterclaim in a lawsuit) alleging that the Work
+ *      or a Contribution incorporated within the Work constitutes direct
+ *      or contributory patent infringement, then any patent licenses
+ *      granted to You under this License for that Work shall terminate
+ *      as of the date such litigation is filed.
+ *
+ *   4. Redistribution. You may reproduce and distribute copies of the
+ *      Work or Derivative Works thereof in any medium, with or without
+ *      modifications, and in Source or Object form, provided that You
+ *      meet the following conditions:
+ *
+ *      (a) You must give any other recipients of the Work or
+ *          Derivative Works a copy of this License; and
+ *
+ *      (b) You must cause any modified files to carry prominent notices
+ *          stating that You changed the files; and
+ *
+ *      (c) You must retain, in the Source form of any Derivative Works
+ *          that You distribute, all copyright, patent, trademark, and
+ *          attribution notices from the Source form of the Work,
+ *          excluding those notices that do not pertain to any part of
+ *          the Derivative Works; and
+ *
+ *      (d) If the Work includes a "NOTICE" text file as part of its
+ *          distribution, then any Derivative Works that You distribute must
+ *          include a readable copy of the attribution notices contained
+ *          within such NOTICE file, excluding those notices that do not
+ *          pertain to any part of the Derivative Works, in at least one
+ *          of the following places: within a NOTICE text file distributed
+ *          as part of the Derivative Works; within the Source form or
+ *          documentation, if provided along with the Derivative Works; or,
+ *          within a display generated by the Derivative Works, if and
+ *          wherever such third-party notices normally appear. The contents
+ *          of the NOTICE file are for informational purposes only and
+ *          do not modify the License. You may add Your own attribution
+ *          notices within Derivative Works that You distribute, alongside
+ *          or as an addendum to the NOTICE text from the Work, provided
+ *          that such additional attribution notices cannot be construed
+ *          as modifying the License.
+ *
+ *      You may add Your own copyright statement to Your modifications and
+ *      may provide additional or different license terms and conditions
+ *      for use, reproduction, or distribution of Your modifications, or
+ *      for any such Derivative Works as a whole, provided Your use,
+ *      reproduction, and distribution of the Work otherwise complies with
+ *      the conditions stated in this License.
+ *
+ *   5. Submission of Contributions. Unless You explicitly state otherwise,
+ *      any Contribution intentionally submitted for inclusion in the Work
+ *      by You to the Licensor shall be under the terms and conditions of
+ *      this License, without any additional terms or conditions.
+ *      Notwithstanding the above, nothing herein shall supersede or modify
+ *      the terms of any separate license agreement you may have executed
+ *      with Licensor regarding such Contributions.
+ *
+ *   6. Trademarks. This License does not grant permission to use the trade
+ *      names, trademarks, service marks, or product names of the Licensor,
+ *      except as required for reasonable and customary use in describing the
+ *      origin of the Work and reproducing the content of the NOTICE file.
+ *
+ *   7. Disclaimer of Warranty. Unless required by applicable law or
+ *      agreed to in writing, Licensor provides the Work (and each
+ *      Contributor provides its Contributions) on an "AS IS" BASIS,
+ *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *      implied, including, without limitation, any warranties or conditions
+ *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ *      PARTICULAR PURPOSE. You are solely responsible for determining the
+ *      appropriateness of using or redistributing the Work and assume any
+ *      risks associated with Your exercise of permissions under this License.
+ *
+ *   8. Limitation of Liability. In no event and under no legal theory,
+ *      whether in tort (including negligence), contract, or otherwise,
+ *      unless required by applicable law (such as deliberate and grossly
+ *      negligent acts) or agreed to in writing, shall any Contributor be
+ *      liable to You for damages, including any direct, indirect, special,
+ *      incidental, or consequential damages of any character arising as a
+ *      result of this License or out of the use or inability to use the
+ *      Work (including but not limited to damages for loss of goodwill,
+ *      work stoppage, computer failure or malfunction, or any and all
+ *      other commercial damages or losses), even if such Contributor
+ *      has been advised of the possibility of such damages.
+ *
+ *   9. Accepting Warranty or Additional Liability. While redistributing
+ *      the Work or Derivative Works thereof, You may choose to offer,
+ *      and charge a fee for, acceptance of support, warranty, indemnity,
+ *      or other liability obligations and/or rights consistent with this
+ *      License. However, in accepting such obligations, You may act only
+ *      on Your own behalf and on Your sole responsibility, not on behalf
+ *      of any other Contributor, and only if You agree to indemnify,
+ *      defend, and hold each Contributor harmless for any liability
+ *      incurred by, or claims asserted against, such Contributor by reason
+ *      of your accepting any such warranty or additional liability.
+ *
+ *   END OF TERMS AND CONDITIONS
+ *
+ *   APPENDIX: How to apply the Apache License to your work.
+ *
+ *      To apply the Apache License to your work, attach the following
+ *      boilerplate notice, with the fields enclosed by brackets "[]"
+ *      replaced with your own identifying information. (Don't include
+ *      the brackets!)  The text should be enclosed in the appropriate
+ *      comment syntax for the file format. We also recommend that a
+ *      file or class name and description of purpose be included on the
+ *      same "printed page" as the copyright notice for easier
+ *      identification within third-party archives.
+ *
+ *   Copyright [yyyy] [name of copyright owner]
+ *
+ *   Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/ant-nodeps.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant-nodeps.jar.license.txt
new file mode 100644
index 0000000..f820d4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant-nodeps.jar.license.txt
@@ -0,0 +1,203 @@
+/*
+ *                                 Apache License
+ *                           Version 2.0, January 2004
+ *                        http://www.apache.org/licenses/
+ *
+ *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ *   1. Definitions.
+ *
+ *      "License" shall mean the terms and conditions for use, reproduction,
+ *      and distribution as defined by Sections 1 through 9 of this document.
+ *
+ *      "Licensor" shall mean the copyright owner or entity authorized by
+ *      the copyright owner that is granting the License.
+ *
+ *      "Legal Entity" shall mean the union of the acting entity and all
+ *      other entities that control, are controlled by, or are under common
+ *      control with that entity. For the purposes of this definition,
+ *      "control" means (i) the power, direct or indirect, to cause the
+ *      direction or management of such entity, whether by contract or
+ *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ *      outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ *      "You" (or "Your") shall mean an individual or Legal Entity
+ *      exercising permissions granted by this License.
+ *
+ *      "Source" form shall mean the preferred form for making modifications,
+ *      including but not limited to software source code, documentation
+ *      source, and configuration files.
+ *
+ *      "Object" form shall mean any form resulting from mechanical
+ *      transformation or translation of a Source form, including but
+ *      not limited to compiled object code, generated documentation,
+ *      and conversions to other media types.
+ *
+ *      "Work" shall mean the work of authorship, whether in Source or
+ *      Object form, made available under the License, as indicated by a
+ *      copyright notice that is included in or attached to the work
+ *      (an example is provided in the Appendix below).
+ *
+ *      "Derivative Works" shall mean any work, whether in Source or Object
+ *      form, that is based on (or derived from) the Work and for which the
+ *      editorial revisions, annotations, elaborations, or other modifications
+ *      represent, as a whole, an original work of authorship. For the purposes
+ *      of this License, Derivative Works shall not include works that remain
+ *      separable from, or merely link (or bind by name) to the interfaces of,
+ *      the Work and Derivative Works thereof.
+ *
+ *      "Contribution" shall mean any work of authorship, including
+ *      the original version of the Work and any modifications or additions
+ *      to that Work or Derivative Works thereof, that is intentionally
+ *      submitted to Licensor for inclusion in the Work by the copyright owner
+ *      or by an individual or Legal Entity authorized to submit on behalf of
+ *      the copyright owner. For the purposes of this definition, "submitted"
+ *      means any form of electronic, verbal, or written communication sent
+ *      to the Licensor or its representatives, including but not limited to
+ *      communication on electronic mailing lists, source code control systems,
+ *      and issue tracking systems that are managed by, or on behalf of, the
+ *      Licensor for the purpose of discussing and improving the Work, but
+ *      excluding communication that is conspicuously marked or otherwise
+ *      designated in writing by the copyright owner as "Not a Contribution."
+ *
+ *      "Contributor" shall mean Licensor and any individual or Legal Entity
+ *      on behalf of whom a Contribution has been received by Licensor and
+ *      subsequently incorporated within the Work.
+ *
+ *   2. Grant of Copyright License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      copyright license to reproduce, prepare Derivative Works of,
+ *      publicly display, publicly perform, sublicense, and distribute the
+ *      Work and such Derivative Works in Source or Object form.
+ *
+ *   3. Grant of Patent License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      (except as stated in this section) patent license to make, have made,
+ *      use, offer to sell, sell, import, and otherwise transfer the Work,
+ *      where such license applies only to those patent claims licensable
+ *      by such Contributor that are necessarily infringed by their
+ *      Contribution(s) alone or by combination of their Contribution(s)
+ *      with the Work to which such Contribution(s) was submitted. If You
+ *      institute patent litigation against any entity (including a
+ *      cross-claim or counterclaim in a lawsuit) alleging that the Work
+ *      or a Contribution incorporated within the Work constitutes direct
+ *      or contributory patent infringement, then any patent licenses
+ *      granted to You under this License for that Work shall terminate
+ *      as of the date such litigation is filed.
+ *
+ *   4. Redistribution. You may reproduce and distribute copies of the
+ *      Work or Derivative Works thereof in any medium, with or without
+ *      modifications, and in Source or Object form, provided that You
+ *      meet the following conditions:
+ *
+ *      (a) You must give any other recipients of the Work or
+ *          Derivative Works a copy of this License; and
+ *
+ *      (b) You must cause any modified files to carry prominent notices
+ *          stating that You changed the files; and
+ *
+ *      (c) You must retain, in the Source form of any Derivative Works
+ *          that You distribute, all copyright, patent, trademark, and
+ *          attribution notices from the Source form of the Work,
+ *          excluding those notices that do not pertain to any part of
+ *          the Derivative Works; and
+ *
+ *      (d) If the Work includes a "NOTICE" text file as part of its
+ *          distribution, then any Derivative Works that You distribute must
+ *          include a readable copy of the attribution notices contained
+ *          within such NOTICE file, excluding those notices that do not
+ *          pertain to any part of the Derivative Works, in at least one
+ *          of the following places: within a NOTICE text file distributed
+ *          as part of the Derivative Works; within the Source form or
+ *          documentation, if provided along with the Derivative Works; or,
+ *          within a display generated by the Derivative Works, if and
+ *          wherever such third-party notices normally appear. The contents
+ *          of the NOTICE file are for informational purposes only and
+ *          do not modify the License. You may add Your own attribution
+ *          notices within Derivative Works that You distribute, alongside
+ *          or as an addendum to the NOTICE text from the Work, provided
+ *          that such additional attribution notices cannot be construed
+ *          as modifying the License.
+ *
+ *      You may add Your own copyright statement to Your modifications and
+ *      may provide additional or different license terms and conditions
+ *      for use, reproduction, or distribution of Your modifications, or
+ *      for any such Derivative Works as a whole, provided Your use,
+ *      reproduction, and distribution of the Work otherwise complies with
+ *      the conditions stated in this License.
+ *
+ *   5. Submission of Contributions. Unless You explicitly state otherwise,
+ *      any Contribution intentionally submitted for inclusion in the Work
+ *      by You to the Licensor shall be under the terms and conditions of
+ *      this License, without any additional terms or conditions.
+ *      Notwithstanding the above, nothing herein shall supersede or modify
+ *      the terms of any separate license agreement you may have executed
+ *      with Licensor regarding such Contributions.
+ *
+ *   6. Trademarks. This License does not grant permission to use the trade
+ *      names, trademarks, service marks, or product names of the Licensor,
+ *      except as required for reasonable and customary use in describing the
+ *      origin of the Work and reproducing the content of the NOTICE file.
+ *
+ *   7. Disclaimer of Warranty. Unless required by applicable law or
+ *      agreed to in writing, Licensor provides the Work (and each
+ *      Contributor provides its Contributions) on an "AS IS" BASIS,
+ *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *      implied, including, without limitation, any warranties or conditions
+ *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ *      PARTICULAR PURPOSE. You are solely responsible for determining the
+ *      appropriateness of using or redistributing the Work and assume any
+ *      risks associated with Your exercise of permissions under this License.
+ *
+ *   8. Limitation of Liability. In no event and under no legal theory,
+ *      whether in tort (including negligence), contract, or otherwise,
+ *      unless required by applicable law (such as deliberate and grossly
+ *      negligent acts) or agreed to in writing, shall any Contributor be
+ *      liable to You for damages, including any direct, indirect, special,
+ *      incidental, or consequential damages of any character arising as a
+ *      result of this License or out of the use or inability to use the
+ *      Work (including but not limited to damages for loss of goodwill,
+ *      work stoppage, computer failure or malfunction, or any and all
+ *      other commercial damages or losses), even if such Contributor
+ *      has been advised of the possibility of such damages.
+ *
+ *   9. Accepting Warranty or Additional Liability. While redistributing
+ *      the Work or Derivative Works thereof, You may choose to offer,
+ *      and charge a fee for, acceptance of support, warranty, indemnity,
+ *      or other liability obligations and/or rights consistent with this
+ *      License. However, in accepting such obligations, You may act only
+ *      on Your own behalf and on Your sole responsibility, not on behalf
+ *      of any other Contributor, and only if You agree to indemnify,
+ *      defend, and hold each Contributor harmless for any liability
+ *      incurred by, or claims asserted against, such Contributor by reason
+ *      of your accepting any such warranty or additional liability.
+ *
+ *   END OF TERMS AND CONDITIONS
+ *
+ *   APPENDIX: How to apply the Apache License to your work.
+ *
+ *      To apply the Apache License to your work, attach the following
+ *      boilerplate notice, with the fields enclosed by brackets "[]"
+ *      replaced with your own identifying information. (Don't include
+ *      the brackets!)  The text should be enclosed in the appropriate
+ *      comment syntax for the file format. We also recommend that a
+ *      file or class name and description of purpose be included on the
+ *      same "printed page" as the copyright notice for easier
+ *      identification within third-party archives.
+ *
+ *   Copyright [yyyy] [name of copyright owner]
+ *
+ *   Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/ant-trax.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant-trax.jar.license.txt
new file mode 100644
index 0000000..f820d4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant-trax.jar.license.txt
@@ -0,0 +1,203 @@
+/*
+ *                                 Apache License
+ *                           Version 2.0, January 2004
+ *                        http://www.apache.org/licenses/
+ *
+ *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ *   1. Definitions.
+ *
+ *      "License" shall mean the terms and conditions for use, reproduction,
+ *      and distribution as defined by Sections 1 through 9 of this document.
+ *
+ *      "Licensor" shall mean the copyright owner or entity authorized by
+ *      the copyright owner that is granting the License.
+ *
+ *      "Legal Entity" shall mean the union of the acting entity and all
+ *      other entities that control, are controlled by, or are under common
+ *      control with that entity. For the purposes of this definition,
+ *      "control" means (i) the power, direct or indirect, to cause the
+ *      direction or management of such entity, whether by contract or
+ *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ *      outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ *      "You" (or "Your") shall mean an individual or Legal Entity
+ *      exercising permissions granted by this License.
+ *
+ *      "Source" form shall mean the preferred form for making modifications,
+ *      including but not limited to software source code, documentation
+ *      source, and configuration files.
+ *
+ *      "Object" form shall mean any form resulting from mechanical
+ *      transformation or translation of a Source form, including but
+ *      not limited to compiled object code, generated documentation,
+ *      and conversions to other media types.
+ *
+ *      "Work" shall mean the work of authorship, whether in Source or
+ *      Object form, made available under the License, as indicated by a
+ *      copyright notice that is included in or attached to the work
+ *      (an example is provided in the Appendix below).
+ *
+ *      "Derivative Works" shall mean any work, whether in Source or Object
+ *      form, that is based on (or derived from) the Work and for which the
+ *      editorial revisions, annotations, elaborations, or other modifications
+ *      represent, as a whole, an original work of authorship. For the purposes
+ *      of this License, Derivative Works shall not include works that remain
+ *      separable from, or merely link (or bind by name) to the interfaces of,
+ *      the Work and Derivative Works thereof.
+ *
+ *      "Contribution" shall mean any work of authorship, including
+ *      the original version of the Work and any modifications or additions
+ *      to that Work or Derivative Works thereof, that is intentionally
+ *      submitted to Licensor for inclusion in the Work by the copyright owner
+ *      or by an individual or Legal Entity authorized to submit on behalf of
+ *      the copyright owner. For the purposes of this definition, "submitted"
+ *      means any form of electronic, verbal, or written communication sent
+ *      to the Licensor or its representatives, including but not limited to
+ *      communication on electronic mailing lists, source code control systems,
+ *      and issue tracking systems that are managed by, or on behalf of, the
+ *      Licensor for the purpose of discussing and improving the Work, but
+ *      excluding communication that is conspicuously marked or otherwise
+ *      designated in writing by the copyright owner as "Not a Contribution."
+ *
+ *      "Contributor" shall mean Licensor and any individual or Legal Entity
+ *      on behalf of whom a Contribution has been received by Licensor and
+ *      subsequently incorporated within the Work.
+ *
+ *   2. Grant of Copyright License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      copyright license to reproduce, prepare Derivative Works of,
+ *      publicly display, publicly perform, sublicense, and distribute the
+ *      Work and such Derivative Works in Source or Object form.
+ *
+ *   3. Grant of Patent License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      (except as stated in this section) patent license to make, have made,
+ *      use, offer to sell, sell, import, and otherwise transfer the Work,
+ *      where such license applies only to those patent claims licensable
+ *      by such Contributor that are necessarily infringed by their
+ *      Contribution(s) alone or by combination of their Contribution(s)
+ *      with the Work to which such Contribution(s) was submitted. If You
+ *      institute patent litigation against any entity (including a
+ *      cross-claim or counterclaim in a lawsuit) alleging that the Work
+ *      or a Contribution incorporated within the Work constitutes direct
+ *      or contributory patent infringement, then any patent licenses
+ *      granted to You under this License for that Work shall terminate
+ *      as of the date such litigation is filed.
+ *
+ *   4. Redistribution. You may reproduce and distribute copies of the
+ *      Work or Derivative Works thereof in any medium, with or without
+ *      modifications, and in Source or Object form, provided that You
+ *      meet the following conditions:
+ *
+ *      (a) You must give any other recipients of the Work or
+ *          Derivative Works a copy of this License; and
+ *
+ *      (b) You must cause any modified files to carry prominent notices
+ *          stating that You changed the files; and
+ *
+ *      (c) You must retain, in the Source form of any Derivative Works
+ *          that You distribute, all copyright, patent, trademark, and
+ *          attribution notices from the Source form of the Work,
+ *          excluding those notices that do not pertain to any part of
+ *          the Derivative Works; and
+ *
+ *      (d) If the Work includes a "NOTICE" text file as part of its
+ *          distribution, then any Derivative Works that You distribute must
+ *          include a readable copy of the attribution notices contained
+ *          within such NOTICE file, excluding those notices that do not
+ *          pertain to any part of the Derivative Works, in at least one
+ *          of the following places: within a NOTICE text file distributed
+ *          as part of the Derivative Works; within the Source form or
+ *          documentation, if provided along with the Derivative Works; or,
+ *          within a display generated by the Derivative Works, if and
+ *          wherever such third-party notices normally appear. The contents
+ *          of the NOTICE file are for informational purposes only and
+ *          do not modify the License. You may add Your own attribution
+ *          notices within Derivative Works that You distribute, alongside
+ *          or as an addendum to the NOTICE text from the Work, provided
+ *          that such additional attribution notices cannot be construed
+ *          as modifying the License.
+ *
+ *      You may add Your own copyright statement to Your modifications and
+ *      may provide additional or different license terms and conditions
+ *      for use, reproduction, or distribution of Your modifications, or
+ *      for any such Derivative Works as a whole, provided Your use,
+ *      reproduction, and distribution of the Work otherwise complies with
+ *      the conditions stated in this License.
+ *
+ *   5. Submission of Contributions. Unless You explicitly state otherwise,
+ *      any Contribution intentionally submitted for inclusion in the Work
+ *      by You to the Licensor shall be under the terms and conditions of
+ *      this License, without any additional terms or conditions.
+ *      Notwithstanding the above, nothing herein shall supersede or modify
+ *      the terms of any separate license agreement you may have executed
+ *      with Licensor regarding such Contributions.
+ *
+ *   6. Trademarks. This License does not grant permission to use the trade
+ *      names, trademarks, service marks, or product names of the Licensor,
+ *      except as required for reasonable and customary use in describing the
+ *      origin of the Work and reproducing the content of the NOTICE file.
+ *
+ *   7. Disclaimer of Warranty. Unless required by applicable law or
+ *      agreed to in writing, Licensor provides the Work (and each
+ *      Contributor provides its Contributions) on an "AS IS" BASIS,
+ *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *      implied, including, without limitation, any warranties or conditions
+ *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ *      PARTICULAR PURPOSE. You are solely responsible for determining the
+ *      appropriateness of using or redistributing the Work and assume any
+ *      risks associated with Your exercise of permissions under this License.
+ *
+ *   8. Limitation of Liability. In no event and under no legal theory,
+ *      whether in tort (including negligence), contract, or otherwise,
+ *      unless required by applicable law (such as deliberate and grossly
+ *      negligent acts) or agreed to in writing, shall any Contributor be
+ *      liable to You for damages, including any direct, indirect, special,
+ *      incidental, or consequential damages of any character arising as a
+ *      result of this License or out of the use or inability to use the
+ *      Work (including but not limited to damages for loss of goodwill,
+ *      work stoppage, computer failure or malfunction, or any and all
+ *      other commercial damages or losses), even if such Contributor
+ *      has been advised of the possibility of such damages.
+ *
+ *   9. Accepting Warranty or Additional Liability. While redistributing
+ *      the Work or Derivative Works thereof, You may choose to offer,
+ *      and charge a fee for, acceptance of support, warranty, indemnity,
+ *      or other liability obligations and/or rights consistent with this
+ *      License. However, in accepting such obligations, You may act only
+ *      on Your own behalf and on Your sole responsibility, not on behalf
+ *      of any other Contributor, and only if You agree to indemnify,
+ *      defend, and hold each Contributor harmless for any liability
+ *      incurred by, or claims asserted against, such Contributor by reason
+ *      of your accepting any such warranty or additional liability.
+ *
+ *   END OF TERMS AND CONDITIONS
+ *
+ *   APPENDIX: How to apply the Apache License to your work.
+ *
+ *      To apply the Apache License to your work, attach the following
+ *      boilerplate notice, with the fields enclosed by brackets "[]"
+ *      replaced with your own identifying information. (Don't include
+ *      the brackets!)  The text should be enclosed in the appropriate
+ *      comment syntax for the file format. We also recommend that a
+ *      file or class name and description of purpose be included on the
+ *      same "printed page" as the copyright notice for easier
+ *      identification within third-party archives.
+ *
+ *   Copyright [yyyy] [name of copyright owner]
+ *
+ *   Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/ant.jar.license.txt b/non-releases/trunk_before_flattening/legal/ant.jar.license.txt
new file mode 100644
index 0000000..f820d4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ant.jar.license.txt
@@ -0,0 +1,203 @@
+/*
+ *                                 Apache License
+ *                           Version 2.0, January 2004
+ *                        http://www.apache.org/licenses/
+ *
+ *   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ *   1. Definitions.
+ *
+ *      "License" shall mean the terms and conditions for use, reproduction,
+ *      and distribution as defined by Sections 1 through 9 of this document.
+ *
+ *      "Licensor" shall mean the copyright owner or entity authorized by
+ *      the copyright owner that is granting the License.
+ *
+ *      "Legal Entity" shall mean the union of the acting entity and all
+ *      other entities that control, are controlled by, or are under common
+ *      control with that entity. For the purposes of this definition,
+ *      "control" means (i) the power, direct or indirect, to cause the
+ *      direction or management of such entity, whether by contract or
+ *      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ *      outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ *      "You" (or "Your") shall mean an individual or Legal Entity
+ *      exercising permissions granted by this License.
+ *
+ *      "Source" form shall mean the preferred form for making modifications,
+ *      including but not limited to software source code, documentation
+ *      source, and configuration files.
+ *
+ *      "Object" form shall mean any form resulting from mechanical
+ *      transformation or translation of a Source form, including but
+ *      not limited to compiled object code, generated documentation,
+ *      and conversions to other media types.
+ *
+ *      "Work" shall mean the work of authorship, whether in Source or
+ *      Object form, made available under the License, as indicated by a
+ *      copyright notice that is included in or attached to the work
+ *      (an example is provided in the Appendix below).
+ *
+ *      "Derivative Works" shall mean any work, whether in Source or Object
+ *      form, that is based on (or derived from) the Work and for which the
+ *      editorial revisions, annotations, elaborations, or other modifications
+ *      represent, as a whole, an original work of authorship. For the purposes
+ *      of this License, Derivative Works shall not include works that remain
+ *      separable from, or merely link (or bind by name) to the interfaces of,
+ *      the Work and Derivative Works thereof.
+ *
+ *      "Contribution" shall mean any work of authorship, including
+ *      the original version of the Work and any modifications or additions
+ *      to that Work or Derivative Works thereof, that is intentionally
+ *      submitted to Licensor for inclusion in the Work by the copyright owner
+ *      or by an individual or Legal Entity authorized to submit on behalf of
+ *      the copyright owner. For the purposes of this definition, "submitted"
+ *      means any form of electronic, verbal, or written communication sent
+ *      to the Licensor or its representatives, including but not limited to
+ *      communication on electronic mailing lists, source code control systems,
+ *      and issue tracking systems that are managed by, or on behalf of, the
+ *      Licensor for the purpose of discussing and improving the Work, but
+ *      excluding communication that is conspicuously marked or otherwise
+ *      designated in writing by the copyright owner as "Not a Contribution."
+ *
+ *      "Contributor" shall mean Licensor and any individual or Legal Entity
+ *      on behalf of whom a Contribution has been received by Licensor and
+ *      subsequently incorporated within the Work.
+ *
+ *   2. Grant of Copyright License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      copyright license to reproduce, prepare Derivative Works of,
+ *      publicly display, publicly perform, sublicense, and distribute the
+ *      Work and such Derivative Works in Source or Object form.
+ *
+ *   3. Grant of Patent License. Subject to the terms and conditions of
+ *      this License, each Contributor hereby grants to You a perpetual,
+ *      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ *      (except as stated in this section) patent license to make, have made,
+ *      use, offer to sell, sell, import, and otherwise transfer the Work,
+ *      where such license applies only to those patent claims licensable
+ *      by such Contributor that are necessarily infringed by their
+ *      Contribution(s) alone or by combination of their Contribution(s)
+ *      with the Work to which such Contribution(s) was submitted. If You
+ *      institute patent litigation against any entity (including a
+ *      cross-claim or counterclaim in a lawsuit) alleging that the Work
+ *      or a Contribution incorporated within the Work constitutes direct
+ *      or contributory patent infringement, then any patent licenses
+ *      granted to You under this License for that Work shall terminate
+ *      as of the date such litigation is filed.
+ *
+ *   4. Redistribution. You may reproduce and distribute copies of the
+ *      Work or Derivative Works thereof in any medium, with or without
+ *      modifications, and in Source or Object form, provided that You
+ *      meet the following conditions:
+ *
+ *      (a) You must give any other recipients of the Work or
+ *          Derivative Works a copy of this License; and
+ *
+ *      (b) You must cause any modified files to carry prominent notices
+ *          stating that You changed the files; and
+ *
+ *      (c) You must retain, in the Source form of any Derivative Works
+ *          that You distribute, all copyright, patent, trademark, and
+ *          attribution notices from the Source form of the Work,
+ *          excluding those notices that do not pertain to any part of
+ *          the Derivative Works; and
+ *
+ *      (d) If the Work includes a "NOTICE" text file as part of its
+ *          distribution, then any Derivative Works that You distribute must
+ *          include a readable copy of the attribution notices contained
+ *          within such NOTICE file, excluding those notices that do not
+ *          pertain to any part of the Derivative Works, in at least one
+ *          of the following places: within a NOTICE text file distributed
+ *          as part of the Derivative Works; within the Source form or
+ *          documentation, if provided along with the Derivative Works; or,
+ *          within a display generated by the Derivative Works, if and
+ *          wherever such third-party notices normally appear. The contents
+ *          of the NOTICE file are for informational purposes only and
+ *          do not modify the License. You may add Your own attribution
+ *          notices within Derivative Works that You distribute, alongside
+ *          or as an addendum to the NOTICE text from the Work, provided
+ *          that such additional attribution notices cannot be construed
+ *          as modifying the License.
+ *
+ *      You may add Your own copyright statement to Your modifications and
+ *      may provide additional or different license terms and conditions
+ *      for use, reproduction, or distribution of Your modifications, or
+ *      for any such Derivative Works as a whole, provided Your use,
+ *      reproduction, and distribution of the Work otherwise complies with
+ *      the conditions stated in this License.
+ *
+ *   5. Submission of Contributions. Unless You explicitly state otherwise,
+ *      any Contribution intentionally submitted for inclusion in the Work
+ *      by You to the Licensor shall be under the terms and conditions of
+ *      this License, without any additional terms or conditions.
+ *      Notwithstanding the above, nothing herein shall supersede or modify
+ *      the terms of any separate license agreement you may have executed
+ *      with Licensor regarding such Contributions.
+ *
+ *   6. Trademarks. This License does not grant permission to use the trade
+ *      names, trademarks, service marks, or product names of the Licensor,
+ *      except as required for reasonable and customary use in describing the
+ *      origin of the Work and reproducing the content of the NOTICE file.
+ *
+ *   7. Disclaimer of Warranty. Unless required by applicable law or
+ *      agreed to in writing, Licensor provides the Work (and each
+ *      Contributor provides its Contributions) on an "AS IS" BASIS,
+ *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ *      implied, including, without limitation, any warranties or conditions
+ *      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ *      PARTICULAR PURPOSE. You are solely responsible for determining the
+ *      appropriateness of using or redistributing the Work and assume any
+ *      risks associated with Your exercise of permissions under this License.
+ *
+ *   8. Limitation of Liability. In no event and under no legal theory,
+ *      whether in tort (including negligence), contract, or otherwise,
+ *      unless required by applicable law (such as deliberate and grossly
+ *      negligent acts) or agreed to in writing, shall any Contributor be
+ *      liable to You for damages, including any direct, indirect, special,
+ *      incidental, or consequential damages of any character arising as a
+ *      result of this License or out of the use or inability to use the
+ *      Work (including but not limited to damages for loss of goodwill,
+ *      work stoppage, computer failure or malfunction, or any and all
+ *      other commercial damages or losses), even if such Contributor
+ *      has been advised of the possibility of such damages.
+ *
+ *   9. Accepting Warranty or Additional Liability. While redistributing
+ *      the Work or Derivative Works thereof, You may choose to offer,
+ *      and charge a fee for, acceptance of support, warranty, indemnity,
+ *      or other liability obligations and/or rights consistent with this
+ *      License. However, in accepting such obligations, You may act only
+ *      on Your own behalf and on Your sole responsibility, not on behalf
+ *      of any other Contributor, and only if You agree to indemnify,
+ *      defend, and hold each Contributor harmless for any liability
+ *      incurred by, or claims asserted against, such Contributor by reason
+ *      of your accepting any such warranty or additional liability.
+ *
+ *   END OF TERMS AND CONDITIONS
+ *
+ *   APPENDIX: How to apply the Apache License to your work.
+ *
+ *      To apply the Apache License to your work, attach the following
+ *      boilerplate notice, with the fields enclosed by brackets "[]"
+ *      replaced with your own identifying information. (Don't include
+ *      the brackets!)  The text should be enclosed in the appropriate
+ *      comment syntax for the file format. We also recommend that a
+ *      file or class name and description of purpose be included on the
+ *      same "printed page" as the copyright notice for easier
+ *      identification within third-party archives.
+ *
+ *   Copyright [yyyy] [name of copyright owner]
+ *
+ *   Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/antlr-2.7.5.jar.license.txt b/non-releases/trunk_before_flattening/legal/antlr-2.7.5.jar.license.txt
new file mode 100644
index 0000000..04b0357
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/antlr-2.7.5.jar.license.txt
@@ -0,0 +1,31 @@
+
+SOFTWARE RIGHTS
+
+ANTLR 1989-2004 Developed by Terence Parr
+Partially supported by University of San Francisco & jGuru.com
+
+We reserve no legal rights to the ANTLR--it is fully in the
+public domain. An individual or company may do whatever
+they wish with source code distributed with ANTLR or the
+code generated by ANTLR, including the incorporation of
+ANTLR, or its output, into commerical software.
+
+We encourage users to develop software with ANTLR. However,
+we do ask that credit is given to us for developing
+ANTLR. By "credit", we mean that if you use ANTLR or
+incorporate any source code into one of your programs
+(commercial product, research project, or otherwise) that
+you acknowledge this fact somewhere in the documentation,
+research report, etc... If you like ANTLR and have
+developed a nice tool with the output, please mention that
+you developed it using ANTLR. In addition, we ask that the
+headers remain intact in our source code. As long as these
+guidelines are kept, we expect to continue enhancing this
+system and expect to make other tools available as they are
+completed.
+
+The primary ANTLR guy:
+
+Terence Parr
+parrt@cs.usfca.edu
+parrt@antlr.org
diff --git a/non-releases/trunk_before_flattening/legal/asm-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/asm-2.1.jar.license.txt
new file mode 100644
index 0000000..d0cd82d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/asm-2.1.jar.license.txt
@@ -0,0 +1,28 @@
+
+ ASM: a very small and fast Java bytecode manipulation framework
+ Copyright (c) 2000-2005 INRIA, France Telecom
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/asm-util-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/asm-util-2.1.jar.license.txt
new file mode 100644
index 0000000..d0cd82d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/asm-util-2.1.jar.license.txt
@@ -0,0 +1,28 @@
+
+ ASM: a very small and fast Java bytecode manipulation framework
+ Copyright (c) 2000-2005 INRIA, France Telecom
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/avalon-framework-api-4.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/avalon-framework-api-4.3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/avalon-framework-api-4.3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/avalon-framework-impl-4.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/avalon-framework-impl-4.3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/avalon-framework-impl-4.3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/avalon-logkit-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/avalon-logkit-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/avalon-logkit-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/axis-1.2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/axis-1.2.1.jar.license.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/axis-1.2.1.jar.license.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/non-releases/trunk_before_flattening/legal/axis-jaxrpc-1.2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/axis-jaxrpc-1.2.1.jar.license.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/axis-jaxrpc-1.2.1.jar.license.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/non-releases/trunk_before_flattening/legal/axis-saaj-1.2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/axis-saaj-1.2.1.jar.license.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/axis-saaj-1.2.1.jar.license.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/non-releases/trunk_before_flattening/legal/batik-all-1.6.jar.license.txt b/non-releases/trunk_before_flattening/legal/batik-all-1.6.jar.license.txt
new file mode 100644
index 0000000..3e4e3d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/batik-all-1.6.jar.license.txt
@@ -0,0 +1,201 @@
+                                  Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/bsf-2.3.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/bsf-2.3.0.jar.license.txt
new file mode 100644
index 0000000..77ef125
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/bsf-2.3.0.jar.license.txt
@@ -0,0 +1,53 @@
+   The Apache Software License, Version 1.1
+  
+   Copyright (c) 2002 The Apache Software Foundation.  All rights
+   reserved.
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+  
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+  
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+  
+   3. The end-user documentation included with the redistribution,
+      if any, must include the following acknowledgment:
+         "This product includes software developed by the
+          Apache Software Foundation (http://www.apache.org/)."
+      Alternately, this acknowledgment may appear in the software itself,
+      if and wherever such third-party acknowledgments normally appear.
+  
+   4. The names "BSF", "Apache", and "Apache Software Foundation" must
+      not be used to endorse or promote products derived from this
+      software without prior written permission. For written
+      permission, please contact apache@apache.org.
+  
+   5. Products derived from this software may not be called "Apache",
+      nor may "Apache" appear in their name, without prior written
+      permission of the Apache Software Foundation.
+  
+   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+   DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+   ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ Sanjiva Weerawarana and others at International Business Machines
+ Corporation. For more information on the Apache Software Foundation,
+ please see <http://www.apache.org/>.
+
+
diff --git a/non-releases/trunk_before_flattening/legal/castor-0.9.6-xml.jar.license.txt b/non-releases/trunk_before_flattening/legal/castor-0.9.6-xml.jar.license.txt
new file mode 100644
index 0000000..31eed69
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/castor-0.9.6-xml.jar.license.txt
@@ -0,0 +1,38 @@
+Copyright 1999-2004 (C) Intalio Inc., and others. All Rights Reserved.
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions of source code must retain copyright statements
+   and notices. Redistributions must also contain a copy of this
+   document.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. The name "ExoLab" must not be used to endorse or promote products
+   derived from this Software without prior written permission of
+   Intalio Inc. For written permission, please contact info@exolab.org.
+
+4. Products derived from this Software may not be called "Castor"
+   nor may "Castor" appear in their names without prior written
+   permission of Intalio Inc. Exolab, Castor and Intalio are
+   trademarks of Intalio Inc.
+
+5. Due credit should be given to the ExoLab Project
+   (http://www.exolab.org/).
+
+THIS SOFTWARE IS PROVIDED BY INTALIO AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO OR ITS
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/chaperon-20040205.jar.license.txt b/non-releases/trunk_before_flattening/legal/chaperon-20040205.jar.license.txt
new file mode 100644
index 0000000..b31c83d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/chaperon-20040205.jar.license.txt
@@ -0,0 +1,48 @@
+/*
+ * Chaperon. Apache-Style Software License
+ *
+ *
+ * Copyright (c) 2002 Chaperon. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by 
+ *        Chaperon (http://www.sourceforge.net/projects/chaperon/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "Chaperon" must not be used to endorse 
+ *    or promote products derived from this software without prior written 
+ *    permission.  For written permission, please contact 
+ *    stephan@vern.chem.tu-berlin.de.
+ *
+ * 5. Products derived from this software may not be called "Chaperon",
+ *    nor may "Chaperon" appear in their name, without prior written
+ *    permission of stephan@vern.chem.tu-berlin.de.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE CHAPERON PROJECT OR ITS CONTRIBUTORS 
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
diff --git a/non-releases/trunk_before_flattening/legal/commons-beanutils-core-1.7.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-beanutils-core-1.7.0.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-beanutils-core-1.7.0.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-betwixt-0.6.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-betwixt-0.6.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-betwixt-0.6.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-cli-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-cli-1.0.jar.license.txt
new file mode 100644
index 0000000..c2dc940
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-cli-1.0.jar.license.txt
@@ -0,0 +1,60 @@
+/*
+ * $Header: /home/cvs/cocoon-2.1/legal/commons-cli-1.0.jar.license.txt,v 1.1 2004/03/04 08:08:51 cziegeler Exp $
+ * $Revision: 1.1 $
+ * $Date: 2004/03/04 08:08:51 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
diff --git a/non-releases/trunk_before_flattening/legal/commons-codec-1.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-codec-1.3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-codec-1.3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-collections-3.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-collections-3.1.jar.license.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-collections-3.1.jar.license.txt
@@ -0,0 +1,202 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

diff --git a/non-releases/trunk_before_flattening/legal/commons-dbcp-1.2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-dbcp-1.2.1.jar.license.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-dbcp-1.2.1.jar.license.txt
@@ -0,0 +1,202 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

diff --git a/non-releases/trunk_before_flattening/legal/commons-digester-1.7.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-digester-1.7.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-digester-1.7.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-discovery-0.2.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-discovery-0.2.jar.license.txt
new file mode 100644
index 0000000..c778cee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-discovery-0.2.jar.license.txt
@@ -0,0 +1,54 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
diff --git a/non-releases/trunk_before_flattening/legal/commons-httpclient-2.0.2.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-httpclient-2.0.2.jar.license.txt
new file mode 100644
index 0000000..d9a10c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-httpclient-2.0.2.jar.license.txt
@@ -0,0 +1,176 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/non-releases/trunk_before_flattening/legal/commons-io-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-io-1.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-io-1.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-jci-r159148.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-jci-r159148.jar.license.txt
new file mode 100644
index 0000000..1a9893b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-jci-r159148.jar.license.txt
@@ -0,0 +1,176 @@
+                                Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/non-releases/trunk_before_flattening/legal/commons-jexl-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-jexl-1.0.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-jexl-1.0.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-jxpath-1.2-r329470.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-jxpath-1.2-r329470.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-jxpath-1.2-r329470.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-lang-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-lang-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-lang-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-logging-1.0.4.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-logging-1.0.4.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-logging-1.0.4.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-pool-1.2.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-pool-1.2.jar.license.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-pool-1.2.jar.license.txt
@@ -0,0 +1,202 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

diff --git a/non-releases/trunk_before_flattening/legal/commons-transaction-1.0.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-transaction-1.0.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-transaction-1.0.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/commons-validator-1.1.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/commons-validator-1.1.3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/commons-validator-1.1.3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/concurrent-1.3.4.jar.license.txt b/non-releases/trunk_before_flattening/legal/concurrent-1.3.4.jar.license.txt
new file mode 100644
index 0000000..69f5102
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/concurrent-1.3.4.jar.license.txt
@@ -0,0 +1,3 @@
+Doug Lea's concurrent utilities.
+See the Notes at
+http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
diff --git a/non-releases/trunk_before_flattening/legal/cowarp-0.5-dev-20051002.jar.license.txt b/non-releases/trunk_before_flattening/legal/cowarp-0.5-dev-20051002.jar.license.txt
new file mode 100644
index 0000000..f49a4e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/cowarp-0.5-dev-20051002.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/db-ojb-1.0.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/db-ojb-1.0.3.jar.license.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/db-ojb-1.0.3.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/deli-x031104.jar.license.txt b/non-releases/trunk_before_flattening/legal/deli-x031104.jar.license.txt
new file mode 100644
index 0000000..35cfdd0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/deli-x031104.jar.license.txt
@@ -0,0 +1,60 @@
+DELI Delivery Context Library
+
+==========================================================================
+
+Note: this is the 'BSD License' as endorsed by OpenSource.org.
+
+(c) Copyright Hewlett-Packard Company 2001
+All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+==========================================================================
+
+This distribution includes Jena, RDFFilter, Sax2 and Xerces. 
+
+DELI is released under the Hewlett Packard License above.
+For more details on DELI see
+http://www-uk.hpl.hp.com/people/marbut/
+
+Jena is released under the Hewlett Packard License above.
+For more information on Jena see 
+http://www.hpl.hp.com/semweb
+
+For details of the Xerces license see xerces_license.txt in the distribution.
+Further information on Xerces is available at 
+http://xml.apache.org/xerces-j/index.html
+
+For details of the icu4j license see icu4j_license.txt in the distribution.
+For further information on icu4j is available at
+http://oss.software.ibm.com/icu4j/
+
+Sax2 is Public Domain. 
+Further information on Sax2 is available at
+http://sax.sourceforge.net/
+
+==========================================================================
+
+Welcome! The zip file you have downloaded contains code for the DELI
+library. For more details of DELI, see the Technical Report HPL-2001-260 at
+http://www-uk.hpl.hp.com/people/marbut/
+
+
diff --git a/non-releases/trunk_before_flattening/legal/ehcache-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/ehcache-1.1.jar.license.txt
new file mode 100644
index 0000000..a50c609
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/ehcache-1.1.jar.license.txt
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 - 2004 Greg Luck.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by Greg Luck
+ *       (http://sourceforge.net/users/gregluck) and contributors.
+ *       See http://sourceforge.net/project/memberlist.php?group_id=93232
+ *       for a list of contributors"
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "EHCache" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For written
+ *    permission, please contact Greg Luck (gregluck at users.sourceforge.net).
+ *
+ * 5. Products derived from this software may not be called "EHCache"
+ *    nor may "EHCache" appear in their names without prior written
+ *    permission of Greg Luck.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL GREG LUCK OR OTHER
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by contributors
+ * individuals on behalf of the EHCache project.  For more
+ * information on EHCache, please see <http://ehcache.sourceforge.net/>.
+ *
+ */
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-component-1.2.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-component-1.2.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-component-1.2.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-datasource-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-datasource-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-datasource-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-event-api-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-event-api-1.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-event-api-1.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-event-impl-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-event-impl-1.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-event-impl-1.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-i18n-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-i18n-1.1.jar.license.txt
new file mode 100644
index 0000000..dbfd421
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-i18n-1.1.jar.license.txt
@@ -0,0 +1,50 @@
+/*
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+ 
+ Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 
+ 4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
+    Framework" and "Apache Software Foundation"  must not be used to endorse
+    or promote products derived  from this  software without  prior written
+    permission. For written permission, please contact apache@apache.org.
+ 
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ 
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ 
+*/
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-instrument-api-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-instrument-api-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-instrument-api-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-logger-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-logger-2.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-logger-2.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-naming-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-naming-1.0.jar.license.txt
new file mode 100644
index 0000000..dbfd421
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-naming-1.0.jar.license.txt
@@ -0,0 +1,50 @@
+/*
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+ 
+ Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 
+ 4. The names "Jakarta", "Apache Avalon", "Avalon Excalibur", "Avalon
+    Framework" and "Apache Software Foundation"  must not be used to endorse
+    or promote products derived  from this  software without  prior written
+    permission. For written permission, please contact apache@apache.org.
+ 
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ 
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ 
+*/
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-pool-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-pool-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-pool-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-sourceresolve-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-sourceresolve-2.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-sourceresolve-2.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-store-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-store-2.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-store-2.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/excalibur-xmlutil-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/excalibur-xmlutil-2.1.jar.license.txt
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/excalibur-xmlutil-2.1.jar.license.txt
@@ -0,0 +1,176 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
diff --git a/non-releases/trunk_before_flattening/legal/fop-0.20.5.jar.license.txt b/non-releases/trunk_before_flattening/legal/fop-0.20.5.jar.license.txt
new file mode 100644
index 0000000..d38fbeb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/fop-0.20.5.jar.license.txt
@@ -0,0 +1,48 @@
+
+ ============================================================================
+                   The Apache Software License, Version 1.1
+ ============================================================================
+ 
+    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+ 
+ 1. Redistributions of  source code must  retain the above copyright  notice,
+    this list of conditions and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+ 
+ 3. The end-user documentation included with the redistribution, if any, must
+    include  the following  acknowledgment:  "This product includes  software
+    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
+    Alternately, this  acknowledgment may  appear in the software itself,  if
+    and wherever such third-party acknowledgments normally appear.
+ 
+ 4. The names "FOP" and  "Apache Software Foundation"  must not be used to
+    endorse  or promote  products derived  from this  software without  prior
+    written permission. For written permission, please contact
+    apache@apache.org.
+ 
+ 5. Products  derived from this software may not  be called "Apache", nor may
+    "Apache" appear  in their name,  without prior written permission  of the
+    Apache Software Foundation.
+ 
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
+ APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
+ ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
+ (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+ This software  consists of voluntary contributions made  by many individuals
+ on  behalf of the Apache Software  Foundation and was  originally created by
+ James Tauber <jtauber@jtauber.com>. For more  information on the Apache 
+ Software Foundation, please see <http://www.apache.org/>.
+ 
diff --git a/non-releases/trunk_before_flattening/legal/geronimo-spec-activation-1.0.2-rc4.jar.license.txt b/non-releases/trunk_before_flattening/legal/geronimo-spec-activation-1.0.2-rc4.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/geronimo-spec-activation-1.0.2-rc4.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/geronimo-spec-javamail-1.3.1-rc5.jar.license.txt b/non-releases/trunk_before_flattening/legal/geronimo-spec-javamail-1.3.1-rc5.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/geronimo-spec-javamail-1.3.1-rc5.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/geronimo-spec-jms-1.1-rc3.jar.license.txt b/non-releases/trunk_before_flattening/legal/geronimo-spec-jms-1.1-rc3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/geronimo-spec-jms-1.1-rc3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/geronimo-spec-jta-1.0.1B-rc3.jar.license.txt b/non-releases/trunk_before_flattening/legal/geronimo-spec-jta-1.0.1B-rc3.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/geronimo-spec-jta-1.0.1B-rc3.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/groovy-1.0-jsr-04.jar.license.txt b/non-releases/trunk_before_flattening/legal/groovy-1.0-jsr-04.jar.license.txt
new file mode 100644
index 0000000..0f6cb23
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/groovy-1.0-jsr-04.jar.license.txt
@@ -0,0 +1,47 @@
+
+
+/*
+ $Id$
+
+ Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
+
+ Redistribution and use of this software and associated documentation
+ ("Software"), with or without modification, are permitted provided
+ that the following conditions are met:
+
+ 1. Redistributions of source code must retain copyright
+    statements and notices.  Redistributions must also contain a
+    copy of this document.
+
+ 2. Redistributions in binary form must reproduce the
+    above copyright notice, this list of conditions and the
+    following disclaimer in the documentation and/or other
+    materials provided with the distribution.
+
+ 3. The name "groovy" must not be used to endorse or promote
+    products derived from this Software without prior written
+    permission of The Codehaus.  For written permission,
+    please contact info@codehaus.org.
+
+ 4. Products derived from this Software may not be called "groovy"
+    nor may "groovy" appear in their names without prior written
+    permission of The Codehaus. "groovy" is a registered
+    trademark of The Codehaus.
+
+ 5. Due credit should be given to The Codehaus -
+    http://groovy.codehaus.org/
+
+ THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
diff --git a/non-releases/trunk_before_flattening/legal/hsqldb-1.8.0.2.jar.license.txt b/non-releases/trunk_before_flattening/legal/hsqldb-1.8.0.2.jar.license.txt
new file mode 100644
index 0000000..953bfa0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/hsqldb-1.8.0.2.jar.license.txt
@@ -0,0 +1,31 @@
+/* Copyright (c) 2001-2005, The HSQL Development Group
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the HSQL Development Group nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
diff --git a/non-releases/trunk_before_flattening/legal/htmlarea.license.txt b/non-releases/trunk_before_flattening/legal/htmlarea.license.txt
new file mode 100644
index 0000000..32ac404
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/htmlarea.license.txt
@@ -0,0 +1,30 @@
+htmlArea License (based on BSD license)
+Copyright (c) 2002-2004, interactivetools.com, inc.
+Copyright (c) 2003-2004 dynarch.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1) Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+2) Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3) Neither the name of interactivetools.com, inc. nor the names of its
+   contributors may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/httpunit-1.6.jar.licence.txt b/non-releases/trunk_before_flattening/legal/httpunit-1.6.jar.licence.txt
new file mode 100644
index 0000000..afa5489
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/httpunit-1.6.jar.licence.txt
@@ -0,0 +1,7 @@
+Copyright © 2000-2004, Russell Gold
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/non-releases/trunk_before_flattening/legal/icu4j-3.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/icu4j-3.0.jar.license.txt
new file mode 100644
index 0000000..ca081ab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/icu4j-3.0.jar.license.txt
@@ -0,0 +1,34 @@
+ICU License - ICU 1.8.1 and later
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1995-2003 International Business Machines Corporation and others
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+--------------------------------------------------------------------------------
+All trademarks and registered trademarks mentioned herein are the property of their respective owners.
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/itext-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/itext-1.1.jar.license.txt
new file mode 100644
index 0000000..7714141
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/itext-1.1.jar.license.txt
@@ -0,0 +1,470 @@
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
diff --git a/non-releases/trunk_before_flattening/legal/jackrabbit-1.0-dev-r292737.jar.license.txt b/non-releases/trunk_before_flattening/legal/jackrabbit-1.0-dev-r292737.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jackrabbit-1.0-dev-r292737.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jackrabbit-commons-1.0-dev-r292737.jar.license.txt b/non-releases/trunk_before_flattening/legal/jackrabbit-commons-1.0-dev-r292737.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jackrabbit-commons-1.0-dev-r292737.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jakarta-bcel-20040329.jar.license.txt b/non-releases/trunk_before_flattening/legal/jakarta-bcel-20040329.jar.license.txt
new file mode 100644
index 0000000..1fcfc54
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jakarta-bcel-20040329.jar.license.txt
@@ -0,0 +1,53 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache BCEL" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache BCEL", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/jakarta-oro-2.0.8.jar.license.txt b/non-releases/trunk_before_flattening/legal/jakarta-oro-2.0.8.jar.license.txt
new file mode 100644
index 0000000..4b3a622
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jakarta-oro-2.0.8.jar.license.txt
@@ -0,0 +1,57 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation", "Jakarta-Oro" 
+ *    must not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache" 
+ *    or "Jakarta-Oro", nor may "Apache" or "Jakarta-Oro" appear in their 
+ *    name, without prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon software originally written 
+ * by Daniel F. Savarese. We appreciate his contributions.
+ */
+
diff --git a/non-releases/trunk_before_flattening/legal/jakarta-regexp-1.4.jar.license.txt b/non-releases/trunk_before_flattening/legal/jakarta-regexp-1.4.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jakarta-regexp-1.4.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jakarta-slide-webdavlib-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/jakarta-slide-webdavlib-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jakarta-slide-webdavlib-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jcs-1.2.5-dev-20050313.jar.license.txt b/non-releases/trunk_before_flattening/legal/jcs-1.2.5-dev-20050313.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jcs-1.2.5-dev-20050313.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jdbi-1.3.1.jar.licence.txt b/non-releases/trunk_before_flattening/legal/jdbi-1.3.1.jar.licence.txt
new file mode 100644
index 0000000..11069ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jdbi-1.3.1.jar.licence.txt
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jdom-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/jdom-1.0.jar.license.txt
new file mode 100644
index 0000000..5a75e93
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jdom-1.0.jar.license.txt
@@ -0,0 +1,56 @@
+/*-- 
+
+ $Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $
+
+ Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions, and the following disclaimer.
+ 
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions, and the disclaimer that follows 
+    these conditions in the documentation and/or other materials 
+    provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+    derived from this software without prior written permission.  For
+    written permission, please contact <request_AT_jdom_DOT_org>.
+ 
+ 4. Products derived from this software may not be called "JDOM", nor
+    may "JDOM" appear in their name, without prior written permission
+    from the JDOM Project Management <request_AT_jdom_DOT_org>.
+ 
+ In addition, we request (but do not require) that you include in the 
+ end-user documentation provided with the redistribution and/or in the 
+ software itself an acknowledgement equivalent to the following:
+     "This product includes software developed by the
+      JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos 
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many 
+ individuals on behalf of the JDOM Project and was originally 
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
+ on the JDOM Project, please see <http://www.jdom.org/>. 
+
+ */
+
diff --git a/non-releases/trunk_before_flattening/legal/jdtcore-3.0.2.jar.license.html b/non-releases/trunk_before_flattening/legal/jdtcore-3.0.2.jar.license.html
new file mode 100644
index 0000000..7e14392
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jdtcore-3.0.2.jar.license.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>20th June, 2002</p>	
+<h3>License</h3>
+<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Common Public License Version 1.0 (&quot;CPL&quot;).  A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
+
+<h3>Contributions</h3>
+
+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
+
+<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
+other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
+to others under the terms of the Other License.  In addition, with regard to Modifications for which you are the copyright holder, you are also
+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
+the CPL.</p>
+
+<h3>Disassembler</h3>
+<p>This plug-in contains a bytecode disassembler (&quot;Disassembler&quot;) that can produce a listing of the Java assembler mnemonics (&quot;Assembler Mnemonics&quot;) for a Java method.  If you 
+use the Disassembler to view the Assembler Mnemonics for a method, you should ensure that doing so will not violate the terms of any licenses that apply to your use of that method, as
+such licenses may not permit you to reverse engineer, decompile, or disassemble method bytecodes.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/jena-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/jena-2.1.jar.license.txt
new file mode 100644
index 0000000..2746bda
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jena-2.1.jar.license.txt
@@ -0,0 +1,30 @@
+/*
+ * (c) Copyright 2000, 2001, 2002, 2003, 2004 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+This product includes software developed by the
+Apache Software Foundation (http://www.apache.org/).
diff --git a/non-releases/trunk_before_flattening/legal/jetty-5.1.8.jar.license.txt b/non-releases/trunk_before_flattening/legal/jetty-5.1.8.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jetty-5.1.8.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jetty-jmx-5.1.8.jar.license.txt b/non-releases/trunk_before_flattening/legal/jetty-jmx-5.1.8.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jetty-jmx-5.1.8.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/jfor-0.7.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/jfor-0.7.1.jar.license.txt
new file mode 100644
index 0000000..07947bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jfor-0.7.1.jar.license.txt
@@ -0,0 +1,43 @@
+ * ====================================================================
+ * jfor Apache-Style Software License.
+ * Copyright (c) 2002 by the jfor project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed
+ * by the jfor project (http://www.jfor.org)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The name "jfor" must not be used to endorse
+ * or promote products derived from this software without prior written
+ * permission.  For written permission, please contact info@jfor.org.
+ *
+ * 5. Products derived from this software may not be called "jfor",
+ * nor may "jfor" appear in their name, without prior written
+ * permission of info@jfor.org.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE JFOR PROJECT OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
diff --git a/non-releases/trunk_before_flattening/legal/jing-20030619.jar.license.txt b/non-releases/trunk_before_flattening/legal/jing-20030619.jar.license.txt
new file mode 100644
index 0000000..d04a636
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jing-20030619.jar.license.txt
@@ -0,0 +1,31 @@
+Copyright (c) 2001, 2002 Thai Open Source Software Center Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+    Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+    Neither the name of the Thai Open Source Software Center Ltd nor
+    the names of its contributors may be used to endorse or promote
+    products derived from this software without specific prior written
+    permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/jmock-1.0.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/jmock-1.0.1.jar.license.txt
new file mode 100644
index 0000000..d75c363
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jmock-1.0.1.jar.license.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2000-2003, jMock.org
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of jMock nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
diff --git a/non-releases/trunk_before_flattening/legal/joost-20040330.jar.license.txt b/non-releases/trunk_before_flattening/legal/joost-20040330.jar.license.txt
new file mode 100644
index 0000000..7714141
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/joost-20040330.jar.license.txt
@@ -0,0 +1,470 @@
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
diff --git a/non-releases/trunk_before_flattening/legal/jstyle.jar.license.txt b/non-releases/trunk_before_flattening/legal/jstyle.jar.license.txt
new file mode 100644
index 0000000..ec58ec3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jstyle.jar.license.txt
@@ -0,0 +1,116 @@
+Jstyle was replaced several years ago by Artistic Style, which can be 
+found at http://astyle.sourceforge.net. Jstyle is covered by Artistic 
+License.
+
+http://astyle.sourceforge.net/license.html
+--------------------------------------------------------------------------------
+
+The ``Artistic License''
+
+Preamble
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package, while
+giving the users of the package the right to use and distribute the
+Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications. 
+
+--------------------------------------------------------------------------------
+
+Definitions
+``Package'' refers to the collection of files distributed by the
+Copyright Holder, and derivatives of that collection of files created
+through textual modification.
+``Standard Version'' refers to such a Package if it has not been
+modified, or has been modified in accordance with the wishes of the
+Copyright Holder as specified below.
+``Copyright Holder'' is whoever is named in the copyright or copyrights
+for the package.
+``You'' is you, if you're thinking about copying or distributing this
+Package.
+``Reasonable copying fee'' is whatever you can justify on the basis of
+media cost, duplication charges, time of people involved, and so on.
+(You will not be required to justify it to the Copyright Holder, but
+only to the computing community at large as a market that must bear the
+fee.)
+``Freely Available'' means that no fee is charged for the item itself,
+though there may be fees involved in handling the item. It also means
+that recipients of the item may redistribute it under the same
+conditions they received it.
+
+--------------------------------------------------------------------------------
+
+You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated
+disclaimers.
+You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+place your modifications in the Public Domain or otherwise make them
+Freely Available, such as by posting said modifications to Usenet or an
+equivalent medium, or placing the modifications on a major archive site
+such as uunet.uu.net, or by allowing the Copyright Holder to include
+your modifications in the Standard Version of the Package.
+use the modified Package only within your corporation or organization.
+rename any non-standard executables so the names do not conflict with
+standard executables, which must also be provided, and provide a
+separate manual page for each non-standard executable that clearly
+documents how it differs from the Standard Version.
+make other distribution arrangements with the Copyright Holder.
+You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+distribute a Standard Version of the executables and library files,
+together with instructions (in the manual page or equivalent) on where
+to get the Standard Version.
+accompany the distribution with the machine-readable source of the
+Package with your modifications.
+give non-standard executables non-standard names, and clearly document
+the differences in manual pages (or equivalent), together with
+instructions on where to get the Standard Version.
+make other distribution arrangements with the Copyright Holder.
+You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this Package.
+You may not charge a fee for this Package itself. However, you may
+distribute this Package in aggregate with other (possibly commercial)
+programs as part of a larger (possibly commercial) software distribution
+provided that you do not advertise this Package as a product of your
+own. You may embed this Package's interpreter within an executable of
+yours (by linking); this shall be construed as a mere form of
+aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+The scripts and library files supplied as input to or produced as output
+from the programs of this Package do not automatically fall under the
+copyright of this Package, but belong to whomever generated them, and
+may be sold commercially, and may be aggregated with this Package. If
+such scripts or library files are aggregated with this Package via the
+so-called "undump" or "unexec" methods of producing a binary executable
+image, then distribution of such an image shall neither be construed as
+a distribution of this Package nor shall it fall under the restrictions
+of Paragraphs 3 and 4, provided that you do not represent such an
+executable image as a Standard Version of this Package.
+C subroutines (or comparably compiled subroutines in other languages)
+supplied by you and linked into this Package in order to emulate
+subroutines and variables of the language defined by this Package shall
+not be considered part of this Package, but are the equivalent of input
+as in Paragraph 6, provided these subroutines do not change the language
+in any way that would cause it to fail the regression tests for the
+language.
+Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution. Such use shall not be
+construed as a distribution of this Package.
+The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written
+permission. 
+
+THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
diff --git a/non-releases/trunk_before_flattening/legal/jtidy-04aug2000r7-dev.jar.license.txt b/non-releases/trunk_before_flattening/legal/jtidy-04aug2000r7-dev.jar.license.txt
new file mode 100644
index 0000000..84e366b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/jtidy-04aug2000r7-dev.jar.license.txt
@@ -0,0 +1,49 @@
+  Java HTML Tidy - JTidy
+  HTML parser and pretty printer
+
+  Copyright (c) 1998-2000 World Wide Web Consortium (Massachusetts
+  Institute of Technology, Institut National de Recherche en
+  Informatique et en Automatique, Keio University). All Rights
+  Reserved.
+
+  Contributing Author(s):
+
+     Dave Raggett <dsr@w3.org>
+     Andy Quick <ac.quick@sympatico.ca> (translation to Java)
+     Gary L Peskin <garyp@firstech.com> (Java development)
+     Sami Lempinen <sami@lempinen.net>  (release management)
+
+  The contributing author(s) would like to thank all those who
+  helped with testing, bug fixes, and patience.  This wouldn't
+  have been possible without all of you.
+
+  COPYRIGHT NOTICE:
+ 
+  This software and documentation is provided "as is," and
+  the copyright holders and contributing author(s) make no
+  representations or warranties, express or implied, including
+  but not limited to, warranties of merchantability or fitness
+  for any particular purpose or that the use of the software or
+  documentation will not infringe any third party patents,
+  copyrights, trademarks or other rights. 
+
+  The copyright holders and contributing author(s) will not be
+  liable for any direct, indirect, special or consequential damages
+  arising out of any use of the software or documentation, even if
+  advised of the possibility of such damage.
+
+  Permission is hereby granted to use, copy, modify, and distribute
+  this source code, or portions hereof, documentation and executables,
+  for any purpose, without fee, subject to the following restrictions:
+
+  1. The origin of this source code must not be misrepresented.
+  2. Altered versions must be plainly marked as such and must
+     not be misrepresented as being the original source.
+  3. This Copyright notice may not be removed or altered from any
+     source or altered source distribution.
+ 
+  The copyright holders and contributing author(s) specifically
+  permit, without fee, and encourage the use of this source code
+  as a component for supporting the Hypertext Markup Language in
+  commercial products. If you use this source code in a product,
+  acknowledgment is not required but would be appreciated.
diff --git a/non-releases/trunk_before_flattening/legal/junit-3.8.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/junit-3.8.1.jar.license.txt
new file mode 100644
index 0000000..fbd1e20
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/junit-3.8.1.jar.license.txt
@@ -0,0 +1,185 @@
+
+IBM Public License Version 1.0 
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS IBM PUBLIC 
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE 
+PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 
+1. DEFINITIONS 
+
+"Contribution" means: 
+  a) in the case of International Business Machines Corporation ("IBM"), 
+  the Original Program, and 
+  b) in the case of each Contributor, 
+  i) changes to the Program, and
+  ii) additions to the Program;
+  where such changes and/or additions to the Program originate from and 
+  are distributed by that particular Contributor. A Contribution 
+  'originates' from a Contributor if it was added to the Program by such 
+  Contributor itself or anyone acting on such Contributor's behalf. 
+  Contributions do not include additions to the Program which: (i) are 
+  separate modules of software distributed in conjunction with the Program 
+  under their own license agreement, and (ii) are not derivative works of 
+  the Program.
+"Contributor" means IBM and any other entity that distributes the Program. 
+
+"Licensed Patents " mean patent claims licensable by a Contributor which 
+are necessarily infringed by the use or sale of its Contribution alone or 
+when combined with the Program. 
+"Original Program" means the original version of the software accompanying 
+this Agreement as released by IBM, including source code, object code and 
+documentation, if any. 
+"Program" means the Original Program and Contributions. 
+"Recipient" means anyone who receives the Program under this Agreement, 
+including all Contributors. 
+2. GRANT OF RIGHTS 
+  a) Subject to the terms of this Agreement, each Contributor hereby 
+  grants Recipient a non-exclusive, worldwide, royalty-free copyright 
+  license to reproduce, prepare derivative works of, publicly display, 
+  publicly perform, distribute and sublicense the Contribution of such 
+  Contributor, if any, and such derivative works, in source code and 
+  object code form.
+  b) Subject to the terms of this Agreement, each Contributor hereby 
+  grants Recipient a non-exclusive, worldwide, royalty-free patent license 
+  under Licensed Patents to make, use, sell, offer to sell, import and 
+  otherwise transfer the Contribution of such Contributor, if any, in 
+  source code and object code form. This patent license shall apply to the 
+  combination of the Contribution and the Program if, at the time the 
+  Contribution is added by the Contributor, such addition of the 
+  Contribution causes such combination to be covered by the Licensed 
+  Patents. The patent license shall not apply to any other combinations 
+  which include the Contribution. No hardware per se is licensed 
+  hereunder. 
+  c) Recipient understands that although each Contributor grants the 
+  licenses to its Contributions set forth herein, no assurances are 
+  provided by any Contributor that the Program does not infringe the 
+  patent or other intellectual property rights of any other entity. Each 
+  Contributor disclaims any liability to Recipient for claims brought by 
+  any other entity based on infringement of intellectual property rights 
+  or otherwise. As a condition to exercising the rights and licenses 
+  granted hereunder, each Recipient hereby assumes sole responsibility to 
+  secure any other intellectual property rights needed, if any. For 
+  example, if a third party patent license is required to allow Recipient 
+  to distribute the Program, it is Recipient's responsibility to acquire 
+  that license before distributing the Program.
+  d) Each Contributor represents that to its knowledge it has sufficient 
+  copyright rights in its Contribution, if any, to grant the copyright 
+  license set forth in this Agreement. 
+3. REQUIREMENTS 
+A Contributor may choose to distribute the Program in object code form 
+under its own license agreement, provided that: 
+  a) it complies with the terms and conditions of this Agreement; and
+  b) its license agreement:
+  i) effectively disclaims on behalf of all Contributors all warranties 
+  and conditions, express and implied, including warranties or conditions 
+  of title and non-infringement, and implied warranties or conditions of 
+  merchantability and fitness for a particular purpose; 
+  ii) effectively excludes on behalf of all Contributors all liability for 
+  damages, including direct, indirect, special, incidental and 
+  consequential damages, such as lost profits; 
+  iii) states that any provisions which differ from this Agreement are 
+  offered by that Contributor alone and not by any other party; and
+  iv) states that source code for the Program is available from such 
+  Contributor, and informs licensees how to obtain it in a reasonable 
+  manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form: 
+  a) it must be made available under this Agreement; and 
+  b) a copy of this Agreement must be included with each copy of the 
+  Program. 
+Each Contributor must include the following in a conspicuous location in 
+the Program: 
+  Copyright © {date here}, International Business Machines Corporation and 
+  others. All Rights Reserved. 
+In addition, each Contributor must identify itself as the originator of 
+its Contribution, if any, in a manner that reasonably allows subsequent 
+Recipients to identify the originator of the Contribution. 
+4. COMMERCIAL DISTRIBUTION 
+Commercial distributors of software may accept certain responsibilities 
+with respect to end users, business partners and the like. While this 
+license is intended to facilitate the commercial use of the Program, the 
+Contributor who includes the Program in a commercial product offering 
+should do so in a manner which does not create potential liability for 
+other Contributors. Therefore, if a Contributor includes the Program in a 
+commercial product offering, such Contributor ("Commercial Contributor") 
+hereby agrees to defend and indemnify every other Contributor 
+("Indemnified Contributor") against any losses, damages and costs 
+(collectively "Losses") arising from claims, lawsuits and other legal 
+actions brought by a third party against the Indemnified Contributor to 
+the extent caused by the acts or omissions of such Commercial Contributor 
+in connection with its distribution of the Program in a commercial product 
+offering. The obligations in this section do not apply to any claims or 
+Losses relating to any actual or alleged intellectual property 
+infringement. In order to qualify, an Indemnified Contributor must: a) 
+promptly notify the Commercial Contributor in writing of such claim, and 
+b) allow the Commercial Contributor to control, and cooperate with the 
+Commercial Contributor in, the defense and any related settlement 
+negotiations. The Indemnified Contributor may participate in any such 
+claim at its own expense. 
+For example, a Contributor might include the Program in a commercial 
+product offering, Product X. That Contributor is then a Commercial 
+Contributor. If that Commercial Contributor then makes performance claims, 
+or offers warranties related to Product X, those performance claims and 
+warranties are such Commercial Contributor's responsibility alone. Under 
+this section, the Commercial Contributor would have to defend claims 
+against the other Contributors related to those performance claims and 
+warranties, and if a court requires any other Contributor to pay any 
+damages as a result, the Commercial Contributor must pay those damages. 
+5. NO WARRANTY 
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER 
+EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR 
+CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A 
+PARTICULAR PURPOSE. Each Recipient is solely responsible for determining 
+the appropriateness of using and distributing the Program and assumes all 
+risks associated with its exercise of rights under this Agreement, 
+including but not limited to the risks and costs of program errors, 
+compliance with applicable laws, damage to or loss of data, programs or 
+equipment, and unavailability or interruption of operations. 
+6. DISCLAIMER OF LIABILITY 
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING 
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF 
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION 
+OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF 
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+7. GENERAL 
+If any provision of this Agreement is invalid or unenforceable under 
+applicable law, it shall not affect the validity or enforceability of the 
+remainder of the terms of this Agreement, and without further action by 
+the parties hereto, such provision shall be reformed to the minimum extent 
+necessary to make such provision valid and enforceable. 
+If Recipient institutes patent litigation against a Contributor with 
+respect to a patent applicable to software (including a cross-claim or 
+counterclaim in a lawsuit), then any patent licenses granted by that 
+Contributor to such Recipient under this Agreement shall terminate as of 
+the date such litigation is filed. In addition, If Recipient institutes 
+patent litigation against any entity (including a cross-claim or 
+counterclaim in a lawsuit) alleging that the Program itself (excluding 
+combinations of the Program with other software or hardware) infringes 
+such Recipient's patent(s), then such Recipient's rights granted under 
+Section 2(b) shall terminate as of the date such litigation is filed. 
+All Recipient's rights under this Agreement shall terminate if it fails to 
+comply with any of the material terms or conditions of this Agreement and 
+does not cure such failure in a reasonable period of time after becoming 
+aware of such noncompliance. If all Recipient's rights under this 
+Agreement terminate, Recipient agrees to cease use and distribution of the 
+Program as soon as reasonably practicable. However, Recipient's 
+obligations under this Agreement and any licenses granted by Recipient 
+relating to the Program shall continue and survive. 
+IBM may publish new versions (including revisions) of this Agreement from 
+time to time. Each new version of the Agreement will be given a 
+distinguishing version number. The Program (including Contributions) may 
+always be distributed subject to the version of the Agreement under which 
+it was received. In addition, after a new version of the Agreement is 
+published, Contributor may elect to distribute the Program (including its 
+Contributions) under the new version. No one other than IBM has the right 
+to modify this Agreement. Except as expressly stated in Sections 2(a) and 
+2(b) above, Recipient receives no rights or licenses to the intellectual 
+property of any Contributor under this Agreement, whether expressly, by 
+implication, estoppel or otherwise. All rights in the Program not 
+expressly granted under this Agreement are reserved. 
+This Agreement is governed by the laws of the State of New York and the 
+intellectual property laws of the United States of America. No party to 
+this Agreement will bring a legal action under this Agreement more than 
+one year after the cause of action arose. Each party waives its rights to 
+a jury trial in any resulting litigation. 
diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-cm_api-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-cm_api-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-cm_api-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-console_all-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-console_all-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-console_all-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-consoletty-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-consoletty-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-consoletty-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-framework-1.3.3.jar.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-framework-1.3.3.jar.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-framework-1.3.3.jar.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-frameworkcommands-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-frameworkcommands-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-frameworkcommands-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-http_all-1.1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-http_all-1.1.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-http_all-1.1.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-log_all-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-log_all-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-log_all-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish-logcommands-1.0.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish-logcommands-1.0.0.jar.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish-logcommands-1.0.0.jar.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/knopflerfish.license.txt b/non-releases/trunk_before_flattening/legal/knopflerfish.license.txt
new file mode 100644
index 0000000..3c5b40e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/knopflerfish.license.txt
@@ -0,0 +1,33 @@
+/*

+ * Copyright (c) 2003-2004, KNOPFLERFISH project

+ * All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following

+ * conditions are met:

+ *

+ * - Redistributions of source code must retain the above copyright

+ *   notice, this list of conditions and the following disclaimer.

+ *

+ * - Redistributions in binary form must reproduce the above

+ *   copyright notice, this list of conditions and the following

+ *   disclaimer in the documentation and/or other materials

+ *   provided with the distribution.

+ *

+ * - Neither the name of the KNOPFLERFISH project nor the names of its

+ *   contributors may be used to endorse or promote products derived

+ *   from this software without specific prior written permission.

+ *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS

+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT

+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS

+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,

+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,

+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

+ * OF THE POSSIBILITY OF SUCH DAMAGE.

+ */

diff --git a/non-releases/trunk_before_flattening/legal/log4j-1.2.12.jar.license.txt b/non-releases/trunk_before_flattening/legal/log4j-1.2.12.jar.license.txt
new file mode 100644
index 0000000..6279e52
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/log4j-1.2.12.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 1999-2005 The Apache Software Foundation
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/lucene-1.4.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/lucene-1.4.3.jar.license.txt
new file mode 100644
index 0000000..aac7fca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/lucene-1.4.3.jar.license.txt
@@ -0,0 +1,15 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/midi-license.txt b/non-releases/trunk_before_flattening/legal/midi-license.txt
new file mode 100644
index 0000000..d38d3f3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/midi-license.txt
@@ -0,0 +1,6 @@
+The MIDI file parsing parts of the "midi" block classes are based
+on code from the XMidi project, written by Peter Arthur Loeb
+(http://www.palserv.com/XMidi/) and used with permission.
+The warranty disclaimer of the MIT license 
+(http://www.opensource.org/licenses/mit-license.html)
+applies to Peter Arthur Loeb's code.
diff --git a/non-releases/trunk_before_flattening/legal/mx4j-jmx-3.0.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/mx4j-jmx-3.0.1.jar.license.txt
new file mode 100644
index 0000000..281ebef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/mx4j-jmx-3.0.1.jar.license.txt
@@ -0,0 +1,51 @@
+/* ====================================================================
+ * The MX4J License, Version 1.0
+ *
+ * Copyright (c) 2001 MX4J.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        MX4J project (http://mx4j.sourceforge.net)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "MX4J" and "mx4j" must not be used to endorse or promote
+ *    products derived from this software without prior written
+ *    permission. For written permission, please contact biorn_steedom@users.sourceforge.net
+ *
+ * 5. Products derived from this software may not be called "MX4J",
+ *    nor may "MX4J" appear in their name, without prior written
+ *    permission of Simone Bordet.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL CARLOS QUIROZ OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of MX4J.  For more information on
+ * MX4J, please see
+ * <http://mx4j.sourceforge.net>.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/myfaces-api-r233484.jar.license.txt b/non-releases/trunk_before_flattening/legal/myfaces-api-r233484.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/myfaces-api-r233484.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/myfaces-impl-r233484.jar.license.txt b/non-releases/trunk_before_flattening/legal/myfaces-impl-r233484.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/myfaces-impl-r233484.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/nekodtd-0.1.11.jar.license.txt b/non-releases/trunk_before_flattening/legal/nekodtd-0.1.11.jar.license.txt
new file mode 100644
index 0000000..a1fe647
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/nekodtd-0.1.11.jar.license.txt
@@ -0,0 +1,47 @@
+The CyberNeko Software License, Version 1.0
+
+ 
+(C) Copyright 2002,2003, Andy Clark.  All rights reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer. 
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+3. The end-user documentation included with the redistribution,
+   if any, must include the following acknowledgment:  
+     "This product includes software developed by Andy Clark."
+   Alternately, this acknowledgment may appear in the software itself,
+   if and wherever such third-party acknowledgments normally appear.
+
+4. The names "CyberNeko" and "NekoHTML" must not be used to endorse
+   or promote products derived from this software without prior 
+   written permission. For written permission, please contact 
+   andy@cyberneko.net.
+
+5. Products derived from this software may not be called "NekoHTML",
+   nor may "NekoHTML" appear in their name, without prior written
+   permission of the author.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+====================================================================
+
+This license is based on the Apache Software License, version 1.1.
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/legal/nekohtml-0.9.5.jar-license.txt b/non-releases/trunk_before_flattening/legal/nekohtml-0.9.5.jar-license.txt
new file mode 100644
index 0000000..7596743
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/nekohtml-0.9.5.jar-license.txt
@@ -0,0 +1,47 @@
+The CyberNeko Software License, Version 1.0
+
+ 
+(C) Copyright 2002-2005, Andy Clark.  All rights reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer. 
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+3. The end-user documentation included with the redistribution,
+   if any, must include the following acknowledgment:  
+     "This product includes software developed by Andy Clark."
+   Alternately, this acknowledgment may appear in the software itself,
+   if and wherever such third-party acknowledgments normally appear.
+
+4. The names "CyberNeko" and "NekoHTML" must not be used to endorse
+   or promote products derived from this software without prior 
+   written permission. For written permission, please contact 
+   andyc@cyberneko.net.
+
+5. Products derived from this software may not be called "CyberNeko",
+   nor may "CyberNeko" appear in their name, without prior written
+   permission of the author.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+====================================================================
+
+This license is based on the Apache Software License, version 1.1.
diff --git a/non-releases/trunk_before_flattening/legal/osgi_copyright.txt b/non-releases/trunk_before_flattening/legal/osgi_copyright.txt
new file mode 100644
index 0000000..f3f7b9b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/osgi_copyright.txt
@@ -0,0 +1,65 @@
+Copyright (c) 2000, 2003

+

+The Open Services Gateway Initiative

+Bishop Ranch 2

+2694 Bishop Drive

+Suite 275

+San Ramon

+CA 94583 USA

+

+All Rights Reserved.

+

+LEGAL TERMS AND CONDITIONS REGARDING SPECIFICATION

+

+Implementation of certain elements of the Open Services Gateway

+Initiative (OSGi) Specification may be subject to third party

+intellectual property rights, including without limitation, patent

+rights (such a third party may or may not be a member of OSGi).  OSGi is

+not responsible and shall not be held responsible in any manner for

+identifying or failing to identify any or all such third party

+intellectual property rights.

+

+THE RECIPIENT ACKNOWLEDGES AND AGREES THAT THE SPECIFICATION IS PROVIDED

+"AS IS" AND WITH NO WARRANTIES WHATSOEVER, WHETHER EXPRESS, IMPLIED OR

+STATUTORY, INCLUDING, BUT NOT LIMITED TO ANY WARRANTY OF

+MERCHANTABILITY, NONINFRINGEMENT, FITNESS OF ANY PARTICULAR PURPOSE, OR

+ANY WARRANTY OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION, OR

+SAMPLE.  THE RECIPIENT'S USE OF THE SPECIFICATION IS SOLELY AT THE

+RECIPIENT'S OWN RISK.  THE RECIPIENT'S USE OF THE SPECIFICATION IS

+SUBJECT TO THE RECIPIENT'S OSGi MEMBER AGREEMENT, IN THE EVENT THAT THE

+RECIPIENT IS AN OSGi MEMBER.  IN NO EVENT SHALL OSGi BE LIABLE OR

+OBLIGATED TO THE RECIPIENT OR ANY THIRD PARTY IN ANY MANNER FOR ANY

+SPECIAL, NON-COMPENSATORY, CONSEQUENTIAL, INDIRECT, INCIDENTAL,

+STATUTORY OR PUNITIVE DAMAGES OF ANY KIND, INCLUDING, WITHOUT

+LIMITATION, LOST PROFITS AND LOST REVENUE, REGARDLESS OF THE FORM OF

+ACTION, WHETHER IN CONTRACT, TORT, NEGLIGENCE, STRICT PRODUCT LIABILITY,

+OR OTHERWISE, EVEN IF OSGi HAS BEEN INFORMED OF OR IS AWARE OF THE

+POSSIBILITY OF ANY SUCH DAMAGES IN ADVANCE.

+

+THE LIMITATIONS SET FORTH ABOVE SHALL BE DEEMED TO APPLY TO THE MAXIMUM

+EXTENT PERMITTED BY APPLICABLE LAW AND NOTWITHSTANDING THE FAILURE OF

+THE ESSENTIAL PURPOSE OF ANY LIMITED REMEDIES AVAILABLE TO THE

+RECIPIENT.  THE RECIPIENT ACKNOWLEDGES AND AGREES THAT THE RECIPIENT HAS

+FULLY CONSIDERED THE FOREGOING ALLOCATION OF RISK AND FINDS IT

+REASONABLE, AND THAT THE FOREGOING LIMITATIONS ARE AN ESSENTIAL BASIS OF

+THE BARGAIN BETWEEN THE RECIPIENT AND OSGi.  IF THE RECIPIENT USES THE

+SPECIFICATION, THE RECIPIENT AGREES TO ALL OF THE FOREGOING TERMS AND

+CONDITIONS.  IF THE RECIPIENT DOES NOT AGREE TO THESE TERMS AND

+CONDITIONS, THE RECIPIENT SHOULD NOT USE THE SPECIFICATION AND SHOULD

+CONTACT OSGi IMMEDIATELY.

+

+Trademarks

+

+OSGi(TM) is a trademark, registered trademark, or service mark of The

+Open Services Gateway Initiative in the US and other countries.  Java is

+a trademark, registered trademark, or service mark of Sun Microsystems,

+Inc.  in the US and other countries.  All other trademarks, registered

+trademarks, or service marks used in this document are the property of

+their respective owners and are hereby recognized.

+

+Feedback

+

+This specification can be downloaded from the OSGi web site:

+http://www.osgi.org.  Comments about this specification can be mailed

+to: speccomments@mail.osgi.org

+

diff --git a/non-releases/trunk_before_flattening/legal/pluto-1.0.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/pluto-1.0.1.jar.license.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/pluto-1.0.1.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/poi-2.5.1-final-20040804.jar.license.txt b/non-releases/trunk_before_flattening/legal/poi-2.5.1-final-20040804.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/poi-2.5.1-final-20040804.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/portals-bridges-common-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/portals-bridges-common-1.0.jar.license.txt
new file mode 100644
index 0000000..691a722
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/portals-bridges-common-1.0.jar.license.txt
@@ -0,0 +1,190 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2004 The Apache Software Foundation
+
diff --git a/non-releases/trunk_before_flattening/legal/portlet-api-1.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/portlet-api-1.0.jar.license.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/portlet-api-1.0.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/qdox-1.5.jar.license.txt b/non-releases/trunk_before_flattening/legal/qdox-1.5.jar.license.txt
new file mode 100644
index 0000000..ab40b63
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/qdox-1.5.jar.license.txt
@@ -0,0 +1,50 @@
+/* ====================================================================

+ * The IronSmith Software License, Version 1.1

+ *

+ * (this license is derived and fully compatible with the Apache Software

+ * License - see http://www.apache.org/LICENSE.txt)

+ *

+ * Copyright (c) 2002 The IronSmith Project. All rights reserved.

+ *

+ * Redistribution and use in source and binary forms, with or without

+ * modification, are permitted provided that the following conditions

+ * are met:

+ *

+ * 1. Redistributions of source code must retain the above copyright

+ *    notice, this list of conditions and the following disclaimer.

+ *

+ * 2. Redistributions in binary form must reproduce the above copyright

+ *    notice, this list of conditions and the following disclaimer in

+ *    the documentation and/or other materials provided with the

+ *    distribution.

+ *

+ * 3. The end-user documentation included with the redistribution,

+ *    if any, must include the following acknowledgment:

+ *       "This product includes software developed by the

+ *        IronSmith Project (http://www.ironsmith.org/)."

+ *    Alternately, this acknowledgment may appear in the software itself,

+ *    if and wherever such third-party acknowledgments normally appear.

+ *

+ * 4. The names "IronSmith" and "The IronSmith Project"

+ *    must not be used to endorse or promote products derived from this

+ *    software without prior written permission. For written

+ *    permission, please contact help@ironsmith.org.

+ *

+ * 5. Products derived from this software may not be called "IronSmith"

+ *    or "QDox", nor may "IronSmith" or "QDox" appear in their

+ *    name, without prior written permission of the IronSmith Project.

+ *

+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED

+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES

+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR

+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,

+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF

+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND

+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT

+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

+ * SUCH DAMAGE.

+ * ==================================================================== 

+ */

diff --git a/non-releases/trunk_before_flattening/legal/quartz-1.5.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/quartz-1.5.0.jar.license.txt
new file mode 100644
index 0000000..9979349
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/quartz-1.5.0.jar.license.txt
@@ -0,0 +1,23 @@
+
+All source code, binaries, documentation, and other files in this distribution 
+are subject to the following copyright and license agreement, unless 
+otherwise documented:
+
+
+/* 
+ * Copyright 2004-2005 OpenSymphony 
+ * 
+ * Licensed 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.
+ * 
+ */
+
diff --git a/non-releases/trunk_before_flattening/legal/rhino-1.6R2.jar.license.txt b/non-releases/trunk_before_flattening/legal/rhino-1.6R2.jar.license.txt
new file mode 100644
index 0000000..d6ceeba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/rhino-1.6R2.jar.license.txt
@@ -0,0 +1,472 @@
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
+
+
diff --git a/non-releases/trunk_before_flattening/legal/servlet-2.3.jar.license.txt b/non-releases/trunk_before_flattening/legal/servlet-2.3.jar.license.txt
new file mode 100644
index 0000000..9bace83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/servlet-2.3.jar.license.txt
@@ -0,0 +1,59 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * ====================================================================
+ *
+ * This source code implements specifications defined by the Java
+ * Community Process. In order to remain compliant with the specification
+ * DO NOT add / change / or delete method signatures!
+ */ 
diff --git a/non-releases/trunk_before_flattening/legal/slide-kernel-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/slide-kernel-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/slide-kernel-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/slide-stores-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/slide-stores-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/slide-stores-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/slide-webdavservlet-2.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/slide-webdavservlet-2.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/slide-webdavservlet-2.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/spring-1.1.5.jar.license.txt b/non-releases/trunk_before_flattening/legal/spring-1.1.5.jar.license.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/spring-1.1.5.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/spring-1.2.6.jar.license.txt b/non-releases/trunk_before_flattening/legal/spring-1.2.6.jar.license.txt
new file mode 100644
index 0000000..29f81d8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/spring-1.2.6.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed 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.

diff --git a/non-releases/trunk_before_flattening/legal/velocity-1.4.jar.license.txt b/non-releases/trunk_before_flattening/legal/velocity-1.4.jar.license.txt
new file mode 100644
index 0000000..43fa6ab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/velocity-1.4.jar.license.txt
@@ -0,0 +1,202 @@
+                               Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/non-releases/trunk_before_flattening/legal/wsdl4j-1.5.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/wsdl4j-1.5.1.jar.license.txt
new file mode 100644
index 0000000..9d7ce63
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/wsdl4j-1.5.1.jar.license.txt
@@ -0,0 +1,90 @@
+Common Public License  
+
+Common Public License Version 0.5 
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 
+
+
+1. DEFINITIONS 
+
+"Contribution" means: 
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and 
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program. 
+
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. 
+
+
+"Program" means the Contributions distributed in accordance with this Agreement. 
+
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 
+
+
+2. GRANT OF RIGHTS 
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 
+3. REQUIREMENTS 
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: 
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; 
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; 
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. 
+When the Program is made available in source code form: 
+
+a) it must be made available under this Agreement; and 
+b) a copy of this Agreement must be included with each copy of the Program. 
+
+Contributors may not remove or alter any copyright notices contained within the Program. 
+
+
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 
+
+
+4. COMMERCIAL DISTRIBUTION 
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. 
+
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 
+
+
+5. NO WARRANTY 
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 
+
+
+6. DISCLAIMER OF LIABILITY 
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
+
+
+7. GENERAL 
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 
+
+
+If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. 
+
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. 
+
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. 
+
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. 
diff --git a/non-releases/trunk_before_flattening/legal/wsrp4j-consumer-0.3-dev.jar.license.txt b/non-releases/trunk_before_flattening/legal/wsrp4j-consumer-0.3-dev.jar.license.txt
new file mode 100644
index 0000000..691a722
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/wsrp4j-consumer-0.3-dev.jar.license.txt
@@ -0,0 +1,190 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2004 The Apache Software Foundation
+
diff --git a/non-releases/trunk_before_flattening/legal/wsrp4j-shared-0.3-dev.jar.license.txt b/non-releases/trunk_before_flattening/legal/wsrp4j-shared-0.3-dev.jar.license.txt
new file mode 100644
index 0000000..691a722
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/wsrp4j-shared-0.3-dev.jar.license.txt
@@ -0,0 +1,190 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2004 The Apache Software Foundation
+
diff --git a/non-releases/trunk_before_flattening/legal/xalan-2.7.0.jar.license.txt b/non-releases/trunk_before_flattening/legal/xalan-2.7.0.jar.license.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xalan-2.7.0.jar.license.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
diff --git a/non-releases/trunk_before_flattening/legal/xercesImpl-2.7.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/xercesImpl-2.7.1.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xercesImpl-2.7.1.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/xindice-1.1b4.jar.license.txt b/non-releases/trunk_before_flattening/legal/xindice-1.1b4.jar.license.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xindice-1.1b4.jar.license.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/xml-apis-1.3.02.jar.license.txt b/non-releases/trunk_before_flattening/legal/xml-apis-1.3.02.jar.license.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xml-apis-1.3.02.jar.license.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/non-releases/trunk_before_flattening/legal/xml-commons-resolver-1.1.jar.license.txt b/non-releases/trunk_before_flattening/legal/xml-commons-resolver-1.1.jar.license.txt
new file mode 100644
index 0000000..b9f6031
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xml-commons-resolver-1.1.jar.license.txt
@@ -0,0 +1,53 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/xmlbeans-1.0.3.license.txt b/non-releases/trunk_before_flattening/legal/xmlbeans-1.0.3.license.txt
new file mode 100644
index 0000000..cecccc0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmlbeans-1.0.3.license.txt
@@ -0,0 +1,213 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+
+===========================================================================
+
+ADDITIONAL LICENSES COVERING PARTS OF THIS DISTRIBUTION:
+
+This distribution includes W3C XML Schema documents Copyright (c) 2001-2003
+World Wide Web Consortium.  These schemas are licensed under the W3C
+Software License, which is included in the same directory as the schemas.
+The license can also be found at:
+http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231.
+
diff --git a/non-releases/trunk_before_flattening/legal/xmldb-api-20030701.jar.license.txt b/non-releases/trunk_before_flattening/legal/xmldb-api-20030701.jar.license.txt
new file mode 100644
index 0000000..6cf5b78
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmldb-api-20030701.jar.license.txt
@@ -0,0 +1,52 @@
+
+   The XML:DB Initiative Software License, Version 1.0
+ 
+ 
+  Copyright (c) 2000-2001 The XML:DB Initiative.  All rights
+  reserved.
+ 
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+ 
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+ 
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+ 
+  3. The end-user documentation included with the redistribution,
+     if any, must include the following acknowledgment:
+        "This product includes software developed by the
+         XML:DB Initiative (http://www.xmldb.org/)."
+     Alternately, this acknowledgment may appear in the software itself,
+     if and wherever such third-party acknowledgments normally appear.
+ 
+  4. The name "XML:DB Initiative" must not be used to endorse or
+     promote products derived from this software without prior written
+     permission. For written permission, please contact info@xmldb.org.
+ 
+  5. Products derived from this software may not be called "XML:DB",
+     nor may "XML:DB" appear in their name, without prior written
+     permission of the XML:DB Initiative.
+ 
+  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  SUCH DAMAGE.
+  ====================================================================
+ 
+  This software consists of voluntary contributions made by many
+  individuals on behalf of the XML:DB Initiative. For more information
+  on the XML:DB Initiative, please see <http://www.xmldb.org/>.
+ 
diff --git a/non-releases/trunk_before_flattening/legal/xmldb-common-20030701.jar.license.txt b/non-releases/trunk_before_flattening/legal/xmldb-common-20030701.jar.license.txt
new file mode 100644
index 0000000..6cf5b78
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmldb-common-20030701.jar.license.txt
@@ -0,0 +1,52 @@
+
+   The XML:DB Initiative Software License, Version 1.0
+ 
+ 
+  Copyright (c) 2000-2001 The XML:DB Initiative.  All rights
+  reserved.
+ 
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+ 
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+ 
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+ 
+  3. The end-user documentation included with the redistribution,
+     if any, must include the following acknowledgment:
+        "This product includes software developed by the
+         XML:DB Initiative (http://www.xmldb.org/)."
+     Alternately, this acknowledgment may appear in the software itself,
+     if and wherever such third-party acknowledgments normally appear.
+ 
+  4. The name "XML:DB Initiative" must not be used to endorse or
+     promote products derived from this software without prior written
+     permission. For written permission, please contact info@xmldb.org.
+ 
+  5. Products derived from this software may not be called "XML:DB",
+     nor may "XML:DB" appear in their name, without prior written
+     permission of the XML:DB Initiative.
+ 
+  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  SUCH DAMAGE.
+  ====================================================================
+ 
+  This software consists of voluntary contributions made by many
+  individuals on behalf of the XML:DB Initiative. For more information
+  on the XML:DB Initiative, please see <http://www.xmldb.org/>.
+ 
diff --git a/non-releases/trunk_before_flattening/legal/xmldb-xupdate-20040205.jar.license.txt b/non-releases/trunk_before_flattening/legal/xmldb-xupdate-20040205.jar.license.txt
new file mode 100644
index 0000000..6cf5b78
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmldb-xupdate-20040205.jar.license.txt
@@ -0,0 +1,52 @@
+
+   The XML:DB Initiative Software License, Version 1.0
+ 
+ 
+  Copyright (c) 2000-2001 The XML:DB Initiative.  All rights
+  reserved.
+ 
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+ 
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+ 
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+ 
+  3. The end-user documentation included with the redistribution,
+     if any, must include the following acknowledgment:
+        "This product includes software developed by the
+         XML:DB Initiative (http://www.xmldb.org/)."
+     Alternately, this acknowledgment may appear in the software itself,
+     if and wherever such third-party acknowledgments normally appear.
+ 
+  4. The name "XML:DB Initiative" must not be used to endorse or
+     promote products derived from this software without prior written
+     permission. For written permission, please contact info@xmldb.org.
+ 
+  5. Products derived from this software may not be called "XML:DB",
+     nor may "XML:DB" appear in their name, without prior written
+     permission of the XML:DB Initiative.
+ 
+  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  SUCH DAMAGE.
+  ====================================================================
+ 
+  This software consists of voluntary contributions made by many
+  individuals on behalf of the XML:DB Initiative. For more information
+  on the XML:DB Initiative, please see <http://www.xmldb.org/>.
+ 
diff --git a/non-releases/trunk_before_flattening/legal/xmlrpc-1.1.license.txt b/non-releases/trunk_before_flattening/legal/xmlrpc-1.1.license.txt
new file mode 100644
index 0000000..2c02338
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmlrpc-1.1.license.txt
@@ -0,0 +1,54 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 2001 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "XML-RPC" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
diff --git a/non-releases/trunk_before_flattening/legal/xmlunit0.8.jar.license.txt b/non-releases/trunk_before_flattening/legal/xmlunit0.8.jar.license.txt
new file mode 100644
index 0000000..0a1439f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xmlunit0.8.jar.license.txt
@@ -0,0 +1,35 @@
+/*
+******************************************************************
+Copyright (c) 2001, Jeff Martin, Tim Bacon
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of the xmlunit.sourceforge.net nor the names
+      of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************
+*/
diff --git a/non-releases/trunk_before_flattening/legal/xreporter-expression-20040701.jar.license.txt b/non-releases/trunk_before_flattening/legal/xreporter-expression-20040701.jar.license.txt
new file mode 100644
index 0000000..ee20562
--- /dev/null
+++ b/non-releases/trunk_before_flattening/legal/xreporter-expression-20040701.jar.license.txt
@@ -0,0 +1,48 @@
+============================================================================
+The xReporter License, based on the Apache Software License 1.1
+============================================================================
+
+Copyright (C) 2002 Outerthought bvba and Schaubroeck nv. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must
+   include the following acknowledgment: "This product includes software developed
+   by Outerthought and Schaubroeck http://xreporter.cocoondev.org/" This
+   acknowledgment must also appear in the software itself, if and wherever such
+   third-party acknowledgments normally appear: an accompanying README or LICENSE
+   file and/or startup splash screen.
+
+4. The names xReporter, Outerthought and Schaubroeck must not be used to
+   endorse or promote products derived from this software without prior written
+   permission. For written permission, please contact
+   xreporter-license@outerthought.org.
+
+5. Products derived from this software may not be called xReporter,
+   Outerthought or Schaubroeck, nor may xReporter, Outerthought or Schaubroeck
+   appear in their name, without prior written permission of Outerthought and
+   Schaubroeck.
+
+6. Outerthought and Schaubroeck reserve the right to change the terms and
+   conditions of this license at any time without any prior notice, including the
+   donation of this software to an Open Source Community or Foundation.
+
+
+THIS SOFTWARE IS PROVIDED AS IS AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+OUTERTHOUGHT, SCHAUBROECK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/non-releases/trunk_before_flattening/lib/core/avalon-framework-api-4.3.jar b/non-releases/trunk_before_flattening/lib/core/avalon-framework-api-4.3.jar
new file mode 100644
index 0000000..0c75529
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/avalon-framework-api-4.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/avalon-framework-impl-4.3.jar b/non-releases/trunk_before_flattening/lib/core/avalon-framework-impl-4.3.jar
new file mode 100644
index 0000000..4cfe8da
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/avalon-framework-impl-4.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/avalon-logkit-2.1.jar b/non-releases/trunk_before_flattening/lib/core/avalon-logkit-2.1.jar
new file mode 100644
index 0000000..02f07b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/avalon-logkit-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-cli-1.0.jar b/non-releases/trunk_before_flattening/lib/core/commons-cli-1.0.jar
new file mode 100644
index 0000000..22a004e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-cli-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-collections-3.1.jar b/non-releases/trunk_before_flattening/lib/core/commons-collections-3.1.jar
new file mode 100644
index 0000000..47265c6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-collections-3.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-httpclient-2.0.2.jar b/non-releases/trunk_before_flattening/lib/core/commons-httpclient-2.0.2.jar
new file mode 100644
index 0000000..c5c52ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-httpclient-2.0.2.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-io-1.1.jar b/non-releases/trunk_before_flattening/lib/core/commons-io-1.1.jar
new file mode 100644
index 0000000..624fc1a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-io-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-javaflow-r306555.jar b/non-releases/trunk_before_flattening/lib/core/commons-javaflow-r306555.jar
new file mode 100644
index 0000000..3296585
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-javaflow-r306555.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-jci-r306555.jar b/non-releases/trunk_before_flattening/lib/core/commons-jci-r306555.jar
new file mode 100644
index 0000000..57f25a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-jci-r306555.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-jexl-1.0.jar b/non-releases/trunk_before_flattening/lib/core/commons-jexl-1.0.jar
new file mode 100644
index 0000000..929b9b0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-jexl-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-jxpath-1.2-r329470.jar b/non-releases/trunk_before_flattening/lib/core/commons-jxpath-1.2-r329470.jar
new file mode 100644
index 0000000..9311286
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-jxpath-1.2-r329470.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-lang-2.1.jar b/non-releases/trunk_before_flattening/lib/core/commons-lang-2.1.jar
new file mode 100644
index 0000000..87b80ab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-lang-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/commons-logging-1.0.4.jar b/non-releases/trunk_before_flattening/lib/core/commons-logging-1.0.4.jar
new file mode 100644
index 0000000..b73a80f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/commons-logging-1.0.4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/concurrent-1.3.4.jar b/non-releases/trunk_before_flattening/lib/core/concurrent-1.3.4.jar
new file mode 100644
index 0000000..04d3472
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/concurrent-1.3.4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/ehcache-1.1.jar b/non-releases/trunk_before_flattening/lib/core/ehcache-1.1.jar
new file mode 100644
index 0000000..2bda916
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/ehcache-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-i18n-1.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-i18n-1.1.jar
new file mode 100644
index 0000000..8905dc1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-i18n-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-instrument-api-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-instrument-api-2.1.jar
new file mode 100644
index 0000000..79425d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-instrument-api-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-logger-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-logger-2.1.jar
new file mode 100644
index 0000000..27b0ff2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-logger-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-naming-1.0.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-naming-1.0.jar
new file mode 100644
index 0000000..e791508
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-naming-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-pool-api-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-api-2.1.jar
new file mode 100644
index 0000000..2a8000c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-api-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-pool-impl-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-impl-2.1.jar
new file mode 100644
index 0000000..34e9136
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-impl-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-pool-instrumented-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-instrumented-2.1.jar
new file mode 100644
index 0000000..3c043b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-pool-instrumented-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-sourceresolve-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-sourceresolve-2.1.jar
new file mode 100644
index 0000000..02a0b99
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-sourceresolve-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-store-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-store-2.1.jar
new file mode 100644
index 0000000..da8a150
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-store-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/excalibur-xmlutil-2.1.jar b/non-releases/trunk_before_flattening/lib/core/excalibur-xmlutil-2.1.jar
new file mode 100644
index 0000000..38dd11a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/excalibur-xmlutil-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/jcs-1.2.5-dev-20050313.jar b/non-releases/trunk_before_flattening/lib/core/jcs-1.2.5-dev-20050313.jar
new file mode 100644
index 0000000..3c77097
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/jcs-1.2.5-dev-20050313.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/jetty-jmx-5.1.8.jar b/non-releases/trunk_before_flattening/lib/core/jetty-jmx-5.1.8.jar
new file mode 100644
index 0000000..aa74f87
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/jetty-jmx-5.1.8.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-cm_api-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-cm_api-1.0.0.jar
new file mode 100644
index 0000000..e2223d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-cm_api-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-console_all-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-console_all-1.0.0.jar
new file mode 100644
index 0000000..e440b52
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-console_all-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-consoletty-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-consoletty-1.0.0.jar
new file mode 100644
index 0000000..86ba78c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-consoletty-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-framework-1.3.3.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-framework-1.3.3.jar
new file mode 100644
index 0000000..1db23d7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-framework-1.3.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-frameworkcommands-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-frameworkcommands-1.0.0.jar
new file mode 100644
index 0000000..650d94a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-frameworkcommands-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-http_all-1.1.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-http_all-1.1.0.jar
new file mode 100644
index 0000000..140dd03
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-http_all-1.1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-log_all-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-log_all-1.0.0.jar
new file mode 100644
index 0000000..75c7d86
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-log_all-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/knopflerfish-logcommands-1.0.0.jar b/non-releases/trunk_before_flattening/lib/core/knopflerfish-logcommands-1.0.0.jar
new file mode 100644
index 0000000..0281112
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/knopflerfish-logcommands-1.0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/log4j-1.2.12.jar b/non-releases/trunk_before_flattening/lib/core/log4j-1.2.12.jar
new file mode 100644
index 0000000..9b5a720
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/log4j-1.2.12.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/mx4j-jmx-3.0.1.jar b/non-releases/trunk_before_flattening/lib/core/mx4j-jmx-3.0.1.jar
new file mode 100644
index 0000000..95536ec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/mx4j-jmx-3.0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/rhino-1.6R2.jar b/non-releases/trunk_before_flattening/lib/core/rhino-1.6R2.jar
new file mode 100644
index 0000000..e0dba1c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/rhino-1.6R2.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/servlet-2_3.jar b/non-releases/trunk_before_flattening/lib/core/servlet-2_3.jar
new file mode 100644
index 0000000..d368d0f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/servlet-2_3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/xml-commons-resolver-1.1.jar b/non-releases/trunk_before_flattening/lib/core/xml-commons-resolver-1.1.jar
new file mode 100644
index 0000000..073d789
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/xml-commons-resolver-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/core/xmlbeans-1.0.3.jar b/non-releases/trunk_before_flattening/lib/core/xmlbeans-1.0.3.jar
new file mode 100644
index 0000000..c731ea8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/core/xmlbeans-1.0.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/endorsed/jakarta-bcel-20040329.jar b/non-releases/trunk_before_flattening/lib/endorsed/jakarta-bcel-20040329.jar
new file mode 100644
index 0000000..207a389
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/endorsed/jakarta-bcel-20040329.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/endorsed/jakarta-regexp-1.4.jar b/non-releases/trunk_before_flattening/lib/endorsed/jakarta-regexp-1.4.jar
new file mode 100644
index 0000000..4489923
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/endorsed/jakarta-regexp-1.4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/endorsed/xalan-2.7.0.jar b/non-releases/trunk_before_flattening/lib/endorsed/xalan-2.7.0.jar
new file mode 100644
index 0000000..007be39
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/endorsed/xalan-2.7.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/endorsed/xercesImpl-2.7.1.jar b/non-releases/trunk_before_flattening/lib/endorsed/xercesImpl-2.7.1.jar
new file mode 100644
index 0000000..0b100e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/endorsed/xercesImpl-2.7.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/endorsed/xml-apis-1.3.02.jar b/non-releases/trunk_before_flattening/lib/endorsed/xml-apis-1.3.02.jar
new file mode 100644
index 0000000..243eaea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/endorsed/xml-apis-1.3.02.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/jars.xml b/non-releases/trunk_before_flattening/lib/jars.xml
new file mode 100644
index 0000000..8a39201
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/jars.xml
@@ -0,0 +1,1322 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | $Id$
+    |
+    | Add an entry for each jar file used by Cocoon, following the other entries.
+    | Please ensure that you use a version number or datestamp in the jar filename.
+    |
+    +-->
+
+<jars>
+  <file id="concurrent">
+    <title>Doug Lea's Concurrent Utilities</title>
+    <description>
+      The concurrency management primitives that will be the 
+      foundation of JDK 1.5 concurrency management.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/concurrent-1.3.4.jar</lib>
+    <homepage>http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html</homepage>
+  </file>
+
+  <file id="excalibur-datasource">
+    <title>Excalibur DataSource</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development. 
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>optional/excalibur-datasource-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="commons-cli">
+    <title>Jakarta Commons CLI</title>
+    <description>
+      Part of jakarta-commons, it's a package that
+      is used to manage commandline options.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/commons-cli-1.0.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/cli/</homepage>
+  </file>
+
+  <file id="excalibur-i18n">
+    <title>Excalibur I18n</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-i18n-1.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-instrument-api">
+    <title>Excalibur Instrument</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-instrument-api-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-logger">
+    <title>Excalibur Logger</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-logger-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-naming">
+    <title>Excalibur Naming</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-naming-1.0.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-pool">
+    <title>Excalibur Pool</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-pool-api-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-sourceresolve">
+    <title>Excalibur Pool</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-pool-impl-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file>
+    <title>Excalibur Pool</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-pool-instrumented-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file>
+    <title>Excalibur SourceResolve</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-sourceresolve-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-store">
+    <title>Excalibur Store</title>
+    <description>
+      Part of avalon, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-store-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="excalibur-xmlutil">
+    <title>Excalibur XMLUtil</title>
+    <description>
+      Part of Excalibur, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/excalibur-xmlutil-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/</homepage>
+  </file>
+
+  <file id="avalon-framework-api">
+    <title>Avalon Framework</title>
+    <description>
+      Part of avalon, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/avalon-framework-api-4.3.jar</lib>
+    <homepage>http://excalibur.apache.org/framework/index.html</homepage>
+  </file>
+
+  <file id="avalon-framework-impl">
+    <title>Avalon Framework - Implementation</title>
+    <description>
+      Part of avalon, it is a set of classes and patterns that
+      support high level server development.
+    </description>
+    <used-by>Cocoon</used-by>
+    <lib>core/avalon-framework-impl-4.3.jar</lib>
+    <homepage>http://excalibur.apache.org/framework/index.html</homepage>
+  </file>
+
+  <file id="commons-collections">
+    <title>Jakarta Commons Collections</title>
+    <description>Common implementations of collection classes.</description>
+    <used-by>Cocoon, OJB</used-by>
+    <lib>core/commons-collections-3.1.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/collections/</homepage>
+  </file>
+
+  <file>
+    <title>Jakarta Commons IO</title>
+    <description>
+      Commons IO is a library of utilities to assist with developing IO functionality.
+    </description>
+    <used-by>Cocoon,jci</used-by>
+    <lib>core/commons-io-1.1.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/io/</homepage>
+  </file>
+
+  <file id="jakarta-regexp">
+    <title>Jakarta Regexp</title>
+    <description>
+      Regexp is a Java Regular Expression package that was graciously
+      donated to the Apache Software Foundation by Jonathan Locke.
+    </description>
+    <used-by>sitemap matchers</used-by>
+    <lib>endorsed/jakarta-regexp-1.4.jar</lib>
+    <homepage>http://jakarta.apache.org/regexp/</homepage>
+  </file>
+
+  <file id="avalon-logkit">
+    <title>Avalon Logkit</title>
+    <description>
+      avalon-logkit is a logging toolkit designed for secure
+      performance oriented logging in applications.
+    </description>
+    <used-by>Cocoon logging</used-by>
+    <lib>core/avalon-logkit-2.1.jar</lib>
+    <homepage>http://excalibur.apache.org/framework/index.html</homepage>
+  </file>
+
+  <file id="xalan">
+    <title>The XSLT processor</title>
+    <description>
+      Xalan is an XSLT processor that fully supports the W3C specs.
+      Includes XSLTC.
+    </description>
+    <ant-target>jar</ant-target>
+    <used-by>Cocoon</used-by>
+    <lib>endorsed/xalan-2.7.0.jar</lib>
+    <homepage>http://xml.apache.org/xalan-j/</homepage>
+  </file>
+
+  <file id="xercesImpl">
+    <title>The XML parser</title>
+    <description>Xerces is an XML parser.</description>
+    <used-by>Cocoon</used-by>
+    <ant-target>jars</ant-target>
+    <lib>endorsed/xercesImpl-2.7.1.jar</lib>
+    <homepage>http://xml.apache.org/xerces2-j/</homepage>
+  </file>
+
+  <file id="xml-apis">
+    <title>The XML APIs</title>
+    <description>
+      JAXP, DOM and SAX interfaces. 
+      These are the common interfaces for XML processing.
+    </description>
+    <ant-target>external</ant-target>
+    <used-by>Cocoon</used-by>
+    <lib>endorsed/xml-apis-1.3.02.jar</lib>
+    <homepage>http://xml.apache.org/commons/</homepage>
+  </file>
+
+  <file id="batik-all">
+    <title>Batik</title>
+    <description>
+      Batik is a Java based toolkit for applications which handle images in
+      the Scalable Vector Graphics (SVG) format for various purposes, such as
+      viewing, generation or manipulation.</description>
+    <used-by>SVG serializer (batik block)</used-by>
+    <lib>optional/batik-all-1.6.jar</lib>
+    <homepage>http://xml.apache.org/batik/</homepage>
+  </file>
+
+  <file id="bsf">
+    <title>BSF scripting framework</title>
+    <description>
+      The Bean Scripting Framework (BSF) is an architecture for
+      incorporating scripting into, and enabling scripting against, Java
+      applications and applets. Using BSF, an application can use scripting,
+      and become scriptable, against any BSF-supported language. When BSF
+      supports additional languages, the application will automatically
+      support the additional languages.
+    </description>
+    <used-by>BSF Block (Script generator, script action)</used-by>
+    <lib>optional/bsf-2.3.0.jar</lib>
+    <homepage>http://jakarta.apache.org/bsf/</homepage>
+  </file>
+
+  <file id="groovy">
+    <title>Groovy language engine</title>
+    <description>
+      Groovy is a new agile dynamic language for the JVM combining lots of great
+      features from languages like Python, Ruby and Smalltalk and making them
+      available to the Java developers using a Java-like syntax.
+    </description>
+    <used-by>BSF Block (Script generator, script action)</used-by>
+    <lib>optional/groovy-1.0-jsr-04.jar</lib>
+    <homepage>http://groovy.codehaus.org/</homepage>
+  </file>
+
+  <file id="asm">
+    <title>ASM</title>
+    <description>
+      ASM is a Java bytecode manipulation framework. It can be used to
+          dynamically generate stub classes or other proxy classes, directly in
+          binary form, or to dynamically modify classes at load time, i.e., just
+          before they are loaded into the Java Virtual Machine.
+    </description>
+    <used-by>BSF Block (Script generator, script action)</used-by>
+    <lib>optional/asm-2.1.jar</lib>
+    <homepage>http://asm.objectweb.org/</homepage>
+  </file>
+
+  <file id="asm-util">
+    <title>ASM Util</title>
+    <description>
+      Part of ASM (a Java bytecode manipulation framework). Provides some ASM
+      class visitors that can be useful for programming and debugging purposes.
+    </description>
+    <used-by>BSF Block (Script generator, script action)</used-by>
+    <lib>optional/asm-util-2.1.jar</lib>
+    <homepage>http://asm.objectweb.org/</homepage>
+  </file>
+
+  <file id="deli">
+    <title>Device capabilities</title>
+    <description>
+      Open Source Delivery Context Java Library supporting CC/PP and UAProf.
+      Different web-enabled devices have different input, output, hardware,
+      software, network and browser capabilities. In order for a web server or
+      web-based application to provide optimized content to different clients
+      it requires a description of the capabilities of the client known as the
+      delivery context.
+    </description>
+    <used-by>DELI (deli block)</used-by>
+    <lib>optional/deli-x050330.jar</lib>
+    <homepage>http://delicon.sourceforge.net</homepage>
+  </file>
+
+  <file id="commons-httpclient">
+    <title>Jakarta Commons HttpClient</title>
+    <description>
+      Although the java.net package provides basic support for accessing
+      resources via HTTP, it doesn't provide the full flexibility or
+      functionality needed by many applications. The Jakarta Commons HttpClient
+      component seeks to fill this void by providing an efficient, up-to-date,
+      and feature-rich package implementing the client side of the most recent
+      HTTP standards and recommendations.
+    </description>
+    <used-by>SOAP logicsheet, WebServiceProxyGenerator, HttpProxyGenerator</used-by>
+    <lib>core/commons-httpclient-2.0.2.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/httpclient/</homepage>
+  </file>
+
+  <file id="commons-logging">
+    <title>Jakarta Commons Logging</title>
+    <description>
+     The Logging package is an ultra-thin bridge between different logging libraries.
+    </description>
+    <used-by>Jakarta Commons HttpClient, Chaperon</used-by>
+    <lib>core/commons-logging-1.0.4.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/logging/</homepage>
+  </file>
+
+  <file id="itext">
+    <title>iText XML to PDF/HTML/RTF converter (Renderer)</title>
+    <description>iText reads XML documents and turns them into PDFs</description>
+    <used-by>iText serializer</used-by>
+    <lib>optional/itext-1.1.jar</lib>
+    <homepage>http://www.lowagie.com/iText/</homepage>
+  </file>
+
+  <file id="fop">
+    <title>XML FO processor</title>
+    <description>
+      FOP is a Java application that reads a formatting object tree conforming to
+      the XSL recommendation and then turns it into a PDF document.
+    </description>
+    <used-by>FOP serializer (fop block)</used-by>
+    <lib>optional/fop-0.20.5.jar</lib>
+    <homepage>http://xml.apache.org/fop/</homepage>
+  </file>
+
+  <file id="jfor">
+    <title>XSL-FO to RTF converter</title>
+    <description>
+      jfor is a Java application that reads XSL-FO documents
+      and converts them to RTF format, allowing them to be loaded in
+      common wordprocessors.
+    </description>
+    <used-by>RTF serializer (jfor block)</used-by>
+    <lib>optional/jfor-0.7.1.jar</lib>
+    <homepage>http://www.jfor.org</homepage>
+  </file>
+
+  <file id="hsqldb">
+    <title>Simple SQL database</title>
+    <description>
+      hsqldb is a relational database engine written in Java, with a JDBC
+      driver, supporting a subset of ANSI-92 SQL. It offers a small, fast
+      database engine which offers both in memory and disk based tables.
+    </description>
+    <used-by>Cocoon samples webapp</used-by>
+    <lib>optional/hsqldb-1.8.0.2.jar</lib>
+    <homepage>http://hsqldb.sourceforge.net/</homepage>
+  </file>
+
+  <file id="poi">
+    <title>Create proprietary file formats</title>
+    <description>
+      The POI project consists of APIs for manipulating various file formats
+      based upon Microsoft's OLE 2 Compound Document format using pure Java.
+    </description>
+    <used-by>MS Excel serializer (poi block)</used-by>
+    <lib>optional/poi-2.5.1-final-20040804.jar</lib>
+    <homepage>http://jakarta.apache.org/poi/</homepage>
+  </file>
+
+  <file id="jena">
+    <title>Jena RDF framework</title>
+    <description>Jena is a java API for manipulating RDF models.</description>
+    <used-by>DELI (deli block)</used-by>
+    <lib>optional/jena-2.1.jar</lib>
+    <homepage>http://jena.sourceforge.net/</homepage>
+  </file>
+
+  <file id="icu4j">
+    <title>ICU4J International Components for Unicode framework</title>
+    <description>The International Components for Unicode (ICU) library 
+    provides robust and full-featured Unicode services on a wide variety 
+    of platforms. </description>
+    <used-by>DELI (deli block)</used-by>
+    <lib>optional/icu4j-3.0.jar</lib>
+    <homepage>http://www-306.ibm.com/software/globalization/icu/</homepage>
+  </file>
+
+  <file id="jcs">
+    <title>JCS</title>
+    <description>Java Caching System</description>
+    <used-by>JCS Store</used-by>
+    <lib>core/jcs-1.2.5-dev-20050313.jar</lib>
+    <homepage>http://jakarta.apache.org/jcs/</homepage>
+  </file>
+
+  <file id="ehcache">
+    <title>EHCache</title>
+    <description>Easy Hibernate Cache</description>
+    <used-by>EHCache Store</used-by>
+    <lib>core/ehcache-1.1.jar</lib>
+    <homepage>http://ehcache.sourceforge.net/</homepage>
+  </file>
+
+  <file id="jtidy">
+    <title>Transform HTML to XML</title>
+    <description>Tidy is a HTML syntax checker and pretty printer.</description>
+    <used-by>HTML generator (html block), RSSTransformer (Portal block)</used-by>
+    <lib>optional/jtidy-04aug2000r7-dev.jar</lib>
+    <homepage>http://jtidy.sourceforge.net/</homepage>
+  </file>
+
+  <file id="nekodtd">
+    <title>CyberNeko DTD Converter</title>
+    <description>NekoHTML is a lightweight HTML syntax correcter written using Xerces Native Interface.</description>
+    <used-by>Forms block</used-by>
+    <lib>optional/nekodtd-0.1.11.jar</lib>
+    <homepage>http://www.apache.org/~andyc/neko/doc/</homepage>
+  </file>
+
+  <file id="nekohtml">
+    <title>CyberNeko</title>
+    <description>NekoDTD is a configuration that parses Document Type Definition (DTD) files and converts the information into an XML document.</description>
+    <used-by>NekoHTML generator (html block), Forms block</used-by>
+    <lib>optional/nekohtml-0.9.5.jar</lib>
+    <homepage>http://www.apache.org/~andyc/neko/doc/</homepage>
+  </file>  
+  
+  <file id="daisy-htmlcleaner">
+    <title>Daisy HTMLCleaner</title>
+    <description>
+      NekoHTML, but then performs further filtering, conversion and restructuring 
+      on it to have a nice output, limitted to a subset of the HTML DTD
+    </description>
+    <used-by>Forms block</used-by>
+    <lib>optional/daisy-htmlcleaner-1.1.jar</lib>
+    <homepage>http://cocoondev.org/daisy/</homepage>
+  </file>  
+
+  <file id="daisy-util">
+    <title>Daisy Utils</title>
+    <description>
+      Java Utility classes of Daisy
+    </description>
+    <used-by>Forms block - HTMLCleaner</used-by>
+    <lib>optional/daisy-util-1.1.jar</lib>
+    <homepage>http://cocoondev.org/daisy/</homepage>
+  </file>    
+
+  <file id="lucene">
+    <title>Lucene (Search engine)</title>
+    <description>
+      jakarta-lucene is a search engine toolkit designed for indexing and
+      searching of documents.
+    </description>
+    <used-by>Lucene block</used-by>
+    <lib>optional/lucene-1.4.3.jar</lib>
+    <homepage>http://lucene.apache.org/</homepage>
+  </file>
+
+  <file id="log4j">
+    <title>Log4j</title>
+    <description>Logging for java</description>
+    <used-by>Core and DELI (deli block)</used-by>
+    <lib>core/log4j-1.2.12.jar</lib>
+    <homepage>http://logging.apache.org/log4j/</homepage>
+  </file>
+
+  <file id="xml-commons">
+    <title>XML Catalog Entity Resolver</title>
+    <description>
+      Maps URIs to other URIs using the mechanisms defined by
+      OASIS Catalog or XML Catalog. Mainly used for DTDs and character
+      entity sets, but can be used for other resources too.
+    </description>
+    <used-by>Cocoon Role entity-resolver</used-by>
+    <lib>core/xml-commons-resolver-1.1.jar</lib>
+    <homepage>http://xml.apache.org/commons/</homepage>
+  </file>
+
+  <file id="servlet-api">
+    <title>Servlet API</title>
+    <description>Servlet API Version 2.3</description>
+    <used-by>Cocoon</used-by>
+    <lib>core/servlet-2_3.jar</lib>
+    <homepage>http://jakarta.apache.org/tomcat/</homepage>
+  </file>
+
+  <file id="velocity">
+    <title>Velocity engine</title>
+    <description>Velocity is a general purpose template engine written in Java.</description>
+    <used-by>Velocity Generator (velocity block)</used-by>
+    <lib>optional/velocity-1.4.jar</lib>
+    <homepage>http://jakarta.apache.org/velocity/</homepage>
+  </file>
+
+  <file id="xmldb-api">
+    <title>XML:DB APIs</title>
+    <description>Database tailored for the storage of XML data.</description>
+    <used-by>XML:DB source (xmldb block)</used-by>
+    <lib>optional/xmldb-api-20030701.jar</lib>
+    <homepage>http://xmldb-org.sourceforge.net/</homepage>
+  </file>
+
+  <file id="xmldb-common">
+    <title>XML:DB APIs</title>
+    <description>Database tailored for the storage of XML data.</description>
+    <used-by>XML:DB source (xmldb block)</used-by>
+    <lib>optional/xmldb-common-20030701.jar</lib>
+    <homepage>http://www.xmldb.org/</homepage>
+  </file>
+
+  <file id="xmldb-xupdate">
+    <title>XML:DB APIs</title>
+    <description>Database tailored for the storage of XML data.</description>
+    <used-by>XML:DB source (xmldb block)</used-by>
+    <lib>optional/xmldb-xupdate-20040205.jar</lib>
+    <homepage>http://www.xmldb.org/</homepage>
+  </file>
+
+  <file id="xindice">
+    <title>XML Xindice</title>
+    <description>Native XML Database by Apache XML project</description>
+    <used-by>xmldb block</used-by>
+    <lib>optional/xindice-1.1b4.jar</lib>
+    <homepage>http://xml.apache.org/xindice/</homepage>
+  </file>
+
+  <file id="xmlrpc">
+    <title>XML-RPC</title>
+    <description>
+      Java implementation of XML-RPC, a popular protocol that uses XML over
+      HTTP to implement remote procedure calls.
+    </description>
+    <used-by>xmldb block</used-by>
+    <lib>optional/xmlrpc-1.1.jar</lib>
+    <homepage>http://ws.apache.org/xmlrpc/</homepage>
+  </file>
+
+  <file id="commons-jxpath">
+    <title>Jakarta Commons JXPath</title>
+    <description>XPath interpreter. Work with JavaBeans and DOM nodes</description>
+    <used-by>Flow, JXPath logicsheet</used-by>
+    <lib>core/commons-jxpath-1.2-r329470.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/jxpath/</homepage>
+  </file>
+
+  <file id="commons-jexl">
+    <title>Jakarta Commons Jexl</title>
+    <description>JSTL Expression Language</description>
+    <used-by>JXTemplateGenerator</used-by>
+    <lib>core/commons-jexl-1.0.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/jexl/</homepage>
+  </file>
+
+  <file id="eclipse-jdtcore">
+    <title>Eclipse Java Development Tools Core</title>
+    <description>Eclipse Java Compiler</description>
+    <used-by>XSP</used-by>
+    <lib>optional/jdtcore-3.1.0.jar</lib>
+    <homepage>http://www.eclipse.org/jdt/</homepage>
+  </file>
+
+  <file id="rhino">
+    <title>JavaScript engine</title>
+    <description>Rhino is an implementation of JavaScript in Java.</description>
+    <used-by>Control flow</used-by>
+    <lib>core/rhino-1.6R2.jar</lib>
+    <homepage>http://www.mozilla.org/rhino</homepage>
+  </file>
+  
+  <file id="xmlbeans">
+    <title>Apache XMLBeans</title>
+    <description>XMLBeans is an XML-Java binding tool.</description>
+    <used-by>Rhino</used-by>
+    <lib>core/xmlbeans-1.0.3.jar</lib>
+    <homepage>http://xmlbeans.apache.org/</homepage>
+  </file>
+
+  <file id="chaperon">
+    <title>Chaperon Text Parser</title>
+    <description>
+      The chaperon project is parser which could parse text files, and convert
+      those to XML files.
+    </description>
+    <used-by>Chaperon block</used-by>
+    <lib>optional/chaperon-20040205.jar</lib>
+    <homepage>http://chaperon.sourceforge.net</homepage>
+  </file>
+
+  <file id="castor-xml">
+    <title>Castor</title>
+    <description>
+      Data binding framework for Java, including Java-to-XML
+      binding, Java-to-SQL persistence.
+    </description>
+    <used-by>CastorTransformer and precept</used-by>
+    <lib>optional/castor-0.9.6-xml.jar</lib>
+    <homepage>http://castor.codehaus.org/</homepage>
+  </file>
+
+  <file id="jing">
+    <title>Jing</title>
+    <description>RELAX NG validator</description>
+    <used-by>validation</used-by>
+    <lib>optional/jing-20030619.jar</lib>
+    <homepage>http://www.thaiopensource.com/relaxng/jing.html</homepage>
+  </file>
+
+  <file id="cocoon-serializers-charsets">
+    <title>Cocoon Serializers Block Encodings</title>
+    <description>
+      A large list of character sets used for XML/HTML serialization.
+    </description>
+    <used-by>serializers</used-by>
+    <lib>optional/cocoon-serializers-charsets-0.1.jar</lib>
+    <homepage>http://cocoon.apache.org/</homepage>
+  </file>
+
+  <file id="slide-kernel">
+    <title>Slide kernel</title>
+    <description>The Jakarta Slide kernel API.</description>
+    <used-by>Slide block</used-by>
+    <lib>optional/slide-kernel-2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/slide/</homepage>
+  </file>
+
+  <file id="slide-stores">
+    <title>Slide stores</title>
+    <description>The Jakarta Slide stores implementation.</description>
+    <used-by>Slide block</used-by>
+    <lib>optional/slide-stores-2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/slide/</homepage>
+  </file>
+
+  <file id="slide-webdavservlet">
+    <title>Slide WebDAV Servlet</title>
+    <description>The Jakarta Slide WebDAV servlet.</description>
+    <used-by>Slide block</used-by>
+    <lib>optional/slide-webdavservlet-2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/slide/</homepage>
+  </file>
+
+  <file id="jakarta-slide-webdavlib">
+    <title>Slide WebDAV Client library</title>
+    <description>The Jakarta Slide WebDAV client library.</description>
+    <used-by>WebDAV block</used-by>
+    <lib>optional/jakarta-slide-webdavlib-2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/slide/</homepage>
+  </file>
+
+  <file id="commons-transaction">
+    <title>Jakarta Commons Transaction</title>
+    <description>Utility classes commonly used in transactional Java programming</description>
+    <used-by>WebDAV block</used-by>
+    <lib>optional/commons-transaction-1.0.1.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/transaction/</homepage>
+  </file>
+
+  <file id="commons-codec">
+    <title>Jakarta Commons Codec</title>
+    <description>Implementations of common encoders and decoders</description>
+    <used-by>WebDAV block</used-by>
+    <lib>optional/commons-codec-1.3.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/codec/</homepage>
+  </file>
+
+  <file id="jdom">
+    <title>JDOM</title>
+    <description>JDOM</description>
+    <used-by>Slide block</used-by>
+    <lib>optional/jdom-1.0.jar</lib>
+    <homepage>http://www.jdom.org/</homepage>
+  </file>
+
+  <file id="geronimo-spec-jta">
+    <title>JTA spec</title>
+    <description>
+      J2EE Java Transaction API.
+      Implementation taken from the Apache Geronimo project for license compatibility.
+    </description>
+    <used-by>Slide block</used-by>
+    <lib>optional/geronimo-spec-jta-1.0.1B-rc3.jar</lib>
+    <homepage>http://java.sun.com/products/jta/</homepage>
+  </file>
+
+  <file id="wsdl4j">
+    <title>WSDL</title>
+    <description>
+      The Web Services Description Language for Java Toolkit (WSDL4J) allows
+      the creation, representation, and manipulation of WSDL documents
+      describing services
+    </description>
+    <used-by>Axis block</used-by>
+    <lib>optional/wsdl4j-1.5.1.jar</lib>
+    <homepage>http://sourceforge.net/projects/wsdl4j</homepage>
+  </file>
+
+  <file id="axis-saaj">
+    <title>SOAP with Attachments API for Java (SAAJ)</title>
+    <description>
+      SAAJ enables developers to produce and consume messages conforming to the
+      SOAP 1.1 specification and SOAP with Attachments note.
+    </description>
+    <used-by>Axis block</used-by>
+    <lib>optional/axis-saaj-1.2.1.jar</lib>
+    <homepage>http://java.sun.com/xml/saaj/</homepage>
+  </file>
+
+  <file id="commons-discovery">
+    <title>Commons Discovery</title>
+    <description>
+      The Discovery Component is about discovering, or finding, implementations
+      for pluggable interfaces. It provides facilities intantiating classes in
+      general, and for lifecycle management of singleton (factory) classes.
+    </description>
+    <used-by>Axis block</used-by>
+    <lib>optional/commons-discovery-0.2.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/discovery/</homepage>
+  </file>
+
+  <file id="axis-jaxrpc">
+    <title>Java API for XML-based RPC (JAX-RPC)</title>
+    <description>The JAX-RPC enables Java technology developers to build Web
+      applications and Web services incorporating XML based RPC functionality
+      according to the SOAP (Simple Object Access Protocol) 1.1 specification.
+      JAX-RPC provides the core API for developing and deploying web services
+      on the Java platform.
+    </description>
+    <used-by>Axis block</used-by>
+    <lib>optional/axis-jaxrpc-1.2.1.jar</lib>
+    <homepage>http://java.sun.com/xml/jaxrpc/</homepage>
+  </file>
+
+  <file id="axis">
+    <title>Apache Axis</title>
+    <description>
+      Apache Axis is an implementation of the SOAP ("Simple Object Access
+      Protocol")
+    </description>
+    <used-by>Axis block</used-by>
+    <lib>optional/axis-1.2.1.jar</lib>
+    <homepage>http://ws.apache.org/axis/</homepage>
+  </file>
+
+  <file id="commons-lang">
+    <title>Jakarta Commons lang</title>
+    <description>
+      Part of jakarta-commons, it's a package that provides extended services
+      on base classes of the JDK, such as unrolling exceptions.
+    </description>
+    <used-by>Cocoon, OJB</used-by>
+    <lib>core/commons-lang-2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/lang/</homepage>
+  </file>
+
+  <file id="xreporter-expression">
+    <title>xReporter expression language interpreter</title>
+    <description>
+      An expression language interpreter.
+    </description>
+    <used-by>Cocoon Forms block</used-by>
+    <lib>optional/xreporter-expression-20040701.jar</lib>
+    <homepage>http://cocoondev.org/xreporter/</homepage>
+  </file>
+
+  <file id="jakarta-oro">
+    <title>ORO</title>
+    <description>Perl5 compatible regular expression engine</description>
+    <used-by>Cocoon Forms block</used-by>
+    <lib>optional/jakarta-oro-2.0.8.jar</lib>
+    <homepage>http://jakarta.apache.org/oro/</homepage>
+  </file>
+
+  <file id="joost">
+    <title>Joost</title>
+    <description>Streaming Transformation for XML (STX) library</description>
+    <used-by>STX block</used-by>
+    <lib>optional/joost-20040330.jar</lib>
+    <homepage>http://joost.sourceforge.net/</homepage>
+  </file>
+
+  <file id="qdox">
+    <title>QDox - Quick JavaDoc Scanner</title>
+    <description>
+      QDox is a high speed, small footprint parser for extracting class/interface/method
+      definitions from source files complete with JavaDoc @tags.
+    </description>
+    <used-by>QDoxSource (qdox block)</used-by>
+    <lib>optional/qdox-1.5.jar</lib>
+    <homepage>http://qdox.codehaus.org/</homepage>
+   </file>
+
+   <file id="quartz">
+    <title>Quartz</title>
+    <description>Quartz Scheduler</description>
+    <used-by>Cron block</used-by>
+    <lib>optional/quartz-1.5.0.jar</lib>
+    <homepage>http://www.opensymphony.com/quartz/</homepage>
+   </file>
+
+   <file id="apache-garbage">
+    <title>Garbage</title>
+    <description>Garbage</description>
+    <used-by>Scratchpad block</used-by>
+    <lib>optional/apache-garbage-0.0.jar</lib>
+    <homepage>http://cocoon.apache.org/</homepage>
+   </file>
+
+  <file id="commons-betwixt">
+    <title>Jakarta Commons Betwixt</title>
+    <description>
+       The Betwixt library provides an XML introspection mechanism for
+       mapping beans to XML in a flexible way. It is implemented using
+       an XMLIntrospector and XMLBeanInfo classes which are similar to
+       the standard Introspector and BeanInfo from the Java Beans 
+       specification.
+    </description>
+    <used-by>BetwixtTransformer</used-by>
+    <lib>optional/commons-betwixt-0.6.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/betwixt/</homepage>
+  </file>
+
+  <file id="commons-beanutils-core">
+    <title>Jakarta Commons Beantuils</title>
+    <description>
+      The Java language provides Reflection and Introspection APIs 
+      (see the java.lang.reflect and java.beans packages in the JDK Javadocs). 
+      However, these APIs can be quite complex to understand and utilize. 
+      The BeanUtils component provides easy-to-use wrappers around these capabilities.
+    </description>
+    <used-by>Faces block, BetwixtTransformer, Template</used-by>
+    <lib>optional/commons-beanutils-core-1.7.0.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/beanutils/</homepage>
+  </file>
+
+  <file id="commons-digester">
+    <title>Jakarta Commons Digester</title>
+    <description>
+       Allow configure an XML -> Java object mapping module, which triggers
+       certain actions called  rules  whenever a particular pattern of nested
+       XML elements is recognized. A rich set of predefined  rules  is
+       available for your use, or you can also create your own.
+    </description>
+    <used-by>Faces block, BetwixtTransformer</used-by>
+    <lib>optional/commons-digester-1.7.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/digester/</homepage>
+  </file>  
+
+  <!-- OJB  -->
+  <file id="antlr">
+    <title>Antlr - ANother Tool for Language Recognition</title>
+    <description>
+      Language tool that provides a framework for constructing recognizers, compilers, and
+      translators from grammatical descriptions containing Java, C#, or C++ actions
+    </description>
+    <used-by>OJB</used-by>
+    <lib>optional/antlr-2.7.5.jar</lib>
+    <homepage>http://www.antlr.org/</homepage>
+  </file>
+
+  <file id="commons-dbcp">
+    <title>Jakarta Commons DBCP</title>
+    <description>
+       Database Connection Pool API
+    </description>
+    <used-by>OJB</used-by>
+    <lib>optional/commons-dbcp-1.2.1.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/dbcp/</homepage>
+  </file>
+
+  <file id="commons-pool">
+    <title>Jakarta Commons Pool</title>
+    <description>
+       defines a handful of pooling interfaces and some base classes that
+       may be useful when creating new pool implementations.
+    </description>
+    <used-by>OJB</used-by>
+    <lib>optional/commons-pool-1.2.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/pool/</homepage>
+  </file>
+
+  <file id="db-ojb">
+    <title>Apache ObJectRelationalBridge</title>
+    <description>
+        OJB is an Object/Relational mapping tool that allows transparent persistence
+        for Java Objects against relational databases.
+    </description>
+    <used-by>OJB</used-by>
+    <lib>optional/db-ojb-1.0.3.jar</lib>
+    <homepage>http://db.apache.org/ojb/</homepage>
+  </file>
+  <!-- OJB block end (6-Aug-2003) -->
+
+  <file>
+    <title>Javamail Spec</title>
+    <description>
+      J2EE Javamail Specification.  This implentation
+      developed by the (currently incubating) Apache Geronimo project is an
+      open source implementation from the original spec.  As such it is licensed
+      under the Apache license and therefore freely distributable.
+    </description>
+    <used-by>Mail</used-by>
+    <lib>optional/geronimo-spec-javamail-1.3.1-rc5.jar</lib>
+    <homepage>http://geronimo.apache.org/</homepage>
+  </file>
+
+  <file>
+    <title>Activation Spec</title>
+    <description>
+      J2EE Activation Specification.  This implentation
+      developed by the (currently incubating) Apache Geronimo project is an
+      open source implementation from the original spec.  As such it is licensed
+      under the Apache license and therefore freely distributable.
+    </description>
+    <used-by>Mail</used-by>
+    <lib>optional/geronimo-spec-activation-1.0.2-rc4.jar</lib>
+    <homepage>http://geronimo.apache.org/</homepage>
+  </file>
+  <!-- JMS block begin -->
+  <file id="geronimo-spec-jms">
+    <title>JMS Spec</title>
+    <description>
+      J2EE Java Message Service Specification.  This implentation
+      developed by the (currently incubating) Apache Geronimo project is an
+      open source implementation from the original spec.  As such it is licensed 
+      under the Apache license and therefore freely distributable.
+    </description>
+    <used-by>JMS</used-by>
+    <lib>optional/geronimo-spec-jms-1.1-rc3.jar</lib>
+    <homepage>http://geronimo.apache.org/</homepage>
+  </file>
+  <!--
+  <file id="openjms-exolabcore-">
+    <title>OpenJMS</title>
+    <description>OpenJMS core libraries. OpenJMS is a OpenSource JMS, Java Messaging
+    Service, implementation.</description>
+    <used-by>JMS</used-by>
+    <lib>optional/exolabcore-0.3.6.jar</lib>
+    <homepage>http://openjms.sf.net</homepage>
+  </file>
+
+  <file id="openjms-client">
+    <title>OpenJMS</title>
+    <description>OpenJMS client libraries. OpenJMS is a OpenSource JMS, Java Messaging
+    Service, implementation.</description>
+    <used-by>JMS</used-by>
+    <lib>optional/openjms-client-0.7.6-rc2.jar</lib>
+    <homepage>http://openjms.sf.net</homepage>
+  </file>
+
+  <file id="jms-api">
+    <title>Sun JMS API</title>
+    <description>Sun's Java Messaging Service APIs. From the website:
+       Enterprise messaging provides a reliable,
+       flexible service for the asynchronous
+       exchange of critical business data and events
+       throughout an enterprise. The JMS API adds to
+       this a common API and provider framework that
+       enables the development of portable, message
+       based applications in the Java programming
+       language.
+    </description>
+    <used-by>JMS</used-by>
+    <lib>optional/jms-1.0.2a.jar</lib>
+    <homepage>http://java.sun.com/jms</homepage>
+  </file>
+
+  <file id="jndi-api">
+    <title>Sun JNDI</title>
+    <description>Sun's Java Naming and Directory Interface. From the website:
+       The Java Naming and Directory Interface (JNDI) is a standard extension to
+       the Java platform, providing Java technology-enabled applications with a
+       unified interface to multiple naming and directory services in the
+       enterprise. As part of the Java Enterprise API set, JNDI enables seamless
+       connectivity to heterogeneous enterprise naming and directory services.
+       Developers can now build powerful and portable directory-enabled
+       applications using this industry standard.</description>
+    <used-by>JMS</used-by>
+    <lib>optional/jndi-1.2.1.jar</lib>
+    <homepage>http://java.sun.com/jndi</homepage>
+  </file>
+  -->
+  <!-- JMS block end -->
+
+  <file id="portlet-api">
+    <title>JSR-168 Portlet Spec</title>
+    <description>
+      JSR-168 Portlet Specification. This implentation developed by the
+      Apache Pluto project is an open source implementation from the
+      original spec.
+    </description>
+    <used-by>Portal</used-by>
+    <lib>optional/portlet-api-1.0.jar</lib>
+    <homepage>http://portals.apache.org/pluto/</homepage>
+  </file>
+  <file id="pluto">
+    <title>JSR-168 Container Implementation</title>
+    <description>
+      JSR-168 Portlet Specification. This implentation developed by the
+      Apache Pluto project is an open source implementation from the
+      original spec.
+    </description>
+    <used-by>Portal</used-by>
+    <lib>optional/pluto-1.0.1.jar</lib>
+    <homepage>http://portals.apache.org/pluto/</homepage>
+  </file>
+  <file id="portals-bridges-common">
+    <title>Portals Bridges</title>
+    <description>
+      Portals Bridges provides support for JSR-168 compliant Portlet development
+      using common web frameworks like Struts, JSF, PHP, Perl and Velocity. 
+    </description>
+    <used-by>Portal</used-by>
+    <lib>optional/portals-bridges-common-1.0.jar</lib>
+    <homepage>http://portals.apache.org/bridges/</homepage>
+  </file>
+  <file id="cowarp">
+    <title>CoWarp</title>
+    <description>
+      A web application framework for Cocoon providing an authentication mechanism
+      with special support for the portal.
+    </description>
+    <used-by>Portal</used-by>
+    <lib>optional/cowarp-0.5-dev-20051002.jar</lib>
+    <homepage>http://osoco.sourceforge.net/cowarp/</homepage>
+  </file>
+
+  <file id="jakarta-bcel">
+    <title>Jakarta BCEL</title>
+    <description>
+      The Byte Code Engineering Library is intended to give users a convenient
+      possibility to analyze, create, and manipulate (binary) Java class files.
+    </description>
+    <used-by>XSLTC, javaflow</used-by>
+    <lib>endorsed/jakarta-bcel-20040329.jar</lib>
+    <homepage>http://jakarta.apache.org/bcel/</homepage>
+  </file>
+
+  <file id="myfaces">
+    <title>MyFaces</title>
+    <description>
+      MyFaces is an open source implementation of the JSR-127 JavaServer Faces
+      specification.
+    </description>
+    <used-by>Faces block</used-by>
+    <lib>optional/myfaces-impl-r233484.jar</lib>
+    <homepage>http://myfaces.apache.org/</homepage>
+  </file>
+
+  <file id="myfaces-jsf-api">
+    <title>MyFaces</title>
+    <description>
+      MyFaces is an open source implementation of the JSR-127 JavaServer Faces
+      specification.
+    </description>
+    <used-by>Faces block</used-by>
+    <lib>optional/myfaces-api-r233484.jar</lib>
+    <homepage>http://myfaces.apache.org/</homepage>
+  </file>
+
+  <file id="commons-el">
+    <title>Jakarta Commons EL</title>
+    <description>
+      EL is the JSP 2.0 Expression Language Interpreter from Apache.
+    </description>
+    <used-by>Faces block</used-by>
+    <lib>optional/commons-el-1.0.jar</lib>
+    <homepage>http://jakarta.apache.org/commons/el/</homepage>
+  </file>
+
+  <file id="jsp-api">
+    <title>Apache Tomcat JSP API</title>
+    <description>
+      JSP API classes from Apache Tomcat
+    </description>
+    <used-by>Faces block</used-by>
+    <lib>optional/jsp-api-2.0.jar</lib>
+    <homepage>http://jakarta.apache.org/tomcat/</homepage>
+  </file>
+
+  <file id="commons-jci">
+    <title>Java Compilation Interface API</title>
+    <description>
+      API for compiling java
+    </description>
+    <used-by>javaflow</used-by>
+    <lib>core/commons-jci-r306555.jar</lib>
+    <homepage></homepage>
+  </file>
+
+  <file id="commons-javaflow">
+    <title>Javaflow API</title>
+    <description>
+      API java continuations
+    </description>
+    <used-by>javaflow</used-by>
+    <lib>core/commons-javaflow-r306555.jar</lib>
+    <homepage></homepage>
+  </file>
+
+  <file>
+    <title>JCR API</title>
+    <description>
+      JCR (aka JSR-170 API)
+    </description>
+    <used-by>JCR block</used-by>
+    <lib>optional/jcr-1.0.jar</lib>
+    <homepage>http://www.jcp.org/en/jsr/detail?id=170</homepage>
+  </file>
+
+  <file>
+    <title>Jackrabbit</title>
+    <description>
+      Jackrabbit JCR implementation
+    </description>
+    <used-by>JCR block</used-by>
+    <lib>optional/jackrabbit-commons-1.0-dev-r292737.jar</lib>
+    <homepage>http://incubator.apache.org/jackrabbit/</homepage>
+  </file>
+
+  <file>
+    <title>Jackrabbit</title>
+    <description>
+      Jackrabbit JCR implementation
+    </description>
+    <used-by>JCR block</used-by>
+    <lib>optional/jackrabbit-1.0-dev-r292737.jar</lib>
+    <homepage>http://incubator.apache.org/jackrabbit/</homepage>
+  </file>
+
+  <file id="spring-core">
+    <title>Spring</title>
+    <description>
+      The Spring Framework.
+    </description>
+    <used-by>Spring block</used-by>
+    <lib>optional/spring-1.2.6.jar</lib>
+    <homepage>http://www.springframework.org/</homepage>
+  </file>
+  
+  <file id="knopflerfish-cm_api">
+    <title>Knopflerfish CM</title>
+    <description>
+      Knopflerfish CM
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-cm_api-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>  
+  
+  <file id="knopflerfish-console">
+    <title>Knopflerfish Console</title>
+    <description>
+      Knopflerfish Console
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-console_all-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>    
+  
+  <file id="knopflerfish-consoletty">
+    <title>Knopflerfish Consoletty</title>
+    <description>
+      Knopflerfish
+    </description> Consoletty
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-consoletty-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>  
+ 
+  <file id="knopflerfish-framework">
+    <title>Knopflerfish Framework</title>
+    <description>
+      Knopflerfish Framework
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-framework-1.3.3.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>     
+
+  <file id="knopflerfish-frameworkcommands">
+    <title>Knopflerfish</title>
+    <description>
+      Knopflerfish framework commands
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-frameworkcommands-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>  
+  <file id="knopflerfish-http-all">
+    <title>Knopflerfish HTTP</title>
+    <description>
+      Knopflerfish HTTP
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-http_all-1.1.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>  
+  
+  <file id="knopflerfish-log">
+    <title>Knopflerfish Log</title>
+    <description>
+      Knopflerfish Log
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-log_all-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>  
+  
+  <file id="knopflerfish-logcommands">
+    <title>Knopflerfish log commands</title>
+    <description>
+      Knopflerfish Logcommands
+    </description>
+    <used-by>OSGI</used-by>
+    <lib>core/knopflerfish-logcommands-1.0.0.jar</lib>
+    <homepage>http://www.knopflerfish.org/</homepage>
+  </file>   
+
+  <file id="wsrp4j-shared">
+    <title>WSRP4J Shared</title>
+    <description>
+      WSRP implementation from the WSRP4J project.
+    </description>
+    <used-by>Portal block</used-by>
+    <lib>optional/wsrp4j-shared-0.3-dev.jar</lib>
+    <homepage>http://ws.apache.org/wsrp4j/</homepage>
+  </file>
+
+  <file id="wsrp-consumer">
+    <title>WSRP4J Consumer</title>
+    <description>
+      WSRP implementation from the WSRP4J project.
+    </description>
+    <used-by>Portal block</used-by>
+    <lib>optional/wsrp4j-consumer-0.3-dev.jar</lib>
+    <homepage>http://ws.apache.org/wsrp4j/</homepage>
+  </file>
+   
+  <file>
+    <title>JDBI</title>
+    <description>
+      Convenient access to JDBC using Maps and List.
+    </description>
+    <used-by>Forms block</used-by>
+    <lib>optional/jdbi-1.3.1.jar</lib>
+    <homepage>http://jdbi.codehaus.org/</homepage>
+  </file>
+  
+  <file id="mx4j-jmx">
+    <title>JMX interfaces</title>
+    <description>
+      The JMX interfaces from the MX4J project.
+    </description>
+    <used-by>Core</used-by>
+    <lib>core/mx4j-jmx-3.0.1.jar</lib>
+    <homepage>http://mx4j.sourceforge.net/</homepage>
+  </file>
+
+  <file id="jetty-jmx">
+    <title>Jetty JMX</title>
+    <description>
+      Jetty JMX support for ModelMBeanImpl.
+    </description>
+    <used-by>Core</used-by>
+    <lib>core/jetty-jmx-5.1.8.jar</lib>
+    <homepage>http://jetty.mortbay.org/jetty/</homepage>
+  </file>
+
+</jars>
+
diff --git a/non-releases/trunk_before_flattening/lib/local/local-libs.txt b/non-releases/trunk_before_flattening/lib/local/local-libs.txt
new file mode 100644
index 0000000..6641388
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/local/local-libs.txt
@@ -0,0 +1,5 @@
+Put here local libraries required for optional components, such as JFor or JavaMail.
+
+Local libraries aren't checked by the jar-checking system, so you must ensure they do
+not conflict with libraries that are part of the Cocoon distribution (directories core/
+and optional/).
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/lib/optional/antlr-2.7.5.jar b/non-releases/trunk_before_flattening/lib/optional/antlr-2.7.5.jar
new file mode 100644
index 0000000..fbe5e3c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/antlr-2.7.5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/apache-garbage-0.0.jar b/non-releases/trunk_before_flattening/lib/optional/apache-garbage-0.0.jar
new file mode 100644
index 0000000..7d00469
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/apache-garbage-0.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/asm-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/asm-2.1.jar
new file mode 100644
index 0000000..4f47899
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/asm-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/asm-util-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/asm-util-2.1.jar
new file mode 100644
index 0000000..103b8be
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/asm-util-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/axis-1.2.1.jar b/non-releases/trunk_before_flattening/lib/optional/axis-1.2.1.jar
new file mode 100644
index 0000000..df936e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/axis-1.2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/axis-jaxrpc-1.2.1.jar b/non-releases/trunk_before_flattening/lib/optional/axis-jaxrpc-1.2.1.jar
new file mode 100644
index 0000000..fe0b047
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/axis-jaxrpc-1.2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/axis-saaj-1.2.1.jar b/non-releases/trunk_before_flattening/lib/optional/axis-saaj-1.2.1.jar
new file mode 100644
index 0000000..b495028
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/axis-saaj-1.2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/batik-all-1.6.jar b/non-releases/trunk_before_flattening/lib/optional/batik-all-1.6.jar
new file mode 100644
index 0000000..7816fdc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/batik-all-1.6.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/bsf-2.3.0.jar b/non-releases/trunk_before_flattening/lib/optional/bsf-2.3.0.jar
new file mode 100644
index 0000000..caa4dea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/bsf-2.3.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/castor-0.9.6-xml.jar b/non-releases/trunk_before_flattening/lib/optional/castor-0.9.6-xml.jar
new file mode 100644
index 0000000..444c5a1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/castor-0.9.6-xml.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/chaperon-20040205.jar b/non-releases/trunk_before_flattening/lib/optional/chaperon-20040205.jar
new file mode 100644
index 0000000..16ebe3b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/chaperon-20040205.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/cocoon-serializers-charsets-0.1.jar b/non-releases/trunk_before_flattening/lib/optional/cocoon-serializers-charsets-0.1.jar
new file mode 100644
index 0000000..b829f30
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/cocoon-serializers-charsets-0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-beanutils-core-1.7.0.jar b/non-releases/trunk_before_flattening/lib/optional/commons-beanutils-core-1.7.0.jar
new file mode 100644
index 0000000..ce79cbe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-beanutils-core-1.7.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-betwixt-0.6.jar b/non-releases/trunk_before_flattening/lib/optional/commons-betwixt-0.6.jar
new file mode 100644
index 0000000..7e66c5f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-betwixt-0.6.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-codec-1.3.jar b/non-releases/trunk_before_flattening/lib/optional/commons-codec-1.3.jar
new file mode 100644
index 0000000..957b675
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-codec-1.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-dbcp-1.2.1.jar b/non-releases/trunk_before_flattening/lib/optional/commons-dbcp-1.2.1.jar
new file mode 100644
index 0000000..1aa4242
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-dbcp-1.2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-digester-1.7.jar b/non-releases/trunk_before_flattening/lib/optional/commons-digester-1.7.jar
new file mode 100644
index 0000000..1783dbe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-digester-1.7.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-discovery-0.2.jar b/non-releases/trunk_before_flattening/lib/optional/commons-discovery-0.2.jar
new file mode 100644
index 0000000..b885548
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-discovery-0.2.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-el-1.0.jar b/non-releases/trunk_before_flattening/lib/optional/commons-el-1.0.jar
new file mode 100644
index 0000000..608ed79
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-el-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-pool-1.2.jar b/non-releases/trunk_before_flattening/lib/optional/commons-pool-1.2.jar
new file mode 100644
index 0000000..df45b82
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-pool-1.2.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/commons-transaction-1.0.1.jar b/non-releases/trunk_before_flattening/lib/optional/commons-transaction-1.0.1.jar
new file mode 100644
index 0000000..8192188
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/commons-transaction-1.0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/cowarp-0.5-dev-20051002.jar b/non-releases/trunk_before_flattening/lib/optional/cowarp-0.5-dev-20051002.jar
new file mode 100644
index 0000000..581055f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/cowarp-0.5-dev-20051002.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/daisy-htmlcleaner-1.1.jar b/non-releases/trunk_before_flattening/lib/optional/daisy-htmlcleaner-1.1.jar
new file mode 100644
index 0000000..74af2c2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/daisy-htmlcleaner-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/daisy-util-1.1.jar b/non-releases/trunk_before_flattening/lib/optional/daisy-util-1.1.jar
new file mode 100644
index 0000000..82c2de6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/daisy-util-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/db-ojb-1.0.3.jar b/non-releases/trunk_before_flattening/lib/optional/db-ojb-1.0.3.jar
new file mode 100644
index 0000000..d33a57c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/db-ojb-1.0.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/deli-x050330.jar b/non-releases/trunk_before_flattening/lib/optional/deli-x050330.jar
new file mode 100644
index 0000000..76f041a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/deli-x050330.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/excalibur-datasource-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/excalibur-datasource-2.1.jar
new file mode 100644
index 0000000..9de006e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/excalibur-datasource-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/fop-0.20.5.jar b/non-releases/trunk_before_flattening/lib/optional/fop-0.20.5.jar
new file mode 100644
index 0000000..5e8503a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/fop-0.20.5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-activation-1.0.2-rc4.jar b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-activation-1.0.2-rc4.jar
new file mode 100644
index 0000000..51f98e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-activation-1.0.2-rc4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-javamail-1.3.1-rc5.jar b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-javamail-1.3.1-rc5.jar
new file mode 100644
index 0000000..797b13a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-javamail-1.3.1-rc5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jms-1.1-rc3.jar b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jms-1.1-rc3.jar
new file mode 100644
index 0000000..12d392f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jms-1.1-rc3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jta-1.0.1B-rc3.jar b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jta-1.0.1B-rc3.jar
new file mode 100644
index 0000000..b8ef9f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/geronimo-spec-jta-1.0.1B-rc3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/groovy-1.0-jsr-04.jar b/non-releases/trunk_before_flattening/lib/optional/groovy-1.0-jsr-04.jar
new file mode 100644
index 0000000..d43a686
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/groovy-1.0-jsr-04.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/hsqldb-1.8.0.2.jar b/non-releases/trunk_before_flattening/lib/optional/hsqldb-1.8.0.2.jar
new file mode 100644
index 0000000..ffba899
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/hsqldb-1.8.0.2.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/icu4j-3.0.jar b/non-releases/trunk_before_flattening/lib/optional/icu4j-3.0.jar
new file mode 100644
index 0000000..b697696
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/icu4j-3.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/itext-1.1.jar b/non-releases/trunk_before_flattening/lib/optional/itext-1.1.jar
new file mode 100644
index 0000000..6793a42
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/itext-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jackrabbit-1.0-dev-r292737.jar b/non-releases/trunk_before_flattening/lib/optional/jackrabbit-1.0-dev-r292737.jar
new file mode 100644
index 0000000..4218726
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jackrabbit-1.0-dev-r292737.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jackrabbit-commons-1.0-dev-r292737.jar b/non-releases/trunk_before_flattening/lib/optional/jackrabbit-commons-1.0-dev-r292737.jar
new file mode 100644
index 0000000..3a892e4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jackrabbit-commons-1.0-dev-r292737.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jakarta-oro-2.0.8.jar b/non-releases/trunk_before_flattening/lib/optional/jakarta-oro-2.0.8.jar
new file mode 100644
index 0000000..23488d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jakarta-oro-2.0.8.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jakarta-slide-webdavlib-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/jakarta-slide-webdavlib-2.1.jar
new file mode 100644
index 0000000..f20f1c4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jakarta-slide-webdavlib-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jcr-1.0.jar b/non-releases/trunk_before_flattening/lib/optional/jcr-1.0.jar
new file mode 100644
index 0000000..dcb71cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jcr-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jdbi-1.3.1.jar b/non-releases/trunk_before_flattening/lib/optional/jdbi-1.3.1.jar
new file mode 100644
index 0000000..c401b50
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jdbi-1.3.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jdom-1.0.jar b/non-releases/trunk_before_flattening/lib/optional/jdom-1.0.jar
new file mode 100644
index 0000000..288e64c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jdom-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jdtcore-3.1.0.jar b/non-releases/trunk_before_flattening/lib/optional/jdtcore-3.1.0.jar
new file mode 100644
index 0000000..d920738
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jdtcore-3.1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jena-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/jena-2.1.jar
new file mode 100644
index 0000000..c71a3cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jena-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jfor-0.7.1.jar b/non-releases/trunk_before_flattening/lib/optional/jfor-0.7.1.jar
new file mode 100644
index 0000000..4fd89fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jfor-0.7.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jing-20030619.jar b/non-releases/trunk_before_flattening/lib/optional/jing-20030619.jar
new file mode 100644
index 0000000..6acbfb0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jing-20030619.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/joost-20040330.jar b/non-releases/trunk_before_flattening/lib/optional/joost-20040330.jar
new file mode 100644
index 0000000..b169190
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/joost-20040330.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jsp-api-2.0.jar b/non-releases/trunk_before_flattening/lib/optional/jsp-api-2.0.jar
new file mode 100644
index 0000000..c8a1d1c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jsp-api-2.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/jtidy-04aug2000r7-dev.jar b/non-releases/trunk_before_flattening/lib/optional/jtidy-04aug2000r7-dev.jar
new file mode 100644
index 0000000..a11dfe5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/jtidy-04aug2000r7-dev.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/lucene-1.4.3.jar b/non-releases/trunk_before_flattening/lib/optional/lucene-1.4.3.jar
new file mode 100644
index 0000000..58add99
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/lucene-1.4.3.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/myfaces-api-r233484.jar b/non-releases/trunk_before_flattening/lib/optional/myfaces-api-r233484.jar
new file mode 100644
index 0000000..ab689e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/myfaces-api-r233484.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/myfaces-impl-r233484.jar b/non-releases/trunk_before_flattening/lib/optional/myfaces-impl-r233484.jar
new file mode 100644
index 0000000..ecf0823
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/myfaces-impl-r233484.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/nekodtd-0.1.11.jar b/non-releases/trunk_before_flattening/lib/optional/nekodtd-0.1.11.jar
new file mode 100644
index 0000000..96e0c30
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/nekodtd-0.1.11.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/nekohtml-0.9.5.jar b/non-releases/trunk_before_flattening/lib/optional/nekohtml-0.9.5.jar
new file mode 100644
index 0000000..ebd5b4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/nekohtml-0.9.5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/pluto-1.0.1.jar b/non-releases/trunk_before_flattening/lib/optional/pluto-1.0.1.jar
new file mode 100644
index 0000000..e43aab6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/pluto-1.0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/poi-2.5.1-final-20040804.jar b/non-releases/trunk_before_flattening/lib/optional/poi-2.5.1-final-20040804.jar
new file mode 100644
index 0000000..149b801
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/poi-2.5.1-final-20040804.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/portals-bridges-common-1.0.jar b/non-releases/trunk_before_flattening/lib/optional/portals-bridges-common-1.0.jar
new file mode 100644
index 0000000..40dcd2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/portals-bridges-common-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/portlet-api-1.0.jar b/non-releases/trunk_before_flattening/lib/optional/portlet-api-1.0.jar
new file mode 100644
index 0000000..60dd7d8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/portlet-api-1.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/qdox-1.5.jar b/non-releases/trunk_before_flattening/lib/optional/qdox-1.5.jar
new file mode 100644
index 0000000..7ef9a8a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/qdox-1.5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/quartz-1.5.0.jar b/non-releases/trunk_before_flattening/lib/optional/quartz-1.5.0.jar
new file mode 100644
index 0000000..4699e3b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/quartz-1.5.0.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/slide-kernel-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/slide-kernel-2.1.jar
new file mode 100644
index 0000000..39a573e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/slide-kernel-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/slide-stores-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/slide-stores-2.1.jar
new file mode 100644
index 0000000..2fa44fb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/slide-stores-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/slide-webdavservlet-2.1.jar b/non-releases/trunk_before_flattening/lib/optional/slide-webdavservlet-2.1.jar
new file mode 100644
index 0000000..7618ae5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/slide-webdavservlet-2.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/spring-1.2.6.jar b/non-releases/trunk_before_flattening/lib/optional/spring-1.2.6.jar
new file mode 100644
index 0000000..f14370f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/spring-1.2.6.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/velocity-1.4.jar b/non-releases/trunk_before_flattening/lib/optional/velocity-1.4.jar
new file mode 100644
index 0000000..04ec9d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/velocity-1.4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/wsdl4j-1.5.1.jar b/non-releases/trunk_before_flattening/lib/optional/wsdl4j-1.5.1.jar
new file mode 100644
index 0000000..c6254ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/wsdl4j-1.5.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/wsrp4j-consumer-0.3-dev.jar b/non-releases/trunk_before_flattening/lib/optional/wsrp4j-consumer-0.3-dev.jar
new file mode 100644
index 0000000..cd8b44c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/wsrp4j-consumer-0.3-dev.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/wsrp4j-shared-0.3-dev.jar b/non-releases/trunk_before_flattening/lib/optional/wsrp4j-shared-0.3-dev.jar
new file mode 100644
index 0000000..3bab098
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/wsrp4j-shared-0.3-dev.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xindice-1.1b4.jar b/non-releases/trunk_before_flattening/lib/optional/xindice-1.1b4.jar
new file mode 100644
index 0000000..ef9f333
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xindice-1.1b4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xmldb-api-20030701.jar b/non-releases/trunk_before_flattening/lib/optional/xmldb-api-20030701.jar
new file mode 100644
index 0000000..23f7e18
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xmldb-api-20030701.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xmldb-common-20030701.jar b/non-releases/trunk_before_flattening/lib/optional/xmldb-common-20030701.jar
new file mode 100644
index 0000000..3fb0302
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xmldb-common-20030701.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xmldb-xupdate-20040205.jar b/non-releases/trunk_before_flattening/lib/optional/xmldb-xupdate-20040205.jar
new file mode 100644
index 0000000..3b7f931
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xmldb-xupdate-20040205.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xmlrpc-1.1.jar b/non-releases/trunk_before_flattening/lib/optional/xmlrpc-1.1.jar
new file mode 100644
index 0000000..b360b03
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xmlrpc-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/lib/optional/xreporter-expression-20040701.jar b/non-releases/trunk_before_flattening/lib/optional/xreporter-expression-20040701.jar
new file mode 100644
index 0000000..06974cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/lib/optional/xreporter-expression-20040701.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/awards/xmlj-award-2001.jpg b/non-releases/trunk_before_flattening/misc/awards/xmlj-award-2001.jpg
new file mode 100644
index 0000000..7ebb107
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/awards/xmlj-award-2001.jpg
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon-buttons.psd b/non-releases/trunk_before_flattening/misc/graphics/cocoon-buttons.psd
new file mode 100644
index 0000000..6f59f29
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon-buttons.psd
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon.ai b/non-releases/trunk_before_flattening/misc/graphics/cocoon.ai
new file mode 100644
index 0000000..0aaa8a3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon.ai
@@ -0,0 +1,7249 @@
+%!PS-Adobe-3.0 
+%%Creator: Adobe Illustrator(R) 8.0
+%%AI8_CreatorVersion: 8
+%%Title: (cocoon2.ai)
+%%CreationDate: (12/11/99) (1:33 AM)
+%%BoundingBox: 12 42 583 822
+%%HiResBoundingBox: 12.771 42.3027 582.9004 821.7056
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%%DocumentFonts: AvantGarde-Book
+%%DocumentNeededFonts: AvantGarde-Book
+%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0
+%%+ procset Adobe_typography_AI5 1.0 1
+%%+ procset Adobe_ColorImage_AI6 1.3 0
+%%+ procset Adobe_Illustrator_AI5 1.3 0
+%%+ procset Adobe_cshow 2.0 8
+%%+ procset Adobe_shading_AI8 1.0 0
+%AI5_FileFormat 4.0
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%CMYKProcessColor: 1 1 1 1 ([Registration])
+%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) 
+%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 2 3 4
+%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () 
+%AI3_TemplateBox: 296.5 419.5 296.5 419.5
+%AI3_TileBox: 8 38 584 800
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 592 840
+%AI5_RulerUnits: 1
+%AI5_ArtFlags: 1 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 1
+%AI8_OpenToView: -143 667 1 1016 673 18 0 1 14 65 1 1
+%AI5_OpenViewLayers: 7
+%%PageOrigin:8 38
+%%AI3_PaperRect:-8 802 587 -40
+%%AI3_Margin:8 -39 -9 40
+%AI7_GridSettings: 14.1732 2 14.1732 2 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI7_Thumbnail: 96 128 8
+%%BeginData: 26112 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%05060C0606060C0606060C0606060C0606060C0606060C0606060C060606
+%0C0606060C0606060C0606060C0606060C0606060C0606060C0606060C06
+%06060C0606060C0606060C0606060C0606060C0606060C0606060C060606
+%0C060605FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D0D140D140D140D140D140D140D140D140D140D0D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0614131414133613361414133614360D3614361336131414
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF050D140D0D148484A8AF366036A95A368484
+%84FF5A140D0D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF06141314140D0D0D140D1413
+%1413140D36143613363636140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D05FFFF060D140D0D14
+%0D0D060D0D0D0D140D14353635363536130D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D14140D1413140D140D130D1413140D1413140D141413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D0D140D140D130D130D0D0D140D140D140D140D0D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%050D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF050D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D05FFFF050D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF061413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D05FFFF050D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D05FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF050D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF061413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D05FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%050D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF050D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D05FFFF050D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF061413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D05FFFF050D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D05FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF050D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF061413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D05FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%050D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%0C140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D141305FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF050D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF061413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D05FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D1427FFFF0C140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D141305FFFF060D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D05FFFF050D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D1427FFFF061413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D05FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF0C140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D141305FFFF060D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D848459843536848459A8145A7D8459842F5A7D8459841484
+%5984845A358459847D2F140D140D1427FFFF061413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D60840D2F0D35A8590D605384FF2E0D2F0D3CA8
+%2F0D847D85A8840D5AA984522F0D60A80D1413140D05FFFF050D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D1436A8845A845959A8845AA805A8
+%84845A842FA8598459A80DA853845AA85959140D14A8140D140D1427FFFF
+%061413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1460355A595914
+%5A59590C2F1460355A5959145A59590D0D1459355A1335130D14130D0D14
+%13140D05FFFF060D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D147D140D0D360D2F3659142F2F350D0D140D350D140D140D
+%140D142F140D140D1427FFFF0C140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413357E593C35845A840C84847D5959A96059
+%845A847D7E597D5A848435140D141305FFFF060D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D0D35140D140D140D140D140D140D140D1427FFFF0C140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D141305FFFF
+%060D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D140D140D140D140D140D140D140D140D140D140D140D140D140D140D
+%140D1427FFFF061413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D1413140D1413140D1413140D1413140D1413140D14
+%13140D1413140D1413140D1413140D1413140D1413140D1413140D141314
+%0D1413140D1413140D05FFFFF80606050506060505060605050606050506
+%060505060605050606050506060505060605050606050506060505060605
+%050606050506060505060605050606050506060505060605050606050506
+%06050506060505060605050606050527FFFF
+%%EndData
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Adobe_level2_AI5 1.2 0
+%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
+%%Version: 1.2 0
+%%CreationDate: (04/10/93) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+userdict /Adobe_level2_AI5 26 dict dup begin
+	put
+	/packedarray where not
+	{
+		userdict begin
+		/packedarray
+		{
+			array astore readonly
+		} bind def
+		/setpacking /pop load def
+		/currentpacking false def
+	 end
+		0
+	} if
+	pop
+	userdict /defaultpacking currentpacking put true setpacking
+	/initialize
+	{
+		Adobe_level2_AI5 begin
+	} bind def
+	/terminate
+	{
+		currentdict Adobe_level2_AI5 eq
+		{
+		 end
+		} if
+	} bind def
+	mark
+	/setcustomcolor where not
+	{
+		/findcmykcustomcolor
+		{
+			(AI8_CMYK_CustomColor)
+			6 packedarray
+		} bind def
+		/findrgbcustomcolor
+		{
+			(AI8_RGB_CustomColor)
+			5 packedarray
+		} bind def
+		/setcustomcolor
+		{
+			exch 
+			aload pop dup
+			(AI8_CMYK_CustomColor) eq
+			{
+				pop pop
+				4
+				{
+					4 index mul
+					4 1 roll
+				} repeat
+				5 -1 roll pop
+				setcmykcolor
+			}
+			{
+				dup (AI8_RGB_CustomColor) eq
+				{
+					pop pop
+					3
+					{
+						1 exch sub
+						3 index mul 
+						1 exch sub
+						3 1 roll
+					} repeat
+					4 -1 roll pop
+					setrgbcolor
+				}
+				{
+					pop
+					4
+					{
+						4 index mul 4 1 roll
+					} repeat
+					5 -1 roll pop
+					setcmykcolor
+				} ifelse
+			} ifelse
+		}
+		def
+	} if
+	/setAIseparationgray
+	{
+		false setoverprint
+		0 setgray
+		/setseparationgray where{
+			pop setseparationgray
+		}{
+			/setcolorspace where{
+				pop
+				[/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace
+				1 exch sub setcolor
+			}{
+				setgray
+			}ifelse
+		}ifelse
+	} def
+	
+	/gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
+	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
+	userdict /level2?
+	systemdict /languagelevel known dup
+	{
+		pop systemdict /languagelevel get 2 ge
+	} if
+	put
+/level2ScreenFreq
+{
+ begin
+		60
+		HalftoneType 1 eq
+		{
+			pop Frequency
+		} if
+		HalftoneType 2 eq
+		{
+			pop GrayFrequency
+		} if
+		HalftoneType 5 eq
+		{
+			pop Default level2ScreenFreq
+		} if
+ end
+} bind def
+userdict /currentScreenFreq  
+	level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
+level2? not
+	{
+		/setcmykcolor where not
+		{
+			/setcmykcolor
+			{
+				exch .11 mul add exch .59 mul add exch .3 mul add
+				1 exch sub setgray
+			} def
+		} if
+		/currentcmykcolor where not
+		{
+			/currentcmykcolor
+			{
+				0 0 0 1 currentgray sub
+			} def
+		} if
+		/setoverprint where not
+		{
+			/setoverprint /pop load def
+		} if
+		/selectfont where not
+		{
+			/selectfont
+			{
+				exch findfont exch
+				dup type /arraytype eq
+				{
+					makefont
+				}
+				{
+					scalefont
+				} ifelse
+				setfont
+			} bind def
+		} if
+		/cshow where not
+		{
+			/cshow
+			{
+				[
+				0 0 5 -1 roll aload pop
+				] cvx bind forall
+			} bind def
+		} if
+	} if
+	cleartomark
+	/anyColor?
+	{
+		add add add 0 ne
+	} bind def
+	/testColor
+	{
+		gsave
+		setcmykcolor currentcmykcolor
+		grestore
+	} bind def
+	/testCMYKColorThrough
+	{
+		testColor anyColor?
+	} bind def
+	userdict /composite?
+	1 0 0 0 testCMYKColorThrough
+	0 1 0 0 testCMYKColorThrough
+	0 0 1 0 testCMYKColorThrough
+	0 0 0 1 testCMYKColorThrough
+	and and and
+	put
+	composite? not
+	{
+		userdict begin
+		gsave
+		/cyan? 1 0 0 0 testCMYKColorThrough def
+		/magenta? 0 1 0 0 testCMYKColorThrough def
+		/yellow? 0 0 1 0 testCMYKColorThrough def
+		/black? 0 0 0 1 testCMYKColorThrough def
+		grestore
+		/isCMYKSep? cyan? magenta? yellow? black? or or or def
+		/customColor? isCMYKSep? not def
+	 end
+	} if
+ end defaultpacking setpacking
+%%EndResource
+%%BeginResource: procset Adobe_typography_AI5 1.0 1
+%%Title: (Typography Operators)
+%%Version: 1.0 1
+%%CreationDate:(6/10/1996) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_typography_AI5 68 dict dup begin
+put
+/initialize
+{
+ begin
+ begin
+	Adobe_typography_AI5 begin
+	Adobe_typography_AI5
+	{
+		dup xcheck
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+ end
+ end
+	Adobe_typography_AI5 begin
+} def
+/terminate
+{
+	currentdict Adobe_typography_AI5 eq
+	{
+	 end
+	} if
+} def
+/modifyEncoding
+{
+	/_tempEncode exch ddef
+	/_pntr 0 ddef
+	{
+		counttomark -1 roll
+		dup type dup /marktype eq
+		{
+			pop pop exit
+		}
+		{
+			/nametype eq
+			{
+				_tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll
+				put
+			}
+			{
+				/_pntr exch ddef
+			} ifelse
+		} ifelse
+	} loop
+	_tempEncode
+} def
+/havefont
+{
+	systemdict /languagelevel known
+		{
+		/Font resourcestatus dup
+			{ exch pop exch pop }
+		if
+		}
+		{
+		systemdict /FontDirectory get 1 index known
+			{ pop true }
+			{
+			systemdict /fileposition known
+				{
+				dup length 6 add exch
+				Ss 6 250 getinterval
+				cvs pop
+				Ss exch 0 exch getinterval
+				status
+					{ pop pop pop pop true }
+					{ false }
+				ifelse
+				}
+				{
+				pop false
+				}
+			ifelse
+			}
+		ifelse
+		}
+	ifelse
+} def
+/TE
+{
+	StandardEncoding 256 array copy modifyEncoding
+	/_nativeEncoding exch def
+} def
+/subststring {
+	exch 2 index exch search
+	{
+		exch pop
+		exch dup () eq
+		{
+			pop exch concatstring
+		}
+		{
+			3 -1 roll
+			exch concatstring
+			concatstring
+		} ifelse
+		exch pop true
+	}
+	{
+		pop pop false
+	} ifelse
+} def
+/concatstring {
+	1 index length 1 index length
+	1 index add
+	string
+	dup 0 5 index putinterval
+	dup 2 index 4 index putinterval
+	4 1 roll pop pop pop
+} def
+%
+/TZ
+{
+	dup type /arraytype eq
+	{
+		/_wv exch def
+	}
+	{
+		/_wv 0 def
+	} ifelse
+	/_useNativeEncoding exch def
+	2 index havefont
+	{
+		3 index
+		255 string
+		cvs
+		
+		dup
+		(_Symbol_)
+		eq
+		{
+			pop
+			2 index
+			findfont
+			
+		}
+		{
+			1 index 0 eq
+			{
+				dup length 1 sub
+				1 exch
+				getinterval
+				
+				cvn
+				findfont
+			}
+			{
+				pop 2 index findfont
+			} ifelse
+		} ifelse
+	}
+	{
+		dup 1 eq
+		{
+			2 index 64 string cvs
+			dup (-90pv-RKSJ-) (-83pv-RKSJ-) subststring
+			{
+				exch pop dup havefont
+				{
+					findfont false
+				}
+				{
+					pop true
+				} ifelse
+			}
+			{
+				pop	dup
+				(-90ms-RKSJ-) (-Ext-RKSJ-) subststring
+				{
+					exch pop dup havefont
+					{
+						findfont false
+					}
+					{
+						pop true
+					} ifelse
+				}
+				{
+					pop pop true
+				} ifelse
+			} ifelse
+			{
+				1 index 1 eq
+				{
+					/Ryumin-Light-Ext-RKSJ-V havefont
+					{/Ryumin-Light-Ext-RKSJ-V}
+					{/Courier}
+					ifelse
+				}
+				{
+					/Ryumin-Light-83pv-RKSJ-H havefont
+					{/Ryumin-Light-83pv-RKSJ-H}
+					{/Courier}
+					ifelse
+				} ifelse
+				findfont
+				[1 0 0.5 1 0 0] makefont
+			} if
+		}
+		{
+			/Courier findfont
+		} ifelse
+	} ifelse
+	_wv type /arraytype eq
+	{
+		_wv makeblendedfont
+	} if
+	dup length 10 add dict
+ begin
+	mark exch
+	{
+		1 index /FID ne
+		{
+			def
+		} if
+		cleartomark mark
+	} forall
+	pop
+	/FontScript exch def
+	/FontDirection exch def
+	/FontRequest exch def
+	/FontName exch def
+	counttomark 0 eq
+	{
+		1 _useNativeEncoding eq
+		{
+			/Encoding _nativeEncoding def
+		} if
+		cleartomark
+	}
+	{
+		/Encoding load 256 array copy
+		modifyEncoding /Encoding exch def
+	} ifelse
+	FontName currentdict
+ end
+	definefont pop
+} def
+/tr
+{
+	_ax _ay 3 2 roll
+} def
+/trj
+{
+	_cx _cy _sp _ax _ay 6 5 roll
+} def
+/a0
+{
+	/Tx
+	{
+		dup
+		currentpoint 3 2 roll
+		tr _psf
+		newpath moveto
+		tr _ctm _pss
+	} ddef
+	/Tj
+	{
+		dup
+		currentpoint 3 2 roll
+		trj _pjsf
+		newpath moveto
+		trj _ctm _pjss
+	} ddef
+} def
+/a1
+{
+W B
+} def
+/e0
+{
+	/Tx
+	{
+		tr _psf
+	} ddef
+	/Tj
+	{
+		trj _pjsf
+	} ddef
+} def
+/e1
+{
+W F 
+} def
+/i0
+{
+	/Tx
+	{
+		tr sp
+	} ddef
+	/Tj
+	{
+		trj jsp
+	} ddef
+} def
+/i1
+{
+	W N
+} def
+/o0
+{
+	/Tx
+	{
+		tr sw rmoveto
+	} ddef
+	/Tj
+	{
+		trj swj rmoveto
+	} ddef
+} def
+/r0
+{
+	/Tx
+	{
+		tr _ctm _pss
+	} ddef
+	/Tj
+	{
+		trj _ctm _pjss
+	} ddef
+} def
+/r1
+{
+W S
+} def
+/To
+{
+	pop _ctm currentmatrix pop
+} def
+/TO
+{
+	iTe _ctm setmatrix newpath
+} def
+/Tp
+{
+	pop _tm astore pop _ctm setmatrix
+	_tDict begin
+	/W
+	{
+	} def
+	/h
+	{
+	} def
+} def
+/TP
+{
+ end
+	iTm 0 0 moveto
+} def
+/Tr
+{
+	_render 3 le
+	{
+		currentpoint newpath moveto
+	} if
+	dup 8 eq
+	{
+		pop 0
+	}
+	{
+		dup 9 eq
+		{
+			pop 1
+		} if
+	} ifelse
+	dup /_render exch ddef
+	_renderStart exch get load exec
+} def
+/iTm
+{
+	_ctm setmatrix _tm concat
+	_shift aload pop _lineorientation 1 eq { exch } if translate
+	_scale aload pop _lineorientation 1 eq _yokoorientation 1 eq or { exch } if scale
+} def
+/Tm
+{
+	_tm astore pop iTm 0 0 moveto
+} def
+/Td
+{
+	_mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto
+} def
+/iTe
+{
+	_render -1 eq
+	{
+	}
+	{
+		_renderEnd _render get dup null ne
+		{
+			load exec
+		}
+		{
+			pop
+		} ifelse
+	} ifelse
+	/_render -1 ddef
+} def
+/Ta
+{
+	pop
+} def
+/Tf
+{
+	1 index type /nametype eq
+	{
+		dup 0.75 mul 1 index 0.25 mul neg
+	} if
+	/_fontDescent exch ddef
+	/_fontAscent exch ddef
+	/_fontSize exch ddef
+	/_fontRotateAdjust _fontAscent _fontDescent add 2 div neg ddef
+	/_fontHeight _fontSize ddef
+	findfont _fontSize scalefont setfont
+} def
+/Tl
+{
+	pop neg 0 exch
+	_leading astore pop
+} def
+/Tt
+{
+	pop
+} def
+/TW
+{
+	3 npop
+} def
+/Tw
+{
+	/_cx exch ddef
+} def
+/TC
+{
+	3 npop
+} def
+/Tc
+{
+	/_ax exch ddef
+} def
+/Ts
+{
+	0 exch
+	_shift astore pop
+	currentpoint
+	iTm
+	moveto
+} def
+/Ti
+{
+	3 npop
+} def
+/Tz
+{
+	count 1 eq { 100 } if
+	100 div exch 100 div exch
+	_scale astore pop
+	iTm
+} def
+/TA
+{
+	pop
+} def
+/Tq
+{
+	pop
+} def
+/Tg
+{
+	pop
+} def
+/TG
+{
+	pop
+} def
+/Tv
+{
+	/_lineorientation exch ddef
+} def
+/TV
+{
+	/_charorientation exch ddef
+} def
+/Ty
+{
+	dup /_yokoorientation exch ddef 1 sub neg Tv
+} def
+/TY
+{
+	pop
+} def
+/T~
+{
+	Tx
+} def
+/Th
+{
+	pop pop pop pop pop
+} def
+/TX
+{
+	pop
+} def
+/Tk
+{
+	_fontSize mul 1000 div
+	_lineorientation 0 eq { neg 0 } { 0 exch } ifelse
+	rmoveto
+	pop
+} def
+/TK
+{
+	2 npop
+} def
+/T*
+{
+	_leading aload pop
+	_lineorientation 0 ne { exch } if
+	Td
+} def
+/T*-
+{
+	_leading aload pop
+	_lineorientation 0 ne { exch } if
+	exch neg exch neg
+	Td
+} def
+/T-
+{
+	_ax neg 0 rmoveto
+	_lineorientation 1 eq _charorientation 0 eq and { 1 TV _hyphen Tx 0 TV } { _hyphen Tx } ifelse
+} def
+/T+
+{
+} def
+/TR
+{
+	_ctm currentmatrix pop
+	_tm astore pop
+	iTm 0 0 moveto
+} def
+/TS
+{
+	currentfont 3 1 roll
+	/_Symbol_ findfont _fontSize scalefont setfont
+	
+	0 eq
+	{
+		Tx
+	}
+	{
+		Tj
+	} ifelse
+	setfont
+} def
+/Xb
+{
+	pop pop
+} def
+/Tb /Xb load def
+/Xe
+{
+	pop pop pop pop
+} def
+/Te /Xe load def
+/XB
+{
+} def
+/TB /XB load def
+currentdict readonly pop
+end
+setpacking
+%
+/X^
+{
+	currentfont 5 1 roll
+	dup havefont
+		{
+		findfont _fontSize scalefont setfont
+		}
+		{
+		pop
+		exch
+		} ifelse
+	2 index 0 eq
+	{
+		Tx
+	}
+	{
+		Tj
+	} ifelse
+	pop	pop
+	setfont
+} def
+/T^	/X^	load def
+%%EndResource
+%%BeginProcSet: Adobe_ColorImage_AI6 1.3 0
+userdict /Adobe_ColorImage_AI6 known not
+{
+	userdict /Adobe_ColorImage_AI6 53 dict put 
+} if
+userdict /Adobe_ColorImage_AI6 get begin
+/initialize { 
+	Adobe_ColorImage_AI6 begin
+	Adobe_ColorImage_AI6 {
+		dup type /arraytype eq {
+			dup xcheck {
+				bind
+			} if
+		} if
+		pop pop
+	} forall
+} def
+/terminate { end } def
+currentdict /Adobe_ColorImage_AI6_Vars known not {
+	/Adobe_ColorImage_AI6_Vars 41 dict def
+} if
+Adobe_ColorImage_AI6_Vars begin
+	/plateindex -1 def
+	/_newproc null def
+	/_proc1 null def
+	/_proc2 null def
+	/sourcearray 4 array def
+	/_ptispace null def
+	/_ptiname null def
+	/_pti0 0 def
+	/_pti1 0 def
+	/_ptiproc null def
+	/_ptiscale 0 def
+	/_pticomps 0 def
+	/_ptibuf 0 string def
+	/_gtigray 0 def
+	/_cticmyk null def
+	/_rtirgb null def
+	/XIEnable true def
+	/XIType 0 def
+	/XIEncoding 0 def
+	/XICompression 0 def
+	/XIChannelCount 0 def
+	/XIBitsPerPixel 0 def
+	/XIImageHeight 0 def
+	/XIImageWidth 0 def
+	/XIImageMatrix null def
+	/XIRowBytes 0 def
+	/XIFile null def
+	/XIBuffer1 null def
+	/XIBuffer2 null def
+	/XIBuffer3 null def
+	/XIDataProc null def
+	/XIColorSpace /DeviceGray def
+	/XIColorValues 0 def
+	/XIPlateList false def
+end
+/ci6colorimage /colorimage where {/colorimage get}{null} ifelse def
+/ci6image systemdict /image get def
+/ci6curtransfer systemdict /currenttransfer get def
+/ci6curoverprint /currentoverprint where {/currentoverprint get}{{_of}} ifelse def
+/ci6foureq {
+	4 index ne {
+		pop pop pop false
+	}{
+		4 index ne {
+			pop pop false
+		}{
+			4 index ne {
+				pop false
+			}{
+				4 index eq
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6testplate {
+	Adobe_ColorImage_AI6_Vars begin
+		/plateindex -1 def
+		/setcmykcolor where {
+			pop
+			gsave
+			1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			grestore
+			1 0 0 0 ci6foureq { 
+				/plateindex 0 def
+			}{
+				0 1 0 0 ci6foureq { 
+					/plateindex 1 def
+				}{
+					0 0 1 0 ci6foureq {
+						/plateindex 2 def
+					}{
+						0 0 0 1 ci6foureq { 
+							/plateindex 3 def
+						}{
+							0 0 0 0 ci6foureq {
+								/plateindex 5 def
+							} if
+						} ifelse
+					} ifelse
+				} ifelse
+			} ifelse
+			pop pop pop pop
+		} if
+		plateindex
+ end
+} def
+/ci6concatprocs {
+	/packedarray where {
+		pop dup type /packedarraytype eq 2 index type
+		/packedarraytype eq or
+	}{
+		false
+	} ifelse
+	{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		_proc1 aload pop
+		_proc2 aload pop
+		_proc1 length
+		_proc2 length add
+		packedarray cvx
+	}{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		/_newproc _proc1 length _proc2 length add array def
+		_newproc 0 _proc1 putinterval
+		_newproc _proc1 length _proc2 putinterval
+		_newproc cvx
+	} ifelse
+} def
+/ci6istint {
+	type /arraytype eq 
+} def
+/ci6isspot {
+	dup type /arraytype eq {
+		dup length 1 sub get /Separation eq
+	}{
+		pop false
+	} ifelse
+} def
+/ci6spotname {
+	dup ci6isspot {dup length 2 sub get}{pop ()} ifelse
+} def
+/ci6altspace {
+	aload pop pop pop ci6colormake
+} def
+/ci6numcomps {
+	dup /DeviceGray eq {
+		pop 1
+	}{
+		dup /DeviceRGB eq {
+			pop 3
+		}{
+			/DeviceCMYK eq {
+				4
+			}{
+				1
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6marksplate {
+	dup /DeviceGray eq {
+		pop plateindex 3 eq
+	}{
+		dup /DeviceRGB eq {
+			pop plateindex 5 ne
+		}{
+			dup /DeviceCMYK eq {
+				pop plateindex 5 ne
+			}{
+				dup ci6isspot {
+					/findcmykcustomcolor where {
+						pop
+						dup length 2 sub get
+						0.1 0.1 0.1 0.1 5 -1 roll
+						findcmykcustomcolor 1 setcustomcolor
+						systemdict /currentgray get exec
+						1 ne
+					}{
+						pop plateindex 5 ne
+					} ifelse
+				}{
+					pop plateindex 5 ne
+				} ifelse
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colormake {
+	dup ci6numcomps
+	exch 1 index 2 add 1 roll
+	dup 1 eq {pop}{array astore} ifelse
+	exch
+} def
+/ci6colorexpand {
+	dup ci6spotname exch
+	dup ci6istint {
+		ci6altspace
+		exch 4 1 roll
+	}{
+		1 3 1 roll
+	} ifelse
+} def
+/ci6colortint {
+	dup /DeviceGray eq {
+		3 1 roll 1 exch sub mul 1 exch sub exch
+	}{
+		dup /DeviceRGB eq {
+			3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch
+		}{
+			dup /DeviceCMYK eq {
+				3 1 roll {1 index mul exch} forall pop 4 array astore exch
+			}{
+				3 1 roll mul exch
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colortocmyk {
+	dup /DeviceGray eq {
+		pop 1 exch sub 0 0 0 4 -1 roll 4 array astore
+	}{
+		dup /DeviceRGB eq {
+			pop aload pop _rgbtocmyk 4 array astore
+		}{
+			dup /DeviceCMYK eq {
+				pop
+			}{
+				ci6altspace ci6colortint ci6colortocmyk
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6makeimagedict {
+	7 dict begin
+		/ImageType 1 def
+		/Decode exch def
+		/DataSource exch def
+		/ImageMatrix exch def
+		/BitsPerComponent exch def
+		/Height exch def
+		/Width exch def
+	currentdict end
+} def
+/ci6stringinvert {
+	0 1 2 index length 1 sub {
+		dup 2 index exch get 255 exch sub 2 index 3 1 roll put
+	} for
+} def
+/ci6stringknockout {
+	0 1 2 index length 1 sub {
+		255 2 index 3 1 roll put
+	} for
+} def
+/ci6stringapply {
+	0 1 4 index length 1 sub {
+		dup
+		4 index exch get
+		3 index 3 1 roll
+		3 index exec
+	} for
+	pop exch pop
+} def
+/ci6walkrgbstring {
+	0 3 index
+	dup length 1 sub 0 3 3 -1 roll {
+		3 getinterval {} forall
+		5 index exec
+		3 index
+	} for
+	
+	 5 {pop} repeat
+} def
+/ci6walkcmykstring
+{
+	0 3 index
+	dup length 1 sub 0 4 3 -1 roll {
+		4 getinterval {} forall
+		
+		6 index exec
+		
+		3 index
+		
+	} for
+	
+	5 { pop } repeat
+	
+} def
+/ci6putrgbtograystr
+{
+	.11 mul exch
+	
+	.59 mul add exch
+	
+	.3 mul add
+	
+	cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6putcmyktograystr
+{
+	exch .11 mul add
+	
+	exch .59 mul add
+	
+	exch .3 mul add
+	
+	dup 255 gt { pop 255 } if
+	
+	255 exch sub cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6rgbtograyproc {	
+	Adobe_ColorImage_AI6_Vars begin 
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putrgbtograystr load exch
+		ci6walkrgbstring
+ end
+} def
+/ci6cmyktograyproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putcmyktograystr load exch
+		ci6walkcmykstring
+ end
+} def
+/ci6separatecmykproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		
+		XIBuffer3
+		
+		0 2 index
+		
+		plateindex 4 2 index length 1 sub {
+			get 255 exch sub
+			
+			3 copy put pop 1 add
+			
+			2 index
+		} for
+		pop pop exch pop
+ end
+} def
+	
+/ci6compositeimage {
+	dup 1 eq {
+		pop pop image
+	}{
+		/ci6colorimage load null ne {
+			ci6colorimage
+		}{
+			3 1 roll pop
+			sourcearray 0 3 -1 roll put
+			3 eq {/ci6rgbtograyproc}{/ci6cmyktograyproc} ifelse load
+			image
+		} ifelse
+	} ifelse
+} def
+/ci6knockoutimage {
+	gsave
+	0 ci6curtransfer exec 1 ci6curtransfer exec
+	eq {
+		0 ci6curtransfer exec 0.5 lt
+	}{
+		0 ci6curtransfer exec 1 ci6curtransfer exec gt
+	} ifelse
+	{{pop 0}}{{pop 1}} ifelse
+	systemdict /settransfer get exec
+	ci6compositeimage
+	grestore
+} def
+/ci6drawimage {
+	ci6testplate -1 eq {
+		pop ci6compositeimage
+	}{
+		dup type /arraytype eq {
+			dup length plateindex gt {plateindex get}{pop false} ifelse
+		}{
+			{
+				true
+			}{
+				dup 1 eq {plateindex 3 eq}{plateindex 3 le} ifelse
+			} ifelse
+		} ifelse
+		{
+			dup 1 eq {
+				pop pop ci6image
+			}{
+				dup 3 eq {
+					ci6compositeimage
+				}{
+					pop pop
+					sourcearray 0 3 -1 roll put
+					/ci6separatecmykproc load
+					ci6image
+				} ifelse
+			} ifelse
+		}{
+			ci6curoverprint {
+				7 {pop} repeat
+			}{
+				ci6knockoutimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6proctintimage {
+	/_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store
+	/_pticomps _ptispace ci6numcomps store
+	/_ptiscale _pti1 _pti0 sub store
+	level2? {
+		_ptiname length 0 gt version cvr 2012 ge and {
+			[/Separation _ptiname _ptispace {_ptiproc}] setcolorspace
+			[_pti0 _pti1] ci6makeimagedict ci6image
+		}{
+			[/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace
+			[0 255] ci6makeimagedict ci6image
+		} ifelse
+	}{
+		_pticomps 1 eq {
+			{
+				dup
+				{
+					255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put
+				} ci6stringapply
+			} ci6concatprocs ci6image
+		}{
+			{
+				dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse
+				_ptibuf {
+					exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc
+					_pticomps 2 add -2 roll
+					_pticomps 1 sub -1 0 {
+						1 index add 2 index exch
+						5 -1 roll
+						255 mul cvi put
+					} for
+					pop pop
+				} ci6stringapply
+			} ci6concatprocs false _pticomps
+			/ci6colorimage load null eq {7 {pop} repeat}{ci6colorimage} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6graytintimage {
+	/_gtigray 5 -1 roll store
+	{1 _gtigray sub mul 1 exch sub} 4 1 roll
+	/DeviceGray ci6proctintimage
+} def
+/ci6cmyktintimage {
+	/_cticmyk 5 -1 roll store
+	{_cticmyk {1 index mul exch} forall pop} 4 1 roll
+	/DeviceCMYK ci6proctintimage
+} def
+/ci6rgbtintimage {
+	/_rtirgb 5 -1 roll store
+	{_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll
+	/DeviceRGB ci6proctintimage
+} def
+/ci6tintimage {
+	ci6testplate -1 eq {
+		ci6colorexpand
+		3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll
+		dup /DeviceGray eq {
+			pop ci6graytintimage
+		}{
+			dup /DeviceRGB eq {
+				pop ci6rgbtintimage
+			}{
+				pop ci6cmyktintimage
+			} ifelse
+		} ifelse
+	}{
+		dup ci6marksplate {
+			plateindex 5 lt {
+				ci6colortocmyk plateindex get
+				dup 0 eq ci6curoverprint and {
+					7 {pop} repeat
+				}{
+					1 exch sub
+					exch {1 0}{0 1} ifelse () ci6graytintimage
+				} ifelse
+			}{
+				pop exch {0}{0 exch} ifelse 0 3 1 roll () ci6graytintimage
+			} ifelse
+		}{
+			ci6curoverprint {
+				8 {pop} repeat
+			}{
+				pop pop pop
+				{pop 1} 0 1 () /DeviceGray ci6proctintimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/XINullImage {
+} def
+/XIImageMask {
+	XIImageWidth XIImageHeight false
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	imagemask
+} def
+/XIImageTint {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	XIType 3 eq XIColorValues XIColorSpace ci6tintimage
+} def
+/XIImage {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	false XIChannelCount XIPlateList ci6drawimage
+} def
+/XG {
+	pop pop
+} def
+/XF {
+	13 {pop} repeat
+} def
+/Xh {
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		/XIImageMatrix exch def
+		0 0 moveto
+		XIImageMatrix concat
+		XIImageWidth XIImageHeight scale
+		
+		/_lp /null ddef
+		_fc
+		/_lp /imagemask ddef
+ end
+} def
+/XH {
+	Adobe_ColorImage_AI6_Vars begin
+		grestore
+ end
+} def
+/XIEnable {
+	Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put
+} def
+/XC {
+	Adobe_ColorImage_AI6_Vars begin
+		ci6colormake
+		/XIColorSpace exch def
+		/XIColorValues exch def
+ end
+} def
+/XIPlates {
+	Adobe_ColorImage_AI6_Vars begin
+		/XIPlateList exch def
+ end
+} def
+/XI
+{
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		cvi dup
+		256 idiv /XICompression exch store
+		256 mod /XIEncoding exch store
+		pop pop
+		/XIChannelCount exch def
+		/XIBitsPerPixel exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		pop pop pop pop
+		/XIImageMatrix exch def
+		XIBitsPerPixel 1 eq {
+			XIImageWidth 8 div ceiling cvi
+		}{
+			XIImageWidth XIChannelCount mul
+		} ifelse
+		/XIRowBytes exch def
+		XIEnable {
+			/XIBuffer3 XIImageWidth string def
+			XICompression 0 eq {
+				/XIBuffer1 XIRowBytes string def
+				XIEncoding 0 eq {
+					{currentfile XIBuffer1 readhexstring pop}
+				}{
+					{currentfile XIBuffer1 readstring pop}
+				} ifelse
+			}{
+				/XIBuffer1 256 string def
+				/XIBuffer2 XIRowBytes string def
+				{currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if}
+				/ASCII85Decode filter /DCTDecode filter
+				/XIFile exch def
+				{XIFile XIBuffer2 readstring pop}
+			} ifelse
+			/XIDataProc exch def
+			
+			XIType 1 ne {
+				0 setgray
+			} if
+			XIType 1 eq {
+				XIImageMask
+			}{
+				XIType 2 eq XIType 3 eq or {
+					XIImageTint
+				}{
+					XIImage
+				} ifelse
+			} ifelse
+		}{
+			XINullImage
+		} ifelse
+		/XIPlateList false def
+		grestore
+ end
+} def
+end
+%%EndProcSet
+%%BeginResource: procset Adobe_Illustrator_AI5 1.3 0
+%%Title: (Adobe Illustrator (R) Version 8.0 Full Prolog)
+%%Version: 1.3 0
+%%CreationDate: (3/7/1994) ()
+%%Copyright: ((C) 1987-1998 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_Illustrator_AI5_vars 112 dict dup begin
+put
+/_?cmyk false def
+/_eo false def
+/_lp /none def
+/_pf
+{
+} def
+/_ps
+{
+} def
+/_psf
+{
+} def
+/_pss
+{
+} def
+/_pjsf
+{
+} def
+/_pjss
+{
+} def
+/_pola 0 def
+/_doClip 0 def
+/cf currentflat def
+/_lineorientation 0 def
+/_charorientation 0 def
+/_yokoorientation 0 def
+/_tm matrix def
+/_renderStart
+[
+/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
+] def
+/_renderEnd
+[
+null null null null /i1 /i1 /i1 /i1
+] def
+/_render -1 def
+/_shift [0 0] def
+/_ax 0 def
+/_ay 0 def
+/_cx 0 def
+/_cy 0 def
+/_leading
+[
+0 0
+] def
+/_ctm matrix def
+/_mtx matrix def
+/_sp 16#020 def
+/_hyphen (-) def
+/_fontSize 0 def
+/_fontAscent 0 def
+/_fontDescent 0 def
+/_fontHeight 0 def
+/_fontRotateAdjust 0 def
+/Ss 256 string def
+Ss 0 (fonts/) putinterval
+/_cnt 0 def
+/_scale [1 1] def
+/_nativeEncoding 0 def
+/_useNativeEncoding 0 def
+/_tempEncode 0 def
+/_pntr 0 def
+/_tDict 2 dict def
+/_hfname 100 string def
+/_hffound false def
+/Tx
+{
+} def
+/Tj
+{
+} def
+/CRender
+{
+} def
+/_AI3_savepage
+{
+} def
+/_gf null def
+/_cf 4 array def
+/_rgbf 3 array def
+/_if null def
+/_of false def
+/_fc
+{
+} def
+/_gs null def
+/_cs 4 array def
+/_rgbs 3 array def
+/_is null def
+/_os false def
+/_sc
+{
+} def
+/_pd 1 dict def
+/_ed 15 dict def
+/_pm matrix def
+/_fm null def
+/_fd null def
+/_fdd null def
+/_sm null def
+/_sd null def
+/_sdd null def
+/_i null def
+/_lobyte 0 def
+/_hibyte 0 def
+/_cproc null def
+/_cscript 0 def
+/_hvax 0 def
+/_hvay 0 def
+/_hvwb 0 def
+/_hvcx 0 def
+/_hvcy 0 def
+/_bitfont null def
+/_bitlobyte 0 def
+/_bithibyte 0 def
+/_bitkey null def
+/_bitdata null def
+/_bitindex 0 def
+/discardSave null def
+/buffer 256 string def
+/beginString null def
+/endString null def
+/endStringLength null def
+/layerCnt 1 def
+/layerCount 1 def
+/perCent (%) 0 get def
+/perCentSeen? false def
+/newBuff null def
+/newBuffButFirst null def
+/newBuffLast null def
+/clipForward? false def
+end
+userdict /Adobe_Illustrator_AI5 known not {
+	userdict /Adobe_Illustrator_AI5 100 dict put
+} if
+userdict /Adobe_Illustrator_AI5 get begin
+/initialize
+{
+	Adobe_Illustrator_AI5 dup begin
+	Adobe_Illustrator_AI5_vars begin
+	/_aicmykps where {pop /_?cmyk _aicmykps def}if
+	discardDict
+	{
+		bind pop pop
+	} forall
+	dup /nc get begin
+	{
+		dup xcheck 1 index type /operatortype ne and
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	newpath
+} def
+/terminate
+{
+ end
+ end
+} def
+/_
+null def
+/ddef
+{
+	Adobe_Illustrator_AI5_vars 3 1 roll put
+} def
+/xput
+{
+	dup load dup length exch maxlength eq
+	{
+		dup dup load dup
+		length 2 mul dict copy def
+	} if
+	load begin
+	def
+ end
+} def
+/npop
+{
+	{
+		pop
+	} repeat
+} def
+/hswj
+{
+	dup stringwidth 3 2 roll
+	{
+		_hvwb eq { exch _hvcx add exch _hvcy add } if
+		exch _hvax add exch _hvay add
+	} cforall
+} def
+/vswj
+{
+	0 0 3 -1 roll
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			dup cstring stringwidth 5 2 roll
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			4 -1 roll sub exch
+			3 -1 roll sub exch
+		}
+		{
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			_fontHeight sub
+		} ifelse
+	} cforall
+} def
+/swj
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hswj } { vswj } ifelse
+} def
+/sw
+{
+	0 0 0 6 3 roll swj
+} def
+/vjss
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			gsave
+			false charpath currentpoint
+			5 index setmatrix stroke
+			grestore
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			gsave
+			2 index false charpath
+			6 index setmatrix stroke
+			grestore
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjss
+{
+	4 1 roll
+	{
+		dup cstring
+		gsave
+		false charpath currentpoint
+		5 index setmatrix stroke
+		grestore
+		moveto
+		_sp eq
+		{
+			5 index 5 index rmoveto
+		} if
+		2 copy rmoveto
+	} cforall
+	6 npop
+} def
+/jss
+{
+	_lineorientation 0 eq { hjss } { vjss } ifelse
+} def
+/ss
+{
+	0 0 0 7 3 roll jss
+} def
+/vjsp
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			false charpath
+            currentpoint
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			2 index false charpath
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjsp
+{
+    4 1 roll
+    {
+        dup cstring
+        false charpath
+        _sp eq
+        {
+            5 index 5 index rmoveto
+        } if
+        2 copy rmoveto
+    } cforall
+    6 npop
+} def
+/jsp
+{
+	matrix currentmatrix
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/sp
+{
+    matrix currentmatrix
+    0 0 0 7 3 roll
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/pl
+{
+	transform
+	0.25 sub round 0.25 add exch
+	0.25 sub round 0.25 add exch
+	itransform
+} def
+/setstrokeadjust where
+{
+	pop true setstrokeadjust
+	/c
+	{
+		curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		moveto
+	} def
+}
+{
+	/c
+	{
+		pl curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll pl curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		pl 2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		pl lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		pl moveto
+	} def
+} ifelse
+/d
+{
+	setdash
+} def
+/cf
+{
+} def
+/i
+{
+	dup 0 eq
+	{
+		pop cf
+	} if
+	setflat
+} def
+/j
+{
+	setlinejoin
+} def
+/J
+{
+	setlinecap
+} def
+/M
+{
+	setmiterlimit
+} def
+/w
+{
+	setlinewidth
+} def
+/XR
+{
+	0 ne
+	/_eo exch ddef
+} def
+/H
+{
+} def
+/h
+{
+	closepath
+} def
+/N
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			_eo {eoclip} {clip} ifelse /_doClip 0 ddef
+		} if
+		newpath
+	}
+	{
+		/CRender
+		{
+			N
+		} ddef
+	} ifelse
+} def
+/n
+{
+	N
+} def
+/F
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
+			/_doClip 0 ddef
+		}
+		{
+			_pf
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			F
+		} ddef
+	} ifelse
+} def
+/f
+{
+	closepath
+	F
+} def
+/S
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			_ps
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			S
+		} ddef
+	} ifelse
+} def
+/s
+{
+	closepath
+	S
+} def
+/B
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		gsave F grestore
+		{
+			gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			S
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			B
+		} ddef
+	} ifelse
+} def
+/b
+{
+	closepath
+	B
+} def
+/W
+{
+	/_doClip 1 ddef
+} def
+/*
+{
+	count 0 ne
+	{
+		dup type /stringtype eq
+		{
+			pop
+		} if
+	} if
+	newpath
+} def
+/u
+{
+} def
+/U
+{
+} def
+/q
+{
+	_pola 0 eq
+	{
+		gsave
+	} if
+} def
+/Q
+{
+	_pola 0 eq
+	{
+		grestore
+	} if
+} def
+/*u
+{
+	_pola 1 add /_pola exch ddef
+} def
+/*U
+{
+	_pola 1 sub /_pola exch ddef
+	_pola 0 eq
+	{
+		CRender
+	} if
+} def
+/D
+{
+	pop
+} def
+/*w
+{
+} def
+/*W
+{
+} def
+/`
+{
+	/_i save ddef
+	clipForward?
+	{
+		nulldevice
+	} if
+	6 1 roll 4 npop
+	concat pop
+	userdict begin
+	/showpage
+	{
+	} def
+	0 setgray
+	0 setlinecap
+	1 setlinewidth
+	0 setlinejoin
+	10 setmiterlimit
+	[] 0 setdash
+	/setstrokeadjust where {pop false setstrokeadjust} if
+	newpath
+	0 setgray
+	false setoverprint
+} def
+/~
+{
+ end
+	_i restore
+} def
+/_rgbtocmyk
+{
+	3
+	{
+		1 exch sub 3 1 roll
+	} repeat
+	3 copy 1 4 1 roll
+	3
+	{
+		3 index 2 copy gt
+		{
+			exch
+		} if
+		pop 4 1 roll
+	} repeat
+	pop pop pop
+	4 1 roll
+	3
+	{
+		3 index sub
+		3 1 roll
+	} repeat
+	4 -1 roll
+} def
+/setrgbfill
+{
+	_rgbf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_rgbf aload pop setrgbcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/setrgbstroke
+{
+	_rgbs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_rgbs aload pop setrgbcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/O
+{
+	0 ne
+	/_of exch ddef
+	/_lp /none ddef
+} def
+/R
+{
+	0 ne
+	/_os exch ddef
+	/_lp /none ddef
+} def
+/g
+{
+	/_gf exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/G
+{
+	/_gs exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/k
+{
+	_cf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_cf aload pop setcmykcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/K
+{
+	_cs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_cs aload pop setcmykcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xa
+{
+	_?cmyk {
+		3 npop k
+	}{
+		setrgbfill 4 npop
+	} ifelse
+} def
+/XA
+{
+	_?cmyk {
+		3 npop K
+	}{
+		setrgbstroke 4 npop
+	} ifelse
+} def
+/Xs
+{
+	/_gf exch ddef
+	5 npop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setAIseparationgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XS
+{
+	/_gs exch ddef
+	5 npop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setAIseparationgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xx
+{
+	exch
+	/_gf exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XX
+{
+	exch
+	/_gs exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/x
+{
+	/_gf exch ddef
+	findcmykcustomcolor
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/X
+{
+	/_gs exch ddef
+	findcmykcustomcolor
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/XK
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		K
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		XA
+	} ifelse
+} def
+/Xk
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		k
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		Xa
+	} ifelse
+} def
+/A
+{
+	pop
+} def
+/annotatepage
+{
+userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
+} def
+/XT {
+	pop pop
+} def
+/Xt {
+	pop
+} def
+/discard
+{
+	save /discardSave exch store
+	discardDict begin
+	/endString exch store
+	gt38?
+	{
+		2 add
+	} if
+	load
+	stopped
+	pop
+ end
+	discardSave restore
+} bind def
+userdict /discardDict 7 dict dup begin
+put
+/pre38Initialize
+{
+	/endStringLength endString length store
+	/newBuff buffer 0 endStringLength getinterval store
+	/newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
+	/newBuffLast newBuff endStringLength 1 sub 1 getinterval store
+} def
+/shiftBuffer
+{
+	newBuff 0 newBuffButFirst putinterval
+	newBuffLast 0
+	currentfile read not
+	{
+	stop
+	} if
+	put
+} def
+0
+{
+	pre38Initialize
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff endString eq
+			{
+				cleartomark stop
+			} if
+			shiftBuffer
+		} loop
+	}
+	{
+	stop
+	} ifelse
+} def
+1
+{
+	pre38Initialize
+	/beginString exch store
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff beginString eq
+			{
+				/layerCount dup load 1 add store
+			}
+			{
+				newBuff endString eq
+				{
+					/layerCount dup load 1 sub store
+					layerCount 0 eq
+					{
+						cleartomark stop
+					} if
+				} if
+			} ifelse
+			shiftBuffer
+		} loop
+	} if
+} def
+2
+{
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			endString eq {
+				cleartomark stop
+			} if
+		}ifelse
+	} loop
+} def
+3
+{
+	/beginString exch store
+	/layerCnt 1 store
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			dup beginString eq
+			{
+				pop /layerCnt dup load 1 add store
+			}
+			{
+				endString eq
+				{
+					layerCnt 1 eq
+					{
+						cleartomark stop
+					}
+					{
+						/layerCnt dup load 1 sub store
+					} ifelse
+				} if
+			} ifelse
+		}ifelse
+	} loop
+} def
+end
+userdict /clipRenderOff 15 dict dup begin
+put
+{
+	/n /N /s /S /f /F /b /B
+}
+{
+	{
+		_doClip 1 eq
+		{
+			/_doClip 0 ddef _eo {eoclip} {clip} ifelse
+		} if
+		newpath
+	} def
+} forall
+/Tr /pop load def
+/Bb {} def
+/BB /pop load def
+/Bg {12 npop} def
+/Bm {6 npop} def
+/Bc /Bm load def
+/Bh {4 npop} def
+end
+/Lb
+{
+	6 npop
+	7 2 roll
+	5 npop
+	0 eq
+	{
+		0 eq
+		{
+			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
+		}
+		{
+			
+			/clipForward? true def
+			
+			/Tx /pop load def
+			/Tj /pop load def
+			
+			currentdict end clipRenderOff begin begin
+		} ifelse
+	}
+	{
+		0 eq
+		{
+			save /discardSave exch store
+		} if
+	} ifelse
+} bind def
+/LB
+{
+	discardSave dup null ne
+	{
+		restore
+	}
+	{
+		pop
+		clipForward?
+		{
+			currentdict
+		 end
+		 end
+		 begin
+					
+			/clipForward? false ddef
+		} if
+	} ifelse
+} bind def
+/Pb
+{
+	pop pop
+	0 (%AI5_EndPalette) discard
+} bind def
+/Np
+{
+	0 (%AI5_End_NonPrinting--) discard
+} bind def
+/Ln /pop load def
+/Ap
+/pop load def
+/Ar
+{
+	72 exch div
+	0 dtransform dup mul exch dup mul add sqrt
+	dup 1 lt
+	{
+		pop 1
+	} if
+	setflat
+} def
+/Mb
+{
+	q
+} def
+/Md
+{
+} def
+/MB
+{
+	Q
+} def
+/nc 4 dict def
+nc begin
+/setgray
+{
+	pop
+} bind def
+/setcmykcolor
+{
+	4 npop
+} bind def
+/setrgbcolor
+{
+	3 npop
+} bind def
+/setcustomcolor
+{
+	2 npop
+} bind def
+currentdict readonly pop
+end
+/XP
+{
+	4 npop
+} bind def
+/XD
+{
+	pop
+} bind def
+end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_cshow 2.0 8
+%%Title: (Writing System Operators)
+%%Version: 2.0 8
+%%CreationDate: (1/23/89) ()
+%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_cshow 14 dict dup begin put
+/initialize
+{
+	Adobe_cshow begin
+	Adobe_cshow
+	{
+		dup xcheck
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	Adobe_cshow begin
+} def
+/terminate
+{
+currentdict Adobe_cshow eq
+	{
+ end
+	} if
+} def
+/cforall
+{
+	/_lobyte 0 ddef
+	/_hibyte 0 ddef
+	/_cproc exch ddef
+	/_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef
+	{
+		/_lobyte exch ddef
+		_hibyte 0 eq
+		_cscript 1 eq
+		_lobyte 129 ge _lobyte 159 le and
+		_lobyte 224 ge _lobyte 252 le and or and
+		_cscript 2 eq
+		_lobyte 161 ge _lobyte 254 le and and
+		_cscript 3 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript 25 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript -1 eq
+		or or or or and
+		{
+			/_hibyte _lobyte ddef
+		}
+		{
+			_hibyte 256 mul _lobyte add
+			_cproc
+			/_hibyte 0 ddef
+		} ifelse
+	} forall
+} def
+/cstring
+{
+	dup 256 lt
+	{
+		(s) dup 0 4 3 roll put
+	}
+	{
+		dup 256 idiv exch 256 mod
+		(hl) dup dup 0 6 5 roll put 1 4 3 roll put
+	} ifelse
+} def
+/clength
+{
+	0 exch
+	{ 256 lt { 1 } { 2 } ifelse add } cforall
+} def
+/hawidthshow
+{
+	{
+		dup cstring
+		show
+		_hvax _hvay rmoveto
+		_hvwb eq { _hvcx _hvcy rmoveto } if
+	} cforall
+} def
+/vawidthshow
+{
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			0 _fontRotateAdjust rmoveto
+			cstring
+			_hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow
+			0 _fontRotateAdjust neg rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			exch _hvay sub exch _hvax sub
+			2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			3 2 roll
+			cstring
+			dup stringwidth pop 2 div neg _fontAscent neg rmoveto
+			show
+			moveto
+		} ifelse
+	} cforall
+} def
+/hvawidthshow
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse
+} def
+/hvwidthshow
+{
+	0 0 3 -1 roll hvawidthshow
+} def
+/hvashow
+{
+	0 0 0 6 -3 roll hvawidthshow
+} def
+/hvshow
+{
+	0 0 0 0 0 6 -1 roll hvawidthshow
+} def
+currentdict readonly pop end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_shading_AI8 1.0 0
+%%Title: (Adobe Illustrator 8 Shading Procset)
+%%Version: 1.0 0
+%%CreationDate: (12/17/97) ()
+%%Copyright: ((C) 1987-1997 Adobe Systems Incorporated All Rights Reserved)
+userdict /defaultpacking currentpacking put true setpacking
+userdict /Adobe_shading_AI8 10 dict dup begin put
+/initialize {
+	Adobe_shading_AI8 begin
+	Adobe_shading_AI8 bdprocs
+	Mesh /initialize get exec
+} def
+/terminate {
+	currentdict Adobe_shading_AI8 eq {
+	 end
+	} if
+} def
+/bdprocs {
+	{
+		dup xcheck 1 index type /arraytype eq and {
+			bind
+		} if
+		pop pop
+	} forall
+} def
+/X! {pop} def
+/X# {pop pop} def
+/Mesh 40 dict def
+Mesh begin
+/initialize {
+	Mesh bdprocs
+	Mesh begin
+		/emulate? /AI8MeshEmulation where {
+			pop AI8MeshEmulation
+		}{
+			systemdict /shfill known not
+		} ifelse def
+ end
+} def
+/bd {
+	shadingdict begin
+} def
+/paint {
+	emulate? {
+	 end
+	}{
+		/_lp /none ddef _fc /_lp /none ddef
+		
+		/AIColorSpace AIColorSpace tocolorspace store
+		/ColorSpace AIColorSpace topsspace store
+		
+		version_ge_3010.106 not systemdict /setsmoothness known and {
+			0.0001 setsmoothness
+		} if
+		
+		composite? {
+			/DataSource getdatasrc def
+			Matrix concat
+			currentdict end
+			shfill
+		}{
+			AIColorSpace makesmarks AIPlateList markingplate and not isoverprint and {
+			 end
+			}{
+				/ColorSpace /DeviceGray store
+				/Decode [0 1 0 1 0 1] store
+				/DataSource getplatesrc def
+				Matrix concat
+				currentdict end
+				shfill
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/shadingdict 12 dict def
+shadingdict begin
+	/ShadingType 6 def
+	/BitsPerCoordinate 16 def
+	/BitsPerComponent 8 def
+	/BitsPerFlag 8 def
+end
+/datafile null def
+/databuf 256 string def
+/dataptr 0 def
+/srcspace null def
+/srcchannels 0 def
+/dstchannels 0 def
+/dstplate 0 def
+/srctodstcolor null def
+/getplatesrc {
+	/srcspace AIColorSpace store
+	/srcchannels AIColorSpace getnchannels store
+	/dstchannels 1 store
+	/dstplate getplateindex store
+	/srctodstcolor srcspace makesmarks {
+		dstplate 4 eq {
+			{1 exch sub}
+		}{
+			{srcspace tocmyk 3 dstplate sub index 1 exch sub 5 1 roll 4 {pop} repeat}
+		} ifelse
+	}{
+		{srcchannels {pop} repeat 1}
+	} ifelse store
+	/datafile getdatasrc store
+	/rdpatch168 load DataLength () /SubFileDecode filter
+} def
+/getdatasrc {
+	/rdcmntline load /ASCII85Decode filter
+} def
+/rdpatch168 {
+	/dataptr 0 store
+	49 rdcount
+	4 {
+		dup {pop srcchannels getint8} if
+		dup {pop srctodstcolor dstchannels putint8 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdpatch3216 {
+	/dataptr 0 store
+	97 rdcount
+	4 {
+		dup {pop srcchannels getint16} if
+		dup {pop srctodstcolor dstchannels putint16 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdcount {
+	dup 0 gt {
+		datafile databuf dataptr 4 -1 roll getinterval readstring
+		exch length dataptr add /dataptr exch store
+	}{
+		true
+	} ifelse
+} def
+/getint8 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 255 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint8 {
+	dup dataptr add /dataptr exch store
+	dataptr exch
+	{
+		1 sub exch
+		255 mul cvi
+		databuf 2 index
+		3 -1 roll put
+	} repeat
+	pop
+} def 
+/getint16 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 256 mul datafile read} if
+		dup {pop add 65535 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint16 {
+	dup 2 mul dataptr add /dataptr exch store
+	dataptr exch
+	{
+		2 sub exch
+		65535 mul cvi dup
+		256 idiv databuf 3 index 3 -1 roll put
+		256 mod databuf 2 index 1 add 3 -1 roll put
+	} repeat
+	pop
+} def 
+/srcbuf 256 string def
+/rdcmntline {
+	currentfile srcbuf readline pop
+	(%) anchorsearch {pop} if
+} def
+/getplateindex {
+	0 [cyan? magenta? yellow? black? customColor?] {{exit} if 1 add} forall
+} def
+/aicsarray 4 array def
+/aicsaltvals 4 array def
+/aicsaltcolr aicsaltvals def
+/tocolorspace {
+	dup type /arraytype eq {
+		mark exch aload pop
+		aicsarray 0 3 -1 roll put
+		aicsarray 1 3 -1 roll put
+		dup aicsarray 2 3 -1 roll put
+		gettintxform aicsarray 3 3 -1 roll put
+		counttomark aicsaltvals 0 3 -1 roll getinterval /aicsaltcolr exch store
+		aicsaltcolr astore pop pop
+		aicsarray
+	} if
+} def
+/subtintxform {aicsaltcolr {1 index mul exch} forall pop} def
+/addtintxform {aicsaltcolr {1 sub 1 index mul 1 add exch} forall pop} def
+/gettintxform {
+	/DeviceRGB eq {/addtintxform}{/subtintxform} ifelse load
+} def
+/getnchannels {
+	dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin Channels end
+} def
+/makesmarks {
+	composite? {
+		pop true
+	}{
+		dup dup type /arraytype eq {0 get} if
+		colorspacedict exch get begin MarksPlate end
+	} ifelse
+} def
+/markingplate {
+	composite? {
+		pop true
+	}{
+		dup type /arraytype eq {
+			dup length getplateindex gt {getplateindex get}{pop false} ifelse
+		} if
+	} ifelse
+} def
+/tocmyk {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToCMYK end
+} def
+/topsspace {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToPSSpace end
+} def
+/colorspacedict 5 dict dup begin
+	/DeviceGray 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {pop black?} def
+		/ToCMYK {pop 1 exch sub 0 0 0 4 -1 roll} def
+		/ToPSSpace {} def
+ end def
+	/DeviceRGB 4 dict dup begin
+		/Channels 3 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop _rgbtocmyk} def
+		/ToPSSpace {} def
+ end def
+	/DeviceCMYK 4 dict dup begin
+		/Channels 4 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop} def
+		/ToPSSpace {} def
+ end def
+	/Separation 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			/findcmykcustomcolor where {
+				pop dup 1 exch ToCMYK 5 -1 roll 1 get
+				findcmykcustomcolor 1 setcustomcolor
+				systemdict /currentgray get exec
+				1 ne
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {} def
+ end def
+	/Process 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			isCMYKSep? {
+				1 exch ToCMYK 4 array astore getplateindex get 0 ne 
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {
+			4 array copy dup 0 /Separation put
+		} def
+ end def
+end def
+/isoverprint {
+	/currentoverprint where {pop currentoverprint}{_of} ifelse
+} def
+/version_ge_3010.106 {
+   version {cvr} stopped {
+      pop
+      false
+   }{
+      3010.106 ge
+   } ifelse
+} def
+end
+end
+defaultpacking setpacking
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeFont: AvantGarde-Book
+userdict /_useSmoothShade false put
+userdict /_aicmykps false put
+userdict /_forceToCMYK false put
+Adobe_level2_AI5 /initialize get exec
+Adobe_cshow /initialize get exec
+Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_typography_AI5 /initialize get exec
+Adobe_ColorImage_AI6 /initialize get exec
+Adobe_shading_AI8 /initialize get exec
+Adobe_Illustrator_AI5 /initialize get exec
+[
+39/quotesingle 96/grave 130/quotesinglbase/florin/quotedblbase/ellipsis
+/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 145/quoteleft
+/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark
+/scaron/guilsinglright/oe/dotlessi 159/Ydieresis /space 164/currency 166/brokenbar
+168/dieresis/copyright/ordfeminine 172/logicalnot/hyphen/registered/macron/ring
+/plusminus/twosuperior/threesuperior/acute/mu 183/periodcentered/cedilla
+/onesuperior/ordmasculine 188/onequarter/onehalf/threequarters 192/Agrave
+/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute
+/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde
+/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave
+/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute
+/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex
+/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute
+/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis
+TE
+%AI55J_Tsume: None
+%AI3_BeginEncoding: _AvantGarde-Book AvantGarde-Book
+[/_AvantGarde-Book/AvantGarde-Book 0 0 1 TZ%AI3_EndEncoding AdobeType
+%AI5_Begin_NonPrinting
+Np
+%AI3_BeginPattern: (Brick)
+(Brick) 0 0 72 72 [
+%AI3_Tile
+(0 O 0 R 0.3 0.85 0.85 0 k
+ 0.3 0.85 0.85 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+0 0 m
+0 72 L
+72 72 L
+72 0 L
+0 0 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 0.3 w 4 M []0 d%AI3_Note:0 D
+0 XR
+0 68.4097 m
+72 68.4097 l
+S0 61.209 m
+72 61.209 L
+S0 54.0088 m
+72 54.0088 L
+S0 46.8076 m
+72 46.8076 L
+S0 39.6084 m
+72 39.6084 L
+S0 32.4072 m
+72 32.4072 L
+S0 25.207 m
+72 25.207 L
+S0 18.0059 m
+72 18.0059 L
+S0 10.8057 m
+72 10.8057 L
+S0 3.6064 m
+72 3.6064 L
+S68.4102 68.4097 m
+68.4102 61.2217 l
+S54.0098 68.4097 m
+54.0098 61.2217 L
+S39.6094 68.4097 m
+39.6094 61.2217 L
+S25.21 68.4097 m
+25.21 61.2217 L
+S10.8105 68.4097 m
+10.8105 61.2217 L
+S68.4102 53.9717 m
+68.4102 46.7842 l
+S54.0098 53.9717 m
+54.0098 46.7842 L
+S39.6094 53.9717 m
+39.6094 46.7842 L
+S25.21 53.9717 m
+25.21 46.7842 L
+S10.8105 53.9717 m
+10.8105 46.7842 L
+S68.4102 39.5967 m
+68.4102 32.4092 l
+S54.0098 39.5967 m
+54.0098 32.4092 L
+S39.6094 39.5967 m
+39.6094 32.4092 L
+S25.21 39.5967 m
+25.21 32.4092 L
+S10.8105 39.5967 m
+10.8105 32.4092 L
+S68.4102 25.2217 m
+68.4102 18.0342 l
+S54.0098 25.2217 m
+54.0098 18.0342 L
+S39.6094 25.2217 m
+39.6094 18.0342 L
+S25.21 25.2217 m
+25.21 18.0342 L
+S10.8105 25.2217 m
+10.8105 18.0342 L
+S68.4102 10.7842 m
+68.4102 3.5967 l
+S54.0098 10.7842 m
+54.0098 3.5967 L
+S39.6094 10.7842 m
+39.6094 3.5967 L
+S25.21 10.7842 m
+25.21 3.5967 L
+S10.8105 10.7842 m
+10.8105 3.5967 L
+S61.1973 3.5967 m
+61.1973 0 L
+S46.7969 3.5967 m
+46.7969 0 L
+S32.3965 3.5967 m
+32.3965 0 L
+S17.9971 3.5967 m
+17.9971 0 L
+S3.5967 3.5967 m
+3.5967 0 l
+S61.1973 18.0342 m
+61.1973 10.8467 L
+S46.7969 18.0342 m
+46.7969 10.8467 L
+S32.3965 18.0342 m
+32.3965 10.8467 L
+S17.9971 18.0342 m
+17.9971 10.8467 L
+S3.5967 18.0342 m
+3.5967 10.8467 l
+S61.1973 32.4092 m
+61.1973 25.2217 L
+S46.7969 32.4092 m
+46.7969 25.2217 L
+S17.9971 32.4092 m
+17.9971 25.2217 L
+S3.5967 32.4092 m
+3.5967 25.2217 l
+S61.1973 46.7842 m
+61.1973 39.5967 L
+S46.7969 46.7842 m
+46.7969 39.5967 L
+S32.3965 46.7842 m
+32.3965 39.5967 L
+S17.9971 46.7842 m
+17.9971 39.5967 L
+S3.5967 46.7842 m
+3.5967 39.5967 l
+S61.1973 61.2217 m
+61.1973 54.0347 L
+S46.7969 61.2217 m
+46.7969 54.0347 L
+S32.3965 61.2217 m
+32.3965 54.0347 L
+S17.9971 61.2217 m
+17.9971 54.0347 L
+S3.5967 61.2217 m
+3.5967 54.0347 l
+S61.1973 71.959 m
+61.1973 68.4717 L
+S46.7969 71.959 m
+46.7969 68.4717 L
+S32.3965 71.959 m
+32.3965 68.4717 L
+S17.9971 71.959 m
+17.9971 68.4717 L
+S3.5967 71.959 m
+3.5967 68.4717 l
+S32.3965 32.4092 m
+32.3965 25.2217 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Confetti)
+(Confetti) 4.85 3.617 76.85 75.617 [
+%AI3_Tile
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+4.85 3.617 m
+4.85 75.617 L
+76.85 75.617 L
+76.85 3.617 L
+4.85 3.617 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0 g
+ 0 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 0.3 w 4 M []0 d%AI3_Note:0 D
+0 XR
+10.6 64.867 m
+7.85 62.867 l
+S9.1 8.617 m
+6.85 6.867 l
+S78.1 68.617 m
+74.85 67.867 l
+S76.85 56.867 m
+74.35 55.117 l
+S79.6 51.617 m
+76.6 51.617 l
+S76.35 44.117 m
+73.6 45.867 l
+S78.6 35.867 m
+76.6 34.367 l
+S76.1 23.867 m
+73.35 26.117 l
+S78.1 12.867 m
+73.85 13.617 l
+S68.35 14.617 m
+66.1 12.867 l
+S76.6 30.617 m
+73.6 30.617 l
+S62.85 58.117 m
+60.956 60.941 l
+S32.85 59.617 m
+31.196 62.181 l
+S47.891 64.061 m
+49.744 66.742 l
+S72.814 2.769 m
+73.928 5.729 l
+S67.976 2.633 m
+67.35 5.909 l
+S61.85 27.617 m
+59.956 30.441 l
+S53.504 56.053 m
+51.85 58.617 l
+S52.762 1.779 m
+52.876 4.776 l
+S45.391 5.311 m
+47.244 7.992 l
+S37.062 3.375 m
+35.639 5.43 l
+S55.165 34.828 m
+57.518 37.491 l
+S20.795 3.242 m
+22.12 5.193 l
+S14.097 4.747 m
+15.008 8.965 l
+S9.736 1.91 m
+8.073 4.225 l
+S31.891 5.573 m
+32.005 8.571 l
+S12.1 70.367 m
+15.6 68.867 l
+S9.35 54.867 m
+9.6 58.117 l
+S12.85 31.867 m
+14.35 28.117 l
+S10.1 37.367 m
+12.35 41.117 l
+S34.1 71.117 m
+31.85 68.617 l
+S38.35 71.117 m
+41.6 68.367 l
+S55.1 71.117 m
+58.35 69.117 l
+S57.35 65.117 m
+55.35 61.867 l
+S64.35 66.367 m
+69.35 68.617 l
+S71.85 62.867 m
+69.35 61.117 l
+S23.6 70.867 m
+23.6 67.867 l
+S20.6 65.867 m
+17.35 65.367 l
+S24.85 61.367 m
+25.35 58.117 l
+S25.85 65.867 m
+29.35 66.617 l
+S14.1 54.117 m
+16.85 56.117 l
+S12.35 11.617 m
+12.6 15.617 l
+S12.1 19.867 m
+14.35 22.367 l
+S26.1 9.867 m
+23.6 13.367 l
+S34.6 47.117 m
+32.1 45.367 l
+S62.6 41.867 m
+59.85 43.367 l
+S31.6 35.617 m
+27.85 36.367 l
+S36.35 26.117 m
+34.35 24.617 l
+S33.85 14.117 m
+31.1 16.367 l
+S37.1 9.867 m
+35.1 11.117 l
+S34.35 20.867 m
+31.35 20.867 l
+S44.6 56.617 m
+42.1 54.867 l
+S47.35 51.367 m
+44.35 51.367 l
+S44.1 43.867 m
+41.35 45.617 l
+S43.35 33.117 m
+42.6 30.617 l
+S43.85 23.617 m
+41.1 25.867 l
+S44.35 15.617 m
+42.35 16.867 l
+S67.823 31.1 m
+64.823 31.1 l
+S27.1 32.617 m
+29.6 30.867 l
+S31.85 55.117 m
+34.85 55.117 l
+S19.6 40.867 m
+22.1 39.117 l
+S16.85 35.617 m
+19.85 35.617 l
+S20.1 28.117 m
+22.85 29.867 l
+S52.1 42.617 m
+54.484 44.178 l
+S52.437 50.146 m
+54.821 48.325 l
+S59.572 54.133 m
+59.35 51.117 l
+S50.185 10.055 m
+53.234 9.928 l
+S51.187 15.896 m
+53.571 14.075 l
+S58.322 19.883 m
+59.445 16.823 l
+S53.1 32.117 m
+50.6 30.367 l
+S52.85 24.617 m
+49.6 25.617 l
+S61.85 9.117 m
+59.1 10.867 l
+S69.35 34.617 m
+66.6 36.367 l
+S67.1 23.617 m
+65.1 22.117 l
+S24.435 46.055 m
+27.484 45.928 l
+S25.437 51.896 m
+27.821 50.075 l
+S62.6 47.117 m
+65.321 46.575 l
+S19.85 19.867 m
+20.35 16.617 l
+S21.85 21.867 m
+25.35 22.617 l
+S37.6 62.867 m
+41.6 62.117 l
+S38.323 42.1 m
+38.823 38.6 l
+S69.35 52.617 m
+66.85 53.867 l
+S14.85 62.117 m
+18.1 59.367 l
+S9.6 46.117 m
+7.1 44.367 l
+S20.6 51.617 m
+18.6 50.117 l
+S46.141 70.811 m
+47.994 73.492 l
+S69.391 40.561 m
+71.244 43.242 l
+S38.641 49.311 m
+39.35 52.117 l
+S25.141 16.811 m
+25.85 19.617 l
+S36.6 32.867 m
+34.6 31.367 l
+S6.1 68.617 m
+2.85 67.867 l
+S4.85 56.867 m
+2.35 55.117 l
+S7.6 51.617 m
+4.6 51.617 l
+S6.6 35.867 m
+4.6 34.367 l
+S6.1 12.867 m
+1.85 13.617 l
+S4.6 30.617 m
+1.6 30.617 l
+S72.814 74.769 m
+73.928 77.729 l
+S67.976 74.633 m
+67.35 77.909 l
+S52.762 73.779 m
+52.876 76.776 l
+S37.062 75.375 m
+35.639 77.43 l
+S20.795 75.242 m
+22.12 77.193 l
+S9.736 73.91 m
+8.073 76.225 l
+S10.1 23.617 m
+6.35 24.367 l
+S73.217 18.276 m
+71.323 21.1 l
+S28.823 39.6 m
+29.505 42.389 l
+S49.6 38.617 m
+47.6 37.117 l
+S60.323 73.6 m
+62.323 76.6 l
+S60.323 1.6 m
+62.323 4.6 l
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Leaves - Fall )
+(Leaves - Fall ) 0 0 64.0781 78.9336 [
+%AI3_Tile
+(0 O 0 R 0.05 0.2 1 0 k
+ 0.05 0.2 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+64.0781 78.9336 m
+64.0781 0 L
+0 0 L
+0 78.9336 L
+64.0781 78.9336 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0.83 0 1 0 k
+ 0.83 0 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:1 D
+0 XR
+29.7578 0.9902 m
+30.4346 1.1914 30.7246 1.3428 V
+29.2559 4.0547 33.707 8.3359 34.627 9.0762 C
+35.2275 8.8506 35.3477 6.3184 34.6699 4.9805 C
+35.5137 5.1035 37.7031 3.7256 38.4609 2.4365 C
+38.5254 3.125 40.0957 6.0664 40.9219 6.4434 C
+40.002 6.8408 39.3359 8.3135 38.5742 9.7617 C
+39.5957 9.9287 40.9961 9.0078 42.4668 8.1025 C
+42.9814 8.9043 44.3555 9.875 45.6143 10.3916 C
+44.5264 11.0781 44.0313 11.8203 43.5352 13.2793 C
+42.4922 12.7139 40.3057 12.5645 39.7764 12.8516 C
+40.291 13.9648 42.5371 14.5078 43.2676 14.4551 C
+43.0137 15.3164 42.8652 17.4697 43.0391 20.0625 C
+41.3789 18.7461 39.834 17.4297 38.1738 17.4883 C
+38.4434 16.0664 37.8076 14.2607 37.4307 13.7676 C
+36.8574 14.5117 36.4463 15.3389 36.8008 17.3164 C
+35.3486 17.8008 34.1113 18.3467 32.7373 19.6045 C
+32.7373 17.7734 32.166 16.5723 31.2969 15.2959 C
+32.5576 14.8076 33.8301 13.6045 33.8252 12.5664 C
+32.9775 12.7178 31.2852 13.4619 30.793 14.4551 C
+30.0742 13.707 28.3906 12.3984 26.7871 12.3945 C
+27.9746 11.5391 28.8945 10.5059 28.9893 8.5938 C
+30.2422 9.5645 32.6953 10.1797 34.0752 9.582 C
+29.2344 5.3457 29.7031 2.3125 29.7578 0.9902 C
+f13.8525 29.9844 m
+13.3281 29.5127 13.1309 29.25 V
+15.623 27.4326 13.3691 21.6074 12.8555 20.5439 C
+12.2168 20.4883 10.8096 23.2285 10.8457 24.7266 C
+9.7129 23.9707 8.0488 24.0918 6.4463 24.3779 C
+7.0186 23.2891 6.6172 21.3447 5.8164 20.5439 C
+6.8184 20.5801 8.1699 19.8652 9.4785 18.8838 C
+8.6436 18.0645 6.8164 18.2246 4.9004 18.8838 C
+4.9004 17.5107 4.0781 15.7734 3.2412 14.5918 C
+4.5576 14.6484 5.7031 13.9629 6.5605 12.9316 C
+7.2256 14.5 9.2598 15.6133 10.166 15.5645 C
+10.1826 14.1992 8.6094 12.1094 7.5879 11.7109 C
+8.1875 11.041 9.207 9.5107 10.166 7.0947 C
+10.9648 9.0205 12.1348 10.2627 13.3672 11.1953 C
+12.2256 12.7578 12.3994 13.6289 12.7988 15.1074 C
+13.541 14.5664 14.5723 14.1338 14.7441 12.1309 C
+16.4609 12.416 17.5957 12.3447 19.0938 11.4434 C
+18.6387 13.1055 18.6348 14.707 18.9551 16.4063 C
+17.1055 16.2666 15.5449 16.4795 14.5156 17.9688 C
+15.3457 18.1953 17.6055 18.2549 18.4795 17.3223 C
+18.8066 18.3047 19.7012 19.7109 21.1475 20.4043 C
+19.707 20.6641 18.7227 21.7637 17.8135 23.4492 C
+17.1006 22.0332 14.873 20.3691 13.3711 20.3145 C
+15.373 24.3779 15.373 27.2959 13.8525 29.9844 C
+f41.2324 26.0742 m
+41.5518 26.7021 41.7549 26.959 V
+44.1523 25.0176 48.958 28.3262 49.8535 29.0957 C
+49.7432 29.7266 47.6182 30.8643 45.9004 29.834 C
+46.3408 31.123 45.4395 33.084 44.2402 34.126 C
+45.9805 34.0254 48.126 35.3867 48.6484 36.1289 C
+48.8701 35.1514 50.0527 33.8809 51.3379 32.8672 C
+51.6895 33.8398 50.9941 35.958 50.0781 37.5605 C
+51.3125 38.0605 52.4248 38.9912 52.8828 40.25 C
+53.3398 38.9336 54.3428 38.2598 55.6875 37.5039 C
+54.5273 36.0762 53.7471 33.9023 54.0273 33.0391 C
+55.3496 33.374 56.9209 36.0918 57.0439 37.1816 C
+57.9189 36.415 59.4727 35.7285 62.0537 35.4219 C
+60.3535 34.3438 59.9902 32.3516 59.4063 30.9219 C
+58.2588 31.3682 56.0898 31.4277 55.1152 30.8643 C
+55.8281 30.2852 57.168 29.7344 59.1777 29.7207 C
+59.1777 28.1758 59.6406 27.043 60.8945 25.8281 C
+59.1719 25.8418 57.0723 25.3555 55.5762 24.9629 C
+55.3281 26.292 54.4844 27.8887 53.3398 28.2891 C
+53.334 27.4277 53.5996 25.1797 54.4844 24.5117 C
+53.6201 23.9443 52.3672 22.5674 51.9102 20.8496 C
+51.2881 22.1758 50.4268 23.4805 48.5645 23.9238 C
+49.749 24.9766 50.584 26.9941 50.25 28.4609 C
+45.1973 24.4785 42.5215 25.7773 41.2324 26.0742 C
+f27.7578 38.7324 m
+28.4346 38.9316 28.7246 39.084 V
+27.2559 41.7969 31.707 46.0776 32.627 46.8169 C
+33.2275 46.5918 33.3477 44.0586 32.6699 42.7227 C
+33.5137 42.8457 35.7031 41.4678 36.4609 40.1787 C
+36.5254 40.8652 38.0957 43.8066 38.9219 44.1846 C
+38.002 44.582 37.3359 46.0547 36.5742 47.5039 C
+37.5957 47.6709 38.9961 46.7485 40.4668 45.8438 C
+40.9814 46.6445 42.3555 47.6177 43.6143 48.1328 C
+42.5264 48.8198 42.0313 49.5615 41.5352 51.0205 C
+40.4922 50.4556 38.3057 50.3057 37.7764 50.5938 C
+38.291 51.7056 40.5371 52.2485 41.2676 52.1958 C
+41.0137 53.0576 40.8652 55.2109 41.0391 57.8037 C
+39.3789 56.4878 37.834 55.1719 36.1738 55.2285 C
+36.4434 53.8076 35.8076 52.002 35.4307 51.5088 C
+34.8574 52.2529 34.4463 53.0796 34.8008 55.0576 C
+33.3486 55.5425 32.1113 56.0879 30.7373 57.3467 C
+30.7373 55.5146 30.166 54.314 29.2969 53.0366 C
+30.5576 52.5488 31.8301 51.3467 31.8252 50.3076 C
+30.9775 50.46 29.2852 51.2036 28.793 52.1958 C
+28.0742 51.4497 26.3906 50.1396 24.7871 50.1357 C
+25.9746 49.2817 26.8945 48.2466 26.9893 46.335 C
+28.2422 47.3057 30.6953 47.9209 32.0752 47.3237 C
+27.2344 43.0869 27.7031 40.0547 27.7578 38.7324 C
+f13.5195 70.3916 m
+12.9941 69.9209 12.7988 69.6587 V
+15.2891 67.8418 13.0352 62.0146 12.5225 60.9517 C
+11.8828 60.8955 10.4766 63.6367 10.5117 65.1348 C
+9.3809 64.3789 7.7148 64.4995 6.1133 64.7856 C
+6.6855 63.6987 6.2842 61.7529 5.4834 60.9517 C
+6.4854 60.9878 7.8359 60.2729 9.1455 59.2925 C
+8.3105 58.4717 6.4834 58.6338 4.5674 59.2925 C
+4.5674 57.9189 3.7461 56.1816 2.9082 54.9995 C
+4.2246 55.0576 5.3691 54.3706 6.2275 53.3408 C
+6.8926 54.9097 8.9258 56.0215 9.832 55.9727 C
+9.8496 54.6079 8.2764 52.5176 7.2539 52.1187 C
+7.8545 51.4497 8.873 49.9189 9.832 47.5039 C
+10.6309 49.4297 11.8008 50.6719 13.0342 51.6045 C
+11.8926 53.1655 12.0664 54.0366 12.4648 55.5146 C
+13.209 54.9746 14.2393 54.5415 14.4102 52.5386 C
+16.127 52.8247 17.2637 52.7529 18.7598 51.8525 C
+18.3057 53.5137 18.3027 55.1147 18.623 56.8149 C
+16.7725 56.6748 15.2129 56.8887 14.1826 58.377 C
+15.0117 58.6035 17.2725 58.6626 18.1465 57.731 C
+18.4736 58.7129 19.3691 60.1187 20.8145 60.8125 C
+19.375 61.0728 18.3896 62.1719 17.4805 63.8579 C
+16.7676 62.4429 14.541 60.7769 13.0371 60.7227 C
+15.041 64.7856 15.041 67.7046 13.5195 70.3916 C
+f41.2324 64.4824 m
+41.5518 65.1113 41.7549 65.3682 V
+44.1523 63.4272 48.958 66.7354 49.8535 67.5034 C
+49.7432 68.1362 47.6182 69.2725 45.9004 68.2422 C
+46.3408 69.5313 45.4395 71.4922 44.2402 72.5342 C
+45.9805 72.4341 48.126 73.7954 48.6484 74.5371 C
+48.8701 73.5601 50.0527 72.29 51.3379 71.2754 C
+51.6895 72.249 50.9941 74.3662 50.0781 75.9683 C
+51.3125 76.4692 52.4248 77.3994 52.8828 78.6582 C
+53.3398 77.3423 54.3428 76.667 55.6875 75.9111 C
+54.5273 74.4844 53.7471 72.3101 54.0273 71.4473 C
+55.3496 71.7822 56.9209 74.5 57.0439 75.5903 C
+57.9189 74.8232 59.4727 74.1372 62.0537 73.8311 C
+60.3535 72.7534 59.9902 70.7612 59.4063 69.3301 C
+58.2588 69.7773 56.0898 69.8364 55.1152 69.2725 C
+55.8281 68.6934 57.168 68.1431 59.1777 68.1284 C
+59.1777 66.583 59.6406 65.4512 60.8945 64.2373 C
+59.1719 64.249 57.0723 63.7632 55.5762 63.3721 C
+55.3281 64.7002 54.4844 66.2974 53.3398 66.6973 C
+53.334 65.8364 53.5996 63.5874 54.4844 62.9214 C
+53.6201 62.353 52.3672 60.9751 51.9102 59.2583 C
+51.2881 60.583 50.4268 61.8882 48.5645 62.333 C
+49.749 63.3862 50.584 65.4033 50.25 66.8691 C
+45.1973 62.8872 42.5215 64.1851 41.2324 64.4824 C
+f%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Stripes)
+(Stripes) 8.45 4.6001 80.45 76.6001 [
+%AI3_Tile
+(0 O 0 R 1 0.07 1 0 k
+ 1 0.07 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 3.6 w 4 M []0 d%AI3_Note:0 D
+0 XR
+8.2 8.2 m
+80.7 8.2 L
+S8.2 22.6001 m
+80.7 22.6001 L
+S8.2 37.0002 m
+80.7 37.0002 L
+S8.2 51.4 m
+80.7 51.4 L
+S8.2 65.8001 m
+80.7 65.8001 L
+S8.2 15.4 m
+80.7 15.4 L
+S8.2 29.8001 m
+80.7 29.8001 L
+S8.2 44.2 m
+80.7 44.2 L
+S8.2 58.6001 m
+80.7 58.6001 L
+S8.2 73.0002 m
+80.7 73.0002 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginBrushPattern
+(New Pattern 1)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7844.75 8611 m
+-7844.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7844.75 8611 L
+nu0 Ap
+0 O
+1 g
+-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+F-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+F-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+F-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+F-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+F-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+F-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+F-7854.7817 8589.125 m
+-7860.9009 8587.6162 -7864.7817 8589.125 V
+-7868.877 8587.6484 -7874.7817 8589.125 V
+-7879.7446 8587.4492 -7884.7817 8589.125 V
+-7890.7969 8587.5742 -7894.7817 8589.125 V
+-7894.7817 8608.8096 L
+-7891.6958 8609.7842 -7888.2969 8609.9912 -7884.3799 8608.9082 C
+-7878.2134 8610.4912 -7874.4634 8608.9082 V
+-7869.4634 8610.4912 -7864.3799 8608.8242 V
+-7860.0474 8610.4082 -7854.3799 8608.9082 V
+-7848.8799 8610.3242 -7844.7817 8609.125 V
+-7844.7817 8589.4404 L
+-7847.5254 8588.4287 -7850.6514 8587.9287 -7854.7817 8589.125 C
+f0 R
+0 G
+1 J 1 j 0.5 w-7874.75 8609 m
+-7882.54 8610.9473 -7888.813 8607.585 -7894.75 8603.0488 C
+S-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+S-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+S-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+S-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+S-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+S-7864.75 8589 m
+-7856.96 8587.0527 -7850.687 8590.415 -7844.75 8594.9512 C
+S-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+S-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+SUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 2)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7829.187 8610 L
+-7829.187 8545.9023 L
+-7894 8545.9023 L
+-7894 8610 L
+nu0 O
+0 g
+-7859.6978 8568.4297 m
+-7861.6094 8545.9023 L
+-7863.5215 8568.4297 L
+-7862.9033 8568.3066 -7862.2642 8568.2402 -7861.6094 8568.2402 c
+-7860.9551 8568.2402 -7860.3159 8568.3066 -7859.6978 8568.4297 C
+f-7871.2402 8576.3975 m
+-7894 8578.3301 L
+-7871.1138 8580.2734 L
+-7871.2856 8579.5469 -7871.3848 8578.793 -7871.3848 8578.0156 c
+-7871.3848 8577.4629 -7871.3281 8576.9248 -7871.2402 8576.3975 C
+f-7866.519 8569.5723 m
+-7880.1626 8560.8047 L
+-7870.2153 8573.377 L
+-7869.3574 8571.791 -7868.0718 8570.4766 -7866.519 8569.5723 C
+f-7863.481 8587.6074 m
+-7861.5786 8610 L
+-7859.6768 8587.5967 L
+-7860.3018 8587.7227 -7860.9473 8587.791 -7861.6094 8587.791 c
+-7862.25 8587.791 -7862.873 8587.7246 -7863.481 8587.6074 C
+f-7851.9609 8579.5068 m
+-7829.187 8577.5732 L
+-7852.083 8575.6289 L
+-7852.083 8575.8506 L
+-7851.9258 8576.5488 -7851.834 8577.2695 -7851.834 8578.0156 c
+-7851.834 8578.5234 -7851.8848 8579.0195 -7851.9609 8579.5068 C
+f-7870.1138 8582.8262 m
+-7880.1641 8595.5293 L
+-7866.2778 8586.6055 L
+-7867.8823 8585.7305 -7869.2114 8584.416 -7870.1138 8582.8262 C
+f-7852.9961 8573.3945 m
+-7842.875 8560.6055 L
+-7856.7666 8569.5313 L
+-7855.1768 8570.4414 -7853.8633 8571.7793 -7852.9961 8573.3945 C
+f-7856.6895 8586.4512 m
+-7842.873 8595.3281 L
+-7852.9658 8582.5732 L
+-7853.8198 8584.1895 -7855.1152 8585.5313 -7856.6895 8586.4512 C
+f-7852.8887 8582.6133 m
+-7852.3862 8581.6641 -7852.043 8580.6211 -7851.875 8579.5195 c
+-7851.7993 8579.0293 -7851.748 8578.5273 -7851.748 8578.0156 c
+-7851.748 8577.2637 -7851.8398 8576.5352 -7851.998 8575.8311 c
+-7852.1958 8574.957 -7852.5049 8574.124 -7852.918 8573.3545 c
+-7853.7954 8571.7246 -7855.1191 8570.374 -7856.7241 8569.4561 c
+-7857.6294 8568.9375 -7858.6226 8568.5537 -7859.6802 8568.3457 c
+-7860.3047 8568.2207 -7860.9497 8568.1523 -7861.6094 8568.1523 c
+-7862.2695 8568.1523 -7862.915 8568.2207 -7863.5391 8568.3457 c
+-7864.623 8568.5605 -7865.6382 8568.957 -7866.5625 8569.4961 c
+-7868.1313 8570.4102 -7869.4282 8571.7363 -7870.291 8573.335 c
+-7870.7969 8574.2695 -7871.145 8575.2969 -7871.3262 8576.3828 c
+-7871.415 8576.916 -7871.4727 8577.459 -7871.4727 8578.0156 c
+-7871.4727 8578.8008 -7871.3711 8579.5605 -7871.1978 8580.293 c
+-7870.981 8581.207 -7870.6406 8582.0732 -7870.187 8582.8701 c
+-7869.2793 8584.4727 -7867.939 8585.8008 -7866.3174 8586.6826 c
+-7865.4487 8587.1553 -7864.5 8587.498 -7863.4961 8587.6934 c
+-7862.8848 8587.8115 -7862.2554 8587.8779 -7861.6094 8587.8779 c
+-7860.9414 8587.8779 -7860.29 8587.8086 -7859.6602 8587.6826 c
+-7858.5786 8587.4668 -7857.5664 8587.0654 -7856.6455 8586.5273 c
+-7855.0566 8585.5977 -7853.751 8584.2441 -7852.8887 8582.6133 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 3)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7884.75 8611 m
+-7884.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7884.75 8611 L
+nuu0 Ap
+0 O
+1 g
+-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 c
+-7887.897 8590.9736 -7891.0898 8589 -7894.75 8589 C
+-7894.75 8609 L
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 c
+-7891.9121 8608.7754 -7890.1807 8608.0645 -7888.7441 8606.9824 c
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 c
+f0 R
+0 G
+1 J 1 j 0.5 w-7894.75 8589.3174 m
+-7891.7207 8590.2744 -7888.8926 8591.9326 -7886.1543 8593.9072 C
+S-7894.75 8594.9512 m
+-7891.5991 8597.3564 -7888.543 8600.0869 -7885.4058 8602.5361 C
+S-7888.7441 8606.9824 m
+-7890.8105 8605.8916 -7892.7993 8604.5342 -7894.75 8603.043 C
+S-7893.8018 8608.9521 m
+-7894.1191 8608.8682 -7894.4375 8608.7852 -7894.75 8608.6865 C
+S-7888.7441 8606.9824 m
+-7890.1807 8608.0645 -7891.9121 8608.7744 -7893.8018 8608.9521 C
+S-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 C
+S-7894.75 8609 m
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 C
+S-7888.7441 8606.9824 m
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 C
+S-7886.1543 8593.9072 m
+-7887.8975 8590.9736 -7891.0898 8589 -7894.75 8589 C
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 5)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7736.3994 8611 m
+-7736.3994 8597.4199 L
+-7895 8597.4199 L
+-7895 8611 L
+-7736.3994 8611 L
+nuu0 O
+0.285 0.228 0.171 0 k
+-7751.0786 8609.4844 m
+-7751.043 8610.6895 L
+-7737.5103 8611.5176 -7736.8418 8610.2822 v
+-7736.7441 8610.1016 -7736.647 8609.7148 -7736.561 8609.1934 C
+-7738.584 8609.8242 -7748.291 8609.5713 -7751.0786 8609.4844 C
+f0.44 0.352 0.264 0 k
+-7751.4063 8598.0234 m
+-7751.3711 8599.2676 L
+-7748.4912 8599.0488 -7738.1914 8598.3164 -7736.543 8598.8652 C
+-7736.7031 8598.2188 -7736.9199 8597.7646 -7737.2046 8597.6152 c
+-7738.8306 8596.7656 -7751.4063 8598.0234 Y
+f0.145 0.116 0.087 0 k
+-7751.3711 8599.2676 m
+-7751.0786 8609.4844 L
+-7748.291 8609.5713 -7738.584 8609.8242 -7736.561 8609.1934 C
+-7736.1519 8606.7773 -7735.9258 8601.3604 -7736.543 8598.8652 C
+-7738.1914 8598.3164 -7748.4912 8599.0488 -7751.3711 8599.2676 C
+fUu0.155 0.124 0.093 0 k
+-7776.9375 8603.2734 m
+-7775.897 8603.6563 L
+-7757.0728 8599.1465 L
+-7757.481 8598.3145 L
+-7776.3633 8600.7246 L
+-7777.252 8601.0059 L
+-7777.6504 8600.8936 -7778.1934 8600.8242 V
+-7777.6094 8601.2373 -7777.1426 8602.1406 -7776.9375 8603.2734 C
+fu0.085 0.068 0.051 0 k
+-7781.7993 8607.666 m
+-7782.5977 8607.7217 -7779.749 8607.6641 Y
+-7780.3481 8607.0176 -7780.771 8605.8203 -7780.8105 8604.4375 c
+-7780.8169 8604.2246 -7780.8105 8604.0176 -7780.7993 8603.8135 C
+-7781.041 8603.707 -7781.0918 8603.7734 -7781.6289 8603.5645 C
+-7781 8607.6113 -7781.7993 8607.666 v
+f0.305 0.244 0.183 0 k
+-7780.3442 8600.8672 m
+-7780.5527 8600.8105 -7780.4937 8602.9307 Y
+-7779.4785 8603.7588 L
+-7777.8359 8602.9434 L
+-7776.9375 8603.2734 L
+-7777.1426 8602.1406 -7777.6094 8601.2373 -7778.1934 8600.8242 C
+-7778.6094 8600.7715 -7779.874 8600.7998 -7780.3442 8600.8672 C
+fU0.115 0.092 0.069 0 k
+-7776.9375 8603.2734 m
+-7777.8359 8602.9434 L
+-7779.4785 8603.7588 L
+-7780.4937 8602.9307 L
+-7780.793 8603.708 -7780.7993 8603.8135 V
+-7779.5137 8604.3789 -7778.1831 8604.7402 -7776.8398 8604.9258 C
+-7776.79 8604.7275 -7776.7842 8604.543 -7776.79 8604.3369 c
+-7776.7998 8603.9717 -7776.8218 8603.6182 -7776.9375 8603.2734 C
+f0.41 0.328 0.246 0 k
+-7757.4512 8599.3965 m
+-7759.377 8600.6426 -7768.3862 8606.0986 -7776.8398 8604.9258 C
+-7776.9038 8606.0928 -7777.248 8607.0908 -7777.75 8607.6631 C
+-7777.1895 8607.6621 L
+-7756.7402 8610.7559 L
+-7757.0366 8600.4258 L
+-7757.0728 8599.1465 L
+-7757.2046 8599.2373 -7757.4512 8599.3965 v
+f0.395 0.316 0.237 0 k
+-7780.8105 8604.4375 m
+-7780.771 8605.8203 -7780.3481 8607.0176 -7779.749 8607.6641 C
+-7777.6807 8607.6631 L
+-7777.1782 8607.0908 -7776.8218 8606.0713 -7776.8398 8604.9258 C
+-7778.1831 8604.7402 -7779.5137 8604.3789 -7780.7993 8603.8135 C
+-7780.8105 8604.0176 -7780.8169 8604.2246 -7780.8105 8604.4375 c
+fUu0 0 0 0.11 k
+-7751.2642 8598.2012 m
+-7750.2407 8598.0352 L
+-7751.2642 8598.2012 L
+-7751.2642 8598.2012 L
+f0 0 0 0.34 k
+-7757.481 8598.3145 m
+-7757.0728 8599.1465 L
+-7755.6714 8598.918 L
+-7754.5234 8598.7314 L
+-7752.6758 8598.4307 L
+-7751.2642 8598.2012 L
+-7750.2407 8598.0352 L
+-7750.2954 8597.7168 -7750.3672 8597.498 -7750.4648 8597.4199 C
+-7757.481 8598.3145 L
+f0 0 0 0.32 k
+-7755.8042 8603.207 m
+-7756.041 8610.8613 L
+-7750.7144 8611 L
+-7749.7266 8607.5146 -7750.1816 8603.1543 V
+-7755.8042 8603.207 L
+fU0.025 0.02 0.015 0 k
+-7749.3223 8600.3848 m
+-7746.373 8600.9199 -7743.2402 8601.1602 -7740.3159 8600.3613 c
+-7740.2856 8600.3496 -7740.2754 8600.3184 -7740.2871 8600.2969 c
+-7740.2881 8600.2656 -7740.3198 8600.2559 -7740.3418 8600.2559 c
+-7743.2422 8601.0645 -7746.375 8600.8242 -7749.3042 8600.2783 c
+-7749.3262 8600.2793 -7749.3574 8600.291 -7749.3672 8600.3223 c
+-7749.3662 8600.3438 -7749.355 8600.375 -7749.3223 8600.3848 c
+-7749.3223 8600.3848 l
+f-7747.8374 8599.3076 m
+-7747.7295 8599.3789 -7747.6313 8599.4941 -7747.5234 8599.502 c
+-7743.7886 8599.832 -7740.1631 8599.7813 -7736.4746 8599.6641 c
+-7736.4526 8599.6641 -7736.4209 8599.6426 -7736.4214 8599.6211 c
+-7736.4214 8599.5879 -7736.4551 8599.5684 -7736.4766 8599.5684 c
+-7739.3223 8599.6816 -7742.1401 8599.6992 -7745.0039 8599.5352 c
+-7745.9336 8599.4766 -7746.9082 8599.7402 -7747.7778 8599.2207 c
+-7747.7993 8599.2109 -7747.8306 8599.2109 -7747.8506 8599.2334 c
+-7747.8618 8599.2559 -7747.8594 8599.2871 -7747.8374 8599.3076 c
+-7747.8374 8599.3076 l
+f-7743.373 8601.3672 m
+-7741.5098 8602.6797 -7739.3022 8603.374 -7737.1001 8603.8867 c
+-7737.0679 8603.8965 -7737.0474 8603.8848 -7737.0366 8603.8535 c
+-7737.0273 8603.8203 -7737.0488 8603.8008 -7737.0703 8603.79 c
+-7739.2617 8603.2656 -7741.459 8602.6035 -7743.3105 8601.2803 c
+-7743.3433 8601.2598 -7743.375 8601.2715 -7743.3848 8601.293 c
+-7743.4058 8601.3145 -7743.3945 8601.3457 -7743.373 8601.3672 c
+-7743.373 8601.3672 l
+f-7748.9321 8608.0566 m
+-7746.7295 8608.5703 -7744.5298 8609.0303 -7742.2798 8609.2754 c
+-7742.2598 8609.2852 -7742.229 8609.2637 -7742.229 8609.2422 c
+-7742.2183 8609.209 -7742.2407 8609.1777 -7742.2729 8609.1787 c
+-7744.5122 8608.8809 -7746.7305 8608.5176 -7748.9126 8607.9502 c
+-7748.9351 8607.9512 -7748.9673 8607.9629 -7748.9766 8607.9941 c
+-7748.9751 8608.0156 -7748.9648 8608.0479 -7748.9321 8608.0566 c
+-7748.9321 8608.0566 l
+f-7748.439 8607.3604 m
+-7746.3457 8608.1973 -7744.1016 8607.9297 -7741.9023 8607.9629 c
+-7741.8706 8607.9609 -7741.8496 8607.9395 -7741.8506 8607.9082 c
+-7741.8521 8607.875 -7741.873 8607.8555 -7741.8945 8607.8555 c
+-7744.0928 8607.8438 -7746.3374 8608.0996 -7748.4209 8607.2529 c
+-7748.4434 8607.2539 -7748.4746 8607.2656 -7748.4834 8607.2969 c
+-7748.4834 8607.3184 -7748.4722 8607.3506 -7748.439 8607.3604 c
+-7748.439 8607.3604 l
+f-7747.707 8608.7051 m
+-7746.3833 8608.752 -7745.1504 8608.5469 -7743.8271 8608.209 c
+-7743.3594 8608.0996 -7742.9199 8608.2266 -7742.4609 8608.2129 c
+-7741.897 8608.1973 l
+-7741.874 8608.1963 -7741.8633 8608.1855 -7741.8535 8608.1738 c
+-7741.834 8608.1523 -7741.8442 8608.1211 -7741.8662 8608.0996 c
+-7742.0625 8607.9453 l
+-7742.0742 8607.9453 -7742.085 8607.9355 -7742.0962 8607.9355 c
+-7742.5 8607.9473 l
+-7743.9551 8608.1914 -7745.457 8608.6719 -7746.8926 8608.0742 c
+-7746.9258 8608.0645 -7746.957 8608.0859 -7746.9673 8608.1074 c
+-7746.9673 8608.1396 -7746.9551 8608.1602 -7746.9336 8608.1709 c
+-7745.647 8608.6992 -7744.1714 8608.4756 -7742.8818 8608.0547 c
+-7742.0918 8608.043 L
+-7742.124 8608.0332 L
+-7741.9282 8608.1875 L
+-7741.8984 8608.0898 L
+-7742.4639 8608.1064 l
+-7742.9321 8608.1406 -7743.3848 8607.9834 -7743.8398 8608.1035 c
+-7745.1543 8608.4609 -7746.3975 8608.625 -7747.71 8608.5986 c
+-7747.7422 8608.5996 -7747.7642 8608.6211 -7747.7617 8608.6533 c
+-7747.7617 8608.6855 -7747.7402 8608.7061 -7747.707 8608.7051 c
+-7747.707 8608.7051 l
+f-7748.5718 8609.0605 m
+-7745.8711 8610.2207 -7742.9023 8609.5703 -7740.1279 8609.1816 c
+-7739.7832 8609.2891 l
+-7739.7617 8609.2988 -7739.7417 8609.2871 -7739.7207 8609.2656 c
+-7739.71 8609.2441 -7739.7217 8609.2129 -7739.7422 8609.2021 c
+-7740.0801 8609.0098 l
+-7742.7754 8608.3926 -7745.5391 8608.7813 -7748.271 8608.7852 c
+-7748.3022 8608.7871 -7748.3232 8608.8086 -7748.3223 8608.8398 c
+-7748.3198 8608.8721 -7748.2983 8608.8926 -7748.2681 8608.8926 c
+-7745.6738 8608.9355 -7743.0303 8608.4434 -7740.4727 8609.0742 c
+-7739.7954 8609.2891 L
+-7739.7534 8609.1914 L
+-7740.1406 8609.0859 l
+-7742.9058 8609.4424 -7745.8418 8610.1348 -7748.5313 8608.9746 c
+-7748.5537 8608.9648 -7748.585 8608.9648 -7748.5962 8608.998 c
+-7748.6055 8609.0195 -7748.605 8609.0508 -7748.5718 8609.0605 c
+-7748.5718 8609.0605 l
+f-7745.6895 8602.3945 m
+-7744.3945 8602.9004 -7742.9834 8602.6465 -7741.6802 8602.3438 c
+-7741.647 8602.3418 -7741.6367 8602.3203 -7741.6382 8602.2891 c
+-7741.6504 8602.2568 -7741.6714 8602.2461 -7741.7031 8602.248 c
+-7742.998 8602.5303 -7744.377 8602.8154 -7745.6504 8602.2969 c
+-7745.6826 8602.2871 -7745.7144 8602.2988 -7745.7246 8602.3311 c
+-7745.7222 8602.3525 -7745.7114 8602.3848 -7745.6895 8602.3945 c
+-7745.6895 8602.3945 l
+f-7746.1401 8604.2207 m
+-7744.2266 8604.6895 -7742.3145 8605.1035 -7740.355 8605.3242 c
+-7740.3242 8605.334 -7740.3022 8605.3125 -7740.293 8605.2803 c
+-7740.2954 8605.2598 -7740.3159 8605.2285 -7740.3374 8605.2285 c
+-7742.2959 8605.0078 -7744.209 8604.582 -7746.1206 8604.1133 c
+-7746.1426 8604.1152 -7746.1738 8604.126 -7746.1831 8604.1582 c
+-7746.1831 8604.1797 -7746.1719 8604.2109 -7746.1401 8604.2207 c
+-7746.1401 8604.2207 l
+f-7746.9336 8606.6348 m
+-7744.499 8607.4609 -7741.8647 8607.0547 -7739.3457 8607.0879 c
+-7739.313 8607.0879 -7739.293 8607.0664 -7739.293 8607.0332 c
+-7739.2954 8607.0117 -7739.3159 8606.9922 -7739.3481 8606.9922 c
+-7741.8574 8606.916 -7744.481 8607.3848 -7746.8945 8606.5264 c
+-7746.9282 8606.5273 -7746.959 8606.5391 -7746.9688 8606.5605 c
+-7746.9678 8606.5918 -7746.9561 8606.624 -7746.9336 8606.6348 c
+-7746.9336 8606.6348 l
+f-7742.0542 8607.8496 m
+-7740.6582 8608.5449 -7739.0503 8608.4033 -7737.5342 8608.4668 c
+-7737.502 8608.4648 -7737.4824 8608.4434 -7737.4824 8608.4121 c
+-7737.4834 8608.3906 -7737.5054 8608.3594 -7737.5366 8608.3594 c
+-7739.0137 8608.2207 -7740.6489 8608.5234 -7742.0039 8607.7617 c
+-7742.0366 8607.7529 -7742.0679 8607.7637 -7742.0786 8607.7861 c
+-7742.0879 8607.8076 -7742.0767 8607.8398 -7742.0542 8607.8496 c
+-7742.0542 8607.8496 l
+f-7741.3418 8604.4248 m
+-7740.3926 8604.3975 -7739.4336 8604.3701 -7738.4839 8604.3428 c
+-7738.4526 8604.3418 -7738.4312 8604.3203 -7738.4336 8604.2881 c
+-7738.4336 8604.2559 -7738.4551 8604.2354 -7738.4878 8604.2363 c
+-7739.437 8604.2637 -7740.397 8604.291 -7741.3457 8604.3184 c
+-7741.377 8604.3184 -7741.3975 8604.3418 -7741.3975 8604.373 c
+-7741.397 8604.4043 -7741.374 8604.4258 -7741.3418 8604.4248 c
+-7741.3418 8604.4248 l
+f-7739.1592 8602.0361 m
+-7738.6895 8602.0645 -7738.209 8602.0723 -7737.7383 8602.0918 c
+-7737.7168 8602.0908 -7737.6855 8602.0684 -7737.6865 8602.0371 c
+-7737.687 8602.0039 -7737.71 8601.9844 -7737.7417 8601.9844 c
+-7738.2114 8601.9873 -7738.6816 8601.9375 -7739.1514 8601.9395 c
+-7739.1831 8601.9297 -7739.2031 8601.9512 -7739.2134 8601.9844 c
+-7739.2129 8602.0156 -7739.1914 8602.0371 -7739.1592 8602.0361 c
+-7739.1592 8602.0361 l
+f-7746.9702 8604.2344 m
+-7746.5688 8604.5107 -7746.125 8604.6797 -7745.645 8604.751 c
+-7745.6113 8604.7607 -7745.5918 8604.7383 -7745.5806 8604.7168 c
+-7745.5703 8604.6855 -7745.5928 8604.6543 -7745.6152 8604.6543 c
+-7746.0854 8604.5723 -7746.5176 8604.4023 -7746.9209 8604.1475 c
+-7746.9521 8604.1377 -7746.9849 8604.1387 -7746.9946 8604.1709 c
+-7747.0039 8604.1934 -7746.9922 8604.2246 -7746.9702 8604.2344 c
+-7746.9702 8604.2344 l
+f-7748.1904 8610.085 m
+-7745.7344 8610.5273 -7743.2983 8611.001 -7740.7993 8610.7266 c
+-7740.7778 8610.7266 -7740.7568 8610.7041 -7740.7578 8610.6719 c
+-7740.7578 8610.6406 -7740.7798 8610.6191 -7740.8022 8610.6191 c
+-7743.291 8610.873 -7745.7344 8610.4844 -7748.1719 8609.9775 c
+-7748.1934 8609.9785 -7748.2256 8609.9902 -7748.2344 8610.0215 c
+-7748.2344 8610.043 -7748.2222 8610.0752 -7748.1904 8610.085 c
+-7748.1904 8610.085 l
+f0.195 0.156 0.117 0 k
+-7748.166 8598.6445 m
+-7745.7969 8598.2676 -7743.4058 8598.3477 -7741.0298 8598.5898 c
+-7740.998 8598.5879 -7740.9766 8598.5664 -7740.9766 8598.5352 c
+-7740.9785 8598.5137 -7741 8598.4824 -7741.0215 8598.4824 c
+-7743.4082 8598.2422 -7745.791 8598.1602 -7748.1694 8598.5391 c
+-7748.2026 8598.5391 -7748.2222 8598.5605 -7748.2217 8598.5938 c
+-7748.2207 8598.625 -7748.1992 8598.6465 -7748.166 8598.6445 c
+-7748.166 8598.6445 l
+f0.335 0.268 0.201 0 k
+-7747.4351 8598.1113 m
+-7744.9282 8598.1152 -7742.4146 8598.2773 -7739.918 8597.8965 c
+-7739.8862 8597.8945 -7739.8647 8597.873 -7739.8662 8597.8418 c
+-7739.8672 8597.8086 -7739.8896 8597.7891 -7739.9209 8597.7891 c
+-7742.418 8598.1699 -7744.9297 8598.0293 -7747.4375 8598.0059 c
+-7747.46 8598.0059 -7747.481 8598.0273 -7747.4785 8598.0596 c
+-7747.4785 8598.0918 -7747.457 8598.1123 -7747.4351 8598.1113 c
+-7747.4351 8598.1113 l
+f0.205 0.164 0.123 0 k
+-7748.9766 8598.3262 m
+-7747.5039 8598.668 -7746.0078 8598.4023 -7744.5391 8598.2207 c
+-7744.5078 8598.2207 -7744.4873 8598.1973 -7744.499 8598.166 c
+-7744.5 8598.1348 -7744.5215 8598.1133 -7744.5537 8598.125 c
+-7746.0103 8598.2842 -7747.4961 8598.583 -7748.9473 8598.2188 c
+-7748.9785 8598.2207 -7749.0103 8598.2324 -7749.0098 8598.2637 c
+-7749.019 8598.2852 -7748.998 8598.3164 -7748.9766 8598.3262 c
+-7748.9766 8598.3262 l
+f-7742.3535 8597.7949 m
+-7741.1978 8597.9219 -7740.0273 8597.8145 -7738.8926 8597.5898 c
+-7738.8711 8597.5781 -7738.8506 8597.5566 -7738.8618 8597.5244 c
+-7738.8623 8597.5029 -7738.8945 8597.4824 -7738.916 8597.4941 c
+-7740.0503 8597.7402 -7741.1914 8597.7939 -7742.3462 8597.6885 c
+-7742.3794 8597.6895 -7742.3984 8597.7109 -7742.4087 8597.7324 c
+-7742.4082 8597.7646 -7742.3862 8597.7852 -7742.3535 8597.7949 c
+-7742.3535 8597.7949 l
+f0.335 0.268 0.201 0 k
+-7749.2681 8600.4473 m
+-7747.9214 8601.1885 -7746.3066 8600.5977 -7744.855 8600.6416 c
+-7744.8223 8600.6406 -7744.8022 8600.6191 -7744.8022 8600.5859 c
+-7744.8042 8600.5654 -7744.8262 8600.5449 -7744.8574 8600.5449 c
+-7746.2886 8600.4902 -7747.8823 8601.0801 -7749.2168 8600.3506 c
+-7749.2383 8600.3398 -7749.2695 8600.3516 -7749.291 8600.374 c
+-7749.3008 8600.3955 -7749.2886 8600.4277 -7749.2681 8600.4473 c
+-7749.2681 8600.4473 l
+f-7747.8945 8602.5645 m
+-7745.6719 8603.0449 -7743.3896 8602.6162 -7741.1504 8602.5625 c
+-7741.1177 8602.5615 -7741.0977 8602.5391 -7741.0977 8602.5078 c
+-7741.1001 8602.4863 -7741.1318 8602.4668 -7741.1519 8602.4668 c
+-7743.3833 8602.4775 -7745.6519 8602.9805 -7747.875 8602.457 c
+-7747.8975 8602.457 -7747.9287 8602.4688 -7747.9375 8602.502 c
+-7747.9375 8602.5225 -7747.9258 8602.5547 -7747.8945 8602.5645 c
+-7747.8945 8602.5645 l
+f-7742.0273 8599.1406 m
+-7740.3496 8599.9688 -7738.499 8600.502 -7736.603 8600.3613 c
+-7736.5718 8600.3613 -7736.5513 8600.3389 -7736.5527 8600.3066 c
+-7736.5527 8600.2754 -7736.5742 8600.2539 -7736.6074 8600.2559 c
+-7738.481 8600.416 -7740.3198 8599.8604 -7741.9873 8599.0547 c
+-7742.0078 8599.0449 -7742.041 8599.0449 -7742.0503 8599.0781 c
+-7742.061 8599.0996 -7742.061 8599.1309 -7742.0273 8599.1406 c
+-7742.0273 8599.1406 l
+fu0.5 0.85 1 0.45 k
+-7895 8605.9082 m
+-7895.0254 8606.4883 -7894.5664 8607.1875 -7893.167 8607.9902 C
+-7892.8521 8608.0029 -7891.3945 8608.0234 -7889.0889 8608.0488 C
+-7889.0889 8605.8223 L
+-7891.1382 8605.8457 -7893.1177 8605.8867 -7895 8605.9082 C
+f-7894.5088 8604.9688 m
+-7889.0889 8604.8447 L
+-7889.0889 8603.8145 L
+-7892.644 8603.959 L
+-7893.8145 8604.3301 -7894.5088 8604.9688 V
+f0.5 0.85 1 0.32 k
+-7889.0889 8604.8252 m
+-7894.4746 8604.9434 L
+-7894.7695 8605.2148 -7894.9849 8605.5566 -7895 8605.9277 C
+-7893.1177 8605.9063 -7891.1382 8605.8848 -7889.0889 8605.8613 C
+-7889.0889 8604.8252 L
+f0.5 0.85 1 0.45 k
+-7784.1504 8604.6172 m
+-7862.3584 8605.541 -7889.1079 8605.8418 V
+-7889.1079 8608.0488 L
+-7872.8145 8608.2324 -7813.9902 8608.707 Y
+-7779.749 8607.6641 L
+-7780.457 8604.5684 L
+-7784.1504 8604.6172 L
+f0.5 0.85 1 0.12 k
+-7889.1079 8603.8145 m
+-7889.1079 8604.8447 L
+-7780.4258 8603 L
+-7780.3833 8600.8633 L
+-7813.6553 8600.7129 L
+-7889.1079 8603.8145 L
+fu0.065 0.052 0.039 0 k
+-7757.0728 8599.1465 m
+-7757.0366 8600.4258 L
+-7757.2954 8599.1172 L
+-7775.897 8603.6563 L
+-7776.9375 8603.2734 L
+-7776.8794 8603.6055 -7776.8398 8603.957 -7776.8306 8604.3223 c
+-7776.8242 8604.5283 -7776.8281 8604.7285 -7776.8398 8604.9258 C
+-7768.3862 8606.0986 -7758.9634 8601.6719 -7757.0366 8600.4258 C
+-7756.7402 8610.7559 L
+-7756.041 8610.8613 L
+-7755.8042 8603.207 L
+-7750.1816 8603.1543 L
+-7750.0898 8601.0137 -7750.0718 8599.0215 -7750.2407 8598.0352 C
+-7757.0728 8599.1465 L
+f0.4 0.7 1 0 k
+-7780.457 8604.5879 m
+-7780.4258 8602.9805 L
+-7889.1079 8604.8252 L
+-7889.1079 8605.8613 L
+-7862.3584 8605.5605 -7780.457 8604.5879 Y
+fUU0.025 0.02 0.015 0 k
+-7744.7344 8607.0293 m
+-7744.7344 8607.0625 -7744.7129 8607.082 -7744.6802 8607.082 c
+-7741.6714 8607.1133 -7739.4214 8606.9453 -7736.415 8606.8594 C
+-7736.4087 8606.7656 L
+-7739.3262 8606.8701 -7741.7607 8607.0078 -7744.6841 8606.9746 C
+-7744.7168 8606.9766 -7744.7358 8606.998 -7744.7344 8607.0293 C
+f-7736.3994 8606.7656 m
+-7736.4082 8606.7441 L
+-7736.4087 8606.7656 L
+-7736.4063 8606.7656 -7736.4033 8606.7656 -7736.3994 8606.7656 C
+f-7740.4487 8605.4238 m
+-7741.4458 8605.292 -7742.3394 8605.7656 -7743.2114 8606.1973 C
+-7743.2441 8606.208 -7743.2534 8606.2402 -7743.2422 8606.2715 C
+-7743.2305 8606.293 -7743.1982 8606.3027 -7743.1777 8606.291 c
+-7742.3262 8605.8301 -7741.4312 8605.4199 -7740.4678 8605.5195 c
+-7739.1079 8605.6621 -7737.9038 8606.375 -7736.5254 8606.4531 C
+-7736.4463 8606.3594 L
+-7738.04 8606.2656 -7738.8647 8605.623 -7740.4487 8605.4238 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 6)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894.75 8587 m
+-7894.75 8611 L
+-7884.75 8611 L
+-7884.75 8587 L
+-7894.75 8587 L
+n0 Ap
+0 O
+1 g
+-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 c
+-7887.5879 8589.2256 -7889.3198 8589.9346 -7890.7559 8591.0176 c
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 c
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.2319 8602.5996 -7893.3457 8604.0918 c
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+-7884.75 8589 L
+f0 R
+0 G
+1 J 1 j 0.5 w-7884.75 8608.6816 m
+-7887.7793 8607.7256 -7890.6074 8606.0674 -7893.3457 8604.0918 C
+S-7884.75 8603.0488 m
+-7887.8999 8600.6436 -7890.957 8597.9131 -7894.0942 8595.4639 C
+S-7890.7559 8591.0176 m
+-7888.6904 8592.1084 -7886.7017 8593.4668 -7884.75 8594.957 C
+S-7885.6982 8589.0479 m
+-7885.3809 8589.1309 -7885.063 8589.2148 -7884.75 8589.3145 C
+S-7890.7559 8591.0176 m
+-7889.3193 8589.9355 -7887.5879 8589.2256 -7885.6982 8589.0479 C
+S-7894.0942 8595.4639 m
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.231 8602.5996 -7893.3457 8604.0918 C
+S-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 C
+S-7890.7559 8591.0176 m
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 C
+S-7893.3457 8604.0918 m
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+SU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 8)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7893.9521 8608.3125 m
+-7786.7954 8608.3125 L
+-7786.7954 8594.1855 L
+-7893.9521 8594.1855 L
+-7893.9521 8608.3125 L
+nu0 O
+0 0 0 1 k
+-7892.2832 8607.623 m
+-7892.8535 8610 -7892.8184 8606.0039 V
+-7893.0479 8602.8027 L
+-7893.6167 8600.4551 L
+-7893.4502 8598.123 L
+-7891.9502 8597.4551 -7875.2832 8596.123 V
+-7868.6167 8594.7891 -7859.6167 8594.7891 V
+-7794.3936 8595.4766 -7789.4912 8596.8848 v
+-7830.3882 8594.875 -7832.9688 8595.5117 v
+-7793.8569 8597.1602 -7790.8545 8598.4316 v
+-7828.79 8596.5469 -7832.167 8598.1777 v
+-7797.249 8599.9102 -7793.021 8601.5313 v
+-7799.7217 8600.8828 -7801.5127 8601.082 v
+-7798.3896 8601.5703 l
+-7803.4194 8601.502 l
+-7806.3218 8601.1289 l
+-7798.4521 8602.2422 -7797.9033 8602.8086 v
+-7794.3154 8602.1309 -7808.5186 8602.3848 v
+-7842.1177 8598.4551 -7892.2832 8607.623 V
+f/BBAccumRotation (5.805971) XT
+0 R
+0 0 0 0.5 K
+0.025 w-7893.9502 8597.123 m
+-7873.667 8595.2949 -7853.9727 8594.2207 v
+-7811.1514 8594.502 -7806.5737 8594.9004 v
+-7794.1631 8595.0313 -7786.7959 8596.0273 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 1 K
+-7831.8369 8594.4082 m
+-7835.2959 8594.0273 -7861.2607 8594.2793 Y
+-7871.627 8594.1602 -7893.9502 8597.123 Y
+S/BBAccumRotation (5.805971) XT
+-7830.9873 8597.6641 m
+-7800.3608 8598.582 -7793.6606 8599.2324 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 0.5 K
+-7839.6201 8602.2051 m
+-7804.3706 8603.6172 -7801.4058 8604.1406 v
+S/BBAccumRotation (5.805971) XT
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 10)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7843.8921 8610 L
+-7843.8921 8553.9756 L
+-7894 8553.9756 L
+-7894 8610 L
+nu0 O
+0.1 1 1 0 k
+-7856.9014 8575.5752 m
+-7858.7178 8569.0957 -7868.8247 8572.4658 Y
+-7868.791 8572.5303 L
+-7878.8999 8569.1611 -7880.7144 8575.6396 V
+-7886.6758 8593.0068 -7881.4922 8599.7451 V
+-7874.7529 8609.3369 -7870.6055 8609.3369 V
+-7867.0103 8609.2705 L
+-7862.8638 8609.2705 -7856.125 8599.6816 Y
+-7850.9409 8592.9424 -7856.9014 8575.5752 Y
+fu0 0 0 1 k
+-7861.3926 8553.9756 m
+-7862.1167 8555.4199 -7862.9238 8556.4756 V
+-7862.4058 8556.0635 -7861.5151 8555.1924 -7861.3926 8553.9756 C
+f-7875.064 8556.4854 m
+-7875.8711 8555.4307 -7876.5942 8553.9863 Y
+-7876.4727 8555.2021 -7875.582 8556.0732 -7875.064 8556.4854 C
+fU0 0.61 0.74 0 k
+-7860.5977 8578.4609 m
+-7861.9038 8573.7959 -7869.1816 8576.2217 Y
+-7869.1567 8576.2686 L
+-7876.436 8573.8428 -7877.7417 8578.5078 V
+-7882.0337 8591.0117 -7878.3018 8595.8633 V
+-7873.4487 8602.7686 -7870.4634 8602.7686 V
+-7867.875 8602.7227 L
+-7864.8887 8602.7227 -7860.0366 8595.8174 Y
+-7856.3042 8590.9639 -7860.5977 8578.4609 Y
+fu1 Ap
+0.73 0.43 1 0.22 k
+0 R
+0 0 0 1 K
+-7864.6226 8581.2754 m
+-7863.813 8581.2754 -7863.1558 8580.6182 -7863.1558 8579.8096 c
+-7863.1558 8579 -7863.813 8578.3428 -7864.6226 8578.3428 c
+-7865.4321 8578.3428 -7866.0889 8579 -7866.0889 8579.8096 c
+-7866.0889 8580.6182 -7865.4321 8581.2754 -7864.6226 8581.2754 c
+b-7864.3638 8592.9971 m
+-7863.0806 8592.9971 -7862.0415 8592.1201 -7862.0415 8591.042 c
+-7862.0415 8589.9619 -7863.0806 8589.0869 -7864.3638 8589.0869 c
+-7865.645 8589.0869 -7866.6846 8589.9619 -7866.6846 8591.042 c
+-7866.6846 8592.1201 -7865.645 8592.9971 -7864.3638 8592.9971 c
+b-7863.834 8604.7861 m
+-7862.2817 8604.7861 -7861.0239 8604.1299 -7861.0239 8603.3213 c
+-7861.0239 8602.5117 -7862.2817 8601.8545 -7863.834 8601.8545 c
+-7865.3862 8601.8545 -7866.645 8602.5117 -7866.645 8603.3213 c
+-7866.645 8604.1299 -7865.3862 8604.7861 -7863.834 8604.7861 c
+b-7859.6104 8576.5264 m
+-7858.8687 8576.5264 -7858.2671 8575.8154 -7858.2671 8574.9365 c
+-7858.2671 8574.0596 -7858.8687 8573.3477 -7859.6104 8573.3477 c
+-7860.353 8573.3477 -7860.9546 8574.0596 -7860.9546 8574.9365 c
+-7860.9546 8575.8154 -7860.353 8576.5264 -7859.6104 8576.5264 c
+b-7858.0034 8598.083 m
+-7858.8818 8597.7354 -7859.1494 8596.335 -7858.603 8594.9541 c
+-7858.0566 8593.5752 -7856.9014 8592.7363 -7856.0234 8593.085 c
+-7855.145 8593.4326 -7854.877 8594.833 -7855.4233 8596.2139 c
+-7855.9702 8597.5947 -7857.125 8598.4316 -7858.0034 8598.083 c
+bu-7873.0566 8581.1592 m
+-7873.8662 8581.1592 -7874.5239 8580.502 -7874.5239 8579.6934 c
+-7874.5239 8578.8828 -7873.8662 8578.2266 -7873.0566 8578.2266 c
+-7872.248 8578.2266 -7871.5913 8578.8828 -7871.5913 8579.6934 c
+-7871.5913 8580.502 -7872.248 8581.1592 -7873.0566 8581.1592 c
+b-7873.3159 8592.8799 m
+-7874.5991 8592.8799 -7875.6382 8592.0049 -7875.6382 8590.9248 c
+-7875.6382 8589.8447 -7874.5991 8588.9697 -7873.3159 8588.9697 c
+-7872.0342 8588.9697 -7870.9951 8589.8447 -7870.9951 8590.9248 c
+-7870.9951 8592.0049 -7872.0342 8592.8799 -7873.3159 8592.8799 c
+b-7873.8457 8604.6709 m
+-7875.3975 8604.6709 -7876.6558 8604.0146 -7876.6558 8603.2041 c
+-7876.6558 8602.3936 -7875.3975 8601.7383 -7873.8457 8601.7383 c
+-7872.293 8601.7383 -7871.0352 8602.3936 -7871.0352 8603.2041 c
+-7871.0352 8604.0146 -7872.293 8604.6709 -7873.8457 8604.6709 c
+b-7878.0679 8576.4092 m
+-7878.811 8576.4092 -7879.4121 8575.6982 -7879.4121 8574.8213 c
+-7879.4121 8573.9443 -7878.811 8573.2334 -7878.0679 8573.2334 c
+-7877.3262 8573.2334 -7876.7241 8573.9443 -7876.7241 8574.8213 c
+-7876.7241 8575.6982 -7877.3262 8576.4092 -7878.0679 8576.4092 c
+b-7879.6758 8597.9678 m
+-7878.7983 8597.6201 -7878.5298 8596.2188 -7879.0762 8594.8379 c
+-7879.6226 8593.457 -7880.7778 8592.6201 -7881.6558 8592.9678 c
+-7882.5342 8593.3164 -7882.8032 8594.7178 -7882.2568 8596.0967 c
+-7881.7104 8597.4775 -7880.5552 8598.3154 -7879.6758 8597.9678 c
+bUU0 Ap
+0 0 0 1 k
+-7869.1318 8576.6553 m
+-7869.1318 8609.3145 l
+Fu-7853.3906 8562.5303 m
+-7854.0815 8561.8369 -7857.019 8562.7021 Y
+-7858.229 8562.874 -7858.0562 8565.2939 Y
+-7857.019 8567.3682 -7857.7104 8567.1943 Y
+-7858.2998 8567.1943 -7859.855 8567.1143 -7860.7822 8567.0635 C
+-7861.1226 8565.6689 -7862.6128 8564.4756 -7864.7217 8563.7695 C
+-7862.7578 8560.4775 -7864.5176 8559.7949 -7866.2935 8559.79 C
+-7866.3096 8559.7021 -7866.332 8559.6162 -7866.3599 8559.5332 C
+-7864.1089 8559.5791 -7863.6392 8557.2588 Y
+-7863.4048 8557.0635 -7863.1606 8556.7861 -7862.9238 8556.4756 C
+-7863.1416 8556.6475 -7863.2944 8556.7393 Y
+-7864.2583 8556.7393 -7865.8774 8558.4941 -7866.4966 8559.207 C
+-7866.9194 8558.4434 -7867.853 8557.9111 -7868.9434 8557.9111 c
+-7870.0698 8557.9111 -7871.0322 8558.4795 -7871.4312 8559.2852 C
+-7871.9985 8558.624 -7873.6968 8556.751 -7874.6943 8556.751 C
+-7874.8462 8556.6572 -7875.064 8556.4854 V
+-7874.8281 8556.7939 -7874.583 8557.0732 -7874.3481 8557.2686 C
+-7873.8638 8559.6563 -7871.5254 8559.5342 V
+-7871.5449 8559.5889 -7871.5674 8559.6436 -7871.5806 8559.7021 C
+-7874.9238 8559.6924 -7873.937 8562.3174 -7873.2104 8563.6602 C
+-7875.5918 8564.376 -7877.2646 8565.7012 -7877.5239 8567.25 C
+-7878.4473 8567.2998 -7879.6729 8567.3584 -7880.1802 8567.3584 C
+-7880.8726 8567.5313 -7879.835 8565.458 V
+-7879.6626 8563.0391 -7880.8726 8562.8662 V
+-7883.8096 8562.002 -7884.501 8562.6934 V
+-7885.1919 8563.5566 -7886.0562 8562.3467 V
+-7885.1919 8564.0752 -7883.291 8563.5566 V
+-7880.6982 8562.8662 -7881.3906 8564.5938 V
+-7881.9087 8568.0498 -7880.1802 8568.7402 V
+-7878.0342 8569.8545 -7876.2822 8570.0889 V
+-7875.9087 8570.4141 -7875.4639 8570.7109 -7874.958 8570.9766 C
+-7877.5562 8571.0469 -7880.2246 8571.9209 -7881.0752 8574.9561 C
+-7881.5151 8576.2432 -7882.0518 8578.2432 V
+-7883.1025 8578.8252 -7884.3022 8580.0078 -7885.541 8582.2627 C
+-7886.394 8585.4502 -7887.167 8580.7129 V
+-7888.3975 8577.6494 -7889.6504 8577.5381 V
+-7888.4702 8579.2871 -7888.9038 8580.416 V
+-7887.2998 8584.917 -7885.6138 8583.8994 V
+-7884.0986 8583.2197 -7882.688 8580.8154 V
+-7883.0698 8582.4971 -7883.4326 8584.417 -7883.6743 8586.3906 C
+-7884.4888 8586.3975 L
+-7886.3506 8585.4795 -7886.3262 8588.959 V
+-7887.1226 8592.9453 -7886.3594 8595.6826 V
+-7885.647 8598.1504 -7888.1274 8596.9307 V
+-7889.2842 8597.3242 -7889.9839 8596.7881 V
+-7892.3882 8595.4131 -7894 8597.124 V
+-7892.147 8596.8799 -7891.4482 8597.417 V
+-7889.9785 8597.5615 -7889.897 8598.1787 V
+-7886.9561 8598.8555 -7886.188 8598.0771 V
+-7884.417 8597.2139 -7885.1304 8594.3604 V
+-7885.8799 8586.4814 -7884.3198 8588.4053 V
+-7884.1182 8588.4219 -7883.8784 8588.5176 V
+-7884.1519 8592.4326 -7883.8018 8596.3252 -7881.9961 8598.8516 C
+-7885.4536 8591.333 -7880.2974 8576.3037 Y
+-7878.9609 8571.5303 -7873.127 8572.1016 -7870.145 8572.7344 C
+-7870.0718 8574.1299 -7869.8374 8575.9492 -7869.1318 8576.6553 C
+-7868.2134 8574.6963 -7868.2358 8573.0732 V
+-7867.0762 8572.7217 -7860.2817 8570.8447 -7857.4487 8574.3369 C
+-7858.4312 8571.8135 -7860.8262 8571.0186 -7863.2007 8570.9189 C
+-7862.667 8570.6318 -7862.2041 8570.3047 -7861.8257 8569.9502 C
+-7860.041 8569.7861 -7857.7104 8568.5771 Y
+-7855.9814 8567.8857 -7856.5015 8564.4307 Y
+-7857.1919 8562.7021 -7854.5991 8563.3936 Y
+-7852.7002 8563.9111 -7851.835 8562.1836 Y
+-7852.7002 8563.3936 -7853.3906 8562.5303 Y
+f-7847.9082 8596.9521 m
+-7848.6074 8597.4893 -7849.7632 8597.0938 Y
+-7852.2446 8598.3135 -7851.5327 8595.8467 Y
+-7850.769 8593.1104 -7851.564 8589.1221 Y
+-7851.541 8585.6445 -7853.4014 8586.5596 Y
+-7854.0342 8586.5557 L
+-7854.3198 8584.6123 -7854.7046 8582.7549 -7855.0898 8581.1699 C
+-7853.7129 8583.4199 -7852.2778 8584.0635 Y
+-7850.5913 8585.082 -7848.9878 8580.5791 Y
+-7849.4214 8579.4502 -7848.2417 8577.7021 Y
+-7849.4937 8577.8125 -7850.7246 8580.876 Y
+-7851.4976 8585.6152 -7852.3511 8582.4268 Y
+-7853.5776 8580.1904 -7854.769 8579.0098 -7855.814 8578.4229 C
+-7856.2026 8577.0635 -7856.4858 8576.2393 Y
+-7856.7002 8575.4727 -7857.0337 8574.8486 -7857.4487 8574.3369 C
+-7857.3799 8574.5127 -7857.3174 8574.6982 -7857.2632 8574.8916 C
+-7851.3022 8592.2588 -7856.4858 8598.9971 V
+-7863.2246 8608.5869 -7867.3721 8608.5869 V
+-7870.9663 8608.6514 L
+-7875.1138 8608.6514 -7881.853 8599.0615 Y
+-7881.9038 8598.9961 -7881.9463 8598.9219 -7881.9961 8598.8516 C
+-7881.7378 8599.4141 -7881.437 8599.9404 -7881.0752 8600.4092 C
+-7874.3359 8610 -7870.189 8610 V
+-7866.5942 8609.9346 L
+-7862.4482 8609.9346 -7855.709 8600.3447 Y
+-7853.5801 8597.5771 -7853.3306 8593.0176 -7853.7769 8588.6055 C
+-7853.6553 8588.5752 -7853.5698 8588.5684 Y
+-7852.0112 8586.6475 -7852.7598 8594.5244 Y
+-7853.4746 8597.3789 -7851.7026 8598.2402 Y
+-7850.9351 8599.0186 -7847.9946 8598.3428 Y
+-7847.9136 8597.7256 -7846.4434 8597.5811 Y
+-7845.7446 8597.0449 -7843.8921 8597.2881 Y
+-7845.5024 8595.5771 -7847.9082 8596.9521 Y
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 34)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894.0254 8610.0264 m
+-7838.0542 8610.0264 L
+-7838.0542 8548.5342 L
+-7894.0254 8548.5342 L
+-7894.0254 8610.0264 L
+nuu0 O
+0.0745 0.9 0.9019 0.18 k
+0 R
+0 0 0 1 K
+1 J 1 j 0.0518 w-7867.5991 8586.7217 m
+-7867.3594 8597.5215 -7872.8794 8607.8398 v
+-7872.4009 8610 -7870.959 8610 v
+-7871.2002 8606.6406 -7870.2393 8606.1611 v
+-7865.9199 8594.1602 -7866.6382 8586.2402 v
+-7867.5991 8586.7217 l
+b-7867.5991 8586.7217 m
+-7869.2793 8592 -7881.0391 8593.2012 v
+-7885.3594 8593.6807 -7885.5991 8595.1211 v
+-7879.1206 8585.5195 -7878.1602 8585.7607 v
+-7891.3594 8580.001 -7894 8574.7197 v
+-7888.959 8577.6006 -7885.5991 8575.4404 v
+-7877.6802 8575.2012 -7872.6406 8577.3613 v
+-7868.8008 8579.2813 -7876.7202 8563.2012 v
+-7872.8794 8574.9609 -7869.2793 8548.5605 v
+-7868.3198 8553.8408 -7866.8799 8555.2813 v
+-7860.8799 8562.9609 -7861.8398 8565.1211 v
+-7862.3198 8568.9609 -7857.7598 8562.7207 v
+-7858 8572.3213 -7860.4009 8575.6807 v
+-7862.5591 8579.2813 -7856.5591 8577.1211 v
+-7850.5591 8575.2012 -7845.2793 8576.8809 v
+-7839.7598 8578.3203 -7838.0801 8575.4404 v
+-7849.8398 8587.9209 -7855.5991 8587.6807 v
+-7853.9194 8591.2813 l
+-7851.519 8596.0811 -7852 8597.2813 v
+-7867.2681 8587.8828 -7867.5991 8586.7217 v
+b-7867.5991 8586.7217 m
+-7864.959 8568.2402 -7867.5991 8560.5605 v
+-7869.998 8550.001 -7869.2793 8548.5605 v
+S-7866.1602 8575.4404 m
+-7860.1602 8570.6406 -7858.959 8565.3604 v
+S-7866.1602 8574.7197 m
+-7875.0391 8567.041 -7876.7202 8563.2012 v
+S-7838.0801 8575.4404 m
+-7839.2793 8577.6006 -7867.3594 8585.7607 y
+-7872.4009 8580.2422 -7883.9199 8577.8408 v
+-7891.5986 8576.8809 -7894 8574.7197 v
+S-7884.6382 8593.6807 m
+-7873.1191 8584.5615 -7867.3594 8585.7607 y
+-7853.1992 8592 -7852 8597.2813 v
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 36)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7893.8496 8609.9961 m
+-7843.96 8609.9961 L
+-7843.96 8558.9258 L
+-7893.8496 8558.9258 L
+-7893.8496 8609.9961 L
+nu0 O
+0.025 0.1 0.475 0 k
+-7872.1504 8577.9043 m
+-7874.4766 8576.8125 -7876.6914 8576.4434 -7878.373 8576.9238 c
+-7879.0518 8577.1172 -7879.645 8577.4473 -7880.123 8577.9238 c
+-7880.6006 8578.4023 -7880.9297 8578.9951 -7881.123 8579.6729 c
+-7882.0088 8582.7715 -7880.0103 8587.6777 -7875.9233 8591.7666 c
+-7871.834 8595.8535 -7866.9297 8597.8516 -7863.8286 8596.9668 c
+-7863.1519 8596.7715 -7862.5586 8596.4424 -7862.0806 8595.9658 c
+-7861.603 8595.4883 -7861.2754 8594.8955 -7861.082 8594.2168 c
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.582 8585.21 -7864.791 8583.6133 -7866.2793 8582.123 c
+-7868.1504 8580.2539 -7870.1914 8578.8242 -7872.1504 8577.9043 c
+fu0.0035 0.014 0.0665 0 k
+-7871.2183 8576.9727 m
+-7873.8306 8576.0215 -7876.3975 8575.9688 -7878.373 8576.9238 C
+-7876.6914 8576.4434 -7874.4766 8576.8125 -7872.1504 8577.9043 c
+-7871.6191 8578.1543 -7871.0806 8578.4434 -7870.543 8578.7676 C
+-7868.8984 8578.0537 L
+-7869.667 8577.6172 -7870.4434 8577.2539 -7871.2183 8576.9727 c
+f0.015 0.06 0.285 0 k
+-7868.8984 8578.0537 m
+-7870.543 8578.7676 L
+-7869.0962 8579.6348 -7867.6426 8580.7607 -7866.2793 8582.123 c
+-7866.1538 8582.25 -7866.0327 8582.3779 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7866.3706 8579.7236 -7867.6191 8578.7813 -7868.8984 8578.0537 C
+fUu0.039 0.156 0.741 0 k
+-7859.687 8565.4043 m
+-7859.9746 8565.6914 -7871.2183 8576.9727 Y
+-7870.4434 8577.2539 -7869.667 8577.6172 -7868.8984 8578.0537 C
+-7855.4146 8564.5703 L
+-7857.061 8564.0996 -7858.6406 8564.3555 -7859.687 8565.4043 c
+f0.025 0.1 0.475 0 k
+-7855.4146 8564.5703 m
+-7868.8984 8578.0537 L
+-7867.584 8578.8027 -7866.2969 8579.7754 -7865.1143 8580.957 c
+-7865.084 8580.9863 -7865.0586 8581.0156 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7851.5264 8567.1328 -7851.7202 8566.9141 -7851.9302 8566.7012 c
+-7853.0103 8565.623 -7854.2305 8564.9082 -7855.4146 8564.5703 C
+fUu0.0115 0.046 0.2185 0 k
+-7845.9346 8574.3926 m
+-7843.5337 8571.9893 -7843.335 8568.0898 -7845.1382 8564.6973 C
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f0.015 0.06 0.285 0 k
+-7853.5337 8559.5957 m
+-7852.582 8558.9258 L
+-7855.2046 8558.3516 -7857.8306 8558.9141 -7859.6206 8560.7061 c
+-7858.1719 8559.2578 -7855.9082 8558.9307 -7853.5337 8559.5957 C
+f0.0295 0.118 0.5605 0 k
+-7853.5337 8559.5957 m
+-7855.9082 8558.9307 -7858.1719 8559.2578 -7859.6206 8560.7061 c
+-7861.019 8562.1055 -7861.3706 8564.2637 -7860.7954 8566.5469 C
+-7858.8672 8563.5449 -7855.4082 8564.5537 V
+-7853.585 8559.6309 L
+-7853.5337 8559.5957 L
+f*u
+0.048 0.192 0.912 0 k
+1 D
+-7845.9346 8574.3926 m
+-7847.2817 8575.7383 -7849.332 8576.1133 -7851.5234 8575.627 C
+-7861.6714 8585.7734 L
+-7861.7695 8585.5684 -7861.7695 8585.5684 -7861.6714 8585.7734 c
+-7860.2246 8588.8145 -7859.9702 8591.916 -7861.082 8594.2168 C
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.5054 8585.3438 -7864.5918 8583.8848 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7865.1816 8580.8945 -7865.1465 8580.9238 -7865.1143 8580.957 c
+-7865.084 8580.9883 -7865.0566 8581.0176 -7865.0273 8581.0469 c
+-7865.0278 8581.0469 -7865.0278 8581.0469 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f*U
+0.0215 0.086 0.4085 0 k
+0 D
+-7852.582 8558.9258 m
+-7853.5337 8559.5957 L
+-7851.6846 8560.1113 -7849.7656 8561.2285 -7848.1138 8562.8828 c
+-7847.4063 8563.5889 -7846.7998 8564.3418 -7846.2954 8565.1182 C
+-7845.1382 8564.6973 L
+-7845.6553 8563.7246 -7846.3374 8562.793 -7847.1802 8561.9512 c
+-7848.7695 8560.3594 -7850.6758 8559.3428 -7852.582 8558.9258 C
+f0.0205 0.082 0.3895 0 k
+-7846.2954 8565.1182 m
+-7846.7998 8564.3418 -7847.4063 8563.5889 -7848.1138 8562.8828 c
+-7849.7656 8561.2285 -7851.6846 8560.1113 -7853.5337 8559.5957 C
+-7853.585 8559.6309 L
+-7855.4082 8564.5537 L
+-7854.2114 8564.9219 -7852.9878 8565.6436 -7851.9302 8566.7012 c
+-7851.7202 8566.9141 -7851.5264 8567.1328 -7851.3408 8567.3574 C
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+fUu0.445 0.356 0.267 0 k
+-7893.8496 8609.9961 m
+-7871.957 8586.9688 L
+-7872.2007 8586.6494 -7872.5752 8586.6133 -7872.8887 8586.6592 C
+-7877.1802 8591.2891 -7888.3145 8603.4561 -7892.7266 8608.2793 C
+-7893.5649 8609.3516 -7894 8609.9932 -7893.8496 8609.9961 C
+f0.15 0.12 0.09 0 k
+-7893.834 8609.9961 m
+-7892.6606 8609.7031 -7871.6934 8588.0029 Y
+-7871.6934 8587.502 -7871.7993 8587.1758 -7871.957 8586.9688 C
+-7893.8496 8609.9961 L
+-7893.8442 8609.9961 -7893.8418 8610 -7893.834 8609.9961 c
+f0.2 0.16 0.12 0 k
+-7892.7266 8608.2793 m
+-7888.3145 8603.4561 -7877.1802 8591.2891 -7872.8887 8586.6592 C
+-7873.2002 8586.7041 -7873.4526 8586.8301 Y
+-7874.603 8587.1328 -7888.5742 8602.9619 -7892.7266 8608.2793 C
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 37)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7892.9502 8609.2324 m
+-7843.0391 8609.2324 L
+-7843.0391 8545.1152 L
+-7892.9502 8545.1152 L
+-7892.9502 8609.2324 L
+nu0 O
+0 0 0 1 k
+0 R
+0 0 0 1 K
+0 w-7843.2358 8545.1152 m
+-7843.6064 8545.248 -7843.9858 8545.2832 -7844.3833 8545.2031 c
+-7844.4863 8545.168 l
+-7844.5254 8545.1602 -7844.5703 8545.1787 -7844.6025 8545.1992 c
+-7844.9434 8545.3926 l
+-7848.7129 8547.2959 -7852.0962 8549.8965 -7854.5 8553.4473 c
+-7855.9634 8555.5918 -7857.123 8557.8789 -7858.7993 8559.8564 c
+-7859.1729 8560.209 -7859.1758 8560.7725 -7858.834 8561.1309 c
+-7858.4951 8561.501 -7857.918 8561.5078 -7857.561 8561.165 c
+-7857.4038 8561.21 l
+-7857.2642 8561.1289 -7857.0742 8561.0703 -7857.0234 8560.957 c
+-7855.853 8558.2031 -7855.1895 8555.5137 -7853.4336 8553.1387 c
+-7851.1719 8550.0947 -7848.1777 8547.9941 -7845.0298 8546.0234 c
+-7844.3672 8545.6055 L
+-7844.4966 8545.6348 L
+-7843.7695 8545.6426 l
+-7843.791 8545.6113 -7843.8008 8545.5957 -7843.8223 8545.5645 C
+-7843.6064 8545.5234 -7843.377 8545.4746 -7843.1626 8545.4336 c
+-7843.0762 8545.4238 -7843.0186 8545.3389 -7843.0391 8545.2383 c
+-7843.0503 8545.1523 -7843.1382 8545.1084 -7843.2358 8545.1152 c
+-7843.2358 8545.1152 l
+b-7859.2222 8558.9951 m
+-7859.5742 8558.8066 -7859.9658 8558.6719 -7860.248 8558.3887 c
+-7866.4521 8552.1719 -7876.6802 8551.2734 -7884.0488 8557.6855 C
+-7884.1582 8557.7813 -7884.1582 8557.957 -7884.063 8558.0645 C
+-7881.0527 8556.9434 -7872.8838 8558.375 -7869.3223 8561.4121 C
+-7869.2534 8561.4668 -7869.1465 8561.4531 -7869.1055 8561.3711 C
+-7869.0503 8561.3047 -7869.0664 8561.1953 -7869.1328 8561.1563 C
+-7872.5625 8558.0859 -7877.0674 8556.29 -7881.6729 8556.748 C
+-7878.8535 8555.1855 -7875.6313 8554.4941 -7872.3984 8554.6885 c
+-7867.7144 8554.9717 -7863.4634 8557.1191 -7859.3711 8559.2793 c
+-7859.291 8559.3193 -7859.1978 8559.293 -7859.1553 8559.2109 C
+-7859.1016 8559.1309 -7859.1426 8559.0352 -7859.2222 8558.9951 c
+b-7868.647 8560.3359 m
+-7870.2266 8564.3613 -7872.3911 8568.3203 -7875.8018 8571.0762 c
+-7875.9648 8571.2119 -7875.9946 8571.4492 -7875.8711 8571.6055 c
+-7875.7344 8571.7676 -7875.5049 8571.7793 -7875.3481 8571.6563 c
+-7871.123 8569.5967 -7868.1904 8565.1309 -7868.1626 8560.4014 c
+-7868.1626 8560.4014 l
+-7868.1328 8560.2676 -7868.2354 8560.1348 -7868.3633 8560.1221 c
+-7868.5039 8560.1055 -7868.6318 8560.1973 -7868.647 8560.3359 c
+-7868.647 8560.3359 l
+b-7862.9414 8565.0176 m
+-7863.042 8565.1816 -7863.1152 8565.3838 -7863.2617 8565.4824 c
+-7866.0806 8567.3906 -7868.9785 8568.6309 -7871.8848 8570.1328 c
+-7872.0503 8570.209 -7872.1118 8570.418 -7872.0313 8570.5703 c
+-7871.9512 8570.7227 -7871.7559 8570.7793 -7871.5898 8570.7041 c
+-7868.439 8569.3232 -7864.313 8568.5 -7862.6729 8565.1797 c
+-7862.6289 8565.1113 -7862.6455 8565.0146 -7862.7266 8564.9648 c
+-7862.7959 8564.9199 -7862.897 8564.9492 -7862.9414 8565.0176 c
+-7862.9414 8565.0176 l
+b-7862.6602 8565.918 m
+-7862.4438 8566.4297 -7862.1431 8566.8896 -7862.0503 8567.4355 c
+-7861.2183 8572.2773 -7861.1152 8577.042 -7862.248 8581.6875 c
+-7862.248 8581.6875 l
+-7862.3418 8581.9531 -7862.2114 8582.2441 -7861.9438 8582.3389 c
+-7861.6777 8582.4336 -7861.3882 8582.3125 -7861.2935 8582.0479 c
+-7859.293 8576.8115 -7859.897 8570.7373 -7862.3711 8565.7832 c
+-7862.4063 8565.7002 -7862.498 8565.6689 -7862.582 8565.6914 c
+-7862.6641 8565.7275 -7862.6978 8565.835 -7862.6602 8565.918 c
+-7862.6602 8565.918 l
+b-7861.5352 8581.5938 m
+-7858.8984 8579.2275 -7856.6816 8576.252 -7855.853 8572.7363 c
+-7855.853 8572.7363 l
+-7855.7246 8572.1816 -7856.0742 8571.623 -7856.6416 8571.4902 c
+-7857.1992 8571.375 -7857.7578 8571.7246 -7857.8862 8572.2793 c
+-7858.5649 8575.5313 -7859.8711 8578.6729 -7861.7954 8581.3867 c
+-7861.7954 8581.3867 l
+-7861.8462 8581.4551 -7861.834 8581.5576 -7861.7695 8581.6201 c
+-7861.6992 8581.6699 -7861.5977 8581.6582 -7861.5352 8581.5938 c
+-7861.5352 8581.5938 l
+b-7846.3711 8574.1826 m
+-7847.7114 8569.8301 -7850.2598 8566.0693 -7853.689 8563.1533 C
+-7853.729 8563.0723 -7853.8242 8563.0322 -7853.9038 8563.0859 C
+-7853.9863 8563.127 -7854.0122 8563.2207 -7853.9722 8563.3018 C
+-7853.957 8563.7891 -7853.7144 8564.2334 -7853.4458 8564.5313 c
+-7848.4063 8570.1621 -7844.9902 8578.7197 -7847.3433 8585.9551 C
+-7847.0762 8580.4512 -7848.7241 8574.3008 -7852.1362 8569.6738 c
+-7853.1606 8568.2695 -7854.7422 8568.1211 -7856.3081 8568.2031 C
+-7856.4023 8568.1895 -7856.4834 8568.2432 -7856.4961 8568.3369 c
+-7856.5098 8568.4189 -7856.4551 8568.5137 -7856.3623 8568.5254 C
+-7853.1479 8569.7695 -7851.4878 8573.2246 -7850.084 8576.1943 c
+-7848.415 8579.7441 -7847.7017 8583.6387 -7848.0054 8587.5 C
+-7848.0454 8587.6777 -7848.1138 8589.3975 -7847.9775 8589.4102 C
+-7847.8306 8589.4395 -7847.709 8589.3438 -7847.6802 8589.1943 C
+-7847.645 8589.0449 -7844.6426 8579.7988 -7846.3711 8574.1826 c
+b-7854.4863 8561.4912 m
+-7853.3945 8557.6211 -7851.1094 8554.251 -7848.4824 8551.2383 c
+-7848.3306 8551.1045 -7848.3145 8550.8867 -7848.4502 8550.7354 c
+-7848.5752 8550.6006 -7848.8047 8550.582 -7848.957 8550.7178 c
+-7852.3306 8553.332 -7853.4487 8557.541 -7854.7954 8561.375 c
+-7854.7954 8561.375 l
+-7854.8262 8561.4648 -7854.7754 8561.5586 -7854.6982 8561.5869 c
+-7854.6094 8561.6191 -7854.5166 8561.5684 -7854.4863 8561.4912 c
+-7854.4863 8561.4912 l
+b-7848.5313 8586.1094 m
+-7848.5991 8586.0566 -7848.707 8586.083 -7848.748 8586.1504 C
+-7848.9634 8586.4746 -7850.6914 8588.5195 -7851.3926 8589.1406 c
+-7856.1719 8593.3945 -7859.5137 8597.9609 -7867.5391 8601.7227 c
+-7874.4512 8604.9639 -7877.1113 8607.5957 -7884.3862 8605.8262 c
+-7887.687 8605.0293 -7889.0313 8604.5313 -7890.4351 8599.4551 C
+-7891.9473 8593.2988 -7890.8672 8595.7832 -7891.084 8588.4385 c
+-7891.2222 8583.6973 -7894 8572.4551 -7881.5254 8558.2598 C
+-7881.4199 8558.1484 -7881.4336 8557.9961 -7881.5337 8557.9072 C
+-7881.6328 8557.8027 -7881.7959 8557.8164 -7881.8862 8557.916 C
+-7887.5786 8562.7168 -7891.0234 8569.6582 -7892.3145 8576.9424 c
+-7893.2871 8582.4668 -7892.9199 8587.25 -7892.666 8593.6367 c
+-7892.5688 8596.0938 -7893.6855 8603.0723 -7888.9102 8607.0625 c
+-7885.3926 8610 -7880.3911 8609.5469 -7876.3545 8608.1563 c
+-7870.6992 8606.2119 -7865.9727 8603.1465 -7860.8711 8599.6094 c
+-7857.2656 8597.125 -7849.2881 8587.2852 -7848.4785 8586.3262 C
+-7848.4351 8586.2588 -7848.4502 8586.1504 -7848.5313 8586.1094 C
+b-7883.0503 8573.3057 m
+-7882.168 8572.5029 -7881.7017 8573.8457 -7881.4297 8574.6016 c
+-7881.1626 8575.3574 -7880.189 8575.25 -7880.5127 8575.5732 c
+-7880.8369 8575.8975 -7880.8369 8575.9521 -7881.3232 8575.5195 c
+-7881.8086 8575.0879 -7881.8086 8575.7363 -7882.5649 8575.25 c
+-7883.3198 8574.7627 -7883.645 8573.8457 -7883.0503 8573.3057 c
+b-7875.6519 8577.9492 m
+-7875.3657 8577.5918 -7874.6802 8577.5723 -7874.4648 8577.8945 c
+-7874.25 8578.2197 -7873.3306 8578.2734 -7873.4937 8578.5967 c
+-7873.6543 8578.9219 -7873.6016 8579.1387 -7874.0874 8578.9219 c
+-7874.5737 8578.7051 -7874.4121 8579.2998 -7874.897 8579.084 c
+-7875.3833 8578.8672 -7875.8687 8578.2197 -7875.6519 8577.9492 c
+b-7867.6074 8583.0791 m
+-7867.1206 8582.7559 -7865.8794 8583.5117 -7866.4727 8583.5117 c
+-7867.0674 8583.5117 -7866.311 8584.2676 -7866.8521 8584.4834 c
+-7867.3906 8584.6992 -7867.2832 8584.4297 -7867.6074 8584.6445 c
+-7867.9297 8584.8613 -7868.3633 8585.2393 -7868.5239 8584.4297 c
+-7868.6855 8583.6191 -7868.3633 8583.6191 -7867.9849 8583.3496 c
+-7867.6074 8583.0791 -7867.6074 8583.0791 y
+b-7882.2402 8583.3496 m
+-7881.1074 8583.2422 -7881.8633 8583.998 -7881.269 8584.4834 c
+-7880.6738 8584.9697 -7879.918 8585.6172 -7880.729 8585.4004 c
+-7881.5391 8585.1855 -7882.9961 8585.6719 -7882.9434 8584.5381 c
+-7882.8887 8583.4033 -7882.6328 8583.3867 -7882.2402 8583.3496 c
+b-7876.5703 8591.6113 m
+-7876.1016 8591.3438 -7876.6802 8591.7197 -7876.0303 8591.6113 c
+-7875.3833 8591.5039 -7874.7886 8591.6113 -7875.2207 8591.8281 c
+-7875.6519 8592.0439 -7876.3008 8592.1523 -7876.4634 8591.9893 c
+-7876.625 8591.8281 -7876.9473 8591.8281 -7876.5703 8591.6113 c
+b-7867.0674 8591.1797 m
+-7867.4785 8590.1797 -7866.0962 8590.4238 -7865.4473 8590.7461 c
+-7864.7998 8591.0723 -7863.8262 8590.4775 -7864.4209 8590.9102 c
+-7865.0137 8591.3418 -7864.7998 8590.9102 -7865.3926 8591.2334 c
+-7865.9873 8591.5566 -7866.6895 8592.0977 -7867.0674 8591.1797 c
+b-7882.6738 8597.0664 m
+-7882.7222 8596.0752 -7881.8086 8596.957 -7881.269 8597.0117 c
+-7880.729 8597.0664 -7880.0801 8597.0664 -7880.2432 8597.2813 c
+-7880.4038 8597.498 -7880.459 8597.498 -7881.1626 8597.7129 c
+-7881.8633 8597.9297 -7882.6191 8598.1445 -7882.6738 8597.0664 c
+b-7883.1582 8591.6113 m
+-7884.0664 8591.9746 -7884.293 8591.8809 -7884.5625 8592.2051 c
+-7884.834 8592.5293 -7885.1558 8593.2314 -7885.5352 8592.0977 c
+-7885.9121 8590.9629 -7885.4282 8589.7764 -7885.0479 8589.9375 c
+-7884.6714 8590.0996 -7884.293 8590.7461 -7883.8618 8590.9629 c
+-7883.4297 8591.1797 -7882.6191 8591.3945 -7883.1582 8591.6113 c
+bUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 41)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7813 8610 L
+-7813 8505 L
+-7894 8505 L
+-7894 8610 L
+nuuu0 O
+0 0 0 1 k
+-7875.8057 8522.4258 m
+-7876.0742 8520.6621 -7877.1602 8519.291 -7878.5239 8519.3965 c
+-7879.8862 8519.502 -7880.707 8521.0234 -7880.7432 8522.8066 c
+-7880.748 8523.0693 -7880.6743 8524.2441 -7880.6304 8524.4775 C
+-7880.6382 8524.582 -7880.6191 8524.6738 -7880.6104 8524.7803 c
+-7880.5142 8526.0254 -7879.3574 8527.3604 -7877.9414 8527.25 c
+-7876.5249 8527.1406 -7875.4897 8525.8613 -7875.6367 8524.4727 c
+-7875.644 8524.4072 -7875.6958 8523.626 -7875.707 8523.5625 C
+-7875.6816 8523.2852 -7875.7598 8522.7256 -7875.8057 8522.4258 c
+f-7886.2646 8531.7334 m
+-7886.9946 8539.916 -7881.5015 8539.1191 v
+-7878.3682 8538.0186 -7879.4414 8535.1211 v
+-7879.6426 8533.752 -7881.7847 8532.498 v
+-7882.146 8532.25 -7882.7632 8531.1016 v
+-7883.1294 8529.5977 -7884.5186 8529.2979 v
+-7886.0762 8529.251 -7886.2646 8531.7334 v
+f-7860.7646 8540.4971 m
+F-7860.0762 8538.3408 m
+-7860.7847 8537.1934 -7863.8848 8537.6279 Y
+-7864.811 8537.6885 -7865.3799 8537.1113 Y
+-7867.8394 8533.0918 -7871.0386 8533.8857 -7871.4082 8533.9932 C
+-7871.4097 8533.9863 L
+-7874.999 8534.6045 -7875.2666 8539.6035 V
+-7875.4912 8540.3828 -7876.335 8540.7695 V
+-7879.2695 8541.8613 -7879.3481 8543.208 V
+-7879.8999 8545.1152 -7877.6006 8545.7422 V
+-7875.6792 8546.2568 -7873.7886 8543.8945 V
+-7872.6113 8542.6797 -7869.5762 8541.9395 V
+-7869.5728 8541.9531 L
+-7866.3594 8541.0459 -7864.6392 8541.5889 Y
+-7861.8521 8542.7676 -7860.4063 8541.4014 Y
+-7858.6826 8539.7559 -7860.0762 8538.3408 Y
+f-7873.9834 8521.8789 m
+-7874.5854 8520.2002 -7874.2822 8518.4775 -7873.0327 8517.9229 c
+-7871.7842 8517.3672 -7870.3384 8518.3164 -7869.4585 8519.8672 c
+-7869.3286 8520.0957 -7868.8359 8521.165 -7868.7632 8521.3906 C
+-7868.7065 8521.4785 -7868.6792 8521.5684 -7868.6362 8521.667 c
+-7868.1289 8522.8086 -7868.5122 8524.5303 -7869.8105 8525.1074 c
+-7871.1089 8525.6855 -7872.6279 8525.0527 -7873.1582 8523.7617 c
+-7873.1831 8523.7002 -7873.5078 8522.9883 -7873.5298 8522.9268 C
+-7873.6831 8522.6963 -7873.8809 8522.166 -7873.9834 8521.8789 c
+f-7859.7129 8524.9316 m
+-7855.1802 8531.7822 -7860.3911 8533.6943 v
+-7863.6714 8534.2168 -7864.103 8531.1572 v
+-7864.5786 8529.8564 -7863.29 8527.7354 v
+-7863.0903 8527.3447 -7863.0938 8526.04 v
+-7863.4858 8524.5449 -7862.4082 8523.6182 v
+-7861.0591 8522.8359 -7859.7129 8524.9316 v
+fUu-7834.7358 8574.1074 m
+-7834.3687 8572.3623 -7834.9048 8570.6963 -7836.2183 8570.3164 c
+-7837.5322 8569.9375 -7838.8345 8571.0752 -7839.4937 8572.7324 c
+-7839.5903 8572.9775 -7839.9326 8574.1025 -7839.9746 8574.3369 C
+-7840.0176 8574.4326 -7840.0322 8574.5244 -7840.0625 8574.6279 c
+-7840.4087 8575.8271 -7839.7935 8577.4805 -7838.4282 8577.875 c
+-7837.063 8578.2695 -7835.645 8577.4365 -7835.2969 8576.085 c
+-7835.2793 8576.0205 -7835.0552 8575.2705 -7835.0425 8575.207 C
+-7834.9214 8574.9551 -7834.7983 8574.4053 -7834.7358 8574.1074 c
+f-7848.2705 8578.6172 m
+-7851.8242 8586.0244 -7846.3999 8587.2061 v
+-7843.0801 8587.2754 -7843.0688 8584.1846 v
+-7842.7778 8582.8311 -7844.3433 8580.9072 v
+-7844.5942 8580.5459 -7844.7695 8579.2539 v
+-7844.5854 8577.7188 -7845.7793 8576.9492 v
+-7847.2222 8576.3594 -7848.2705 8578.6172 v
+f-7827.4648 8595.7695 m
+F-7826.063 8593.9912 m
+-7826.3247 8592.6689 -7829.3799 8591.9883 Y
+-7830.27 8591.7197 -7830.5986 8590.9795 Y
+-7831.4922 8586.3535 -7834.7666 8585.9746 -7835.1494 8585.9453 C
+-7835.1494 8585.9395 L
+-7838.7271 8585.2588 -7840.731 8589.8467 V
+-7841.2153 8590.4961 -7842.1416 8590.5625 V
+-7845.272 8590.5557 -7845.8169 8591.7891 V
+-7847.0039 8593.3809 -7845.0713 8594.7764 V
+-7843.4526 8595.9316 -7840.853 8594.3818 V
+-7839.3242 8593.6582 -7836.2222 8594.0293 V
+-7836.2231 8594.042 L
+-7832.896 8594.3213 -7831.4766 8595.4326 Y
+-7829.2793 8597.5146 -7827.4463 8596.7432 Y
+-7825.2554 8595.8057 -7826.063 8593.9912 Y
+f-7832.8374 8574.2354 m
+-7832.813 8572.4512 -7831.9258 8570.9453 -7830.5601 8570.8633 c
+-7829.1943 8570.7803 -7828.1743 8572.1768 -7827.895 8573.9385 c
+-7827.854 8574.1973 -7827.7666 8575.3711 -7827.7778 8575.6094 C
+-7827.7559 8575.7109 -7827.7617 8575.8037 -7827.7559 8575.9121 c
+-7827.6807 8577.1592 -7828.644 8578.6367 -7830.0625 8578.7217 c
+-7831.4814 8578.8066 -7832.6826 8577.6826 -7832.7246 8576.2871 c
+-7832.7271 8576.2217 -7832.7822 8575.4404 -7832.7798 8575.375 C
+-7832.8433 8575.1045 -7832.8423 8574.54 -7832.8374 8574.2354 c
+f-7821.0186 8581.5625 m
+-7819.1777 8589.5684 -7824.7271 8589.5303 v
+-7827.9834 8588.8691 -7827.3154 8585.8516 v
+-7827.3032 8584.4668 -7825.353 8582.9326 v
+-7825.0278 8582.6377 -7824.5742 8581.415 v
+-7824.417 8579.876 -7823.083 8579.3877 v
+-7821.5454 8579.1279 -7821.0186 8581.5625 v
+fUU1 Ap
+-7894 8610 m
+-7894 8505 L
+-7813 8505 L
+-7813 8610 L
+-7894 8610 L
+nUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 42)
+0 A
+u0 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 45)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8567.918 m
+-7895 8611 L
+-7808.2217 8611 L
+-7808.2217 8567.918 L
+-7895 8567.918 L
+nuu0 O
+0 0 0 1 k
+-7835.2217 8597.2363 m
+-7835.2217 8605.0742 L
+-7823.2217 8598.1445 L
+-7811.2217 8591.2168 L
+-7823.2217 8584.2891 L
+-7835.2217 8577.3613 L
+-7835.2217 8585.4824 L
+-7893.9351 8571.7168 L
+-7880.9878 8590.8027 L
+-7895 8611 L
+-7835.2217 8597.2363 L
+f0 1 1 0.1 k
+0 R
+0 0 0 1 K
+-7833.2217 8594.2363 m
+-7833.2217 8602.0742 L
+-7821.2217 8595.1445 L
+-7809.2217 8588.2168 L
+-7821.2217 8581.2891 L
+-7833.2217 8574.3613 L
+-7833.2217 8582.4824 L
+-7891.9351 8568.7168 L
+-7877.2754 8588.3594 L
+-7891.9351 8608 L
+-7833.2217 8594.2363 L
+bUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 50)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7766.877 8610 L
+-7766.877 8562.415 L
+-7894 8562.415 L
+-7894 8610 L
+nu*u
+0 O
+0.9529 0.949 0.1961 0.0745 k
+-7867.793 8594.417 m
+-7867.8232 8594.2676 L
+-7869.9849 8588.3643 -7870.9438 8585.6377 -7871.2754 8584.2891 c
+-7871.3657 8584.2891 L
+-7871.6953 8585.6074 -7872.7754 8588.335 -7874.9673 8594.2676 c
+-7874.9966 8594.417 L
+-7867.793 8594.417 l
+f1 D
+-7878.1182 8602.9678 m
+-7879.6191 8606.5371 -7880.3994 8608.709 -7878.1182 8608.917 c
+-7878.1182 8609.9678 L
+-7880.6992 8609.9375 -7883.5806 8609.917 -7886.3418 8609.917 c
+-7890.0649 8609.917 -7892.5273 8609.9375 -7894 8609.9678 c
+-7894 8608.917 L
+-7892.1064 8608.709 -7891.0542 8606.5674 -7883.5513 8589.5029 c
+-7871.6953 8562.415 L
+-7869.8638 8562.415 L
+-7858.1582 8589.5029 L
+-7850.8047 8606.5078 -7849.7246 8608.709 -7847.8887 8608.917 c
+-7847.8887 8609.9678 L
+-7849.5142 8609.9375 -7851.916 8609.917 -7855.5767 8609.917 c
+-7858.5488 8609.917 -7861.6694 8609.9375 -7864.7026 8609.9678 c
+-7864.7026 8608.917 L
+-7862.481 8608.709 -7863.3218 8606.5078 -7864.7617 8602.9678 C
+-7878.1182 8602.9678 l
+f*U
+*u
+0 D
+-7823.0762 8578.0811 m
+-7823.0762 8574.4717 -7825.3535 8572.0947 -7829.1294 8572.0947 c
+-7830.2383 8572.0947 -7831.0767 8572.2158 -7831.5273 8572.2451 c
+-7831.5273 8584.5479 L
+-7830.8672 8584.6084 -7830.208 8584.6084 -7829.729 8584.6084 c
+-7828.2002 8584.6084 -7826.7026 8584.127 -7825.6841 8583.4053 c
+-7824.3945 8582.5332 -7823.0762 8580.7881 -7823.0762 8578.1416 C
+-7823.0762 8578.0811 l
+f1 D
+-7842.0806 8582.3926 m
+-7842.0806 8566.6445 -7842.0806 8564.4287 -7844.542 8564.2783 c
+-7844.542 8563.3184 L
+-7843.042 8563.2588 -7840.3174 8563.1992 -7837.5664 8563.1689 c
+-7835.6538 8563.1084 -7832.3945 8563.0186 -7830.1479 8562.9775 c
+-7826.582 8562.9775 -7823.585 8563.4258 -7821.0049 8564.2627 c
+-7816.353 8565.8477 -7811.9702 8569.8525 -7811.9702 8577.6602 c
+-7811.9702 8582.7432 -7814.4014 8586.3193 -7816.5034 8588.0605 c
+-7817.583 8589.0215 -7818.8135 8589.832 -7819.7744 8590.3125 c
+-7819.7744 8590.4629 L
+-7817.5234 8593.4912 -7815.6025 8596.0625 -7809.3906 8604.6426 c
+-7807.5 8607.0645 -7805.9102 8608.7383 -7804.7402 8608.9775 c
+-7804.7402 8610 L
+-7806.6602 8610 -7809 8609.8848 -7811.1294 8609.8848 c
+-7813.3511 8609.8848 -7814.8521 8610 -7816.4424 8610 c
+-7817.6729 8610 -7818.7241 8609.9404 -7819.5039 8609.2725 c
+-7823.0151 8603.8477 -7826.9121 8597.7559 -7830.1182 8592.7139 c
+-7830.5078 8592.7139 -7830.957 8592.7139 -7831.5273 8592.7139 c
+-7831.5273 8595.2852 L
+-7831.5273 8606.5264 -7831.437 8608.7686 -7829.1895 8608.9775 c
+-7829.1895 8609.9697 L
+-7830.6279 8609.9404 -7833.9194 8609.915 -7836.6992 8609.915 c
+-7839.9287 8609.915 -7842.8921 8609.9404 -7844.5122 8609.9697 c
+-7844.5122 8608.9775 L
+-7842.0518 8608.7686 -7842.0806 8606.5264 -7842.0806 8589.5918 C
+-7842.0806 8582.3926 l
+f*U
+*u
+0 D
+-7791.4561 8589.5928 m
+-7791.4561 8606.4941 -7791.4561 8608.6484 -7794.2832 8608.9775 C
+-7794.2832 8609.9697 l
+-7792.3887 8609.9404 -7789.0542 8609.915 -7785.7822 8609.915 c
+-7782.6294 8609.915 -7779.5688 8609.9404 -7777.2881 8609.9697 C
+-7777.2881 8608.9775 l
+-7780.2578 8608.9775 -7780.2881 8606.5244 -7780.2881 8589.5928 C
+-7780.2881 8572.1514 L
+-7772.8193 8572.1514 l
+-7769.999 8572.1514 -7768.5298 8572.96 -7767.8994 8575.2627 C
+-7766.9072 8575.2627 l
+-7766.9072 8570.4697 -7766.877 8566.415 -7766.877 8563.1709 c
+-7771.3486 8563.2012 -7776.748 8563.2314 -7782.0601 8563.2314 C
+-7789.7446 8563.2314 l
+-7794.5537 8563.2314 -7799.9966 8563.2012 -7804.9614 8563.1709 c
+-7804.9614 8566.3848 -7804.9326 8570.4697 -7804.9326 8575.2627 C
+-7803.9072 8575.2627 l
+-7803.3657 8573.1094 -7801.771 8572.1514 -7798.9438 8572.1514 C
+-7791.4561 8572.1514 l
+-7791.4561 8589.5928 L
+f*U
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 62)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8593.9043 m
+-7856.7305 8585.3408 L
+-7895 8585.3408 L
+-7895 8593.9043 L
+-7856.7305 8593.9043 L
+f-7856.7305 8597.0967 m
+-7856.7305 8596.4229 L
+-7895 8596.4229 L
+-7895 8597.0967 L
+-7856.7305 8597.0967 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 63)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8589.8262 m
+-7856.7305 8598.3896 L
+-7869.3408 8598.3896 L
+-7869.3408 8611 L
+-7877.9038 8611 L
+-7877.9063 8589.8262 L
+-7877.9038 8589.8262 L
+-7877.9038 8589.8252 L
+-7856.7305 8589.8262 L
+f-7856.7305 8587.3076 m
+-7880.4233 8587.3076 L
+-7880.4233 8611 L
+-7881.0967 8611 L
+-7881.0977 8586.6328 L
+-7856.7305 8586.6328 L
+-7856.7305 8587.3076 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 64)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8610.999 m
+-7895 8572.7285 L
+-7856.7305 8572.7285 L
+-7856.7305 8610.999 L
+-7895 8610.999 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8585.3389 m
+-7882.3896 8585.3389 L
+-7882.3896 8610.999 L
+-7873.8262 8611 L
+-7873.8262 8593.9033 L
+-7856.7305 8593.9033 L
+-7856.7305 8585.3389 L
+f-7856.7305 8596.4219 m
+-7871.3081 8596.4219 L
+-7871.3081 8611 L
+-7870.6338 8611 L
+-7870.6338 8597.0957 L
+-7856.7305 8597.0957 L
+-7856.7305 8596.4219 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 65)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.0625 8583.4609 m
+-7894.6025 8583.4609 L
+-7894.6025 8611 L
+-7867.0625 8611 L
+-7867.0625 8583.4609 L
+n0 O
+0 0.55 1 0.12 k
+-7866.8418 8596.7002 m
+-7895 8596.7002 L
+-7895 8597.8252 L
+-7866.8418 8597.8252 L
+-7866.8418 8596.7002 L
+fu0 0.55 1 0.3 k
+-7893.9814 8584.5215 m
+-7894.4102 8586.5254 -7893.1865 8590.1514 -7890.0874 8593.251 c
+-7886.9878 8596.3496 -7883.3457 8597.6602 -7881.3594 8597.1455 C
+-7881.3594 8597.1455 L
+-7880.875 8595.1895 -7882.1519 8591.5117 -7885.25 8588.4141 c
+-7888.3457 8585.3184 -7892.0122 8584.1064 -7893.9814 8584.5215 C
+f0 0.39 0.7 0.12 k
+-7893.9814 8609.9912 m
+-7894.4102 8607.9883 -7893.1865 8604.3613 -7890.0874 8601.2617 c
+-7886.9878 8598.1641 -7883.3457 8596.8535 -7881.3594 8597.3672 C
+-7881.3594 8597.3672 L
+-7880.875 8599.3242 -7882.1519 8603.001 -7885.25 8606.0996 c
+-7888.3457 8609.1953 -7892.0122 8610.4063 -7893.9814 8609.9912 C
+fUu0 0.55 1 0.3 k
+-7880.1782 8609.9912 m
+-7880.6074 8607.9883 -7879.3838 8604.3613 -7876.2842 8601.2617 c
+-7873.1855 8598.1641 -7869.543 8596.8535 -7867.5576 8597.3672 C
+-7867.5566 8597.3672 L
+-7867.0718 8599.3242 -7868.3496 8603.001 -7871.4473 8606.0996 c
+-7874.543 8609.1953 -7878.209 8610.4063 -7880.1782 8609.9912 C
+f0 0.39 0.7 0.12 k
+-7880.1782 8584.5215 m
+-7880.6074 8586.5254 -7879.3838 8590.1514 -7876.2842 8593.251 c
+-7873.1855 8596.3496 -7869.543 8597.6602 -7867.5576 8597.1455 C
+-7867.5566 8597.1455 L
+-7867.0718 8595.1895 -7868.3496 8591.5117 -7871.4473 8588.4141 c
+-7874.543 8585.3184 -7878.209 8584.1064 -7880.1782 8584.5215 C
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 67)
+0 A
+u0 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 69)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.4609 m
+-7895 8583.4609 L
+-7895 8611 L
+-7867.4609 8611 L
+-7867.4609 8583.4609 L
+n0 O
+0 0.55 1 0.3 k
+-7885.4233 8597.252 m
+-7884.3096 8595.5313 -7880.8809 8593.833 -7876.4966 8593.833 c
+-7872.1152 8593.833 -7868.6138 8595.4824 -7867.5718 8597.25 C
+-7867.5718 8597.25 L
+-7868.6138 8598.9766 -7872.1152 8600.6738 -7876.4966 8600.6738 c
+-7880.875 8600.6738 -7884.3242 8598.9375 -7885.4233 8597.252 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 83)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8609.9355 m
+-7680.4009 8609.9355 L
+-7680.4009 8602.1348 L
+-7894 8602.1348 L
+-7894 8609.9355 L
+n0 O
+0 0 0 1 k
+-7894 8606.0352 m
+-7883.9858 8608.5273 -7877.187 8609.875 -7865.2007 8609.9355 c
+-7852.2183 8610 -7787.2002 8609.9355 y
+-7722.1816 8610 -7709.2002 8609.9355 v
+-7697.2129 8609.875 -7690.415 8608.5273 -7680.4009 8606.0352 C
+-7690.415 8603.543 -7697.2129 8602.1953 -7709.2002 8602.1348 c
+-7722.1816 8602.0693 -7787.2002 8602.1348 y
+-7852.2183 8602.0693 -7865.2007 8602.1348 v
+-7877.187 8602.1953 -7883.9858 8603.543 -7894 8606.0352 C
+fU%AI8_EndBrushPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+4 Bn
+%AI5_BeginGradient: (Black, White)
+(Black, White) 0 2 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0 %_Br
+[
+0 0 50 100 %_BS
+%_0 0 50 100 Bs
+1 0 50 0 %_BS
+%_1 0 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Chrome)
+(Chrome) 0 6 Bd
+[
+0
+<
+464646454545444444444343434342424241414141404040403F3F3F3E3E3E3E3D3D3D3C3C3C3C3B
+3B3B3B3A3A3A39393939383838383737373636363635353535343434333333333232323131313130
+3030302F2F2F2E2E2E2E2D2D2D2D2C2C2C2B2B2B2B2A2A2A2A292929282828282727272626262625
+2525252424242323232322222222212121202020201F1F1F1F1E1E1E1D1D1D1D1C1C1C1B1B1B1B1A
+1A1A1A1919191818181817171717161616151515151414141413131312121212111111101010100F
+0F0F0F0E0E0E0D0D0D0D0C0C0C0C0B0B0B0A0A0A0A09090909080808070707070606060505050504
+04040403030302020202010101010000
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+1F1E1E1E1E1E1E1E1E1E1D1D1D1D1D1D1D1D1C1C1C1C1C1C1C1C1B1B1B1B1B1B1B1B1B1A1A1A1A1A
+1A1A1A19191919191919191818181818181818181717171717171717161616161616161615151515
+15151515151414141414141414131313131313131312121212121212121211111111111111111010
+1010101010100F0F0F0F0F0F0F0F0F0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0C0C0C0C0C0C0C0C0C
+0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A090909090909090909080808080808080807070707070707
+07060606060606060606050505050505050504040404040404040303030303030303030202020202
+02020201010101010101010000000000
+>
+1 %_Br
+0
+0.275
+1
+<
+6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544
+434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F
+>
+1 %_Br
+0
+<
+00000101010102020202030303040404040505050606060607070707080808090909090A0A0A0A0B
+0B0B0C0C0C0C0D0D0D0D0E0E0E0F0F0F0F1010101111111112121212131313141414141515151516
+161617171717181818181919191A1A1A1A1B1B1B1C1C1C1C1D1D1D1D1E1E1E1F1F1F1F2020202021
+212122222222232323232424242525252526262627272727282828282929292A2A2A2A2B2B2B2B2C
+2C2C2D2D2D2D2E2E2E2E2F2F2F303030303131313232323233333333343434353535353636363637
+373738383838393939393A3A3A3B3B3B3B3C3C3C3D3D3D3D3E3E3E3E3F3F3F404040404141414142
+42424343434344444444454545464646
+>
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+<
+00000101020203030304040505050606070708080809090A0A0B0B0B0C0C0D0D0D0E0E0F0F101010
+1111121212131314141515151616171718181819191A1A1A1B1B1C1C1D1D1D1E1E1F1F1F20202121
+222222232324242525252626272727282829292A2A2A2B2B2C2C2D2D2D2E2E2F2F2F303031313232
+32333334343435353636373737383839393A3A3A3B3B3C3C3C3D3D3E3E3F3F3F4040414142424243
+4344444445454646474747484849494A4A4A4B4B4C4C4C4D4D4E4E4F4F4F50505151515252535354
+54545555565657575758585959595A5A5B5B5C5C5C5D5D5E5E5E5F5F606061616162626363646464
+6565666666676768686969696A6A6B6B
+>
+1 %_Br
+1
+0 %_Br
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+4D4C4C4C4B4B4B4A4A4A4A4949494848484747474746464645454544444444434343424242414141
+414040403F3F3F3E3E3E3E3D3D3D3C3C3C3B3B3B3B3A3A3A39393938383838373737363636353535
+35343434333333323232323131313030302F2F2F2F2E2E2E2D2D2D2C2C2C2C2B2B2B2A2A2A292929
+2928282827272726262626252525242424232323232222222121212020201F1F1F1F1E1E1E1D1D1D
+1C1C1C1C1B1B1B1A1A1A191919191818181717171616161615151514141413131313121212111111
+101010100F0F0F0E0E0E0D0D0D0D0C0C0C0B0B0B0A0A0A0A09090908080807070707060606050505
+04040404030303020202010101010000
+>
+0
+0
+1 %_Br
+[
+1 0 50 92 %_BS
+%_1 0 50 92 Bs
+0 0.275 1 0.12 1 50 59 %_BS
+%_0 0.275 1 0.12 1 50 59 Bs
+0 0.275 1 0.42 1 50 50 %_BS
+%_0 0.275 1 0.42 1 50 50 Bs
+1 0 50 49 %_BS
+%_1 0 50 49 Bs
+1 0 50 41 %_BS
+%_1 0 50 41 Bs
+1 0.3 0 0 1 50 0 %_BS
+%_1 0.3 0 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Rainbow)
+(Rainbow) 0 6 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+0
+1 %_Br
+1
+<
+0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
+2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
+5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
+7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
+A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
+CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
+F7F8F9FAFBFCFDFEFF
+>
+0
+0
+1 %_Br
+1
+<
+00000000000000000000000000000000000001010101010101010101010101010101010101010101
+01010101010101010101010101010202020202020202020202020202020202020202020202020202
+02020202020202020202030303030303030303030303030303030303030303030303030303030303
+03030303030304040404040404040404040404040404040404040404040404040404040404040404
+04040505050505050505050505050505050505050505050505050505050505050505050505050606
+06060606060606060606060606060606060606060606060606060606060606060607070707070707
+07070707070707070707070707070707
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0
+1 %_Br
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+0
+1
+0
+1 %_Br
+0
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+1 %_Br
+[
+0 1 0 0 1 50 100 %_BS
+%_0 1 0 0 1 50 100 Bs
+1 1 0 0 1 50 80 %_BS
+%_1 1 0 0 1 50 80 Bs
+1 0.0279 0 0 1 50 60 %_BS
+%_1 0.0279 0 0 1 50 60 Bs
+1 0 1 0 1 50 40 %_BS
+%_1 0 1 0 1 50 40 Bs
+0 0 1 0 1 50 20 %_BS
+%_0 0 1 0 1 50 20 Bs
+0 1 1 0 1 50 0 %_BS
+%_0 1 1 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Yellow & Orange Radial)
+(Yellow & Orange Radial) 1 2 Bd
+[
+0
+<
+0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
+232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
+494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
+707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
+>
+<
+FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
+F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
+F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
+EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E6
+>
+0
+1 %_Br
+[
+0 0 1 0 1 52 19 %_BS
+%_0 0 1 0 1 52 19 Bs
+0 0.55 0.9 0 1 50 100 %_BS
+%_0 0.55 0.9 0 1 50 100 Bs
+BD
+%AI5_EndGradient
+%AI5_End_NonPrinting--
+%AI5_BeginPalette
+0 0 Pb
+1 1 1 1 ([Registration]) 0 Xs
+([Registration]) Pc
+0 0 0 0 k
+(C=0 M=0 Y=0 K=0) Pc
+0 0 0 1 k
+(C=0 M=0 Y=0 K=100) Pc
+0 0.1 1 0 k
+(C=0 M=10 Y=100 K=0) Pc
+0 0.5 0 0 k
+(C=0 M=50 Y=0 K=0) Pc
+0 0.5 1 0 k
+(C=0 M=50 Y=100 K=0) Pc
+1 0.55 1 0 k
+(C=100 M=55 Y=100 K=0) Pc
+1 0.9 0.1 0 k
+(C=100 M=90 Y=10 K=0) Pc
+0.15 1 1 0 k
+(C=15 M=100 Y=100 K=0) Pc
+0.45 0.9 0 0 k
+(C=45 M=90 Y=0 K=0) Pc
+0.5 0.4 0.3 0 k
+(C=50 M=40 Y=30 K=0) Pc
+0.5 0.85 1 0 k
+(C=50 M=85 Y=100 K=0) Pc
+0.75 0.05 1 0 k
+(C=75 M=5 Y=100 K=0) Pc
+0.75 0.9 0 0 k
+(C=75 M=90 Y=0 K=0) Pc
+0.8 0.05 0 0 k
+(C=80 M=5 Y=0 K=0) Pc
+Bb
+2 (Black, White) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Black, White) Pc
+Bb
+2 (Chrome) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Chrome) Pc
+Bb
+2 (Rainbow) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Rainbow) Pc
+Bb
+0 0 0 0 Bh
+2 (Yellow & Orange Radial) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Yellow & Orange Radial) Pc
+(Brick) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Brick) Pc
+(Confetti) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Confetti) Pc
+(Leaves - Fall ) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Leaves - Fall ) Pc
+(Stripes) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Stripes) Pc
+PB
+%AI5_EndPalette
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Dog Tracks)
+(1 /New Pattern 41/ 1 0 0 0 1 / 0 1 1 0 1 1 0 0 0 0 -90 -90 0 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Fall Leaf)
+(1 /New Pattern 34/ 1 0.0745 0.9 0.9019 0.18 / 0 0.602793 1 1 0.1 1 1 -) -
+(1 1 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Ladybug)
+(1 /New Pattern 10/ 5 0.898039 0 0 / 0 1 1 0 0.803911 1.2 1 -1.55 1.55 ) -
+(1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Push Pin)
+(1 /New Pattern 36/ 1 0.025 0.1 0.475 0 / 0 1 1 0 0.401676 1 1 -1.06145) -
+( 1.06 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Strawberry)
+(1 /New Pattern 37/ 1 0 0 0 1 / 0 0.803911 1 1 0.803911 1 1 -0.5 0.5 1 ) -
+(-75 75.419 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Twinkle Star )
+(1 /New Pattern 2/ 0 1 / 1 0.5 1 1 0.25 1 1 -0.5 0.5 1 0 0 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Double Lines)
+(1 / New Pattern 62/ New Pattern 63/ New Pattern 64/ / / 1 1 0.14 0.09 ) -
+(0 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Laurel)
+(1 / New Pattern 65/ New Pattern 42/ New Pattern 67/ / New Pattern 69/ ) -
+(1 0 0.55 1 0.3 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Rope )
+(1 / New Pattern 1/ / / New Pattern 3/ New Pattern 6/ 5 0 0 0 /  1 0 1 ) -
+(0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Arrow)
+(1 / New Pattern 45/ / / / / 5 0.898039 0 0 /  2 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Marker)
+(1 / New Pattern 8/ / / / / 0 0 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Paintbrush)
+(1 / New Pattern 5/ / / / / 1 0.5 0.85 1 0.45 /  0 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Tapered Stroke)
+(1 / New Pattern 83/ / / / / 1 0 0 0 1 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Type)
+(1 / New Pattern 50/ / / / / 1 0.952941 0.94902 0.196078 0.0745098 /  1) -
+( 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(6 pt Flat )
+(1 4 8 10 10 90 90 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(10 pt Oval)
+(1 1 19 15 15 130 130 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(12 pt Oval )
+(1 7 17 45 45 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(20 pt Oval)
+(1 20 20 20 100 40 80 0 2 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(25 pt Round )
+(1 10 40 100 100 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(50 pt Flat)
+(1 40 60 0 0 44 44 0 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Brush Manager Order)
+(Adobe Brush Manager Order)
+( Adobe Calligraphic Brush Tool/ 6 pt Flat / Adobe Calligraphic Brush T) -
+(ool/ 10 pt Oval/ Adobe Calligraphic Brush Tool/ 12 pt Oval / Adobe Cal) -
+(ligraphic Brush Tool/ 20 pt Oval/ Adobe Calligraphic Brush Tool/ 25 pt) -
+( Round / Adobe Calligraphic Brush Tool/ 50 pt Flat/ Adobe Scatter Brus) -
+(h Tool/ Dog Tracks/ Adobe Scatter Brush Tool/ Fall Leaf/ Adobe Scatter) -
+( Brush Tool/ Ladybug/ Adobe Scatter Brush Tool/ Push Pin/ Adobe Scatte) -
+(r Brush Tool/ Strawberry/ Adobe Scatter Brush Tool/ Twinkle Star / Ado) -
+(be ArtOnPath Brush Tool/ Marker/ Adobe ArtOnPath Brush Tool/ Tapered S) -
+(troke/ Adobe ArtOnPath Brush Tool/ Arrow/ Adobe ArtOnPath Brush Tool/ ) -
+(Paintbrush/ Adobe ArtOnPath Brush Tool/ Type/ Adobe PatternOnPath Brus) -
+(h Tool/ Double Lines/ Adobe PatternOnPath Brush Tool/ Laurel/ Adobe Pa) -
+(tternOnPath Brush Tool/ Rope /) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_PluginGroupInfo
+(Adobe Path Blends) (Adobe Blends Plugin) (Live Blends.aip)
+%AI8_PluginGroupInfo
+(Adobe PatternOnPath Brush Tool) (Adobe Pattern Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe ArtOnPath Brush Tool) (Adobe Art Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe Calligraphic Brush Tool) (Adobe Calligraphic Brush Plugin) (Calligraphic Brush Tool.aip)
+%AI8_PluginGroupInfo
+(Adobe Scatter Brush Tool) (Adobe Scatter Brush Plugin) (Scatter Brush Tool.aip)
+%AI5_End_NonPrinting--
+%%EndSetup
+%AI5_BeginLayer
+1 1 1 1 0 0 1 0 79 128 255 0 50 Lb
+(Layer 1) Ln
+0 A
+1 Ap
+0 O
+0.9137 0.1922 0.0549 0.0039 0 0.5255 0.702 Xa
+0 R
+0 0 0 1 K
+800 Ar
+0 J 0 j 2.8346 w 4 M []0 d%AI3_Note:0 D
+0 XR
+581.4834 43.7197 m
+14.1885 43.7197 L
+14.1885 820.2881 L
+581.4834 820.2881 L
+581.4834 43.7197 L
+buu0 Ap
+0 0 0 0.75 K
+1 J 1 j370.2041 104.5977 m
+347.5264 104.5977 l
+344.4092 104.5977 341.8574 102.0469 341.8574 98.9287 c
+341.8574 96.0938 l
+341.8574 92.9756 344.4092 90.4248 347.5264 90.4248 c
+370.2041 90.4248 L
+S0 0 0 0 K
+368.5029 106.2988 m
+345.8262 106.2988 l
+342.708 106.2988 340.1572 103.748 340.1572 100.6299 c
+340.1572 97.7949 l
+340.1572 94.6768 342.708 92.126 345.8262 92.126 c
+368.5029 92.126 L
+SUu0 0 0 0.75 K
+382.96 104.5977 m
+379.8418 104.5977 377.29 102.0469 377.29 98.9287 c
+377.29 96.0938 l
+377.29 92.9756 379.8418 90.4248 382.96 90.4248 c
+399.9678 90.4248 l
+403.0859 90.4248 405.6377 92.9756 405.6377 96.0938 c
+405.6377 98.9287 l
+405.6377 102.0469 403.0859 104.5977 399.9678 104.5977 c
+382.96 104.5977 l
+s0 0 0 0 K
+381.2588 106.2988 m
+378.1416 106.2988 375.5898 103.748 375.5898 100.6299 c
+375.5898 97.7949 l
+375.5898 94.6768 378.1416 92.126 381.2588 92.126 c
+398.2666 92.126 l
+401.3857 92.126 403.9365 94.6768 403.9365 97.7949 c
+403.9365 100.6299 l
+403.9365 103.748 401.3857 106.2988 398.2666 106.2988 c
+381.2588 106.2988 l
+sUu0 0 0 0.75 K
+453.8262 104.5977 m
+450.708 104.5977 448.1563 102.0469 448.1563 98.9287 c
+448.1563 96.0938 l
+448.1563 92.9756 450.708 90.4248 453.8262 90.4248 c
+470.834 90.4248 l
+473.9512 90.4248 476.5029 92.9756 476.5029 96.0938 c
+476.5029 98.9287 l
+476.5029 102.0469 473.9512 104.5977 470.834 104.5977 c
+453.8262 104.5977 l
+s0 0 0 0 K
+452.125 106.2988 m
+449.0068 106.2988 446.4551 103.748 446.4551 100.6299 c
+446.4551 97.7949 l
+446.4551 94.6768 449.0068 92.126 452.125 92.126 c
+469.1328 92.126 l
+472.25 92.126 474.8018 94.6768 474.8018 97.7949 c
+474.8018 100.6299 l
+474.8018 103.748 472.25 106.2988 469.1328 106.2988 c
+452.125 106.2988 l
+sUu0 0 0 0.75 K
+489.2598 104.5977 m
+486.1406 104.5977 483.5898 102.0469 483.5898 98.9287 c
+483.5898 96.0938 l
+483.5898 92.9756 486.1406 90.4248 489.2598 90.4248 c
+506.2676 90.4248 l
+509.3848 90.4248 511.9355 92.9756 511.9355 96.0938 c
+511.9355 98.9287 l
+511.9355 102.0469 509.3848 104.5977 506.2676 104.5977 c
+489.2598 104.5977 l
+s0 0 0 0 K
+487.5586 106.2988 m
+484.4395 106.2988 481.8887 103.748 481.8887 100.6299 c
+481.8887 97.7949 l
+481.8887 94.6768 484.4395 92.126 487.5586 92.126 c
+504.5664 92.126 l
+507.6836 92.126 510.2344 94.6768 510.2344 97.7949 c
+510.2344 100.6299 l
+510.2344 103.748 507.6836 106.2988 504.5664 106.2988 c
+487.5586 106.2988 l
+sUu0 0 0 0.75 K
+441.0693 104.5977 m
+418.3936 104.5977 l
+415.2754 104.5977 412.7236 102.0469 412.7236 98.9287 c
+412.7236 96.0938 l
+412.7236 92.9756 415.2754 90.4248 418.3936 90.4248 c
+441.0693 90.4248 L
+S0 0 0 0 K
+439.3691 106.2988 m
+416.6924 106.2988 l
+413.5752 106.2988 411.0234 103.748 411.0234 100.6299 c
+411.0234 97.7949 l
+411.0234 94.6768 413.5752 92.126 416.6924 92.126 c
+439.3691 92.126 L
+SUu0 0 0 0.75 K
+545.9521 90.4248 m
+545.9521 98.9287 l
+545.9521 102.0469 543.4014 104.5977 540.2822 104.5977 c
+519.0234 104.5977 L
+519.0225 90.4248 l
+S0 0 0 0 K
+544.251 92.126 m
+544.251 100.6299 l
+544.251 103.748 541.7002 106.2988 538.5811 106.2988 c
+517.3223 106.2988 L
+517.3213 92.126 l
+SUu1 Ap
+0 0 0 0.75 K
+469.416 97.5117 m
+469.416 97.5117 l
+469.416 97.5117 l
+469.416 97.5117 l
+469.416 97.5117 l
+s0 0 0 0 K
+467.7148 99.2129 m
+467.7148 99.2129 l
+467.7148 99.2129 l
+467.7148 99.2129 l
+467.7148 99.2129 l
+sUu0 0 0 0.75 K
+490.6758 97.5117 m
+490.6758 97.5117 l
+490.6758 97.5117 l
+490.6758 97.5117 l
+490.6758 97.5117 l
+s0 0 0 0 K
+488.9746 99.2129 m
+488.9746 99.2129 l
+488.9746 99.2129 l
+488.9746 99.2129 l
+488.9746 99.2129 l
+sUu0 0 0 0.75 K
+398.5498 97.5117 m
+398.5498 97.5117 l
+398.5498 97.5117 l
+398.5498 97.5117 l
+398.5498 97.5117 l
+s0 0 0 0 K
+396.8496 99.2129 m
+396.8496 99.2129 l
+396.8496 99.2129 l
+396.8496 99.2129 l
+396.8496 99.2129 l
+sUU0 Ap
+0 O
+0 g
+0 0 0 1 K
+%AI5_File:
+%AI5_BeginRaster
+() 1 XG
+[ 1.0006 0 0 1.0006 34.752 789.2021 ] 114 38 0 Xh
+[ 1.0006 0 0 1.0006 34.752 789.2021 ] 0 0 114 38 114 38 8 3 0 0 0 0
+%%BeginData: 27298
+XI
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B275BED599CFE099CFE075BED50086B2
+%0086B275BED50086B20086B275BED50086B20086B2BADEEA75BED575BED5
+%65B6D00086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%44A6C744A6C70086B20086B20086B275BED50086B20086B275BED50086B2
+%0086B275BED50086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B244A6C744A6C70086B20086B20086B2BADEEA
+%75BED575BED5BADEEA0086B20086B2BADEEA75BED575BED544A6C70086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B244A6C744A6C7
+%0086B20086B20086B275BED50086B20086B275BED50086B20086B275BED5
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B244A6C744A6C70086B20086B20086B275BED50086B20086B2
+%75BED50086B20086B2BADEEA75BED575BED565B6D00086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B22095BC75BED575BED5
+%75BED544A6C70086B20086B20086B20086B275BED575BED575BED575BED5
+%75BED565B6D00086B20086B20086B20086B22095BC75BED575BED575BED5
+%44A6C70086B20086B20086B20086B20086B2108EB775BED5BADEEABADEEA
+%99CFE044A6C70086B20086B20086B275BED575BED565B6D00086B20086B2
+%65B6D075BED575BED50086B20086B20086B275BED575BED575BED575BED5
+%75BED575BED575BED50086B20086B20086B20086B20086B20086B254AECB
+%75BED575BED5108EB70086B20086B275BED575BED575BED50086B20086B2
+%0086B275BED575BED575BED554AECB0086B2309DC075BED575BED575BED5
+%2095BC0086B20086B275BED575BED565B6D00086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B289C7DBFFFFFFFFFFFFFFFFFFCEE8F00086B20086B20086B20086B2
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBADEEA0086B20086B20086B2
+%89C7DBFFFFFFFFFFFFFFFFFFCEE8F00086B20086B20086B20086B2108EB7
+%CEE8F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65B6D00086B20086B2FFFFFF
+%FFFFFFBADEEA0086B20086B2BADEEAFFFFFFFFFFFF0086B20086B20086B2
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0086B20086B20086B2
+%0086B20086B20086B22095BCEEF7FAFFFFFFAAD7E50086B265B6D0FFFFFF
+%FFFFFF54AECB0086B20086B20086B2FFFFFFFFFFFFFFFFFFBADEEA0086B2
+%75BED5FFFFFFFFFFFFFFFFFF44A6C70086B20086B2FFFFFFFFFFFFBADEEA
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B2DEEFF5FFFFFFDEEFF5FFFFFFFFFFFF
+%2095BC0086B20086B20086B2FFFFFFFFFFFFDEEFF575BED5EEF7FAFFFFFF
+%FFFFFF309DC00086B20086B2DEEFF5FFFFFFDEEFF5FFFFFFFFFFFF2095BC
+%0086B20086B20086B299CFE0FFFFFFFFFFFF89C7DB54AECBEEF7FAFFFFFF
+%FFFFFF108EB70086B2FFFFFFFFFFFFBADEEA0086B20086B2BADEEAFFFFFF
+%FFFFFF0086B20086B20086B2FFFFFFFFFFFFDEEFF575BED575BED575BED5
+%75BED50086B20086B20086B20086B20086B20086B20086B275BED5FFFFFF
+%FFFFFF54AECBEEF7FAFFFFFFBADEEA0086B20086B20086B20086B2FFFFFF
+%FFFFFFFFFFFFFFFFFF0086B2BADEEAFFFFFFFFFFFFFFFFFF44A6C70086B2
+%0086B2FFFFFFFFFFFFBADEEA0086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B2309DC0FFFFFF
+%FFFFFF75BED5FFFFFFFFFFFF75BED50086B20086B20086B2FFFFFFFFFFFF
+%BADEEA0086B289C7DBFFFFFFFFFFFF44A6C70086B2309DC0FFFFFFFFFFFF
+%75BED5FFFFFFFFFFFF75BED50086B20086B20086B2DEEFF5FFFFFFDEEFF5
+%0086B20086B244A6C754AECB2095BC0086B20086B2FFFFFFFFFFFFDEEFF5
+%75BED575BED5DEEFF5FFFFFFFFFFFF0086B20086B20086B2FFFFFFFFFFFF
+%DEEFF575BED575BED575BED565B6D00086B20086B20086B20086B20086B2
+%0086B20086B20086B2BADEEAFFFFFFFFFFFFFFFFFFEEF7FA2095BC0086B2
+%0086B20086B20086B2FFFFFFFFFFFFBADEEAFFFFFF309DC0EEF7FABADEEA
+%FFFFFFFFFFFF44A6C70086B20086B2FFFFFFFFFFFFBADEEA0086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B289C7DBFFFFFFFFFFFF2095BCCEE8F0FFFFFFCEE8F00086B2
+%0086B20086B2FFFFFFFFFFFFEEF7FABADEEAFFFFFFFFFFFFFFFFFF108EB7
+%0086B289C7DBFFFFFFFFFFFF2095BCCEE8F0FFFFFFCEE8F00086B20086B2
+%0086B2FFFFFFFFFFFFBADEEA0086B20086B20086B20086B20086B20086B2
+%0086B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0086B2
+%0086B20086B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBADEEA0086B2
+%0086B20086B20086B20086B20086B20086B20086B2309DC0FFFFFFFFFFFF
+%FFFFFF75BED50086B20086B20086B20086B20086B2FFFFFFFFFFFF75BED5
+%FFFFFF75BED5FFFFFF75BED5FFFFFFFFFFFF44A6C70086B20086B2FFFFFF
+%FFFFFFBADEEA0086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20081AE0086B2
+%0086B20086B20086B20086B20086B20086B2DEEFF5FFFFFFFFFFFF75BED5
+%CEE8F0FFFFFFFFFFFF2095BC0086B20086B2FFFFFFFFFFFFFFFFFFFFFFFF
+%FFFFFFFFFFFF65B6D00086B20086B2DEEFF5FFFFFFFFFFFF75BED5CEE8F0
+%FFFFFFFFFFFF2095BC0086B20086B2FFFFFFFFFFFFBADEEA0086B20086B2
+%44A6C744A6C70086B20086B20086B2FFFFFFFFFFFFDEEFF575BED575BED5
+%DEEFF5FFFFFFFFFFFF0086B20086B20086B2FFFFFFFFFFFFDEEFF575BED5
+%75BED575BED565B6D00086B20086B20086B20086B20086B20086B20086B2
+%0086B2AAD7E5FFFFFFFFFFFFFFFFFFDEEFF5108EB70086B20086B20086B2
+%0086B2FFFFFFFFFFFF54AECBFFFFFFDEEFF5FFFFFF54AECBFFFFFFFFFFFF
+%44A6C70086B20086B2FFFFFFFFFFFFBADEEA0086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B2006D9D006395007EAB0086B20086B20086B20086B2309DC0
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75B8D00080AD0082AF
+%FFFFFFFFFFFFCEE8F044A6C744A6C7108EB70086B20086B2309DC0FFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75BED50086B20086B2AAD7E5
+%FFFFFFFFFFFF108EB70086B2CEE8F0FFFFFFEEF7FA2095BC0086B2FFFFFF
+%FFFFFFBADEEA0086B20086B2BADEEAFFFFFFFFFFFF0086B20086B20086B2
+%FFFFFFFFFFFFBADEEA0086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B254AECBFFFFFFFFFFFFAAD7E5FFFFFFFFFFFF
+%89C7DB0086B20086B20086B20086B2FFFFFFFFFFFF44A6C7CEE8F0FFFFFF
+%FFFFFF108EB7FFFFFFFFFFFF44A6C70086B20086B2FFFFFFFFFFFFBADEEA
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20083B0006596004D82006092
+%007DAA0086B20086B289C7DBFFFFFFFFFFFF99CDDF75B7CF74BDD5FFFFFF
+%FFFFFFCEE4EE0074A30072A1FFFFFFFFFFFFB8DDEA0082AF0085B10086B2
+%0086B20086B289C7DBFFFFFFFFFFFF99CFE075BED575BED5FFFFFFFFFFFF
+%CEE8F00086B20086B244A6C7FFFFFFFFFFFFDEEFF5CEE8F0FFFFFFFFFFFF
+%BADEEA0086B20086B2FFFFFFFFFFFFBADEEA0086B20086B2BADEEAFFFFFF
+%FFFFFF0086B20086B20086B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+%FFFFFF44A6C70086B20086B20086B20086B20086B2108EB7EEF7FAFFFFFF
+%BADEEA0086B275BED5FFFFFFFFFFFF44A6C70086B20086B20086B2FFFFFF
+%FFFFFF44A6C789C7DBFFFFFFDEEFF50086B2FFFFFFFFFFFF44A6C70086B2
+%0086B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75BED50086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20076A500528600497F005F910078A6DEEFF5FFFFFFFFFFFF
+%1591B9007FAC0076A5CEE4EEFFFFFFFFFFFF2088B10078A6FFFFFFFFFFFF
+%B8DDEA00709F0074A30071A00073A2007BA8DEEFF5FFFFFFFFFFFF108EB7
+%0086B20086B2CEE8F0FFFFFFFFFFFF2095BC0086B20086B265B6D0EEF7FA
+%FFFFFFFFFFFFFFFFFFBADEEA108EB70086B20086B2FFFFFFFFFFFFBADEEA
+%0086B20086B2BADEEAFFFFFFFFFFFF0086B20086B20086B2FFFFFFFFFFFF
+%FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44A6C70086B20086B20086B20086B2
+%0086B2AAD7E5FFFFFFEEF7FA2095BC0086B20086B2CEE8F0FFFFFFDEEFF5
+%108EB70086B20086B2FFFFFFFFFFFF44A6C765B6D0FFFFFF99CFE00086B2
+%FFFFFFFFFFFF44A6C70086B20086B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+%FFFFFF75BED50086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20085B1006B9B00497F
+%00467C0056890072A10077A60082AF0077A60071A000699A006B9B0071A0
+%006F9E0076A50073A20073A20073A2007EAB007BA8007DAA007CA90074A3
+%0072A100709F007CA90083B00086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B244A6C744A6C72095BC0086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B2007DAA00609200497F00467C005286005B8E006899
+%0071A000699A00699A006899006D9D00709F006D9D006D9D0077A60074A3
+%0074A30078A60075A4007EAB007CA9007DAA0081AE0076A500709F0077A6
+%007EAB0086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B2007EAB
+%006899004D8200467C00497F005689005F9100699A00699A006D9D006798
+%006798006E9D0071A0006D9D0074A3006F9E0075A40072A10078A60078A6
+%0077A6007CA9007DAA0087B3007FAC00709F0075A4007EAB0085B10086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B2007FAC0072A10074A300699A005B8E00568900497F00467C
+%004D82005689006092006798006B9B006D9D006899006B9B00699A00699A
+%006F9E00709F0077A60072A10074A30078A6007BA80077A60078A6007EAB
+%0089B5007FAC0071A00073A20074A30078A6007CA90080AD0085B10086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B2BADEEA75BED5
+%75BED575BED50086B2BADEEA75BED575BED589C7DB0086B20086B2309DC0
+%89C7DB75BED589C7DB309DC00086B20086B20086B275BED50086B2BADEEA
+%75BED575BED565B6D00086B2309DC099CFE075BED589C7DB7CC1D799CFE0
+%99CFE075BED50086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20080AD0078A6007FAC008DB6008FB9
+%0075A40072A100699A00609200568900497F00467C004D82005689006092
+%006798006F9E00699A006B9B0067980071A0006D9D006D9D0071A00078A6
+%0071A00072A1007BA80073A20077A6007BA8007EAB0089B50081AE007BA8
+%007CA9007BA80076A50078A6007EAB0075A4007FAC0085B10086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B275BED50086B20086B275BED50086B275BED50086B20086B2
+%89C7DB0086B20086B289C7DB0086B20086B20086B289C7DB0086B20086B2
+%0086B275BED50086B275BED50086B20086B20086B20086B299CFE00086B2
+%0086B2108EB744A6C744A6C744A6C70086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20085B20078A6
+%0073A20089B5008DB6008DB6007CA900709F0078A60072A10071A000699A
+%00609200568900497F00467C00497F005286005B8E006596006798006D9D
+%006B9B0067980072A1006D9D006B9B0074A30071A00071A00073A2007BA8
+%0072A10077A60078A60078A6007DAA007BA8007EAB007FAC0083B0007CA9
+%0075A4007DAA0078A60076A5007BA80083B00086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B2BADEEA75BED575BED575BED5
+%0086B2BADEEA75BED5BADEEA54AECB0086B20086B275BED50086B20086B2
+%0086B275BED50086B20086B20086B275BED50086B2BADEEA75BED575BED5
+%44A6C70086B275BED50086B20086B20086B20086B244A6C744A6C70086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20081AE0081AE007CA9007BA80080AD0078A5
+%007CA90076A50075A40076A50072A10073A200699A00609200568900497F
+%00467C00467C004D82005689005F9100639500699A006899006B9B0073A2
+%00699A006D9D0074A30076A50072A10071A00072A10078A60075A40078A6
+%0072A10072A10075A40076A5007BA80080AD0092BA008DB6007EAB006D9D
+%0074A30076A5007CA90083B00086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%75BED50086B20086B20086B20086B275BED50086B275BED5309DC00086B2
+%0086B289C7DB0086B20086B20086B289C7DB0086B244A6C70086B275BED5
+%0086B275BED50086B20086B20086B20086B289C7DB0086B20086B22095BC
+%54AECB44A6C744A6C70086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20083B0007FAC
+%0083B0007BA80085B10071A0007EAB007BA80078A60078A60077A6007BA8
+%006D9D006D9D006D9D006D9D006596005B8E00528600467C00467C00467C
+%00497F005286005B8E00639500699A0068990074A3006D9D006D9D006D9D
+%0073A2006F9E0071A0006B9B006D9D006F9E0071A00076A50077A6007EAB
+%00709F00699A00699A007EAB008FB90083B00078A60074A30076A50083B0
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B275BED50086B20086B20086B20086B275BED5
+%0086B20086B289C7DB0086B20086B2309DC089C7DB75BED589C7DB309DC0
+%0086B289C7DB75BED565B6D00086B2BADEEA75BED575BED565B6D00086B2
+%309DC089C7DB75BED599CFE0108EB744A6C744A6C70086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B2007FAC0074A30089B5
+%0080AD0078A6007BA80083B000709F006B9B006D9D006D9D00709F006E9D
+%006D9D00699A006092005B8E00528600497F00467C00467C00497F004D82
+%005689005B8E00609200689900679800699A006899006D9D00699A006E9D
+%0071A00074A3007BA8006D9D006D9D006B9B0073A20077A6006F9E0071A0
+%0077A60089B5008DB6007EAB0071A00074A30074A30078A60078A60082AF
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20083B00075A40085B1008FB90089B50086B2007CA90076A5
+%0078A60072A10076A50071A00071A00072A10072A10072A1006D9D00699A
+%006395005F9100568900528600497F00467C00467C00497F00497F004D82
+%005689005689005B8E0060920067980072A1006B9B00699A006D9D0072A1
+%0078A600699A00699A0075A40080AD007DAA007BA8007EAB007DAA0089B5
+%0092BA0096BD0092BA0083B0007CA90076A50083B00086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B2007EAB0077A6
+%007CA90092BA008DB6007DAA007DAA0077A60077A60078A6007CA90074A3
+%0075A4007BA80071A00072A100709F0074A30074A30073A2006B9B006798
+%006798005F91005B8E005689005286004D8200497F00497F00497F00497F
+%00497F005286005286005B8E005689005F910063950076A50073A2006D9D
+%0071A00076A5007EAB0087B3008FB90092BA0096BD0099BF0096BD0092BA
+%0085B10077A60086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B2007CA90074A30085B1008FB90092BA
+%007FAC007BA80081AE0077A60078A6007CA90078A60078A60076A50075A4
+%0076A50075A40074A30075A40076A50073A20072A10071A00071A0006B9B
+%00699A00699A006899006092006092005B8E005B8E005286005689005286
+%005286004D82004D82005286005286005B8E0060920072A1007CA90086B2
+%008DB6008FB9008FB90096BD009AC00092BA007CA9007CA90086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20082AF007BA8007DAA0087B30076A50096BD0099BF0081AE0086B2
+%0096BD0086B2007BA80078A60078A60075A40078A60078A60077A60077A6
+%0074A3007CA90076A50074A30072A10073A20075A40072A1006B9B006B9B
+%0075A40078A600699A0067980071A0006798006899006798006B9B005F91
+%005B8E0072A10076A50077A6006D9D0074A30075A4007CA90078A6007EAB
+%0089B50080AD0086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20081AE007CA9
+%0076A5007CA90077A60071A00086B2008FB9007EAB007DAA007EAB007DAA
+%007BA8007CA9007FAC0081AE007BA80076A5007EAB0078A60077A60078A6
+%0078A6007BA80074A3006F9E0071A0007CA9007BA8006D9D0073A20078A6
+%0072A10073A20076A5007CA90075A40076A5008FB90092BA0099BF0092BA
+%0092BA0092BA008FB9008FB90089B5007BA80086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20085B10083B0007DAA
+%0078A60074A30074A30074A3006F9E006F9E0075A40089B50086B2007BA8
+%0078A6008DB6008DB60081AE007BA8007BA80082AF0087B3007CA90078A6
+%0089B5008DB60080AD007CA90081AE007FAC007FAC0078A6007DAA0087B3
+%007DAA0083B0008FB90092BA0092BA008FB90089B50078A60075A4007FAC
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0083B0007EAB007EAB0078A60075A40074A30077A60075A40072A10076A5
+%0078A6007FAC0087B3007DAA0073A2007CA9007BA8006F9E0077A60085B1
+%007DAA0075A4007BA80078A60077A60073A20071A00076A50077A6007BA8
+%0081AE0086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B20086B20086B20086B20086B20086B20086B20086B20086B2
+%0086B20086B2
+%%EndData
+XH
+%AI5_EndRaster
+Bu0 To
+1 0 0 1 383.8105 69.7324 0 Tp
+0 Tv
+TP
+0 Tr
+0 0 0 0.8 k
+0 J 0 j 1 w%_ 0 50 XQ
+/_AvantGarde-Book 11.3386 11.2138 -2.5284 Tf
+0 Ts
+100.7621 100 Tz
+0 Tt
+%_0 0 100 100 Xu
+%AI55J_GlyphSubst: GlyphSubstNone 
+0 TA
+%_ 0 XL
+0 TY
+0 TV
+36 0 Xb
+XB
+0 0 5 TC
+100 100 200 TW
+25 TG
+0 0 0 Ti
+0 Ta
+0 1 2 2 3 Th
+0 Tq
+240 Tg
+12.7559 0 Tl
+0 Tc
+0 Tw
+(The XML Publishing Framework) Tx 
+(\r) Tx 
+TO
+0 To
+1 0 0 1 382.6768 70.8662 0 Tp
+0 Tv
+TP
+0 Tr
+0 0 0 0 k
+(The XML Publishing Framework) Tx 
+(\r) Tx 
+TO
+ULB
+%AI5_EndLayer--
+%%PageTrailer
+gsave annotatepage grestore showpage
+%%Trailer
+Adobe_Illustrator_AI5 /terminate get exec
+Adobe_shading_AI8 /terminate get exec
+Adobe_ColorImage_AI6 /terminate get exec
+Adobe_typography_AI5 /terminate get exec
+Adobe_cshow /terminate get exec
+Adobe_level2_AI5 /terminate get exec
+%%EOF
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon.jpg b/non-releases/trunk_before_flattening/misc/graphics/cocoon.jpg
new file mode 100644
index 0000000..af9d18c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon.jpg
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.gif b/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.gif
new file mode 100644
index 0000000..141fe6d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.svg b/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.svg
new file mode 100644
index 0000000..94e40a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon2-naked.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448)  -->

+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [

+	<!ENTITY ns_svg "http://www.w3.org/2000/svg">

+	<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">

+]>

+<svg  version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="612" height="792" viewBox="0 0 612 792"

+	 overflow="visible" enable-background="new 0 0 612 792" xml:space="preserve">

+<g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M232.384,95.441

+			h-22.676c-3.118,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.551,5.669,5.669,5.669h22.677"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M230.684,93.741

+			h-22.677c-3.118,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.551,5.669,5.669,5.669h22.677"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M245.14,95.441

+			c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h17.008c3.119,0,5.67-2.551,5.67-5.669v-2.835

+			c0-3.118-2.551-5.669-5.67-5.669H245.14z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M243.439,93.741

+			c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h17.008c3.119,0,5.67-2.551,5.67-5.669V99.41

+			c0-3.118-2.551-5.669-5.67-5.669H243.439z"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M316.007,95.441

+			c-3.118,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.552,5.669,5.67,5.669h17.009c3.117,0,5.67-2.551,5.67-5.669v-2.835

+			c0-3.118-2.553-5.669-5.67-5.669H316.007z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M314.307,93.741

+			c-3.119,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.551,5.669,5.67,5.669h17.008c3.117,0,5.67-2.551,5.67-5.669V99.41

+			c0-3.118-2.553-5.669-5.67-5.669H314.307z"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M351.439,95.441

+			c-3.119,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.551,5.669,5.67,5.669h17.009c3.116,0,5.668-2.551,5.668-5.669v-2.835

+			c0-3.118-2.552-5.669-5.668-5.669H351.439z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M349.738,93.741

+			c-3.118,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.552,5.669,5.67,5.669h17.009c3.116,0,5.668-2.551,5.668-5.669V99.41

+			c0-3.118-2.552-5.669-5.668-5.669H349.738z"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M303.25,95.441

+			h-22.677c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h22.677"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M301.55,93.741

+			h-22.677c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h22.677"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M408.134,109.614

+			v-8.504c0-3.118-2.551-5.669-5.67-5.669h-21.26v14.173"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M406.434,107.914

+			V99.41c0-3.118-2.552-5.669-5.67-5.669h-21.261v14.173"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M331.598,102.527

+			h0.002H331.598z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M329.896,100.827

+			L329.896,100.827L329.896,100.827z"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M352.855,102.527

+			h0.002H352.855z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M351.154,100.827

+			h0.002H351.154z"/>

+	</g>

+	<g>

+		<path fill="none" stroke="#000000" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M260.731,102.527

+			L260.731,102.527L260.731,102.527z"/>

+		<path fill="none" stroke="#FFFFFF" stroke-width="2.8346" stroke-linecap="round" stroke-linejoin="round" d="M259.03,100.827

+			L259.03,100.827L259.03,100.827z"/>

+	</g>

+</g>

+</svg>

diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon2.ai b/non-releases/trunk_before_flattening/misc/graphics/cocoon2.ai
new file mode 100644
index 0000000..98294c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon2.ai
@@ -0,0 +1,9617 @@
+%!PS-Adobe-3.0 
+%%Creator: Adobe Illustrator(R) 8.0
+%%AI8_CreatorVersion: 9.0
+%%For: (Stefano Mazzocchi) ( )
+%%Title: (cocoon2.ai)
+%%CreationDate: 2/23/2002 7:54 PM
+%%BoundingBox: -23 422 545 842
+%%HiResBoundingBox: -22.0845 422.583 544.75 841.4175
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0
+%%+ procset AGM_Gradient 1.0 0
+%%+ procset Adobe_ColorImage_AI6 1.3 0
+%%+ procset Adobe_Illustrator_AI5 1.3 0
+%%+ procset Adobe_pattern_AI5 1.0 0
+%%+ procset Adobe_cshow 2.0 8
+%%+ procset Adobe_shading_AI8 1.0 0
+%AI5_FileFormat 4.0
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%CMYKProcessColor: 1 1 1 1 ([Registration])
+%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) 
+%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 2 3 4
+%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () 
+%AI3_TemplateBox: 296.5 419.5 296.5 419.5
+%AI3_TileBox: 8 40 584 832
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 592 840
+%AI5_RulerUnits: 1
+%AI5_ArtFlags: 1 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 1
+%AI8_OpenToView: -39 897.6665 1.5 1012 671 18 0 1 8 90 1 0
+%AI5_OpenViewLayers: 7
+%%PageOrigin:8 40
+%%AI3_PaperRect:-8 834 587 -8
+%%AI3_Margin:8 -40 -9 8
+%AI7_GridSettings: 14.1732 2 14.1732 2 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI9_Flatten: 1
+%AI7_Thumbnail: 128 96 8
+%%BeginData: 8842 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%524C45FD7FA87D7DFD7EFFA8A8FD7EFFA87DFD7EFFA8A8FD7EFFA87DFD7E
+%FFA8A8FD7EFF7D7DFD7EFFA8A8FD7EFFA87DFD21FF7E59597D597D597D59
+%7D597D597D597D597D597D597D597D597D597D597D597D597D597D597D59
+%7D597D597D597D597D597D597D597D597D597D597DFD21FFA8A8FD20FF2E
+%3613360D3613360D3613360D3613360D3613360D3613360D3613360D3613
+%360D3613360D3613360D3613360D3613360D3613360D3613360D3613362F
+%5984FD1FFFA87DFD1FFF2E360D360D360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D360D360D360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D360D537DFD1EFFA8A8FD1EFF59360D3613360D
+%3613360D3613360D3613360D3613360D3613360D3613360D3613360D3613
+%360D3613360D3613360D3613360D3613360D3613360D3613360D361359FD
+%1EFFA87DFD1EFF590D360D360D360D36355A595A59592F36355A595A597D
+%0D36355A595A59592F36355A595A597D0D362F5A595A597D0D365959595A
+%59590D360D360D360D360D362FA8FD1DFFA8A8FD1EFF2F3613360D361336
+%0D842F360D3613360D842F360D36357D0D842F360D3613360D842F360D36
+%357D0D842F360D36357D0D5A13360D3659590D3613360D3613360D367DFD
+%1DFF7D7DFD1EFF2F0D360D360D360D3659360D360D360D3659360D360D36
+%593659360D360D360D3659360D360D36593659360D360D3659362F360D36
+%0D3659360D360D360D360D360D84FD1DFFA8A8FD1EFF2F3613360D361336
+%0D36595A595A595A0D36595A595A59590D36595A595A595A0D36595A595A
+%59590D36595A595A59590D5A13360D36135A0D3613360D3613360D367DFD
+%1DFFA87DFD1EFF590D360D360D360D360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D360D360D360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D362EFD1EFFA8A8FD1EFFA8350D3613360D3613
+%360D3613360D3613360D3613360D3613360D3613360D3613360D3613360D
+%3613360D3613360D3613360D3613360D3613360D3613360D36357DFD1EFF
+%A87DFD1FFF592F0D360D360D360D360D360D360D360D360D360D360D360D
+%360D360D360D360D360D360D360D360D360D360D360D360D360D360D360D
+%360D360D360D360D53FD1FFFA8A8FD20FFA8FD3B5953A8FD20FFA87DFD7E
+%FFA8A8FD7EFF7D7DFD7EFFA8A8FD7EFFA87DFD20FF8453592F5953592F59
+%53592F5953592F5953592F5953592F5953592F5953592F5953592F595359
+%2F5953592F5953592F5953592F5953592F59535952A8FD21FFA8A8FD1FFF
+%592F36135A36605A5A366013360D605A5A366035360D36135A36605A5A36
+%36133635605A5A366013360D36365A36605A5A0D36355A36605A5A363613
+%362F59FD20FFA87DFD1EFF7D0D360D602F2F2E352F2F2E350D842E352F2F
+%2E7E35360D842E2F2E352F2F2E36355A2E352F2F2F7E0D3635592F2F2E35
+%2F7D0D5A2E2F2E352F3559360D360D84FD1FFFA8A8FD1EFF59360D605336
+%0D3613360D36135A533613360D3635842F842E360D3613360D3613842F36
+%13360D3635590D842F360D3613365A595A590D3613360D3659360D3659FD
+%1FFFA87DFD1EFF7D0D360D7E35360D360D360D360D7E2F360D360D605335
+%0D7E2F360D360D360D36357D0D360D360D842E36595A0D360D36355A2E5A
+%2F360D360D360D5A0D360D7DFD1FFFA8A8FD1EFFA85913360D5A595A595A
+%595A2F361359595A595A2F3613360D5A595A595A59590D363559595A595A
+%2F3613362F5A595A595A2F36353613360D3613362F361353A8FD1FFF7D7D
+%FD1FFFA8592E2F0D360D360D360D360D360D360D360D360D360D360D360D
+%360D360D360D360D360D360D360D360D360D360D360D360D360D360D360D
+%360D2F2E59A8FD20FFA8A8FD22FFA8A87D847DA87D847DA87D847DA87D84
+%7DA87D847DA87D847DA87D847DA87D847DA87D847DA87D847DA87D847DA8
+%7D847DA87D847DA87D84A8FD23FFA87DFD7EFFA8A8FD7EFFA87DFD7EFFA8
+%A8FD7EFFA87DFD7EFFA8A8FD7EFF7D7DFD7EFFA8A8FD26FFFD3159FD27FF
+%A87DFD25FF7D350D360D360D360D360D360D360D360D360D360D360D360D
+%360D360D360D360D350D350D2F2E350D350D360D350D360D357DFD26FFA8
+%A8FD25FF7E13362F592F352F5213592F362F352F362F350D362F532F3513
+%360D532F360D592F362F3613350D362F352F592F360D36137EFD26FFA87D
+%FD25FF59360D352E352F2F0D360D2F2E350D350D362F2F2E352F360D360D
+%360D2F2F2F0D360D350D360D360D350D360D350D360D3659FD26FFA8A8FD
+%25FF7E133636605A5A365A133636605A5A3536133636605A5A365A133636
+%605A5A3536133636605A5A3536135A36605A5A3536137EFD26FFA87DFD25
+%FF59365A532E352F2F2E365A532E352F592F365A532E352F2F2E365A532E
+%352F592F365A532E352F592F36532F2E352F7D2F3659FD26FFA8A8FD25FF
+%7E0D7E13360D3613360D7E13360D36357D0D7E13360D3613360D7E13360D
+%36357D0D7E35360D36137D0D5A13360D3613590D7EFD26FF7D7DFD25FF59
+%36595A355A355A3536595A355A35842E36595A355A355A3536595A355A35
+%842E36595A355A35842E362F360D360D36593659FD26FFA8A8FD25FF7D2F
+%362F592F592F590D362F592F592F360D362F592F592F590D362F592F592F
+%360D362F592F592F360D3613360D3613362F7EFD26FFA87DFD26FF532E35
+%2F2F2E352F2F2E352F2F2E352F2F2E352F2F2E352F2F2E352F2F2E352F2F
+%2E352F2F2E352F2F2E352F2F2E352F53FD27FFA8A8FD7EFFA87DFD7EFFA8
+%A8FD7EFFA87DFD7EFFA8A8FD21FFA87D847D847D847D847D847D847D847D
+%847D847D847D847D847D847D847D847D847D847D847D847D847D847D847D
+%847D847D847D847D847D847D847D847D847D847D847D847D847D847D847D
+%847D8484FD0DFF7D7DFD1FFF7D592F360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D360D360D360D360D360D360D360D360D360D36
+%0D360D360D360D360D360D360D360D360D360D360D360D360D360D360D36
+%0D360D352E59FD0BFFA8A8FD1EFF5959133635605A5A36605A360D605A5A
+%36603636353613360D3613360D605A5A36605A3635605A5A36605A360D60
+%5A5A36605A3636605A5A366036360D3613360D36135A36605A5A36361336
+%0D3613360D5A13362F53A9FD09FFA87DFD1DFF7D350D360D352E352F5959
+%7E2F5A2F352F2F2E84355A0D3635360D36596059592F2F2E350D352E352F
+%2F597E2F6059592F2F2E352F592E352F2F2E8435360D360D360D362F2F2E
+%352F7D5A36595A3560365A2F360D360D59FD09FFA8A8FD1DFF5913360D36
+%13360D6059592E36357E36605A6059353584368459605935357D59605A5A
+%363613360D36137E5936357D59605A5A3636595A36605A60595913360D36
+%13360D605A5A36607E520D362F3553592F350D3613362F84FD08FFA87DFD
+%1CFF7D0D360D360D360D360D350D360D362F2F2E352F2F0D362F2F2E2F2F
+%2F0D362F2F2E352F2F0D360D360D362F2F2F362F2F2E352F2F0D352F2F2E
+%352F2F0D360D360D360D362F352F2F2E2F0D360D360D2F0D360D360D360D
+%362EFD08FFA8A8FD1CFF593613360D3613360D3613360D3613360D361336
+%0D3613360D3613360D3613360D3613360D3613360D3613360D3613360D36
+%13360D3613360D3613360D3613360D3613360D3613360D3613360D361336
+%0D3613360D3613360D59FD08FFA87DFD1CFF590D360D360D5A84FD09FF59
+%360D84A8FD07FF845A0D3635A9FD09FF840D365AFD08FFA835360D3684FD
+%07FFA8842F365AFD09FF7E360D360D362EFD08FFA8A8FD1CFF53360D3613
+%36A9A8FD0A272F84A952FD07277DA85913FF7D2EFD0927355AFF52FD0627
+%527DFF2F36AFA8FD072753A87D138452FD072752FF7D360D361335FD08FF
+%7D7DFD1CFF590D360D360DFFF8360D360D360D360D360D365A7D2E360D36
+%0D3635360DAF2836FF270D360D360D360D360D360D84592F0D360D360D36
+%3536A8520DFFF83635360D360D360D5A7D2F5A7D0D360D360D360D3659A8
+%2F360D362EFD08FFA8A8FD1CFF84360D361336FF5913360D3613360D3613
+%360D857D360D3613360D5A5236A95313FF2E3613360D3613360D36133684
+%7D13360D36133636592FFF2736FF5335592F360D3613365AAF2E85523613
+%360D3613360D60A8590D361359FD08FFA87DFD1DFF2E360D360DA97D6036
+%5A355A365A355A353635FF7D5A355A365A356084FF2736A8A8595A365A35
+%5A365A35360D5AA884365A355A365A35A9A9270DA9A85A355A365A355A5A
+%FF52535A7D0D360D360D360D3635A82F360D59A8FD08FFA8A8FD1EFF2E36
+%0D36357DFD09A87D2F3659FD09A827350D367DFD09A87D36137E7DFD07A8
+%7D272F363584FD08A852270D6027360D3613360D3613367D59133559FD09
+%FFA87DFD1EFFA82E350D360D2F2E352F2F2E352F2F2E350D360D352F2F2E
+%352F2F2E350D360D362F2F2E352F2F2E352F2F0D360D352E352F2F2E352F
+%2F0D360D360D352F2F2E352F2F2E350D360D350D360D360D360D360D350D
+%3559FD0AFFA8A8FD20FF59592F592F592F592F592F592F592F592F592F59
+%2F592F592F592F592F592F592F592F592F592F592F592F592F592F592F59
+%2F592F592F592F592F592F592F592F592F592F592F592F592F592F592F59
+%537DA8FD0BFFA87DFD7EFFA8A8FD7EFF7D7DFD7EFFA8A8FD7EFFA87DFD7E
+%FFA8A8FD7EFFA87DFD7EFFA8A8FD7EFFA87DFD7EFFA8A8FD7EFF7D7DFD7E
+%FFA8A8FD7EFFA87DFD7EFFA8A8FD7EFFA87DFD7EFFA8A8FD7EFFA87DFD7E
+%FFA8A8FD7EFF7D7DFD7EFFA8A8FD7EFFA87DFD7EFFA8A8FD7EFFA87DFD7E
+%FFA8A8FD7EFFA87DFD7EFFFD04A87DA8A8A87DA8A8A87DA8A8A87DA8A8A8
+%7DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8
+%A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A8
+%7DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8
+%A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DFD7FFFFF
+%%EndData
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Adobe_level2_AI5 1.2 0
+%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
+%%Version: 1.2 0
+%%CreationDate: (04/10/93) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+userdict /Adobe_level2_AI5 26 dict dup begin
+	put
+	/packedarray where not
+	{
+		userdict begin
+		/packedarray
+		{
+			array astore readonly
+		} bind def
+		/setpacking /pop load def
+		/currentpacking false def
+	 end
+		0
+	} if
+	pop
+	userdict /defaultpacking currentpacking put true setpacking
+	/initialize
+	{
+		Adobe_level2_AI5 begin
+	} bind def
+	/terminate
+	{
+		currentdict Adobe_level2_AI5 eq
+		{
+		 end
+		} if
+	} bind def
+	mark
+	/setcustomcolor where not
+	{
+		/findcmykcustomcolor
+		{
+			(AI8_CMYK_CustomColor)
+			6 packedarray
+		} bind def
+		/findrgbcustomcolor
+		{
+			(AI8_RGB_CustomColor)
+			5 packedarray
+		} bind def
+		/setcustomcolor
+		{
+			exch 
+			aload pop dup
+			(AI8_CMYK_CustomColor) eq
+			{
+				pop pop
+				4
+				{
+					4 index mul
+					4 1 roll
+				} repeat
+				5 -1 roll pop
+				setcmykcolor
+			}
+			{
+				dup (AI8_RGB_CustomColor) eq
+				{
+					pop pop
+					3
+					{
+						1 exch sub
+						3 index mul 
+						1 exch sub
+						3 1 roll
+					} repeat
+					4 -1 roll pop
+					setrgbcolor
+				}
+				{
+					pop
+					4
+					{
+						4 index mul 4 1 roll
+					} repeat
+					5 -1 roll pop
+					setcmykcolor
+				} ifelse
+			} ifelse
+		}
+		def
+	} if
+	/setAIseparationgray
+	{
+		false setoverprint
+		0 setgray
+		/setseparationgray where{
+			pop setseparationgray
+		}{
+			/setcolorspace where{
+				pop
+				[/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace
+				1 exch sub setcolor
+			}{
+				setgray
+			}ifelse
+		}ifelse
+	} def
+	
+	/gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
+	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
+	userdict /level2?
+	systemdict /languagelevel known dup
+	{
+		pop systemdict /languagelevel get 2 ge
+	} if
+	put
+/level2ScreenFreq
+{
+ begin
+		60
+		HalftoneType 1 eq
+		{
+			pop Frequency
+		} if
+		HalftoneType 2 eq
+		{
+			pop GrayFrequency
+		} if
+		HalftoneType 5 eq
+		{
+			pop Default level2ScreenFreq
+		} if
+ end
+} bind def
+userdict /currentScreenFreq  
+	level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
+level2? not
+	{
+		/setcmykcolor where not
+		{
+			/setcmykcolor
+			{
+				exch .11 mul add exch .59 mul add exch .3 mul add
+				1 exch sub setgray
+			} def
+		} if
+		/currentcmykcolor where not
+		{
+			/currentcmykcolor
+			{
+				0 0 0 1 currentgray sub
+			} def
+		} if
+		/setoverprint where not
+		{
+			/setoverprint /pop load def
+		} if
+		/selectfont where not
+		{
+			/selectfont
+			{
+				exch findfont exch
+				dup type /arraytype eq
+				{
+					makefont
+				}
+				{
+					scalefont
+				} ifelse
+				setfont
+			} bind def
+		} if
+		/cshow where not
+		{
+			/cshow
+			{
+				[
+				0 0 5 -1 roll aload pop
+				] cvx bind forall
+			} bind def
+		} if
+	} if
+	cleartomark
+	/anyColor?
+	{
+		add add add 0 ne
+	} bind def
+	/testColor
+	{
+		gsave
+		setcmykcolor currentcmykcolor
+		grestore
+	} bind def
+	/testCMYKColorThrough
+	{
+		testColor anyColor?
+	} bind def
+	userdict /composite?
+	1 0 0 0 testCMYKColorThrough
+	0 1 0 0 testCMYKColorThrough
+	0 0 1 0 testCMYKColorThrough
+	0 0 0 1 testCMYKColorThrough
+	and and and
+	put
+	composite? not
+	{
+		userdict begin
+		gsave
+		/cyan? 1 0 0 0 testCMYKColorThrough def
+		/magenta? 0 1 0 0 testCMYKColorThrough def
+		/yellow? 0 0 1 0 testCMYKColorThrough def
+		/black? 0 0 0 1 testCMYKColorThrough def
+		grestore
+		/isCMYKSep? cyan? magenta? yellow? black? or or or def
+		/customColor? isCMYKSep? not def
+	 end
+	} if
+ end defaultpacking setpacking
+%%EndResource
+%%BeginResource: procset AGM_Gradient_Sep 1.0 0
+%%Title: (AGM Gradient Procset)
+%%Version: 1.0 0
+%%CreationDate: (4/26/96) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+userdict /defaultpacking currentpacking put true setpacking
+userdict /AGM_Gradient_Sep 5 dict dup begin put
+/AGM_Gradient_Sep_private 100 dict def
+/initialize{
+	AGM_Gradient_Sep begin
+	AGM_Gradient_Sep_private begin
+	_compositeJob{
+		initializeSinglePassSeps
+	}{
+		initializeMultiPassSeps
+	}ifelse
+	initializeSeps
+	AGM_Gradient_private begin
+		/_fillSD newSpotDict def
+		/_rampSD newSpotDict def
+		/_nCustomColorSD nd
+ end
+	AGM_Gradient_Sep_private 
+	{
+		dup xcheck 1 index type /arraytype eq and
+		{
+			bind
+		}if
+		pop pop
+	}forall
+	AGM_Gradient_Sep
+	{
+		dup xcheck 1 index type /arraytype eq and
+		{
+			bind
+		}if
+		pop pop
+	}forall
+ end
+	
+	currentdict readonly pop	
+ end
+}def
+/terminate{
+	currentdict AGM_Gradient_Sep eq{
+	 end
+	}if
+}def
+AGM_Gradient_Sep_private begin
+/initializeSeps{
+	/currentoverprint { _of } def
+	_noImage not _level2PS not and{
+		/linealFill{
+			currentoverprint{
+				0 0 1 1 rectfill
+			}{
+				mySave
+				8 setImageParms
+				_color{
+					_nCustomColorSD begin
+						cyan magenta yellow black
+	
+						_spotColor{
+							spot1/tintImage spot1/tintValue get 1 exch sub makeByte8 put
+							spot2/tintImage spot2/tintValue get 1 exch sub makeByte8 put
+						}if
+				 end
+	
+					4{
+						makeByte8 4 1 roll
+					}repeat
+					true 4 _nCustomColorSD ncolorimage
+				}{
+					_nCustomColorSD/black get 1 exch sub makeByte8 
+					_nCustomColorSD bwImage
+				}ifelse
+				myRestore
+			}ifelse
+		}def
+	}if
+	/_whiteBytes 1 makeByte8 pt
+	 /knockOut{
+		_noImage _level2PS or currentoverprint or{
+			gsave
+			false setoverprint
+			1 setgray 
+			0 0 1 1 rectfill
+			grestore
+		}{
+			8 setImageParms _whiteBytes /_image load 5 execImage
+		}ifelse
+	}def
+	/newSpotDict{
+		11 dict dup begin
+			/nSpots 2 def
+			/spot1 7 dict def
+			/spot2 7 dict def
+	 end
+	}def
+	/initSpotData
+	{
+	 begin
+			/name nd
+			/tintImage nd
+			/tintValue nd
+			/spot_C nd
+			/spot_M nd
+			/spot_Y nd
+			/spot_K nd
+	 end
+	}def
+	/initSpotDict{
+	 begin
+			/cyanInk nd
+			/magentaInk nd
+			/yellowInk nd
+			/blackInk nd
+			/cyan nd
+			/magenta nd
+			/yellow nd
+			/black nd
+			spot1 initSpotData
+			spot2 initSpotData
+	 end
+	}def
+	/copySpotDict{
+		/_dst xp
+	 begin
+			cyanInk magentaInk yellowInk blackInk
+			cyan magenta yellow black
+			spot1 spot2
+	 end
+		_dst begin
+			/spot1 spot1 maxlength dict def
+			/spot2 spot2 maxlength dict def
+			spot2 copy pop
+			spot1 copy pop
+			/black xd
+			/yellow xd
+			/magenta xd
+			/cyan xd
+			/blackInk xd
+			/yellowInk xd
+			/magentaInk xd
+			/cyanInk xd
+	 end
+	}def
+	/setCustomColor
+	{
+		1 index /Black eq{
+			6 1 roll 5 npop
+			1 exch sub
+			setgray
+		}{
+			6 1 roll _ccAry1 astore exch
+			dup null eq{
+				pop 0
+			}if
+			setcustomcolor
+		}ifelse
+	}def
+	/setCStop{
+		/_colorStyle exch pt
+		
+		_colorStyle 0 eq{
+			0 0 0
+			4 -1 roll
+			1 exch sub
+			_spotColor{
+				/_colorStyle 3 pt
+				/Black
+				1 index
+				1 exch sub
+			}if
+		}if
+		_colorStyle 2 eq{
+			3 npop
+		}if
+		_rampSD _fillSD copySpotDict
+		
+		_colorStyle 4 eq{ 
+			pop
+			9 2 roll 3 npop 6 -2 roll
+		} if
+		
+		_colorStyle 3 eq _colorStyle 4 eq or{ 	
+				
+			_fillSD begin
+				/_spot1 spot1 pt
+				/_spot2 spot2 pt
+		 end
+			
+			exch dup _spot1/name get eq{
+				_spot1 _spot2
+			}{
+				_spot2 _spot1
+			}ifelse
+		 begin
+			 begin
+					/name xd
+					1 exch sub /tintValue xd
+					4{
+						tintValue mul 4 1 roll
+					}repeat
+					_spotColor not{
+						/tintValue null def
+					}if
+			 end
+				/tintValue 0 def
+		 end
+		}if
+		_fillSD nsetcustomcolor
+	}def
+	/renderCMYK{
+		spot1/name get null eq
+		spot2/name get null eq and
+		dup not{
+			pop
+			spot1 spotConverted
+		}if
+		dup not{
+			pop
+			spot2 spotConverted
+		}if
+	}def
+	/currentInk{
+		true
+		_inRipSep{
+			currentcolorspace 0 get
+			dup /DeviceGray eq
+			1 index /DeviceCMYK eq or{
+				pop
+				currentcmykcolor add add add 0 eq{
+					pop false
+				}if
+			}{
+				/Separation eq{
+					currentcolor 0 eq{
+						pop false
+					}if
+				}if
+			}ifelse
+		}{
+			currentgray 1 eq{
+				pop false
+			}if
+		}ifelse
+	}def
+	/currentInkN{
+	
+		_nCustomColorSD begin
+			/_spot1 spot1 pt
+			/_spot2 spot2 pt
+			renderCMYK
+	 end
+		{
+			currentInk
+		}{
+			gsave
+			_spot1 begin
+				name null ne{
+					spot_C spot_M spot_Y spot_K name tintValue setCustomColor
+					currentInk
+				}{
+					false
+				}ifelse
+		 end
+			_spot2 begin
+				name null ne{
+					spot_C spot_M spot_Y spot_K name tintValue setCustomColor
+					currentInk
+				}{
+					false
+				}ifelse
+		 end
+			grestore
+			
+			or
+		} ifelse
+	}def
+	/fill_ /fill load def
+	/fillOvp{
+		currentoverprint{
+			_inRipSep{
+				currentcolorspace 0 get
+				dup /DeviceGray eq
+				1 index /DeviceCMYK eq or{
+					pop
+					currentcmykcolor add add add 0 eq{
+						newpath
+					}if
+				}{
+					/Separation eq{
+						currentcolor 0 eq{
+							newpath
+						}if
+					}if
+				}ifelse
+			}{
+				currentgray 1 eq{
+					newpath
+				}if
+			}ifelse
+		}if
+		fill_
+	}def
+	/fill{
+		_nCustomColorSD begin
+			/_spot1 spot1 pt
+			/_spot2 spot2 pt
+			renderCMYK
+	 end
+		
+		{
+			fillOvp
+		}{
+			_spot1 begin
+				gsave
+				name null ne{
+					spot_C spot_M spot_Y spot_K name tintValue setCustomColor
+				}{
+					1 setgray
+				}ifelse
+				fillOvp 
+				grestore
+		 end
+			_spot2 begin
+				name null ne{
+					gsave
+					true setoverprint
+					spot_C spot_M spot_Y spot_K name tintValue setCustomColor
+					fillOvp
+					grestore
+				}if
+		 end
+			newpath
+		}ifelse
+	}def
+	/expandSpot{
+		_spotColor{
+			/_len xp
+			_rampSD begin
+				spot1 begin
+					tintImage null ne{
+						tintImage _len expandOne /tintImage xd
+					}if
+			 end
+				spot2 begin
+					tintImage null ne{
+						tintImage _len expandOne /tintImage xd
+					}if
+			 end
+		 end
+		}{
+			pop
+		}ifelse
+	}def
+	/rampImage{
+		currentoverprint{
+			rectImage
+		}{
+			_enabledSmoothShade{
+				fillRamp
+			}{
+				_color{
+					_rampSD begin
+						/cyanInk _cyanData 0 ne def
+						/magentaInk _magentaData 0 ne def
+						/yellowInk _yellowData 0 ne def
+						/blackInk _blackData 0 ne def
+				 end
+					
+					_nSamples setImageParms
+					_nSamples expandSpot
+					_cyanData _magentaData _yellowData _blackData _nSamples 4 expandColor
+					true 4 _rampSD ncolorimage
+				}{
+					_rampSD begin
+						/cyanInk false def
+						/magentaInk false def
+						/yellowInk false def
+						/blackInk true def
+				 end
+					_nSamples setImageParms 
+					_blackData _rampSD bwImage
+				}ifelse
+			}ifelse
+		}ifelse
+	}def
+	/nsetcustomcolor where{
+		pop
+	}{
+		/nsetcustomcolor
+		{
+			/_nCustomColorSD xp
+			_nCustomColorSD begin
+				4 copy
+				/black xd
+				/yellow xd
+				/magenta xd
+				/cyan xd
+				4 copy
+				0 ne /blackInk xd
+				0 ne /yellowInk xd
+				0 ne /magentaInk xd
+				0 ne /cyanInk xd
+		 end
+			setcmykcolor
+		}def
+	}ifelse
+	/nsetcustomcolorend where{
+		pop
+	}{
+		/nsetcustomcolorend
+		{
+			/_nCustomColorSD null pt
+		}def
+	}ifelse
+}def
+/initializeSinglePassSeps{
+	/_decodeNorm	[0 1] pt
+	/_decodeInvert 	[1 0] pt
+	/spotConverted
+	{
+	 begin
+			name null eq{
+				false
+			}{
+				tintValue null eq tintImage null eq and{
+					true
+				}{
+					_inDistiller{
+						false
+					}{
+						false
+						currentpagedevice/SeparationColorNames get{name eq or}forall
+						not
+					}ifelse
+				}ifelse
+			}ifelse
+	 end
+	}def
+	/dictImage
+	{
+		20 dict dup begin
+			/Dict xd
+			/Decode xd
+			/DataSource xd
+			/ImageMatrix xd
+			/BitsPerComponent xd
+			/Height xd
+			/Width xd
+			/ImageType 1 def
+			Dict
+	 end
+		/_image load 1 execImage
+	}def
+	/bwImage{
+	 begin
+			gsave
+			currentoverprint{
+				blackInk{
+					[/Separation /Black /DeviceGray{}] setcolorspace
+					_decodeInvert dictImage
+				}{
+					5 npop
+				}ifelse
+			}{
+				/DeviceGray setcolorspace
+				_decodeNorm dictImage
+			}ifelse
+			grestore
+	 end
+	}def
+	/ncolorimage where{
+		pop
+	}{
+		/ncolorimage{
+		 begin
+				renderCMYK{
+					cyanInk 
+					magentaInk and
+					yellowInk and
+					blackInk and
+					not
+					currentoverprint 
+					and{	
+						pop pop
+						gsave
+						cyanInk{
+							8 copy
+							[/Separation /Cyan /DeviceGray{}] setcolorspace
+							3 npop
+							_decodeNorm dictImage
+						}if
+						magentaInk{
+							8 copy
+							[/Separation /Magenta /DeviceGray{}] setcolorspace
+							4 -1 roll
+							3 npop
+							_decodeNorm dictImage
+						}if
+						yellowInk{
+							8 copy
+							[/Separation /Yellow /DeviceGray{}] setcolorspace
+							4 -2 roll
+							3 npop
+							_decodeNorm dictImage
+						}if
+						blackInk{
+							4 -3 roll
+							[/Separation /Black /DeviceGray{}] setcolorspace
+							3 npop
+							_decodeNorm dictImage
+						}{
+							8 npop
+						}ifelse
+						grestore
+					}{
+						/_colorimage load 10 execImage
+					}ifelse
+				}{
+					6 npop
+					gsave
+					spot1 begin
+						name null ne tintImage null ne and{
+							[/Separation name /DeviceGray{}] setcolorspace
+							4 copy
+							tintImage 
+							name /Black eq{
+								_decodeNorm
+							}{
+								_decodeInvert
+							}ifelse 
+							dictImage
+						}{
+							1 setgray fill
+						}ifelse
+				 end
+					spot2 begin
+						true setoverprint
+						name null ne tintImage null ne and{
+							[/Separation name /DeviceGray{}] setcolorspace
+							tintImage 
+							name /Black eq{
+								_decodeNorm
+							}{
+								_decodeInvert
+							}ifelse 
+							dictImage
+						}{
+							4 npop
+							1 setgray fill
+						}ifelse
+				 end
+					grestore
+				}ifelse
+		 end
+		}def
+	}ifelse
+	/getRampColorSpace{
+		
+		/_renderCMYK _rampSD begin renderCMYK end pt
+		
+		_renderCMYK not{
+			_rampSD begin
+				[/DeviceN 
+					[
+					spot1 begin
+						name null ne tintImage null ne and{
+							name
+						}if
+				 end
+					spot2 begin
+						name null ne tintImage null ne and{
+							name
+						}if
+				 end
+					]
+					_inDistiller {
+						/DeviceCMYK [
+							spot1 begin
+								name null ne tintImage null ne and{
+									spot_C spot_M spot_Y spot_K 1
+								}{
+									0 0 0 0 0
+								}ifelse
+						 end
+							spot2 begin
+								name null ne tintImage null ne and{
+									spot_C spot_M spot_Y spot_K 2
+								}{
+									0 0 0 0 0
+								}ifelse
+						 end
+							5 1 roll 6 -2 roll add
+							dup 1 eq {
+								pop
+								8 /index cvx 1 /exch cvx /sub cvx
+								9 1 /roll cvx
+							}{
+								2 eq {
+									8 /index cvx 1 /exch cvx /sub cvx
+									10 1 /roll cvx
+								}if
+							}ifelse
+							4 1 /roll cvx 5 -2 /roll cvx
+							8 /index cvx /mul cvx /exch cvx 9 /index cvx /mul cvx /add cvx 7 1 /roll cvx
+							3 1 /roll cvx 4 -2 /roll cvx
+							7 /index cvx /mul cvx /exch cvx 8 /index cvx /mul cvx /add cvx 6 1 /roll cvx
+							2 1 /roll cvx 3 -2 /roll cvx
+							6 /index cvx /mul cvx /exch cvx 7 /index cvx /mul cvx /add cvx 5 1 /roll cvx
+							5 /index cvx /mul cvx /exch cvx 6 /index cvx /mul cvx /add cvx 4 1 /roll cvx
+							6 -2 /roll cvx /pop cvx /pop cvx
+						] cvx bind
+					}{
+						/DeviceCMYK {}
+					}ifelse
+				] setcolorspace
+		 end
+			/_nColorSpace currentcolorspace pt
+		}if
+		
+		_nSamples 1 gt{ 
+			/_ndx 0 pt
+			[blendColor] cvx exec
+		}if
+		_renderCMYK{
+			/_C0 [currentcolor] pt
+			/_C0_Space currentcolorspace pt
+		}{
+			/_C0 [
+				_nCustomColorSD begin
+					spot1 begin 
+						name null ne{
+							tintValue
+						}if
+				 end
+					spot2 begin 
+						name null ne{
+							tintValue
+						}if
+				 end
+			 end
+			] pt
+			/_C0_Space _nColorSpace pt
+		}ifelse
+		
+		_nSamples 1 gt{ 
+			/_ndx _nSamples 1 sub pt
+			[blendColor] cvx exec
+		}if
+		_renderCMYK{
+			/_C1 [currentcolor] pt
+			/_C1_Space currentcolorspace pt
+		}{
+			/_C1 [
+				_nCustomColorSD begin
+					spot1 begin 
+						name null ne{
+							tintValue
+						}if
+				 end
+					spot2 begin 
+						name null ne{
+							tintValue
+						}if
+				 end
+			 end
+			] pt
+			/_C1_Space _nColorSpace pt
+		}ifelse
+		
+		/_rampColorSpace _C0_Space pt
+		_spotColor{
+			nsetcustomcolorend
+		}if
+	}def
+}def
+/initializeMultiPassSeps{
+	/invertXfer{
+		[
+		{
+			1 exch sub
+		}/exec load systemdict /currenttransfer get exec /exec load
+		] cvx systemdict /settransfer get exec
+	}def
+	/ccThrough{
+		gsave
+		1 setCustomColor
+		currentcmykcolor
+		grestore
+		add add add 0 ne
+	}def
+	/spotConverted
+	{
+	 begin
+			_isCMYKSep not{
+				false
+			}{
+				name null eq{
+					false
+				}{
+					tintValue null eq tintImage null eq and{
+						true
+					}{
+						spot_C spot_M spot_Y spot_K name ccThrough
+					}ifelse
+				}ifelse
+			}ifelse
+	 end
+	}def
+	/spotChannel
+	{
+		_isCMYKSep{
+			pop false
+		}{
+			/_spotDict xp
+				_spotDict/name get null eq{
+					false
+				}{
+					_spotDict/spot_C get
+					_spotDict/spot_M get
+					_spotDict/spot_Y get
+					_spotDict/spot_K get
+					_spotDict/name get
+					ccThrough 
+				}ifelse
+		}ifelse
+	}def
+	/getChannelData
+	{
+		_isCMYKSep dup{
+			pop renderCMYK
+		}if
+		{
+			_blackPlate{
+				4 1 roll 3 npop blackInk
+			}{
+				_yellowPlate{
+					4 2 roll 3 npop yellowInk
+				}{
+					_magentaPlate{
+						4 3 roll 3 npop magentaInk
+					}{
+						3 npop cyanInk
+					}ifelse
+				}ifelse
+			}ifelse
+			{
+				true /nonZeroData
+			}{
+				true /zeroData
+			}ifelse
+		}{
+			4 npop
+			spot1/name get null ne 
+			spot1 spotChannel and{
+				spot1/tintImage get dup null ne{
+					false /nonZeroData
+				}{
+					pop false /noData
+				}ifelse
+			}{
+				spot2/name get null ne 
+				spot2 spotChannel and{
+					spot2/tintImage get dup null ne{
+						false /nonZeroData
+					}{
+						pop false /noData
+					}ifelse
+				}{
+					false /noData
+				}ifelse
+			}ifelse
+		}ifelse
+	}def
+	/renderChannelData
+	{
+		/_tmp xp
+		_tmp /nonZeroData ne currentoverprint and{
+			pop
+			_tmp /zeroData eq{pop}if
+			4 npop
+		}{
+			_tmp /nonZeroData eq{
+				{
+					invertXfer
+				}if
+					systemdict/image
+				get 5 execImage
+			}{
+				pop
+				_tmp /zeroData eq{pop}if
+				4 npop
+				knockOut
+			}ifelse
+		}ifelse
+	}def
+	/bwImage{
+	 begin
+			gsave
+			dup dup dup
+			getChannelData
+			exch pop false exch
+			renderChannelData
+			grestore
+	 end
+	}def
+	/ncolorimage{
+	 begin
+			pop pop
+			gsave
+			spot2/name get null ne spot2 spotChannel and{
+				true setoverprint
+			}if
+			getChannelData 
+			renderChannelData
+			grestore
+	 end
+	}def
+	/getRampColorSpace{
+		
+		/_renderCMYK _rampSD begin renderCMYK end pt
+		
+		_nSamples 1 gt{ 
+			/_ndx 0 pt
+			[blendColor] cvx exec
+		}if
+		
+		_renderCMYK{
+			/_C0 [currentcolor] pt
+			/_C0_Space currentcolorspace pt
+		}{
+			/_C0 [
+				_nCustomColorSD begin
+					0
+					spot1 begin 
+						name null ne
+						tintValue null ne and
+						spot1 spotChannel and{
+							pop tintValue
+						}if
+				 end
+					spot2 begin 
+						name null ne
+						tintValue null ne and
+						spot2 spotChannel and{
+							pop tintValue
+						}if
+				 end
+					1 exch sub
+			 end
+			] pt
+			/_C0_Space /DeviceGray pt
+		}ifelse
+		
+		_nSamples 1 gt{ 
+			/_ndx _nSamples 1 sub pt
+			[blendColor] cvx exec
+		}if
+		
+		_renderCMYK{
+			/_C1 [currentcolor] pt
+			/_C1_Space currentcolorspace pt
+		}{
+			/_C1 [
+				_nCustomColorSD begin
+					0
+					spot1 begin 
+						name null ne
+						tintValue null ne and
+						spot1 spotChannel and{
+							pop tintValue
+						}if
+				 end
+					spot2 begin 
+						name null ne
+						tintValue null ne and
+						spot2 spotChannel and{
+							pop tintValue
+						}if
+				 end
+					1 exch sub
+			 end
+			] pt
+			/_C1_Space /DeviceGray pt
+		}ifelse
+		
+		/_rampColorSpace _C0_Space pt
+		_spotColor{
+			nsetcustomcolorend
+		}if
+	}def
+}def
+end
+end
+defaultpacking setpacking
+%%EndResource
+%%BeginResource: procset AGM_Gradient 1.0 0
+%%Title: (AGM Gradient Procset)
+%%Version: 1.0 0
+%%CreationDate: (4/26/96) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+userdict /defaultpacking currentpacking put true setpacking
+userdict /AGM_Gradient 20 dict dup begin put
+/AGM_Gradient_private 201 dict def
+/initialize
+{
+	AGM_Gradient begin
+	AGM_Gradient_private begin
+	initializeVars
+	
+	/bd systemdict/mark get def
+	/ed
+		_level2PS 
+		{
+			(>>)
+		}{
+			(counttomark 2 idiv dup dict begin {def} repeat pop currentdict end)
+		} ifelse
+	cvx def
+	
+	_level2PS{
+		initializeLev2
+	}{
+		initializeLev1
+	}ifelse
+	
+	queryDevice
+	
+	initializeRectFill
+	initializeShading
+	initializeOps
+	_producingSeps{
+		AGM_Gradient_Sep/initialize get exec
+	}{
+		initializeComposite
+	}ifelse
+	_illustrator{
+		/f{}def
+		/F{}def
+		/s{}def
+		/S{}def
+		/b{}def
+		/B{}def
+	}if
+	/image where{
+		/image get /_image xd
+	}if
+	/colorimage where{
+		/colorimage get /_colorimage xd
+	}if
+	AGM_Gradient_private
+	{
+		dup xcheck 1 index type /arraytype eq and
+		{
+			bind
+		}if
+		pop pop
+	}forall
+	AGM_Gradient
+	{
+		dup xcheck 1 index type /arraytype eq and
+		{
+			bind
+		}if
+		pop pop
+	}forall
+ end
+	
+	currentdict readonly pop
+ end
+}def
+/initializeAI
+{
+	pop pop 
+	AGM_Gradient/AGM_Gradient_private get /_illustrator true put
+	AGM_Gradient/initialize get exec
+		AGM_Gradient begin
+}def
+/unload{
+	systemdict/languagelevel known{
+		systemdict/languagelevel get 2 ge{
+			userdict/AGM_Gradient_Sep 2 copy known{
+				undef
+			}{
+				pop pop
+			}ifelse
+			userdict/AGM_Gradient 2 copy known{
+				undef
+			}{
+				pop pop
+			}ifelse
+		}if
+	}if
+}def
+/terminate{
+	currentdict AGM_Gradient eq{
+	 end
+	}if
+}def
+ 
+AGM_Gradient_private begin
+/initializeVars{
+	/_d255 256 array def
+	0 1 255{
+		_d255 exch dup 255 div put
+	}bind for
+	/_d255- 256 array def
+	0 1 255{
+		_d255- exch 1 _d255 2 index get sub put
+	}bind for
+	/_sSave nd
+	/_dUserSpace matrix defaultmatrix def
+	/_bUMatrix matrix def
+	/_imageMatrix matrix def
+	/_saveMatrix matrix def
+	/_xm matrix def
+	/_ccAry1 5 array def
+	/_bbox 4 array pt
+	/_level2PS 
+		systemdict/languagelevel known dup{
+			pop systemdict/languagelevel get 2 ge
+		}if
+	def
+	/_level3PS
+		_level2PS systemdict/shfill known and
+	def
+	currentdict /_illustrator known not{
+		/_illustrator false def
+	}if
+	
+}def
+/initializeOps
+{
+	AGM_Gradient begin
+	currentdict/Bc known not{
+		/Bc{
+		
+			_renderFlag 2 eq _enabledSmoothShade or{
+				6 npop
+			}{
+				pushBSpace
+				_rampIndex 0 eq{
+					pop pop
+					setCStop
+				}if
+				linealFill
+				popBSpace
+			}ifelse
+		
+		}def
+	}if
+	
+	currentdict/Bg known not{
+		/Bg{
+			10 npop
+			/_gradName xp
+			/_renderFlag xp
+			/_enabledSmoothShade false pt
+		
+			_renderFlag 2 ne{
+		
+				_illustrator{
+					_of setoverprint
+				}if
+		
+				/_enabledSmoothShade 
+					_level3PS{
+						_usingSmoothShade
+						_producingSeps not
+						currentoverprint not or and
+						_noImage not and
+					}{
+						false
+					}ifelse
+				pt
+				
+				_illustrator _eo and _renderFlag 3 eq or{
+					eoclip
+				}{
+					clip
+				}ifelse
+		
+				_gradNames _gradName 2 copy known{
+					get
+					mark exch aload pop
+					/_gradType xp
+					1 sub dup /_rampIndex xp
+					/_maxRampIndex xp
+					mark exch aload pop
+					0 0
+				}if
+				pop pop
+				getRampData
+			}{
+				mark mark
+			}ifelse
+		}def
+	}if
+	
+	currentdict/Bm known not{
+		/Bm{
+			_renderFlag 2 ne{
+				_gradType 0 eq{
+					linealRamp
+				}{
+					radialGrad
+				}ifelse
+			}{
+				6 npop
+			}ifelse
+		}def
+	}if
+	
+	currentdict/Bh known not{
+		/Bh{
+			2 npop
+			/_yHi xp
+			/_xHi xp
+			/_radHilite _xHi 0 ne _yHi 0 ne or pt
+		}def
+	}if
+	
+	currentdict/Bn known not{
+		/Bn{
+			AGM_Gradient_private begin
+				dict /_gradNames xp
+		 end
+		}def
+	}if
+	
+	currentdict/Bd known not{
+		/Bd{
+			AGM_Gradient begin
+			AGM_Gradient_private begin
+				/_nColorsBd xp
+				/_gradType xp
+				/_gradName xp
+		}def
+	}if
+	
+	currentdict/BD known not{
+		/BD{
+				currentdict/_gradNames known not{
+					/_gradNames 20 dict def
+				}if
+				] _nColorsBd _gradType
+				]  _gradName exch /_gradNames xput
+		 end
+		 end
+		}def
+	}if
+	
+	currentdict/Bb known not{
+		/Bb{
+		
+			AGM_Gradient/AGM_Gradient_private get /_illustrator get not{
+				AGM_Gradient begin
+			}if
+			AGM_Gradient_private begin
+			_producingSeps{
+				AGM_Gradient_Sep/AGM_Gradient_Sep_private get begin
+			}if
+			mySave
+		}def
+	}if
+	
+	currentdict/BB known not{
+		/BB{
+		
+			/_tmp xp
+			cleartomark cleartomark
+		
+			_tmp dup
+			_renderFlag
+		
+			myRestore
+		
+			_producingSeps{
+			 end
+			}if
+		
+			_illustrator dup
+		 end
+			not {
+			 end
+			}if
+		
+			{
+				2 ne exch 0 gt and{
+					2 eq{
+						s
+					}{
+						S
+					}ifelse
+				}{
+					pop newpath
+				}ifelse
+			}{
+				pop newpath
+			}ifelse
+		
+		
+		}def
+	}if
+	
+	currentdict/Xm known not{
+		/Xm{
+			_xm astore pop
+		}def
+	}if
+	
+ end
+}def
+/queryDevice{
+	/_inDistiller
+		systemdict /currentdistillerparams known
+	def
+	/_inRipSep
+		_level2PS{
+			currentpagedevice/Separations 2 copy known{
+				get
+			}{
+				pop pop false
+			}ifelse
+		}{
+			false
+		}ifelse
+		_inDistiller or
+	def
+	/_noImage /lv1Fix where{
+		pop lv1Fix
+	}{
+		false
+	}ifelse
+	def
+	/_useShells where{
+		/_useShells get /_usingShells xp
+	}{
+		/_usingShells false def
+	}ifelse
+	
+	/_useSmoothShade where{
+		pop
+	}{
+		/_useSmoothShade false def 
+	}ifelse
+	/_forceToCMYK where{
+		pop
+	}{
+		/_forceToCMYK false def 
+	}ifelse
+	/_cyanPlate 1 0 0 0 testCMYKColorThrough def
+	/_magentaPlate 0 1 0 0 testCMYKColorThrough def
+	/_yellowPlate 0 0 1 0 testCMYKColorThrough def
+	/_blackPlate 0 0 0 1 testCMYKColorThrough def
+	/_compositeJob
+		_cyanPlate _magentaPlate and _yellowPlate and _blackPlate and
+	def
+	/_isCMYKSep
+		_cyanPlate _magentaPlate or _yellowPlate or _blackPlate or
+	def
+	/_compositeSpotDevice where{
+		pop
+	}{
+		/_compositeSpotDevice _compositeJob not _inRipSep or{
+			1
+		}{
+			0
+		}ifelse
+		def
+	}ifelse
+	/_producingSeps _compositeSpotDevice 0 ne def
+	/_deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt def
+	/_dpiThreshold where{
+		pop
+	}{
+		/_dpiThreshold 600 def
+	}ifelse
+	/_screenFreqThreshold where{
+		pop
+	}{
+		/_screenFreqThreshold 150 def
+	}ifelse
+	/_contoneDevice where{
+		pop
+	}{
+		/_contoneDevice false def
+	}ifelse
+	/_subSampleOK 
+		_deviceDPI _dpiThreshold le 
+		currentScreenFreq _screenFreqThreshold le and 
+		_contoneDevice not and 
+	def
+}def
+/initializeRectFill{
+	/rectfill where dup{
+		exch pop not _producingSeps or
+	}{
+		not
+	}ifelse
+	{
+		/rectfill{
+			gsave
+			newpath
+			4 2 roll moveto
+			1 index 0 rlineto
+			0 1 index rlineto
+			1 index neg 0 rlineto
+			pop pop
+			closepath
+			fill
+			grestore
+		}def
+	}if
+}def
+/initializeLev1{
+	/currentScreenFreq{
+		currentscreen pop pop
+	}def
+	/_byte 1 string def
+	/colorimage where{
+		pop
+	}{
+		/colorimage{
+			pop pop
+			/_blackTmp xp
+			/_yellowTmp xp
+			/_magentaTmp xp
+			/_cyanTmp xp
+			/_cnt 0 pt
+			[
+			_byte dup 0
+			_cyanTmp 
+				/_cnt cvx /get cvx _d255 /exch cvx /get cvx .3 /mul cvx
+			_magentaTmp
+				/_cnt cvx /get cvx _d255 /exch cvx /get cvx .59 /mul cvx
+			_yellowTmp
+				/_cnt cvx /get cvx _d255 /exch cvx /get cvx .11 /mul cvx
+			_blackTmp 
+				/_cnt cvx /get cvx _d255 /exch cvx /get cvx
+			/add cvx /add cvx /add cvx 1 /exch cvx /sub cvx
+			/dup cvx 0 /lt cvx{
+				pop 0
+			}/if cvx
+			/dup cvx 1 /gt cvx{
+				pop 1
+			}/if cvx
+			255 /mul cvx /cvi cvx
+			256 /mod cvx
+			/dup cvx 0 /lt cvx{
+				pop 0
+			}/if cvx
+			/put cvx
+			/_cnt dup cvx 1 /add cvx /pt cvx
+			] cvx
+			bind
+			/_image load 5 execImage
+		}def
+	}ifelse
+}def
+/initializeLev2{
+	/level2ScreenFreq{
+	 begin
+		60
+		HalftoneType 1 eq{
+			pop Frequency
+		}if
+		HalftoneType 2 eq{
+			pop GrayFrequency
+		}if
+		HalftoneType 5 eq{
+			pop Default level2ScreenFreq
+		}if
+		 end
+	}def
+	/currentScreenFreq{
+		currenthalftone level2ScreenFreq
+	}def
+}def
+/initializeShading{
+	_useSmoothShade _level3PS and{
+		/_usingSmoothShade true pt
+		initializeLev3_Ops
+	}{
+		/_usingSmoothShade false pt
+	}ifelse
+}def
+/initializeLev3_Ops
+{
+	/initShFill{
+		/_index _gradType 0 eq {0}{_maxRampIndex 1 sub} ifelse pt
+		/_rampFuncsArray _maxRampIndex array pt
+		/_boundsArray _maxRampIndex 1 sub array pt
+		/_encodeArray _maxRampIndex 2 mul array pt
+		/_beginCoord _rampPoint pt
+		/_colorSpace null pt
+		/_firstFill _rampIndex _maxRampIndex eq pt
+		/_lastFill false pt
+	}def
+	/linealShFill{
+		popBSpace
+		_xm aload pop pushBSpace
+		
+		/_size _index 1 add pt
+		_size _maxRampIndex lt {
+			/_rampFuncsArray _rampFuncsArray 0 _size getinterval pt
+			/_boundsArray _boundsArray 0 _size 1 sub getinterval pt
+			/_encodeArray _encodeArray 0 _size 2 mul getinterval pt
+		}if
+		
+		bd
+			/ShadingType 2
+			/ColorSpace _colorSpace
+			_rgbInCMYK{
+				/Function [
+					_cData sampFunc
+					_mData sampFunc
+					_yData sampFunc
+					_kData sampFunc
+				]
+			}{
+				/Function 
+					bd
+						/FunctionType 3
+						/Domain [0 1]
+						/Functions _rampFuncsArray
+						/Bounds _boundsArray
+						/Encode _encodeArray
+					ed
+			}ifelse
+			/Extend [_firstFill _lastFill]
+			/Domain [0 1] 
+			/Coords [_beginCoord 0 _endCoord 0]
+		ed
+		shfill
+	}def
+	
+	/radialShFill{
+		/_size _maxRampIndex _index sub pt
+		_size _maxRampIndex lt {
+			/_rampFuncsArray _rampFuncsArray _index _size getinterval pt
+			/_boundsArray _boundsArray _index _size 1 sub getinterval pt
+			/_encodeArray _encodeArray _index 2 mul _size 2 mul getinterval pt
+		}if
+		
+		/_rampLen _beginCoord _endCoord sub pt
+		bd
+			/ShadingType 3
+			/ColorSpace _colorSpace
+			_rgbInCMYK{
+				/Function [
+					_cData sampFunc
+					_mData sampFunc
+					_yData sampFunc
+					_kData sampFunc
+				]
+			}{
+				/Function 
+					bd
+						/FunctionType 3
+						/Domain [0 1]
+						/Functions _rampFuncsArray
+						/Bounds _boundsArray
+						/Encode _encodeArray
+					ed
+			}ifelse
+			/Extend [_lastFill _firstFill]
+			/Domain [0 1] 
+			/Coords [_xHi _rampLen mul _yHi _rampLen mul _endCoord 0 0 _beginCoord] 
+		ed
+		shfill
+		
+		_radHilite{
+			_xHi _rampLen mul _yHi _rampLen mul translate
+		}if
+	}def
+	
+	%
+	/sampFunc{
+		/_tmp exch pt
+		bd
+			_tmp length 1 eq {
+				_tmp 0 get
+				/_tmp 2 string pt
+				dup _tmp 0 3 -1 roll put
+				_tmp 1 3 -1 roll put
+			}if
+			/FunctionType 0
+			/Order 1
+			/Size [_tmp length]
+			/Domain [0 1]
+			/BitsPerSample 8
+			/DataSource _tmp
+			/Range [0 1]
+		ed
+	}def
+	
+	/fillRamp{
+	
+	
+		/_invert _midPoint 0.5 lt pt
+		_rampIndex _maxRampIndex eq {
+			initShFill
+		}if
+		
+		getRampColorSpace
+		
+		_colorSpace null eq{
+			/_colorSpace _rampColorSpace pt
+		}{
+			_colorSpace _rampColorSpace ne _rgbInCMYK or{
+				/_index _index 1 
+				_gradType 0 eq{
+					sub pt
+					linealShFill
+				}{
+					add pt
+					radialShFill
+				}ifelse
+				initShFill
+				/_colorSpace _rampColorSpace pt
+			} if
+		}ifelse
+		/_endCoord _endPoint pt	
+		/_rgbInCMYK false pt
+		_producingSeps _forceToCMYK or _rgbRamp and {
+			_spotColor{
+				_renderCMYK
+			}{
+				_isCMYKSep
+			}ifelse
+		}{
+			false
+		}ifelse
+		{
+			_compositeJob{
+				/_rgbInCMYK true pt
+				_cyanData _magentaData _yellowData _blackData _nSamples 4 expandColor
+				dup length string copy /_kData exch pt
+				dup length string copy /_yData exch pt
+				dup length string copy /_mData exch pt
+				dup length string copy /_cData exch pt
+			}{
+				_rampFuncsArray _index
+					_cyanPlate{_cyanData}if
+						_magentaPlate{_magentaData}if
+						_yellowPlate{_yellowData}if
+						_blackPlate{_blackData}if
+					_nSamples expandOne
+					sampFunc
+					dup begin /Decode [1 0] def end
+				put
+				/_invert false pt
+			}ifelse
+		}{
+			_rampFuncsArray _index
+				bd
+					/FunctionType 2
+					/Domain [0 1]
+					/N 0.5 log _invert{1 _midPoint sub}{_midPoint}ifelse log div
+					_gradType 0 eq{
+						_invert{/C1}{/C0}ifelse _C0
+						_invert{/C0}{/C1}ifelse _C1
+					}{
+						_invert{/C0}{/C1}ifelse _C1
+						_invert{/C1}{/C0}ifelse _C0
+					}ifelse
+				ed
+			put
+		}ifelse
+		
+		_rampIndex 1 ne{
+			_boundsArray _index _gradType 1 eq{1 sub}if _endCoord put
+		} if
+		
+		0 1 _invert {exch}if
+		_encodeArray _index 2 mul 1 add 3 -1 roll put
+		_encodeArray _index 2 mul 3 -1 roll put
+		_rampIndex 1 eq {
+			/_lastFill true pt
+			_gradType 0 eq{
+				linealShFill
+			}{
+				radialShFill
+			}ifelse
+		}if
+		/_index _index 1 
+		_gradType 0 eq{
+			add pt
+		}{
+			sub pt
+		}ifelse
+	}def
+}def
+/initializeComposite{
+	/bwImage{
+		pop /_image load 5 execImage 
+	}def
+	/rampImage{
+		_enabledSmoothShade{
+			fillRamp
+		}{
+			_color{
+				_nSamples setImageParms
+	
+				
+				_rgbRamp _forceToCMYK not and{
+					_redData _greenData _blueData _nSamples 3 expandColor
+					true 3 null ncolorimage
+				}{
+					_cyanData _magentaData _yellowData _blackData _nSamples 4 expandColor
+					true 4 null ncolorimage
+				}ifelse
+			}{
+				_nSamples setImageParms _blackData null bwImage
+			}ifelse
+		}ifelse
+	}def
+	/setCStop{
+		/_colorStyle exch pt
+		_colorStyle 0 eq{
+			1 exch sub
+			0 0 0
+			4 -1 roll
+		}if
+		
+		_colorStyle 2 eq{
+			_forceToCMYK{
+				3 npop setcmykcolor
+			}{
+				setrgbcolor 4 npop
+			}ifelse
+		}if
+		
+		_colorStyle 3 eq{
+			1 exch sub /_tmp xp
+			pop
+			4{
+				_tmp mul 4 1 roll
+			}repeat
+		}if
+		
+		_colorStyle 4 eq{
+			_forceToCMYK{
+				6 npop setcmykcolor
+			}{
+				3 -1 roll pop pop
+				1 exch sub /_tmp xp
+				3{
+					1 exch sub _tmp mul 1 exch sub 3 1 roll
+				}repeat
+				setrgbcolor 
+				4 npop
+			}ifelse
+		}if
+		_colorStyle 2 ne _colorStyle 4 ne and{
+			null nsetcustomcolor
+		}if
+	}def
+	/nsetcustomcolor
+	{
+		pop setcmykcolor
+	}def
+	/nsetcustomcolorend
+	{
+	}def
+	/ncolorimage{
+		pop 
+		/_colorimage load 10 execImage
+	}def
+	_noImage not _level2PS not and{
+		/linealFill{
+			8 setImageParms
+			_color{
+				currentcmykcolor
+				4{
+					makeByte8 4 1 roll
+				}repeat
+				true 4 null ncolorimage
+			}{
+				currentgray makeByte8 null bwImage
+			}ifelse
+		}def
+	}if
+	/getRampColorSpace{
+		_nSamples 1 gt{ 
+			/_ndx 0 pt
+			[blendColor] cvx exec
+		}if
+		/_C0 [currentcolor] pt
+		/_C0_Space currentcolorspace pt
+		
+		_nSamples 1 gt{ 
+			/_ndx _nSamples 1 sub pt
+			[blendColor] cvx exec
+		}if
+		/_C1 [currentcolor] pt
+		/_C1_Space currentcolorspace pt
+		
+		/_rampColorSpace _C0_Space pt
+		
+		_spotColor{
+			nsetcustomcolorend
+		}if
+	}def
+}def
+/npop{
+	{pop}repeat
+}def
+/xd{
+	exch def
+}def
+/nd{
+	null def
+}def
+/pt{
+	AGM_Gradient_private 3 1 roll put
+}def
+/xp{
+	exch pt
+}def
+/xput{
+	dup load dup length exch maxlength eq{
+		dup dup load dup
+		length 2 mul dict copy def
+	}if
+	load begin
+		def
+  end
+}def
+/mySave{
+	save /_sSave xp
+}def
+/myRestore{
+	_sSave type /savetype eq{
+		_sSave restore
+	}if
+}def
+/gMark{
+	counttomark 2 add -1 roll
+}def
+/execImage{
+	/_tmp xp
+	{
+		exec
+	}stopped{
+		$error /errorname get /undefinedresult ne{
+			stop
+		}{
+			_tmp npop
+		}ifelse
+	}if
+}def
+/pushBSpace{
+	newpath gsave
+	_bUMatrix astore concat 
+}def
+/popBSpace{
+	grestore
+}def
+/makeByte8{
+	/_tmp 0 pt
+	255 mul cvi
+	8 string 8{
+		dup _tmp 3 index put 
+		/_tmp _tmp 1 add pt
+	}repeat
+	exch pop
+}def
+/setImageParms{
+	1 8 2 index 0 0 1 0 0 _imageMatrix astore
+}def
+/linealFill{
+	0 0 1 1 rectfill
+}def
+/testCMYKColorThrough{
+	gsave
+	setcmykcolor currentcmykcolor
+	grestore
+	add add add 0 ne
+}def
+/expandOne	{
+	/_tmp xp
+	dup type /stringtype ne{
+		_tmp string
+		exch
+		dup 0 ne{
+			255 mul cvi
+			0 1 _tmp 1 sub{
+				3 copy
+				exch put pop
+			}for
+		}if
+		pop
+	}if
+}def
+/expandColor{
+	/_channels xp
+	/_len xp
+	_channels{
+		_len expandOne _channels 1 roll
+	}repeat
+}def
+/blendColor{
+	
+	_color{
+		_rgbRamp _producingSeps not and _forceToCMYK not and{
+			_redData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			_greenData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			_blueData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			/setrgbcolor cvx
+		}{
+			_cyanData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			_magentaData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			_yellowData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+			_blackData dup type /stringtype eq{
+				/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+			}if
+	
+			_spotColor{
+				_rampSD begin
+					/_rampSD cvx /begin cvx
+	
+					spot1 begin
+						tintImage dup type /stringtype eq{
+							/_ndx cvx /get cvx _d255- /exch cvx /get cvx
+						}{
+							dup null ne{
+								name type /nametype ne{
+									1 exch sub
+								}if
+							}if
+						}ifelse
+				 end
+					/spot1 cvx /tintValue 3 -1 /roll cvx /put cvx
+	
+					spot2 begin
+						tintImage dup type /stringtype eq{
+							/_ndx cvx /get cvx _d255- /exch cvx /get cvx
+						}{
+							dup null ne{
+								name type /nametype ne{
+									1 exch sub
+								}if
+							}if
+						}ifelse
+				 end
+					/spot2 cvx /tintValue 3 -1 /roll cvx /put cvx
+					/end cvx
+			 end
+				/_rampSD cvx
+				/nsetcustomcolor cvx
+			}{
+				/setcmykcolor cvx
+			}ifelse
+		}ifelse
+	}{
+		_blackData dup type /stringtype eq{
+			/_ndx cvx /get cvx _d255 /exch cvx /get cvx
+		}if
+		
+		_enabledSmoothShade{
+			1 /exch cvx /sub cvx 0 0 0 4 -1 /roll cvx /setcmykcolor cvx
+		}{
+			 /setgray cvx
+		}ifelse
+	}ifelse
+}def
+/useRectImage{
+	_subSampleOK _enabledSmoothShade not and{
+		{
+			mark
+			0 1 dtransform atan cvi 90 mod 0 eq
+			1 0 dtransform atan cvi 90 mod 0 eq
+		} stopped
+		{
+			cleartomark
+			false
+		}
+		{
+			and exch pop
+		} ifelse
+	}{
+		false
+	}ifelse
+}def
+/linealImage{
+	_noImage{
+		rectImage
+	}{
+		_producingSeps{
+				AGM_Gradient_Sep/AGM_Gradient_Sep_private get
+				/rampImage get exec
+		}{
+			useRectImage{
+				rectImage
+			}{
+				rampImage
+			}ifelse
+		}ifelse
+	}ifelse
+}def
+/linealRamp{
+	pushBSpace
+	_ramp{
+		linealImage
+	}{
+		linealFill
+	}ifelse
+	popBSpace
+	/_rampIndex _rampIndex 1 sub pt
+	_rampIndex 0 gt{
+		getRampData
+	}if
+}def
+/radialGrad{
+	/_usingShells currentoverprint _producingSeps and _usingShells or pt
+	/_firstShell true pt
+	_enabledSmoothShade not{
+		currentoverprint _producingSeps and{
+			
+			newpath
+			clippath pathbbox 
+			1 add 4 1 roll
+			1 add 4 1 roll
+			1 sub 4 1 roll
+			1 sub 4 1 roll
+			_bbox astore pop
+			
+			newpath
+			_bbox 0 get _bbox 1 get moveto
+			_bbox 2 get _bbox 1 get lineto
+			_bbox 2 get _bbox 3 get lineto
+			_bbox 0 get _bbox 3 get lineto
+			closepath
+			6 copy
+			gsave _bUMatrix astore concat
+			1 0 moveto 0 0 1 0 360 arc closepath
+			eoclip fill
+			popBSpace
+		}{
+			fill
+		}ifelse
+	}if
+	pushBSpace
+	
+	_radHilite{
+		_xHi _yHi _bUMatrix idtransform /_yHi xp /_xHi xp
+		_rampPoint 1 lt{
+			1 _rampPoint sub dup _xHi mul exch _yHi mul translate
+		}if
+	}if
+	_rampIndex{
+		radialRamp
+		/_rampIndex _rampIndex 1 sub pt
+		_rampIndex 0 gt{
+			getRampData
+		}if
+	}repeat
+	
+	popBSpace
+	
+}def
+/getNSamples{
+	0 exch
+	{
+		dup type /stringtype eq{
+			length exch pop exit
+		}if
+		pop
+	}forall
+	dup 0 eq{
+		pop 1
+	}if
+}def
+/getRampData{
+	/_rampType gMark pt
+	/_color _rampType 0 gt pt
+	/_ccRGB _rampType 5 eq _rampType 6 eq or pt
+	/_rgbRamp _rampType 4 eq _ccRGB or pt
+	/_ccProcess _rampType 2 eq _rampType 3 eq or pt
+	_producingSeps{
+		_rampSD initSpotDict
+		/_spotColor _ccProcess _ccRGB or pt
+	}{
+		/_spotColor false pt
+	}ifelse
+	/_ramp true pt
+	100 div /_rampPoint xp
+	100 div /_midPoint xp
+	
+	dup /_colorStyle xp
+	_colorStyle 0 eq{ 
+		2
+	}{
+		_colorStyle 1 eq{ 
+			5
+		}{
+			_colorStyle 2 eq{
+				8
+			}{
+				_colorStyle 3 eq{
+					_producingSeps{
+						_rampSD /spot1 get begin
+							/name 3 index def
+							/spot_K 4 index def
+							/spot_Y 5 index def
+							/spot_M 6 index def
+							/spot_C 7 index def
+					 end
+					}if
+					7
+				}{
+					_producingSeps{
+						_rampSD/spot1 get begin
+							/name 4 index def
+							/spot_K 8 index def
+							/spot_Y 9 index def
+							/spot_M 10 index def
+							/spot_C 11 index def
+					 end
+					}if
+					11
+				} ifelse
+			}ifelse
+		}ifelse
+	}ifelse
+	/_tmp xp
+	_tmp index 100 div /_endPoint xp
+	
+	_gradType 1 eq{
+		_tmp 1 add index 100 div /_midPoint xp
+	}if
+	
+	_producingSeps{
+		_tmp 2 add index /_nextColorStyle xp
+		_nextColorStyle 3 eq{
+			/_tmp _tmp 4 add pt
+			_tmp index dup
+			_rampSD/spot1 get /name get ne{
+				_rampSD /spot2 get begin
+					/name xd
+					/spot_K _tmp 2 add index def
+					/spot_Y _tmp 3 add index def
+					/spot_M _tmp 4 add index def
+					/spot_C _tmp 5 add index def
+			 end
+			}{
+				pop
+			}ifelse
+		}if
+		_nextColorStyle 4 eq{
+			/_tmp _tmp 5 add pt
+			_tmp index dup
+			_rampSD/spot1 get /name get ne{
+				_rampSD /spot2 get begin
+					/name xd
+					/spot_K _tmp 5 add index def
+					/spot_Y _tmp 6 add index def
+					/spot_M _tmp 7 add index def
+					/spot_C _tmp 8 add index def
+			 end
+			}{
+				pop
+			}ifelse
+		}if
+	}if
+	_rampType 3 eq _rampType 6 eq or{
+		/_tint2Data gMark pt
+	}if
+	_ccProcess _ccRGB or{
+		/_tint1Data gMark pt
+	}if
+	_rgbRamp{
+		/_blueData gMark pt
+		/_greenData gMark pt
+		/_redData gMark pt
+	}if
+	
+	_producingSeps{
+		_ccProcess _ccRGB or{
+			_rampType 3 eq _rampType 6 eq or{
+				_rampSD /spot2 get begin
+					/tintImage _gradType 0 eq{
+						_tint2Data
+					}{
+						_tint1Data
+					}ifelse
+					def
+					name null eq{
+						/name /Black def
+					}if
+			 end
+			}if
+			_rampSD /spot1 get begin
+				/tintImage _gradType 0 eq _rampType 2 eq or _rampType 5 eq or{
+					_tint1Data
+				}{
+					_tint2Data
+				}ifelse
+				def
+				_rampType 2 eq _rampType 5 eq or{
+					name null eq{
+						/name _rampSD/spot2 get /name get def
+						/spot_C _rampSD/spot2 get /spot_C get def
+						/spot_M _rampSD/spot2 get /spot_M get def
+						/spot_Y _rampSD/spot2 get /spot_Y get def
+						/spot_K _rampSD/spot2 get /spot_K get def
+						_rampSD/spot2 get /name null put
+					}if
+				}{
+					name null eq{
+						/name /Black def
+					}if
+				}ifelse
+		 end
+		}if
+	}if
+	/_blackData gMark pt
+	_rampType 0 gt{
+		counttomark 4 add -3 roll
+		/_yellowData xp
+		/_magentaData xp
+		/_cyanData xp
+	}if
+	_ramp{
+		/_nSamples
+			[
+			_rampType 0 eq {_blackData}if
+			_rampType 1 eq {_cyanData _magentaData _yellowData _blackData}if
+			_rampType 2 eq {_cyanData _magentaData _yellowData _blackData _tint1Data}if
+			_rampType 3 eq {_cyanData _magentaData _yellowData _blackData _tint1Data _tint2Data}if
+			_rampType 4 eq {_cyanData _magentaData _yellowData _blackData _redData _greenData _blueData}if
+			_rampType 5 eq {_cyanData _magentaData _yellowData _blackData _redData _greenData _blueData _tint1Data}if
+			_rampType 6 eq {_cyanData _magentaData _yellowData _blackData _redData _greenData _blueData _tint1Data _tint2Data}if
+			] getNSamples pt
+		_enabledSmoothShade not {/_ramp _nSamples 1 gt pt} if
+	} if
+	
+	setCStop
+}def
+/rectImage{
+	gsave
+	/_sInc 1 pt
+	/_bInc 1 _nSamples div pt
+	/_nSubSamples _nSamples pt
+	/_optimize false pt
+		
+	_subSampleOK{
+		/_uRampLen 1 0 dtransform _dUserSpace idtransform dup mul exch dup mul add sqrt pt
+		/_pChange _uRampLen 0 eq{0}{_nSamples _uRampLen div}ifelse pt
+		
+		_pChange .5 gt dup /_optimize xp{
+			/_nSubSamples _uRampLen 2 div round cvi dup 1 le{pop 2}if pt
+			/_bInc 1 _nSubSamples div pt
+			/_sInc _nSamples 1 sub _nSubSamples 1 sub div pt
+		}if
+	}if
+	0
+	_nSubSamples
+	[
+	/dup cvx
+	_optimize {
+		/round cvx /cvi cvx
+	} if
+	/_ndx /exch cvx /pt cvx
+	blendColor
+	0 0 _bInc 1 /rectfill cvx
+	_bInc 0 /translate cvx
+	_sInc /add cvx
+	] cvx
+	bind
+	repeat
+	pop
+	_spotColor{
+		nsetcustomcolorend
+	}if
+	grestore
+}def
+/radialInit{
+	/_nRadSamples _nSamples dup 0 eq{pop 1}if pt
+	/_sInc -1 pt
+	/_rampLen _rampPoint _endPoint sub pt
+	/_bInc _rampLen _nSamples div neg pt
+	/_optimize false pt
+	_subSampleOK{
+		/_uRampLen
+			_rampLen 0 dtransform _dUserSpace idtransform dup mul exch dup mul add sqrt
+			0 _rampLen dtransform _dUserSpace idtransform dup mul exch dup mul add sqrt
+			2 copy lt{
+				exch
+			}if pop
+		pt
+		/_pChange 
+			_uRampLen 0 eq{
+				0
+			}{
+				_nSamples _uRampLen div
+			}ifelse
+		pt
+		_pChange .5 gt dup /_optimize xp{
+			/_nRadSamples _uRampLen 2 div round cvi dup 1 le{pop 2}if pt
+			/_bInc _rampLen _nRadSamples div neg pt
+			/_sInc _nSamples 1 sub _nRadSamples 1 sub div neg pt
+		}if
+	}if
+	_radHilite{
+		/_xBCInc _xHi _rampLen mul _nRadSamples div pt
+		/_yBCInc _yHi _rampLen mul _nRadSamples div pt
+	}if
+}def
+/radialRamp{
+	_enabledSmoothShade{
+		fillRamp
+	}{
+		/_saveMatrix _saveMatrix currentmatrix def
+		
+		radialInit
+	
+		%
+		%
+		true
+		_producingSeps _rgbRamp not and{
+			_nSamples 1 gt{ 
+				pop
+				/_ndx 0 pt
+				[blendColor] cvx exec
+				currentInkN
+				/_ndx _nSamples 1 sub pt
+				[blendColor] cvx exec
+				currentInkN
+				or
+			}if
+		}if
+		{
+			_rampPoint
+		
+			_nSamples 1 sub
+		
+			_nRadSamples 
+			[
+				/dup cvx
+		
+				_optimize{
+					/round cvx /cvi cvx
+				}if
+		
+				/_ndx /exch cvx /pt cvx
+				
+				_usingShells{
+					/_firstShell cvx{
+						/_firstShell false pt
+					}{
+						0 0 3 index 360 0 arcn fill
+					}/ifelse cvx
+				}if
+		
+				blendColor
+		
+				_usingShells{
+					0 0 3 /index cvx 0 360 /arc cvx 
+				}{
+					0 0 3 /index cvx 0 360 /arc cvx /fill cvx
+				}ifelse
+		
+				/exch cvx _bInc /add cvx /exch cvx
+		
+				_sInc /add cvx
+		
+				_radHilite{
+					_xBCInc _yBCInc /translate cvx
+				}if
+			] cvx bind
+			repeat
+		
+			pop pop
+		}{
+			_usingShells{
+				0 0 _rampPoint 360 0 arcn fill
+			}if
+		}ifelse
+	
+		_saveMatrix setmatrix
+		
+		_radHilite{
+			_xHi _rampLen mul _yHi _rampLen mul translate
+		}if
+		
+		_usingShells _rampIndex 1 eq and{
+			fill
+		}if
+	
+		_spotColor{
+			nsetcustomcolorend
+		}if
+	}ifelse
+}def
+end
+end
+defaultpacking setpacking
+%%EndResource
+%%BeginProcSet: Adobe_ColorImage_AI6 1.3 0
+userdict /Adobe_ColorImage_AI6 known not
+{
+	userdict /Adobe_ColorImage_AI6 53 dict put 
+} if
+userdict /Adobe_ColorImage_AI6 get begin
+/initialize { 
+	Adobe_ColorImage_AI6 begin
+	Adobe_ColorImage_AI6 {
+		dup type /arraytype eq {
+			dup xcheck {
+				bind
+			} if
+		} if
+		pop pop
+	} forall
+} def
+/terminate { end } def
+currentdict /Adobe_ColorImage_AI6_Vars known not {
+	/Adobe_ColorImage_AI6_Vars 41 dict def
+} if
+Adobe_ColorImage_AI6_Vars begin
+	/plateindex -1 def
+	/_newproc null def
+	/_proc1 null def
+	/_proc2 null def
+	/sourcearray 4 array def
+	/_ptispace null def
+	/_ptiname null def
+	/_pti0 0 def
+	/_pti1 0 def
+	/_ptiproc null def
+	/_ptiscale 0 def
+	/_pticomps 0 def
+	/_ptibuf 0 string def
+	/_gtigray 0 def
+	/_cticmyk null def
+	/_rtirgb null def
+	/XIEnable true def
+	/XIType 0 def
+	/XIEncoding 0 def
+	/XICompression 0 def
+	/XIChannelCount 0 def
+	/XIBitsPerPixel 0 def
+	/XIImageHeight 0 def
+	/XIImageWidth 0 def
+	/XIImageMatrix null def
+	/XIRowBytes 0 def
+	/XIFile null def
+	/XIBuffer1 null def
+	/XIBuffer2 null def
+	/XIBuffer3 null def
+	/XIDataProc null def
+	/XIColorSpace /DeviceGray def
+	/XIColorValues 0 def
+	/XIPlateList false def
+end
+/ci6colorimage /colorimage where {/colorimage get}{null} ifelse def
+/ci6image systemdict /image get def
+/ci6curtransfer systemdict /currenttransfer get def
+/ci6curoverprint /currentoverprint where {/currentoverprint get}{{_of}} ifelse def
+/ci6foureq {
+	4 index ne {
+		pop pop pop false
+	}{
+		4 index ne {
+			pop pop false
+		}{
+			4 index ne {
+				pop false
+			}{
+				4 index eq
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6testplate {
+	Adobe_ColorImage_AI6_Vars begin
+		/plateindex -1 def
+		/setcmykcolor where {
+			pop
+			gsave
+			1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			grestore
+			1 0 0 0 ci6foureq { 
+				/plateindex 0 def
+			}{
+				0 1 0 0 ci6foureq { 
+					/plateindex 1 def
+				}{
+					0 0 1 0 ci6foureq {
+						/plateindex 2 def
+					}{
+						0 0 0 1 ci6foureq { 
+							/plateindex 3 def
+						}{
+							0 0 0 0 ci6foureq {
+								/plateindex 5 def
+							} if
+						} ifelse
+					} ifelse
+				} ifelse
+			} ifelse
+			pop pop pop pop
+		} if
+		plateindex
+ end
+} def
+/ci6concatprocs {
+	/packedarray where {
+		pop dup type /packedarraytype eq 2 index type
+		/packedarraytype eq or
+	}{
+		false
+	} ifelse
+	{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		_proc1 aload pop
+		_proc2 aload pop
+		_proc1 length
+		_proc2 length add
+		packedarray cvx
+	}{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		/_newproc _proc1 length _proc2 length add array def
+		_newproc 0 _proc1 putinterval
+		_newproc _proc1 length _proc2 putinterval
+		_newproc cvx
+	} ifelse
+} def
+/ci6istint {
+	type /arraytype eq 
+} def
+/ci6isspot {
+	dup type /arraytype eq {
+		dup length 1 sub get /Separation eq
+	}{
+		pop false
+	} ifelse
+} def
+/ci6spotname {
+	dup ci6isspot {dup length 2 sub get}{pop ()} ifelse
+} def
+/ci6altspace {
+	aload pop pop pop ci6colormake
+} def
+/ci6numcomps {
+	dup /DeviceGray eq {
+		pop 1
+	}{
+		dup /DeviceRGB eq {
+			pop 3
+		}{
+			/DeviceCMYK eq {
+				4
+			}{
+				1
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6marksplate {
+	dup /DeviceGray eq {
+		pop plateindex 3 eq
+	}{
+		dup /DeviceRGB eq {
+			pop plateindex 5 ne
+		}{
+			dup /DeviceCMYK eq {
+				pop plateindex 5 ne
+			}{
+				dup ci6isspot {
+					/findcmykcustomcolor where {
+						pop
+						dup length 2 sub get
+						0.1 0.1 0.1 0.1 5 -1 roll
+						findcmykcustomcolor 1 setcustomcolor
+						systemdict /currentgray get exec
+						1 ne
+					}{
+						pop plateindex 5 ne
+					} ifelse
+				}{
+					pop plateindex 5 ne
+				} ifelse
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colormake {
+	dup ci6numcomps
+	exch 1 index 2 add 1 roll
+	dup 1 eq {pop}{array astore} ifelse
+	exch
+} def
+/ci6colorexpand {
+	dup ci6spotname exch
+	dup ci6istint {
+		ci6altspace
+		exch 4 1 roll
+	}{
+		1 3 1 roll
+	} ifelse
+} def
+/ci6colortint {
+	dup /DeviceGray eq {
+		3 1 roll 1 exch sub mul 1 exch sub exch
+	}{
+		dup /DeviceRGB eq {
+			3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch
+		}{
+			dup /DeviceCMYK eq {
+				3 1 roll {1 index mul exch} forall pop 4 array astore exch
+			}{
+				3 1 roll mul exch
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colortocmyk {
+	dup /DeviceGray eq {
+		pop 1 exch sub 0 0 0 4 -1 roll 4 array astore
+	}{
+		dup /DeviceRGB eq {
+			pop aload pop _rgbtocmyk 4 array astore
+		}{
+			dup /DeviceCMYK eq {
+				pop
+			}{
+				ci6altspace ci6colortint ci6colortocmyk
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6makeimagedict {
+	7 dict begin
+		/ImageType 1 def
+		/Decode exch def
+		/DataSource exch def
+		/ImageMatrix exch def
+		/BitsPerComponent exch def
+		/Height exch def
+		/Width exch def
+	currentdict end
+} def
+/ci6stringinvert {
+	0 1 2 index length 1 sub {
+		dup 2 index exch get 255 exch sub 2 index 3 1 roll put
+	} for
+} def
+/ci6stringknockout {
+	0 1 2 index length 1 sub {
+		255 2 index 3 1 roll put
+	} for
+} def
+/ci6stringapply {
+	0 1 4 index length 1 sub {
+		dup
+		4 index exch get
+		3 index 3 1 roll
+		3 index exec
+	} for
+	pop exch pop
+} def
+/ci6walkrgbstring {
+	0 3 index
+	dup length 1 sub 0 3 3 -1 roll {
+		3 getinterval {} forall
+		5 index exec
+		3 index
+	} for
+	
+	 5 {pop} repeat
+} def
+/ci6walkcmykstring
+{
+	0 3 index
+	dup length 1 sub 0 4 3 -1 roll {
+		4 getinterval {} forall
+		
+		6 index exec
+		
+		3 index
+		
+	} for
+	
+	5 { pop } repeat
+	
+} def
+/ci6putrgbtograystr
+{
+	.11 mul exch
+	
+	.59 mul add exch
+	
+	.3 mul add
+	
+	cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6putcmyktograystr
+{
+	exch .11 mul add
+	
+	exch .59 mul add
+	
+	exch .3 mul add
+	
+	dup 255 gt { pop 255 } if
+	
+	255 exch sub cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6rgbtograyproc {	
+	Adobe_ColorImage_AI6_Vars begin 
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putrgbtograystr load exch
+		ci6walkrgbstring
+ end
+} def
+/ci6cmyktograyproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putcmyktograystr load exch
+		ci6walkcmykstring
+ end
+} def
+/ci6separatecmykproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		
+		XIBuffer3
+		
+		0 2 index
+		
+		plateindex 4 2 index length 1 sub {
+			get 255 exch sub
+			
+			3 copy put pop 1 add
+			
+			2 index
+		} for
+		pop pop exch pop
+ end
+} def
+	
+/ci6compositeimage {
+	dup 1 eq {
+		pop pop image
+	}{
+		/ci6colorimage load null ne {
+			ci6colorimage
+		}{
+			3 1 roll pop
+			sourcearray 0 3 -1 roll put
+			3 eq {/ci6rgbtograyproc}{/ci6cmyktograyproc} ifelse load
+			image
+		} ifelse
+	} ifelse
+} def
+/ci6knockoutimage {
+	gsave
+	0 ci6curtransfer exec 1 ci6curtransfer exec
+	eq {
+		0 ci6curtransfer exec 0.5 lt
+	}{
+		0 ci6curtransfer exec 1 ci6curtransfer exec gt
+	} ifelse
+	{{pop 0}}{{pop 1}} ifelse
+	systemdict /settransfer get exec
+	ci6compositeimage
+	grestore
+} def
+/ci6drawimage {
+	ci6testplate -1 eq {
+		pop ci6compositeimage
+	}{
+		dup type /arraytype eq {
+			dup length plateindex gt {plateindex get}{pop false} ifelse
+		}{
+			{
+				true
+			}{
+				dup 1 eq {plateindex 3 eq}{plateindex 3 le} ifelse
+			} ifelse
+		} ifelse
+		{
+			dup 1 eq {
+				pop pop ci6image
+			}{
+				dup 3 eq {
+					ci6compositeimage
+				}{
+					pop pop
+					sourcearray 0 3 -1 roll put
+					/ci6separatecmykproc load
+					ci6image
+				} ifelse
+			} ifelse
+		}{
+			ci6curoverprint {
+				7 {pop} repeat
+			}{
+				ci6knockoutimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6proctintimage {
+	/_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store
+	/_pticomps _ptispace ci6numcomps store
+	/_ptiscale _pti1 _pti0 sub store
+	level2? {
+		_ptiname length 0 gt version cvr 2012 ge and {
+			[/Separation _ptiname _ptispace {_ptiproc}] setcolorspace
+			[_pti0 _pti1] ci6makeimagedict ci6image
+		}{
+			[/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace
+			[0 255] ci6makeimagedict ci6image
+		} ifelse
+	}{
+		_pticomps 1 eq {
+			{
+				dup
+				{
+					255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put
+				} ci6stringapply
+			} ci6concatprocs ci6image
+		}{
+			{
+				dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse
+				_ptibuf {
+					exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc
+					_pticomps 2 add -2 roll
+					_pticomps 1 sub -1 0 {
+						1 index add 2 index exch
+						5 -1 roll
+						255 mul cvi put
+					} for
+					pop pop
+				} ci6stringapply
+			} ci6concatprocs false _pticomps
+			/ci6colorimage load null eq {7 {pop} repeat}{ci6colorimage} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6graytintimage {
+	/_gtigray 5 -1 roll store
+	{1 _gtigray sub mul 1 exch sub} 4 1 roll
+	/DeviceGray ci6proctintimage
+} def
+/ci6cmyktintimage {
+	/_cticmyk 5 -1 roll store
+	{_cticmyk {1 index mul exch} forall pop} 4 1 roll
+	/DeviceCMYK ci6proctintimage
+} def
+/ci6rgbtintimage {
+	/_rtirgb 5 -1 roll store
+	{_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll
+	/DeviceRGB ci6proctintimage
+} def
+/ci6tintimage {
+	ci6testplate -1 eq {
+		ci6colorexpand
+		3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll
+		dup /DeviceGray eq {
+			pop ci6graytintimage
+		}{
+			dup /DeviceRGB eq {
+				pop ci6rgbtintimage
+			}{
+				pop ci6cmyktintimage
+			} ifelse
+		} ifelse
+	}{
+		dup ci6marksplate {
+			plateindex 5 lt {
+				ci6colortocmyk plateindex get
+				dup 0 eq ci6curoverprint and {
+					7 {pop} repeat
+				}{
+					1 exch sub
+					exch {1 0}{0 1} ifelse () ci6graytintimage
+				} ifelse
+			}{
+				pop exch {0}{0 exch} ifelse 0 3 1 roll () ci6graytintimage
+			} ifelse
+		}{
+			ci6curoverprint {
+				8 {pop} repeat
+			}{
+				pop pop pop
+				{pop 1} 0 1 () /DeviceGray ci6proctintimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/XINullImage {
+} def
+/XIImageMask {
+	XIImageWidth XIImageHeight false
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	imagemask
+} def
+/XIImageTint {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	XIType 3 eq XIColorValues XIColorSpace ci6tintimage
+} def
+/XIImage {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	false XIChannelCount XIPlateList ci6drawimage
+} def
+/XG {
+	pop pop
+} def
+/XF {
+	13 {pop} repeat
+} def
+/Xh {
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		/XIImageMatrix exch def
+		0 0 moveto
+		XIImageMatrix concat
+		XIImageWidth XIImageHeight scale
+		
+		/_lp /null ddef
+		_fc
+		/_lp /imagemask ddef
+ end
+} def
+/XH {
+	Adobe_ColorImage_AI6_Vars begin
+		grestore
+ end
+} def
+/XIEnable {
+	Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put
+} def
+/XC {
+	Adobe_ColorImage_AI6_Vars begin
+		ci6colormake
+		/XIColorSpace exch def
+		/XIColorValues exch def
+ end
+} def
+/XIPlates {
+	Adobe_ColorImage_AI6_Vars begin
+		/XIPlateList exch def
+ end
+} def
+/XI
+{
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		cvi dup
+		256 idiv /XICompression exch store
+		256 mod /XIEncoding exch store
+		pop pop
+		/XIChannelCount exch def
+		/XIBitsPerPixel exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		pop pop pop pop
+		/XIImageMatrix exch def
+		XIBitsPerPixel 1 eq {
+			XIImageWidth 8 div ceiling cvi
+		}{
+			XIImageWidth XIChannelCount mul
+		} ifelse
+		/XIRowBytes exch def
+		XIEnable {
+			/XIBuffer3 XIImageWidth string def
+			XICompression 0 eq {
+				/XIBuffer1 XIRowBytes string def
+				XIEncoding 0 eq {
+					{currentfile XIBuffer1 readhexstring pop}
+				}{
+					{currentfile XIBuffer1 readstring pop}
+				} ifelse
+			}{
+				/XIBuffer1 256 string def
+				/XIBuffer2 XIRowBytes string def
+				{currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if}
+				/ASCII85Decode filter /DCTDecode filter
+				/XIFile exch def
+				{XIFile XIBuffer2 readstring pop}
+			} ifelse
+			/XIDataProc exch def
+			
+			XIType 1 ne {
+				0 setgray
+			} if
+			XIType 1 eq {
+				XIImageMask
+			}{
+				XIType 2 eq XIType 3 eq or {
+					XIImageTint
+				}{
+					XIImage
+				} ifelse
+			} ifelse
+		}{
+			XINullImage
+		} ifelse
+		/XIPlateList false def
+		grestore
+ end
+} def
+end
+%%EndProcSet
+%%BeginResource: procset Adobe_Illustrator_AI5 1.3 0
+%%Title: (Adobe Illustrator (R) Version 8.0 Full Prolog)
+%%Version: 1.3 0
+%%CreationDate: (3/7/1994) ()
+%%Copyright: ((C) 1987-1998 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_Illustrator_AI5_vars 112 dict dup begin
+put
+/_?cmyk false def
+/_eo false def
+/_lp /none def
+/_pf
+{
+} def
+/_ps
+{
+} def
+/_psf
+{
+} def
+/_pss
+{
+} def
+/_pjsf
+{
+} def
+/_pjss
+{
+} def
+/_pola 0 def
+/_doClip 0 def
+/cf currentflat def
+/_lineorientation 0 def
+/_charorientation 0 def
+/_yokoorientation 0 def
+/_tm matrix def
+/_renderStart
+[
+/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
+] def
+/_renderEnd
+[
+null null null null /i1 /i1 /i1 /i1
+] def
+/_render -1 def
+/_shift [0 0] def
+/_ax 0 def
+/_ay 0 def
+/_cx 0 def
+/_cy 0 def
+/_leading
+[
+0 0
+] def
+/_ctm matrix def
+/_mtx matrix def
+/_sp 16#020 def
+/_hyphen (-) def
+/_fontSize 0 def
+/_fontAscent 0 def
+/_fontDescent 0 def
+/_fontHeight 0 def
+/_fontRotateAdjust 0 def
+/Ss 256 string def
+Ss 0 (fonts/) putinterval
+/_cnt 0 def
+/_scale [1 1] def
+/_nativeEncoding 0 def
+/_useNativeEncoding 0 def
+/_tempEncode 0 def
+/_pntr 0 def
+/_tDict 2 dict def
+/_hfname 100 string def
+/_hffound false def
+/Tx
+{
+} def
+/Tj
+{
+} def
+/CRender
+{
+} def
+/_AI3_savepage
+{
+} def
+/_gf null def
+/_cf 4 array def
+/_rgbf 3 array def
+/_if null def
+/_of false def
+/_fc
+{
+} def
+/_gs null def
+/_cs 4 array def
+/_rgbs 3 array def
+/_is null def
+/_os false def
+/_sc
+{
+} def
+/_pd 1 dict def
+/_ed 15 dict def
+/_pm matrix def
+/_fm null def
+/_fd null def
+/_fdd null def
+/_sm null def
+/_sd null def
+/_sdd null def
+/_i null def
+/_lobyte 0 def
+/_hibyte 0 def
+/_cproc null def
+/_cscript 0 def
+/_hvax 0 def
+/_hvay 0 def
+/_hvwb 0 def
+/_hvcx 0 def
+/_hvcy 0 def
+/_bitfont null def
+/_bitlobyte 0 def
+/_bithibyte 0 def
+/_bitkey null def
+/_bitdata null def
+/_bitindex 0 def
+/discardSave null def
+/buffer 256 string def
+/beginString null def
+/endString null def
+/endStringLength null def
+/layerCnt 1 def
+/layerCount 1 def
+/perCent (%) 0 get def
+/perCentSeen? false def
+/newBuff null def
+/newBuffButFirst null def
+/newBuffLast null def
+/clipForward? false def
+end
+userdict /Adobe_Illustrator_AI5 known not {
+	userdict /Adobe_Illustrator_AI5 100 dict put
+} if
+userdict /Adobe_Illustrator_AI5 get begin
+/initialize
+{
+	Adobe_Illustrator_AI5 dup begin
+	Adobe_Illustrator_AI5_vars begin
+	/_aicmykps where {pop /_?cmyk _aicmykps def}if
+	discardDict
+	{
+		bind pop pop
+	} forall
+	dup /nc get begin
+	{
+		dup xcheck 1 index type /operatortype ne and
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	newpath
+} def
+/terminate
+{
+ end
+ end
+} def
+/_
+null def
+/ddef
+{
+	Adobe_Illustrator_AI5_vars 3 1 roll put
+} def
+/xput
+{
+	dup load dup length exch maxlength eq
+	{
+		dup dup load dup
+		length 2 mul dict copy def
+	} if
+	load begin
+	def
+ end
+} def
+/npop
+{
+	{
+		pop
+	} repeat
+} def
+/hswj
+{
+	dup stringwidth 3 2 roll
+	{
+		_hvwb eq { exch _hvcx add exch _hvcy add } if
+		exch _hvax add exch _hvay add
+	} cforall
+} def
+/vswj
+{
+	0 0 3 -1 roll
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			dup cstring stringwidth 5 2 roll
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			4 -1 roll sub exch
+			3 -1 roll sub exch
+		}
+		{
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			_fontHeight sub
+		} ifelse
+	} cforall
+} def
+/swj
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hswj } { vswj } ifelse
+} def
+/sw
+{
+	0 0 0 6 3 roll swj
+} def
+/vjss
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			gsave
+			false charpath currentpoint
+			5 index setmatrix stroke
+			grestore
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			gsave
+			2 index false charpath
+			6 index setmatrix stroke
+			grestore
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjss
+{
+	4 1 roll
+	{
+		dup cstring
+		gsave
+		false charpath currentpoint
+		5 index setmatrix stroke
+		grestore
+		moveto
+		_sp eq
+		{
+			5 index 5 index rmoveto
+		} if
+		2 copy rmoveto
+	} cforall
+	6 npop
+} def
+/jss
+{
+	_lineorientation 0 eq { hjss } { vjss } ifelse
+} def
+/ss
+{
+	0 0 0 7 3 roll jss
+} def
+/vjsp
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			false charpath
+            currentpoint
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			2 index false charpath
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjsp
+{
+    4 1 roll
+    {
+        dup cstring
+        false charpath
+        _sp eq
+        {
+            5 index 5 index rmoveto
+        } if
+        2 copy rmoveto
+    } cforall
+    6 npop
+} def
+/jsp
+{
+	matrix currentmatrix
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/sp
+{
+    matrix currentmatrix
+    0 0 0 7 3 roll
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/pl
+{
+	transform
+	0.25 sub round 0.25 add exch
+	0.25 sub round 0.25 add exch
+	itransform
+} def
+/setstrokeadjust where
+{
+	pop true setstrokeadjust
+	/c
+	{
+		curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		moveto
+	} def
+}
+{
+	/c
+	{
+		pl curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll pl curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		pl 2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		pl lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		pl moveto
+	} def
+} ifelse
+/d
+{
+	setdash
+} def
+/cf
+{
+} def
+/i
+{
+	dup 0 eq
+	{
+		pop cf
+	} if
+	setflat
+} def
+/j
+{
+	setlinejoin
+} def
+/J
+{
+	setlinecap
+} def
+/M
+{
+	setmiterlimit
+} def
+/w
+{
+	setlinewidth
+} def
+/XR
+{
+	0 ne
+	/_eo exch ddef
+} def
+/H
+{
+} def
+/h
+{
+	closepath
+} def
+/N
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			_eo {eoclip} {clip} ifelse /_doClip 0 ddef
+		} if
+		newpath
+	}
+	{
+		/CRender
+		{
+			N
+		} ddef
+	} ifelse
+} def
+/n
+{
+	N
+} def
+/F
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
+			/_doClip 0 ddef
+		}
+		{
+			_pf
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			F
+		} ddef
+	} ifelse
+} def
+/f
+{
+	closepath
+	F
+} def
+/S
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			_ps
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			S
+		} ddef
+	} ifelse
+} def
+/s
+{
+	closepath
+	S
+} def
+/B
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		gsave F grestore
+		{
+			gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			S
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			B
+		} ddef
+	} ifelse
+} def
+/b
+{
+	closepath
+	B
+} def
+/W
+{
+	/_doClip 1 ddef
+} def
+/*
+{
+	count 0 ne
+	{
+		dup type /stringtype eq
+		{
+			pop
+		} if
+	} if
+	newpath
+} def
+/u
+{
+} def
+/U
+{
+} def
+/q
+{
+	_pola 0 eq
+	{
+		gsave
+	} if
+} def
+/Q
+{
+	_pola 0 eq
+	{
+		grestore
+	} if
+} def
+/*u
+{
+	_pola 1 add /_pola exch ddef
+} def
+/*U
+{
+	_pola 1 sub /_pola exch ddef
+	_pola 0 eq
+	{
+		CRender
+	} if
+} def
+/D
+{
+	pop
+} def
+/*w
+{
+} def
+/*W
+{
+} def
+/`
+{
+	/_i save ddef
+	clipForward?
+	{
+		nulldevice
+	} if
+	6 1 roll 4 npop
+	concat pop
+	userdict begin
+	/showpage
+	{
+	} def
+	0 setgray
+	0 setlinecap
+	1 setlinewidth
+	0 setlinejoin
+	10 setmiterlimit
+	[] 0 setdash
+	/setstrokeadjust where {pop false setstrokeadjust} if
+	newpath
+	0 setgray
+	false setoverprint
+} def
+/~
+{
+ end
+	_i restore
+} def
+/_rgbtocmyk
+{
+	3
+	{
+		1 exch sub 3 1 roll
+	} repeat
+	3 copy 1 4 1 roll
+	3
+	{
+		3 index 2 copy gt
+		{
+			exch
+		} if
+		pop 4 1 roll
+	} repeat
+	pop pop pop
+	4 1 roll
+	3
+	{
+		3 index sub
+		3 1 roll
+	} repeat
+	4 -1 roll
+} def
+/setrgbfill
+{
+	_rgbf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_rgbf aload pop setrgbcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/setrgbstroke
+{
+	_rgbs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_rgbs aload pop setrgbcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/O
+{
+	0 ne
+	/_of exch ddef
+	/_lp /none ddef
+} def
+/R
+{
+	0 ne
+	/_os exch ddef
+	/_lp /none ddef
+} def
+/g
+{
+	/_gf exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/G
+{
+	/_gs exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/k
+{
+	_cf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_cf aload pop setcmykcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/K
+{
+	_cs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_cs aload pop setcmykcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xa
+{
+	_?cmyk {
+		3 npop k
+	}{
+		setrgbfill 4 npop
+	} ifelse
+} def
+/XA
+{
+	_?cmyk {
+		3 npop K
+	}{
+		setrgbstroke 4 npop
+	} ifelse
+} def
+/Xs
+{
+	/_gf exch ddef
+	5 npop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setAIseparationgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XS
+{
+	/_gs exch ddef
+	5 npop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setAIseparationgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xx
+{
+	exch
+	/_gf exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XX
+{
+	exch
+	/_gs exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/x
+{
+	/_gf exch ddef
+	findcmykcustomcolor
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/X
+{
+	/_gs exch ddef
+	findcmykcustomcolor
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/XK
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		K
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		XA
+	} ifelse
+} def
+/Xk
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		k
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		Xa
+	} ifelse
+} def
+/A
+{
+	pop
+} def
+/annotatepage
+{
+userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
+} def
+/XT {
+	pop pop
+} def
+/Xt {
+	pop
+} def
+/discard
+{
+	save /discardSave exch store
+	discardDict begin
+	/endString exch store
+	gt38?
+	{
+		2 add
+	} if
+	load
+	stopped
+	pop
+ end
+	discardSave restore
+} bind def
+userdict /discardDict 7 dict dup begin
+put
+/pre38Initialize
+{
+	/endStringLength endString length store
+	/newBuff buffer 0 endStringLength getinterval store
+	/newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
+	/newBuffLast newBuff endStringLength 1 sub 1 getinterval store
+} def
+/shiftBuffer
+{
+	newBuff 0 newBuffButFirst putinterval
+	newBuffLast 0
+	currentfile read not
+	{
+	stop
+	} if
+	put
+} def
+0
+{
+	pre38Initialize
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff endString eq
+			{
+				cleartomark stop
+			} if
+			shiftBuffer
+		} loop
+	}
+	{
+	stop
+	} ifelse
+} def
+1
+{
+	pre38Initialize
+	/beginString exch store
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff beginString eq
+			{
+				/layerCount dup load 1 add store
+			}
+			{
+				newBuff endString eq
+				{
+					/layerCount dup load 1 sub store
+					layerCount 0 eq
+					{
+						cleartomark stop
+					} if
+				} if
+			} ifelse
+			shiftBuffer
+		} loop
+	} if
+} def
+2
+{
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			endString eq {
+				cleartomark stop
+			} if
+		}ifelse
+	} loop
+} def
+3
+{
+	/beginString exch store
+	/layerCnt 1 store
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			dup beginString eq
+			{
+				pop /layerCnt dup load 1 add store
+			}
+			{
+				endString eq
+				{
+					layerCnt 1 eq
+					{
+						cleartomark stop
+					}
+					{
+						/layerCnt dup load 1 sub store
+					} ifelse
+				} if
+			} ifelse
+		}ifelse
+	} loop
+} def
+end
+userdict /clipRenderOff 15 dict dup begin
+put
+{
+	/n /N /s /S /f /F /b /B
+}
+{
+	{
+		_doClip 1 eq
+		{
+			/_doClip 0 ddef _eo {eoclip} {clip} ifelse
+		} if
+		newpath
+	} def
+} forall
+/Tr /pop load def
+/Bb {} def
+/BB /pop load def
+/Bg {12 npop} def
+/Bm {6 npop} def
+/Bc /Bm load def
+/Bh {4 npop} def
+end
+/Lb
+{
+	6 npop
+	7 2 roll
+	5 npop
+	0 eq
+	{
+		0 eq
+		{
+			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
+		}
+		{
+			
+			/clipForward? true def
+			
+			/Tx /pop load def
+			/Tj /pop load def
+			
+			currentdict end clipRenderOff begin begin
+		} ifelse
+	}
+	{
+		0 eq
+		{
+			save /discardSave exch store
+		} if
+	} ifelse
+} bind def
+/LB
+{
+	discardSave dup null ne
+	{
+		restore
+	}
+	{
+		pop
+		clipForward?
+		{
+			currentdict
+		 end
+		 end
+		 begin
+					
+			/clipForward? false ddef
+		} if
+	} ifelse
+} bind def
+/Pb
+{
+	pop pop
+	0 (%AI5_EndPalette) discard
+} bind def
+/Np
+{
+	0 (%AI5_End_NonPrinting--) discard
+} bind def
+/Ln /pop load def
+/Ap
+/pop load def
+/Ar
+{
+	72 exch div
+	0 dtransform dup mul exch dup mul add sqrt
+	dup 1 lt
+	{
+		pop 1
+	} if
+	setflat
+} def
+/Mb
+{
+	q
+} def
+/Md
+{
+} def
+/MB
+{
+	Q
+} def
+/nc 4 dict def
+nc begin
+/setgray
+{
+	pop
+} bind def
+/setcmykcolor
+{
+	4 npop
+} bind def
+/setrgbcolor
+{
+	3 npop
+} bind def
+/setcustomcolor
+{
+	2 npop
+} bind def
+currentdict readonly pop
+end
+/XP
+{
+	4 npop
+} bind def
+/XD
+{
+	pop
+} bind def
+end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_pattern_AI5 1.1 0
+%%Title: (Adobe Illustrator (R) Version 5.0 Pattern Operators)
+%%Version: 1.1 0
+%%CreationDate: (03/26/93) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_Illustrator_AI5 known not {
+	userdict /Adobe_Illustrator_AI5 95 dict put
+} if
+userdict /Adobe_Illustrator_AI5 get begin
+/@
+{
+} def
+/&
+{
+} def
+/dp
+{
+	dup null eq
+	{
+		pop
+		_dp 0 ne
+		{
+			0 1 _dp 1 sub _dl mod
+			{
+				_da exch get 3 get
+			} for
+			_dp 1 sub _dl mod 1 add packedarray
+			_da 0 get aload pop 8 -1 roll 5 -1 roll pop 4 1 roll
+			definepattern pop
+		} if
+	}
+	{
+		_dp 0 ne _dp _dl mod 0 eq and
+		{
+			null dp
+		} if
+		7 packedarray _da exch _dp _dl mod exch put
+		_dp _dl mod _da 0 get 4 get 2 packedarray
+		/_dp _dp 1 add def
+	} ifelse
+} def
+/E
+{
+	_ed begin
+	dup 0 get type /arraytype ne
+	{
+		0
+		{
+			dup 1 add index type /arraytype eq
+			{
+				1 add
+			}
+			{
+				exit
+			} ifelse
+		} loop
+		array astore
+	} if
+	/_dd exch def
+	/_ury exch def
+	/_urx exch def
+	/_lly exch def
+	/_llx exch def
+	/_n exch def
+	/_y 0 def
+	/_dl 4 def
+	/_dp 0 def
+	/_da _dl array def
+	0 1 _dd length 1 sub
+	{
+		/_d exch _dd exch get def
+		0 2 _d length 2 sub
+		{
+			/_x exch def
+			/_c false def
+			/_r _d _x 1 add get cvlit def
+			_r _ ne
+			{
+				_urx _llx sub _ury _lly sub
+				[
+				1 0 0 1 0 0
+				]
+				[
+				/save cvx
+				_llx neg _lly neg /translate cvx
+				_c
+				{
+					nc /begin cvx
+				} if
+				_r dup type /stringtype eq
+				{
+					cvx
+				}
+				{
+					{
+						exec
+					} /forall cvx
+				} ifelse
+				_c
+				{
+					/end cvx
+				} if
+				/restore cvx
+				] cvx
+				/_fn 12 _n length add string def
+				_y _fn cvs pop
+				/_y _y 1 add def
+				_fn 12 _n putinterval
+				_fn _c false dp
+				_d exch _x 1 add exch put
+			} if
+		} for
+	} for
+	null dp
+	_n _dd /_pd
+ end
+	xput
+} def
+/fc
+{
+	_fm dup concatmatrix pop
+} def
+/p
+{
+	/_fm exch ddef
+	9 -2 roll _pm translate fc
+	7 -2 roll _pm scale fc
+	5 -1 roll _pm rotate fc
+	4 -2 roll exch 0 ne
+	{
+		dup _pm rotate fc
+		1 -1 _pm scale fc
+		neg _pm rotate fc
+	}
+	{
+		pop
+	} ifelse
+	dup _pm rotate fc
+	exch dup sin exch cos div 1 0 0 1 0 6 2 roll
+	_pm astore fc
+	neg _pm rotate fc
+	_pd exch get /_fdd exch ddef
+	/_pf
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _fdd length 1 sub
+		{
+			/_fd exch _fdd exch get ddef
+			_fd
+			0 2 _fd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _fc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _fm
+					patternfill
+				}
+				{
+					pop
+					fill
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		newpath
+	} ddef
+	/_psf
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _fdd length 1 sub
+		{
+			/_fd exch _fdd exch get ddef
+			_fd
+			0 2 _fd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _fc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _fm
+					9 copy 6 npop patternashow
+				}
+				{
+					pop
+					6 copy 3 npop hvashow
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		sw rmoveto
+	} ddef
+	/_pjsf
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _fdd length 1 sub
+		{
+			/_fd exch _fdd exch get ddef
+			_fd
+			0 2 _fd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _fc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _fm
+					12 copy 6 npop patternawidthshow
+				}
+				{
+					pop 9 copy 3 npop hvawidthshow
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		swj rmoveto
+	} ddef
+	/_lp /none ddef
+} def
+/sc
+{
+	_sm dup concatmatrix pop
+} def
+/P
+{
+	/_sm exch ddef
+	9 -2 roll _pm translate sc
+	7 -2 roll _pm scale sc
+	5 -1 roll _pm rotate sc
+	4 -2 roll exch 0 ne
+	{
+		dup _pm rotate sc
+		1 -1 _pm scale sc
+		neg _pm rotate sc
+	}
+	{
+		pop
+	} ifelse
+	dup _pm rotate sc
+	exch dup sin exch cos div 1 0 0 1 0 6 2 roll
+	_pm astore sc
+	neg _pm rotate sc
+	_pd exch get /_sdd exch ddef
+	/_ps
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _sdd length 1 sub
+		{
+			/_sd exch _sdd exch get ddef
+			_sd
+			0 2 _sd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _sc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _sm
+					patternstroke
+				}
+				{
+					pop stroke
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		newpath
+	} ddef
+	/_pss
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _sdd length 1 sub
+		{
+			/_sd exch _sdd exch get ddef
+			_sd
+			0 2 _sd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _sc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _sm
+					10 copy 6 npop patternashowstroke
+				}
+				{
+					pop 7 copy 3 npop ss
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		pop sw rmoveto
+	} ddef
+	/_pjss
+	{
+		save
+		/_doClip 0 ddef
+		0 1 _sdd length 1 sub
+		{
+			/_sd exch _sdd exch get ddef
+			_sd
+			0 2 _sd length 2 sub
+			{
+				gsave
+				2 copy get dup _ ne
+				{
+					cvx exec _sc
+				}
+				{
+					pop
+				} ifelse
+				2 copy 1 add get dup _ ne
+				{
+					aload pop findfont _sm
+					13 copy 6 npop patternawidthshowstroke
+				}
+				{
+					pop 10 copy 3 npop jss
+				} ifelse
+				grestore
+				pop
+			} for
+			pop
+		} for
+		restore
+		pop swj rmoveto
+	} ddef
+	/_lp /none ddef
+} def
+end
+userdict /Adobe_pattern_AI5 18 dict dup begin
+put
+/initialize
+{
+	/definepattern where
+	{
+		pop
+		pop pop
+	}
+	{
+	 begin
+	 begin
+		Adobe_pattern_AI5 begin
+		Adobe_pattern_AI5
+		{
+			dup xcheck
+			{
+				bind
+			} if
+			pop pop
+		} forall
+		mark
+		cachestatus 7 1 roll pop pop pop pop exch pop exch
+		{
+			{
+				10000 add
+				dup 2 index gt
+				{
+					exit
+				} if
+				dup setcachelimit
+			} loop
+		} stopped
+		cleartomark
+	 end 	
+		
+	 end
+	 end
+		
+		Adobe_pattern_AI5 begin
+	} ifelse
+} def
+/terminate
+{
+	currentdict Adobe_pattern_AI5 eq
+	{
+	 end
+	} if
+} def
+errordict
+/nocurrentpoint
+{
+	pop
+	stop
+} put
+errordict
+/invalidaccess
+{
+	pop
+	stop
+} put
+/patternencoding
+256 array def
+0 1 255
+{
+	patternencoding exch ( ) 2 copy exch 0 exch put cvn put
+} for
+/definepattern
+{
+	17 dict begin
+	/uniform exch def
+	/cache exch def
+	/key exch def
+	/procarray exch def
+	/mtx exch matrix invertmatrix def
+	/height exch def
+	/width exch def
+	/ctm matrix currentmatrix def
+	/ptm matrix def
+	/str 32 string def
+	/slice 9 dict def
+	slice /s 1 put
+	slice /q 256 procarray length div sqrt floor cvi put
+	slice /b 0 put
+	/FontBBox
+	[
+	0 0 0 0
+	] def
+	/FontMatrix mtx matrix copy def
+	/Encoding patternencoding def
+	/FontType 3 def
+	/BuildChar
+	{
+		exch
+	 begin
+		/setstrokeadjust where {pop true setstrokeadjust} if
+		slice begin
+		dup q dup mul mod s idiv /i exch def
+		dup q dup mul mod s mod /j exch def
+		q dup mul idiv procarray exch get
+		/xl j width s div mul def
+		/xg j 1 add width s div mul def
+		/yl i height s div mul def
+		/yg i 1 add height s div mul def
+		uniform
+		{
+			1 1
+		}
+		{
+			width 0 dtransform
+			dup mul exch dup mul add sqrt dup 1 add exch div
+			0 height dtransform
+			dup mul exch dup mul add sqrt dup 1 add exch div
+		} ifelse
+		width 0 cache
+		{
+			xl 4 index mul yl 4 index mul xg 6 index mul yg 6 index mul
+			setcachedevice
+		}
+		{
+			setcharwidth
+		} ifelse
+		gsave
+		scale
+		newpath
+		xl yl moveto
+		xg yl lineto
+		xg yg lineto
+		xl yg lineto
+		closepath
+		clip
+		newpath
+	 end
+	 end
+		exec
+		grestore
+	} def
+	key currentdict definefont
+ end
+} def
+/patterncachesize
+{
+	gsave
+	newpath
+	0 0 moveto
+	width 0 lineto
+	width height lineto
+	0 height lineto
+	closepath
+	patternmatrix setmatrix
+	pathbbox
+	exch ceiling 4 -1 roll floor sub 3 1 roll
+	ceiling exch floor sub
+	mul 1 add
+	grestore
+} def
+/patterncachelimit
+{
+	cachestatus 7 1 roll 6 npop 8 mul
+} def
+/patternpath
+{
+	exch dup begin
+	setfont
+	ctm setmatrix
+	concat
+	slice exch /b exch slice /q get dup mul mul put
+	FontMatrix concat
+	uniform
+	{
+		width 0 dtransform round width div exch round width div exch
+		0 height dtransform round height div exch height div exch
+		0 0 transform round exch round exch
+		ptm astore setmatrix
+	}
+	{
+		ptm currentmatrix pop
+	} ifelse
+	{
+		currentpoint
+	} stopped not
+	{
+		2 npop
+		pathbbox
+		true
+		4 index 3 index eq
+		4 index 3 index eq
+		and
+		{
+			pop false
+			{
+				{
+					2 npop
+				}
+				{
+					3 npop true
+				}
+				{
+					7 npop true
+				}
+				{
+					pop true
+				} pathforall
+			} stopped
+			{
+				5 npop true
+			} if
+		} if
+		{
+			height div ceiling height mul 4 1 roll
+			width div ceiling width mul 4 1 roll
+			height div floor height mul 4 1 roll
+			width div floor width mul 4 1 roll
+			2 index sub height div ceiling cvi exch
+			3 index sub width div ceiling cvi exch
+			4 2 roll moveto
+			FontMatrix mtx invertmatrix
+			dup dup 4 get exch 5 get rmoveto
+			ptm ptm concatmatrix pop
+			slice /s
+			patterncachesize patterncachelimit div ceiling sqrt ceiling cvi
+			dup slice /q get gt
+			{
+				pop slice /q get
+			} if
+			put
+			0 1 slice /s get dup mul 1 sub
+			{
+				slice /b get add
+				gsave
+				0 1 str length 1 sub
+				{
+					str exch 2 index put
+				} for
+				pop
+				dup
+				{
+					gsave
+					ptm setmatrix
+					1 index str length idiv
+					{
+						str show
+					} repeat
+					1 index str length mod str exch 0 exch getinterval show
+					grestore
+					0 height rmoveto
+				} repeat
+				grestore
+			} for
+			2 npop
+		}
+		{
+			4 npop
+		} ifelse
+	} if
+ end
+} def
+/patternclip
+{
+	_eo {eoclip} {clip} ifelse
+} def
+/patternstrokepath
+{
+	strokepath
+} def
+/patternmatrix
+matrix def
+/patternfill
+{
+	dup type /dicttype eq
+	{
+		Adobe_pattern_AI5 /patternmatrix get
+	} if
+	gsave
+	patternclip
+	Adobe_pattern_AI5 /patternpath get exec
+	grestore
+	newpath
+} def
+/patternstroke
+{
+	dup type /dicttype eq
+	{
+		Adobe_pattern_AI5 /patternmatrix get
+	} if
+	gsave
+	patternstrokepath
+	true
+	{
+		{
+			{
+				newpath
+				moveto
+			}
+			{
+				lineto
+			}
+			{
+				curveto
+			}
+			{
+				closepath
+				3 copy
+				Adobe_pattern_AI5 /patternfill get exec
+			} pathforall
+			3 npop
+		} stopped
+		{
+			5 npop
+			patternclip
+			Adobe_pattern_AI5 /patternfill get exec
+		} if
+	}
+	{
+		patternclip
+		Adobe_pattern_AI5 /patternfill get exec
+	} ifelse
+	grestore
+	newpath
+} def
+/vpatternawidthshow
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			gsave
+			false charpath currentpoint
+			5 index 5 index 5 index Adobe_pattern_AI5 /patternfill get exec
+			grestore
+			_fontRotateAdjust sub
+			moveto
+			_hvwb eq { _hvcx _hvcy rmoveto } if
+			_hvax _hvay rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			_hvax sub
+			3 index _hvwb eq { _hvcx sub } if
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+			gsave
+			2 index false charpath
+			6 index 6 index 6 index Adobe_pattern_AI5 /patternfill get exec
+			grestore
+			newpath moveto pop pop
+		} ifelse
+	} cforall
+	3 npop
+} def
+/hpatternawidthshow
+{
+	{
+		dup cstring exch
+		gsave
+		3 index eq { 5 index 5 index rmoveto } if
+		false charpath currentpoint
+		9 index 9 index 9 index
+		Adobe_pattern_AI5 /patternfill get exec
+		grestore
+		newpath moveto
+		2 copy rmoveto
+	} cforall
+	8 npop
+} def
+/patternashow
+{
+0 0 0 6 3 roll
+patternawidthshow
+} def
+/patternawidthshow
+{
+	6 index type /dicttype eq
+	{
+		Adobe_pattern_AI5 /patternmatrix get 7 1 roll
+	} if
+	_lineorientation 0 eq { hpatternawidthshow } { vpatternawidthshow } ifelse
+} def
+/vpatternawidthshowstroke
+{
+	7 1 roll
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			gsave
+			false charpath currentpoint
+			3 index setmatrix
+			6 index 6 index 6 index Adobe_pattern_AI5 /patternstroke get exec
+			grestore
+			_fontRotateAdjust sub
+			moveto
+			_hvwb eq { _hvcx _hvcy rmoveto } if
+			_hvax _hvay rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			_hvax sub
+			3 index _hvwb eq { _hvcx sub } if
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+			gsave
+			2 index false charpath
+			4 index setmatrix
+			7 index 7 index 7 index Adobe_pattern_AI5 /patternstroke get exec
+			grestore
+			newpath moveto pop pop
+		} ifelse
+	} cforall
+	4 npop
+} def
+/hpatternawidthshowstroke
+{
+	7 1 roll
+	{
+		dup cstring exch
+		gsave
+		3 index eq { 5 index 5 index rmoveto } if
+		false charpath currentpoint
+		7 index setmatrix
+		10 index 10 index 10 index
+		Adobe_pattern_AI5 /patternstroke get exec
+		grestore
+		newpath moveto
+		2 copy rmoveto
+	} cforall
+	9 npop
+} def
+/patternashowstroke
+{
+	0 0 0 7 3 roll
+	patternawidthshowstroke
+} def
+/patternawidthshowstroke
+{
+	7 index type /dicttype eq
+	{
+		patternmatrix /patternmatrix get 8 1 roll
+	} if
+	_lineorientation 0 eq { hpatternawidthshowstroke } { vpatternawidthshowstroke } ifelse
+} def
+end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_cshow 2.0 8
+%%Title: (Writing System Operators)
+%%Version: 2.0 8
+%%CreationDate: (1/23/89) ()
+%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_cshow 14 dict dup begin put
+/initialize
+{
+	Adobe_cshow begin
+	Adobe_cshow
+	{
+		dup xcheck
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	Adobe_cshow begin
+} def
+/terminate
+{
+currentdict Adobe_cshow eq
+	{
+ end
+	} if
+} def
+/cforall
+{
+	/_lobyte 0 ddef
+	/_hibyte 0 ddef
+	/_cproc exch ddef
+	/_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef
+	{
+		/_lobyte exch ddef
+		_hibyte 0 eq
+		_cscript 1 eq
+		_lobyte 129 ge _lobyte 159 le and
+		_lobyte 224 ge _lobyte 252 le and or and
+		_cscript 2 eq
+		_lobyte 161 ge _lobyte 254 le and and
+		_cscript 3 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript 25 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript -1 eq
+		or or or or and
+		{
+			/_hibyte _lobyte ddef
+		}
+		{
+			_hibyte 256 mul _lobyte add
+			_cproc
+			/_hibyte 0 ddef
+		} ifelse
+	} forall
+} def
+/cstring
+{
+	dup 256 lt
+	{
+		(s) dup 0 4 3 roll put
+	}
+	{
+		dup 256 idiv exch 256 mod
+		(hl) dup dup 0 6 5 roll put 1 4 3 roll put
+	} ifelse
+} def
+/clength
+{
+	0 exch
+	{ 256 lt { 1 } { 2 } ifelse add } cforall
+} def
+/hawidthshow
+{
+	{
+		dup cstring
+		show
+		_hvax _hvay rmoveto
+		_hvwb eq { _hvcx _hvcy rmoveto } if
+	} cforall
+} def
+/vawidthshow
+{
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			0 _fontRotateAdjust rmoveto
+			cstring
+			_hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow
+			0 _fontRotateAdjust neg rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			exch _hvay sub exch _hvax sub
+			2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			3 2 roll
+			cstring
+			dup stringwidth pop 2 div neg _fontAscent neg rmoveto
+			show
+			moveto
+		} ifelse
+	} cforall
+} def
+/hvawidthshow
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse
+} def
+/hvwidthshow
+{
+	0 0 3 -1 roll hvawidthshow
+} def
+/hvashow
+{
+	0 0 0 6 -3 roll hvawidthshow
+} def
+/hvshow
+{
+	0 0 0 0 0 6 -1 roll hvawidthshow
+} def
+currentdict readonly pop end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_shading_AI8 1.0 0
+%%Title: (Adobe Illustrator 8 Shading Procset)
+%%Version: 1.0 0
+%%CreationDate: (12/17/97) ()
+%%Copyright: ((C) 1987-1997 Adobe Systems Incorporated All Rights Reserved)
+userdict /defaultpacking currentpacking put true setpacking
+userdict /Adobe_shading_AI8 10 dict dup begin put
+/initialize {
+	Adobe_shading_AI8 begin
+	Adobe_shading_AI8 bdprocs
+	Mesh /initialize get exec
+} def
+/terminate {
+	currentdict Adobe_shading_AI8 eq {
+	 end
+	} if
+} def
+/bdprocs {
+	{
+		dup xcheck 1 index type /arraytype eq and {
+			bind
+		} if
+		pop pop
+	} forall
+} def
+/X! {pop} def
+/X# {pop pop} def
+/Mesh 40 dict def
+Mesh begin
+/initialize {
+	Mesh bdprocs
+	Mesh begin
+		/emulate? /AI8MeshEmulation where {
+			pop AI8MeshEmulation
+		}{
+			systemdict /shfill known not
+		} ifelse def
+ end
+} def
+/bd {
+	shadingdict begin
+} def
+/paint {
+	emulate? {
+	 end
+	}{
+		/_lp /none ddef _fc /_lp /none ddef
+		
+		/AIColorSpace AIColorSpace tocolorspace store
+		/ColorSpace AIColorSpace topsspace store
+		
+		version_ge_3010.106 not systemdict /setsmoothness known and {
+			0.0001 setsmoothness
+		} if
+		
+		composite? {
+			/DataSource getdatasrc def
+			Matrix concat
+			currentdict end
+			shfill
+		}{
+			AIColorSpace makesmarks AIPlateList markingplate and not isoverprint and {
+			 end
+			}{
+				/ColorSpace /DeviceGray store
+				/Decode [0 1 0 1 0 1] store
+				/DataSource getplatesrc def
+				Matrix concat
+				currentdict end
+				shfill
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/shadingdict 12 dict def
+shadingdict begin
+	/ShadingType 6 def
+	/BitsPerCoordinate 16 def
+	/BitsPerComponent 8 def
+	/BitsPerFlag 8 def
+end
+/datafile null def
+/databuf 256 string def
+/dataptr 0 def
+/srcspace null def
+/srcchannels 0 def
+/dstchannels 0 def
+/dstplate 0 def
+/srctodstcolor null def
+/getplatesrc {
+	/srcspace AIColorSpace store
+	/srcchannels AIColorSpace getnchannels store
+	/dstchannels 1 store
+	/dstplate getplateindex store
+	/srctodstcolor srcspace makesmarks {
+		dstplate 4 eq {
+			{1 exch sub}
+		}{
+			{srcspace tocmyk 3 dstplate sub index 1 exch sub 5 1 roll 4 {pop} repeat}
+		} ifelse
+	}{
+		{srcchannels {pop} repeat 1}
+	} ifelse store
+	/datafile getdatasrc store
+	/rdpatch168 load DataLength () /SubFileDecode filter
+} def
+/getdatasrc {
+	/rdcmntline load /ASCII85Decode filter
+} def
+/rdpatch168 {
+	/dataptr 0 store
+	49 rdcount
+	4 {
+		dup {pop srcchannels getint8} if
+		dup {pop srctodstcolor dstchannels putint8 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdpatch3216 {
+	/dataptr 0 store
+	97 rdcount
+	4 {
+		dup {pop srcchannels getint16} if
+		dup {pop srctodstcolor dstchannels putint16 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdcount {
+	dup 0 gt {
+		datafile databuf dataptr 4 -1 roll getinterval readstring
+		exch length dataptr add /dataptr exch store
+	}{
+		true
+	} ifelse
+} def
+/getint8 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 255 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint8 {
+	dup dataptr add /dataptr exch store
+	dataptr exch
+	{
+		1 sub exch
+		255 mul cvi
+		databuf 2 index
+		3 -1 roll put
+	} repeat
+	pop
+} def 
+/getint16 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 256 mul datafile read} if
+		dup {pop add 65535 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint16 {
+	dup 2 mul dataptr add /dataptr exch store
+	dataptr exch
+	{
+		2 sub exch
+		65535 mul cvi dup
+		256 idiv databuf 3 index 3 -1 roll put
+		256 mod databuf 2 index 1 add 3 -1 roll put
+	} repeat
+	pop
+} def 
+/srcbuf 256 string def
+/rdcmntline {
+	currentfile srcbuf readline pop
+	(%) anchorsearch {pop} if
+} def
+/getplateindex {
+	0 [cyan? magenta? yellow? black? customColor?] {{exit} if 1 add} forall
+} def
+/aicsarray 4 array def
+/aicsaltvals 4 array def
+/aicsaltcolr aicsaltvals def
+/tocolorspace {
+	dup type /arraytype eq {
+		mark exch aload pop
+		aicsarray 0 3 -1 roll put
+		aicsarray 1 3 -1 roll put
+		dup aicsarray 2 3 -1 roll put
+		gettintxform aicsarray 3 3 -1 roll put
+		counttomark aicsaltvals 0 3 -1 roll getinterval /aicsaltcolr exch store
+		aicsaltcolr astore pop pop
+		aicsarray
+	} if
+} def
+/subtintxform {aicsaltcolr {1 index mul exch} forall pop} def
+/addtintxform {aicsaltcolr {1 sub 1 index mul 1 add exch} forall pop} def
+/gettintxform {
+	/DeviceRGB eq {/addtintxform}{/subtintxform} ifelse load
+} def
+/getnchannels {
+	dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin Channels end
+} def
+/makesmarks {
+	composite? {
+		pop true
+	}{
+		dup dup type /arraytype eq {0 get} if
+		colorspacedict exch get begin MarksPlate end
+	} ifelse
+} def
+/markingplate {
+	composite? {
+		pop true
+	}{
+		dup type /arraytype eq {
+			dup length getplateindex gt {getplateindex get}{pop false} ifelse
+		} if
+	} ifelse
+} def
+/tocmyk {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToCMYK end
+} def
+/topsspace {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToPSSpace end
+} def
+/colorspacedict 5 dict dup begin
+	/DeviceGray 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {pop black?} def
+		/ToCMYK {pop 1 exch sub 0 0 0 4 -1 roll} def
+		/ToPSSpace {} def
+ end def
+	/DeviceRGB 4 dict dup begin
+		/Channels 3 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop _rgbtocmyk} def
+		/ToPSSpace {} def
+ end def
+	/DeviceCMYK 4 dict dup begin
+		/Channels 4 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop} def
+		/ToPSSpace {} def
+ end def
+	/Separation 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			/findcmykcustomcolor where {
+				pop dup 1 exch ToCMYK 5 -1 roll 1 get
+				findcmykcustomcolor 1 setcustomcolor
+				systemdict /currentgray get exec
+				1 ne
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {} def
+ end def
+	/Process 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			isCMYKSep? {
+				1 exch ToCMYK 4 array astore getplateindex get 0 ne 
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {
+			4 array copy dup 0 /Separation put
+		} def
+ end def
+end def
+/isoverprint {
+	/currentoverprint where {pop currentoverprint}{_of} ifelse
+} def
+/version_ge_3010.106 {
+   version {cvr} stopped {
+      pop
+      false
+   }{
+      3010.106 ge
+   } ifelse
+} def
+end
+end
+defaultpacking setpacking
+%%EndResource
+%%EndProlog
+%%BeginSetup
+userdict /_useSmoothShade true put
+userdict /_aicmykps false put
+userdict /_forceToCMYK false put
+Adobe_level2_AI5 /initialize get exec
+Adobe_cshow /initialize get exec
+Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 AGM_Gradient /initializeAI get exec
+Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_pattern_AI5 /initialize get exec
+Adobe_ColorImage_AI6 /initialize get exec
+Adobe_shading_AI8 /initialize get exec
+Adobe_Illustrator_AI5 /initialize get exec
+%AI5_Begin_NonPrinting
+Np
+4 Bn
+%AI5_BeginGradient: (Black, White)
+(Black, White) 0 2 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0 %_Br
+[
+0 0 50 100 %_BS
+%_0 0 50 100 Bs
+1 0 50 0 %_BS
+%_1 0 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Chrome)
+(Chrome) 0 6 Bd
+[
+0
+<
+464646454545444444444343434342424241414141404040403F3F3F3E3E3E3E3D3D3D3C3C3C3C3B
+3B3B3B3A3A3A39393939383838383737373636363635353535343434333333333232323131313130
+3030302F2F2F2E2E2E2E2D2D2D2D2C2C2C2B2B2B2B2A2A2A2A292929282828282727272626262625
+2525252424242323232322222222212121202020201F1F1F1F1E1E1E1D1D1D1D1C1C1C1B1B1B1B1A
+1A1A1A1919191818181817171717161616151515151414141413131312121212111111101010100F
+0F0F0F0E0E0E0D0D0D0D0C0C0C0C0B0B0B0A0A0A0A09090909080808070707070606060505050504
+04040403030302020202010101010000
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+1F1E1E1E1E1E1E1E1E1E1D1D1D1D1D1D1D1D1C1C1C1C1C1C1C1C1B1B1B1B1B1B1B1B1B1A1A1A1A1A
+1A1A1A19191919191919191818181818181818181717171717171717161616161616161615151515
+15151515151414141414141414131313131313131312121212121212121211111111111111111010
+1010101010100F0F0F0F0F0F0F0F0F0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0C0C0C0C0C0C0C0C0C
+0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A090909090909090909080808080808080807070707070707
+07060606060606060606050505050505050504040404040404040303030303030303030202020202
+02020201010101010101010000000000
+>
+1 %_Br
+0
+0.275
+1
+<
+6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544
+434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F
+>
+1 %_Br
+0
+<
+00000101010102020202030303040404040505050606060607070707080808090909090A0A0A0A0B
+0B0B0C0C0C0C0D0D0D0D0E0E0E0F0F0F0F1010101111111112121212131313141414141515151516
+161617171717181818181919191A1A1A1A1B1B1B1C1C1C1C1D1D1D1D1E1E1E1F1F1F1F2020202021
+212122222222232323232424242525252526262627272727282828282929292A2A2A2A2B2B2B2B2C
+2C2C2D2D2D2D2E2E2E2E2F2F2F303030303131313232323233333333343434353535353636363637
+373738383838393939393A3A3A3B3B3B3B3C3C3C3D3D3D3D3E3E3E3E3F3F3F404040404141414142
+42424343434344444444454545464646
+>
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+<
+00000101020203030304040505050606070708080809090A0A0B0B0B0C0C0D0D0D0E0E0F0F101010
+1111121212131314141515151616171718181819191A1A1A1B1B1C1C1D1D1D1E1E1F1F1F20202121
+222222232324242525252626272727282829292A2A2A2B2B2C2C2D2D2D2E2E2F2F2F303031313232
+32333334343435353636373737383839393A3A3A3B3B3C3C3C3D3D3E3E3F3F3F4040414142424243
+4344444445454646474747484849494A4A4A4B4B4C4C4C4D4D4E4E4F4F4F50505151515252535354
+54545555565657575758585959595A5A5B5B5C5C5C5D5D5E5E5E5F5F606061616162626363646464
+6565666666676768686969696A6A6B6B
+>
+1 %_Br
+1
+0 %_Br
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+4D4C4C4C4B4B4B4A4A4A4A4949494848484747474746464645454544444444434343424242414141
+414040403F3F3F3E3E3E3E3D3D3D3C3C3C3B3B3B3B3A3A3A39393938383838373737363636353535
+35343434333333323232323131313030302F2F2F2F2E2E2E2D2D2D2C2C2C2C2B2B2B2A2A2A292929
+2928282827272726262626252525242424232323232222222121212020201F1F1F1F1E1E1E1D1D1D
+1C1C1C1C1B1B1B1A1A1A191919191818181717171616161615151514141413131313121212111111
+101010100F0F0F0E0E0E0D0D0D0D0C0C0C0B0B0B0A0A0A0A09090908080807070707060606050505
+04040404030303020202010101010000
+>
+0
+0
+1 %_Br
+[
+1 0 50 92 %_BS
+%_1 0 50 92 Bs
+0 0.275 1 0.12 1 50 59 %_BS
+%_0 0.275 1 0.12 1 50 59 Bs
+0 0.275 1 0.42 1 50 50 %_BS
+%_0 0.275 1 0.42 1 50 50 Bs
+1 0 50 49 %_BS
+%_1 0 50 49 Bs
+1 0 50 41 %_BS
+%_1 0 50 41 Bs
+1 0.3 0 0 1 50 0 %_BS
+%_1 0.3 0 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Rainbow)
+(Rainbow) 0 6 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+0
+1 %_Br
+1
+<
+0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
+2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
+5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
+7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
+A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
+CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
+F7F8F9FAFBFCFDFEFF
+>
+0
+0
+1 %_Br
+1
+<
+00000000000000000000000000000000000001010101010101010101010101010101010101010101
+01010101010101010101010101010202020202020202020202020202020202020202020202020202
+02020202020202020202030303030303030303030303030303030303030303030303030303030303
+03030303030304040404040404040404040404040404040404040404040404040404040404040404
+04040505050505050505050505050505050505050505050505050505050505050505050505050606
+06060606060606060606060606060606060606060606060606060606060606060607070707070707
+07070707070707070707070707070707
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0
+1 %_Br
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+0
+1
+0
+1 %_Br
+0
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+1 %_Br
+[
+0 1 0 0 1 50 100 %_BS
+%_0 1 0 0 1 50 100 Bs
+1 1 0 0 1 50 80 %_BS
+%_1 1 0 0 1 50 80 Bs
+1 0.0279 0 0 1 50 60 %_BS
+%_1 0.0279 0 0 1 50 60 Bs
+1 0 1 0 1 50 40 %_BS
+%_1 0 1 0 1 50 40 Bs
+0 0 1 0 1 50 20 %_BS
+%_0 0 1 0 1 50 20 Bs
+0 1 1 0 1 50 0 %_BS
+%_0 1 1 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Yellow & Orange Radial)
+(Yellow & Orange Radial) 1 2 Bd
+[
+0
+<
+0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
+232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
+494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
+707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
+>
+<
+FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
+F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
+F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
+EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E6
+>
+0
+1 %_Br
+[
+0 0 1 0 1 52 19 %_BS
+%_0 0 1 0 1 52 19 Bs
+0 0.55 0.9 0 1 50 100 %_BS
+%_0 0.55 0.9 0 1 50 100 Bs
+BD
+%AI5_EndGradient
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI3_BeginPattern: (Brick)
+(Brick) 0 0 72 72 [
+%AI3_Tile
+(0 O 0 R 0.3 0.85 0.85 0 k
+ 0.3 0.85 0.85 0 K
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 1 w 4 M []0 d0 XR
+0 0 m
+0 72 L
+72 72 L
+72 0 L
+0 0 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 0.3 w 4 M []0 d0 XR
+0 68.4097 m
+72 68.4097 l
+S0 61.209 m
+72 61.209 L
+S0 54.0088 m
+72 54.0088 L
+S0 46.8076 m
+72 46.8076 L
+S0 39.6084 m
+72 39.6084 L
+S0 32.4072 m
+72 32.4072 L
+S0 25.207 m
+72 25.207 L
+S0 18.0059 m
+72 18.0059 L
+S0 10.8057 m
+72 10.8057 L
+S0 3.6064 m
+72 3.6064 L
+S68.4102 68.4097 m
+68.4102 61.2217 l
+S54.0098 68.4097 m
+54.0098 61.2217 L
+S39.6094 68.4097 m
+39.6094 61.2217 L
+S25.21 68.4097 m
+25.21 61.2217 L
+S10.8105 68.4097 m
+10.8105 61.2217 L
+S68.4102 53.9717 m
+68.4102 46.7842 l
+S54.0098 53.9717 m
+54.0098 46.7842 L
+S39.6094 53.9717 m
+39.6094 46.7842 L
+S25.21 53.9717 m
+25.21 46.7842 L
+S10.8105 53.9717 m
+10.8105 46.7842 L
+S68.4102 39.5967 m
+68.4102 32.4092 l
+S54.0098 39.5967 m
+54.0098 32.4092 L
+S39.6094 39.5967 m
+39.6094 32.4092 L
+S25.21 39.5967 m
+25.21 32.4092 L
+S10.8105 39.5967 m
+10.8105 32.4092 L
+S68.4102 25.2217 m
+68.4102 18.0342 l
+S54.0098 25.2217 m
+54.0098 18.0342 L
+S39.6094 25.2217 m
+39.6094 18.0342 L
+S25.21 25.2217 m
+25.21 18.0342 L
+S10.8105 25.2217 m
+10.8105 18.0342 L
+S68.4102 10.7842 m
+68.4102 3.5967 l
+S54.0098 10.7842 m
+54.0098 3.5967 L
+S39.6094 10.7842 m
+39.6094 3.5967 L
+S25.21 10.7842 m
+25.21 3.5967 L
+S10.8105 10.7842 m
+10.8105 3.5967 L
+S61.1973 3.5967 m
+61.1973 0 L
+S46.7969 3.5967 m
+46.7969 0 L
+S32.3965 3.5967 m
+32.3965 0 L
+S17.9971 3.5967 m
+17.9971 0 L
+S3.5967 3.5967 m
+3.5967 0 l
+S61.1973 18.0342 m
+61.1973 10.8467 L
+S46.7969 18.0342 m
+46.7969 10.8467 L
+S32.3965 18.0342 m
+32.3965 10.8467 L
+S17.9971 18.0342 m
+17.9971 10.8467 L
+S3.5967 18.0342 m
+3.5967 10.8467 l
+S61.1973 32.4092 m
+61.1973 25.2217 L
+S46.7969 32.4092 m
+46.7969 25.2217 L
+S17.9971 32.4092 m
+17.9971 25.2217 L
+S3.5967 32.4092 m
+3.5967 25.2217 l
+S61.1973 46.7842 m
+61.1973 39.5967 L
+S46.7969 46.7842 m
+46.7969 39.5967 L
+S32.3965 46.7842 m
+32.3965 39.5967 L
+S17.9971 46.7842 m
+17.9971 39.5967 L
+S3.5967 46.7842 m
+3.5967 39.5967 l
+S61.1973 61.2217 m
+61.1973 54.0347 L
+S46.7969 61.2217 m
+46.7969 54.0347 L
+S32.3965 61.2217 m
+32.3965 54.0347 L
+S17.9971 61.2217 m
+17.9971 54.0347 L
+S3.5967 61.2217 m
+3.5967 54.0347 l
+S61.1973 71.959 m
+61.1973 68.4717 L
+S46.7969 71.959 m
+46.7969 68.4717 L
+S32.3965 71.959 m
+32.3965 68.4717 L
+S17.9971 71.959 m
+17.9971 68.4717 L
+S3.5967 71.959 m
+3.5967 68.4717 l
+S32.3965 32.4092 m
+32.3965 25.2217 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Confetti)
+(Confetti) 4.85 3.617 76.85 75.617 [
+%AI3_Tile
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 1 w 4 M []0 d0 XR
+4.85 3.617 m
+4.85 75.617 L
+76.85 75.617 L
+76.85 3.617 L
+4.85 3.617 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0 g
+ 0 G
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 0.3 w 4 M []0 d0 XR
+10.6 64.867 m
+7.85 62.867 l
+S9.1 8.617 m
+6.85 6.867 l
+S78.1 68.617 m
+74.85 67.867 l
+S76.85 56.867 m
+74.35 55.117 l
+S79.6 51.617 m
+76.6 51.617 l
+S76.35 44.117 m
+73.6 45.867 l
+S78.6 35.867 m
+76.6 34.367 l
+S76.1 23.867 m
+73.35 26.117 l
+S78.1 12.867 m
+73.85 13.617 l
+S68.35 14.617 m
+66.1 12.867 l
+S76.6 30.617 m
+73.6 30.617 l
+S62.85 58.117 m
+60.956 60.941 l
+S32.85 59.617 m
+31.196 62.181 l
+S47.891 64.061 m
+49.744 66.742 l
+S72.814 2.769 m
+73.928 5.729 l
+S67.976 2.633 m
+67.35 5.909 l
+S61.85 27.617 m
+59.956 30.441 l
+S53.504 56.053 m
+51.85 58.617 l
+S52.762 1.779 m
+52.876 4.776 l
+S45.391 5.311 m
+47.244 7.992 l
+S37.062 3.375 m
+35.639 5.43 l
+S55.165 34.828 m
+57.518 37.491 l
+S20.795 3.242 m
+22.12 5.193 l
+S14.097 4.747 m
+15.008 8.965 l
+S9.736 1.91 m
+8.073 4.225 l
+S31.891 5.573 m
+32.005 8.571 l
+S12.1 70.367 m
+15.6 68.867 l
+S9.35 54.867 m
+9.6 58.117 l
+S12.85 31.867 m
+14.35 28.117 l
+S10.1 37.367 m
+12.35 41.117 l
+S34.1 71.117 m
+31.85 68.617 l
+S38.35 71.117 m
+41.6 68.367 l
+S55.1 71.117 m
+58.35 69.117 l
+S57.35 65.117 m
+55.35 61.867 l
+S64.35 66.367 m
+69.35 68.617 l
+S71.85 62.867 m
+69.35 61.117 l
+S23.6 70.867 m
+23.6 67.867 l
+S20.6 65.867 m
+17.35 65.367 l
+S24.85 61.367 m
+25.35 58.117 l
+S25.85 65.867 m
+29.35 66.617 l
+S14.1 54.117 m
+16.85 56.117 l
+S12.35 11.617 m
+12.6 15.617 l
+S12.1 19.867 m
+14.35 22.367 l
+S26.1 9.867 m
+23.6 13.367 l
+S34.6 47.117 m
+32.1 45.367 l
+S62.6 41.867 m
+59.85 43.367 l
+S31.6 35.617 m
+27.85 36.367 l
+S36.35 26.117 m
+34.35 24.617 l
+S33.85 14.117 m
+31.1 16.367 l
+S37.1 9.867 m
+35.1 11.117 l
+S34.35 20.867 m
+31.35 20.867 l
+S44.6 56.617 m
+42.1 54.867 l
+S47.35 51.367 m
+44.35 51.367 l
+S44.1 43.867 m
+41.35 45.617 l
+S43.35 33.117 m
+42.6 30.617 l
+S43.85 23.617 m
+41.1 25.867 l
+S44.35 15.617 m
+42.35 16.867 l
+S67.823 31.1 m
+64.823 31.1 l
+S27.1 32.617 m
+29.6 30.867 l
+S31.85 55.117 m
+34.85 55.117 l
+S19.6 40.867 m
+22.1 39.117 l
+S16.85 35.617 m
+19.85 35.617 l
+S20.1 28.117 m
+22.85 29.867 l
+S52.1 42.617 m
+54.484 44.178 l
+S52.437 50.146 m
+54.821 48.325 l
+S59.572 54.133 m
+59.35 51.117 l
+S50.185 10.055 m
+53.234 9.928 l
+S51.187 15.896 m
+53.571 14.075 l
+S58.322 19.883 m
+59.445 16.823 l
+S53.1 32.117 m
+50.6 30.367 l
+S52.85 24.617 m
+49.6 25.617 l
+S61.85 9.117 m
+59.1 10.867 l
+S69.35 34.617 m
+66.6 36.367 l
+S67.1 23.617 m
+65.1 22.117 l
+S24.435 46.055 m
+27.484 45.928 l
+S25.437 51.896 m
+27.821 50.075 l
+S62.6 47.117 m
+65.321 46.575 l
+S19.85 19.867 m
+20.35 16.617 l
+S21.85 21.867 m
+25.35 22.617 l
+S37.6 62.867 m
+41.6 62.117 l
+S38.323 42.1 m
+38.823 38.6 l
+S69.35 52.617 m
+66.85 53.867 l
+S14.85 62.117 m
+18.1 59.367 l
+S9.6 46.117 m
+7.1 44.367 l
+S20.6 51.617 m
+18.6 50.117 l
+S46.141 70.811 m
+47.994 73.492 l
+S69.391 40.561 m
+71.244 43.242 l
+S38.641 49.311 m
+39.35 52.117 l
+S25.141 16.811 m
+25.85 19.617 l
+S36.6 32.867 m
+34.6 31.367 l
+S6.1 68.617 m
+2.85 67.867 l
+S4.85 56.867 m
+2.35 55.117 l
+S7.6 51.617 m
+4.6 51.617 l
+S6.6 35.867 m
+4.6 34.367 l
+S6.1 12.867 m
+1.85 13.617 l
+S4.6 30.617 m
+1.6 30.617 l
+S72.814 74.769 m
+73.928 77.729 l
+S67.976 74.633 m
+67.35 77.909 l
+S52.762 73.779 m
+52.876 76.776 l
+S37.062 75.375 m
+35.639 77.43 l
+S20.795 75.242 m
+22.12 77.193 l
+S9.736 73.91 m
+8.073 76.225 l
+S10.1 23.617 m
+6.35 24.367 l
+S73.217 18.276 m
+71.323 21.1 l
+S28.823 39.6 m
+29.505 42.389 l
+S49.6 38.617 m
+47.6 37.117 l
+S60.323 73.6 m
+62.323 76.6 l
+S60.323 1.6 m
+62.323 4.6 l
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Leaves - Fall )
+(Leaves - Fall ) 0 0 64.0781 78.9336 [
+%AI3_Tile
+(0 O 0 R 0.05 0.2 1 0 k
+ 0.05 0.2 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 1 w 4 M []0 d0 XR
+64.0781 78.9336 m
+64.0781 0 L
+0 0 L
+0 78.9336 L
+64.0781 78.9336 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0.83 0 1 0 k
+ 0.83 0 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 1 w 4 M []0 d0 XR
+29.7578 0.9902 m
+30.4346 1.1914 30.7246 1.3428 V
+29.2559 4.0547 33.707 8.3359 34.627 9.0762 C
+35.2275 8.8506 35.3477 6.3184 34.6699 4.9805 C
+35.5137 5.1035 37.7031 3.7256 38.4609 2.4365 C
+38.5254 3.125 40.0957 6.0664 40.9219 6.4434 C
+40.002 6.8408 39.3359 8.3135 38.5742 9.7617 C
+39.5957 9.9287 40.9961 9.0078 42.4668 8.1025 C
+42.9814 8.9043 44.3555 9.875 45.6143 10.3916 C
+44.5264 11.0781 44.0313 11.8203 43.5352 13.2793 C
+42.4922 12.7139 40.3057 12.5645 39.7764 12.8516 C
+40.291 13.9648 42.5371 14.5078 43.2676 14.4551 C
+43.0137 15.3164 42.8652 17.4697 43.0391 20.0625 C
+41.3789 18.7461 39.834 17.4297 38.1738 17.4883 C
+38.4434 16.0664 37.8076 14.2607 37.4307 13.7676 C
+36.8574 14.5117 36.4463 15.3389 36.8008 17.3164 C
+35.3486 17.8008 34.1113 18.3467 32.7373 19.6045 C
+32.7373 17.7734 32.166 16.5723 31.2969 15.2959 C
+32.5576 14.8076 33.8301 13.6045 33.8252 12.5664 C
+32.9775 12.7178 31.2852 13.4619 30.793 14.4551 C
+30.0742 13.707 28.3906 12.3984 26.7871 12.3945 C
+27.9746 11.5391 28.8945 10.5059 28.9893 8.5938 C
+30.2422 9.5645 32.6953 10.1797 34.0752 9.582 C
+29.2344 5.3457 29.7031 2.3125 29.7578 0.9902 C
+f13.8525 29.9844 m
+13.3281 29.5127 13.1309 29.25 V
+15.623 27.4326 13.3691 21.6074 12.8555 20.5439 C
+12.2168 20.4883 10.8096 23.2285 10.8457 24.7266 C
+9.7129 23.9707 8.0488 24.0918 6.4463 24.3779 C
+7.0186 23.2891 6.6172 21.3447 5.8164 20.5439 C
+6.8184 20.5801 8.1699 19.8652 9.4785 18.8838 C
+8.6436 18.0645 6.8164 18.2246 4.9004 18.8838 C
+4.9004 17.5107 4.0781 15.7734 3.2412 14.5918 C
+4.5576 14.6484 5.7031 13.9629 6.5605 12.9316 C
+7.2256 14.5 9.2598 15.6133 10.166 15.5645 C
+10.1826 14.1992 8.6094 12.1094 7.5879 11.7109 C
+8.1875 11.041 9.207 9.5107 10.166 7.0947 C
+10.9648 9.0205 12.1348 10.2627 13.3672 11.1953 C
+12.2256 12.7578 12.3994 13.6289 12.7988 15.1074 C
+13.541 14.5664 14.5723 14.1338 14.7441 12.1309 C
+16.4609 12.416 17.5957 12.3447 19.0938 11.4434 C
+18.6387 13.1055 18.6348 14.707 18.9551 16.4063 C
+17.1055 16.2666 15.5449 16.4795 14.5156 17.9688 C
+15.3457 18.1953 17.6055 18.2549 18.4795 17.3223 C
+18.8066 18.3047 19.7012 19.7109 21.1475 20.4043 C
+19.707 20.6641 18.7227 21.7637 17.8135 23.4492 C
+17.1006 22.0332 14.873 20.3691 13.3711 20.3145 C
+15.373 24.3779 15.373 27.2959 13.8525 29.9844 C
+f41.2324 26.0742 m
+41.5518 26.7021 41.7549 26.959 V
+44.1523 25.0176 48.958 28.3262 49.8535 29.0957 C
+49.7432 29.7266 47.6182 30.8643 45.9004 29.834 C
+46.3408 31.123 45.4395 33.084 44.2402 34.126 C
+45.9805 34.0254 48.126 35.3867 48.6484 36.1289 C
+48.8701 35.1514 50.0527 33.8809 51.3379 32.8672 C
+51.6895 33.8398 50.9941 35.958 50.0781 37.5605 C
+51.3125 38.0605 52.4248 38.9912 52.8828 40.25 C
+53.3398 38.9336 54.3428 38.2598 55.6875 37.5039 C
+54.5273 36.0762 53.7471 33.9023 54.0273 33.0391 C
+55.3496 33.374 56.9209 36.0918 57.0439 37.1816 C
+57.9189 36.415 59.4727 35.7285 62.0537 35.4219 C
+60.3535 34.3438 59.9902 32.3516 59.4063 30.9219 C
+58.2588 31.3682 56.0898 31.4277 55.1152 30.8643 C
+55.8281 30.2852 57.168 29.7344 59.1777 29.7207 C
+59.1777 28.1758 59.6406 27.043 60.8945 25.8281 C
+59.1719 25.8418 57.0723 25.3555 55.5762 24.9629 C
+55.3281 26.292 54.4844 27.8887 53.3398 28.2891 C
+53.334 27.4277 53.5996 25.1797 54.4844 24.5117 C
+53.6201 23.9443 52.3672 22.5674 51.9102 20.8496 C
+51.2881 22.1758 50.4268 23.4805 48.5645 23.9238 C
+49.749 24.9766 50.584 26.9941 50.25 28.4609 C
+45.1973 24.4785 42.5215 25.7773 41.2324 26.0742 C
+f27.7578 38.7324 m
+28.4346 38.9316 28.7246 39.084 V
+27.2559 41.7969 31.707 46.0776 32.627 46.8169 C
+33.2275 46.5918 33.3477 44.0586 32.6699 42.7227 C
+33.5137 42.8457 35.7031 41.4678 36.4609 40.1787 C
+36.5254 40.8652 38.0957 43.8066 38.9219 44.1846 C
+38.002 44.582 37.3359 46.0547 36.5742 47.5039 C
+37.5957 47.6709 38.9961 46.7485 40.4668 45.8438 C
+40.9814 46.6445 42.3555 47.6177 43.6143 48.1328 C
+42.5264 48.8198 42.0313 49.5615 41.5352 51.0205 C
+40.4922 50.4556 38.3057 50.3057 37.7764 50.5938 C
+38.291 51.7056 40.5371 52.2485 41.2676 52.1958 C
+41.0137 53.0576 40.8652 55.2109 41.0391 57.8037 C
+39.3789 56.4878 37.834 55.1719 36.1738 55.2285 C
+36.4434 53.8076 35.8076 52.002 35.4307 51.5088 C
+34.8574 52.2529 34.4463 53.0796 34.8008 55.0576 C
+33.3486 55.5425 32.1113 56.0879 30.7373 57.3467 C
+30.7373 55.5146 30.166 54.314 29.2969 53.0366 C
+30.5576 52.5488 31.8301 51.3467 31.8252 50.3076 C
+30.9775 50.46 29.2852 51.2036 28.793 52.1958 C
+28.0742 51.4497 26.3906 50.1396 24.7871 50.1357 C
+25.9746 49.2817 26.8945 48.2466 26.9893 46.335 C
+28.2422 47.3057 30.6953 47.9209 32.0752 47.3237 C
+27.2344 43.0869 27.7031 40.0547 27.7578 38.7324 C
+f13.5195 70.3916 m
+12.9941 69.9209 12.7988 69.6587 V
+15.2891 67.8418 13.0352 62.0146 12.5225 60.9517 C
+11.8828 60.8955 10.4766 63.6367 10.5117 65.1348 C
+9.3809 64.3789 7.7148 64.4995 6.1133 64.7856 C
+6.6855 63.6987 6.2842 61.7529 5.4834 60.9517 C
+6.4854 60.9878 7.8359 60.2729 9.1455 59.2925 C
+8.3105 58.4717 6.4834 58.6338 4.5674 59.2925 C
+4.5674 57.9189 3.7461 56.1816 2.9082 54.9995 C
+4.2246 55.0576 5.3691 54.3706 6.2275 53.3408 C
+6.8926 54.9097 8.9258 56.0215 9.832 55.9727 C
+9.8496 54.6079 8.2764 52.5176 7.2539 52.1187 C
+7.8545 51.4497 8.873 49.9189 9.832 47.5039 C
+10.6309 49.4297 11.8008 50.6719 13.0342 51.6045 C
+11.8926 53.1655 12.0664 54.0366 12.4648 55.5146 C
+13.209 54.9746 14.2393 54.5415 14.4102 52.5386 C
+16.127 52.8247 17.2637 52.7529 18.7598 51.8525 C
+18.3057 53.5137 18.3027 55.1147 18.623 56.8149 C
+16.7725 56.6748 15.2129 56.8887 14.1826 58.377 C
+15.0117 58.6035 17.2725 58.6626 18.1465 57.731 C
+18.4736 58.7129 19.3691 60.1187 20.8145 60.8125 C
+19.375 61.0728 18.3896 62.1719 17.4805 63.8579 C
+16.7676 62.4429 14.541 60.7769 13.0371 60.7227 C
+15.041 64.7856 15.041 67.7046 13.5195 70.3916 C
+f41.2324 64.4824 m
+41.5518 65.1113 41.7549 65.3682 V
+44.1523 63.4272 48.958 66.7354 49.8535 67.5034 C
+49.7432 68.1362 47.6182 69.2725 45.9004 68.2422 C
+46.3408 69.5313 45.4395 71.4922 44.2402 72.5342 C
+45.9805 72.4341 48.126 73.7954 48.6484 74.5371 C
+48.8701 73.5601 50.0527 72.29 51.3379 71.2754 C
+51.6895 72.249 50.9941 74.3662 50.0781 75.9683 C
+51.3125 76.4692 52.4248 77.3994 52.8828 78.6582 C
+53.3398 77.3423 54.3428 76.667 55.6875 75.9111 C
+54.5273 74.4844 53.7471 72.3101 54.0273 71.4473 C
+55.3496 71.7822 56.9209 74.5 57.0439 75.5903 C
+57.9189 74.8232 59.4727 74.1372 62.0537 73.8311 C
+60.3535 72.7534 59.9902 70.7612 59.4063 69.3301 C
+58.2588 69.7773 56.0898 69.8364 55.1152 69.2725 C
+55.8281 68.6934 57.168 68.1431 59.1777 68.1284 C
+59.1777 66.583 59.6406 65.4512 60.8945 64.2373 C
+59.1719 64.249 57.0723 63.7632 55.5762 63.3721 C
+55.3281 64.7002 54.4844 66.2974 53.3398 66.6973 C
+53.334 65.8364 53.5996 63.5874 54.4844 62.9214 C
+53.6201 62.353 52.3672 60.9751 51.9102 59.2583 C
+51.2881 60.583 50.4268 61.8882 48.5645 62.333 C
+49.749 63.3862 50.584 65.4033 50.25 66.8691 C
+45.1973 62.8872 42.5215 64.1851 41.2324 64.4824 C
+f%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Stripes)
+(Stripes) 8.45 4.6001 80.45 76.6001 [
+%AI3_Tile
+(0 O 0 R 1 0.07 1 0 k
+ 1 0.07 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+0 J 0 j 3.6 w 4 M []0 d0 XR
+8.2 8.2 m
+80.7 8.2 L
+S8.2 22.6001 m
+80.7 22.6001 L
+S8.2 37.0002 m
+80.7 37.0002 L
+S8.2 51.4 m
+80.7 51.4 L
+S8.2 65.8001 m
+80.7 65.8001 L
+S8.2 15.4 m
+80.7 15.4 L
+S8.2 29.8001 m
+80.7 29.8001 L
+S8.2 44.2 m
+80.7 44.2 L
+S8.2 58.6001 m
+80.7 58.6001 L
+S8.2 73.0002 m
+80.7 73.0002 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginBrushPattern
+(New Pattern 1)
+0 A
+u1 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7844.75 8611 m
+-7844.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7844.75 8611 L
+nu0 Ap
+0 O
+1 g
+-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+F-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+F-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+F-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+F-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+F-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+F-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+F-7854.7817 8589.125 m
+-7860.9009 8587.6162 -7864.7817 8589.125 V
+-7868.877 8587.6484 -7874.7817 8589.125 V
+-7879.7446 8587.4492 -7884.7817 8589.125 V
+-7890.7969 8587.5742 -7894.7817 8589.125 V
+-7894.7817 8608.8096 L
+-7891.6958 8609.7842 -7888.2969 8609.9912 -7884.3799 8608.9082 C
+-7878.2134 8610.4912 -7874.4634 8608.9082 V
+-7869.4634 8610.4912 -7864.3799 8608.8242 V
+-7860.0474 8610.4082 -7854.3799 8608.9082 V
+-7848.8799 8610.3242 -7844.7817 8609.125 V
+-7844.7817 8589.4404 L
+-7847.5254 8588.4287 -7850.6514 8587.9287 -7854.7817 8589.125 C
+f0 R
+0 G
+1 J 1 j 0.5 w-7874.75 8609 m
+-7882.54 8610.9473 -7888.813 8607.585 -7894.75 8603.0488 C
+S-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+S-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+S-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+S-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+S-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+S-7864.75 8589 m
+-7856.96 8587.0527 -7850.687 8590.415 -7844.75 8594.9512 C
+S-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+S-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+SUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 10)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894 8610 m
+-7843.8921 8610 L
+-7843.8921 8553.9756 L
+-7894 8553.9756 L
+-7894 8610 L
+nu0 O
+0.1 1 1 0 k
+-7856.9014 8575.5752 m
+-7858.7178 8569.0957 -7868.8247 8572.4658 Y
+-7868.791 8572.5303 L
+-7878.8999 8569.1611 -7880.7144 8575.6396 V
+-7886.6758 8593.0068 -7881.4922 8599.7451 V
+-7874.7529 8609.3369 -7870.6055 8609.3369 V
+-7867.0103 8609.2705 L
+-7862.8638 8609.2705 -7856.125 8599.6816 Y
+-7850.9409 8592.9424 -7856.9014 8575.5752 Y
+fu0 0 0 1 k
+-7861.3926 8553.9756 m
+-7862.1167 8555.4199 -7862.9238 8556.4756 V
+-7862.4058 8556.0635 -7861.5151 8555.1924 -7861.3926 8553.9756 C
+f-7875.064 8556.4854 m
+-7875.8711 8555.4307 -7876.5942 8553.9863 Y
+-7876.4727 8555.2021 -7875.582 8556.0732 -7875.064 8556.4854 C
+fU0 0.61 0.74 0 k
+-7860.5977 8578.4609 m
+-7861.9038 8573.7959 -7869.1816 8576.2217 Y
+-7869.1567 8576.2686 L
+-7876.436 8573.8428 -7877.7417 8578.5078 V
+-7882.0337 8591.0117 -7878.3018 8595.8633 V
+-7873.4487 8602.7686 -7870.4634 8602.7686 V
+-7867.875 8602.7227 L
+-7864.8887 8602.7227 -7860.0366 8595.8174 Y
+-7856.3042 8590.9639 -7860.5977 8578.4609 Y
+fu1 Ap
+0.73 0.43 1 0.22 k
+0 R
+0 0 0 1 K
+-7864.6226 8581.2754 m
+-7863.813 8581.2754 -7863.1558 8580.6182 -7863.1558 8579.8096 c
+-7863.1558 8579 -7863.813 8578.3428 -7864.6226 8578.3428 c
+-7865.4321 8578.3428 -7866.0889 8579 -7866.0889 8579.8096 c
+-7866.0889 8580.6182 -7865.4321 8581.2754 -7864.6226 8581.2754 c
+b-7864.3638 8592.9971 m
+-7863.0806 8592.9971 -7862.0415 8592.1201 -7862.0415 8591.042 c
+-7862.0415 8589.9619 -7863.0806 8589.0869 -7864.3638 8589.0869 c
+-7865.645 8589.0869 -7866.6846 8589.9619 -7866.6846 8591.042 c
+-7866.6846 8592.1201 -7865.645 8592.9971 -7864.3638 8592.9971 c
+b-7863.834 8604.7861 m
+-7862.2817 8604.7861 -7861.0239 8604.1299 -7861.0239 8603.3213 c
+-7861.0239 8602.5117 -7862.2817 8601.8545 -7863.834 8601.8545 c
+-7865.3862 8601.8545 -7866.645 8602.5117 -7866.645 8603.3213 c
+-7866.645 8604.1299 -7865.3862 8604.7861 -7863.834 8604.7861 c
+b-7859.6104 8576.5264 m
+-7858.8687 8576.5264 -7858.2671 8575.8154 -7858.2671 8574.9365 c
+-7858.2671 8574.0596 -7858.8687 8573.3477 -7859.6104 8573.3477 c
+-7860.353 8573.3477 -7860.9546 8574.0596 -7860.9546 8574.9365 c
+-7860.9546 8575.8154 -7860.353 8576.5264 -7859.6104 8576.5264 c
+b-7858.0034 8598.083 m
+-7858.8818 8597.7354 -7859.1494 8596.335 -7858.603 8594.9541 c
+-7858.0566 8593.5752 -7856.9014 8592.7363 -7856.0234 8593.085 c
+-7855.145 8593.4326 -7854.877 8594.833 -7855.4233 8596.2139 c
+-7855.9702 8597.5947 -7857.125 8598.4316 -7858.0034 8598.083 c
+bu-7873.0566 8581.1592 m
+-7873.8662 8581.1592 -7874.5239 8580.502 -7874.5239 8579.6934 c
+-7874.5239 8578.8828 -7873.8662 8578.2266 -7873.0566 8578.2266 c
+-7872.248 8578.2266 -7871.5913 8578.8828 -7871.5913 8579.6934 c
+-7871.5913 8580.502 -7872.248 8581.1592 -7873.0566 8581.1592 c
+b-7873.3159 8592.8799 m
+-7874.5991 8592.8799 -7875.6382 8592.0049 -7875.6382 8590.9248 c
+-7875.6382 8589.8447 -7874.5991 8588.9697 -7873.3159 8588.9697 c
+-7872.0342 8588.9697 -7870.9951 8589.8447 -7870.9951 8590.9248 c
+-7870.9951 8592.0049 -7872.0342 8592.8799 -7873.3159 8592.8799 c
+b-7873.8457 8604.6709 m
+-7875.3975 8604.6709 -7876.6558 8604.0146 -7876.6558 8603.2041 c
+-7876.6558 8602.3936 -7875.3975 8601.7383 -7873.8457 8601.7383 c
+-7872.293 8601.7383 -7871.0352 8602.3936 -7871.0352 8603.2041 c
+-7871.0352 8604.0146 -7872.293 8604.6709 -7873.8457 8604.6709 c
+b-7878.0679 8576.4092 m
+-7878.811 8576.4092 -7879.4121 8575.6982 -7879.4121 8574.8213 c
+-7879.4121 8573.9443 -7878.811 8573.2334 -7878.0679 8573.2334 c
+-7877.3262 8573.2334 -7876.7241 8573.9443 -7876.7241 8574.8213 c
+-7876.7241 8575.6982 -7877.3262 8576.4092 -7878.0679 8576.4092 c
+b-7879.6758 8597.9678 m
+-7878.7983 8597.6201 -7878.5298 8596.2188 -7879.0762 8594.8379 c
+-7879.6226 8593.457 -7880.7778 8592.6201 -7881.6558 8592.9678 c
+-7882.5342 8593.3164 -7882.8032 8594.7178 -7882.2568 8596.0967 c
+-7881.7104 8597.4775 -7880.5552 8598.3154 -7879.6758 8597.9678 c
+bUU0 Ap
+0 0 0 1 k
+-7869.1318 8576.6553 m
+-7869.1318 8609.3145 l
+Fu-7853.3906 8562.5303 m
+-7854.0815 8561.8369 -7857.019 8562.7021 Y
+-7858.229 8562.874 -7858.0562 8565.2939 Y
+-7857.019 8567.3682 -7857.7104 8567.1943 Y
+-7858.2998 8567.1943 -7859.855 8567.1143 -7860.7822 8567.0635 C
+-7861.1226 8565.6689 -7862.6128 8564.4756 -7864.7217 8563.7695 C
+-7862.7578 8560.4775 -7864.5176 8559.7949 -7866.2935 8559.79 C
+-7866.3096 8559.7021 -7866.332 8559.6162 -7866.3599 8559.5332 C
+-7864.1089 8559.5791 -7863.6392 8557.2588 Y
+-7863.4048 8557.0635 -7863.1606 8556.7861 -7862.9238 8556.4756 C
+-7863.1416 8556.6475 -7863.2944 8556.7393 Y
+-7864.2583 8556.7393 -7865.8774 8558.4941 -7866.4966 8559.207 C
+-7866.9194 8558.4434 -7867.853 8557.9111 -7868.9434 8557.9111 c
+-7870.0698 8557.9111 -7871.0322 8558.4795 -7871.4312 8559.2852 C
+-7871.9985 8558.624 -7873.6968 8556.751 -7874.6943 8556.751 C
+-7874.8462 8556.6572 -7875.064 8556.4854 V
+-7874.8281 8556.7939 -7874.583 8557.0732 -7874.3481 8557.2686 C
+-7873.8638 8559.6563 -7871.5254 8559.5342 V
+-7871.5449 8559.5889 -7871.5674 8559.6436 -7871.5806 8559.7021 C
+-7874.9238 8559.6924 -7873.937 8562.3174 -7873.2104 8563.6602 C
+-7875.5918 8564.376 -7877.2646 8565.7012 -7877.5239 8567.25 C
+-7878.4473 8567.2998 -7879.6729 8567.3584 -7880.1802 8567.3584 C
+-7880.8726 8567.5313 -7879.835 8565.458 V
+-7879.6626 8563.0391 -7880.8726 8562.8662 V
+-7883.8096 8562.002 -7884.501 8562.6934 V
+-7885.1919 8563.5566 -7886.0562 8562.3467 V
+-7885.1919 8564.0752 -7883.291 8563.5566 V
+-7880.6982 8562.8662 -7881.3906 8564.5938 V
+-7881.9087 8568.0498 -7880.1802 8568.7402 V
+-7878.0342 8569.8545 -7876.2822 8570.0889 V
+-7875.9087 8570.4141 -7875.4639 8570.7109 -7874.958 8570.9766 C
+-7877.5562 8571.0469 -7880.2246 8571.9209 -7881.0752 8574.9561 C
+-7881.5151 8576.2432 -7882.0518 8578.2432 V
+-7883.1025 8578.8252 -7884.3022 8580.0078 -7885.541 8582.2627 C
+-7886.394 8585.4502 -7887.167 8580.7129 V
+-7888.3975 8577.6494 -7889.6504 8577.5381 V
+-7888.4702 8579.2871 -7888.9038 8580.416 V
+-7887.2998 8584.917 -7885.6138 8583.8994 V
+-7884.0986 8583.2197 -7882.688 8580.8154 V
+-7883.0698 8582.4971 -7883.4326 8584.417 -7883.6743 8586.3906 C
+-7884.4888 8586.3975 L
+-7886.3506 8585.4795 -7886.3262 8588.959 V
+-7887.1226 8592.9453 -7886.3594 8595.6826 V
+-7885.647 8598.1504 -7888.1274 8596.9307 V
+-7889.2842 8597.3242 -7889.9839 8596.7881 V
+-7892.3882 8595.4131 -7894 8597.124 V
+-7892.147 8596.8799 -7891.4482 8597.417 V
+-7889.9785 8597.5615 -7889.897 8598.1787 V
+-7886.9561 8598.8555 -7886.188 8598.0771 V
+-7884.417 8597.2139 -7885.1304 8594.3604 V
+-7885.8799 8586.4814 -7884.3198 8588.4053 V
+-7884.1182 8588.4219 -7883.8784 8588.5176 V
+-7884.1519 8592.4326 -7883.8018 8596.3252 -7881.9961 8598.8516 C
+-7885.4536 8591.333 -7880.2974 8576.3037 Y
+-7878.9609 8571.5303 -7873.127 8572.1016 -7870.145 8572.7344 C
+-7870.0718 8574.1299 -7869.8374 8575.9492 -7869.1318 8576.6553 C
+-7868.2134 8574.6963 -7868.2358 8573.0732 V
+-7867.0762 8572.7217 -7860.2817 8570.8447 -7857.4487 8574.3369 C
+-7858.4312 8571.8135 -7860.8262 8571.0186 -7863.2007 8570.9189 C
+-7862.667 8570.6318 -7862.2041 8570.3047 -7861.8257 8569.9502 C
+-7860.041 8569.7861 -7857.7104 8568.5771 Y
+-7855.9814 8567.8857 -7856.5015 8564.4307 Y
+-7857.1919 8562.7021 -7854.5991 8563.3936 Y
+-7852.7002 8563.9111 -7851.835 8562.1836 Y
+-7852.7002 8563.3936 -7853.3906 8562.5303 Y
+f-7847.9082 8596.9521 m
+-7848.6074 8597.4893 -7849.7632 8597.0938 Y
+-7852.2446 8598.3135 -7851.5327 8595.8467 Y
+-7850.769 8593.1104 -7851.564 8589.1221 Y
+-7851.541 8585.6445 -7853.4014 8586.5596 Y
+-7854.0342 8586.5557 L
+-7854.3198 8584.6123 -7854.7046 8582.7549 -7855.0898 8581.1699 C
+-7853.7129 8583.4199 -7852.2778 8584.0635 Y
+-7850.5913 8585.082 -7848.9878 8580.5791 Y
+-7849.4214 8579.4502 -7848.2417 8577.7021 Y
+-7849.4937 8577.8125 -7850.7246 8580.876 Y
+-7851.4976 8585.6152 -7852.3511 8582.4268 Y
+-7853.5776 8580.1904 -7854.769 8579.0098 -7855.814 8578.4229 C
+-7856.2026 8577.0635 -7856.4858 8576.2393 Y
+-7856.7002 8575.4727 -7857.0337 8574.8486 -7857.4487 8574.3369 C
+-7857.3799 8574.5127 -7857.3174 8574.6982 -7857.2632 8574.8916 C
+-7851.3022 8592.2588 -7856.4858 8598.9971 V
+-7863.2246 8608.5869 -7867.3721 8608.5869 V
+-7870.9663 8608.6514 L
+-7875.1138 8608.6514 -7881.853 8599.0615 Y
+-7881.9038 8598.9961 -7881.9463 8598.9219 -7881.9961 8598.8516 C
+-7881.7378 8599.4141 -7881.437 8599.9404 -7881.0752 8600.4092 C
+-7874.3359 8610 -7870.189 8610 V
+-7866.5942 8609.9346 L
+-7862.4482 8609.9346 -7855.709 8600.3447 Y
+-7853.5801 8597.5771 -7853.3306 8593.0176 -7853.7769 8588.6055 C
+-7853.6553 8588.5752 -7853.5698 8588.5684 Y
+-7852.0112 8586.6475 -7852.7598 8594.5244 Y
+-7853.4746 8597.3789 -7851.7026 8598.2402 Y
+-7850.9351 8599.0186 -7847.9946 8598.3428 Y
+-7847.9136 8597.7256 -7846.4434 8597.5811 Y
+-7845.7446 8597.0449 -7843.8921 8597.2881 Y
+-7845.5024 8595.5771 -7847.9082 8596.9521 Y
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 2)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894 8610 m
+-7829.187 8610 L
+-7829.187 8545.9023 L
+-7894 8545.9023 L
+-7894 8610 L
+nu0 O
+0 g
+-7859.6978 8568.4297 m
+-7861.6094 8545.9023 L
+-7863.5215 8568.4297 L
+-7862.9033 8568.3066 -7862.2642 8568.2402 -7861.6094 8568.2402 c
+-7860.9551 8568.2402 -7860.3159 8568.3066 -7859.6978 8568.4297 C
+f-7871.2402 8576.3975 m
+-7894 8578.3301 L
+-7871.1138 8580.2734 L
+-7871.2856 8579.5469 -7871.3848 8578.793 -7871.3848 8578.0156 c
+-7871.3848 8577.4629 -7871.3281 8576.9248 -7871.2402 8576.3975 C
+f-7866.519 8569.5723 m
+-7880.1626 8560.8047 L
+-7870.2153 8573.377 L
+-7869.3574 8571.791 -7868.0718 8570.4766 -7866.519 8569.5723 C
+f-7863.481 8587.6074 m
+-7861.5786 8610 L
+-7859.6768 8587.5967 L
+-7860.3018 8587.7227 -7860.9473 8587.791 -7861.6094 8587.791 c
+-7862.25 8587.791 -7862.873 8587.7246 -7863.481 8587.6074 C
+f-7851.9609 8579.5068 m
+-7829.187 8577.5732 L
+-7852.083 8575.6289 L
+-7852.083 8575.8506 L
+-7851.9258 8576.5488 -7851.834 8577.2695 -7851.834 8578.0156 c
+-7851.834 8578.5234 -7851.8848 8579.0195 -7851.9609 8579.5068 C
+f-7870.1138 8582.8262 m
+-7880.1641 8595.5293 L
+-7866.2778 8586.6055 L
+-7867.8823 8585.7305 -7869.2114 8584.416 -7870.1138 8582.8262 C
+f-7852.9961 8573.3945 m
+-7842.875 8560.6055 L
+-7856.7666 8569.5313 L
+-7855.1768 8570.4414 -7853.8633 8571.7793 -7852.9961 8573.3945 C
+f-7856.6895 8586.4512 m
+-7842.873 8595.3281 L
+-7852.9658 8582.5732 L
+-7853.8198 8584.1895 -7855.1152 8585.5313 -7856.6895 8586.4512 C
+f-7852.8887 8582.6133 m
+-7852.3862 8581.6641 -7852.043 8580.6211 -7851.875 8579.5195 c
+-7851.7993 8579.0293 -7851.748 8578.5273 -7851.748 8578.0156 c
+-7851.748 8577.2637 -7851.8398 8576.5352 -7851.998 8575.8311 c
+-7852.1958 8574.957 -7852.5049 8574.124 -7852.918 8573.3545 c
+-7853.7954 8571.7246 -7855.1191 8570.374 -7856.7241 8569.4561 c
+-7857.6294 8568.9375 -7858.6226 8568.5537 -7859.6802 8568.3457 c
+-7860.3047 8568.2207 -7860.9497 8568.1523 -7861.6094 8568.1523 c
+-7862.2695 8568.1523 -7862.915 8568.2207 -7863.5391 8568.3457 c
+-7864.623 8568.5605 -7865.6382 8568.957 -7866.5625 8569.4961 c
+-7868.1313 8570.4102 -7869.4282 8571.7363 -7870.291 8573.335 c
+-7870.7969 8574.2695 -7871.145 8575.2969 -7871.3262 8576.3828 c
+-7871.415 8576.916 -7871.4727 8577.459 -7871.4727 8578.0156 c
+-7871.4727 8578.8008 -7871.3711 8579.5605 -7871.1978 8580.293 c
+-7870.981 8581.207 -7870.6406 8582.0732 -7870.187 8582.8701 c
+-7869.2793 8584.4727 -7867.939 8585.8008 -7866.3174 8586.6826 c
+-7865.4487 8587.1553 -7864.5 8587.498 -7863.4961 8587.6934 c
+-7862.8848 8587.8115 -7862.2554 8587.8779 -7861.6094 8587.8779 c
+-7860.9414 8587.8779 -7860.29 8587.8086 -7859.6602 8587.6826 c
+-7858.5786 8587.4668 -7857.5664 8587.0654 -7856.6455 8586.5273 c
+-7855.0566 8585.5977 -7853.751 8584.2441 -7852.8887 8582.6133 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 3)
+0 A
+u1 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7884.75 8611 m
+-7884.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7884.75 8611 L
+nuu0 Ap
+0 O
+1 g
+-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 c
+-7887.897 8590.9736 -7891.0898 8589 -7894.75 8589 C
+-7894.75 8609 L
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 c
+-7891.9121 8608.7754 -7890.1807 8608.0645 -7888.7441 8606.9824 c
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 c
+f0 R
+0 G
+1 J 1 j 0.5 w-7894.75 8589.3174 m
+-7891.7207 8590.2744 -7888.8926 8591.9326 -7886.1543 8593.9072 C
+S-7894.75 8594.9512 m
+-7891.5991 8597.3564 -7888.543 8600.0869 -7885.4058 8602.5361 C
+S-7888.7441 8606.9824 m
+-7890.8105 8605.8916 -7892.7993 8604.5342 -7894.75 8603.043 C
+S-7893.8018 8608.9521 m
+-7894.1191 8608.8682 -7894.4375 8608.7852 -7894.75 8608.6865 C
+S-7888.7441 8606.9824 m
+-7890.1807 8608.0645 -7891.9121 8608.7744 -7893.8018 8608.9521 C
+S-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 C
+S-7894.75 8609 m
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 C
+S-7888.7441 8606.9824 m
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 C
+S-7886.1543 8593.9072 m
+-7887.8975 8590.9736 -7891.0898 8589 -7894.75 8589 C
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 34)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894.0254 8610.0264 m
+-7838.0542 8610.0264 L
+-7838.0542 8548.5342 L
+-7894.0254 8548.5342 L
+-7894.0254 8610.0264 L
+nuu0 O
+0.0745 0.9 0.9019 0.18 k
+0 R
+0 0 0 1 K
+1 J 1 j 0.0518 w-7867.5991 8586.7217 m
+-7867.3594 8597.5215 -7872.8794 8607.8398 v
+-7872.4009 8610 -7870.959 8610 v
+-7871.2002 8606.6406 -7870.2393 8606.1611 v
+-7865.9199 8594.1602 -7866.6382 8586.2402 v
+-7867.5991 8586.7217 l
+b-7867.5991 8586.7217 m
+-7869.2793 8592 -7881.0391 8593.2012 v
+-7885.3594 8593.6807 -7885.5991 8595.1211 v
+-7879.1206 8585.5195 -7878.1602 8585.7607 v
+-7891.3594 8580.001 -7894 8574.7197 v
+-7888.959 8577.6006 -7885.5991 8575.4404 v
+-7877.6802 8575.2012 -7872.6406 8577.3613 v
+-7868.8008 8579.2813 -7876.7202 8563.2012 v
+-7872.8794 8574.9609 -7869.2793 8548.5605 v
+-7868.3198 8553.8408 -7866.8799 8555.2813 v
+-7860.8799 8562.9609 -7861.8398 8565.1211 v
+-7862.3198 8568.9609 -7857.7598 8562.7207 v
+-7858 8572.3213 -7860.4009 8575.6807 v
+-7862.5591 8579.2813 -7856.5591 8577.1211 v
+-7850.5591 8575.2012 -7845.2793 8576.8809 v
+-7839.7598 8578.3203 -7838.0801 8575.4404 v
+-7849.8398 8587.9209 -7855.5991 8587.6807 v
+-7853.9194 8591.2813 l
+-7851.519 8596.0811 -7852 8597.2813 v
+-7867.2681 8587.8828 -7867.5991 8586.7217 v
+b-7867.5991 8586.7217 m
+-7864.959 8568.2402 -7867.5991 8560.5605 v
+-7869.998 8550.001 -7869.2793 8548.5605 v
+S-7866.1602 8575.4404 m
+-7860.1602 8570.6406 -7858.959 8565.3604 v
+S-7866.1602 8574.7197 m
+-7875.0391 8567.041 -7876.7202 8563.2012 v
+S-7838.0801 8575.4404 m
+-7839.2793 8577.6006 -7867.3594 8585.7607 y
+-7872.4009 8580.2422 -7883.9199 8577.8408 v
+-7891.5986 8576.8809 -7894 8574.7197 v
+S-7884.6382 8593.6807 m
+-7873.1191 8584.5615 -7867.3594 8585.7607 y
+-7853.1992 8592 -7852 8597.2813 v
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 36)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7893.8496 8609.9961 m
+-7843.96 8609.9961 L
+-7843.96 8558.9258 L
+-7893.8496 8558.9258 L
+-7893.8496 8609.9961 L
+nu0 O
+0.025 0.1 0.475 0 k
+-7872.1504 8577.9043 m
+-7874.4766 8576.8125 -7876.6914 8576.4434 -7878.373 8576.9238 c
+-7879.0518 8577.1172 -7879.645 8577.4473 -7880.123 8577.9238 c
+-7880.6006 8578.4023 -7880.9297 8578.9951 -7881.123 8579.6729 c
+-7882.0088 8582.7715 -7880.0103 8587.6777 -7875.9233 8591.7666 c
+-7871.834 8595.8535 -7866.9297 8597.8516 -7863.8286 8596.9668 c
+-7863.1519 8596.7715 -7862.5586 8596.4424 -7862.0806 8595.9658 c
+-7861.603 8595.4883 -7861.2754 8594.8955 -7861.082 8594.2168 c
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.582 8585.21 -7864.791 8583.6133 -7866.2793 8582.123 c
+-7868.1504 8580.2539 -7870.1914 8578.8242 -7872.1504 8577.9043 c
+fu0.0035 0.014 0.0665 0 k
+-7871.2183 8576.9727 m
+-7873.8306 8576.0215 -7876.3975 8575.9688 -7878.373 8576.9238 C
+-7876.6914 8576.4434 -7874.4766 8576.8125 -7872.1504 8577.9043 c
+-7871.6191 8578.1543 -7871.0806 8578.4434 -7870.543 8578.7676 C
+-7868.8984 8578.0537 L
+-7869.667 8577.6172 -7870.4434 8577.2539 -7871.2183 8576.9727 c
+f0.015 0.06 0.285 0 k
+-7868.8984 8578.0537 m
+-7870.543 8578.7676 L
+-7869.0962 8579.6348 -7867.6426 8580.7607 -7866.2793 8582.123 c
+-7866.1538 8582.25 -7866.0327 8582.3779 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7866.3706 8579.7236 -7867.6191 8578.7813 -7868.8984 8578.0537 C
+fUu0.039 0.156 0.741 0 k
+-7859.687 8565.4043 m
+-7859.9746 8565.6914 -7871.2183 8576.9727 Y
+-7870.4434 8577.2539 -7869.667 8577.6172 -7868.8984 8578.0537 C
+-7855.4146 8564.5703 L
+-7857.061 8564.0996 -7858.6406 8564.3555 -7859.687 8565.4043 c
+f0.025 0.1 0.475 0 k
+-7855.4146 8564.5703 m
+-7868.8984 8578.0537 L
+-7867.584 8578.8027 -7866.2969 8579.7754 -7865.1143 8580.957 c
+-7865.084 8580.9863 -7865.0586 8581.0156 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7851.5264 8567.1328 -7851.7202 8566.9141 -7851.9302 8566.7012 c
+-7853.0103 8565.623 -7854.2305 8564.9082 -7855.4146 8564.5703 C
+fUu0.0115 0.046 0.2185 0 k
+-7845.9346 8574.3926 m
+-7843.5337 8571.9893 -7843.335 8568.0898 -7845.1382 8564.6973 C
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f0.015 0.06 0.285 0 k
+-7853.5337 8559.5957 m
+-7852.582 8558.9258 L
+-7855.2046 8558.3516 -7857.8306 8558.9141 -7859.6206 8560.7061 c
+-7858.1719 8559.2578 -7855.9082 8558.9307 -7853.5337 8559.5957 C
+f0.0295 0.118 0.5605 0 k
+-7853.5337 8559.5957 m
+-7855.9082 8558.9307 -7858.1719 8559.2578 -7859.6206 8560.7061 c
+-7861.019 8562.1055 -7861.3706 8564.2637 -7860.7954 8566.5469 C
+-7858.8672 8563.5449 -7855.4082 8564.5537 V
+-7853.585 8559.6309 L
+-7853.5337 8559.5957 L
+f*u
+1 D
+0.048 0.192 0.912 0 k
+-7845.9346 8574.3926 m
+-7847.2817 8575.7383 -7849.332 8576.1133 -7851.5234 8575.627 C
+-7861.6714 8585.7734 L
+-7861.7695 8585.5684 -7861.7695 8585.5684 -7861.6714 8585.7734 c
+-7860.2246 8588.8145 -7859.9702 8591.916 -7861.082 8594.2168 C
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.5054 8585.3438 -7864.5918 8583.8848 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7865.1816 8580.8945 -7865.1465 8580.9238 -7865.1143 8580.957 c
+-7865.084 8580.9883 -7865.0566 8581.0176 -7865.0273 8581.0469 c
+-7865.0278 8581.0469 -7865.0278 8581.0469 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f*U
+0 D
+0.0215 0.086 0.4085 0 k
+-7852.582 8558.9258 m
+-7853.5337 8559.5957 L
+-7851.6846 8560.1113 -7849.7656 8561.2285 -7848.1138 8562.8828 c
+-7847.4063 8563.5889 -7846.7998 8564.3418 -7846.2954 8565.1182 C
+-7845.1382 8564.6973 L
+-7845.6553 8563.7246 -7846.3374 8562.793 -7847.1802 8561.9512 c
+-7848.7695 8560.3594 -7850.6758 8559.3428 -7852.582 8558.9258 C
+f0.0205 0.082 0.3895 0 k
+-7846.2954 8565.1182 m
+-7846.7998 8564.3418 -7847.4063 8563.5889 -7848.1138 8562.8828 c
+-7849.7656 8561.2285 -7851.6846 8560.1113 -7853.5337 8559.5957 C
+-7853.585 8559.6309 L
+-7855.4082 8564.5537 L
+-7854.2114 8564.9219 -7852.9878 8565.6436 -7851.9302 8566.7012 c
+-7851.7202 8566.9141 -7851.5264 8567.1328 -7851.3408 8567.3574 C
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+fUu0.445 0.356 0.267 0 k
+-7893.8496 8609.9961 m
+-7871.957 8586.9688 L
+-7872.2007 8586.6494 -7872.5752 8586.6133 -7872.8887 8586.6592 C
+-7877.1802 8591.2891 -7888.3145 8603.4561 -7892.7266 8608.2793 C
+-7893.5649 8609.3516 -7894 8609.9932 -7893.8496 8609.9961 C
+f0.15 0.12 0.09 0 k
+-7893.834 8609.9961 m
+-7892.6606 8609.7031 -7871.6934 8588.0029 Y
+-7871.6934 8587.502 -7871.7993 8587.1758 -7871.957 8586.9688 C
+-7893.8496 8609.9961 L
+-7893.8442 8609.9961 -7893.8418 8610 -7893.834 8609.9961 c
+f0.2 0.16 0.12 0 k
+-7892.7266 8608.2793 m
+-7888.3145 8603.4561 -7877.1802 8591.2891 -7872.8887 8586.6592 C
+-7873.2002 8586.7041 -7873.4526 8586.8301 Y
+-7874.603 8587.1328 -7888.5742 8602.9619 -7892.7266 8608.2793 C
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 37)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7892.9502 8609.2324 m
+-7843.0391 8609.2324 L
+-7843.0391 8545.1152 L
+-7892.9502 8545.1152 L
+-7892.9502 8609.2324 L
+nu0 O
+0 0 0 1 k
+0 R
+0 0 0 1 K
+0 w-7843.2358 8545.1152 m
+-7843.6064 8545.248 -7843.9858 8545.2832 -7844.3833 8545.2031 c
+-7844.4863 8545.168 l
+-7844.5254 8545.1602 -7844.5703 8545.1787 -7844.6025 8545.1992 c
+-7844.9434 8545.3926 l
+-7848.7129 8547.2959 -7852.0962 8549.8965 -7854.5 8553.4473 c
+-7855.9634 8555.5918 -7857.123 8557.8789 -7858.7993 8559.8564 c
+-7859.1729 8560.209 -7859.1758 8560.7725 -7858.834 8561.1309 c
+-7858.4951 8561.501 -7857.918 8561.5078 -7857.561 8561.165 c
+-7857.4038 8561.21 l
+-7857.2642 8561.1289 -7857.0742 8561.0703 -7857.0234 8560.957 c
+-7855.853 8558.2031 -7855.1895 8555.5137 -7853.4336 8553.1387 c
+-7851.1719 8550.0947 -7848.1777 8547.9941 -7845.0298 8546.0234 c
+-7844.3672 8545.6055 L
+-7844.4966 8545.6348 L
+-7843.7695 8545.6426 l
+-7843.791 8545.6113 -7843.8008 8545.5957 -7843.8223 8545.5645 C
+-7843.6064 8545.5234 -7843.377 8545.4746 -7843.1626 8545.4336 c
+-7843.0762 8545.4238 -7843.0186 8545.3389 -7843.0391 8545.2383 c
+-7843.0503 8545.1523 -7843.1382 8545.1084 -7843.2358 8545.1152 c
+-7843.2358 8545.1152 l
+b-7859.2222 8558.9951 m
+-7859.5742 8558.8066 -7859.9658 8558.6719 -7860.248 8558.3887 c
+-7866.4521 8552.1719 -7876.6802 8551.2734 -7884.0488 8557.6855 C
+-7884.1582 8557.7813 -7884.1582 8557.957 -7884.063 8558.0645 C
+-7881.0527 8556.9434 -7872.8838 8558.375 -7869.3223 8561.4121 C
+-7869.2534 8561.4668 -7869.1465 8561.4531 -7869.1055 8561.3711 C
+-7869.0503 8561.3047 -7869.0664 8561.1953 -7869.1328 8561.1563 C
+-7872.5625 8558.0859 -7877.0674 8556.29 -7881.6729 8556.748 C
+-7878.8535 8555.1855 -7875.6313 8554.4941 -7872.3984 8554.6885 c
+-7867.7144 8554.9717 -7863.4634 8557.1191 -7859.3711 8559.2793 c
+-7859.291 8559.3193 -7859.1978 8559.293 -7859.1553 8559.2109 C
+-7859.1016 8559.1309 -7859.1426 8559.0352 -7859.2222 8558.9951 c
+b-7868.647 8560.3359 m
+-7870.2266 8564.3613 -7872.3911 8568.3203 -7875.8018 8571.0762 c
+-7875.9648 8571.2119 -7875.9946 8571.4492 -7875.8711 8571.6055 c
+-7875.7344 8571.7676 -7875.5049 8571.7793 -7875.3481 8571.6563 c
+-7871.123 8569.5967 -7868.1904 8565.1309 -7868.1626 8560.4014 c
+-7868.1626 8560.4014 l
+-7868.1328 8560.2676 -7868.2354 8560.1348 -7868.3633 8560.1221 c
+-7868.5039 8560.1055 -7868.6318 8560.1973 -7868.647 8560.3359 c
+-7868.647 8560.3359 l
+b-7862.9414 8565.0176 m
+-7863.042 8565.1816 -7863.1152 8565.3838 -7863.2617 8565.4824 c
+-7866.0806 8567.3906 -7868.9785 8568.6309 -7871.8848 8570.1328 c
+-7872.0503 8570.209 -7872.1118 8570.418 -7872.0313 8570.5703 c
+-7871.9512 8570.7227 -7871.7559 8570.7793 -7871.5898 8570.7041 c
+-7868.439 8569.3232 -7864.313 8568.5 -7862.6729 8565.1797 c
+-7862.6289 8565.1113 -7862.6455 8565.0146 -7862.7266 8564.9648 c
+-7862.7959 8564.9199 -7862.897 8564.9492 -7862.9414 8565.0176 c
+-7862.9414 8565.0176 l
+b-7862.6602 8565.918 m
+-7862.4438 8566.4297 -7862.1431 8566.8896 -7862.0503 8567.4355 c
+-7861.2183 8572.2773 -7861.1152 8577.042 -7862.248 8581.6875 c
+-7862.248 8581.6875 l
+-7862.3418 8581.9531 -7862.2114 8582.2441 -7861.9438 8582.3389 c
+-7861.6777 8582.4336 -7861.3882 8582.3125 -7861.2935 8582.0479 c
+-7859.293 8576.8115 -7859.897 8570.7373 -7862.3711 8565.7832 c
+-7862.4063 8565.7002 -7862.498 8565.6689 -7862.582 8565.6914 c
+-7862.6641 8565.7275 -7862.6978 8565.835 -7862.6602 8565.918 c
+-7862.6602 8565.918 l
+b-7861.5352 8581.5938 m
+-7858.8984 8579.2275 -7856.6816 8576.252 -7855.853 8572.7363 c
+-7855.853 8572.7363 l
+-7855.7246 8572.1816 -7856.0742 8571.623 -7856.6416 8571.4902 c
+-7857.1992 8571.375 -7857.7578 8571.7246 -7857.8862 8572.2793 c
+-7858.5649 8575.5313 -7859.8711 8578.6729 -7861.7954 8581.3867 c
+-7861.7954 8581.3867 l
+-7861.8462 8581.4551 -7861.834 8581.5576 -7861.7695 8581.6201 c
+-7861.6992 8581.6699 -7861.5977 8581.6582 -7861.5352 8581.5938 c
+-7861.5352 8581.5938 l
+b-7846.3711 8574.1826 m
+-7847.7114 8569.8301 -7850.2598 8566.0693 -7853.689 8563.1533 C
+-7853.729 8563.0723 -7853.8242 8563.0322 -7853.9038 8563.0859 C
+-7853.9863 8563.127 -7854.0122 8563.2207 -7853.9722 8563.3018 C
+-7853.957 8563.7891 -7853.7144 8564.2334 -7853.4458 8564.5313 c
+-7848.4063 8570.1621 -7844.9902 8578.7197 -7847.3433 8585.9551 C
+-7847.0762 8580.4512 -7848.7241 8574.3008 -7852.1362 8569.6738 c
+-7853.1606 8568.2695 -7854.7422 8568.1211 -7856.3081 8568.2031 C
+-7856.4023 8568.1895 -7856.4834 8568.2432 -7856.4961 8568.3369 c
+-7856.5098 8568.4189 -7856.4551 8568.5137 -7856.3623 8568.5254 C
+-7853.1479 8569.7695 -7851.4878 8573.2246 -7850.084 8576.1943 c
+-7848.415 8579.7441 -7847.7017 8583.6387 -7848.0054 8587.5 C
+-7848.0454 8587.6777 -7848.1138 8589.3975 -7847.9775 8589.4102 C
+-7847.8306 8589.4395 -7847.709 8589.3438 -7847.6802 8589.1943 C
+-7847.645 8589.0449 -7844.6426 8579.7988 -7846.3711 8574.1826 c
+b-7854.4863 8561.4912 m
+-7853.3945 8557.6211 -7851.1094 8554.251 -7848.4824 8551.2383 c
+-7848.3306 8551.1045 -7848.3145 8550.8867 -7848.4502 8550.7354 c
+-7848.5752 8550.6006 -7848.8047 8550.582 -7848.957 8550.7178 c
+-7852.3306 8553.332 -7853.4487 8557.541 -7854.7954 8561.375 c
+-7854.7954 8561.375 l
+-7854.8262 8561.4648 -7854.7754 8561.5586 -7854.6982 8561.5869 c
+-7854.6094 8561.6191 -7854.5166 8561.5684 -7854.4863 8561.4912 c
+-7854.4863 8561.4912 l
+b-7848.5313 8586.1094 m
+-7848.5991 8586.0566 -7848.707 8586.083 -7848.748 8586.1504 C
+-7848.9634 8586.4746 -7850.6914 8588.5195 -7851.3926 8589.1406 c
+-7856.1719 8593.3945 -7859.5137 8597.9609 -7867.5391 8601.7227 c
+-7874.4512 8604.9639 -7877.1113 8607.5957 -7884.3862 8605.8262 c
+-7887.687 8605.0293 -7889.0313 8604.5313 -7890.4351 8599.4551 C
+-7891.9473 8593.2988 -7890.8672 8595.7832 -7891.084 8588.4385 c
+-7891.2222 8583.6973 -7894 8572.4551 -7881.5254 8558.2598 C
+-7881.4199 8558.1484 -7881.4336 8557.9961 -7881.5337 8557.9072 C
+-7881.6328 8557.8027 -7881.7959 8557.8164 -7881.8862 8557.916 C
+-7887.5786 8562.7168 -7891.0234 8569.6582 -7892.3145 8576.9424 c
+-7893.2871 8582.4668 -7892.9199 8587.25 -7892.666 8593.6367 c
+-7892.5688 8596.0938 -7893.6855 8603.0723 -7888.9102 8607.0625 c
+-7885.3926 8610 -7880.3911 8609.5469 -7876.3545 8608.1563 c
+-7870.6992 8606.2119 -7865.9727 8603.1465 -7860.8711 8599.6094 c
+-7857.2656 8597.125 -7849.2881 8587.2852 -7848.4785 8586.3262 C
+-7848.4351 8586.2588 -7848.4502 8586.1504 -7848.5313 8586.1094 C
+b-7883.0503 8573.3057 m
+-7882.168 8572.5029 -7881.7017 8573.8457 -7881.4297 8574.6016 c
+-7881.1626 8575.3574 -7880.189 8575.25 -7880.5127 8575.5732 c
+-7880.8369 8575.8975 -7880.8369 8575.9521 -7881.3232 8575.5195 c
+-7881.8086 8575.0879 -7881.8086 8575.7363 -7882.5649 8575.25 c
+-7883.3198 8574.7627 -7883.645 8573.8457 -7883.0503 8573.3057 c
+b-7875.6519 8577.9492 m
+-7875.3657 8577.5918 -7874.6802 8577.5723 -7874.4648 8577.8945 c
+-7874.25 8578.2197 -7873.3306 8578.2734 -7873.4937 8578.5967 c
+-7873.6543 8578.9219 -7873.6016 8579.1387 -7874.0874 8578.9219 c
+-7874.5737 8578.7051 -7874.4121 8579.2998 -7874.897 8579.084 c
+-7875.3833 8578.8672 -7875.8687 8578.2197 -7875.6519 8577.9492 c
+b-7867.6074 8583.0791 m
+-7867.1206 8582.7559 -7865.8794 8583.5117 -7866.4727 8583.5117 c
+-7867.0674 8583.5117 -7866.311 8584.2676 -7866.8521 8584.4834 c
+-7867.3906 8584.6992 -7867.2832 8584.4297 -7867.6074 8584.6445 c
+-7867.9297 8584.8613 -7868.3633 8585.2393 -7868.5239 8584.4297 c
+-7868.6855 8583.6191 -7868.3633 8583.6191 -7867.9849 8583.3496 c
+-7867.6074 8583.0791 -7867.6074 8583.0791 y
+b-7882.2402 8583.3496 m
+-7881.1074 8583.2422 -7881.8633 8583.998 -7881.269 8584.4834 c
+-7880.6738 8584.9697 -7879.918 8585.6172 -7880.729 8585.4004 c
+-7881.5391 8585.1855 -7882.9961 8585.6719 -7882.9434 8584.5381 c
+-7882.8887 8583.4033 -7882.6328 8583.3867 -7882.2402 8583.3496 c
+b-7876.5703 8591.6113 m
+-7876.1016 8591.3438 -7876.6802 8591.7197 -7876.0303 8591.6113 c
+-7875.3833 8591.5039 -7874.7886 8591.6113 -7875.2207 8591.8281 c
+-7875.6519 8592.0439 -7876.3008 8592.1523 -7876.4634 8591.9893 c
+-7876.625 8591.8281 -7876.9473 8591.8281 -7876.5703 8591.6113 c
+b-7867.0674 8591.1797 m
+-7867.4785 8590.1797 -7866.0962 8590.4238 -7865.4473 8590.7461 c
+-7864.7998 8591.0723 -7863.8262 8590.4775 -7864.4209 8590.9102 c
+-7865.0137 8591.3418 -7864.7998 8590.9102 -7865.3926 8591.2334 c
+-7865.9873 8591.5566 -7866.6895 8592.0977 -7867.0674 8591.1797 c
+b-7882.6738 8597.0664 m
+-7882.7222 8596.0752 -7881.8086 8596.957 -7881.269 8597.0117 c
+-7880.729 8597.0664 -7880.0801 8597.0664 -7880.2432 8597.2813 c
+-7880.4038 8597.498 -7880.459 8597.498 -7881.1626 8597.7129 c
+-7881.8633 8597.9297 -7882.6191 8598.1445 -7882.6738 8597.0664 c
+b-7883.1582 8591.6113 m
+-7884.0664 8591.9746 -7884.293 8591.8809 -7884.5625 8592.2051 c
+-7884.834 8592.5293 -7885.1558 8593.2314 -7885.5352 8592.0977 c
+-7885.9121 8590.9629 -7885.4282 8589.7764 -7885.0479 8589.9375 c
+-7884.6714 8590.0996 -7884.293 8590.7461 -7883.8618 8590.9629 c
+-7883.4297 8591.1797 -7882.6191 8591.3945 -7883.1582 8591.6113 c
+bUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 41)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894 8610 m
+-7813 8610 L
+-7813 8505 L
+-7894 8505 L
+-7894 8610 L
+nuuu0 O
+0 0 0 1 k
+-7875.8057 8522.4258 m
+-7876.0742 8520.6621 -7877.1602 8519.291 -7878.5239 8519.3965 c
+-7879.8862 8519.502 -7880.707 8521.0234 -7880.7432 8522.8066 c
+-7880.748 8523.0693 -7880.6743 8524.2441 -7880.6304 8524.4775 C
+-7880.6382 8524.582 -7880.6191 8524.6738 -7880.6104 8524.7803 c
+-7880.5142 8526.0254 -7879.3574 8527.3604 -7877.9414 8527.25 c
+-7876.5249 8527.1406 -7875.4897 8525.8613 -7875.6367 8524.4727 c
+-7875.644 8524.4072 -7875.6958 8523.626 -7875.707 8523.5625 C
+-7875.6816 8523.2852 -7875.7598 8522.7256 -7875.8057 8522.4258 c
+f-7886.2646 8531.7334 m
+-7886.9946 8539.916 -7881.5015 8539.1191 v
+-7878.3682 8538.0186 -7879.4414 8535.1211 v
+-7879.6426 8533.752 -7881.7847 8532.498 v
+-7882.146 8532.25 -7882.7632 8531.1016 v
+-7883.1294 8529.5977 -7884.5186 8529.2979 v
+-7886.0762 8529.251 -7886.2646 8531.7334 v
+f-7860.7646 8540.4971 m
+F-7860.0762 8538.3408 m
+-7860.7847 8537.1934 -7863.8848 8537.6279 Y
+-7864.811 8537.6885 -7865.3799 8537.1113 Y
+-7867.8394 8533.0918 -7871.0386 8533.8857 -7871.4082 8533.9932 C
+-7871.4097 8533.9863 L
+-7874.999 8534.6045 -7875.2666 8539.6035 V
+-7875.4912 8540.3828 -7876.335 8540.7695 V
+-7879.2695 8541.8613 -7879.3481 8543.208 V
+-7879.8999 8545.1152 -7877.6006 8545.7422 V
+-7875.6792 8546.2568 -7873.7886 8543.8945 V
+-7872.6113 8542.6797 -7869.5762 8541.9395 V
+-7869.5728 8541.9531 L
+-7866.3594 8541.0459 -7864.6392 8541.5889 Y
+-7861.8521 8542.7676 -7860.4063 8541.4014 Y
+-7858.6826 8539.7559 -7860.0762 8538.3408 Y
+f-7873.9834 8521.8789 m
+-7874.5854 8520.2002 -7874.2822 8518.4775 -7873.0327 8517.9229 c
+-7871.7842 8517.3672 -7870.3384 8518.3164 -7869.4585 8519.8672 c
+-7869.3286 8520.0957 -7868.8359 8521.165 -7868.7632 8521.3906 C
+-7868.7065 8521.4785 -7868.6792 8521.5684 -7868.6362 8521.667 c
+-7868.1289 8522.8086 -7868.5122 8524.5303 -7869.8105 8525.1074 c
+-7871.1089 8525.6855 -7872.6279 8525.0527 -7873.1582 8523.7617 c
+-7873.1831 8523.7002 -7873.5078 8522.9883 -7873.5298 8522.9268 C
+-7873.6831 8522.6963 -7873.8809 8522.166 -7873.9834 8521.8789 c
+f-7859.7129 8524.9316 m
+-7855.1802 8531.7822 -7860.3911 8533.6943 v
+-7863.6714 8534.2168 -7864.103 8531.1572 v
+-7864.5786 8529.8564 -7863.29 8527.7354 v
+-7863.0903 8527.3447 -7863.0938 8526.04 v
+-7863.4858 8524.5449 -7862.4082 8523.6182 v
+-7861.0591 8522.8359 -7859.7129 8524.9316 v
+fUu-7834.7358 8574.1074 m
+-7834.3687 8572.3623 -7834.9048 8570.6963 -7836.2183 8570.3164 c
+-7837.5322 8569.9375 -7838.8345 8571.0752 -7839.4937 8572.7324 c
+-7839.5903 8572.9775 -7839.9326 8574.1025 -7839.9746 8574.3369 C
+-7840.0176 8574.4326 -7840.0322 8574.5244 -7840.0625 8574.6279 c
+-7840.4087 8575.8271 -7839.7935 8577.4805 -7838.4282 8577.875 c
+-7837.063 8578.2695 -7835.645 8577.4365 -7835.2969 8576.085 c
+-7835.2793 8576.0205 -7835.0552 8575.2705 -7835.0425 8575.207 C
+-7834.9214 8574.9551 -7834.7983 8574.4053 -7834.7358 8574.1074 c
+f-7848.2705 8578.6172 m
+-7851.8242 8586.0244 -7846.3999 8587.2061 v
+-7843.0801 8587.2754 -7843.0688 8584.1846 v
+-7842.7778 8582.8311 -7844.3433 8580.9072 v
+-7844.5942 8580.5459 -7844.7695 8579.2539 v
+-7844.5854 8577.7188 -7845.7793 8576.9492 v
+-7847.2222 8576.3594 -7848.2705 8578.6172 v
+f-7827.4648 8595.7695 m
+F-7826.063 8593.9912 m
+-7826.3247 8592.6689 -7829.3799 8591.9883 Y
+-7830.27 8591.7197 -7830.5986 8590.9795 Y
+-7831.4922 8586.3535 -7834.7666 8585.9746 -7835.1494 8585.9453 C
+-7835.1494 8585.9395 L
+-7838.7271 8585.2588 -7840.731 8589.8467 V
+-7841.2153 8590.4961 -7842.1416 8590.5625 V
+-7845.272 8590.5557 -7845.8169 8591.7891 V
+-7847.0039 8593.3809 -7845.0713 8594.7764 V
+-7843.4526 8595.9316 -7840.853 8594.3818 V
+-7839.3242 8593.6582 -7836.2222 8594.0293 V
+-7836.2231 8594.042 L
+-7832.896 8594.3213 -7831.4766 8595.4326 Y
+-7829.2793 8597.5146 -7827.4463 8596.7432 Y
+-7825.2554 8595.8057 -7826.063 8593.9912 Y
+f-7832.8374 8574.2354 m
+-7832.813 8572.4512 -7831.9258 8570.9453 -7830.5601 8570.8633 c
+-7829.1943 8570.7803 -7828.1743 8572.1768 -7827.895 8573.9385 c
+-7827.854 8574.1973 -7827.7666 8575.3711 -7827.7778 8575.6094 C
+-7827.7559 8575.7109 -7827.7617 8575.8037 -7827.7559 8575.9121 c
+-7827.6807 8577.1592 -7828.644 8578.6367 -7830.0625 8578.7217 c
+-7831.4814 8578.8066 -7832.6826 8577.6826 -7832.7246 8576.2871 c
+-7832.7271 8576.2217 -7832.7822 8575.4404 -7832.7798 8575.375 C
+-7832.8433 8575.1045 -7832.8423 8574.54 -7832.8374 8574.2354 c
+f-7821.0186 8581.5625 m
+-7819.1777 8589.5684 -7824.7271 8589.5303 v
+-7827.9834 8588.8691 -7827.3154 8585.8516 v
+-7827.3032 8584.4668 -7825.353 8582.9326 v
+-7825.0278 8582.6377 -7824.5742 8581.415 v
+-7824.417 8579.876 -7823.083 8579.3877 v
+-7821.5454 8579.1279 -7821.0186 8581.5625 v
+fUU1 Ap
+-7894 8610 m
+-7894 8505 L
+-7813 8505 L
+-7813 8610 L
+-7894 8610 L
+nUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 42)
+0 A
+u0 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 45)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7895 8567.918 m
+-7895 8611 L
+-7808.2217 8611 L
+-7808.2217 8567.918 L
+-7895 8567.918 L
+nuu0 O
+0 0 0 1 k
+-7835.2217 8597.2363 m
+-7835.2217 8605.0742 L
+-7823.2217 8598.1445 L
+-7811.2217 8591.2168 L
+-7823.2217 8584.2891 L
+-7835.2217 8577.3613 L
+-7835.2217 8585.4824 L
+-7893.9351 8571.7168 L
+-7880.9878 8590.8027 L
+-7895 8611 L
+-7835.2217 8597.2363 L
+f0 1 1 0.1 k
+0 R
+0 0 0 1 K
+-7833.2217 8594.2363 m
+-7833.2217 8602.0742 L
+-7821.2217 8595.1445 L
+-7809.2217 8588.2168 L
+-7821.2217 8581.2891 L
+-7833.2217 8574.3613 L
+-7833.2217 8582.4824 L
+-7891.9351 8568.7168 L
+-7877.2754 8588.3594 L
+-7891.9351 8608 L
+-7833.2217 8594.2363 L
+bUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 5)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7736.3994 8611 m
+-7736.3994 8597.4199 L
+-7895 8597.4199 L
+-7895 8611 L
+-7736.3994 8611 L
+nuu0 O
+0.285 0.228 0.171 0 k
+-7751.0786 8609.4844 m
+-7751.043 8610.6895 L
+-7737.5103 8611.5176 -7736.8418 8610.2822 v
+-7736.7441 8610.1016 -7736.647 8609.7148 -7736.561 8609.1934 C
+-7738.584 8609.8242 -7748.291 8609.5713 -7751.0786 8609.4844 C
+f0.44 0.352 0.264 0 k
+-7751.4063 8598.0234 m
+-7751.3711 8599.2676 L
+-7748.4912 8599.0488 -7738.1914 8598.3164 -7736.543 8598.8652 C
+-7736.7031 8598.2188 -7736.9199 8597.7646 -7737.2046 8597.6152 c
+-7738.8306 8596.7656 -7751.4063 8598.0234 Y
+f0.145 0.116 0.087 0 k
+-7751.3711 8599.2676 m
+-7751.0786 8609.4844 L
+-7748.291 8609.5713 -7738.584 8609.8242 -7736.561 8609.1934 C
+-7736.1519 8606.7773 -7735.9258 8601.3604 -7736.543 8598.8652 C
+-7738.1914 8598.3164 -7748.4912 8599.0488 -7751.3711 8599.2676 C
+fUu0.155 0.124 0.093 0 k
+-7776.9375 8603.2734 m
+-7775.897 8603.6563 L
+-7757.0728 8599.1465 L
+-7757.481 8598.3145 L
+-7776.3633 8600.7246 L
+-7777.252 8601.0059 L
+-7777.6504 8600.8936 -7778.1934 8600.8242 V
+-7777.6094 8601.2373 -7777.1426 8602.1406 -7776.9375 8603.2734 C
+fu0.085 0.068 0.051 0 k
+-7781.7993 8607.666 m
+-7782.5977 8607.7217 -7779.749 8607.6641 Y
+-7780.3481 8607.0176 -7780.771 8605.8203 -7780.8105 8604.4375 c
+-7780.8169 8604.2246 -7780.8105 8604.0176 -7780.7993 8603.8135 C
+-7781.041 8603.707 -7781.0918 8603.7734 -7781.6289 8603.5645 C
+-7781 8607.6113 -7781.7993 8607.666 v
+f0.305 0.244 0.183 0 k
+-7780.3442 8600.8672 m
+-7780.5527 8600.8105 -7780.4937 8602.9307 Y
+-7779.4785 8603.7588 L
+-7777.8359 8602.9434 L
+-7776.9375 8603.2734 L
+-7777.1426 8602.1406 -7777.6094 8601.2373 -7778.1934 8600.8242 C
+-7778.6094 8600.7715 -7779.874 8600.7998 -7780.3442 8600.8672 C
+fU0.115 0.092 0.069 0 k
+-7776.9375 8603.2734 m
+-7777.8359 8602.9434 L
+-7779.4785 8603.7588 L
+-7780.4937 8602.9307 L
+-7780.793 8603.708 -7780.7993 8603.8135 V
+-7779.5137 8604.3789 -7778.1831 8604.7402 -7776.8398 8604.9258 C
+-7776.79 8604.7275 -7776.7842 8604.543 -7776.79 8604.3369 c
+-7776.7998 8603.9717 -7776.8218 8603.6182 -7776.9375 8603.2734 C
+f0.41 0.328 0.246 0 k
+-7757.4512 8599.3965 m
+-7759.377 8600.6426 -7768.3862 8606.0986 -7776.8398 8604.9258 C
+-7776.9038 8606.0928 -7777.248 8607.0908 -7777.75 8607.6631 C
+-7777.1895 8607.6621 L
+-7756.7402 8610.7559 L
+-7757.0366 8600.4258 L
+-7757.0728 8599.1465 L
+-7757.2046 8599.2373 -7757.4512 8599.3965 v
+f0.395 0.316 0.237 0 k
+-7780.8105 8604.4375 m
+-7780.771 8605.8203 -7780.3481 8607.0176 -7779.749 8607.6641 C
+-7777.6807 8607.6631 L
+-7777.1782 8607.0908 -7776.8218 8606.0713 -7776.8398 8604.9258 C
+-7778.1831 8604.7402 -7779.5137 8604.3789 -7780.7993 8603.8135 C
+-7780.8105 8604.0176 -7780.8169 8604.2246 -7780.8105 8604.4375 c
+fUu0 0 0 0.11 k
+-7751.2642 8598.2012 m
+-7750.2407 8598.0352 L
+-7751.2642 8598.2012 L
+-7751.2642 8598.2012 L
+f0 0 0 0.34 k
+-7757.481 8598.3145 m
+-7757.0728 8599.1465 L
+-7755.6714 8598.918 L
+-7754.5234 8598.7314 L
+-7752.6758 8598.4307 L
+-7751.2642 8598.2012 L
+-7750.2407 8598.0352 L
+-7750.2954 8597.7168 -7750.3672 8597.498 -7750.4648 8597.4199 C
+-7757.481 8598.3145 L
+f0 0 0 0.32 k
+-7755.8042 8603.207 m
+-7756.041 8610.8613 L
+-7750.7144 8611 L
+-7749.7266 8607.5146 -7750.1816 8603.1543 V
+-7755.8042 8603.207 L
+fU0.025 0.02 0.015 0 k
+-7749.3223 8600.3848 m
+-7746.373 8600.9199 -7743.2402 8601.1602 -7740.3159 8600.3613 c
+-7740.2856 8600.3496 -7740.2754 8600.3184 -7740.2871 8600.2969 c
+-7740.2881 8600.2656 -7740.3198 8600.2559 -7740.3418 8600.2559 c
+-7743.2422 8601.0645 -7746.375 8600.8242 -7749.3042 8600.2783 c
+-7749.3262 8600.2793 -7749.3574 8600.291 -7749.3672 8600.3223 c
+-7749.3662 8600.3438 -7749.355 8600.375 -7749.3223 8600.3848 c
+-7749.3223 8600.3848 l
+f-7747.8374 8599.3076 m
+-7747.7295 8599.3789 -7747.6313 8599.4941 -7747.5234 8599.502 c
+-7743.7886 8599.832 -7740.1631 8599.7813 -7736.4746 8599.6641 c
+-7736.4526 8599.6641 -7736.4209 8599.6426 -7736.4214 8599.6211 c
+-7736.4214 8599.5879 -7736.4551 8599.5684 -7736.4766 8599.5684 c
+-7739.3223 8599.6816 -7742.1401 8599.6992 -7745.0039 8599.5352 c
+-7745.9336 8599.4766 -7746.9082 8599.7402 -7747.7778 8599.2207 c
+-7747.7993 8599.2109 -7747.8306 8599.2109 -7747.8506 8599.2334 c
+-7747.8618 8599.2559 -7747.8594 8599.2871 -7747.8374 8599.3076 c
+-7747.8374 8599.3076 l
+f-7743.373 8601.3672 m
+-7741.5098 8602.6797 -7739.3022 8603.374 -7737.1001 8603.8867 c
+-7737.0679 8603.8965 -7737.0474 8603.8848 -7737.0366 8603.8535 c
+-7737.0273 8603.8203 -7737.0488 8603.8008 -7737.0703 8603.79 c
+-7739.2617 8603.2656 -7741.459 8602.6035 -7743.3105 8601.2803 c
+-7743.3433 8601.2598 -7743.375 8601.2715 -7743.3848 8601.293 c
+-7743.4058 8601.3145 -7743.3945 8601.3457 -7743.373 8601.3672 c
+-7743.373 8601.3672 l
+f-7748.9321 8608.0566 m
+-7746.7295 8608.5703 -7744.5298 8609.0303 -7742.2798 8609.2754 c
+-7742.2598 8609.2852 -7742.229 8609.2637 -7742.229 8609.2422 c
+-7742.2183 8609.209 -7742.2407 8609.1777 -7742.2729 8609.1787 c
+-7744.5122 8608.8809 -7746.7305 8608.5176 -7748.9126 8607.9502 c
+-7748.9351 8607.9512 -7748.9673 8607.9629 -7748.9766 8607.9941 c
+-7748.9751 8608.0156 -7748.9648 8608.0479 -7748.9321 8608.0566 c
+-7748.9321 8608.0566 l
+f-7748.439 8607.3604 m
+-7746.3457 8608.1973 -7744.1016 8607.9297 -7741.9023 8607.9629 c
+-7741.8706 8607.9609 -7741.8496 8607.9395 -7741.8506 8607.9082 c
+-7741.8521 8607.875 -7741.873 8607.8555 -7741.8945 8607.8555 c
+-7744.0928 8607.8438 -7746.3374 8608.0996 -7748.4209 8607.2529 c
+-7748.4434 8607.2539 -7748.4746 8607.2656 -7748.4834 8607.2969 c
+-7748.4834 8607.3184 -7748.4722 8607.3506 -7748.439 8607.3604 c
+-7748.439 8607.3604 l
+f-7747.707 8608.7051 m
+-7746.3833 8608.752 -7745.1504 8608.5469 -7743.8271 8608.209 c
+-7743.3594 8608.0996 -7742.9199 8608.2266 -7742.4609 8608.2129 c
+-7741.897 8608.1973 l
+-7741.874 8608.1963 -7741.8633 8608.1855 -7741.8535 8608.1738 c
+-7741.834 8608.1523 -7741.8442 8608.1211 -7741.8662 8608.0996 c
+-7742.0625 8607.9453 l
+-7742.0742 8607.9453 -7742.085 8607.9355 -7742.0962 8607.9355 c
+-7742.5 8607.9473 l
+-7743.9551 8608.1914 -7745.457 8608.6719 -7746.8926 8608.0742 c
+-7746.9258 8608.0645 -7746.957 8608.0859 -7746.9673 8608.1074 c
+-7746.9673 8608.1396 -7746.9551 8608.1602 -7746.9336 8608.1709 c
+-7745.647 8608.6992 -7744.1714 8608.4756 -7742.8818 8608.0547 c
+-7742.0918 8608.043 L
+-7742.124 8608.0332 L
+-7741.9282 8608.1875 L
+-7741.8984 8608.0898 L
+-7742.4639 8608.1064 l
+-7742.9321 8608.1406 -7743.3848 8607.9834 -7743.8398 8608.1035 c
+-7745.1543 8608.4609 -7746.3975 8608.625 -7747.71 8608.5986 c
+-7747.7422 8608.5996 -7747.7642 8608.6211 -7747.7617 8608.6533 c
+-7747.7617 8608.6855 -7747.7402 8608.7061 -7747.707 8608.7051 c
+-7747.707 8608.7051 l
+f-7748.5718 8609.0605 m
+-7745.8711 8610.2207 -7742.9023 8609.5703 -7740.1279 8609.1816 c
+-7739.7832 8609.2891 l
+-7739.7617 8609.2988 -7739.7417 8609.2871 -7739.7207 8609.2656 c
+-7739.71 8609.2441 -7739.7217 8609.2129 -7739.7422 8609.2021 c
+-7740.0801 8609.0098 l
+-7742.7754 8608.3926 -7745.5391 8608.7813 -7748.271 8608.7852 c
+-7748.3022 8608.7871 -7748.3232 8608.8086 -7748.3223 8608.8398 c
+-7748.3198 8608.8721 -7748.2983 8608.8926 -7748.2681 8608.8926 c
+-7745.6738 8608.9355 -7743.0303 8608.4434 -7740.4727 8609.0742 c
+-7739.7954 8609.2891 L
+-7739.7534 8609.1914 L
+-7740.1406 8609.0859 l
+-7742.9058 8609.4424 -7745.8418 8610.1348 -7748.5313 8608.9746 c
+-7748.5537 8608.9648 -7748.585 8608.9648 -7748.5962 8608.998 c
+-7748.6055 8609.0195 -7748.605 8609.0508 -7748.5718 8609.0605 c
+-7748.5718 8609.0605 l
+f-7745.6895 8602.3945 m
+-7744.3945 8602.9004 -7742.9834 8602.6465 -7741.6802 8602.3438 c
+-7741.647 8602.3418 -7741.6367 8602.3203 -7741.6382 8602.2891 c
+-7741.6504 8602.2568 -7741.6714 8602.2461 -7741.7031 8602.248 c
+-7742.998 8602.5303 -7744.377 8602.8154 -7745.6504 8602.2969 c
+-7745.6826 8602.2871 -7745.7144 8602.2988 -7745.7246 8602.3311 c
+-7745.7222 8602.3525 -7745.7114 8602.3848 -7745.6895 8602.3945 c
+-7745.6895 8602.3945 l
+f-7746.1401 8604.2207 m
+-7744.2266 8604.6895 -7742.3145 8605.1035 -7740.355 8605.3242 c
+-7740.3242 8605.334 -7740.3022 8605.3125 -7740.293 8605.2803 c
+-7740.2954 8605.2598 -7740.3159 8605.2285 -7740.3374 8605.2285 c
+-7742.2959 8605.0078 -7744.209 8604.582 -7746.1206 8604.1133 c
+-7746.1426 8604.1152 -7746.1738 8604.126 -7746.1831 8604.1582 c
+-7746.1831 8604.1797 -7746.1719 8604.2109 -7746.1401 8604.2207 c
+-7746.1401 8604.2207 l
+f-7746.9336 8606.6348 m
+-7744.499 8607.4609 -7741.8647 8607.0547 -7739.3457 8607.0879 c
+-7739.313 8607.0879 -7739.293 8607.0664 -7739.293 8607.0332 c
+-7739.2954 8607.0117 -7739.3159 8606.9922 -7739.3481 8606.9922 c
+-7741.8574 8606.916 -7744.481 8607.3848 -7746.8945 8606.5264 c
+-7746.9282 8606.5273 -7746.959 8606.5391 -7746.9688 8606.5605 c
+-7746.9678 8606.5918 -7746.9561 8606.624 -7746.9336 8606.6348 c
+-7746.9336 8606.6348 l
+f-7742.0542 8607.8496 m
+-7740.6582 8608.5449 -7739.0503 8608.4033 -7737.5342 8608.4668 c
+-7737.502 8608.4648 -7737.4824 8608.4434 -7737.4824 8608.4121 c
+-7737.4834 8608.3906 -7737.5054 8608.3594 -7737.5366 8608.3594 c
+-7739.0137 8608.2207 -7740.6489 8608.5234 -7742.0039 8607.7617 c
+-7742.0366 8607.7529 -7742.0679 8607.7637 -7742.0786 8607.7861 c
+-7742.0879 8607.8076 -7742.0767 8607.8398 -7742.0542 8607.8496 c
+-7742.0542 8607.8496 l
+f-7741.3418 8604.4248 m
+-7740.3926 8604.3975 -7739.4336 8604.3701 -7738.4839 8604.3428 c
+-7738.4526 8604.3418 -7738.4312 8604.3203 -7738.4336 8604.2881 c
+-7738.4336 8604.2559 -7738.4551 8604.2354 -7738.4878 8604.2363 c
+-7739.437 8604.2637 -7740.397 8604.291 -7741.3457 8604.3184 c
+-7741.377 8604.3184 -7741.3975 8604.3418 -7741.3975 8604.373 c
+-7741.397 8604.4043 -7741.374 8604.4258 -7741.3418 8604.4248 c
+-7741.3418 8604.4248 l
+f-7739.1592 8602.0361 m
+-7738.6895 8602.0645 -7738.209 8602.0723 -7737.7383 8602.0918 c
+-7737.7168 8602.0908 -7737.6855 8602.0684 -7737.6865 8602.0371 c
+-7737.687 8602.0039 -7737.71 8601.9844 -7737.7417 8601.9844 c
+-7738.2114 8601.9873 -7738.6816 8601.9375 -7739.1514 8601.9395 c
+-7739.1831 8601.9297 -7739.2031 8601.9512 -7739.2134 8601.9844 c
+-7739.2129 8602.0156 -7739.1914 8602.0371 -7739.1592 8602.0361 c
+-7739.1592 8602.0361 l
+f-7746.9702 8604.2344 m
+-7746.5688 8604.5107 -7746.125 8604.6797 -7745.645 8604.751 c
+-7745.6113 8604.7607 -7745.5918 8604.7383 -7745.5806 8604.7168 c
+-7745.5703 8604.6855 -7745.5928 8604.6543 -7745.6152 8604.6543 c
+-7746.0854 8604.5723 -7746.5176 8604.4023 -7746.9209 8604.1475 c
+-7746.9521 8604.1377 -7746.9849 8604.1387 -7746.9946 8604.1709 c
+-7747.0039 8604.1934 -7746.9922 8604.2246 -7746.9702 8604.2344 c
+-7746.9702 8604.2344 l
+f-7748.1904 8610.085 m
+-7745.7344 8610.5273 -7743.2983 8611.001 -7740.7993 8610.7266 c
+-7740.7778 8610.7266 -7740.7568 8610.7041 -7740.7578 8610.6719 c
+-7740.7578 8610.6406 -7740.7798 8610.6191 -7740.8022 8610.6191 c
+-7743.291 8610.873 -7745.7344 8610.4844 -7748.1719 8609.9775 c
+-7748.1934 8609.9785 -7748.2256 8609.9902 -7748.2344 8610.0215 c
+-7748.2344 8610.043 -7748.2222 8610.0752 -7748.1904 8610.085 c
+-7748.1904 8610.085 l
+f0.195 0.156 0.117 0 k
+-7748.166 8598.6445 m
+-7745.7969 8598.2676 -7743.4058 8598.3477 -7741.0298 8598.5898 c
+-7740.998 8598.5879 -7740.9766 8598.5664 -7740.9766 8598.5352 c
+-7740.9785 8598.5137 -7741 8598.4824 -7741.0215 8598.4824 c
+-7743.4082 8598.2422 -7745.791 8598.1602 -7748.1694 8598.5391 c
+-7748.2026 8598.5391 -7748.2222 8598.5605 -7748.2217 8598.5938 c
+-7748.2207 8598.625 -7748.1992 8598.6465 -7748.166 8598.6445 c
+-7748.166 8598.6445 l
+f0.335 0.268 0.201 0 k
+-7747.4351 8598.1113 m
+-7744.9282 8598.1152 -7742.4146 8598.2773 -7739.918 8597.8965 c
+-7739.8862 8597.8945 -7739.8647 8597.873 -7739.8662 8597.8418 c
+-7739.8672 8597.8086 -7739.8896 8597.7891 -7739.9209 8597.7891 c
+-7742.418 8598.1699 -7744.9297 8598.0293 -7747.4375 8598.0059 c
+-7747.46 8598.0059 -7747.481 8598.0273 -7747.4785 8598.0596 c
+-7747.4785 8598.0918 -7747.457 8598.1123 -7747.4351 8598.1113 c
+-7747.4351 8598.1113 l
+f0.205 0.164 0.123 0 k
+-7748.9766 8598.3262 m
+-7747.5039 8598.668 -7746.0078 8598.4023 -7744.5391 8598.2207 c
+-7744.5078 8598.2207 -7744.4873 8598.1973 -7744.499 8598.166 c
+-7744.5 8598.1348 -7744.5215 8598.1133 -7744.5537 8598.125 c
+-7746.0103 8598.2842 -7747.4961 8598.583 -7748.9473 8598.2188 c
+-7748.9785 8598.2207 -7749.0103 8598.2324 -7749.0098 8598.2637 c
+-7749.019 8598.2852 -7748.998 8598.3164 -7748.9766 8598.3262 c
+-7748.9766 8598.3262 l
+f-7742.3535 8597.7949 m
+-7741.1978 8597.9219 -7740.0273 8597.8145 -7738.8926 8597.5898 c
+-7738.8711 8597.5781 -7738.8506 8597.5566 -7738.8618 8597.5244 c
+-7738.8623 8597.5029 -7738.8945 8597.4824 -7738.916 8597.4941 c
+-7740.0503 8597.7402 -7741.1914 8597.7939 -7742.3462 8597.6885 c
+-7742.3794 8597.6895 -7742.3984 8597.7109 -7742.4087 8597.7324 c
+-7742.4082 8597.7646 -7742.3862 8597.7852 -7742.3535 8597.7949 c
+-7742.3535 8597.7949 l
+f0.335 0.268 0.201 0 k
+-7749.2681 8600.4473 m
+-7747.9214 8601.1885 -7746.3066 8600.5977 -7744.855 8600.6416 c
+-7744.8223 8600.6406 -7744.8022 8600.6191 -7744.8022 8600.5859 c
+-7744.8042 8600.5654 -7744.8262 8600.5449 -7744.8574 8600.5449 c
+-7746.2886 8600.4902 -7747.8823 8601.0801 -7749.2168 8600.3506 c
+-7749.2383 8600.3398 -7749.2695 8600.3516 -7749.291 8600.374 c
+-7749.3008 8600.3955 -7749.2886 8600.4277 -7749.2681 8600.4473 c
+-7749.2681 8600.4473 l
+f-7747.8945 8602.5645 m
+-7745.6719 8603.0449 -7743.3896 8602.6162 -7741.1504 8602.5625 c
+-7741.1177 8602.5615 -7741.0977 8602.5391 -7741.0977 8602.5078 c
+-7741.1001 8602.4863 -7741.1318 8602.4668 -7741.1519 8602.4668 c
+-7743.3833 8602.4775 -7745.6519 8602.9805 -7747.875 8602.457 c
+-7747.8975 8602.457 -7747.9287 8602.4688 -7747.9375 8602.502 c
+-7747.9375 8602.5225 -7747.9258 8602.5547 -7747.8945 8602.5645 c
+-7747.8945 8602.5645 l
+f-7742.0273 8599.1406 m
+-7740.3496 8599.9688 -7738.499 8600.502 -7736.603 8600.3613 c
+-7736.5718 8600.3613 -7736.5513 8600.3389 -7736.5527 8600.3066 c
+-7736.5527 8600.2754 -7736.5742 8600.2539 -7736.6074 8600.2559 c
+-7738.481 8600.416 -7740.3198 8599.8604 -7741.9873 8599.0547 c
+-7742.0078 8599.0449 -7742.041 8599.0449 -7742.0503 8599.0781 c
+-7742.061 8599.0996 -7742.061 8599.1309 -7742.0273 8599.1406 c
+-7742.0273 8599.1406 l
+fu0.5 0.85 1 0.45 k
+-7895 8605.9082 m
+-7895.0254 8606.4883 -7894.5664 8607.1875 -7893.167 8607.9902 C
+-7892.8521 8608.0029 -7891.3945 8608.0234 -7889.0889 8608.0488 C
+-7889.0889 8605.8223 L
+-7891.1382 8605.8457 -7893.1177 8605.8867 -7895 8605.9082 C
+f-7894.5088 8604.9688 m
+-7889.0889 8604.8447 L
+-7889.0889 8603.8145 L
+-7892.644 8603.959 L
+-7893.8145 8604.3301 -7894.5088 8604.9688 V
+f0.5 0.85 1 0.32 k
+-7889.0889 8604.8252 m
+-7894.4746 8604.9434 L
+-7894.7695 8605.2148 -7894.9849 8605.5566 -7895 8605.9277 C
+-7893.1177 8605.9063 -7891.1382 8605.8848 -7889.0889 8605.8613 C
+-7889.0889 8604.8252 L
+f0.5 0.85 1 0.45 k
+-7784.1504 8604.6172 m
+-7862.3584 8605.541 -7889.1079 8605.8418 V
+-7889.1079 8608.0488 L
+-7872.8145 8608.2324 -7813.9902 8608.707 Y
+-7779.749 8607.6641 L
+-7780.457 8604.5684 L
+-7784.1504 8604.6172 L
+f0.5 0.85 1 0.12 k
+-7889.1079 8603.8145 m
+-7889.1079 8604.8447 L
+-7780.4258 8603 L
+-7780.3833 8600.8633 L
+-7813.6553 8600.7129 L
+-7889.1079 8603.8145 L
+fu0.065 0.052 0.039 0 k
+-7757.0728 8599.1465 m
+-7757.0366 8600.4258 L
+-7757.2954 8599.1172 L
+-7775.897 8603.6563 L
+-7776.9375 8603.2734 L
+-7776.8794 8603.6055 -7776.8398 8603.957 -7776.8306 8604.3223 c
+-7776.8242 8604.5283 -7776.8281 8604.7285 -7776.8398 8604.9258 C
+-7768.3862 8606.0986 -7758.9634 8601.6719 -7757.0366 8600.4258 C
+-7756.7402 8610.7559 L
+-7756.041 8610.8613 L
+-7755.8042 8603.207 L
+-7750.1816 8603.1543 L
+-7750.0898 8601.0137 -7750.0718 8599.0215 -7750.2407 8598.0352 C
+-7757.0728 8599.1465 L
+f0.4 0.7 1 0 k
+-7780.457 8604.5879 m
+-7780.4258 8602.9805 L
+-7889.1079 8604.8252 L
+-7889.1079 8605.8613 L
+-7862.3584 8605.5605 -7780.457 8604.5879 Y
+fUU0.025 0.02 0.015 0 k
+-7744.7344 8607.0293 m
+-7744.7344 8607.0625 -7744.7129 8607.082 -7744.6802 8607.082 c
+-7741.6714 8607.1133 -7739.4214 8606.9453 -7736.415 8606.8594 C
+-7736.4087 8606.7656 L
+-7739.3262 8606.8701 -7741.7607 8607.0078 -7744.6841 8606.9746 C
+-7744.7168 8606.9766 -7744.7358 8606.998 -7744.7344 8607.0293 C
+f-7736.3994 8606.7656 m
+-7736.4082 8606.7441 L
+-7736.4087 8606.7656 L
+-7736.4063 8606.7656 -7736.4033 8606.7656 -7736.3994 8606.7656 C
+f-7740.4487 8605.4238 m
+-7741.4458 8605.292 -7742.3394 8605.7656 -7743.2114 8606.1973 C
+-7743.2441 8606.208 -7743.2534 8606.2402 -7743.2422 8606.2715 C
+-7743.2305 8606.293 -7743.1982 8606.3027 -7743.1777 8606.291 c
+-7742.3262 8605.8301 -7741.4312 8605.4199 -7740.4678 8605.5195 c
+-7739.1079 8605.6621 -7737.9038 8606.375 -7736.5254 8606.4531 C
+-7736.4463 8606.3594 L
+-7738.04 8606.2656 -7738.8647 8605.623 -7740.4487 8605.4238 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 50)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894 8610 m
+-7766.877 8610 L
+-7766.877 8562.415 L
+-7894 8562.415 L
+-7894 8610 L
+nu*u
+0 O
+0.9529 0.949 0.1961 0.0745 k
+-7867.793 8594.417 m
+-7867.8232 8594.2676 L
+-7869.9849 8588.3643 -7870.9438 8585.6377 -7871.2754 8584.2891 c
+-7871.3657 8584.2891 L
+-7871.6953 8585.6074 -7872.7754 8588.335 -7874.9673 8594.2676 c
+-7874.9966 8594.417 L
+-7867.793 8594.417 l
+f1 D
+-7878.1182 8602.9678 m
+-7879.6191 8606.5371 -7880.3994 8608.709 -7878.1182 8608.917 c
+-7878.1182 8609.9678 L
+-7880.6992 8609.9375 -7883.5806 8609.917 -7886.3418 8609.917 c
+-7890.0649 8609.917 -7892.5273 8609.9375 -7894 8609.9678 c
+-7894 8608.917 L
+-7892.1064 8608.709 -7891.0542 8606.5674 -7883.5513 8589.5029 c
+-7871.6953 8562.415 L
+-7869.8638 8562.415 L
+-7858.1582 8589.5029 L
+-7850.8047 8606.5078 -7849.7246 8608.709 -7847.8887 8608.917 c
+-7847.8887 8609.9678 L
+-7849.5142 8609.9375 -7851.916 8609.917 -7855.5767 8609.917 c
+-7858.5488 8609.917 -7861.6694 8609.9375 -7864.7026 8609.9678 c
+-7864.7026 8608.917 L
+-7862.481 8608.709 -7863.3218 8606.5078 -7864.7617 8602.9678 C
+-7878.1182 8602.9678 l
+f*U
+*u
+0 D
+-7823.0762 8578.0811 m
+-7823.0762 8574.4717 -7825.3535 8572.0947 -7829.1294 8572.0947 c
+-7830.2383 8572.0947 -7831.0767 8572.2158 -7831.5273 8572.2451 c
+-7831.5273 8584.5479 L
+-7830.8672 8584.6084 -7830.208 8584.6084 -7829.729 8584.6084 c
+-7828.2002 8584.6084 -7826.7026 8584.127 -7825.6841 8583.4053 c
+-7824.3945 8582.5332 -7823.0762 8580.7881 -7823.0762 8578.1416 C
+-7823.0762 8578.0811 l
+f1 D
+-7842.0806 8582.3926 m
+-7842.0806 8566.6445 -7842.0806 8564.4287 -7844.542 8564.2783 c
+-7844.542 8563.3184 L
+-7843.042 8563.2588 -7840.3174 8563.1992 -7837.5664 8563.1689 c
+-7835.6538 8563.1084 -7832.3945 8563.0186 -7830.1479 8562.9775 c
+-7826.582 8562.9775 -7823.585 8563.4258 -7821.0049 8564.2627 c
+-7816.353 8565.8477 -7811.9702 8569.8525 -7811.9702 8577.6602 c
+-7811.9702 8582.7432 -7814.4014 8586.3193 -7816.5034 8588.0605 c
+-7817.583 8589.0215 -7818.8135 8589.832 -7819.7744 8590.3125 c
+-7819.7744 8590.4629 L
+-7817.5234 8593.4912 -7815.6025 8596.0625 -7809.3906 8604.6426 c
+-7807.5 8607.0645 -7805.9102 8608.7383 -7804.7402 8608.9775 c
+-7804.7402 8610 L
+-7806.6602 8610 -7809 8609.8848 -7811.1294 8609.8848 c
+-7813.3511 8609.8848 -7814.8521 8610 -7816.4424 8610 c
+-7817.6729 8610 -7818.7241 8609.9404 -7819.5039 8609.2725 c
+-7823.0151 8603.8477 -7826.9121 8597.7559 -7830.1182 8592.7139 c
+-7830.5078 8592.7139 -7830.957 8592.7139 -7831.5273 8592.7139 c
+-7831.5273 8595.2852 L
+-7831.5273 8606.5264 -7831.437 8608.7686 -7829.1895 8608.9775 c
+-7829.1895 8609.9697 L
+-7830.6279 8609.9404 -7833.9194 8609.915 -7836.6992 8609.915 c
+-7839.9287 8609.915 -7842.8921 8609.9404 -7844.5122 8609.9697 c
+-7844.5122 8608.9775 L
+-7842.0518 8608.7686 -7842.0806 8606.5264 -7842.0806 8589.5918 C
+-7842.0806 8582.3926 l
+f*U
+*u
+0 D
+-7791.4561 8589.5928 m
+-7791.4561 8606.4941 -7791.4561 8608.6484 -7794.2832 8608.9775 C
+-7794.2832 8609.9697 l
+-7792.3887 8609.9404 -7789.0542 8609.915 -7785.7822 8609.915 c
+-7782.6294 8609.915 -7779.5688 8609.9404 -7777.2881 8609.9697 C
+-7777.2881 8608.9775 l
+-7780.2578 8608.9775 -7780.2881 8606.5244 -7780.2881 8589.5928 C
+-7780.2881 8572.1514 L
+-7772.8193 8572.1514 l
+-7769.999 8572.1514 -7768.5298 8572.96 -7767.8994 8575.2627 C
+-7766.9072 8575.2627 l
+-7766.9072 8570.4697 -7766.877 8566.415 -7766.877 8563.1709 c
+-7771.3486 8563.2012 -7776.748 8563.2314 -7782.0601 8563.2314 C
+-7789.7446 8563.2314 l
+-7794.5537 8563.2314 -7799.9966 8563.2012 -7804.9614 8563.1709 c
+-7804.9614 8566.3848 -7804.9326 8570.4697 -7804.9326 8575.2627 C
+-7803.9072 8575.2627 l
+-7803.3657 8573.1094 -7801.771 8572.1514 -7798.9438 8572.1514 C
+-7791.4561 8572.1514 l
+-7791.4561 8589.5928 L
+f*U
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 6)
+0 A
+u1 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7894.75 8587 m
+-7894.75 8611 L
+-7884.75 8611 L
+-7884.75 8587 L
+-7894.75 8587 L
+n0 Ap
+0 O
+1 g
+-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 c
+-7887.5879 8589.2256 -7889.3198 8589.9346 -7890.7559 8591.0176 c
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 c
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.2319 8602.5996 -7893.3457 8604.0918 c
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+-7884.75 8589 L
+f0 R
+0 G
+1 J 1 j 0.5 w-7884.75 8608.6816 m
+-7887.7793 8607.7256 -7890.6074 8606.0674 -7893.3457 8604.0918 C
+S-7884.75 8603.0488 m
+-7887.8999 8600.6436 -7890.957 8597.9131 -7894.0942 8595.4639 C
+S-7890.7559 8591.0176 m
+-7888.6904 8592.1084 -7886.7017 8593.4668 -7884.75 8594.957 C
+S-7885.6982 8589.0479 m
+-7885.3809 8589.1309 -7885.063 8589.2148 -7884.75 8589.3145 C
+S-7890.7559 8591.0176 m
+-7889.3193 8589.9355 -7887.5879 8589.2256 -7885.6982 8589.0479 C
+S-7894.0942 8595.4639 m
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.231 8602.5996 -7893.3457 8604.0918 C
+S-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 C
+S-7890.7559 8591.0176 m
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 C
+S-7893.3457 8604.0918 m
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+SU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 62)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8593.9043 m
+-7856.7305 8585.3408 L
+-7895 8585.3408 L
+-7895 8593.9043 L
+-7856.7305 8593.9043 L
+f-7856.7305 8597.0967 m
+-7856.7305 8596.4229 L
+-7895 8596.4229 L
+-7895 8597.0967 L
+-7856.7305 8597.0967 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 63)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8589.8262 m
+-7856.7305 8598.3896 L
+-7869.3408 8598.3896 L
+-7869.3408 8611 L
+-7877.9038 8611 L
+-7877.9063 8589.8262 L
+-7877.9038 8589.8262 L
+-7877.9038 8589.8252 L
+-7856.7305 8589.8262 L
+f-7856.7305 8587.3076 m
+-7880.4233 8587.3076 L
+-7880.4233 8611 L
+-7881.0967 8611 L
+-7881.0977 8586.6328 L
+-7856.7305 8586.6328 L
+-7856.7305 8587.3076 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 64)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7895 8610.999 m
+-7895 8572.7285 L
+-7856.7305 8572.7285 L
+-7856.7305 8610.999 L
+-7895 8610.999 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8585.3389 m
+-7882.3896 8585.3389 L
+-7882.3896 8610.999 L
+-7873.8262 8611 L
+-7873.8262 8593.9033 L
+-7856.7305 8593.9033 L
+-7856.7305 8585.3389 L
+f-7856.7305 8596.4219 m
+-7871.3081 8596.4219 L
+-7871.3081 8611 L
+-7870.6338 8611 L
+-7870.6338 8597.0957 L
+-7856.7305 8597.0957 L
+-7856.7305 8596.4219 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 65)
+0 A
+u1 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7867.0625 8583.4609 m
+-7894.6025 8583.4609 L
+-7894.6025 8611 L
+-7867.0625 8611 L
+-7867.0625 8583.4609 L
+n0 O
+0 0.55 1 0.12 k
+-7866.8418 8596.7002 m
+-7895 8596.7002 L
+-7895 8597.8252 L
+-7866.8418 8597.8252 L
+-7866.8418 8596.7002 L
+fu0 0.55 1 0.3 k
+-7893.9814 8584.5215 m
+-7894.4102 8586.5254 -7893.1865 8590.1514 -7890.0874 8593.251 c
+-7886.9878 8596.3496 -7883.3457 8597.6602 -7881.3594 8597.1455 C
+-7881.3594 8597.1455 L
+-7880.875 8595.1895 -7882.1519 8591.5117 -7885.25 8588.4141 c
+-7888.3457 8585.3184 -7892.0122 8584.1064 -7893.9814 8584.5215 C
+f0 0.39 0.7 0.12 k
+-7893.9814 8609.9912 m
+-7894.4102 8607.9883 -7893.1865 8604.3613 -7890.0874 8601.2617 c
+-7886.9878 8598.1641 -7883.3457 8596.8535 -7881.3594 8597.3672 C
+-7881.3594 8597.3672 L
+-7880.875 8599.3242 -7882.1519 8603.001 -7885.25 8606.0996 c
+-7888.3457 8609.1953 -7892.0122 8610.4063 -7893.9814 8609.9912 C
+fUu0 0.55 1 0.3 k
+-7880.1782 8609.9912 m
+-7880.6074 8607.9883 -7879.3838 8604.3613 -7876.2842 8601.2617 c
+-7873.1855 8598.1641 -7869.543 8596.8535 -7867.5576 8597.3672 C
+-7867.5566 8597.3672 L
+-7867.0718 8599.3242 -7868.3496 8603.001 -7871.4473 8606.0996 c
+-7874.543 8609.1953 -7878.209 8610.4063 -7880.1782 8609.9912 C
+f0 0.39 0.7 0.12 k
+-7880.1782 8584.5215 m
+-7880.6074 8586.5254 -7879.3838 8590.1514 -7876.2842 8593.251 c
+-7873.1855 8596.3496 -7869.543 8597.6602 -7867.5576 8597.1455 C
+-7867.5566 8597.1455 L
+-7867.0718 8595.1895 -7868.3496 8591.5117 -7871.4473 8588.4141 c
+-7874.543 8585.3184 -7878.209 8584.1064 -7880.1782 8584.5215 C
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 67)
+0 A
+u0 Ap
+0 J 0 j 1 w 4 M []0 d0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 69)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7867.4609 8583.4609 m
+-7895 8583.4609 L
+-7895 8611 L
+-7867.4609 8611 L
+-7867.4609 8583.4609 L
+n0 O
+0 0.55 1 0.3 k
+-7885.4233 8597.252 m
+-7884.3096 8595.5313 -7880.8809 8593.833 -7876.4966 8593.833 c
+-7872.1152 8593.833 -7868.6138 8595.4824 -7867.5718 8597.25 C
+-7867.5718 8597.25 L
+-7868.6138 8598.9766 -7872.1152 8600.6738 -7876.4966 8600.6738 c
+-7880.875 8600.6738 -7884.3242 8598.9375 -7885.4233 8597.252 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 8)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7893.9521 8608.3125 m
+-7786.7954 8608.3125 L
+-7786.7954 8594.1855 L
+-7893.9521 8594.1855 L
+-7893.9521 8608.3125 L
+nu0 O
+0 0 0 1 k
+-7892.2832 8607.623 m
+-7892.8535 8610 -7892.8184 8606.0039 V
+-7893.0479 8602.8027 L
+-7893.6167 8600.4551 L
+-7893.4502 8598.123 L
+-7891.9502 8597.4551 -7875.2832 8596.123 V
+-7868.6167 8594.7891 -7859.6167 8594.7891 V
+-7794.3936 8595.4766 -7789.4912 8596.8848 v
+-7830.3882 8594.875 -7832.9688 8595.5117 v
+-7793.8569 8597.1602 -7790.8545 8598.4316 v
+-7828.79 8596.5469 -7832.167 8598.1777 v
+-7797.249 8599.9102 -7793.021 8601.5313 v
+-7799.7217 8600.8828 -7801.5127 8601.082 v
+-7798.3896 8601.5703 l
+-7803.4194 8601.502 l
+-7806.3218 8601.1289 l
+-7798.4521 8602.2422 -7797.9033 8602.8086 v
+-7794.3154 8602.1309 -7808.5186 8602.3848 v
+-7842.1177 8598.4551 -7892.2832 8607.623 V
+f/BBAccumRotation (5.805971) XT
+0 R
+0 0 0 0.5 K
+0.025 w-7893.9502 8597.123 m
+-7873.667 8595.2949 -7853.9727 8594.2207 v
+-7811.1514 8594.502 -7806.5737 8594.9004 v
+-7794.1631 8595.0313 -7786.7959 8596.0273 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 1 K
+-7831.8369 8594.4082 m
+-7835.2959 8594.0273 -7861.2607 8594.2793 Y
+-7871.627 8594.1602 -7893.9502 8597.123 Y
+S/BBAccumRotation (5.805971) XT
+-7830.9873 8597.6641 m
+-7800.3608 8598.582 -7793.6606 8599.2324 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 0.5 K
+-7839.6201 8602.2051 m
+-7804.3706 8603.6172 -7801.4058 8604.1406 v
+S/BBAccumRotation (5.805971) XT
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 83)
+0 A
+u0 J 0 j 1 w 4 M []0 d0 XR
+-7894 8609.9355 m
+-7680.4009 8609.9355 L
+-7680.4009 8602.1348 L
+-7894 8602.1348 L
+-7894 8609.9355 L
+n0 O
+0 0 0 1 k
+-7894 8606.0352 m
+-7883.9858 8608.5273 -7877.187 8609.875 -7865.2007 8609.9355 c
+-7852.2183 8610 -7787.2002 8609.9355 y
+-7722.1816 8610 -7709.2002 8609.9355 v
+-7697.2129 8609.875 -7690.415 8608.5273 -7680.4009 8606.0352 C
+-7690.415 8603.543 -7697.2129 8602.1953 -7709.2002 8602.1348 c
+-7722.1816 8602.0693 -7787.2002 8602.1348 y
+-7852.2183 8602.0693 -7865.2007 8602.1348 v
+-7877.187 8602.1953 -7883.9858 8603.543 -7894 8606.0352 C
+fU%AI8_EndBrushPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe Brush Manager Order)
+(Adobe Brush Manager Order)
+( Adobe Calligraphic Brush Tool/ 6 pt Flat / Adobe Calligraphic Brush T) -
+(ool/ 10 pt Oval/ Adobe Calligraphic Brush Tool/ 12 pt Oval / Adobe Cal) -
+(ligraphic Brush Tool/ 20 pt Oval/ Adobe Calligraphic Brush Tool/ 25 pt) -
+( Round / Adobe Calligraphic Brush Tool/ 50 pt Flat/ Adobe Scatter Brus) -
+(h Tool/ Dog Tracks/ Adobe Scatter Brush Tool/ Fall Leaf/ Adobe Scatter) -
+( Brush Tool/ Ladybug/ Adobe Scatter Brush Tool/ Push Pin/ Adobe Scatte) -
+(r Brush Tool/ Strawberry/ Adobe Scatter Brush Tool/ Twinkle Star / Ado) -
+(be ArtOnPath Brush Tool/ Marker/ Adobe ArtOnPath Brush Tool/ Tapered S) -
+(troke/ Adobe ArtOnPath Brush Tool/ Arrow/ Adobe ArtOnPath Brush Tool/ ) -
+(Paintbrush/ Adobe ArtOnPath Brush Tool/ Type/ Adobe PatternOnPath Brus) -
+(h Tool/ Double Lines/ Adobe PatternOnPath Brush Tool/ Laurel/ Adobe Pa) -
+(tternOnPath Brush Tool/ Rope /) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Dog Tracks)
+(1 /New Pattern 41/ 1 0 0 0 1 / 0 1 1 0 1 1 0 0 0 0 -90 -90 0 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Fall Leaf)
+(1 /New Pattern 34/ 1 0.0745 0.9 0.9019 0.18 / 0 0.602793 1 1 0.1 1 1 -) -
+(1 1 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Ladybug)
+(1 /New Pattern 10/ 5 0.898039 0 0 / 0 1 1 0 0.803911 1.2 1 -1.55 1.55 ) -
+(1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Push Pin)
+(1 /New Pattern 36/ 1 0.025 0.1 0.475 0 / 0 1 1 0 0.401676 1 1 -1.06145) -
+( 1.06 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Strawberry)
+(1 /New Pattern 37/ 1 0 0 0 1 / 0 0.803911 1 1 0.803911 1 1 -0.5 0.5 1 ) -
+(-75 75.419 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Twinkle Star )
+(1 /New Pattern 2/ 0 1 / 1 0.5 1 1 0.25 1 1 -0.5 0.5 1 0 0 0 0 0) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(10 pt Oval)
+(1 1 19 15 15 130 130 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(12 pt Oval )
+(1 7 17 45 45 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(20 pt Oval)
+(1 20 20 20 100 40 80 0 2 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(25 pt Round )
+(1 10 40 100 100 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(50 pt Flat)
+(1 40 60 0 0 44 44 0 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(6 pt Flat )
+(1 4 8 10 10 90 90 2 0 0 0) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Arrow)
+(1 / New Pattern 45/ / / / / 5 0.898039 0 0 /  2 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Marker)
+(1 / New Pattern 8/ / / / / 0 0 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Paintbrush)
+(1 / New Pattern 5/ / / / / 1 0.5 0.85 1 0.45 /  0 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Tapered Stroke)
+(1 / New Pattern 83/ / / / / 1 0 0 0 1 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Type)
+(1 / New Pattern 50/ / / / / 1 0.952941 0.94902 0.196078 0.0745098 /  1) -
+( 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Double Lines)
+(1 / New Pattern 62/ New Pattern 63/ New Pattern 64/ / / 1 1 0.14 0.09 ) -
+(0 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Laurel)
+(1 / New Pattern 65/ New Pattern 42/ New Pattern 67/ / New Pattern 69/ ) -
+(1 0 0.55 1 0.3 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Rope )
+(1 / New Pattern 1/ / / New Pattern 3/ New Pattern 6/ 5 0 0 0 /  1 0 1 ) -
+(0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_BeginPalette
+0 0 Pb
+1 1 1 1 ([Registration]) 0 Xs
+([Registration]) Pc
+0 0 0 0 k
+(C=0 M=0 Y=0 K=0) Pc
+0 0 0 1 k
+(C=0 M=0 Y=0 K=100) Pc
+0 0.1 1 0 k
+(C=0 M=10 Y=100 K=0) Pc
+0 0.5 0 0 k
+(C=0 M=50 Y=0 K=0) Pc
+0 0.5 1 0 k
+(C=0 M=50 Y=100 K=0) Pc
+1 0.55 1 0 k
+(C=100 M=55 Y=100 K=0) Pc
+1 0.9 0.1 0 k
+(C=100 M=90 Y=10 K=0) Pc
+0.15 1 1 0 k
+(C=15 M=100 Y=100 K=0) Pc
+0.45 0.9 0 0 k
+(C=45 M=90 Y=0 K=0) Pc
+0.5 0.4 0.3 0 k
+(C=50 M=40 Y=30 K=0) Pc
+0.5 0.85 1 0 k
+(C=50 M=85 Y=100 K=0) Pc
+0.75 0.05 1 0 k
+(C=75 M=5 Y=100 K=0) Pc
+0.75 0.9 0 0 k
+(C=75 M=90 Y=0 K=0) Pc
+0.8 0.05 0 0 k
+(C=80 M=5 Y=0 K=0) Pc
+Bb
+2 (Black, White) 0 0 0 1 1 0 0 1 0 0 Bg
+0 BB
+(Black, White) Pc
+Bb
+2 (Chrome) 0 0 0 1 1 0 0 1 0 0 Bg
+0 BB
+(Chrome) Pc
+Bb
+2 (Rainbow) 0 0 0 1 1 0 0 1 0 0 Bg
+0 BB
+(Rainbow) Pc
+Bb
+0 0 0 0 Bh
+2 (Yellow & Orange Radial) 0 0 0 1 1 0 0 1 0 0 Bg
+0 BB
+(Yellow & Orange Radial) Pc
+(Brick) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Brick) Pc
+(Confetti) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Confetti) Pc
+(Leaves - Fall ) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Leaves - Fall ) Pc
+(Stripes) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Stripes) Pc
+PB
+%AI5_EndPalette
+%AI5_Begin_NonPrinting
+Np
+%AI8_PluginGroupInfo
+(Adobe Path Blends) (Adobe Blends Plugin) (Live Blends.aip)
+%AI8_PluginGroupInfo
+(Adobe PatternOnPath Brush Tool) (Adobe Pattern Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe ArtOnPath Brush Tool) (Adobe Art Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe Calligraphic Brush Tool) (Adobe Calligraphic Brush Plugin) (Calligraphic Brush Tool.aip)
+%AI8_PluginGroupInfo
+(Adobe Scatter Brush Tool) (Adobe Scatter Brush Plugin) (Scatter Brush Tool.aip)
+%AI5_End_NonPrinting--
+%%EndSetup
+%AI5_BeginLayer
+1 1 1 1 0 0 1 0 79 128 255 0 50 Lb
+(Layer 1) Ln
+0 A
+1 Ap
+0 O
+0 0 0 0 k
+0 R
+0 0 0 1 K
+1 J 1 j 2.8346 w 4 M []0 d0 XR
+543.333 424 m
+-20.667 424 L
+-20.667 840 L
+543.333 840 L
+543.333 424 L
+bu0.9137 0.1922 0.0549 0.0039 k
+0 J 0 j 1 w369.334 626.5024 m
+369.334 623.3843 366.7832 620.833 363.6641 620.833 c
+155.0029 620.833 l
+151.8848 620.833 149.3335 623.3843 149.3335 626.5024 c
+149.3335 656.6636 l
+149.3335 659.7817 151.8848 662.333 155.0029 662.333 c
+363.6641 662.333 l
+366.7832 662.333 369.334 659.7817 369.334 656.6636 c
+369.334 626.5024 l
+f0 R
+0 0 0 1 K
+1 J 1 j 2 w369.334 626.5024 m
+369.334 623.3843 366.7832 620.833 363.6641 620.833 c
+155.0029 620.833 l
+151.8848 620.833 149.3335 623.3843 149.3335 626.5024 c
+149.3335 656.6636 l
+149.3335 659.7817 151.8848 662.333 155.0029 662.333 c
+363.6641 662.333 l
+366.7832 662.333 369.334 659.7817 369.334 656.6636 c
+369.334 626.5024 l
+sU0 O
+0.9137 0.1922 0.0549 0.0039 k
+2.8346 w408.4033 774.1328 m
+408.4033 760.6274 398.3584 749.5767 386.0811 749.5767 c
+137.7554 749.5767 l
+125.4785 749.5767 115.4336 760.6274 115.4336 774.1328 c
+115.4336 787.6392 125.4785 798.689 137.7554 798.689 c
+386.0811 798.689 l
+398.3584 798.689 408.4033 787.6392 408.4033 774.1328 c
+b400.4033 714.4658 m
+400.4033 706.2764 390.7012 699.5762 378.8428 699.5762 c
+138.9937 699.5762 l
+127.1357 699.5762 117.4336 706.2764 117.4336 714.4658 c
+117.4336 722.6558 127.1357 729.3555 138.9937 729.3555 c
+378.8428 729.3555 l
+390.7012 729.3555 400.4033 722.6558 400.4033 714.4658 c
+b504.4033 567.6328 m
+504.4033 550.5522 490.8271 536.5767 474.2334 536.5767 c
+138.603 536.5767 l
+122.0103 536.5767 108.4336 550.5522 108.4336 567.6328 c
+108.4336 584.7139 122.0103 598.689 138.603 598.689 c
+474.2334 598.689 l
+490.8271 598.689 504.4033 584.7139 504.4033 567.6328 c
+buu0 Ap
+185.4341 641.4258 m
+162.7573 641.4258 l
+159.6392 641.4258 157.0884 638.875 157.0884 635.7568 c
+157.0884 632.9219 l
+157.0884 629.8037 159.6392 627.2529 162.7573 627.2529 c
+185.4341 627.2529 L
+S0 0 0 0 K
+183.7334 643.126 m
+161.0566 643.126 l
+157.9385 643.126 155.3877 640.5752 155.3877 637.457 c
+155.3877 634.6221 l
+155.3877 631.5039 157.9385 628.9531 161.0566 628.9531 c
+183.7334 628.9531 L
+SUu0 0 0 1 K
+198.1899 641.4258 m
+195.0728 641.4258 192.521 638.875 192.521 635.7568 c
+192.521 632.9219 l
+192.521 629.8037 195.0728 627.2529 198.1899 627.2529 c
+215.1978 627.2529 l
+218.3169 627.2529 220.8677 629.8037 220.8677 632.9219 c
+220.8677 635.7568 l
+220.8677 638.875 218.3169 641.4258 215.1978 641.4258 c
+198.1899 641.4258 l
+s0 0 0 0 K
+196.4893 643.126 m
+193.3721 643.126 190.8203 640.5752 190.8203 637.457 c
+190.8203 634.6221 l
+190.8203 631.5039 193.3721 628.9531 196.4893 628.9531 c
+213.4971 628.9531 l
+216.6162 628.9531 219.167 631.5039 219.167 634.6221 c
+219.167 637.457 l
+219.167 640.5752 216.6162 643.126 213.4971 643.126 c
+196.4893 643.126 l
+sUu0 0 0 1 K
+269.0562 641.4258 m
+265.939 641.4258 263.3862 638.875 263.3862 635.7568 c
+263.3862 632.9219 l
+263.3862 629.8037 265.939 627.2529 269.0562 627.2529 c
+286.0659 627.2529 l
+289.1831 627.2529 291.7339 629.8037 291.7339 632.9219 c
+291.7339 635.7568 l
+291.7339 638.875 289.1831 641.4258 286.0659 641.4258 c
+269.0562 641.4258 l
+s0 0 0 0 K
+267.355 643.126 m
+264.2378 643.126 261.6851 640.5752 261.6851 637.457 c
+261.6851 634.6221 l
+261.6851 631.5039 264.2378 628.9531 267.355 628.9531 c
+284.3647 628.9531 l
+287.4819 628.9531 290.0327 631.5039 290.0327 634.6221 c
+290.0327 637.457 l
+290.0327 640.5752 287.4819 643.126 284.3647 643.126 c
+267.355 643.126 l
+sUu0 0 0 1 K
+304.4902 641.4258 m
+301.3711 641.4258 298.8203 638.875 298.8203 635.7568 c
+298.8203 632.9219 l
+298.8203 629.8037 301.3711 627.2529 304.4902 627.2529 c
+321.498 627.2529 l
+324.6152 627.2529 327.166 629.8037 327.166 632.9219 c
+327.166 635.7568 l
+327.166 638.875 324.6152 641.4258 321.498 641.4258 c
+304.4902 641.4258 l
+s0 0 0 0 K
+302.7891 643.126 m
+299.6699 643.126 297.1191 640.5752 297.1191 637.457 c
+297.1191 634.6221 l
+297.1191 631.5039 299.6699 628.9531 302.7891 628.9531 c
+319.7969 628.9531 l
+322.9141 628.9531 325.4648 631.5039 325.4648 634.6221 c
+325.4648 637.457 l
+325.4648 640.5752 322.9141 643.126 319.7969 643.126 c
+302.7891 643.126 l
+sUu0 0 0 1 K
+256.3003 641.4258 m
+233.6235 641.4258 l
+230.5063 641.4258 227.9546 638.875 227.9546 635.7568 c
+227.9546 632.9219 l
+227.9546 629.8037 230.5063 627.2529 233.6235 627.2529 c
+256.3003 627.2529 L
+S0 0 0 0 K
+254.5996 643.126 m
+231.9229 643.126 l
+228.8057 643.126 226.2539 640.5752 226.2539 637.457 c
+226.2539 634.6221 l
+226.2539 631.5039 228.8057 628.9531 231.9229 628.9531 c
+254.5996 628.9531 L
+SUu0 0 0 1 K
+361.1836 627.2529 m
+361.1836 635.7568 l
+361.1836 638.875 358.6328 641.4258 355.5137 641.4258 c
+334.2539 641.4258 L
+334.2539 627.2529 l
+S0 0 0 0 K
+359.4824 628.9531 m
+359.4824 637.457 l
+359.4824 640.5752 356.9316 643.126 353.8125 643.126 c
+332.5527 643.126 L
+332.5527 628.9531 l
+SUu1 Ap
+0 0 0 1 K
+284.6479 634.3398 m
+284.6479 634.3398 l
+284.6479 634.3398 l
+284.6479 634.3398 l
+284.6479 634.3398 l
+s0 0 0 0 K
+282.9468 636.04 m
+282.9468 636.04 l
+282.9468 636.04 l
+282.9468 636.04 l
+282.9468 636.04 l
+sUu0 0 0 1 K
+305.9063 634.3398 m
+305.9063 634.3398 l
+305.9063 634.3398 l
+305.9063 634.3398 l
+305.9063 634.3398 l
+s0 0 0 0 K
+304.2051 636.04 m
+304.2051 636.04 l
+304.2051 636.04 l
+304.2051 636.04 l
+304.2051 636.04 l
+sUu0 0 0 1 K
+213.7808 634.3398 m
+213.7808 634.3398 l
+213.7808 634.3398 l
+213.7808 634.3398 l
+213.7808 634.3398 l
+s0 0 0 0 K
+212.0801 636.04 m
+212.0801 636.04 l
+212.0801 636.04 l
+212.0801 636.04 l
+212.0801 636.04 l
+sUUuu0 Ap
+0 0 0 1 K
+185.6006 780.5928 m
+162.9238 780.5928 l
+159.8057 780.5928 157.2549 778.042 157.2549 774.9238 c
+157.2549 772.0889 l
+157.2549 768.9707 159.8057 766.4199 162.9238 766.4199 c
+185.6006 766.4199 L
+S0 0 0 0 K
+183.8999 782.293 m
+161.2231 782.293 l
+158.105 782.293 155.5542 779.7422 155.5542 776.624 c
+155.5542 773.7891 l
+155.5542 770.6709 158.105 768.1201 161.2231 768.1201 c
+183.8999 768.1201 L
+SUu0 0 0 1 K
+198.3564 780.5928 m
+195.2393 780.5928 192.6875 778.042 192.6875 774.9238 c
+192.6875 772.0889 l
+192.6875 768.9707 195.2393 766.4199 198.3564 766.4199 c
+215.3643 766.4199 l
+218.4834 766.4199 221.0342 768.9707 221.0342 772.0889 c
+221.0342 774.9238 l
+221.0342 778.042 218.4834 780.5928 215.3643 780.5928 c
+198.3564 780.5928 l
+s0 0 0 0 K
+196.6558 782.293 m
+193.5386 782.293 190.9868 779.7422 190.9868 776.624 c
+190.9868 773.7891 l
+190.9868 770.6709 193.5386 768.1201 196.6558 768.1201 c
+213.6636 768.1201 l
+216.7827 768.1201 219.3335 770.6709 219.3335 773.7891 c
+219.3335 776.624 l
+219.3335 779.7422 216.7827 782.293 213.6636 782.293 c
+196.6558 782.293 l
+sUu0 0 0 1 K
+269.2227 780.5928 m
+266.1055 780.5928 263.5527 778.042 263.5527 774.9238 c
+263.5527 772.0889 l
+263.5527 768.9707 266.1055 766.4199 269.2227 766.4199 c
+286.2324 766.4199 l
+289.3496 766.4199 291.9004 768.9707 291.9004 772.0889 c
+291.9004 774.9238 l
+291.9004 778.042 289.3496 780.5928 286.2324 780.5928 c
+269.2227 780.5928 l
+s0 0 0 0 K
+267.5215 782.293 m
+264.4043 782.293 261.8516 779.7422 261.8516 776.624 c
+261.8516 773.7891 l
+261.8516 770.6709 264.4043 768.1201 267.5215 768.1201 c
+284.5313 768.1201 l
+287.6484 768.1201 290.1992 770.6709 290.1992 773.7891 c
+290.1992 776.624 l
+290.1992 779.7422 287.6484 782.293 284.5313 782.293 c
+267.5215 782.293 l
+sUu0 0 0 1 K
+304.6563 780.5928 m
+301.5371 780.5928 298.9863 778.042 298.9863 774.9238 c
+298.9863 772.0889 l
+298.9863 768.9707 301.5371 766.4199 304.6563 766.4199 c
+321.6641 766.4199 l
+324.7813 766.4199 327.332 768.9707 327.332 772.0889 c
+327.332 774.9238 l
+327.332 778.042 324.7813 780.5928 321.6641 780.5928 c
+304.6563 780.5928 l
+s0 0 0 0 K
+302.9551 782.293 m
+299.8359 782.293 297.2852 779.7422 297.2852 776.624 c
+297.2852 773.7891 l
+297.2852 770.6709 299.8359 768.1201 302.9551 768.1201 c
+319.9629 768.1201 l
+323.0801 768.1201 325.6309 770.6709 325.6309 773.7891 c
+325.6309 776.624 l
+325.6309 779.7422 323.0801 782.293 319.9629 782.293 c
+302.9551 782.293 l
+sUu0 0 0 1 K
+256.4668 780.5928 m
+233.79 780.5928 l
+230.6729 780.5928 228.1211 778.042 228.1211 774.9238 c
+228.1211 772.0889 l
+228.1211 768.9707 230.6729 766.4199 233.79 766.4199 c
+256.4668 766.4199 L
+S0 0 0 0 K
+254.7661 782.293 m
+232.0894 782.293 l
+228.9722 782.293 226.4204 779.7422 226.4204 776.624 c
+226.4204 773.7891 l
+226.4204 770.6709 228.9722 768.1201 232.0894 768.1201 c
+254.7661 768.1201 L
+SUu0 0 0 1 K
+361.3496 766.4199 m
+361.3496 774.9238 l
+361.3496 778.042 358.7988 780.5928 355.6797 780.5928 c
+334.4199 780.5928 L
+334.4199 766.4199 l
+S0 0 0 0 K
+359.6484 768.1201 m
+359.6484 776.624 l
+359.6484 779.7422 357.0977 782.293 353.9785 782.293 c
+332.7188 782.293 L
+332.7188 768.1201 l
+SUu1 Ap
+0 0 0 1 K
+284.8145 773.5068 m
+284.8145 773.5068 l
+284.8145 773.5068 l
+284.8145 773.5068 l
+284.8145 773.5068 l
+s0 0 0 0 K
+283.1133 775.207 m
+283.1133 775.207 l
+283.1133 775.207 l
+283.1133 775.207 l
+283.1133 775.207 l
+sUu0 0 0 1 K
+306.0723 773.5068 m
+306.0723 773.5068 l
+306.0723 773.5068 l
+306.0723 773.5068 l
+306.0723 773.5068 l
+s0 0 0 0 K
+304.3711 775.207 m
+304.3711 775.207 l
+304.3711 775.207 l
+304.3711 775.207 l
+304.3711 775.207 l
+sUu0 0 0 1 K
+213.9473 773.5068 m
+213.9473 773.5068 l
+213.9473 773.5068 l
+213.9473 773.5068 l
+213.9473 773.5068 l
+s0 0 0 0 K
+212.2466 775.207 m
+212.2466 775.207 l
+212.2466 775.207 l
+212.2466 775.207 l
+212.2466 775.207 l
+sUUuu0 Ap
+0 0 0 1 K
+169.6499 720.5933 m
+141.9043 720.5933 l
+138.0894 720.5933 134.9683 718.043 134.9683 714.9243 c
+134.9683 712.0894 l
+134.9683 708.9707 138.0894 706.4204 141.9043 706.4204 c
+169.6499 706.4204 L
+S0 0 0 0 K
+167.5693 722.2935 m
+139.8237 722.2935 l
+136.0088 722.2935 132.8877 719.7432 132.8877 716.6245 c
+132.8877 713.7896 l
+132.8877 710.6714 136.0088 708.1206 139.8237 708.1206 c
+167.5693 708.1206 L
+SUu0 0 0 1 K
+185.2573 720.5933 m
+181.4434 720.5933 178.3213 718.043 178.3213 714.9243 c
+178.3213 712.0894 l
+178.3213 708.9707 181.4434 706.4204 185.2573 706.4204 c
+206.0669 706.4204 l
+209.8828 706.4204 213.0039 708.9707 213.0039 712.0894 c
+213.0039 714.9243 l
+213.0039 718.043 209.8828 720.5933 206.0669 720.5933 c
+185.2573 720.5933 l
+s0 0 0 0 K
+183.1763 722.2935 m
+179.3623 722.2935 176.2407 719.7432 176.2407 716.6245 c
+176.2407 713.7896 l
+176.2407 710.6714 179.3623 708.1206 183.1763 708.1206 c
+203.9858 708.1206 l
+207.8022 708.1206 210.9233 710.6714 210.9233 713.7896 c
+210.9233 716.6245 l
+210.9233 719.7432 207.8022 722.2935 203.9858 722.2935 c
+183.1763 722.2935 l
+sUu0 0 0 1 K
+271.9639 720.5933 m
+268.1499 720.5933 265.0269 718.043 265.0269 714.9243 c
+265.0269 712.0894 l
+265.0269 708.9707 268.1499 706.4204 271.9639 706.4204 c
+292.7754 706.4204 l
+296.5894 706.4204 299.7109 708.9707 299.7109 712.0894 c
+299.7109 714.9243 l
+299.7109 718.043 296.5894 720.5933 292.7754 720.5933 c
+271.9639 720.5933 l
+s0 0 0 0 K
+269.8828 722.2935 m
+266.0688 722.2935 262.9453 719.7432 262.9453 716.6245 c
+262.9453 713.7896 l
+262.9453 710.6714 266.0688 708.1206 269.8828 708.1206 c
+290.6943 708.1206 l
+294.5083 708.1206 297.6289 710.6714 297.6289 713.7896 c
+297.6289 716.6245 l
+297.6289 719.7432 294.5083 722.2935 290.6943 722.2935 c
+269.8828 722.2935 l
+sUu0 0 0 1 K
+315.3164 720.5933 m
+311.502 720.5933 308.3809 718.043 308.3809 714.9243 c
+308.3809 712.0894 l
+308.3809 708.9707 311.502 706.4204 315.3164 706.4204 c
+336.127 706.4204 l
+339.9395 706.4204 343.0625 708.9707 343.0625 712.0894 c
+343.0625 714.9243 l
+343.0625 718.043 339.9395 720.5933 336.127 720.5933 c
+315.3164 720.5933 l
+s0 0 0 0 K
+313.2363 722.2935 m
+309.4199 722.2935 306.2988 719.7432 306.2988 716.6245 c
+306.2988 713.7896 l
+306.2988 710.6714 309.4199 708.1206 313.2363 708.1206 c
+334.0449 708.1206 l
+337.8594 708.1206 340.9805 710.6714 340.9805 713.7896 c
+340.9805 716.6245 l
+340.9805 719.7432 337.8594 722.2935 334.0449 722.2935 c
+313.2363 722.2935 l
+sUu0 0 0 1 K
+256.3569 720.5933 m
+228.6113 720.5933 l
+224.7974 720.5933 221.6753 718.043 221.6753 714.9243 c
+221.6753 712.0894 l
+221.6753 708.9707 224.7974 706.4204 228.6113 706.4204 c
+256.3569 706.4204 L
+S0 0 0 0 K
+254.2759 722.2935 m
+226.5303 722.2935 l
+222.7163 722.2935 219.5942 719.7432 219.5942 716.6245 c
+219.5942 713.7896 l
+219.5942 710.6714 222.7163 708.1206 226.5303 708.1206 c
+254.2759 708.1206 L
+SUu0 0 0 1 K
+384.6836 706.4204 m
+384.6836 714.9243 l
+384.6836 718.043 381.5625 720.5933 377.7461 720.5933 c
+351.7344 720.5933 L
+351.7344 706.4204 l
+S0 0 0 0 K
+382.6016 708.1206 m
+382.6016 716.6245 l
+382.6016 719.7432 379.4805 722.2935 375.6641 722.2935 c
+349.6523 722.2935 L
+349.6523 708.1206 l
+SUu1 Ap
+0 0 0 1 K
+291.0405 713.5078 m
+291.0405 713.5078 l
+291.0405 713.5078 l
+291.0405 713.5078 l
+291.0405 713.5078 l
+s0 0 0 0 K
+288.9595 715.2075 m
+288.9595 715.2075 l
+288.9595 715.2075 l
+288.9595 715.2075 l
+288.9595 715.2075 l
+sUu0 0 0 1 K
+317.0508 713.5078 m
+317.0508 713.5078 l
+317.0508 713.5078 l
+317.0508 713.5078 l
+317.0508 713.5078 l
+s0 0 0 0 K
+314.9688 715.2075 m
+314.9688 715.2075 l
+314.9688 715.2075 l
+314.9688 715.2075 l
+314.9688 715.2075 l
+sUu0 0 0 1 K
+204.333 713.5078 m
+204.333 713.5078 l
+204.333 713.5078 l
+204.333 713.5078 l
+204.333 713.5078 l
+s0 0 0 0 K
+202.2524 715.2075 m
+202.2524 715.2075 l
+202.2524 715.2075 l
+202.2524 715.2075 l
+202.2524 715.2075 l
+sUUuu0 Ap
+0 0 0 1 K
+4 w185.3848 566.1685 m
+147.0908 566.1685 l
+141.8252 566.1685 137.5176 562.479 137.5176 557.9688 c
+137.5176 553.8682 l
+137.5176 549.3574 141.8252 545.668 147.0908 545.668 c
+185.3848 545.668 L
+S0 0 0 0 K
+182.5127 568.6279 m
+144.2188 568.6279 l
+138.9531 568.6279 134.6455 564.9385 134.6455 560.4277 c
+134.6455 556.3271 l
+134.6455 551.8169 138.9531 548.1274 144.2188 548.1274 c
+182.5127 548.1274 L
+SUu0 0 0 1 K
+206.9258 566.1685 m
+201.6616 566.1685 197.3525 562.479 197.3525 557.9688 c
+197.3525 553.8682 l
+197.3525 549.3574 201.6616 545.668 206.9258 545.668 c
+235.6465 545.668 l
+240.9141 545.668 245.2217 549.3574 245.2217 553.8682 c
+245.2217 557.9688 l
+245.2217 562.479 240.9141 566.1685 235.6465 566.1685 c
+206.9258 566.1685 l
+s0 0 0 0 K
+204.0537 568.6279 m
+198.7896 568.6279 194.4805 564.9385 194.4805 560.4277 c
+194.4805 556.3271 l
+194.4805 551.8169 198.7896 548.1274 204.0537 548.1274 c
+232.7749 548.1274 l
+238.042 548.1274 242.3496 551.8169 242.3496 556.3271 c
+242.3496 560.4277 l
+242.3496 564.9385 238.042 568.6279 232.7749 568.6279 c
+204.0537 568.6279 l
+sUu0 0 0 1 K
+326.5977 566.1685 m
+321.333 566.1685 317.0225 562.479 317.0225 557.9688 c
+317.0225 553.8682 l
+317.0225 549.3574 321.333 545.668 326.5977 545.668 c
+355.3213 545.668 l
+360.5859 545.668 364.8936 549.3574 364.8936 553.8682 c
+364.8936 557.9688 l
+364.8936 562.479 360.5859 566.1685 355.3213 566.1685 c
+326.5977 566.1685 l
+s0 0 0 0 K
+323.7246 568.6279 m
+318.4609 568.6279 314.1494 564.9385 314.1494 560.4277 c
+314.1494 556.3271 l
+314.1494 551.8169 318.4609 548.1274 323.7246 548.1274 c
+352.4492 548.1274 l
+357.7129 548.1274 362.0205 551.8169 362.0205 556.3271 c
+362.0205 560.4277 l
+362.0205 564.9385 357.7129 568.6279 352.4492 568.6279 c
+323.7246 568.6279 l
+sUu0 0 0 1 K
+386.4336 566.1685 m
+381.167 566.1685 376.8594 562.479 376.8594 557.9688 c
+376.8594 553.8682 l
+376.8594 549.3574 381.167 545.668 386.4336 545.668 c
+415.1563 545.668 l
+420.4199 545.668 424.7275 549.3574 424.7275 553.8682 c
+424.7275 557.9688 l
+424.7275 562.479 420.4199 566.1685 415.1563 566.1685 c
+386.4336 566.1685 l
+s0 0 0 0 K
+383.5615 568.6279 m
+378.2939 568.6279 373.9863 564.9385 373.9863 560.4277 c
+373.9863 556.3271 l
+373.9863 551.8169 378.2939 548.1274 383.5615 548.1274 c
+412.2832 548.1274 l
+417.5469 548.1274 421.8545 551.8169 421.8545 556.3271 c
+421.8545 560.4277 l
+421.8545 564.9385 417.5469 568.6279 412.2832 568.6279 c
+383.5615 568.6279 l
+sUu0 0 0 1 K
+305.0566 566.1685 m
+266.7622 566.1685 l
+261.4985 566.1685 257.189 562.479 257.189 557.9688 c
+257.189 553.8682 l
+257.189 549.3574 261.4985 545.668 266.7622 545.668 c
+305.0566 545.668 L
+S0 0 0 0 K
+302.1846 568.6279 m
+263.8901 568.6279 l
+258.6265 568.6279 254.3174 564.9385 254.3174 560.4277 c
+254.3174 556.3271 l
+254.3174 551.8169 258.6265 548.1274 263.8901 548.1274 c
+302.1846 548.1274 L
+SUu0 0 0 1 K
+482.1729 545.668 m
+482.1729 557.9688 l
+482.1729 562.479 477.8652 566.1685 472.5977 566.1685 c
+436.6963 566.1685 L
+436.6963 545.668 l
+S0 0 0 0 K
+479.2998 548.1274 m
+479.2998 560.4277 l
+479.2998 564.9385 474.9922 568.6279 469.7256 568.6279 c
+433.8242 568.6279 L
+433.8242 548.1274 l
+SUu1 Ap
+0 0 0 1 K
+352.9268 555.9189 m
+352.9268 555.9189 l
+352.9268 555.9189 l
+352.9268 555.9189 l
+352.9268 555.9189 l
+s0 0 0 0 K
+350.0547 558.3784 m
+350.0547 558.3784 l
+350.0547 558.3784 l
+350.0547 558.3784 l
+350.0547 558.3784 l
+sUu0 0 0 1 K
+388.8252 555.9189 m
+388.8252 555.9189 l
+388.8252 555.9189 l
+388.8252 555.9189 l
+388.8252 555.9189 l
+s0 0 0 0 K
+385.9521 558.3784 m
+385.9521 558.3784 l
+385.9521 558.3784 l
+385.9521 558.3784 l
+385.9521 558.3784 l
+sUu0 0 0 1 K
+233.2539 555.9189 m
+233.2539 555.9189 l
+233.2539 555.9189 l
+233.2539 555.9189 l
+233.2539 555.9189 l
+s0 0 0 0 K
+230.3818 558.3784 m
+230.3818 558.3784 l
+230.3818 558.3784 l
+230.3818 558.3784 l
+230.3818 558.3784 l
+sUUu0 Ap
+0 0 0 1 K
+2 w163.1582 649.647 m
+180.3291 649.647 l
+183.4473 649.647 185.9985 650.9043 185.9985 652.4414 c
+185.9985 653.9785 183.4473 655.2358 180.3291 655.2358 c
+163.1582 655.2358 L
+S193.7012 655.2358 m
+193.7012 653.9785 193.7012 652.4414 v
+193.7012 650.9043 196.2524 649.647 199.3706 649.647 c
+203.4385 649.647 l
+206.5566 649.647 209.1079 650.9043 209.1079 652.4414 c
+209.1079 653.9785 209.1079 655.2358 Y
+S216.8101 655.2358 m
+216.8101 649.647 l
+S224.5127 655.2358 m
+224.5127 653.9785 224.5127 652.4414 v
+224.5127 650.9043 227.064 649.647 230.1821 649.647 c
+239.9185 649.647 L
+S239.9185 655.2358 m
+255.3237 655.2358 l
+S247.6211 649.647 m
+247.6211 655.2358 l
+S1 Ap
+216.8101 658.4595 m
+216.8101 658.4595 l
+216.8101 658.4595 l
+216.8101 658.4595 l
+216.8101 658.4595 l
+sUu0 Ap
+278.2646 652.7759 m
+278.2646 649.9814 l
+S301.2793 655.5698 m
+301.2793 649.981 l
+S332.0898 655.5698 m
+332.0898 649.981 l
+S332.0898 652.7754 m
+347.4951 652.7754 l
+S347.4961 655.5698 m
+347.4961 649.981 l
+S308.9805 655.5698 m
+324.3877 655.5698 l
+S316.6855 649.981 m
+316.6855 655.5698 l
+S270.4678 655.5708 m
+270.4678 654.313 270.4678 652.7764 v
+270.4678 651.2393 273.0186 649.9814 276.1367 649.9814 c
+287.9082 649.9814 l
+291.0264 649.9814 293.5771 651.2393 293.5771 652.7764 c
+293.5771 654.313 293.5771 655.5708 Y
+S1 Ap
+301.2793 658.7935 m
+301.2793 658.7935 l
+301.2793 658.7935 l
+301.2793 658.7935 l
+301.2793 658.7935 l
+sUu0 Ap
+3 w177.748 587.7261 m
+174.6299 587.7261 172.0786 585.459 172.0786 582.6875 c
+172.0786 579.9165 174.6299 577.6494 177.748 577.6494 c
+194.7554 577.6494 l
+197.8735 577.6494 200.4248 579.9165 200.4248 582.6875 c
+200.4248 585.459 197.8735 587.7261 194.7554 587.7261 c
+177.748 587.7261 l
+s207.5112 587.7261 m
+207.5112 585.459 207.5112 582.6875 v
+207.5112 579.9165 210.0625 577.6494 213.1807 577.6494 c
+230.188 577.6494 l
+233.3062 577.6494 235.8574 579.9165 235.8574 582.6875 c
+235.8574 585.459 235.8574 587.7261 Y
+S221.6841 582.688 m
+221.6841 577.6494 l
+S271.291 587.7261 m
+248.6143 587.7261 l
+245.4961 587.7261 242.9448 585.459 242.9448 582.6875 c
+242.9448 579.9165 245.4961 577.6494 248.6143 577.6494 c
+271.291 577.6494 L
+S242.9448 582.688 m
+250.0313 582.688 l
+S342.1572 587.7261 m
+319.4805 587.7261 l
+316.3623 587.7261 313.8115 585.459 313.8115 582.6875 c
+313.8115 579.9165 316.3623 577.6494 319.4805 577.6494 c
+342.1572 577.6494 L
+S313.8115 582.688 m
+320.8975 582.688 l
+S278.377 587.7261 m
+301.0547 587.7261 l
+304.1729 587.7261 306.7236 586.5928 306.7236 585.207 c
+306.7236 583.8213 304.1729 582.688 301.0547 582.688 c
+298.2197 582.688 l
+295.1021 582.688 294.9546 581.8335 297.8926 580.7891 c
+306.7236 577.6494 L
+S136.6455 587.7261 m
+159.3228 587.7261 l
+162.4409 587.7261 164.9922 586.5928 164.9922 585.207 c
+164.9922 583.8213 162.4409 582.688 159.3228 582.688 c
+156.4883 582.688 l
+153.3701 582.688 150.8188 581.5542 150.8188 580.1689 c
+150.8188 578.7832 150.8188 577.6494 Y
+S349.2432 587.7261 m
+371.9209 587.7261 l
+375.0391 587.7261 377.5898 585.459 377.5898 582.6875 c
+377.5898 579.9165 375.0391 577.6494 371.9209 577.6494 c
+349.2432 577.6494 L
+S349.2432 587.7261 m
+349.2432 577.6499 l
+S413.0225 587.7261 m
+435.7002 587.7261 l
+438.8184 587.7261 441.3691 585.459 441.3691 582.6875 c
+441.3691 579.9165 438.8184 577.6494 435.7002 577.6494 c
+413.0225 577.6494 L
+S434.2822 582.688 m
+441.3691 582.688 l
+S448.4561 587.7261 m
+448.4561 586.5928 448.4561 585.207 v
+448.4561 583.8213 451.0068 582.688 454.125 582.688 c
+471.1328 582.688 l
+474.251 582.688 476.8018 583.8213 476.8018 585.207 c
+476.8018 586.5928 476.8018 587.7261 Y
+S462.6289 582.688 m
+462.6289 577.6494 l
+SUu0 0 0 0 K
+176.748 590.7261 m
+173.6299 590.7261 171.0786 588.459 171.0786 585.6875 c
+171.0786 582.9165 173.6299 580.6494 176.748 580.6494 c
+193.7554 580.6494 l
+196.8735 580.6494 199.4248 582.9165 199.4248 585.6875 c
+199.4248 588.459 196.8735 590.7261 193.7554 590.7261 c
+176.748 590.7261 l
+s206.5112 590.7261 m
+206.5112 588.459 206.5112 585.6875 v
+206.5112 582.9165 209.0625 580.6494 212.1807 580.6494 c
+229.188 580.6494 l
+232.3062 580.6494 234.8574 582.9165 234.8574 585.6875 c
+234.8574 588.459 234.8574 590.7261 Y
+S220.6841 585.688 m
+220.6841 580.6494 l
+S270.291 590.7261 m
+247.6143 590.7261 l
+244.4961 590.7261 241.9448 588.459 241.9448 585.6875 c
+241.9448 582.9165 244.4961 580.6494 247.6143 580.6494 c
+270.291 580.6494 L
+S241.9448 585.688 m
+249.0313 585.688 l
+S341.1572 590.7261 m
+318.4805 590.7261 l
+315.3623 590.7261 312.8115 588.459 312.8115 585.6875 c
+312.8115 582.9165 315.3623 580.6494 318.4805 580.6494 c
+341.1572 580.6494 L
+S312.8115 585.688 m
+319.8975 585.688 l
+S277.377 590.7261 m
+300.0547 590.7261 l
+303.1729 590.7261 305.7236 589.5928 305.7236 588.207 c
+305.7236 586.8213 303.1729 585.688 300.0547 585.688 c
+297.2197 585.688 l
+294.1021 585.688 293.9546 584.8335 296.8926 583.7891 c
+305.7236 580.6494 L
+S135.6455 590.7261 m
+158.3228 590.7261 l
+161.4409 590.7261 163.9922 589.5928 163.9922 588.207 c
+163.9922 586.8213 161.4409 585.688 158.3228 585.688 c
+155.4883 585.688 l
+152.3701 585.688 149.8188 584.5542 149.8188 583.1689 c
+149.8188 581.7832 149.8188 580.6494 Y
+S348.2432 590.7261 m
+370.9209 590.7261 l
+374.0391 590.7261 376.5898 588.459 376.5898 585.6875 c
+376.5898 582.9165 374.0391 580.6494 370.9209 580.6494 c
+348.2432 580.6494 L
+S348.2432 590.7261 m
+348.2432 580.6499 l
+S412.0225 590.7261 m
+434.7002 590.7261 l
+437.8184 590.7261 440.3691 588.459 440.3691 585.6875 c
+440.3691 582.9165 437.8184 580.6494 434.7002 580.6494 c
+412.0225 580.6494 L
+S433.2822 585.688 m
+440.3691 585.688 l
+S447.4561 590.7261 m
+447.4561 589.5928 447.4561 588.207 v
+447.4561 586.8213 450.0068 585.688 453.125 585.688 c
+470.1328 585.688 l
+473.251 585.688 475.8018 586.8213 475.8018 588.207 c
+475.8018 589.5928 475.8018 590.7261 Y
+S461.6289 585.688 m
+461.6289 580.6494 l
+SULB
+%AI5_EndLayer--
+%%PageTrailer
+gsave annotatepage grestore showpage
+%%Trailer
+Adobe_Illustrator_AI5 /terminate get exec
+Adobe_shading_AI8 /terminate get exec
+Adobe_ColorImage_AI6 /terminate get exec
+Adobe_pattern_AI5 /terminate get exec
+AGM_Gradient /terminate get exec
+Adobe_cshow /terminate get exec
+Adobe_level2_AI5 /terminate get exec
+%%EOF
diff --git a/non-releases/trunk_before_flattening/misc/graphics/cocoon2.svg b/non-releases/trunk_before_flattening/misc/graphics/cocoon2.svg
new file mode 100644
index 0000000..4c90b9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/cocoon2.svg
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- Generator: Adobe Illustrator 8.0, SVG Export Plug-In 1.0x56 -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG December 1999//EN" "http://www.w3.org/Graphics/SVG/SVG-19991203.dtd" [
+	<!ENTITY st0 "stroke:#000000;stroke-width:2.8346;">
+	<!ENTITY st1 "stroke:#FFFFFF;stroke-width:2.8346;">
+	<!ENTITY st2 "fill:none;stroke:#000000;stroke-width:2.8346;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;">
+	<!ENTITY st3 "fill-rule:nonzero;fill:#0086B3;stroke:#000000;stroke-width:2.8346;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;">
+]>
+<svg xml:space="preserve" width="300.471" height="45.354">
+<g id="Layer_x0020_1">
+	<path style="&st3;" d="M299.054,22.677c0,11.692-10.205,21.26-22.677,21.26H24.095c-12.473,0-22.677-9.567-22.677-21.26c0-11.693,10.205-21.26,22.677-21.26h252.282c12.472,0,22.677,9.566,22.677,21.26z"/>
+	<g style="&st2;">
+		<g>
+			<path d="M77.384,16.441H54.708c-3.118,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.551,5.669,5.669,5.669h22.677"/>
+			<path style="&st1;" d="M75.684,14.741H53.007c-3.118,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.551,5.669,5.669,5.669h22.677"/>
+		</g>
+		<g>
+			<path d="M90.14,16.441c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h17.008c3.119,0,5.67-2.551,5.67-5.669V22.11c0-3.118-2.551-5.669-5.67-5.669H90.14z"/>
+			<path style="&st1;" d="M88.439,14.741c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h17.008c3.119,0,5.67-2.551,5.67-5.669V20.41c0-3.118-2.551-5.669-5.67-5.669H88.439z"/>
+		</g>
+		<g>
+			<path d="M161.007,16.441c-3.118,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.552,5.669,5.67,5.669h17.009c3.117,0,5.669-2.551,5.669-5.669V22.11c0-3.118-2.552-5.669-5.669-5.669h-17.009z"/>
+			<path style="&st1;" d="M159.306,14.741c-3.118,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.552,5.669,5.67,5.669h17.009c3.117,0,5.669-2.551,5.669-5.669V20.41c0-3.118-2.552-5.669-5.669-5.669h-17.009z"/>
+		</g>
+		<g>
+			<path d="M196.44,16.441c-3.119,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.551,5.669,5.67,5.669h17.008c3.117,0,5.668-2.551,5.668-5.669V22.11c0-3.118-2.551-5.669-5.668-5.669H196.44z"/>
+			<path style="&st1;" d="M194.739,14.741c-3.119,0-5.67,2.551-5.67,5.669v2.835c0,3.118,2.551,5.669,5.67,5.669h17.008c3.117,0,5.668-2.551,5.668-5.669V20.41c0-3.118-2.551-5.669-5.668-5.669h-17.008z"/>
+		</g>
+		<g>
+			<path d="M148.25,16.441h-22.677c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h22.677"/>
+			<path style="&st1;" d="M146.55,14.741h-22.677c-3.117,0-5.669,2.551-5.669,5.669v2.835c0,3.118,2.552,5.669,5.669,5.669h22.677"/>
+		</g>
+		<g>
+			<path d="M253.134,30.614V22.11c0-3.118-2.551-5.669-5.67-5.669h-21.26v14.173"/>
+			<path style="&st1;" d="M251.433,28.914V20.41c0-3.118-2.551-5.669-5.67-5.669h-21.26v14.173"/>
+		</g>
+		<g>
+			<path d="M176.598,23.527h0.001z"/>
+			<path style="&st1;" d="M174.896,21.827h0.001z"/>
+		</g>
+		<g>
+			<path d="M197.856,23.527h0.001z"/>
+			<path style="&st1;" d="M196.155,21.827h0.001z"/>
+		</g>
+		<g>
+			<path d="M105.731,23.527h0.001z"/>
+			<path style="&st1;" d="M104.03,21.827h0.001z"/>
+		</g>
+	</g>
+</g><!-- Layer_x0020_1 -->
+</svg>
diff --git a/non-releases/trunk_before_flattening/misc/graphics/powered.gif b/non-releases/trunk_before_flattening/misc/graphics/powered.gif
new file mode 100644
index 0000000..26a5c64
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/powered.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/misc/graphics/pyramid-model-of-contracts.ai b/non-releases/trunk_before_flattening/misc/graphics/pyramid-model-of-contracts.ai
new file mode 100644
index 0000000..c1035f8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/pyramid-model-of-contracts.ai
@@ -0,0 +1,6474 @@
+%!PS-Adobe-3.0 
+%%BoundingBox: 140 600 454 760
+%%HiResBoundingBox: 140.314 600.9429 453.0938 759.6836
+%%DocumentProcessColors: Cyan Magenta Yellow Black
+%%DocumentFonts: Helvetica
+%%DocumentNeededFonts: Helvetica
+%%DocumentSuppliedResources: procset Adobe_level2_AI5 1.2 0
+%%+ procset Adobe_typography_AI5 1.0 1
+%%+ procset Adobe_ColorImage_AI6 1.3 0
+%%+ procset Adobe_Illustrator_AI5 1.3 0
+%%+ procset Adobe_cshow 2.0 8
+%%+ procset Adobe_shading_AI8 1.0 0
+%AI5_FileFormat 4.0
+%AI3_ColorUsage: Color
+%AI7_ImageSettings: 0
+%%CMYKProcessColor: 1 1 1 1 ([Registration])
+%%AI6_ColorSeparationSet: 1 1 (AI6 Default Color Separation Set) 
+%%+ Options: 1 16 0 1 0 1 1 1 0 1 1 1 1 18 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 2 3 4
+%%+ PPD: 1 21 0 0 60 45 2 2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 () 
+%AI3_TemplateBox: 296.5 419.5 296.5 419.5
+%AI3_TileBox: 8 38 584 800
+%AI3_DocumentPreview: None
+%AI5_ArtSize: 592 840
+%AI5_RulerUnits: 1
+%AI5_ArtFlags: 1 0 0 1 0 0 1 0 0
+%AI5_TargetResolution: 800
+%AI5_NumLayers: 1
+%AI8_OpenToView: -375 867 0.75 1016 675 18 0 1 10 67 1 1
+%AI5_OpenViewLayers: 7
+%%PageOrigin:8 38
+%%AI3_PaperRect:-8 802 587 -40
+%%AI3_Margin:8 -39 -9 40
+%AI7_GridSettings: 14.1732 2 14.1732 2 1 0 0.8 0.8 0.8 0.9 0.9 0.9
+%AI7_Thumbnail: 128 68 8
+%%BeginData: 12086 Hex Bytes
+%0000330000660000990000CC0033000033330033660033990033CC0033FF
+%0066000066330066660066990066CC0066FF009900009933009966009999
+%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66
+%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333
+%3333663333993333CC3333FF3366003366333366663366993366CC3366FF
+%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99
+%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033
+%6600666600996600CC6600FF6633006633336633666633996633CC6633FF
+%6666006666336666666666996666CC6666FF669900669933669966669999
+%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33
+%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF
+%9933009933339933669933999933CC9933FF996600996633996666996699
+%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33
+%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF
+%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399
+%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933
+%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF
+%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC
+%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699
+%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33
+%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100
+%000011111111220000002200000022222222440000004400000044444444
+%550000005500000055555555770000007700000077777777880000008800
+%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB
+%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF
+%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF
+%524C45FD1FFF7DFD40F8FD3FFF7DF8A07CA07CA07CA07CA07CA07CA07CA0
+%7CA07CA07CA07CA07CA07CA07CA07CA07CA07CA07CA07CA07CA07CA07CA0
+%7CA07CA07CA07CA07CA07CA07CA07CA051F8FD3FFF52F8CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEA1F8FD3FFF7D
+%F8C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC97CF8FD3FFF52F8CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEA1F8FD3FFF7DF8C9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC97CF8FD3FFF52F8CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEA1F8FD3F
+%FF52F8C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC97CF8FD3FFF52F8CEC9CEC97C76CEC9CE7C51C9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9A7C9CEC9CEA1F8FD3FFF7DF8C9CEC9CE76F8A7CEC92727
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC97C76CEC9CEC97CF8FD3FFF52F8CEC9CE
+%C951527CC9A65227C9A7512751CE7C514B27C9CE512751CEC97C4B2727CE
+%A7274B7CC9264B267C5151CEC9A64B277CCE2727277C27F8A7CEC9CEA1F8
+%FD3FFF7DF8C9CEC9CE767C27CE517C27CEA77CC951A05176CE517CC97CC9
+%51A0CE27A6C9F8C927C9CE4BA627A6A027C951A0CE4BA6C927C9F8C9A627
+%7C76CEC9CEC97CF8FD3FFF52F8CEC9CEC97BA151C926C927C9CE52514B7C
+%7CA6C97BA1CE522751A6C927C9CE4BCE27274BF8A127C97C7CCE7C7CC9F8
+%4B2727A64BCEC927A17BC9CEC9CEA1F8FD3FFF7DF8C9CEC9CE767C7C5151
+%CE4BCE767CC951A051A0CE767C767CC951A0CE27A6C9F8C926C9CE7CA64B
+%CEA051C951A0CE4BCEC97CC927C9CE4B7C76CEC9CEC97CF8FD3FFF52F8CE
+%C9CEC97CA0CE27A6C927C9A64B277C51767CC97CA0A64B517651C9A62727
+%27CEA0272751C927C9A676CE7CA6C97C4B2676CE4BCEC927C926A7CEC9CE
+%A1F8FD3FFF52F8C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CE7CCEC926C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC97CF8FD3FFF52F8CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC97C4B27A0CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEA1F8FD3FFF7DF8C9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC97CF8FD3FFF52
+%F8CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEA1F8FD3FFF7DF8C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC97CF8FD3FFF52F8CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEA1F8FD3FFF7DF8C9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9
+%CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC97CF8FD3F
+%FF52F8CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CEC9CE
+%C9CEC9CEA1F8FD3FFF52FD40F8FD40FF7D527D527D527D527D5227F85252
+%7D5259527D5259527D5259527D52595252F852527D5259527D5259527D52
+%59527D5259527D27F8F852527D527D527D527D7DFD48FF52F8F883FFAFFF
+%AEFFAFFFAEFFAFFFAEFFAFFFAEFFAF7DF87DAFFFAEFFAFFFAEFFAFFFAEFF
+%AFFFAEFFAFFFAE7DF8F87DFD4FFF27F827AFFFFFFFAFFFFFFFAFFFFFFFAF
+%FFFFFFAFFFFFFF84F8A8FFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFF
+%A852F827A8FD4BFFA8F8F852A8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FF
+%AEFFA87DF87DA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FF58F8
+%F87DFD49FF7DF827A8FFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFF
+%FF84F8A8FFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFA827F8
+%52FD46FFA852F82DA8AFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAF
+%FFAE7DF87DAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAE
+%52F827A8FD43FFA827F87DFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFF
+%AFFFFFFFAFFFA8F884FFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFF
+%FFFFAFFFFF7D27F87DFD41FF52F8F87DFFAEFFA8FFAEFFA8FFAEFFA8FFAE
+%FFA8FFAEFFA8FFAEFFA8FFAE7DF87DAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8
+%FFAEFFA8FFAEFFA8FFAEFFA8A82DF827A8FD3EFF27F827FFFFAFFFFFFFAF
+%FFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFA8F884FFFFFFAFFFFF
+%FFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFF7DF8277DFD3BFF
+%A8F8F852AFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFF
+%AEFFAF7DF87DAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFF
+%AFFFAEFFAFFF83F8F852FD39FF7DF827A8FFFFAFFFFFFFAFFFFFFFAFFFFF
+%FFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFF84F8A8FFAFFFFFFFAFFFFFFFAF
+%FFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFF52F827A8FD35FFA8
+%52F827A8AEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFF
+%A8FFAEFFA87DF87DA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FF
+%AEFFA8FFAEFFA8FFAEFFA87DF8F87DFD33FFA827F87DFFAFFFFFFFAFFFFF
+%FFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFF84F8A8FFAF
+%FFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFF
+%FFAFFF52F852FD31FF52F8F884FFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFF
+%AEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAE7DF87DAEFFAFFFAEFFAFFFAEFF
+%AFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFFAEFFAFFF58F8F87D
+%FD2EFF27F827FFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFF
+%FFFFAFFFFFFFAFFFFFFFAFFFA8F884FFFFFFAFFFFFFFAFFFFFFFAFFFFFFF
+%AFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFFFFFAFFFA827F852FD2BFFA8
+%F8F852AEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8
+%FFAEFFA8FFAEFFA8FFAE7DF87DAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAE
+%FFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA8FFAEFFA852F827A8FD14FF7D
+%527D527D527D527D527D527D527D527D527D5252F8275259527D5259527D
+%7DAFFFFFFFAFFFFFFFAF7D7D5259527D5259527D5259527D5259527D5259
+%5252F852527D5259527D5259527D5259527D5259527D52AFFFFFFFAFFFFF
+%FFAFFFFF5259527D5259527D52595227F852527D527D527D527D527D527D
+%527D527D527D7DFD20F87DAFFFAEFFAFFFAEFFFD2BF827AFFFAEFFAFFFAE
+%FFAF7DFD22F87DC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3
+%CAC3CAC3CAA1F8A8FFAFFFFFFFAFFFFFF852AEA8AEA8AEA8AEA8AEA8AEA8
+%AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82727
+%FFAFFFFFFFAFFFFFFF84F8FD1E857EF8F876C3C3C9A1C3C3C9A1C3C3C9A1
+%C3C3C9A1C3C3C9A1C3C3C9A1C3C3C9A176F87DA8FFAEFFA8FFAEFFF82784
+%AE83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE83
+%A884AE83A884AE83A82727A8FFAEFFA8FFAEFFA87DF8857E8584857E8584
+%857E8584857E8584857E8584857E8584857E8584857E59F8F8A1C3CAC3CA
+%C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAA1F8A8FFAFFF
+%FFFFAFFFFFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AE
+%A8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82752FFAFFFFFFFAFFFFFFF84F8
+%FD1E857EF8F89AC9C3CAC3C9C3CAC3C9C3CAC3C9C3CAC3C9C3CAC3C9C3CA
+%C3C9C3CAC37CF87DAEFFAFFFAEFFAFFFF85284AE83A884AE83A884AE83A8
+%84AE83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE83A82727
+%AEFFAFFFAEFFAFFFAE7DF8857E8584857E8584857E8584857E8584857E85
+%84857E8584857E8584857E59F8F8A1C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3
+%CAC3CAC3CAC3CAC3CAC3CAC3CAA1F884FFFFFFAFFFFFFFAFF852AEA8AEA8
+%AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8
+%AEA8AEA8AEA8272EFFFFFFAFFFFFFFAFFFA8F8FD1E857EF8F89AC9A1C3C3
+%C9A1C3C3C9A1C3C3C9A1C3C3C9A1C3C3C9A1C3C3C9A1C3C37CF87DAEFFA8
+%FFAEFFA8FFF85283A884AE83A884AE83A884AE83A884AE83A884AE83A884
+%AE83A884AE83A884AE83A884AE83A884AE2727AEFFA8FFAEFFA8FFAE7DF8
+%8584857E8584857E8584857E8584857E8584857E8584857E8584857E8584
+%59F8F8A1C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CA
+%C3CAA1F884FFFFFFAFFFFFFFAFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8AE
+%A8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8272EFFFFFF
+%AFFFFFFFAFFFA8F8FD1E857EF8F89ACAC3C9C352C3C9C3CAC3C9C3CAC3C9
+%C3CAC3C976A1C3C9C3CAC3C9C37DF87DAFFFAEFFAFFFAEFFF85283A884AE
+%8352272D58A884AE83A884AE83A884AE837D84AE83A884AE83A884AE837D
+%84AE83A884AE2727AFFFAEFFAFFFAEFFAF7DF88584857E8584855327272E
+%7E5A84857E8584857E2884857E8584857E858459F8F87DC3CAC3CA4BCAC3
+%CAC3CAC3CAC3CAC3CAC3CAC3A1C3CAC3CAC3CAC3CAA1F8A8FFAFFFFFFFAF
+%FFFFF852AEA8AEA85852A8A82D7DAEA8AEA8AEA8AEA8AEA88352AEA8AEA8
+%AEA8AEA8AEA8AE7D52A8AEA8AEA82727FFAFFFFFFFAFFFFFFF84F8FD0785
+%288585525328FD078528FD09857EF8F876C3C3C9A120C3C9A1C3C34B27F8
+%A1C927204B515276C34B2727C3C9A176F87DA8FFAEFFA8FFAEFFF82784AE
+%83A827AE83A884838327270458A82727275227F858A85227277D84F827F8
+%5904047D84AE83A82727A8FFAEFFA8FFAEFFA87DF8857E8584857E5A275A
+%7E5A59F828F88485285384057E5A2705528584857E59F8F8A1C3CAC3CA4B
+%CAC3CAC37D76CAC3277676C3767676A17D76CA9A76C3CAA1FD0BF852AEA8
+%AEA827A8AEA8AEA87D7DAEA827A804A8AE52837DAE7D58A88352AE27AEA8
+%277D58A8AEA8AEA827FD0CF8FD0785532705528528855953850585852885
+%2E858527FD04857EF8F89AC9C3CAC326C3CAC3C9767DC3C94B529AC99A52
+%767C767DC3C9C3CAC37CF8277D527D527D527D52F85284AE83A827AE83A8
+%8458527D84AE27A827AE832759528352FD0427842783A8277D52A884AE83
+%A827F87D527D527D527D527D27F8857E8584857E5A84857E2E2E277E5A27
+%5A288584277EF82727005984857E59F8F8A1C3CAC3CA4BCAC3CAC37676CA
+%C3279A76C37676769A7676CA9A76C3CAA1F8A8FD08FFF852AEA8AEA82D7D
+%AEA82D7D7D52AEA827A827A8AE277D7DAE7D58A8AE7DAE27AEA8277D58A8
+%AEA8AEA82752FD09FFA8F8FD0685532E8585852728858527525A85852885
+%28858559FD04857EF8F89AC9A1C3C3F8272027C9A14B272076C34B26274B
+%767CA1272727A1C3C37CF87DFD08FFF85283A884AE8327272752A8842D27
+%F87DAE27A8842783F87DAE2D272783832784AE277D278383A884AE2727FD
+%09FF7DF88584857E858485280527275328528552F884857E05845927F852
+%857E858459F8F8A1C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3A1C37676CAC3CA
+%C3CAC3CAC3CAA1F8A8FD08FFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8
+%AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82752FD09FFA8
+%F8FD0F855959FD0D857EF8F89ACAC3C9C3CAC3C9C3CAC3C9C3CAC3A04B27
+%4BC9C3CAC3C9C3CAC3C9C37DF87DFD08FFF85283A884AE83A884AE83A884
+%AE83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE27
+%27FD09FF7DF88584857E8584857E8584857E858453275A84857E8584857E
+%8584857E858459F8F87DC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CA
+%C3CAC3CAC3CAC3CAA1F8A8FD08FFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8
+%AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82727FD09
+%FFA8F8FD1E857EF8F876C3C3C9A1C3C3C9A1C3C3C9A1C3C3C9A1C3C3C9A1
+%C3C3C9A1C3C3C9A176F87DFD08FFF82784AE83A884AE83A884AE83A884AE
+%83A884AE83A884AE83A884AE83A884AE83A884AE83A884AE83A82727FD09
+%FF7DF8857E8584857E8584857E8584857E8584857E8584857E8584857E85
+%84857E59F8F8A1C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3
+%CAC3CAC3CAA1F8A8FD08FFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AE
+%A8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82752FD09FFA8F8
+%FD1E857EF8F89AC9C3CAC3C9C3CAC3C9C3CAC3C9C3CAC3C9C3CAC3C9C3CA
+%C3C9C3CAC37CF87DFD08FFF85284AE83A884AE83A884AE83A884AE83A884
+%AE83A884AE83A884AE83A884AE83A884AE83A884AE83A82727FD09FF7DF8
+%857E8584857E8584857E8584857E8584857E8584857E8584857E8584857E
+%59F8F8A1C3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CAC3CA
+%C3CAA1F8A8FD08FFF852AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8
+%AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA8AEA82752FD09FFA8F8FD1E85
+%7EF8F8767C76769A7C76769A7C76769A7C76769A7C76769A7C76769A7C76
+%769A51F87DFD08FFF827587D597D587D597D587D597D587D597D587D597D
+%587D597D587D597D587D597D587D597D587D597D2727FD09FF7DF8595959
+%5359595953595959535959595359595953595959535959595359592EF827
+%FD1FF8FD09FF27FD2AF87DFD09FFA8FD21F8FDFCFFFD83FFFF
+%%EndData
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset Adobe_level2_AI5 1.2 0
+%%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation)
+%%Version: 1.2 0
+%%CreationDate: (04/10/93) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+userdict /Adobe_level2_AI5 26 dict dup begin
+	put
+	/packedarray where not
+	{
+		userdict begin
+		/packedarray
+		{
+			array astore readonly
+		} bind def
+		/setpacking /pop load def
+		/currentpacking false def
+	 end
+		0
+	} if
+	pop
+	userdict /defaultpacking currentpacking put true setpacking
+	/initialize
+	{
+		Adobe_level2_AI5 begin
+	} bind def
+	/terminate
+	{
+		currentdict Adobe_level2_AI5 eq
+		{
+		 end
+		} if
+	} bind def
+	mark
+	/setcustomcolor where not
+	{
+		/findcmykcustomcolor
+		{
+			(AI8_CMYK_CustomColor)
+			6 packedarray
+		} bind def
+		/findrgbcustomcolor
+		{
+			(AI8_RGB_CustomColor)
+			5 packedarray
+		} bind def
+		/setcustomcolor
+		{
+			exch 
+			aload pop dup
+			(AI8_CMYK_CustomColor) eq
+			{
+				pop pop
+				4
+				{
+					4 index mul
+					4 1 roll
+				} repeat
+				5 -1 roll pop
+				setcmykcolor
+			}
+			{
+				dup (AI8_RGB_CustomColor) eq
+				{
+					pop pop
+					3
+					{
+						1 exch sub
+						3 index mul 
+						1 exch sub
+						3 1 roll
+					} repeat
+					4 -1 roll pop
+					setrgbcolor
+				}
+				{
+					pop
+					4
+					{
+						4 index mul 4 1 roll
+					} repeat
+					5 -1 roll pop
+					setcmykcolor
+				} ifelse
+			} ifelse
+		}
+		def
+	} if
+	/setAIseparationgray
+	{
+		false setoverprint
+		0 setgray
+		/setseparationgray where{
+			pop setseparationgray
+		}{
+			/setcolorspace where{
+				pop
+				[/Separation (All) /DeviceCMYK {dup dup dup}] setcolorspace
+				1 exch sub setcolor
+			}{
+				setgray
+			}ifelse
+		}ifelse
+	} def
+	
+	/gt38? mark {version cvr cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def
+	userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put
+	userdict /level2?
+	systemdict /languagelevel known dup
+	{
+		pop systemdict /languagelevel get 2 ge
+	} if
+	put
+/level2ScreenFreq
+{
+ begin
+		60
+		HalftoneType 1 eq
+		{
+			pop Frequency
+		} if
+		HalftoneType 2 eq
+		{
+			pop GrayFrequency
+		} if
+		HalftoneType 5 eq
+		{
+			pop Default level2ScreenFreq
+		} if
+ end
+} bind def
+userdict /currentScreenFreq  
+	level2? {currenthalftone level2ScreenFreq} {currentscreen pop pop} ifelse put
+level2? not
+	{
+		/setcmykcolor where not
+		{
+			/setcmykcolor
+			{
+				exch .11 mul add exch .59 mul add exch .3 mul add
+				1 exch sub setgray
+			} def
+		} if
+		/currentcmykcolor where not
+		{
+			/currentcmykcolor
+			{
+				0 0 0 1 currentgray sub
+			} def
+		} if
+		/setoverprint where not
+		{
+			/setoverprint /pop load def
+		} if
+		/selectfont where not
+		{
+			/selectfont
+			{
+				exch findfont exch
+				dup type /arraytype eq
+				{
+					makefont
+				}
+				{
+					scalefont
+				} ifelse
+				setfont
+			} bind def
+		} if
+		/cshow where not
+		{
+			/cshow
+			{
+				[
+				0 0 5 -1 roll aload pop
+				] cvx bind forall
+			} bind def
+		} if
+	} if
+	cleartomark
+	/anyColor?
+	{
+		add add add 0 ne
+	} bind def
+	/testColor
+	{
+		gsave
+		setcmykcolor currentcmykcolor
+		grestore
+	} bind def
+	/testCMYKColorThrough
+	{
+		testColor anyColor?
+	} bind def
+	userdict /composite?
+	1 0 0 0 testCMYKColorThrough
+	0 1 0 0 testCMYKColorThrough
+	0 0 1 0 testCMYKColorThrough
+	0 0 0 1 testCMYKColorThrough
+	and and and
+	put
+	composite? not
+	{
+		userdict begin
+		gsave
+		/cyan? 1 0 0 0 testCMYKColorThrough def
+		/magenta? 0 1 0 0 testCMYKColorThrough def
+		/yellow? 0 0 1 0 testCMYKColorThrough def
+		/black? 0 0 0 1 testCMYKColorThrough def
+		grestore
+		/isCMYKSep? cyan? magenta? yellow? black? or or or def
+		/customColor? isCMYKSep? not def
+	 end
+	} if
+ end defaultpacking setpacking
+%%EndResource
+%%BeginResource: procset Adobe_typography_AI5 1.0 1
+%%Title: (Typography Operators)
+%%Version: 1.0 1
+%%CreationDate:(6/10/1996) ()
+%%Copyright: ((C) 1987-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_typography_AI5 68 dict dup begin
+put
+/initialize
+{
+ begin
+ begin
+	Adobe_typography_AI5 begin
+	Adobe_typography_AI5
+	{
+		dup xcheck
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+ end
+ end
+	Adobe_typography_AI5 begin
+} def
+/terminate
+{
+	currentdict Adobe_typography_AI5 eq
+	{
+	 end
+	} if
+} def
+/modifyEncoding
+{
+	/_tempEncode exch ddef
+	/_pntr 0 ddef
+	{
+		counttomark -1 roll
+		dup type dup /marktype eq
+		{
+			pop pop exit
+		}
+		{
+			/nametype eq
+			{
+				_tempEncode /_pntr dup load dup 3 1 roll 1 add ddef 3 -1 roll
+				put
+			}
+			{
+				/_pntr exch ddef
+			} ifelse
+		} ifelse
+	} loop
+	_tempEncode
+} def
+/havefont
+{
+	systemdict /languagelevel known
+		{
+		/Font resourcestatus dup
+			{ exch pop exch pop }
+		if
+		}
+		{
+		systemdict /FontDirectory get 1 index known
+			{ pop true }
+			{
+			systemdict /fileposition known
+				{
+				dup length 6 add exch
+				Ss 6 250 getinterval
+				cvs pop
+				Ss exch 0 exch getinterval
+				status
+					{ pop pop pop pop true }
+					{ false }
+				ifelse
+				}
+				{
+				pop false
+				}
+			ifelse
+			}
+		ifelse
+		}
+	ifelse
+} def
+/TE
+{
+	StandardEncoding 256 array copy modifyEncoding
+	/_nativeEncoding exch def
+} def
+/subststring {
+	exch 2 index exch search
+	{
+		exch pop
+		exch dup () eq
+		{
+			pop exch concatstring
+		}
+		{
+			3 -1 roll
+			exch concatstring
+			concatstring
+		} ifelse
+		exch pop true
+	}
+	{
+		pop pop false
+	} ifelse
+} def
+/concatstring {
+	1 index length 1 index length
+	1 index add
+	string
+	dup 0 5 index putinterval
+	dup 2 index 4 index putinterval
+	4 1 roll pop pop pop
+} def
+%
+/TZ
+{
+	dup type /arraytype eq
+	{
+		/_wv exch def
+	}
+	{
+		/_wv 0 def
+	} ifelse
+	/_useNativeEncoding exch def
+	2 index havefont
+	{
+		3 index
+		255 string
+		cvs
+		
+		dup
+		(_Symbol_)
+		eq
+		{
+			pop
+			2 index
+			findfont
+			
+		}
+		{
+			1 index 0 eq
+			{
+				dup length 1 sub
+				1 exch
+				getinterval
+				
+				cvn
+				findfont
+			}
+			{
+				pop 2 index findfont
+			} ifelse
+		} ifelse
+	}
+	{
+		dup 1 eq
+		{
+			2 index 64 string cvs
+			dup (-90pv-RKSJ-) (-83pv-RKSJ-) subststring
+			{
+				exch pop dup havefont
+				{
+					findfont false
+				}
+				{
+					pop true
+				} ifelse
+			}
+			{
+				pop	dup
+				(-90ms-RKSJ-) (-Ext-RKSJ-) subststring
+				{
+					exch pop dup havefont
+					{
+						findfont false
+					}
+					{
+						pop true
+					} ifelse
+				}
+				{
+					pop pop true
+				} ifelse
+			} ifelse
+			{
+				1 index 1 eq
+				{
+					/Ryumin-Light-Ext-RKSJ-V havefont
+					{/Ryumin-Light-Ext-RKSJ-V}
+					{/Courier}
+					ifelse
+				}
+				{
+					/Ryumin-Light-83pv-RKSJ-H havefont
+					{/Ryumin-Light-83pv-RKSJ-H}
+					{/Courier}
+					ifelse
+				} ifelse
+				findfont
+				[1 0 0.5 1 0 0] makefont
+			} if
+		}
+		{
+			/Courier findfont
+		} ifelse
+	} ifelse
+	_wv type /arraytype eq
+	{
+		_wv makeblendedfont
+	} if
+	dup length 10 add dict
+ begin
+	mark exch
+	{
+		1 index /FID ne
+		{
+			def
+		} if
+		cleartomark mark
+	} forall
+	pop
+	/FontScript exch def
+	/FontDirection exch def
+	/FontRequest exch def
+	/FontName exch def
+	counttomark 0 eq
+	{
+		1 _useNativeEncoding eq
+		{
+			/Encoding _nativeEncoding def
+		} if
+		cleartomark
+	}
+	{
+		/Encoding load 256 array copy
+		modifyEncoding /Encoding exch def
+	} ifelse
+	FontName currentdict
+ end
+	definefont pop
+} def
+/tr
+{
+	_ax _ay 3 2 roll
+} def
+/trj
+{
+	_cx _cy _sp _ax _ay 6 5 roll
+} def
+/a0
+{
+	/Tx
+	{
+		dup
+		currentpoint 3 2 roll
+		tr _psf
+		newpath moveto
+		tr _ctm _pss
+	} ddef
+	/Tj
+	{
+		dup
+		currentpoint 3 2 roll
+		trj _pjsf
+		newpath moveto
+		trj _ctm _pjss
+	} ddef
+} def
+/a1
+{
+W B
+} def
+/e0
+{
+	/Tx
+	{
+		tr _psf
+	} ddef
+	/Tj
+	{
+		trj _pjsf
+	} ddef
+} def
+/e1
+{
+W F 
+} def
+/i0
+{
+	/Tx
+	{
+		tr sp
+	} ddef
+	/Tj
+	{
+		trj jsp
+	} ddef
+} def
+/i1
+{
+	W N
+} def
+/o0
+{
+	/Tx
+	{
+		tr sw rmoveto
+	} ddef
+	/Tj
+	{
+		trj swj rmoveto
+	} ddef
+} def
+/r0
+{
+	/Tx
+	{
+		tr _ctm _pss
+	} ddef
+	/Tj
+	{
+		trj _ctm _pjss
+	} ddef
+} def
+/r1
+{
+W S
+} def
+/To
+{
+	pop _ctm currentmatrix pop
+} def
+/TO
+{
+	iTe _ctm setmatrix newpath
+} def
+/Tp
+{
+	pop _tm astore pop _ctm setmatrix
+	_tDict begin
+	/W
+	{
+	} def
+	/h
+	{
+	} def
+} def
+/TP
+{
+ end
+	iTm 0 0 moveto
+} def
+/Tr
+{
+	_render 3 le
+	{
+		currentpoint newpath moveto
+	} if
+	dup 8 eq
+	{
+		pop 0
+	}
+	{
+		dup 9 eq
+		{
+			pop 1
+		} if
+	} ifelse
+	dup /_render exch ddef
+	_renderStart exch get load exec
+} def
+/iTm
+{
+	_ctm setmatrix _tm concat
+	_shift aload pop _lineorientation 1 eq { exch } if translate
+	_scale aload pop _lineorientation 1 eq _yokoorientation 1 eq or { exch } if scale
+} def
+/Tm
+{
+	_tm astore pop iTm 0 0 moveto
+} def
+/Td
+{
+	_mtx translate _tm _tm concatmatrix pop iTm 0 0 moveto
+} def
+/iTe
+{
+	_render -1 eq
+	{
+	}
+	{
+		_renderEnd _render get dup null ne
+		{
+			load exec
+		}
+		{
+			pop
+		} ifelse
+	} ifelse
+	/_render -1 ddef
+} def
+/Ta
+{
+	pop
+} def
+/Tf
+{
+	1 index type /nametype eq
+	{
+		dup 0.75 mul 1 index 0.25 mul neg
+	} if
+	/_fontDescent exch ddef
+	/_fontAscent exch ddef
+	/_fontSize exch ddef
+	/_fontRotateAdjust _fontAscent _fontDescent add 2 div neg ddef
+	/_fontHeight _fontSize ddef
+	findfont _fontSize scalefont setfont
+} def
+/Tl
+{
+	pop neg 0 exch
+	_leading astore pop
+} def
+/Tt
+{
+	pop
+} def
+/TW
+{
+	3 npop
+} def
+/Tw
+{
+	/_cx exch ddef
+} def
+/TC
+{
+	3 npop
+} def
+/Tc
+{
+	/_ax exch ddef
+} def
+/Ts
+{
+	0 exch
+	_shift astore pop
+	currentpoint
+	iTm
+	moveto
+} def
+/Ti
+{
+	3 npop
+} def
+/Tz
+{
+	count 1 eq { 100 } if
+	100 div exch 100 div exch
+	_scale astore pop
+	iTm
+} def
+/TA
+{
+	pop
+} def
+/Tq
+{
+	pop
+} def
+/Tg
+{
+	pop
+} def
+/TG
+{
+	pop
+} def
+/Tv
+{
+	/_lineorientation exch ddef
+} def
+/TV
+{
+	/_charorientation exch ddef
+} def
+/Ty
+{
+	dup /_yokoorientation exch ddef 1 sub neg Tv
+} def
+/TY
+{
+	pop
+} def
+/T~
+{
+	Tx
+} def
+/Th
+{
+	pop pop pop pop pop
+} def
+/TX
+{
+	pop
+} def
+/Tk
+{
+	_fontSize mul 1000 div
+	_lineorientation 0 eq { neg 0 } { 0 exch } ifelse
+	rmoveto
+	pop
+} def
+/TK
+{
+	2 npop
+} def
+/T*
+{
+	_leading aload pop
+	_lineorientation 0 ne { exch } if
+	Td
+} def
+/T*-
+{
+	_leading aload pop
+	_lineorientation 0 ne { exch } if
+	exch neg exch neg
+	Td
+} def
+/T-
+{
+	_ax neg 0 rmoveto
+	_lineorientation 1 eq _charorientation 0 eq and { 1 TV _hyphen Tx 0 TV } { _hyphen Tx } ifelse
+} def
+/T+
+{
+} def
+/TR
+{
+	_ctm currentmatrix pop
+	_tm astore pop
+	iTm 0 0 moveto
+} def
+/TS
+{
+	currentfont 3 1 roll
+	/_Symbol_ findfont _fontSize scalefont setfont
+	
+	0 eq
+	{
+		Tx
+	}
+	{
+		Tj
+	} ifelse
+	setfont
+} def
+/Xb
+{
+	pop pop
+} def
+/Tb /Xb load def
+/Xe
+{
+	pop pop pop pop
+} def
+/Te /Xe load def
+/XB
+{
+} def
+/TB /XB load def
+currentdict readonly pop
+end
+setpacking
+%
+/X^
+{
+	currentfont 5 1 roll
+	dup havefont
+		{
+		findfont _fontSize scalefont setfont
+		}
+		{
+		pop
+		exch
+		} ifelse
+	2 index 0 eq
+	{
+		Tx
+	}
+	{
+		Tj
+	} ifelse
+	pop	pop
+	setfont
+} def
+/T^	/X^	load def
+%%EndResource
+%%BeginProcSet: Adobe_ColorImage_AI6 1.3 0
+userdict /Adobe_ColorImage_AI6 known not
+{
+	userdict /Adobe_ColorImage_AI6 53 dict put 
+} if
+userdict /Adobe_ColorImage_AI6 get begin
+/initialize { 
+	Adobe_ColorImage_AI6 begin
+	Adobe_ColorImage_AI6 {
+		dup type /arraytype eq {
+			dup xcheck {
+				bind
+			} if
+		} if
+		pop pop
+	} forall
+} def
+/terminate { end } def
+currentdict /Adobe_ColorImage_AI6_Vars known not {
+	/Adobe_ColorImage_AI6_Vars 41 dict def
+} if
+Adobe_ColorImage_AI6_Vars begin
+	/plateindex -1 def
+	/_newproc null def
+	/_proc1 null def
+	/_proc2 null def
+	/sourcearray 4 array def
+	/_ptispace null def
+	/_ptiname null def
+	/_pti0 0 def
+	/_pti1 0 def
+	/_ptiproc null def
+	/_ptiscale 0 def
+	/_pticomps 0 def
+	/_ptibuf 0 string def
+	/_gtigray 0 def
+	/_cticmyk null def
+	/_rtirgb null def
+	/XIEnable true def
+	/XIType 0 def
+	/XIEncoding 0 def
+	/XICompression 0 def
+	/XIChannelCount 0 def
+	/XIBitsPerPixel 0 def
+	/XIImageHeight 0 def
+	/XIImageWidth 0 def
+	/XIImageMatrix null def
+	/XIRowBytes 0 def
+	/XIFile null def
+	/XIBuffer1 null def
+	/XIBuffer2 null def
+	/XIBuffer3 null def
+	/XIDataProc null def
+	/XIColorSpace /DeviceGray def
+	/XIColorValues 0 def
+	/XIPlateList false def
+end
+/ci6colorimage /colorimage where {/colorimage get}{null} ifelse def
+/ci6image systemdict /image get def
+/ci6curtransfer systemdict /currenttransfer get def
+/ci6curoverprint /currentoverprint where {/currentoverprint get}{{_of}} ifelse def
+/ci6foureq {
+	4 index ne {
+		pop pop pop false
+	}{
+		4 index ne {
+			pop pop false
+		}{
+			4 index ne {
+				pop false
+			}{
+				4 index eq
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6testplate {
+	Adobe_ColorImage_AI6_Vars begin
+		/plateindex -1 def
+		/setcmykcolor where {
+			pop
+			gsave
+			1 0 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 1 0 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 1 0 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			0 0 0 1 setcmykcolor systemdict /currentgray get exec 1 exch sub
+			grestore
+			1 0 0 0 ci6foureq { 
+				/plateindex 0 def
+			}{
+				0 1 0 0 ci6foureq { 
+					/plateindex 1 def
+				}{
+					0 0 1 0 ci6foureq {
+						/plateindex 2 def
+					}{
+						0 0 0 1 ci6foureq { 
+							/plateindex 3 def
+						}{
+							0 0 0 0 ci6foureq {
+								/plateindex 5 def
+							} if
+						} ifelse
+					} ifelse
+				} ifelse
+			} ifelse
+			pop pop pop pop
+		} if
+		plateindex
+ end
+} def
+/ci6concatprocs {
+	/packedarray where {
+		pop dup type /packedarraytype eq 2 index type
+		/packedarraytype eq or
+	}{
+		false
+	} ifelse
+	{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		_proc1 aload pop
+		_proc2 aload pop
+		_proc1 length
+		_proc2 length add
+		packedarray cvx
+	}{
+		/_proc2 exch cvlit def
+		/_proc1 exch cvlit def
+		/_newproc _proc1 length _proc2 length add array def
+		_newproc 0 _proc1 putinterval
+		_newproc _proc1 length _proc2 putinterval
+		_newproc cvx
+	} ifelse
+} def
+/ci6istint {
+	type /arraytype eq 
+} def
+/ci6isspot {
+	dup type /arraytype eq {
+		dup length 1 sub get /Separation eq
+	}{
+		pop false
+	} ifelse
+} def
+/ci6spotname {
+	dup ci6isspot {dup length 2 sub get}{pop ()} ifelse
+} def
+/ci6altspace {
+	aload pop pop pop ci6colormake
+} def
+/ci6numcomps {
+	dup /DeviceGray eq {
+		pop 1
+	}{
+		dup /DeviceRGB eq {
+			pop 3
+		}{
+			/DeviceCMYK eq {
+				4
+			}{
+				1
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6marksplate {
+	dup /DeviceGray eq {
+		pop plateindex 3 eq
+	}{
+		dup /DeviceRGB eq {
+			pop plateindex 5 ne
+		}{
+			dup /DeviceCMYK eq {
+				pop plateindex 5 ne
+			}{
+				dup ci6isspot {
+					/findcmykcustomcolor where {
+						pop
+						dup length 2 sub get
+						0.1 0.1 0.1 0.1 5 -1 roll
+						findcmykcustomcolor 1 setcustomcolor
+						systemdict /currentgray get exec
+						1 ne
+					}{
+						pop plateindex 5 ne
+					} ifelse
+				}{
+					pop plateindex 5 ne
+				} ifelse
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colormake {
+	dup ci6numcomps
+	exch 1 index 2 add 1 roll
+	dup 1 eq {pop}{array astore} ifelse
+	exch
+} def
+/ci6colorexpand {
+	dup ci6spotname exch
+	dup ci6istint {
+		ci6altspace
+		exch 4 1 roll
+	}{
+		1 3 1 roll
+	} ifelse
+} def
+/ci6colortint {
+	dup /DeviceGray eq {
+		3 1 roll 1 exch sub mul 1 exch sub exch
+	}{
+		dup /DeviceRGB eq {
+			3 1 roll {1 exch sub 1 index mul 1 exch sub exch} forall pop 3 array astore exch
+		}{
+			dup /DeviceCMYK eq {
+				3 1 roll {1 index mul exch} forall pop 4 array astore exch
+			}{
+				3 1 roll mul exch
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6colortocmyk {
+	dup /DeviceGray eq {
+		pop 1 exch sub 0 0 0 4 -1 roll 4 array astore
+	}{
+		dup /DeviceRGB eq {
+			pop aload pop _rgbtocmyk 4 array astore
+		}{
+			dup /DeviceCMYK eq {
+				pop
+			}{
+				ci6altspace ci6colortint ci6colortocmyk
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6makeimagedict {
+	7 dict begin
+		/ImageType 1 def
+		/Decode exch def
+		/DataSource exch def
+		/ImageMatrix exch def
+		/BitsPerComponent exch def
+		/Height exch def
+		/Width exch def
+	currentdict end
+} def
+/ci6stringinvert {
+	0 1 2 index length 1 sub {
+		dup 2 index exch get 255 exch sub 2 index 3 1 roll put
+	} for
+} def
+/ci6stringknockout {
+	0 1 2 index length 1 sub {
+		255 2 index 3 1 roll put
+	} for
+} def
+/ci6stringapply {
+	0 1 4 index length 1 sub {
+		dup
+		4 index exch get
+		3 index 3 1 roll
+		3 index exec
+	} for
+	pop exch pop
+} def
+/ci6walkrgbstring {
+	0 3 index
+	dup length 1 sub 0 3 3 -1 roll {
+		3 getinterval {} forall
+		5 index exec
+		3 index
+	} for
+	
+	 5 {pop} repeat
+} def
+/ci6walkcmykstring
+{
+	0 3 index
+	dup length 1 sub 0 4 3 -1 roll {
+		4 getinterval {} forall
+		
+		6 index exec
+		
+		3 index
+		
+	} for
+	
+	5 { pop } repeat
+	
+} def
+/ci6putrgbtograystr
+{
+	.11 mul exch
+	
+	.59 mul add exch
+	
+	.3 mul add
+	
+	cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6putcmyktograystr
+{
+	exch .11 mul add
+	
+	exch .59 mul add
+	
+	exch .3 mul add
+	
+	dup 255 gt { pop 255 } if
+	
+	255 exch sub cvi 3 copy put
+	
+	pop 1 add
+} def
+/ci6rgbtograyproc {	
+	Adobe_ColorImage_AI6_Vars begin 
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putrgbtograystr load exch
+		ci6walkrgbstring
+ end
+} def
+/ci6cmyktograyproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		XIBuffer3
+		dup 3 1 roll 
+		
+		/ci6putcmyktograystr load exch
+		ci6walkcmykstring
+ end
+} def
+/ci6separatecmykproc {	
+	Adobe_ColorImage_AI6_Vars begin
+		sourcearray 0 get exec
+		
+		XIBuffer3
+		
+		0 2 index
+		
+		plateindex 4 2 index length 1 sub {
+			get 255 exch sub
+			
+			3 copy put pop 1 add
+			
+			2 index
+		} for
+		pop pop exch pop
+ end
+} def
+	
+/ci6compositeimage {
+	dup 1 eq {
+		pop pop image
+	}{
+		/ci6colorimage load null ne {
+			ci6colorimage
+		}{
+			3 1 roll pop
+			sourcearray 0 3 -1 roll put
+			3 eq {/ci6rgbtograyproc}{/ci6cmyktograyproc} ifelse load
+			image
+		} ifelse
+	} ifelse
+} def
+/ci6knockoutimage {
+	gsave
+	0 ci6curtransfer exec 1 ci6curtransfer exec
+	eq {
+		0 ci6curtransfer exec 0.5 lt
+	}{
+		0 ci6curtransfer exec 1 ci6curtransfer exec gt
+	} ifelse
+	{{pop 0}}{{pop 1}} ifelse
+	systemdict /settransfer get exec
+	ci6compositeimage
+	grestore
+} def
+/ci6drawimage {
+	ci6testplate -1 eq {
+		pop ci6compositeimage
+	}{
+		dup type /arraytype eq {
+			dup length plateindex gt {plateindex get}{pop false} ifelse
+		}{
+			{
+				true
+			}{
+				dup 1 eq {plateindex 3 eq}{plateindex 3 le} ifelse
+			} ifelse
+		} ifelse
+		{
+			dup 1 eq {
+				pop pop ci6image
+			}{
+				dup 3 eq {
+					ci6compositeimage
+				}{
+					pop pop
+					sourcearray 0 3 -1 roll put
+					/ci6separatecmykproc load
+					ci6image
+				} ifelse
+			} ifelse
+		}{
+			ci6curoverprint {
+				7 {pop} repeat
+			}{
+				ci6knockoutimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6proctintimage {
+	/_ptispace exch store /_ptiname exch store /_pti1 exch store /_pti0 exch store /_ptiproc exch store
+	/_pticomps _ptispace ci6numcomps store
+	/_ptiscale _pti1 _pti0 sub store
+	level2? {
+		_ptiname length 0 gt version cvr 2012 ge and {
+			[/Separation _ptiname _ptispace {_ptiproc}] setcolorspace
+			[_pti0 _pti1] ci6makeimagedict ci6image
+		}{
+			[/Indexed _ptispace 255 {255 div _ptiscale mul _pti0 add _ptiproc}] setcolorspace
+			[0 255] ci6makeimagedict ci6image
+		} ifelse
+	}{
+		_pticomps 1 eq {
+			{
+				dup
+				{
+					255 div _ptiscale mul _pti0 add _ptiproc 255 mul cvi put
+				} ci6stringapply
+			} ci6concatprocs ci6image
+		}{
+			{
+				dup length _pticomps mul dup _ptibuf length ne {/_ptibuf exch string store}{pop} ifelse
+				_ptibuf {
+					exch _pticomps mul exch 255 div _ptiscale mul _pti0 add _ptiproc
+					_pticomps 2 add -2 roll
+					_pticomps 1 sub -1 0 {
+						1 index add 2 index exch
+						5 -1 roll
+						255 mul cvi put
+					} for
+					pop pop
+				} ci6stringapply
+			} ci6concatprocs false _pticomps
+			/ci6colorimage load null eq {7 {pop} repeat}{ci6colorimage} ifelse
+		} ifelse
+	} ifelse
+} def
+/ci6graytintimage {
+	/_gtigray 5 -1 roll store
+	{1 _gtigray sub mul 1 exch sub} 4 1 roll
+	/DeviceGray ci6proctintimage
+} def
+/ci6cmyktintimage {
+	/_cticmyk 5 -1 roll store
+	{_cticmyk {1 index mul exch} forall pop} 4 1 roll
+	/DeviceCMYK ci6proctintimage
+} def
+/ci6rgbtintimage {
+	/_rtirgb 5 -1 roll store
+	{_rtirgb {1 exch sub 1 index mul 1 exch sub exch} forall pop} 4 1 roll
+	/DeviceRGB ci6proctintimage
+} def
+/ci6tintimage {
+	ci6testplate -1 eq {
+		ci6colorexpand
+		3 -1 roll 5 -1 roll {0}{0 exch} ifelse 4 2 roll
+		dup /DeviceGray eq {
+			pop ci6graytintimage
+		}{
+			dup /DeviceRGB eq {
+				pop ci6rgbtintimage
+			}{
+				pop ci6cmyktintimage
+			} ifelse
+		} ifelse
+	}{
+		dup ci6marksplate {
+			plateindex 5 lt {
+				ci6colortocmyk plateindex get
+				dup 0 eq ci6curoverprint and {
+					7 {pop} repeat
+				}{
+					1 exch sub
+					exch {1 0}{0 1} ifelse () ci6graytintimage
+				} ifelse
+			}{
+				pop exch {0}{0 exch} ifelse 0 3 1 roll () ci6graytintimage
+			} ifelse
+		}{
+			ci6curoverprint {
+				8 {pop} repeat
+			}{
+				pop pop pop
+				{pop 1} 0 1 () /DeviceGray ci6proctintimage
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/XINullImage {
+} def
+/XIImageMask {
+	XIImageWidth XIImageHeight false
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	imagemask
+} def
+/XIImageTint {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	XIType 3 eq XIColorValues XIColorSpace ci6tintimage
+} def
+/XIImage {
+	XIImageWidth XIImageHeight XIBitsPerPixel
+	[XIImageWidth 0 0 XIImageHeight neg 0 0]
+	/XIDataProc load
+	false XIChannelCount XIPlateList ci6drawimage
+} def
+/XG {
+	pop pop
+} def
+/XF {
+	13 {pop} repeat
+} def
+/Xh {
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		/XIImageMatrix exch def
+		0 0 moveto
+		XIImageMatrix concat
+		XIImageWidth XIImageHeight scale
+		
+		/_lp /null ddef
+		_fc
+		/_lp /imagemask ddef
+ end
+} def
+/XH {
+	Adobe_ColorImage_AI6_Vars begin
+		grestore
+ end
+} def
+/XIEnable {
+	Adobe_ColorImage_AI6_Vars /XIEnable 3 -1 roll put
+} def
+/XC {
+	Adobe_ColorImage_AI6_Vars begin
+		ci6colormake
+		/XIColorSpace exch def
+		/XIColorValues exch def
+ end
+} def
+/XIPlates {
+	Adobe_ColorImage_AI6_Vars begin
+		/XIPlateList exch def
+ end
+} def
+/XI
+{
+	Adobe_ColorImage_AI6_Vars begin
+		gsave
+		/XIType exch def
+		cvi dup
+		256 idiv /XICompression exch store
+		256 mod /XIEncoding exch store
+		pop pop
+		/XIChannelCount exch def
+		/XIBitsPerPixel exch def
+		/XIImageHeight exch def
+		/XIImageWidth exch def
+		pop pop pop pop
+		/XIImageMatrix exch def
+		XIBitsPerPixel 1 eq {
+			XIImageWidth 8 div ceiling cvi
+		}{
+			XIImageWidth XIChannelCount mul
+		} ifelse
+		/XIRowBytes exch def
+		XIEnable {
+			/XIBuffer3 XIImageWidth string def
+			XICompression 0 eq {
+				/XIBuffer1 XIRowBytes string def
+				XIEncoding 0 eq {
+					{currentfile XIBuffer1 readhexstring pop}
+				}{
+					{currentfile XIBuffer1 readstring pop}
+				} ifelse
+			}{
+				/XIBuffer1 256 string def
+				/XIBuffer2 XIRowBytes string def
+				{currentfile XIBuffer1 readline pop (%) anchorsearch {pop} if}
+				/ASCII85Decode filter /DCTDecode filter
+				/XIFile exch def
+				{XIFile XIBuffer2 readstring pop}
+			} ifelse
+			/XIDataProc exch def
+			
+			XIType 1 ne {
+				0 setgray
+			} if
+			XIType 1 eq {
+				XIImageMask
+			}{
+				XIType 2 eq XIType 3 eq or {
+					XIImageTint
+				}{
+					XIImage
+				} ifelse
+			} ifelse
+		}{
+			XINullImage
+		} ifelse
+		/XIPlateList false def
+		grestore
+ end
+} def
+end
+%%EndProcSet
+%%BeginResource: procset Adobe_Illustrator_AI5 1.3 0
+%%Title: (Adobe Illustrator (R) Version 8.0 Full Prolog)
+%%Version: 1.3 0
+%%CreationDate: (3/7/1994) ()
+%%Copyright: ((C) 1987-1998 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_Illustrator_AI5_vars 112 dict dup begin
+put
+/_?cmyk false def
+/_eo false def
+/_lp /none def
+/_pf
+{
+} def
+/_ps
+{
+} def
+/_psf
+{
+} def
+/_pss
+{
+} def
+/_pjsf
+{
+} def
+/_pjss
+{
+} def
+/_pola 0 def
+/_doClip 0 def
+/cf currentflat def
+/_lineorientation 0 def
+/_charorientation 0 def
+/_yokoorientation 0 def
+/_tm matrix def
+/_renderStart
+[
+/e0 /r0 /a0 /o0 /e1 /r1 /a1 /i0
+] def
+/_renderEnd
+[
+null null null null /i1 /i1 /i1 /i1
+] def
+/_render -1 def
+/_shift [0 0] def
+/_ax 0 def
+/_ay 0 def
+/_cx 0 def
+/_cy 0 def
+/_leading
+[
+0 0
+] def
+/_ctm matrix def
+/_mtx matrix def
+/_sp 16#020 def
+/_hyphen (-) def
+/_fontSize 0 def
+/_fontAscent 0 def
+/_fontDescent 0 def
+/_fontHeight 0 def
+/_fontRotateAdjust 0 def
+/Ss 256 string def
+Ss 0 (fonts/) putinterval
+/_cnt 0 def
+/_scale [1 1] def
+/_nativeEncoding 0 def
+/_useNativeEncoding 0 def
+/_tempEncode 0 def
+/_pntr 0 def
+/_tDict 2 dict def
+/_hfname 100 string def
+/_hffound false def
+/Tx
+{
+} def
+/Tj
+{
+} def
+/CRender
+{
+} def
+/_AI3_savepage
+{
+} def
+/_gf null def
+/_cf 4 array def
+/_rgbf 3 array def
+/_if null def
+/_of false def
+/_fc
+{
+} def
+/_gs null def
+/_cs 4 array def
+/_rgbs 3 array def
+/_is null def
+/_os false def
+/_sc
+{
+} def
+/_pd 1 dict def
+/_ed 15 dict def
+/_pm matrix def
+/_fm null def
+/_fd null def
+/_fdd null def
+/_sm null def
+/_sd null def
+/_sdd null def
+/_i null def
+/_lobyte 0 def
+/_hibyte 0 def
+/_cproc null def
+/_cscript 0 def
+/_hvax 0 def
+/_hvay 0 def
+/_hvwb 0 def
+/_hvcx 0 def
+/_hvcy 0 def
+/_bitfont null def
+/_bitlobyte 0 def
+/_bithibyte 0 def
+/_bitkey null def
+/_bitdata null def
+/_bitindex 0 def
+/discardSave null def
+/buffer 256 string def
+/beginString null def
+/endString null def
+/endStringLength null def
+/layerCnt 1 def
+/layerCount 1 def
+/perCent (%) 0 get def
+/perCentSeen? false def
+/newBuff null def
+/newBuffButFirst null def
+/newBuffLast null def
+/clipForward? false def
+end
+userdict /Adobe_Illustrator_AI5 known not {
+	userdict /Adobe_Illustrator_AI5 100 dict put
+} if
+userdict /Adobe_Illustrator_AI5 get begin
+/initialize
+{
+	Adobe_Illustrator_AI5 dup begin
+	Adobe_Illustrator_AI5_vars begin
+	/_aicmykps where {pop /_?cmyk _aicmykps def}if
+	discardDict
+	{
+		bind pop pop
+	} forall
+	dup /nc get begin
+	{
+		dup xcheck 1 index type /operatortype ne and
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	newpath
+} def
+/terminate
+{
+ end
+ end
+} def
+/_
+null def
+/ddef
+{
+	Adobe_Illustrator_AI5_vars 3 1 roll put
+} def
+/xput
+{
+	dup load dup length exch maxlength eq
+	{
+		dup dup load dup
+		length 2 mul dict copy def
+	} if
+	load begin
+	def
+ end
+} def
+/npop
+{
+	{
+		pop
+	} repeat
+} def
+/hswj
+{
+	dup stringwidth 3 2 roll
+	{
+		_hvwb eq { exch _hvcx add exch _hvcy add } if
+		exch _hvax add exch _hvay add
+	} cforall
+} def
+/vswj
+{
+	0 0 3 -1 roll
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			dup cstring stringwidth 5 2 roll
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			4 -1 roll sub exch
+			3 -1 roll sub exch
+		}
+		{
+			_hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			exch _hvay sub exch _hvax sub
+			_fontHeight sub
+		} ifelse
+	} cforall
+} def
+/swj
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hswj } { vswj } ifelse
+} def
+/sw
+{
+	0 0 0 6 3 roll swj
+} def
+/vjss
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			gsave
+			false charpath currentpoint
+			5 index setmatrix stroke
+			grestore
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			gsave
+			2 index false charpath
+			6 index setmatrix stroke
+			grestore
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjss
+{
+	4 1 roll
+	{
+		dup cstring
+		gsave
+		false charpath currentpoint
+		5 index setmatrix stroke
+		grestore
+		moveto
+		_sp eq
+		{
+			5 index 5 index rmoveto
+		} if
+		2 copy rmoveto
+	} cforall
+	6 npop
+} def
+/jss
+{
+	_lineorientation 0 eq { hjss } { vjss } ifelse
+} def
+/ss
+{
+	0 0 0 7 3 roll jss
+} def
+/vjsp
+{
+	4 1 roll
+	{
+		dup cstring
+		dup length 1 eq
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			currentpoint
+			_fontRotateAdjust add
+			moveto
+			false charpath
+            currentpoint
+			_fontRotateAdjust sub
+			moveto
+			_sp eq
+			{
+				5 index 5 index rmoveto
+			} if
+			2 copy rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			5 index sub
+			3 index _sp eq
+			{
+				9 index sub
+			} if
+	
+			currentpoint
+			exch 4 index stringwidth pop 2 div sub
+			exch _fontAscent sub
+			moveto
+	
+			2 index false charpath
+	
+			moveto pop pop
+		} ifelse
+	} cforall
+	6 npop
+} def
+/hjsp
+{
+    4 1 roll
+    {
+        dup cstring
+        false charpath
+        _sp eq
+        {
+            5 index 5 index rmoveto
+        } if
+        2 copy rmoveto
+    } cforall
+    6 npop
+} def
+/jsp
+{
+	matrix currentmatrix
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/sp
+{
+    matrix currentmatrix
+    0 0 0 7 3 roll
+    _lineorientation 0 eq {hjsp} {vjsp} ifelse
+} def
+/pl
+{
+	transform
+	0.25 sub round 0.25 add exch
+	0.25 sub round 0.25 add exch
+	itransform
+} def
+/setstrokeadjust where
+{
+	pop true setstrokeadjust
+	/c
+	{
+		curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		moveto
+	} def
+}
+{
+	/c
+	{
+		pl curveto
+	} def
+	/C
+	/c load def
+	/v
+	{
+		currentpoint 6 2 roll pl curveto
+	} def
+	/V
+	/v load def
+	/y
+	{
+		pl 2 copy curveto
+	} def
+	/Y
+	/y load def
+	/l
+	{
+		pl lineto
+	} def
+	/L
+	/l load def
+	/m
+	{
+		pl moveto
+	} def
+} ifelse
+/d
+{
+	setdash
+} def
+/cf
+{
+} def
+/i
+{
+	dup 0 eq
+	{
+		pop cf
+	} if
+	setflat
+} def
+/j
+{
+	setlinejoin
+} def
+/J
+{
+	setlinecap
+} def
+/M
+{
+	setmiterlimit
+} def
+/w
+{
+	setlinewidth
+} def
+/XR
+{
+	0 ne
+	/_eo exch ddef
+} def
+/H
+{
+} def
+/h
+{
+	closepath
+} def
+/N
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			_eo {eoclip} {clip} ifelse /_doClip 0 ddef
+		} if
+		newpath
+	}
+	{
+		/CRender
+		{
+			N
+		} ddef
+	} ifelse
+} def
+/n
+{
+	N
+} def
+/F
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _pf grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _fc
+			/_doClip 0 ddef
+		}
+		{
+			_pf
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			F
+		} ddef
+	} ifelse
+} def
+/f
+{
+	closepath
+	F
+} def
+/S
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		{
+			gsave _ps grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			_ps
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			S
+		} ddef
+	} ifelse
+} def
+/s
+{
+	closepath
+	S
+} def
+/B
+{
+	_pola 0 eq
+	{
+		_doClip 1 eq
+		gsave F grestore
+		{
+			gsave S grestore _eo {eoclip} {clip} ifelse newpath /_lp /none ddef _sc
+			/_doClip 0 ddef
+		}
+		{
+			S
+		} ifelse
+	}
+	{
+		/CRender
+		{
+			B
+		} ddef
+	} ifelse
+} def
+/b
+{
+	closepath
+	B
+} def
+/W
+{
+	/_doClip 1 ddef
+} def
+/*
+{
+	count 0 ne
+	{
+		dup type /stringtype eq
+		{
+			pop
+		} if
+	} if
+	newpath
+} def
+/u
+{
+} def
+/U
+{
+} def
+/q
+{
+	_pola 0 eq
+	{
+		gsave
+	} if
+} def
+/Q
+{
+	_pola 0 eq
+	{
+		grestore
+	} if
+} def
+/*u
+{
+	_pola 1 add /_pola exch ddef
+} def
+/*U
+{
+	_pola 1 sub /_pola exch ddef
+	_pola 0 eq
+	{
+		CRender
+	} if
+} def
+/D
+{
+	pop
+} def
+/*w
+{
+} def
+/*W
+{
+} def
+/`
+{
+	/_i save ddef
+	clipForward?
+	{
+		nulldevice
+	} if
+	6 1 roll 4 npop
+	concat pop
+	userdict begin
+	/showpage
+	{
+	} def
+	0 setgray
+	0 setlinecap
+	1 setlinewidth
+	0 setlinejoin
+	10 setmiterlimit
+	[] 0 setdash
+	/setstrokeadjust where {pop false setstrokeadjust} if
+	newpath
+	0 setgray
+	false setoverprint
+} def
+/~
+{
+ end
+	_i restore
+} def
+/_rgbtocmyk
+{
+	3
+	{
+		1 exch sub 3 1 roll
+	} repeat
+	3 copy 1 4 1 roll
+	3
+	{
+		3 index 2 copy gt
+		{
+			exch
+		} if
+		pop 4 1 roll
+	} repeat
+	pop pop pop
+	4 1 roll
+	3
+	{
+		3 index sub
+		3 1 roll
+	} repeat
+	4 -1 roll
+} def
+/setrgbfill
+{
+	_rgbf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_rgbf aload pop setrgbcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/setrgbstroke
+{
+	_rgbs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_rgbs aload pop setrgbcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/O
+{
+	0 ne
+	/_of exch ddef
+	/_lp /none ddef
+} def
+/R
+{
+	0 ne
+	/_os exch ddef
+	/_lp /none ddef
+} def
+/g
+{
+	/_gf exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/G
+{
+	/_gs exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/k
+{
+	_cf astore pop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_cf aload pop setcmykcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/K
+{
+	_cs astore pop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_cs aload pop setcmykcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xa
+{
+	_?cmyk {
+		3 npop k
+	}{
+		setrgbfill 4 npop
+	} ifelse
+} def
+/XA
+{
+	_?cmyk {
+		3 npop K
+	}{
+		setrgbstroke 4 npop
+	} ifelse
+} def
+/Xs
+{
+	/_gf exch ddef
+	5 npop
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_gf setAIseparationgray
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XS
+{
+	/_gs exch ddef
+	5 npop
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_gs setAIseparationgray
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/Xx
+{
+	exch
+	/_gf exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/XX
+{
+	exch
+	/_gs exch ddef
+	0 eq {
+		findcmykcustomcolor
+	}{
+		_?cmyk {true}{/findrgbcustomcolor where{pop false}{true}ifelse}ifelse
+		{
+			4 1 roll 3 npop
+			findcmykcustomcolor
+		}{
+			8 -4 roll 4 npop
+			findrgbcustomcolor
+		} ifelse
+	} ifelse
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/x
+{
+	/_gf exch ddef
+	findcmykcustomcolor
+	/_if exch ddef
+	/_fc
+	{
+		_lp /fill ne
+		{
+			_of setoverprint
+			_if _gf 1 exch sub setcustomcolor
+			/_lp /fill ddef
+		} if
+	} ddef
+	/_pf
+	{
+		_fc
+		_eo {eofill} {fill} ifelse
+	} ddef
+	/_psf
+	{
+		_fc
+		hvashow
+	} ddef
+	/_pjsf
+	{
+		_fc
+		hvawidthshow
+	} ddef
+	/_lp /none ddef
+} def
+/X
+{
+	/_gs exch ddef
+	findcmykcustomcolor
+	/_is exch ddef
+	/_sc
+	{
+		_lp /stroke ne
+		{
+			_os setoverprint
+			_is _gs 1 exch sub setcustomcolor
+			/_lp /stroke ddef
+		} if
+	} ddef
+	/_ps
+	{
+		_sc
+		stroke
+	} ddef
+	/_pss
+	{
+		_sc
+		ss
+	} ddef
+	/_pjss
+	{
+		_sc
+		jss
+	} ddef
+	/_lp /none ddef
+} def
+/XK
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		K
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		XA
+	} ifelse
+} def
+/Xk
+{
+	3 -1 roll pop
+	0 eq
+	{
+		1 exch sub
+		3 {dup 3 1 roll mul 5 1 roll} repeat
+		mul 4 1 roll
+		k
+	}
+	{
+		1 exch sub 4 1 roll
+		3 {1 exch sub 3 index mul 1 exch sub 3 1 roll} repeat
+		4 -1 roll pop
+		Xa
+	} ifelse
+} def
+/A
+{
+	pop
+} def
+/annotatepage
+{
+userdict /annotatepage 2 copy known {get exec} {pop pop} ifelse
+} def
+/XT {
+	pop pop
+} def
+/Xt {
+	pop
+} def
+/discard
+{
+	save /discardSave exch store
+	discardDict begin
+	/endString exch store
+	gt38?
+	{
+		2 add
+	} if
+	load
+	stopped
+	pop
+ end
+	discardSave restore
+} bind def
+userdict /discardDict 7 dict dup begin
+put
+/pre38Initialize
+{
+	/endStringLength endString length store
+	/newBuff buffer 0 endStringLength getinterval store
+	/newBuffButFirst newBuff 1 endStringLength 1 sub getinterval store
+	/newBuffLast newBuff endStringLength 1 sub 1 getinterval store
+} def
+/shiftBuffer
+{
+	newBuff 0 newBuffButFirst putinterval
+	newBuffLast 0
+	currentfile read not
+	{
+	stop
+	} if
+	put
+} def
+0
+{
+	pre38Initialize
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff endString eq
+			{
+				cleartomark stop
+			} if
+			shiftBuffer
+		} loop
+	}
+	{
+	stop
+	} ifelse
+} def
+1
+{
+	pre38Initialize
+	/beginString exch store
+	mark
+	currentfile newBuff readstring exch pop
+	{
+		{
+			newBuff beginString eq
+			{
+				/layerCount dup load 1 add store
+			}
+			{
+				newBuff endString eq
+				{
+					/layerCount dup load 1 sub store
+					layerCount 0 eq
+					{
+						cleartomark stop
+					} if
+				} if
+			} ifelse
+			shiftBuffer
+		} loop
+	} if
+} def
+2
+{
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			endString eq {
+				cleartomark stop
+			} if
+		}ifelse
+	} loop
+} def
+3
+{
+	/beginString exch store
+	/layerCnt 1 store
+	mark
+	{
+		currentfile buffer {readline} stopped {
+			% assume error was due to overfilling the buffer
+		}{
+			not
+			{
+				stop
+			} if
+			dup beginString eq
+			{
+				pop /layerCnt dup load 1 add store
+			}
+			{
+				endString eq
+				{
+					layerCnt 1 eq
+					{
+						cleartomark stop
+					}
+					{
+						/layerCnt dup load 1 sub store
+					} ifelse
+				} if
+			} ifelse
+		}ifelse
+	} loop
+} def
+end
+userdict /clipRenderOff 15 dict dup begin
+put
+{
+	/n /N /s /S /f /F /b /B
+}
+{
+	{
+		_doClip 1 eq
+		{
+			/_doClip 0 ddef _eo {eoclip} {clip} ifelse
+		} if
+		newpath
+	} def
+} forall
+/Tr /pop load def
+/Bb {} def
+/BB /pop load def
+/Bg {12 npop} def
+/Bm {6 npop} def
+/Bc /Bm load def
+/Bh {4 npop} def
+end
+/Lb
+{
+	6 npop
+	7 2 roll
+	5 npop
+	0 eq
+	{
+		0 eq
+		{
+			(%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard
+		}
+		{
+			
+			/clipForward? true def
+			
+			/Tx /pop load def
+			/Tj /pop load def
+			
+			currentdict end clipRenderOff begin begin
+		} ifelse
+	}
+	{
+		0 eq
+		{
+			save /discardSave exch store
+		} if
+	} ifelse
+} bind def
+/LB
+{
+	discardSave dup null ne
+	{
+		restore
+	}
+	{
+		pop
+		clipForward?
+		{
+			currentdict
+		 end
+		 end
+		 begin
+					
+			/clipForward? false ddef
+		} if
+	} ifelse
+} bind def
+/Pb
+{
+	pop pop
+	0 (%AI5_EndPalette) discard
+} bind def
+/Np
+{
+	0 (%AI5_End_NonPrinting--) discard
+} bind def
+/Ln /pop load def
+/Ap
+/pop load def
+/Ar
+{
+	72 exch div
+	0 dtransform dup mul exch dup mul add sqrt
+	dup 1 lt
+	{
+		pop 1
+	} if
+	setflat
+} def
+/Mb
+{
+	q
+} def
+/Md
+{
+} def
+/MB
+{
+	Q
+} def
+/nc 4 dict def
+nc begin
+/setgray
+{
+	pop
+} bind def
+/setcmykcolor
+{
+	4 npop
+} bind def
+/setrgbcolor
+{
+	3 npop
+} bind def
+/setcustomcolor
+{
+	2 npop
+} bind def
+currentdict readonly pop
+end
+/XP
+{
+	4 npop
+} bind def
+/XD
+{
+	pop
+} bind def
+end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_cshow 2.0 8
+%%Title: (Writing System Operators)
+%%Version: 2.0 8
+%%CreationDate: (1/23/89) ()
+%%Copyright: ((C) 1992-1996 Adobe Systems Incorporated All Rights Reserved)
+currentpacking true setpacking
+userdict /Adobe_cshow 14 dict dup begin put
+/initialize
+{
+	Adobe_cshow begin
+	Adobe_cshow
+	{
+		dup xcheck
+		{
+			bind
+		} if
+		pop pop
+	} forall
+ end
+	Adobe_cshow begin
+} def
+/terminate
+{
+currentdict Adobe_cshow eq
+	{
+ end
+	} if
+} def
+/cforall
+{
+	/_lobyte 0 ddef
+	/_hibyte 0 ddef
+	/_cproc exch ddef
+	/_cscript currentfont /FontScript known { currentfont /FontScript get } { -1 } ifelse ddef
+	{
+		/_lobyte exch ddef
+		_hibyte 0 eq
+		_cscript 1 eq
+		_lobyte 129 ge _lobyte 159 le and
+		_lobyte 224 ge _lobyte 252 le and or and
+		_cscript 2 eq
+		_lobyte 161 ge _lobyte 254 le and and
+		_cscript 3 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript 25 eq
+		_lobyte 161 ge _lobyte 254 le and and
+    	_cscript -1 eq
+		or or or or and
+		{
+			/_hibyte _lobyte ddef
+		}
+		{
+			_hibyte 256 mul _lobyte add
+			_cproc
+			/_hibyte 0 ddef
+		} ifelse
+	} forall
+} def
+/cstring
+{
+	dup 256 lt
+	{
+		(s) dup 0 4 3 roll put
+	}
+	{
+		dup 256 idiv exch 256 mod
+		(hl) dup dup 0 6 5 roll put 1 4 3 roll put
+	} ifelse
+} def
+/clength
+{
+	0 exch
+	{ 256 lt { 1 } { 2 } ifelse add } cforall
+} def
+/hawidthshow
+{
+	{
+		dup cstring
+		show
+		_hvax _hvay rmoveto
+		_hvwb eq { _hvcx _hvcy rmoveto } if
+	} cforall
+} def
+/vawidthshow
+{
+	{
+		dup 255 le
+		_charorientation 1 eq
+		and
+		{
+			-90 rotate
+			0 _fontRotateAdjust rmoveto
+			cstring
+			_hvcx _hvcy _hvwb _hvax _hvay 6 -1 roll awidthshow
+			0 _fontRotateAdjust neg rmoveto
+			90 rotate
+		}
+		{
+			currentpoint
+			_fontHeight sub
+			exch _hvay sub exch _hvax sub
+			2 index _hvwb eq { exch _hvcy sub exch _hvcx sub } if
+			3 2 roll
+			cstring
+			dup stringwidth pop 2 div neg _fontAscent neg rmoveto
+			show
+			moveto
+		} ifelse
+	} cforall
+} def
+/hvawidthshow
+{
+	6 1 roll
+	/_hvay exch ddef
+	/_hvax exch ddef
+	/_hvwb exch ddef
+	/_hvcy exch ddef
+	/_hvcx exch ddef
+	_lineorientation 0 eq { hawidthshow } { vawidthshow } ifelse
+} def
+/hvwidthshow
+{
+	0 0 3 -1 roll hvawidthshow
+} def
+/hvashow
+{
+	0 0 0 6 -3 roll hvawidthshow
+} def
+/hvshow
+{
+	0 0 0 0 0 6 -1 roll hvawidthshow
+} def
+currentdict readonly pop end
+setpacking
+%%EndResource
+%%BeginResource: procset Adobe_shading_AI8 1.0 0
+%%Title: (Adobe Illustrator 8 Shading Procset)
+%%Version: 1.0 0
+%%CreationDate: (12/17/97) ()
+%%Copyright: ((C) 1987-1997 Adobe Systems Incorporated All Rights Reserved)
+userdict /defaultpacking currentpacking put true setpacking
+userdict /Adobe_shading_AI8 10 dict dup begin put
+/initialize {
+	Adobe_shading_AI8 begin
+	Adobe_shading_AI8 bdprocs
+	Mesh /initialize get exec
+} def
+/terminate {
+	currentdict Adobe_shading_AI8 eq {
+	 end
+	} if
+} def
+/bdprocs {
+	{
+		dup xcheck 1 index type /arraytype eq and {
+			bind
+		} if
+		pop pop
+	} forall
+} def
+/X! {pop} def
+/X# {pop pop} def
+/Mesh 40 dict def
+Mesh begin
+/initialize {
+	Mesh bdprocs
+	Mesh begin
+		/emulate? /AI8MeshEmulation where {
+			pop AI8MeshEmulation
+		}{
+			systemdict /shfill known not
+		} ifelse def
+ end
+} def
+/bd {
+	shadingdict begin
+} def
+/paint {
+	emulate? {
+	 end
+	}{
+		/_lp /none ddef _fc /_lp /none ddef
+		
+		/AIColorSpace AIColorSpace tocolorspace store
+		/ColorSpace AIColorSpace topsspace store
+		
+		version_ge_3010.106 not systemdict /setsmoothness known and {
+			0.0001 setsmoothness
+		} if
+		
+		composite? {
+			/DataSource getdatasrc def
+			Matrix concat
+			currentdict end
+			shfill
+		}{
+			AIColorSpace makesmarks AIPlateList markingplate and not isoverprint and {
+			 end
+			}{
+				/ColorSpace /DeviceGray store
+				/Decode [0 1 0 1 0 1] store
+				/DataSource getplatesrc def
+				Matrix concat
+				currentdict end
+				shfill
+			} ifelse
+		} ifelse
+	} ifelse
+} def
+/shadingdict 12 dict def
+shadingdict begin
+	/ShadingType 6 def
+	/BitsPerCoordinate 16 def
+	/BitsPerComponent 8 def
+	/BitsPerFlag 8 def
+end
+/datafile null def
+/databuf 256 string def
+/dataptr 0 def
+/srcspace null def
+/srcchannels 0 def
+/dstchannels 0 def
+/dstplate 0 def
+/srctodstcolor null def
+/getplatesrc {
+	/srcspace AIColorSpace store
+	/srcchannels AIColorSpace getnchannels store
+	/dstchannels 1 store
+	/dstplate getplateindex store
+	/srctodstcolor srcspace makesmarks {
+		dstplate 4 eq {
+			{1 exch sub}
+		}{
+			{srcspace tocmyk 3 dstplate sub index 1 exch sub 5 1 roll 4 {pop} repeat}
+		} ifelse
+	}{
+		{srcchannels {pop} repeat 1}
+	} ifelse store
+	/datafile getdatasrc store
+	/rdpatch168 load DataLength () /SubFileDecode filter
+} def
+/getdatasrc {
+	/rdcmntline load /ASCII85Decode filter
+} def
+/rdpatch168 {
+	/dataptr 0 store
+	49 rdcount
+	4 {
+		dup {pop srcchannels getint8} if
+		dup {pop srctodstcolor dstchannels putint8 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdpatch3216 {
+	/dataptr 0 store
+	97 rdcount
+	4 {
+		dup {pop srcchannels getint16} if
+		dup {pop srctodstcolor dstchannels putint16 true} if
+	} repeat
+	{databuf 0 dataptr getinterval}{()} ifelse
+} def
+/rdcount {
+	dup 0 gt {
+		datafile databuf dataptr 4 -1 roll getinterval readstring
+		exch length dataptr add /dataptr exch store
+	}{
+		true
+	} ifelse
+} def
+/getint8 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 255 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint8 {
+	dup dataptr add /dataptr exch store
+	dataptr exch
+	{
+		1 sub exch
+		255 mul cvi
+		databuf 2 index
+		3 -1 roll put
+	} repeat
+	pop
+} def 
+/getint16 {
+	mark true 3 -1 roll
+	{
+		dup {pop datafile read} if
+		dup {pop 256 mul datafile read} if
+		dup {pop add 65535 div true} if
+	} repeat
+	{
+		counttomark 1 add -1 roll pop true
+	}{
+		cleartomark false
+	} ifelse
+} def
+/putint16 {
+	dup 2 mul dataptr add /dataptr exch store
+	dataptr exch
+	{
+		2 sub exch
+		65535 mul cvi dup
+		256 idiv databuf 3 index 3 -1 roll put
+		256 mod databuf 2 index 1 add 3 -1 roll put
+	} repeat
+	pop
+} def 
+/srcbuf 256 string def
+/rdcmntline {
+	currentfile srcbuf readline pop
+	(%) anchorsearch {pop} if
+} def
+/getplateindex {
+	0 [cyan? magenta? yellow? black? customColor?] {{exit} if 1 add} forall
+} def
+/aicsarray 4 array def
+/aicsaltvals 4 array def
+/aicsaltcolr aicsaltvals def
+/tocolorspace {
+	dup type /arraytype eq {
+		mark exch aload pop
+		aicsarray 0 3 -1 roll put
+		aicsarray 1 3 -1 roll put
+		dup aicsarray 2 3 -1 roll put
+		gettintxform aicsarray 3 3 -1 roll put
+		counttomark aicsaltvals 0 3 -1 roll getinterval /aicsaltcolr exch store
+		aicsaltcolr astore pop pop
+		aicsarray
+	} if
+} def
+/subtintxform {aicsaltcolr {1 index mul exch} forall pop} def
+/addtintxform {aicsaltcolr {1 sub 1 index mul 1 add exch} forall pop} def
+/gettintxform {
+	/DeviceRGB eq {/addtintxform}{/subtintxform} ifelse load
+} def
+/getnchannels {
+	dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin Channels end
+} def
+/makesmarks {
+	composite? {
+		pop true
+	}{
+		dup dup type /arraytype eq {0 get} if
+		colorspacedict exch get begin MarksPlate end
+	} ifelse
+} def
+/markingplate {
+	composite? {
+		pop true
+	}{
+		dup type /arraytype eq {
+			dup length getplateindex gt {getplateindex get}{pop false} ifelse
+		} if
+	} ifelse
+} def
+/tocmyk {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToCMYK end
+} def
+/topsspace {
+	dup dup type /arraytype eq {0 get} if
+	colorspacedict exch get begin ToPSSpace end
+} def
+/colorspacedict 5 dict dup begin
+	/DeviceGray 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {pop black?} def
+		/ToCMYK {pop 1 exch sub 0 0 0 4 -1 roll} def
+		/ToPSSpace {} def
+ end def
+	/DeviceRGB 4 dict dup begin
+		/Channels 3 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop _rgbtocmyk} def
+		/ToPSSpace {} def
+ end def
+	/DeviceCMYK 4 dict dup begin
+		/Channels 4 def
+		/MarksPlate {pop isCMYKSep?} def
+		/ToCMYK {pop} def
+		/ToPSSpace {} def
+ end def
+	/Separation 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			/findcmykcustomcolor where {
+				pop dup 1 exch ToCMYK 5 -1 roll 1 get
+				findcmykcustomcolor 1 setcustomcolor
+				systemdict /currentgray get exec
+				1 ne
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {} def
+ end def
+	/Process 4 dict dup begin
+		/Channels 1 def
+		/MarksPlate {
+			isCMYKSep? {
+				1 exch ToCMYK 4 array astore getplateindex get 0 ne 
+			}{
+				pop false
+			} ifelse
+		} def
+		/ToCMYK {
+			dup 2 get mark exch 4 2 roll
+			3 get exec
+			counttomark -1 roll tocmyk
+			5 -1 roll pop
+		} def
+		/ToPSSpace {
+			4 array copy dup 0 /Separation put
+		} def
+ end def
+end def
+/isoverprint {
+	/currentoverprint where {pop currentoverprint}{_of} ifelse
+} def
+/version_ge_3010.106 {
+   version {cvr} stopped {
+      pop
+      false
+   }{
+      3010.106 ge
+   } ifelse
+} def
+end
+end
+defaultpacking setpacking
+%%EndResource
+%%EndProlog
+%%BeginSetup
+%%IncludeFont: Helvetica
+userdict /_useSmoothShade false put
+userdict /_aicmykps false put
+userdict /_forceToCMYK false put
+Adobe_level2_AI5 /initialize get exec
+Adobe_cshow /initialize get exec
+Adobe_Illustrator_AI5_vars Adobe_Illustrator_AI5 Adobe_typography_AI5 /initialize get exec
+Adobe_ColorImage_AI6 /initialize get exec
+Adobe_shading_AI8 /initialize get exec
+Adobe_Illustrator_AI5 /initialize get exec
+[
+39/quotesingle 96/grave 130/quotesinglbase/florin/quotedblbase/ellipsis
+/dagger/daggerdbl/circumflex/perthousand/Scaron/guilsinglleft/OE 145/quoteleft
+/quoteright/quotedblleft/quotedblright/bullet/endash/emdash/tilde/trademark
+/scaron/guilsinglright/oe/dotlessi 159/Ydieresis /space 164/currency 166/brokenbar
+168/dieresis/copyright/ordfeminine 172/logicalnot/hyphen/registered/macron/ring
+/plusminus/twosuperior/threesuperior/acute/mu 183/periodcentered/cedilla
+/onesuperior/ordmasculine 188/onequarter/onehalf/threequarters 192/Agrave
+/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute
+/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde
+/Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave
+/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/agrave/aacute
+/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute/ecircumflex
+/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute
+/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis
+TE
+%AI55J_Tsume: None
+%AI3_BeginEncoding: _Helvetica Helvetica
+[/_Helvetica/Helvetica 0 0 1 TZ%AI3_EndEncoding AdobeType
+%AI5_Begin_NonPrinting
+Np
+%AI3_BeginPattern: (Brick)
+(Brick) 0 0 72 72 [
+%AI3_Tile
+(0 O 0 R 0.3 0.85 0.85 0 k
+ 0.3 0.85 0.85 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+0 0 m
+0 72 L
+72 72 L
+72 0 L
+0 0 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 0.3 w 4 M []0 d%AI3_Note:0 D
+0 XR
+0 68.4097 m
+72 68.4097 l
+S0 61.209 m
+72 61.209 L
+S0 54.0088 m
+72 54.0088 L
+S0 46.8076 m
+72 46.8076 L
+S0 39.6084 m
+72 39.6084 L
+S0 32.4072 m
+72 32.4072 L
+S0 25.207 m
+72 25.207 L
+S0 18.0059 m
+72 18.0059 L
+S0 10.8057 m
+72 10.8057 L
+S0 3.6064 m
+72 3.6064 L
+S68.4102 68.4097 m
+68.4102 61.2217 l
+S54.0098 68.4097 m
+54.0098 61.2217 L
+S39.6094 68.4097 m
+39.6094 61.2217 L
+S25.21 68.4097 m
+25.21 61.2217 L
+S10.8105 68.4097 m
+10.8105 61.2217 L
+S68.4102 53.9717 m
+68.4102 46.7842 l
+S54.0098 53.9717 m
+54.0098 46.7842 L
+S39.6094 53.9717 m
+39.6094 46.7842 L
+S25.21 53.9717 m
+25.21 46.7842 L
+S10.8105 53.9717 m
+10.8105 46.7842 L
+S68.4102 39.5967 m
+68.4102 32.4092 l
+S54.0098 39.5967 m
+54.0098 32.4092 L
+S39.6094 39.5967 m
+39.6094 32.4092 L
+S25.21 39.5967 m
+25.21 32.4092 L
+S10.8105 39.5967 m
+10.8105 32.4092 L
+S68.4102 25.2217 m
+68.4102 18.0342 l
+S54.0098 25.2217 m
+54.0098 18.0342 L
+S39.6094 25.2217 m
+39.6094 18.0342 L
+S25.21 25.2217 m
+25.21 18.0342 L
+S10.8105 25.2217 m
+10.8105 18.0342 L
+S68.4102 10.7842 m
+68.4102 3.5967 l
+S54.0098 10.7842 m
+54.0098 3.5967 L
+S39.6094 10.7842 m
+39.6094 3.5967 L
+S25.21 10.7842 m
+25.21 3.5967 L
+S10.8105 10.7842 m
+10.8105 3.5967 L
+S61.1973 3.5967 m
+61.1973 0 L
+S46.7969 3.5967 m
+46.7969 0 L
+S32.3965 3.5967 m
+32.3965 0 L
+S17.9971 3.5967 m
+17.9971 0 L
+S3.5967 3.5967 m
+3.5967 0 l
+S61.1973 18.0342 m
+61.1973 10.8467 L
+S46.7969 18.0342 m
+46.7969 10.8467 L
+S32.3965 18.0342 m
+32.3965 10.8467 L
+S17.9971 18.0342 m
+17.9971 10.8467 L
+S3.5967 18.0342 m
+3.5967 10.8467 l
+S61.1973 32.4092 m
+61.1973 25.2217 L
+S46.7969 32.4092 m
+46.7969 25.2217 L
+S17.9971 32.4092 m
+17.9971 25.2217 L
+S3.5967 32.4092 m
+3.5967 25.2217 l
+S61.1973 46.7842 m
+61.1973 39.5967 L
+S46.7969 46.7842 m
+46.7969 39.5967 L
+S32.3965 46.7842 m
+32.3965 39.5967 L
+S17.9971 46.7842 m
+17.9971 39.5967 L
+S3.5967 46.7842 m
+3.5967 39.5967 l
+S61.1973 61.2217 m
+61.1973 54.0347 L
+S46.7969 61.2217 m
+46.7969 54.0347 L
+S32.3965 61.2217 m
+32.3965 54.0347 L
+S17.9971 61.2217 m
+17.9971 54.0347 L
+S3.5967 61.2217 m
+3.5967 54.0347 l
+S61.1973 71.959 m
+61.1973 68.4717 L
+S46.7969 71.959 m
+46.7969 68.4717 L
+S32.3965 71.959 m
+32.3965 68.4717 L
+S17.9971 71.959 m
+17.9971 68.4717 L
+S3.5967 71.959 m
+3.5967 68.4717 l
+S32.3965 32.4092 m
+32.3965 25.2217 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Confetti)
+(Confetti) 4.85 3.617 76.85 75.617 [
+%AI3_Tile
+(0 O 0 R 1 g
+ 1 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+4.85 3.617 m
+4.85 75.617 L
+76.85 75.617 L
+76.85 3.617 L
+4.85 3.617 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0 g
+ 0 G
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 0.3 w 4 M []0 d%AI3_Note:0 D
+0 XR
+10.6 64.867 m
+7.85 62.867 l
+S9.1 8.617 m
+6.85 6.867 l
+S78.1 68.617 m
+74.85 67.867 l
+S76.85 56.867 m
+74.35 55.117 l
+S79.6 51.617 m
+76.6 51.617 l
+S76.35 44.117 m
+73.6 45.867 l
+S78.6 35.867 m
+76.6 34.367 l
+S76.1 23.867 m
+73.35 26.117 l
+S78.1 12.867 m
+73.85 13.617 l
+S68.35 14.617 m
+66.1 12.867 l
+S76.6 30.617 m
+73.6 30.617 l
+S62.85 58.117 m
+60.956 60.941 l
+S32.85 59.617 m
+31.196 62.181 l
+S47.891 64.061 m
+49.744 66.742 l
+S72.814 2.769 m
+73.928 5.729 l
+S67.976 2.633 m
+67.35 5.909 l
+S61.85 27.617 m
+59.956 30.441 l
+S53.504 56.053 m
+51.85 58.617 l
+S52.762 1.779 m
+52.876 4.776 l
+S45.391 5.311 m
+47.244 7.992 l
+S37.062 3.375 m
+35.639 5.43 l
+S55.165 34.828 m
+57.518 37.491 l
+S20.795 3.242 m
+22.12 5.193 l
+S14.097 4.747 m
+15.008 8.965 l
+S9.736 1.91 m
+8.073 4.225 l
+S31.891 5.573 m
+32.005 8.571 l
+S12.1 70.367 m
+15.6 68.867 l
+S9.35 54.867 m
+9.6 58.117 l
+S12.85 31.867 m
+14.35 28.117 l
+S10.1 37.367 m
+12.35 41.117 l
+S34.1 71.117 m
+31.85 68.617 l
+S38.35 71.117 m
+41.6 68.367 l
+S55.1 71.117 m
+58.35 69.117 l
+S57.35 65.117 m
+55.35 61.867 l
+S64.35 66.367 m
+69.35 68.617 l
+S71.85 62.867 m
+69.35 61.117 l
+S23.6 70.867 m
+23.6 67.867 l
+S20.6 65.867 m
+17.35 65.367 l
+S24.85 61.367 m
+25.35 58.117 l
+S25.85 65.867 m
+29.35 66.617 l
+S14.1 54.117 m
+16.85 56.117 l
+S12.35 11.617 m
+12.6 15.617 l
+S12.1 19.867 m
+14.35 22.367 l
+S26.1 9.867 m
+23.6 13.367 l
+S34.6 47.117 m
+32.1 45.367 l
+S62.6 41.867 m
+59.85 43.367 l
+S31.6 35.617 m
+27.85 36.367 l
+S36.35 26.117 m
+34.35 24.617 l
+S33.85 14.117 m
+31.1 16.367 l
+S37.1 9.867 m
+35.1 11.117 l
+S34.35 20.867 m
+31.35 20.867 l
+S44.6 56.617 m
+42.1 54.867 l
+S47.35 51.367 m
+44.35 51.367 l
+S44.1 43.867 m
+41.35 45.617 l
+S43.35 33.117 m
+42.6 30.617 l
+S43.85 23.617 m
+41.1 25.867 l
+S44.35 15.617 m
+42.35 16.867 l
+S67.823 31.1 m
+64.823 31.1 l
+S27.1 32.617 m
+29.6 30.867 l
+S31.85 55.117 m
+34.85 55.117 l
+S19.6 40.867 m
+22.1 39.117 l
+S16.85 35.617 m
+19.85 35.617 l
+S20.1 28.117 m
+22.85 29.867 l
+S52.1 42.617 m
+54.484 44.178 l
+S52.437 50.146 m
+54.821 48.325 l
+S59.572 54.133 m
+59.35 51.117 l
+S50.185 10.055 m
+53.234 9.928 l
+S51.187 15.896 m
+53.571 14.075 l
+S58.322 19.883 m
+59.445 16.823 l
+S53.1 32.117 m
+50.6 30.367 l
+S52.85 24.617 m
+49.6 25.617 l
+S61.85 9.117 m
+59.1 10.867 l
+S69.35 34.617 m
+66.6 36.367 l
+S67.1 23.617 m
+65.1 22.117 l
+S24.435 46.055 m
+27.484 45.928 l
+S25.437 51.896 m
+27.821 50.075 l
+S62.6 47.117 m
+65.321 46.575 l
+S19.85 19.867 m
+20.35 16.617 l
+S21.85 21.867 m
+25.35 22.617 l
+S37.6 62.867 m
+41.6 62.117 l
+S38.323 42.1 m
+38.823 38.6 l
+S69.35 52.617 m
+66.85 53.867 l
+S14.85 62.117 m
+18.1 59.367 l
+S9.6 46.117 m
+7.1 44.367 l
+S20.6 51.617 m
+18.6 50.117 l
+S46.141 70.811 m
+47.994 73.492 l
+S69.391 40.561 m
+71.244 43.242 l
+S38.641 49.311 m
+39.35 52.117 l
+S25.141 16.811 m
+25.85 19.617 l
+S36.6 32.867 m
+34.6 31.367 l
+S6.1 68.617 m
+2.85 67.867 l
+S4.85 56.867 m
+2.35 55.117 l
+S7.6 51.617 m
+4.6 51.617 l
+S6.6 35.867 m
+4.6 34.367 l
+S6.1 12.867 m
+1.85 13.617 l
+S4.6 30.617 m
+1.6 30.617 l
+S72.814 74.769 m
+73.928 77.729 l
+S67.976 74.633 m
+67.35 77.909 l
+S52.762 73.779 m
+52.876 76.776 l
+S37.062 75.375 m
+35.639 77.43 l
+S20.795 75.242 m
+22.12 77.193 l
+S9.736 73.91 m
+8.073 76.225 l
+S10.1 23.617 m
+6.35 24.367 l
+S73.217 18.276 m
+71.323 21.1 l
+S28.823 39.6 m
+29.505 42.389 l
+S49.6 38.617 m
+47.6 37.117 l
+S60.323 73.6 m
+62.323 76.6 l
+S60.323 1.6 m
+62.323 4.6 l
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Leaves - Fall )
+(Leaves - Fall ) 0 0 64.0781 78.9336 [
+%AI3_Tile
+(0 O 0 R 0.05 0.2 1 0 k
+ 0.05 0.2 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+64.0781 78.9336 m
+64.0781 0 L
+0 0 L
+0 78.9336 L
+64.0781 78.9336 L
+f%AI6_EndPatternLayer
+) &
+(0 O 0 R 0.83 0 1 0 k
+ 0.83 0 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:1 D
+0 XR
+29.7578 0.9902 m
+30.4346 1.1914 30.7246 1.3428 V
+29.2559 4.0547 33.707 8.3359 34.627 9.0762 C
+35.2275 8.8506 35.3477 6.3184 34.6699 4.9805 C
+35.5137 5.1035 37.7031 3.7256 38.4609 2.4365 C
+38.5254 3.125 40.0957 6.0664 40.9219 6.4434 C
+40.002 6.8408 39.3359 8.3135 38.5742 9.7617 C
+39.5957 9.9287 40.9961 9.0078 42.4668 8.1025 C
+42.9814 8.9043 44.3555 9.875 45.6143 10.3916 C
+44.5264 11.0781 44.0313 11.8203 43.5352 13.2793 C
+42.4922 12.7139 40.3057 12.5645 39.7764 12.8516 C
+40.291 13.9648 42.5371 14.5078 43.2676 14.4551 C
+43.0137 15.3164 42.8652 17.4697 43.0391 20.0625 C
+41.3789 18.7461 39.834 17.4297 38.1738 17.4883 C
+38.4434 16.0664 37.8076 14.2607 37.4307 13.7676 C
+36.8574 14.5117 36.4463 15.3389 36.8008 17.3164 C
+35.3486 17.8008 34.1113 18.3467 32.7373 19.6045 C
+32.7373 17.7734 32.166 16.5723 31.2969 15.2959 C
+32.5576 14.8076 33.8301 13.6045 33.8252 12.5664 C
+32.9775 12.7178 31.2852 13.4619 30.793 14.4551 C
+30.0742 13.707 28.3906 12.3984 26.7871 12.3945 C
+27.9746 11.5391 28.8945 10.5059 28.9893 8.5938 C
+30.2422 9.5645 32.6953 10.1797 34.0752 9.582 C
+29.2344 5.3457 29.7031 2.3125 29.7578 0.9902 C
+f13.8525 29.9844 m
+13.3281 29.5127 13.1309 29.25 V
+15.623 27.4326 13.3691 21.6074 12.8555 20.5439 C
+12.2168 20.4883 10.8096 23.2285 10.8457 24.7266 C
+9.7129 23.9707 8.0488 24.0918 6.4463 24.3779 C
+7.0186 23.2891 6.6172 21.3447 5.8164 20.5439 C
+6.8184 20.5801 8.1699 19.8652 9.4785 18.8838 C
+8.6436 18.0645 6.8164 18.2246 4.9004 18.8838 C
+4.9004 17.5107 4.0781 15.7734 3.2412 14.5918 C
+4.5576 14.6484 5.7031 13.9629 6.5605 12.9316 C
+7.2256 14.5 9.2598 15.6133 10.166 15.5645 C
+10.1826 14.1992 8.6094 12.1094 7.5879 11.7109 C
+8.1875 11.041 9.207 9.5107 10.166 7.0947 C
+10.9648 9.0205 12.1348 10.2627 13.3672 11.1953 C
+12.2256 12.7578 12.3994 13.6289 12.7988 15.1074 C
+13.541 14.5664 14.5723 14.1338 14.7441 12.1309 C
+16.4609 12.416 17.5957 12.3447 19.0938 11.4434 C
+18.6387 13.1055 18.6348 14.707 18.9551 16.4063 C
+17.1055 16.2666 15.5449 16.4795 14.5156 17.9688 C
+15.3457 18.1953 17.6055 18.2549 18.4795 17.3223 C
+18.8066 18.3047 19.7012 19.7109 21.1475 20.4043 C
+19.707 20.6641 18.7227 21.7637 17.8135 23.4492 C
+17.1006 22.0332 14.873 20.3691 13.3711 20.3145 C
+15.373 24.3779 15.373 27.2959 13.8525 29.9844 C
+f41.2324 26.0742 m
+41.5518 26.7021 41.7549 26.959 V
+44.1523 25.0176 48.958 28.3262 49.8535 29.0957 C
+49.7432 29.7266 47.6182 30.8643 45.9004 29.834 C
+46.3408 31.123 45.4395 33.084 44.2402 34.126 C
+45.9805 34.0254 48.126 35.3867 48.6484 36.1289 C
+48.8701 35.1514 50.0527 33.8809 51.3379 32.8672 C
+51.6895 33.8398 50.9941 35.958 50.0781 37.5605 C
+51.3125 38.0605 52.4248 38.9912 52.8828 40.25 C
+53.3398 38.9336 54.3428 38.2598 55.6875 37.5039 C
+54.5273 36.0762 53.7471 33.9023 54.0273 33.0391 C
+55.3496 33.374 56.9209 36.0918 57.0439 37.1816 C
+57.9189 36.415 59.4727 35.7285 62.0537 35.4219 C
+60.3535 34.3438 59.9902 32.3516 59.4063 30.9219 C
+58.2588 31.3682 56.0898 31.4277 55.1152 30.8643 C
+55.8281 30.2852 57.168 29.7344 59.1777 29.7207 C
+59.1777 28.1758 59.6406 27.043 60.8945 25.8281 C
+59.1719 25.8418 57.0723 25.3555 55.5762 24.9629 C
+55.3281 26.292 54.4844 27.8887 53.3398 28.2891 C
+53.334 27.4277 53.5996 25.1797 54.4844 24.5117 C
+53.6201 23.9443 52.3672 22.5674 51.9102 20.8496 C
+51.2881 22.1758 50.4268 23.4805 48.5645 23.9238 C
+49.749 24.9766 50.584 26.9941 50.25 28.4609 C
+45.1973 24.4785 42.5215 25.7773 41.2324 26.0742 C
+f27.7578 38.7324 m
+28.4346 38.9316 28.7246 39.084 V
+27.2559 41.7969 31.707 46.0776 32.627 46.8169 C
+33.2275 46.5918 33.3477 44.0586 32.6699 42.7227 C
+33.5137 42.8457 35.7031 41.4678 36.4609 40.1787 C
+36.5254 40.8652 38.0957 43.8066 38.9219 44.1846 C
+38.002 44.582 37.3359 46.0547 36.5742 47.5039 C
+37.5957 47.6709 38.9961 46.7485 40.4668 45.8438 C
+40.9814 46.6445 42.3555 47.6177 43.6143 48.1328 C
+42.5264 48.8198 42.0313 49.5615 41.5352 51.0205 C
+40.4922 50.4556 38.3057 50.3057 37.7764 50.5938 C
+38.291 51.7056 40.5371 52.2485 41.2676 52.1958 C
+41.0137 53.0576 40.8652 55.2109 41.0391 57.8037 C
+39.3789 56.4878 37.834 55.1719 36.1738 55.2285 C
+36.4434 53.8076 35.8076 52.002 35.4307 51.5088 C
+34.8574 52.2529 34.4463 53.0796 34.8008 55.0576 C
+33.3486 55.5425 32.1113 56.0879 30.7373 57.3467 C
+30.7373 55.5146 30.166 54.314 29.2969 53.0366 C
+30.5576 52.5488 31.8301 51.3467 31.8252 50.3076 C
+30.9775 50.46 29.2852 51.2036 28.793 52.1958 C
+28.0742 51.4497 26.3906 50.1396 24.7871 50.1357 C
+25.9746 49.2817 26.8945 48.2466 26.9893 46.335 C
+28.2422 47.3057 30.6953 47.9209 32.0752 47.3237 C
+27.2344 43.0869 27.7031 40.0547 27.7578 38.7324 C
+f13.5195 70.3916 m
+12.9941 69.9209 12.7988 69.6587 V
+15.2891 67.8418 13.0352 62.0146 12.5225 60.9517 C
+11.8828 60.8955 10.4766 63.6367 10.5117 65.1348 C
+9.3809 64.3789 7.7148 64.4995 6.1133 64.7856 C
+6.6855 63.6987 6.2842 61.7529 5.4834 60.9517 C
+6.4854 60.9878 7.8359 60.2729 9.1455 59.2925 C
+8.3105 58.4717 6.4834 58.6338 4.5674 59.2925 C
+4.5674 57.9189 3.7461 56.1816 2.9082 54.9995 C
+4.2246 55.0576 5.3691 54.3706 6.2275 53.3408 C
+6.8926 54.9097 8.9258 56.0215 9.832 55.9727 C
+9.8496 54.6079 8.2764 52.5176 7.2539 52.1187 C
+7.8545 51.4497 8.873 49.9189 9.832 47.5039 C
+10.6309 49.4297 11.8008 50.6719 13.0342 51.6045 C
+11.8926 53.1655 12.0664 54.0366 12.4648 55.5146 C
+13.209 54.9746 14.2393 54.5415 14.4102 52.5386 C
+16.127 52.8247 17.2637 52.7529 18.7598 51.8525 C
+18.3057 53.5137 18.3027 55.1147 18.623 56.8149 C
+16.7725 56.6748 15.2129 56.8887 14.1826 58.377 C
+15.0117 58.6035 17.2725 58.6626 18.1465 57.731 C
+18.4736 58.7129 19.3691 60.1187 20.8145 60.8125 C
+19.375 61.0728 18.3896 62.1719 17.4805 63.8579 C
+16.7676 62.4429 14.541 60.7769 13.0371 60.7227 C
+15.041 64.7856 15.041 67.7046 13.5195 70.3916 C
+f41.2324 64.4824 m
+41.5518 65.1113 41.7549 65.3682 V
+44.1523 63.4272 48.958 66.7354 49.8535 67.5034 C
+49.7432 68.1362 47.6182 69.2725 45.9004 68.2422 C
+46.3408 69.5313 45.4395 71.4922 44.2402 72.5342 C
+45.9805 72.4341 48.126 73.7954 48.6484 74.5371 C
+48.8701 73.5601 50.0527 72.29 51.3379 71.2754 C
+51.6895 72.249 50.9941 74.3662 50.0781 75.9683 C
+51.3125 76.4692 52.4248 77.3994 52.8828 78.6582 C
+53.3398 77.3423 54.3428 76.667 55.6875 75.9111 C
+54.5273 74.4844 53.7471 72.3101 54.0273 71.4473 C
+55.3496 71.7822 56.9209 74.5 57.0439 75.5903 C
+57.9189 74.8232 59.4727 74.1372 62.0537 73.8311 C
+60.3535 72.7534 59.9902 70.7612 59.4063 69.3301 C
+58.2588 69.7773 56.0898 69.8364 55.1152 69.2725 C
+55.8281 68.6934 57.168 68.1431 59.1777 68.1284 C
+59.1777 66.583 59.6406 65.4512 60.8945 64.2373 C
+59.1719 64.249 57.0723 63.7632 55.5762 63.3721 C
+55.3281 64.7002 54.4844 66.2974 53.3398 66.6973 C
+53.334 65.8364 53.5996 63.5874 54.4844 62.9214 C
+53.6201 62.353 52.3672 60.9751 51.9102 59.2583 C
+51.2881 60.583 50.4268 61.8882 48.5645 62.333 C
+49.749 63.3862 50.584 65.4033 50.25 66.8691 C
+45.1973 62.8872 42.5215 64.1851 41.2324 64.4824 C
+f%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI3_BeginPattern: (Stripes)
+(Stripes) 8.45 4.6001 80.45 76.6001 [
+%AI3_Tile
+(0 O 0 R 1 0.07 1 0 k
+ 1 0.07 1 0 K
+) @
+(
+%AI6_BeginPatternLayer
+800 Ar
+0 J 0 j 3.6 w 4 M []0 d%AI3_Note:0 D
+0 XR
+8.2 8.2 m
+80.7 8.2 L
+S8.2 22.6001 m
+80.7 22.6001 L
+S8.2 37.0002 m
+80.7 37.0002 L
+S8.2 51.4 m
+80.7 51.4 L
+S8.2 65.8001 m
+80.7 65.8001 L
+S8.2 15.4 m
+80.7 15.4 L
+S8.2 29.8001 m
+80.7 29.8001 L
+S8.2 44.2 m
+80.7 44.2 L
+S8.2 58.6001 m
+80.7 58.6001 L
+S8.2 73.0002 m
+80.7 73.0002 L
+S%AI6_EndPatternLayer
+) &
+] E
+%AI3_EndPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginBrushPattern
+(New Pattern 1)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7844.75 8611 m
+-7844.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7844.75 8611 L
+nu0 Ap
+0 O
+1 g
+-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+F-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+F-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+F-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+F-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+F-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+F-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+F-7854.7817 8589.125 m
+-7860.9009 8587.6162 -7864.7817 8589.125 V
+-7868.877 8587.6484 -7874.7817 8589.125 V
+-7879.7446 8587.4492 -7884.7817 8589.125 V
+-7890.7969 8587.5742 -7894.7817 8589.125 V
+-7894.7817 8608.8096 L
+-7891.6958 8609.7842 -7888.2969 8609.9912 -7884.3799 8608.9082 C
+-7878.2134 8610.4912 -7874.4634 8608.9082 V
+-7869.4634 8610.4912 -7864.3799 8608.8242 V
+-7860.0474 8610.4082 -7854.3799 8608.9082 V
+-7848.8799 8610.3242 -7844.7817 8609.125 V
+-7844.7817 8589.4404 L
+-7847.5254 8588.4287 -7850.6514 8587.9287 -7854.7817 8589.125 C
+f0 R
+0 G
+1 J 1 j 0.5 w-7874.75 8609 m
+-7882.54 8610.9473 -7888.813 8607.585 -7894.75 8603.0488 C
+S-7864.75 8609 m
+-7876.96 8612.0527 -7885.4434 8602.0605 -7894.75 8594.9512 C
+S-7854.75 8609 m
+-7871.1279 8613.0947 -7880.8008 8593.7227 -7894.75 8589.3154 C
+S-7894.75 8589 m
+-7874.75 8584 -7864.75 8614 -7844.75 8609 C
+S-7884.75 8589 m
+-7868.3721 8584.9053 -7858.6992 8604.2773 -7844.75 8608.6846 C
+S-7874.75 8589 m
+-7862.54 8585.9473 -7854.0566 8595.9395 -7844.75 8603.0488 C
+S-7864.75 8589 m
+-7856.96 8587.0527 -7850.687 8590.415 -7844.75 8594.9512 C
+S-7854.75 8589 m
+-7851.1279 8588.0947 -7847.835 8588.3408 -7844.75 8589.3154 C
+S-7884.75 8609 m
+-7888.3721 8609.9053 -7891.665 8609.6592 -7894.75 8608.6846 C
+SUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 2)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7829.187 8610 L
+-7829.187 8545.9023 L
+-7894 8545.9023 L
+-7894 8610 L
+nu0 O
+0 g
+-7859.6978 8568.4297 m
+-7861.6094 8545.9023 L
+-7863.5215 8568.4297 L
+-7862.9033 8568.3066 -7862.2642 8568.2402 -7861.6094 8568.2402 c
+-7860.9551 8568.2402 -7860.3159 8568.3066 -7859.6978 8568.4297 C
+f-7871.2402 8576.3975 m
+-7894 8578.3301 L
+-7871.1138 8580.2734 L
+-7871.2856 8579.5469 -7871.3848 8578.793 -7871.3848 8578.0156 c
+-7871.3848 8577.4629 -7871.3281 8576.9248 -7871.2402 8576.3975 C
+f-7866.519 8569.5723 m
+-7880.1626 8560.8047 L
+-7870.2153 8573.377 L
+-7869.3574 8571.791 -7868.0718 8570.4766 -7866.519 8569.5723 C
+f-7863.481 8587.6074 m
+-7861.5786 8610 L
+-7859.6768 8587.5967 L
+-7860.3018 8587.7227 -7860.9473 8587.791 -7861.6094 8587.791 c
+-7862.25 8587.791 -7862.873 8587.7246 -7863.481 8587.6074 C
+f-7851.9609 8579.5068 m
+-7829.187 8577.5732 L
+-7852.083 8575.6289 L
+-7852.083 8575.8506 L
+-7851.9258 8576.5488 -7851.834 8577.2695 -7851.834 8578.0156 c
+-7851.834 8578.5234 -7851.8848 8579.0195 -7851.9609 8579.5068 C
+f-7870.1138 8582.8262 m
+-7880.1641 8595.5293 L
+-7866.2778 8586.6055 L
+-7867.8823 8585.7305 -7869.2114 8584.416 -7870.1138 8582.8262 C
+f-7852.9961 8573.3945 m
+-7842.875 8560.6055 L
+-7856.7666 8569.5313 L
+-7855.1768 8570.4414 -7853.8633 8571.7793 -7852.9961 8573.3945 C
+f-7856.6895 8586.4512 m
+-7842.873 8595.3281 L
+-7852.9658 8582.5732 L
+-7853.8198 8584.1895 -7855.1152 8585.5313 -7856.6895 8586.4512 C
+f-7852.8887 8582.6133 m
+-7852.3862 8581.6641 -7852.043 8580.6211 -7851.875 8579.5195 c
+-7851.7993 8579.0293 -7851.748 8578.5273 -7851.748 8578.0156 c
+-7851.748 8577.2637 -7851.8398 8576.5352 -7851.998 8575.8311 c
+-7852.1958 8574.957 -7852.5049 8574.124 -7852.918 8573.3545 c
+-7853.7954 8571.7246 -7855.1191 8570.374 -7856.7241 8569.4561 c
+-7857.6294 8568.9375 -7858.6226 8568.5537 -7859.6802 8568.3457 c
+-7860.3047 8568.2207 -7860.9497 8568.1523 -7861.6094 8568.1523 c
+-7862.2695 8568.1523 -7862.915 8568.2207 -7863.5391 8568.3457 c
+-7864.623 8568.5605 -7865.6382 8568.957 -7866.5625 8569.4961 c
+-7868.1313 8570.4102 -7869.4282 8571.7363 -7870.291 8573.335 c
+-7870.7969 8574.2695 -7871.145 8575.2969 -7871.3262 8576.3828 c
+-7871.415 8576.916 -7871.4727 8577.459 -7871.4727 8578.0156 c
+-7871.4727 8578.8008 -7871.3711 8579.5605 -7871.1978 8580.293 c
+-7870.981 8581.207 -7870.6406 8582.0732 -7870.187 8582.8701 c
+-7869.2793 8584.4727 -7867.939 8585.8008 -7866.3174 8586.6826 c
+-7865.4487 8587.1553 -7864.5 8587.498 -7863.4961 8587.6934 c
+-7862.8848 8587.8115 -7862.2554 8587.8779 -7861.6094 8587.8779 c
+-7860.9414 8587.8779 -7860.29 8587.8086 -7859.6602 8587.6826 c
+-7858.5786 8587.4668 -7857.5664 8587.0654 -7856.6455 8586.5273 c
+-7855.0566 8585.5977 -7853.751 8584.2441 -7852.8887 8582.6133 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 3)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7884.75 8611 m
+-7884.75 8587 L
+-7894.75 8587 L
+-7894.75 8611 L
+-7884.75 8611 L
+nuu0 Ap
+0 O
+1 g
+-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 c
+-7887.897 8590.9736 -7891.0898 8589 -7894.75 8589 C
+-7894.75 8609 L
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 c
+-7891.9121 8608.7754 -7890.1807 8608.0645 -7888.7441 8606.9824 c
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 c
+f0 R
+0 G
+1 J 1 j 0.5 w-7894.75 8589.3174 m
+-7891.7207 8590.2744 -7888.8926 8591.9326 -7886.1543 8593.9072 C
+S-7894.75 8594.9512 m
+-7891.5991 8597.3564 -7888.543 8600.0869 -7885.4058 8602.5361 C
+S-7888.7441 8606.9824 m
+-7890.8105 8605.8916 -7892.7993 8604.5342 -7894.75 8603.043 C
+S-7893.8018 8608.9521 m
+-7894.1191 8608.8682 -7894.4375 8608.7852 -7894.75 8608.6865 C
+S-7888.7441 8606.9824 m
+-7890.1807 8608.0645 -7891.9121 8608.7744 -7893.8018 8608.9521 C
+S-7885.4058 8602.5361 m
+-7884.9878 8601.4355 -7884.75 8600.2471 -7884.75 8599 c
+-7884.75 8597.1377 -7885.2681 8595.4004 -7886.1543 8593.9072 C
+S-7894.75 8609 m
+-7894.4297 8609 -7894.1143 8608.9814 -7893.8018 8608.9521 C
+S-7888.7441 8606.9824 m
+-7887.2471 8605.8545 -7886.0801 8604.3184 -7885.4058 8602.5361 C
+S-7886.1543 8593.9072 m
+-7887.8975 8590.9736 -7891.0898 8589 -7894.75 8589 C
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 5)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7736.3994 8611 m
+-7736.3994 8597.4199 L
+-7895 8597.4199 L
+-7895 8611 L
+-7736.3994 8611 L
+nuu0 O
+0.285 0.228 0.171 0 k
+-7751.0786 8609.4844 m
+-7751.043 8610.6895 L
+-7737.5103 8611.5176 -7736.8418 8610.2822 v
+-7736.7441 8610.1016 -7736.647 8609.7148 -7736.561 8609.1934 C
+-7738.584 8609.8242 -7748.291 8609.5713 -7751.0786 8609.4844 C
+f0.44 0.352 0.264 0 k
+-7751.4063 8598.0234 m
+-7751.3711 8599.2676 L
+-7748.4912 8599.0488 -7738.1914 8598.3164 -7736.543 8598.8652 C
+-7736.7031 8598.2188 -7736.9199 8597.7646 -7737.2046 8597.6152 c
+-7738.8306 8596.7656 -7751.4063 8598.0234 Y
+f0.145 0.116 0.087 0 k
+-7751.3711 8599.2676 m
+-7751.0786 8609.4844 L
+-7748.291 8609.5713 -7738.584 8609.8242 -7736.561 8609.1934 C
+-7736.1519 8606.7773 -7735.9258 8601.3604 -7736.543 8598.8652 C
+-7738.1914 8598.3164 -7748.4912 8599.0488 -7751.3711 8599.2676 C
+fUu0.155 0.124 0.093 0 k
+-7776.9375 8603.2734 m
+-7775.897 8603.6563 L
+-7757.0728 8599.1465 L
+-7757.481 8598.3145 L
+-7776.3633 8600.7246 L
+-7777.252 8601.0059 L
+-7777.6504 8600.8936 -7778.1934 8600.8242 V
+-7777.6094 8601.2373 -7777.1426 8602.1406 -7776.9375 8603.2734 C
+fu0.085 0.068 0.051 0 k
+-7781.7993 8607.666 m
+-7782.5977 8607.7217 -7779.749 8607.6641 Y
+-7780.3481 8607.0176 -7780.771 8605.8203 -7780.8105 8604.4375 c
+-7780.8169 8604.2246 -7780.8105 8604.0176 -7780.7993 8603.8135 C
+-7781.041 8603.707 -7781.0918 8603.7734 -7781.6289 8603.5645 C
+-7781 8607.6113 -7781.7993 8607.666 v
+f0.305 0.244 0.183 0 k
+-7780.3442 8600.8672 m
+-7780.5527 8600.8105 -7780.4937 8602.9307 Y
+-7779.4785 8603.7588 L
+-7777.8359 8602.9434 L
+-7776.9375 8603.2734 L
+-7777.1426 8602.1406 -7777.6094 8601.2373 -7778.1934 8600.8242 C
+-7778.6094 8600.7715 -7779.874 8600.7998 -7780.3442 8600.8672 C
+fU0.115 0.092 0.069 0 k
+-7776.9375 8603.2734 m
+-7777.8359 8602.9434 L
+-7779.4785 8603.7588 L
+-7780.4937 8602.9307 L
+-7780.793 8603.708 -7780.7993 8603.8135 V
+-7779.5137 8604.3789 -7778.1831 8604.7402 -7776.8398 8604.9258 C
+-7776.79 8604.7275 -7776.7842 8604.543 -7776.79 8604.3369 c
+-7776.7998 8603.9717 -7776.8218 8603.6182 -7776.9375 8603.2734 C
+f0.41 0.328 0.246 0 k
+-7757.4512 8599.3965 m
+-7759.377 8600.6426 -7768.3862 8606.0986 -7776.8398 8604.9258 C
+-7776.9038 8606.0928 -7777.248 8607.0908 -7777.75 8607.6631 C
+-7777.1895 8607.6621 L
+-7756.7402 8610.7559 L
+-7757.0366 8600.4258 L
+-7757.0728 8599.1465 L
+-7757.2046 8599.2373 -7757.4512 8599.3965 v
+f0.395 0.316 0.237 0 k
+-7780.8105 8604.4375 m
+-7780.771 8605.8203 -7780.3481 8607.0176 -7779.749 8607.6641 C
+-7777.6807 8607.6631 L
+-7777.1782 8607.0908 -7776.8218 8606.0713 -7776.8398 8604.9258 C
+-7778.1831 8604.7402 -7779.5137 8604.3789 -7780.7993 8603.8135 C
+-7780.8105 8604.0176 -7780.8169 8604.2246 -7780.8105 8604.4375 c
+fUu0 0 0 0.11 k
+-7751.2642 8598.2012 m
+-7750.2407 8598.0352 L
+-7751.2642 8598.2012 L
+-7751.2642 8598.2012 L
+f0 0 0 0.34 k
+-7757.481 8598.3145 m
+-7757.0728 8599.1465 L
+-7755.6714 8598.918 L
+-7754.5234 8598.7314 L
+-7752.6758 8598.4307 L
+-7751.2642 8598.2012 L
+-7750.2407 8598.0352 L
+-7750.2954 8597.7168 -7750.3672 8597.498 -7750.4648 8597.4199 C
+-7757.481 8598.3145 L
+f0 0 0 0.32 k
+-7755.8042 8603.207 m
+-7756.041 8610.8613 L
+-7750.7144 8611 L
+-7749.7266 8607.5146 -7750.1816 8603.1543 V
+-7755.8042 8603.207 L
+fU0.025 0.02 0.015 0 k
+-7749.3223 8600.3848 m
+-7746.373 8600.9199 -7743.2402 8601.1602 -7740.3159 8600.3613 c
+-7740.2856 8600.3496 -7740.2754 8600.3184 -7740.2871 8600.2969 c
+-7740.2881 8600.2656 -7740.3198 8600.2559 -7740.3418 8600.2559 c
+-7743.2422 8601.0645 -7746.375 8600.8242 -7749.3042 8600.2783 c
+-7749.3262 8600.2793 -7749.3574 8600.291 -7749.3672 8600.3223 c
+-7749.3662 8600.3438 -7749.355 8600.375 -7749.3223 8600.3848 c
+-7749.3223 8600.3848 l
+f-7747.8374 8599.3076 m
+-7747.7295 8599.3789 -7747.6313 8599.4941 -7747.5234 8599.502 c
+-7743.7886 8599.832 -7740.1631 8599.7813 -7736.4746 8599.6641 c
+-7736.4526 8599.6641 -7736.4209 8599.6426 -7736.4214 8599.6211 c
+-7736.4214 8599.5879 -7736.4551 8599.5684 -7736.4766 8599.5684 c
+-7739.3223 8599.6816 -7742.1401 8599.6992 -7745.0039 8599.5352 c
+-7745.9336 8599.4766 -7746.9082 8599.7402 -7747.7778 8599.2207 c
+-7747.7993 8599.2109 -7747.8306 8599.2109 -7747.8506 8599.2334 c
+-7747.8618 8599.2559 -7747.8594 8599.2871 -7747.8374 8599.3076 c
+-7747.8374 8599.3076 l
+f-7743.373 8601.3672 m
+-7741.5098 8602.6797 -7739.3022 8603.374 -7737.1001 8603.8867 c
+-7737.0679 8603.8965 -7737.0474 8603.8848 -7737.0366 8603.8535 c
+-7737.0273 8603.8203 -7737.0488 8603.8008 -7737.0703 8603.79 c
+-7739.2617 8603.2656 -7741.459 8602.6035 -7743.3105 8601.2803 c
+-7743.3433 8601.2598 -7743.375 8601.2715 -7743.3848 8601.293 c
+-7743.4058 8601.3145 -7743.3945 8601.3457 -7743.373 8601.3672 c
+-7743.373 8601.3672 l
+f-7748.9321 8608.0566 m
+-7746.7295 8608.5703 -7744.5298 8609.0303 -7742.2798 8609.2754 c
+-7742.2598 8609.2852 -7742.229 8609.2637 -7742.229 8609.2422 c
+-7742.2183 8609.209 -7742.2407 8609.1777 -7742.2729 8609.1787 c
+-7744.5122 8608.8809 -7746.7305 8608.5176 -7748.9126 8607.9502 c
+-7748.9351 8607.9512 -7748.9673 8607.9629 -7748.9766 8607.9941 c
+-7748.9751 8608.0156 -7748.9648 8608.0479 -7748.9321 8608.0566 c
+-7748.9321 8608.0566 l
+f-7748.439 8607.3604 m
+-7746.3457 8608.1973 -7744.1016 8607.9297 -7741.9023 8607.9629 c
+-7741.8706 8607.9609 -7741.8496 8607.9395 -7741.8506 8607.9082 c
+-7741.8521 8607.875 -7741.873 8607.8555 -7741.8945 8607.8555 c
+-7744.0928 8607.8438 -7746.3374 8608.0996 -7748.4209 8607.2529 c
+-7748.4434 8607.2539 -7748.4746 8607.2656 -7748.4834 8607.2969 c
+-7748.4834 8607.3184 -7748.4722 8607.3506 -7748.439 8607.3604 c
+-7748.439 8607.3604 l
+f-7747.707 8608.7051 m
+-7746.3833 8608.752 -7745.1504 8608.5469 -7743.8271 8608.209 c
+-7743.3594 8608.0996 -7742.9199 8608.2266 -7742.4609 8608.2129 c
+-7741.897 8608.1973 l
+-7741.874 8608.1963 -7741.8633 8608.1855 -7741.8535 8608.1738 c
+-7741.834 8608.1523 -7741.8442 8608.1211 -7741.8662 8608.0996 c
+-7742.0625 8607.9453 l
+-7742.0742 8607.9453 -7742.085 8607.9355 -7742.0962 8607.9355 c
+-7742.5 8607.9473 l
+-7743.9551 8608.1914 -7745.457 8608.6719 -7746.8926 8608.0742 c
+-7746.9258 8608.0645 -7746.957 8608.0859 -7746.9673 8608.1074 c
+-7746.9673 8608.1396 -7746.9551 8608.1602 -7746.9336 8608.1709 c
+-7745.647 8608.6992 -7744.1714 8608.4756 -7742.8818 8608.0547 c
+-7742.0918 8608.043 L
+-7742.124 8608.0332 L
+-7741.9282 8608.1875 L
+-7741.8984 8608.0898 L
+-7742.4639 8608.1064 l
+-7742.9321 8608.1406 -7743.3848 8607.9834 -7743.8398 8608.1035 c
+-7745.1543 8608.4609 -7746.3975 8608.625 -7747.71 8608.5986 c
+-7747.7422 8608.5996 -7747.7642 8608.6211 -7747.7617 8608.6533 c
+-7747.7617 8608.6855 -7747.7402 8608.7061 -7747.707 8608.7051 c
+-7747.707 8608.7051 l
+f-7748.5718 8609.0605 m
+-7745.8711 8610.2207 -7742.9023 8609.5703 -7740.1279 8609.1816 c
+-7739.7832 8609.2891 l
+-7739.7617 8609.2988 -7739.7417 8609.2871 -7739.7207 8609.2656 c
+-7739.71 8609.2441 -7739.7217 8609.2129 -7739.7422 8609.2021 c
+-7740.0801 8609.0098 l
+-7742.7754 8608.3926 -7745.5391 8608.7813 -7748.271 8608.7852 c
+-7748.3022 8608.7871 -7748.3232 8608.8086 -7748.3223 8608.8398 c
+-7748.3198 8608.8721 -7748.2983 8608.8926 -7748.2681 8608.8926 c
+-7745.6738 8608.9355 -7743.0303 8608.4434 -7740.4727 8609.0742 c
+-7739.7954 8609.2891 L
+-7739.7534 8609.1914 L
+-7740.1406 8609.0859 l
+-7742.9058 8609.4424 -7745.8418 8610.1348 -7748.5313 8608.9746 c
+-7748.5537 8608.9648 -7748.585 8608.9648 -7748.5962 8608.998 c
+-7748.6055 8609.0195 -7748.605 8609.0508 -7748.5718 8609.0605 c
+-7748.5718 8609.0605 l
+f-7745.6895 8602.3945 m
+-7744.3945 8602.9004 -7742.9834 8602.6465 -7741.6802 8602.3438 c
+-7741.647 8602.3418 -7741.6367 8602.3203 -7741.6382 8602.2891 c
+-7741.6504 8602.2568 -7741.6714 8602.2461 -7741.7031 8602.248 c
+-7742.998 8602.5303 -7744.377 8602.8154 -7745.6504 8602.2969 c
+-7745.6826 8602.2871 -7745.7144 8602.2988 -7745.7246 8602.3311 c
+-7745.7222 8602.3525 -7745.7114 8602.3848 -7745.6895 8602.3945 c
+-7745.6895 8602.3945 l
+f-7746.1401 8604.2207 m
+-7744.2266 8604.6895 -7742.3145 8605.1035 -7740.355 8605.3242 c
+-7740.3242 8605.334 -7740.3022 8605.3125 -7740.293 8605.2803 c
+-7740.2954 8605.2598 -7740.3159 8605.2285 -7740.3374 8605.2285 c
+-7742.2959 8605.0078 -7744.209 8604.582 -7746.1206 8604.1133 c
+-7746.1426 8604.1152 -7746.1738 8604.126 -7746.1831 8604.1582 c
+-7746.1831 8604.1797 -7746.1719 8604.2109 -7746.1401 8604.2207 c
+-7746.1401 8604.2207 l
+f-7746.9336 8606.6348 m
+-7744.499 8607.4609 -7741.8647 8607.0547 -7739.3457 8607.0879 c
+-7739.313 8607.0879 -7739.293 8607.0664 -7739.293 8607.0332 c
+-7739.2954 8607.0117 -7739.3159 8606.9922 -7739.3481 8606.9922 c
+-7741.8574 8606.916 -7744.481 8607.3848 -7746.8945 8606.5264 c
+-7746.9282 8606.5273 -7746.959 8606.5391 -7746.9688 8606.5605 c
+-7746.9678 8606.5918 -7746.9561 8606.624 -7746.9336 8606.6348 c
+-7746.9336 8606.6348 l
+f-7742.0542 8607.8496 m
+-7740.6582 8608.5449 -7739.0503 8608.4033 -7737.5342 8608.4668 c
+-7737.502 8608.4648 -7737.4824 8608.4434 -7737.4824 8608.4121 c
+-7737.4834 8608.3906 -7737.5054 8608.3594 -7737.5366 8608.3594 c
+-7739.0137 8608.2207 -7740.6489 8608.5234 -7742.0039 8607.7617 c
+-7742.0366 8607.7529 -7742.0679 8607.7637 -7742.0786 8607.7861 c
+-7742.0879 8607.8076 -7742.0767 8607.8398 -7742.0542 8607.8496 c
+-7742.0542 8607.8496 l
+f-7741.3418 8604.4248 m
+-7740.3926 8604.3975 -7739.4336 8604.3701 -7738.4839 8604.3428 c
+-7738.4526 8604.3418 -7738.4312 8604.3203 -7738.4336 8604.2881 c
+-7738.4336 8604.2559 -7738.4551 8604.2354 -7738.4878 8604.2363 c
+-7739.437 8604.2637 -7740.397 8604.291 -7741.3457 8604.3184 c
+-7741.377 8604.3184 -7741.3975 8604.3418 -7741.3975 8604.373 c
+-7741.397 8604.4043 -7741.374 8604.4258 -7741.3418 8604.4248 c
+-7741.3418 8604.4248 l
+f-7739.1592 8602.0361 m
+-7738.6895 8602.0645 -7738.209 8602.0723 -7737.7383 8602.0918 c
+-7737.7168 8602.0908 -7737.6855 8602.0684 -7737.6865 8602.0371 c
+-7737.687 8602.0039 -7737.71 8601.9844 -7737.7417 8601.9844 c
+-7738.2114 8601.9873 -7738.6816 8601.9375 -7739.1514 8601.9395 c
+-7739.1831 8601.9297 -7739.2031 8601.9512 -7739.2134 8601.9844 c
+-7739.2129 8602.0156 -7739.1914 8602.0371 -7739.1592 8602.0361 c
+-7739.1592 8602.0361 l
+f-7746.9702 8604.2344 m
+-7746.5688 8604.5107 -7746.125 8604.6797 -7745.645 8604.751 c
+-7745.6113 8604.7607 -7745.5918 8604.7383 -7745.5806 8604.7168 c
+-7745.5703 8604.6855 -7745.5928 8604.6543 -7745.6152 8604.6543 c
+-7746.0854 8604.5723 -7746.5176 8604.4023 -7746.9209 8604.1475 c
+-7746.9521 8604.1377 -7746.9849 8604.1387 -7746.9946 8604.1709 c
+-7747.0039 8604.1934 -7746.9922 8604.2246 -7746.9702 8604.2344 c
+-7746.9702 8604.2344 l
+f-7748.1904 8610.085 m
+-7745.7344 8610.5273 -7743.2983 8611.001 -7740.7993 8610.7266 c
+-7740.7778 8610.7266 -7740.7568 8610.7041 -7740.7578 8610.6719 c
+-7740.7578 8610.6406 -7740.7798 8610.6191 -7740.8022 8610.6191 c
+-7743.291 8610.873 -7745.7344 8610.4844 -7748.1719 8609.9775 c
+-7748.1934 8609.9785 -7748.2256 8609.9902 -7748.2344 8610.0215 c
+-7748.2344 8610.043 -7748.2222 8610.0752 -7748.1904 8610.085 c
+-7748.1904 8610.085 l
+f0.195 0.156 0.117 0 k
+-7748.166 8598.6445 m
+-7745.7969 8598.2676 -7743.4058 8598.3477 -7741.0298 8598.5898 c
+-7740.998 8598.5879 -7740.9766 8598.5664 -7740.9766 8598.5352 c
+-7740.9785 8598.5137 -7741 8598.4824 -7741.0215 8598.4824 c
+-7743.4082 8598.2422 -7745.791 8598.1602 -7748.1694 8598.5391 c
+-7748.2026 8598.5391 -7748.2222 8598.5605 -7748.2217 8598.5938 c
+-7748.2207 8598.625 -7748.1992 8598.6465 -7748.166 8598.6445 c
+-7748.166 8598.6445 l
+f0.335 0.268 0.201 0 k
+-7747.4351 8598.1113 m
+-7744.9282 8598.1152 -7742.4146 8598.2773 -7739.918 8597.8965 c
+-7739.8862 8597.8945 -7739.8647 8597.873 -7739.8662 8597.8418 c
+-7739.8672 8597.8086 -7739.8896 8597.7891 -7739.9209 8597.7891 c
+-7742.418 8598.1699 -7744.9297 8598.0293 -7747.4375 8598.0059 c
+-7747.46 8598.0059 -7747.481 8598.0273 -7747.4785 8598.0596 c
+-7747.4785 8598.0918 -7747.457 8598.1123 -7747.4351 8598.1113 c
+-7747.4351 8598.1113 l
+f0.205 0.164 0.123 0 k
+-7748.9766 8598.3262 m
+-7747.5039 8598.668 -7746.0078 8598.4023 -7744.5391 8598.2207 c
+-7744.5078 8598.2207 -7744.4873 8598.1973 -7744.499 8598.166 c
+-7744.5 8598.1348 -7744.5215 8598.1133 -7744.5537 8598.125 c
+-7746.0103 8598.2842 -7747.4961 8598.583 -7748.9473 8598.2188 c
+-7748.9785 8598.2207 -7749.0103 8598.2324 -7749.0098 8598.2637 c
+-7749.019 8598.2852 -7748.998 8598.3164 -7748.9766 8598.3262 c
+-7748.9766 8598.3262 l
+f-7742.3535 8597.7949 m
+-7741.1978 8597.9219 -7740.0273 8597.8145 -7738.8926 8597.5898 c
+-7738.8711 8597.5781 -7738.8506 8597.5566 -7738.8618 8597.5244 c
+-7738.8623 8597.5029 -7738.8945 8597.4824 -7738.916 8597.4941 c
+-7740.0503 8597.7402 -7741.1914 8597.7939 -7742.3462 8597.6885 c
+-7742.3794 8597.6895 -7742.3984 8597.7109 -7742.4087 8597.7324 c
+-7742.4082 8597.7646 -7742.3862 8597.7852 -7742.3535 8597.7949 c
+-7742.3535 8597.7949 l
+f0.335 0.268 0.201 0 k
+-7749.2681 8600.4473 m
+-7747.9214 8601.1885 -7746.3066 8600.5977 -7744.855 8600.6416 c
+-7744.8223 8600.6406 -7744.8022 8600.6191 -7744.8022 8600.5859 c
+-7744.8042 8600.5654 -7744.8262 8600.5449 -7744.8574 8600.5449 c
+-7746.2886 8600.4902 -7747.8823 8601.0801 -7749.2168 8600.3506 c
+-7749.2383 8600.3398 -7749.2695 8600.3516 -7749.291 8600.374 c
+-7749.3008 8600.3955 -7749.2886 8600.4277 -7749.2681 8600.4473 c
+-7749.2681 8600.4473 l
+f-7747.8945 8602.5645 m
+-7745.6719 8603.0449 -7743.3896 8602.6162 -7741.1504 8602.5625 c
+-7741.1177 8602.5615 -7741.0977 8602.5391 -7741.0977 8602.5078 c
+-7741.1001 8602.4863 -7741.1318 8602.4668 -7741.1519 8602.4668 c
+-7743.3833 8602.4775 -7745.6519 8602.9805 -7747.875 8602.457 c
+-7747.8975 8602.457 -7747.9287 8602.4688 -7747.9375 8602.502 c
+-7747.9375 8602.5225 -7747.9258 8602.5547 -7747.8945 8602.5645 c
+-7747.8945 8602.5645 l
+f-7742.0273 8599.1406 m
+-7740.3496 8599.9688 -7738.499 8600.502 -7736.603 8600.3613 c
+-7736.5718 8600.3613 -7736.5513 8600.3389 -7736.5527 8600.3066 c
+-7736.5527 8600.2754 -7736.5742 8600.2539 -7736.6074 8600.2559 c
+-7738.481 8600.416 -7740.3198 8599.8604 -7741.9873 8599.0547 c
+-7742.0078 8599.0449 -7742.041 8599.0449 -7742.0503 8599.0781 c
+-7742.061 8599.0996 -7742.061 8599.1309 -7742.0273 8599.1406 c
+-7742.0273 8599.1406 l
+fu0.5 0.85 1 0.45 k
+-7895 8605.9082 m
+-7895.0254 8606.4883 -7894.5664 8607.1875 -7893.167 8607.9902 C
+-7892.8521 8608.0029 -7891.3945 8608.0234 -7889.0889 8608.0488 C
+-7889.0889 8605.8223 L
+-7891.1382 8605.8457 -7893.1177 8605.8867 -7895 8605.9082 C
+f-7894.5088 8604.9688 m
+-7889.0889 8604.8447 L
+-7889.0889 8603.8145 L
+-7892.644 8603.959 L
+-7893.8145 8604.3301 -7894.5088 8604.9688 V
+f0.5 0.85 1 0.32 k
+-7889.0889 8604.8252 m
+-7894.4746 8604.9434 L
+-7894.7695 8605.2148 -7894.9849 8605.5566 -7895 8605.9277 C
+-7893.1177 8605.9063 -7891.1382 8605.8848 -7889.0889 8605.8613 C
+-7889.0889 8604.8252 L
+f0.5 0.85 1 0.45 k
+-7784.1504 8604.6172 m
+-7862.3584 8605.541 -7889.1079 8605.8418 V
+-7889.1079 8608.0488 L
+-7872.8145 8608.2324 -7813.9902 8608.707 Y
+-7779.749 8607.6641 L
+-7780.457 8604.5684 L
+-7784.1504 8604.6172 L
+f0.5 0.85 1 0.12 k
+-7889.1079 8603.8145 m
+-7889.1079 8604.8447 L
+-7780.4258 8603 L
+-7780.3833 8600.8633 L
+-7813.6553 8600.7129 L
+-7889.1079 8603.8145 L
+fu0.065 0.052 0.039 0 k
+-7757.0728 8599.1465 m
+-7757.0366 8600.4258 L
+-7757.2954 8599.1172 L
+-7775.897 8603.6563 L
+-7776.9375 8603.2734 L
+-7776.8794 8603.6055 -7776.8398 8603.957 -7776.8306 8604.3223 c
+-7776.8242 8604.5283 -7776.8281 8604.7285 -7776.8398 8604.9258 C
+-7768.3862 8606.0986 -7758.9634 8601.6719 -7757.0366 8600.4258 C
+-7756.7402 8610.7559 L
+-7756.041 8610.8613 L
+-7755.8042 8603.207 L
+-7750.1816 8603.1543 L
+-7750.0898 8601.0137 -7750.0718 8599.0215 -7750.2407 8598.0352 C
+-7757.0728 8599.1465 L
+f0.4 0.7 1 0 k
+-7780.457 8604.5879 m
+-7780.4258 8602.9805 L
+-7889.1079 8604.8252 L
+-7889.1079 8605.8613 L
+-7862.3584 8605.5605 -7780.457 8604.5879 Y
+fUU0.025 0.02 0.015 0 k
+-7744.7344 8607.0293 m
+-7744.7344 8607.0625 -7744.7129 8607.082 -7744.6802 8607.082 c
+-7741.6714 8607.1133 -7739.4214 8606.9453 -7736.415 8606.8594 C
+-7736.4087 8606.7656 L
+-7739.3262 8606.8701 -7741.7607 8607.0078 -7744.6841 8606.9746 C
+-7744.7168 8606.9766 -7744.7358 8606.998 -7744.7344 8607.0293 C
+f-7736.3994 8606.7656 m
+-7736.4082 8606.7441 L
+-7736.4087 8606.7656 L
+-7736.4063 8606.7656 -7736.4033 8606.7656 -7736.3994 8606.7656 C
+f-7740.4487 8605.4238 m
+-7741.4458 8605.292 -7742.3394 8605.7656 -7743.2114 8606.1973 C
+-7743.2441 8606.208 -7743.2534 8606.2402 -7743.2422 8606.2715 C
+-7743.2305 8606.293 -7743.1982 8606.3027 -7743.1777 8606.291 c
+-7742.3262 8605.8301 -7741.4312 8605.4199 -7740.4678 8605.5195 c
+-7739.1079 8605.6621 -7737.9038 8606.375 -7736.5254 8606.4531 C
+-7736.4463 8606.3594 L
+-7738.04 8606.2656 -7738.8647 8605.623 -7740.4487 8605.4238 c
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 6)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894.75 8587 m
+-7894.75 8611 L
+-7884.75 8611 L
+-7884.75 8587 L
+-7894.75 8587 L
+n0 Ap
+0 O
+1 g
+-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 c
+-7887.5879 8589.2256 -7889.3198 8589.9346 -7890.7559 8591.0176 c
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 c
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.2319 8602.5996 -7893.3457 8604.0918 c
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+-7884.75 8589 L
+f0 R
+0 G
+1 J 1 j 0.5 w-7884.75 8608.6816 m
+-7887.7793 8607.7256 -7890.6074 8606.0674 -7893.3457 8604.0918 C
+S-7884.75 8603.0488 m
+-7887.8999 8600.6436 -7890.957 8597.9131 -7894.0942 8595.4639 C
+S-7890.7559 8591.0176 m
+-7888.6904 8592.1084 -7886.7017 8593.4668 -7884.75 8594.957 C
+S-7885.6982 8589.0479 m
+-7885.3809 8589.1309 -7885.063 8589.2148 -7884.75 8589.3145 C
+S-7890.7559 8591.0176 m
+-7889.3193 8589.9355 -7887.5879 8589.2256 -7885.6982 8589.0479 C
+S-7894.0942 8595.4639 m
+-7894.5122 8596.5645 -7894.75 8597.7529 -7894.75 8599 c
+-7894.75 8600.8623 -7894.231 8602.5996 -7893.3457 8604.0918 C
+S-7884.75 8589 m
+-7885.0703 8589 -7885.3857 8589.0186 -7885.6982 8589.0479 C
+S-7890.7559 8591.0176 m
+-7892.2529 8592.1465 -7893.4199 8593.6816 -7894.0942 8595.4639 C
+S-7893.3457 8604.0918 m
+-7891.6025 8607.0273 -7888.4102 8609 -7884.75 8609 C
+SU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 8)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7893.9521 8608.3125 m
+-7786.7954 8608.3125 L
+-7786.7954 8594.1855 L
+-7893.9521 8594.1855 L
+-7893.9521 8608.3125 L
+nu0 O
+0 0 0 1 k
+-7892.2832 8607.623 m
+-7892.8535 8610 -7892.8184 8606.0039 V
+-7893.0479 8602.8027 L
+-7893.6167 8600.4551 L
+-7893.4502 8598.123 L
+-7891.9502 8597.4551 -7875.2832 8596.123 V
+-7868.6167 8594.7891 -7859.6167 8594.7891 V
+-7794.3936 8595.4766 -7789.4912 8596.8848 v
+-7830.3882 8594.875 -7832.9688 8595.5117 v
+-7793.8569 8597.1602 -7790.8545 8598.4316 v
+-7828.79 8596.5469 -7832.167 8598.1777 v
+-7797.249 8599.9102 -7793.021 8601.5313 v
+-7799.7217 8600.8828 -7801.5127 8601.082 v
+-7798.3896 8601.5703 l
+-7803.4194 8601.502 l
+-7806.3218 8601.1289 l
+-7798.4521 8602.2422 -7797.9033 8602.8086 v
+-7794.3154 8602.1309 -7808.5186 8602.3848 v
+-7842.1177 8598.4551 -7892.2832 8607.623 V
+f/BBAccumRotation (5.805971) XT
+0 R
+0 0 0 0.5 K
+0.025 w-7893.9502 8597.123 m
+-7873.667 8595.2949 -7853.9727 8594.2207 v
+-7811.1514 8594.502 -7806.5737 8594.9004 v
+-7794.1631 8595.0313 -7786.7959 8596.0273 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 1 K
+-7831.8369 8594.4082 m
+-7835.2959 8594.0273 -7861.2607 8594.2793 Y
+-7871.627 8594.1602 -7893.9502 8597.123 Y
+S/BBAccumRotation (5.805971) XT
+-7830.9873 8597.6641 m
+-7800.3608 8598.582 -7793.6606 8599.2324 v
+S/BBAccumRotation (5.805971) XT
+0 0 0 0.5 K
+-7839.6201 8602.2051 m
+-7804.3706 8603.6172 -7801.4058 8604.1406 v
+S/BBAccumRotation (5.805971) XT
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 10)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7843.8921 8610 L
+-7843.8921 8553.9756 L
+-7894 8553.9756 L
+-7894 8610 L
+nu0 O
+0.1 1 1 0 k
+-7856.9014 8575.5752 m
+-7858.7178 8569.0957 -7868.8247 8572.4658 Y
+-7868.791 8572.5303 L
+-7878.8999 8569.1611 -7880.7144 8575.6396 V
+-7886.6758 8593.0068 -7881.4922 8599.7451 V
+-7874.7529 8609.3369 -7870.6055 8609.3369 V
+-7867.0103 8609.2705 L
+-7862.8638 8609.2705 -7856.125 8599.6816 Y
+-7850.9409 8592.9424 -7856.9014 8575.5752 Y
+fu0 0 0 1 k
+-7861.3926 8553.9756 m
+-7862.1167 8555.4199 -7862.9238 8556.4756 V
+-7862.4058 8556.0635 -7861.5151 8555.1924 -7861.3926 8553.9756 C
+f-7875.064 8556.4854 m
+-7875.8711 8555.4307 -7876.5942 8553.9863 Y
+-7876.4727 8555.2021 -7875.582 8556.0732 -7875.064 8556.4854 C
+fU0 0.61 0.74 0 k
+-7860.5977 8578.4609 m
+-7861.9038 8573.7959 -7869.1816 8576.2217 Y
+-7869.1567 8576.2686 L
+-7876.436 8573.8428 -7877.7417 8578.5078 V
+-7882.0337 8591.0117 -7878.3018 8595.8633 V
+-7873.4487 8602.7686 -7870.4634 8602.7686 V
+-7867.875 8602.7227 L
+-7864.8887 8602.7227 -7860.0366 8595.8174 Y
+-7856.3042 8590.9639 -7860.5977 8578.4609 Y
+fu1 Ap
+0.73 0.43 1 0.22 k
+0 R
+0 0 0 1 K
+-7864.6226 8581.2754 m
+-7863.813 8581.2754 -7863.1558 8580.6182 -7863.1558 8579.8096 c
+-7863.1558 8579 -7863.813 8578.3428 -7864.6226 8578.3428 c
+-7865.4321 8578.3428 -7866.0889 8579 -7866.0889 8579.8096 c
+-7866.0889 8580.6182 -7865.4321 8581.2754 -7864.6226 8581.2754 c
+b-7864.3638 8592.9971 m
+-7863.0806 8592.9971 -7862.0415 8592.1201 -7862.0415 8591.042 c
+-7862.0415 8589.9619 -7863.0806 8589.0869 -7864.3638 8589.0869 c
+-7865.645 8589.0869 -7866.6846 8589.9619 -7866.6846 8591.042 c
+-7866.6846 8592.1201 -7865.645 8592.9971 -7864.3638 8592.9971 c
+b-7863.834 8604.7861 m
+-7862.2817 8604.7861 -7861.0239 8604.1299 -7861.0239 8603.3213 c
+-7861.0239 8602.5117 -7862.2817 8601.8545 -7863.834 8601.8545 c
+-7865.3862 8601.8545 -7866.645 8602.5117 -7866.645 8603.3213 c
+-7866.645 8604.1299 -7865.3862 8604.7861 -7863.834 8604.7861 c
+b-7859.6104 8576.5264 m
+-7858.8687 8576.5264 -7858.2671 8575.8154 -7858.2671 8574.9365 c
+-7858.2671 8574.0596 -7858.8687 8573.3477 -7859.6104 8573.3477 c
+-7860.353 8573.3477 -7860.9546 8574.0596 -7860.9546 8574.9365 c
+-7860.9546 8575.8154 -7860.353 8576.5264 -7859.6104 8576.5264 c
+b-7858.0034 8598.083 m
+-7858.8818 8597.7354 -7859.1494 8596.335 -7858.603 8594.9541 c
+-7858.0566 8593.5752 -7856.9014 8592.7363 -7856.0234 8593.085 c
+-7855.145 8593.4326 -7854.877 8594.833 -7855.4233 8596.2139 c
+-7855.9702 8597.5947 -7857.125 8598.4316 -7858.0034 8598.083 c
+bu-7873.0566 8581.1592 m
+-7873.8662 8581.1592 -7874.5239 8580.502 -7874.5239 8579.6934 c
+-7874.5239 8578.8828 -7873.8662 8578.2266 -7873.0566 8578.2266 c
+-7872.248 8578.2266 -7871.5913 8578.8828 -7871.5913 8579.6934 c
+-7871.5913 8580.502 -7872.248 8581.1592 -7873.0566 8581.1592 c
+b-7873.3159 8592.8799 m
+-7874.5991 8592.8799 -7875.6382 8592.0049 -7875.6382 8590.9248 c
+-7875.6382 8589.8447 -7874.5991 8588.9697 -7873.3159 8588.9697 c
+-7872.0342 8588.9697 -7870.9951 8589.8447 -7870.9951 8590.9248 c
+-7870.9951 8592.0049 -7872.0342 8592.8799 -7873.3159 8592.8799 c
+b-7873.8457 8604.6709 m
+-7875.3975 8604.6709 -7876.6558 8604.0146 -7876.6558 8603.2041 c
+-7876.6558 8602.3936 -7875.3975 8601.7383 -7873.8457 8601.7383 c
+-7872.293 8601.7383 -7871.0352 8602.3936 -7871.0352 8603.2041 c
+-7871.0352 8604.0146 -7872.293 8604.6709 -7873.8457 8604.6709 c
+b-7878.0679 8576.4092 m
+-7878.811 8576.4092 -7879.4121 8575.6982 -7879.4121 8574.8213 c
+-7879.4121 8573.9443 -7878.811 8573.2334 -7878.0679 8573.2334 c
+-7877.3262 8573.2334 -7876.7241 8573.9443 -7876.7241 8574.8213 c
+-7876.7241 8575.6982 -7877.3262 8576.4092 -7878.0679 8576.4092 c
+b-7879.6758 8597.9678 m
+-7878.7983 8597.6201 -7878.5298 8596.2188 -7879.0762 8594.8379 c
+-7879.6226 8593.457 -7880.7778 8592.6201 -7881.6558 8592.9678 c
+-7882.5342 8593.3164 -7882.8032 8594.7178 -7882.2568 8596.0967 c
+-7881.7104 8597.4775 -7880.5552 8598.3154 -7879.6758 8597.9678 c
+bUU0 Ap
+0 0 0 1 k
+-7869.1318 8576.6553 m
+-7869.1318 8609.3145 l
+Fu-7853.3906 8562.5303 m
+-7854.0815 8561.8369 -7857.019 8562.7021 Y
+-7858.229 8562.874 -7858.0562 8565.2939 Y
+-7857.019 8567.3682 -7857.7104 8567.1943 Y
+-7858.2998 8567.1943 -7859.855 8567.1143 -7860.7822 8567.0635 C
+-7861.1226 8565.6689 -7862.6128 8564.4756 -7864.7217 8563.7695 C
+-7862.7578 8560.4775 -7864.5176 8559.7949 -7866.2935 8559.79 C
+-7866.3096 8559.7021 -7866.332 8559.6162 -7866.3599 8559.5332 C
+-7864.1089 8559.5791 -7863.6392 8557.2588 Y
+-7863.4048 8557.0635 -7863.1606 8556.7861 -7862.9238 8556.4756 C
+-7863.1416 8556.6475 -7863.2944 8556.7393 Y
+-7864.2583 8556.7393 -7865.8774 8558.4941 -7866.4966 8559.207 C
+-7866.9194 8558.4434 -7867.853 8557.9111 -7868.9434 8557.9111 c
+-7870.0698 8557.9111 -7871.0322 8558.4795 -7871.4312 8559.2852 C
+-7871.9985 8558.624 -7873.6968 8556.751 -7874.6943 8556.751 C
+-7874.8462 8556.6572 -7875.064 8556.4854 V
+-7874.8281 8556.7939 -7874.583 8557.0732 -7874.3481 8557.2686 C
+-7873.8638 8559.6563 -7871.5254 8559.5342 V
+-7871.5449 8559.5889 -7871.5674 8559.6436 -7871.5806 8559.7021 C
+-7874.9238 8559.6924 -7873.937 8562.3174 -7873.2104 8563.6602 C
+-7875.5918 8564.376 -7877.2646 8565.7012 -7877.5239 8567.25 C
+-7878.4473 8567.2998 -7879.6729 8567.3584 -7880.1802 8567.3584 C
+-7880.8726 8567.5313 -7879.835 8565.458 V
+-7879.6626 8563.0391 -7880.8726 8562.8662 V
+-7883.8096 8562.002 -7884.501 8562.6934 V
+-7885.1919 8563.5566 -7886.0562 8562.3467 V
+-7885.1919 8564.0752 -7883.291 8563.5566 V
+-7880.6982 8562.8662 -7881.3906 8564.5938 V
+-7881.9087 8568.0498 -7880.1802 8568.7402 V
+-7878.0342 8569.8545 -7876.2822 8570.0889 V
+-7875.9087 8570.4141 -7875.4639 8570.7109 -7874.958 8570.9766 C
+-7877.5562 8571.0469 -7880.2246 8571.9209 -7881.0752 8574.9561 C
+-7881.5151 8576.2432 -7882.0518 8578.2432 V
+-7883.1025 8578.8252 -7884.3022 8580.0078 -7885.541 8582.2627 C
+-7886.394 8585.4502 -7887.167 8580.7129 V
+-7888.3975 8577.6494 -7889.6504 8577.5381 V
+-7888.4702 8579.2871 -7888.9038 8580.416 V
+-7887.2998 8584.917 -7885.6138 8583.8994 V
+-7884.0986 8583.2197 -7882.688 8580.8154 V
+-7883.0698 8582.4971 -7883.4326 8584.417 -7883.6743 8586.3906 C
+-7884.4888 8586.3975 L
+-7886.3506 8585.4795 -7886.3262 8588.959 V
+-7887.1226 8592.9453 -7886.3594 8595.6826 V
+-7885.647 8598.1504 -7888.1274 8596.9307 V
+-7889.2842 8597.3242 -7889.9839 8596.7881 V
+-7892.3882 8595.4131 -7894 8597.124 V
+-7892.147 8596.8799 -7891.4482 8597.417 V
+-7889.9785 8597.5615 -7889.897 8598.1787 V
+-7886.9561 8598.8555 -7886.188 8598.0771 V
+-7884.417 8597.2139 -7885.1304 8594.3604 V
+-7885.8799 8586.4814 -7884.3198 8588.4053 V
+-7884.1182 8588.4219 -7883.8784 8588.5176 V
+-7884.1519 8592.4326 -7883.8018 8596.3252 -7881.9961 8598.8516 C
+-7885.4536 8591.333 -7880.2974 8576.3037 Y
+-7878.9609 8571.5303 -7873.127 8572.1016 -7870.145 8572.7344 C
+-7870.0718 8574.1299 -7869.8374 8575.9492 -7869.1318 8576.6553 C
+-7868.2134 8574.6963 -7868.2358 8573.0732 V
+-7867.0762 8572.7217 -7860.2817 8570.8447 -7857.4487 8574.3369 C
+-7858.4312 8571.8135 -7860.8262 8571.0186 -7863.2007 8570.9189 C
+-7862.667 8570.6318 -7862.2041 8570.3047 -7861.8257 8569.9502 C
+-7860.041 8569.7861 -7857.7104 8568.5771 Y
+-7855.9814 8567.8857 -7856.5015 8564.4307 Y
+-7857.1919 8562.7021 -7854.5991 8563.3936 Y
+-7852.7002 8563.9111 -7851.835 8562.1836 Y
+-7852.7002 8563.3936 -7853.3906 8562.5303 Y
+f-7847.9082 8596.9521 m
+-7848.6074 8597.4893 -7849.7632 8597.0938 Y
+-7852.2446 8598.3135 -7851.5327 8595.8467 Y
+-7850.769 8593.1104 -7851.564 8589.1221 Y
+-7851.541 8585.6445 -7853.4014 8586.5596 Y
+-7854.0342 8586.5557 L
+-7854.3198 8584.6123 -7854.7046 8582.7549 -7855.0898 8581.1699 C
+-7853.7129 8583.4199 -7852.2778 8584.0635 Y
+-7850.5913 8585.082 -7848.9878 8580.5791 Y
+-7849.4214 8579.4502 -7848.2417 8577.7021 Y
+-7849.4937 8577.8125 -7850.7246 8580.876 Y
+-7851.4976 8585.6152 -7852.3511 8582.4268 Y
+-7853.5776 8580.1904 -7854.769 8579.0098 -7855.814 8578.4229 C
+-7856.2026 8577.0635 -7856.4858 8576.2393 Y
+-7856.7002 8575.4727 -7857.0337 8574.8486 -7857.4487 8574.3369 C
+-7857.3799 8574.5127 -7857.3174 8574.6982 -7857.2632 8574.8916 C
+-7851.3022 8592.2588 -7856.4858 8598.9971 V
+-7863.2246 8608.5869 -7867.3721 8608.5869 V
+-7870.9663 8608.6514 L
+-7875.1138 8608.6514 -7881.853 8599.0615 Y
+-7881.9038 8598.9961 -7881.9463 8598.9219 -7881.9961 8598.8516 C
+-7881.7378 8599.4141 -7881.437 8599.9404 -7881.0752 8600.4092 C
+-7874.3359 8610 -7870.189 8610 V
+-7866.5942 8609.9346 L
+-7862.4482 8609.9346 -7855.709 8600.3447 Y
+-7853.5801 8597.5771 -7853.3306 8593.0176 -7853.7769 8588.6055 C
+-7853.6553 8588.5752 -7853.5698 8588.5684 Y
+-7852.0112 8586.6475 -7852.7598 8594.5244 Y
+-7853.4746 8597.3789 -7851.7026 8598.2402 Y
+-7850.9351 8599.0186 -7847.9946 8598.3428 Y
+-7847.9136 8597.7256 -7846.4434 8597.5811 Y
+-7845.7446 8597.0449 -7843.8921 8597.2881 Y
+-7845.5024 8595.5771 -7847.9082 8596.9521 Y
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 34)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894.0254 8610.0264 m
+-7838.0542 8610.0264 L
+-7838.0542 8548.5342 L
+-7894.0254 8548.5342 L
+-7894.0254 8610.0264 L
+nuu0 O
+0.0745 0.9 0.9019 0.18 k
+0 R
+0 0 0 1 K
+1 J 1 j 0.0518 w-7867.5991 8586.7217 m
+-7867.3594 8597.5215 -7872.8794 8607.8398 v
+-7872.4009 8610 -7870.959 8610 v
+-7871.2002 8606.6406 -7870.2393 8606.1611 v
+-7865.9199 8594.1602 -7866.6382 8586.2402 v
+-7867.5991 8586.7217 l
+b-7867.5991 8586.7217 m
+-7869.2793 8592 -7881.0391 8593.2012 v
+-7885.3594 8593.6807 -7885.5991 8595.1211 v
+-7879.1206 8585.5195 -7878.1602 8585.7607 v
+-7891.3594 8580.001 -7894 8574.7197 v
+-7888.959 8577.6006 -7885.5991 8575.4404 v
+-7877.6802 8575.2012 -7872.6406 8577.3613 v
+-7868.8008 8579.2813 -7876.7202 8563.2012 v
+-7872.8794 8574.9609 -7869.2793 8548.5605 v
+-7868.3198 8553.8408 -7866.8799 8555.2813 v
+-7860.8799 8562.9609 -7861.8398 8565.1211 v
+-7862.3198 8568.9609 -7857.7598 8562.7207 v
+-7858 8572.3213 -7860.4009 8575.6807 v
+-7862.5591 8579.2813 -7856.5591 8577.1211 v
+-7850.5591 8575.2012 -7845.2793 8576.8809 v
+-7839.7598 8578.3203 -7838.0801 8575.4404 v
+-7849.8398 8587.9209 -7855.5991 8587.6807 v
+-7853.9194 8591.2813 l
+-7851.519 8596.0811 -7852 8597.2813 v
+-7867.2681 8587.8828 -7867.5991 8586.7217 v
+b-7867.5991 8586.7217 m
+-7864.959 8568.2402 -7867.5991 8560.5605 v
+-7869.998 8550.001 -7869.2793 8548.5605 v
+S-7866.1602 8575.4404 m
+-7860.1602 8570.6406 -7858.959 8565.3604 v
+S-7866.1602 8574.7197 m
+-7875.0391 8567.041 -7876.7202 8563.2012 v
+S-7838.0801 8575.4404 m
+-7839.2793 8577.6006 -7867.3594 8585.7607 y
+-7872.4009 8580.2422 -7883.9199 8577.8408 v
+-7891.5986 8576.8809 -7894 8574.7197 v
+S-7884.6382 8593.6807 m
+-7873.1191 8584.5615 -7867.3594 8585.7607 y
+-7853.1992 8592 -7852 8597.2813 v
+SUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 36)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7893.8496 8609.9961 m
+-7843.96 8609.9961 L
+-7843.96 8558.9258 L
+-7893.8496 8558.9258 L
+-7893.8496 8609.9961 L
+nu0 O
+0.025 0.1 0.475 0 k
+-7872.1504 8577.9043 m
+-7874.4766 8576.8125 -7876.6914 8576.4434 -7878.373 8576.9238 c
+-7879.0518 8577.1172 -7879.645 8577.4473 -7880.123 8577.9238 c
+-7880.6006 8578.4023 -7880.9297 8578.9951 -7881.123 8579.6729 c
+-7882.0088 8582.7715 -7880.0103 8587.6777 -7875.9233 8591.7666 c
+-7871.834 8595.8535 -7866.9297 8597.8516 -7863.8286 8596.9668 c
+-7863.1519 8596.7715 -7862.5586 8596.4424 -7862.0806 8595.9658 c
+-7861.603 8595.4883 -7861.2754 8594.8955 -7861.082 8594.2168 c
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.582 8585.21 -7864.791 8583.6133 -7866.2793 8582.123 c
+-7868.1504 8580.2539 -7870.1914 8578.8242 -7872.1504 8577.9043 c
+fu0.0035 0.014 0.0665 0 k
+-7871.2183 8576.9727 m
+-7873.8306 8576.0215 -7876.3975 8575.9688 -7878.373 8576.9238 C
+-7876.6914 8576.4434 -7874.4766 8576.8125 -7872.1504 8577.9043 c
+-7871.6191 8578.1543 -7871.0806 8578.4434 -7870.543 8578.7676 C
+-7868.8984 8578.0537 L
+-7869.667 8577.6172 -7870.4434 8577.2539 -7871.2183 8576.9727 c
+f0.015 0.06 0.285 0 k
+-7868.8984 8578.0537 m
+-7870.543 8578.7676 L
+-7869.0962 8579.6348 -7867.6426 8580.7607 -7866.2793 8582.123 c
+-7866.1538 8582.25 -7866.0327 8582.3779 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7866.3706 8579.7236 -7867.6191 8578.7813 -7868.8984 8578.0537 C
+fUu0.039 0.156 0.741 0 k
+-7859.687 8565.4043 m
+-7859.9746 8565.6914 -7871.2183 8576.9727 Y
+-7870.4434 8577.2539 -7869.667 8577.6172 -7868.8984 8578.0537 C
+-7855.4146 8564.5703 L
+-7857.061 8564.0996 -7858.6406 8564.3555 -7859.687 8565.4043 c
+f0.025 0.1 0.475 0 k
+-7855.4146 8564.5703 m
+-7868.8984 8578.0537 L
+-7867.584 8578.8027 -7866.2969 8579.7754 -7865.1143 8580.957 c
+-7865.084 8580.9863 -7865.0586 8581.0156 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7851.5264 8567.1328 -7851.7202 8566.9141 -7851.9302 8566.7012 c
+-7853.0103 8565.623 -7854.2305 8564.9082 -7855.4146 8564.5703 C
+fUu0.0115 0.046 0.2185 0 k
+-7845.9346 8574.3926 m
+-7843.5337 8571.9893 -7843.335 8568.0898 -7845.1382 8564.6973 C
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f0.015 0.06 0.285 0 k
+-7853.5337 8559.5957 m
+-7852.582 8558.9258 L
+-7855.2046 8558.3516 -7857.8306 8558.9141 -7859.6206 8560.7061 c
+-7858.1719 8559.2578 -7855.9082 8558.9307 -7853.5337 8559.5957 C
+f0.0295 0.118 0.5605 0 k
+-7853.5337 8559.5957 m
+-7855.9082 8558.9307 -7858.1719 8559.2578 -7859.6206 8560.7061 c
+-7861.019 8562.1055 -7861.3706 8564.2637 -7860.7954 8566.5469 C
+-7858.8672 8563.5449 -7855.4082 8564.5537 V
+-7853.585 8559.6309 L
+-7853.5337 8559.5957 L
+f*u
+0.048 0.192 0.912 0 k
+1 D
+-7845.9346 8574.3926 m
+-7847.2817 8575.7383 -7849.332 8576.1133 -7851.5234 8575.627 C
+-7861.6714 8585.7734 L
+-7861.7695 8585.5684 -7861.7695 8585.5684 -7861.6714 8585.7734 c
+-7860.2246 8588.8145 -7859.9702 8591.916 -7861.082 8594.2168 C
+-7860.5176 8592.2461 -7861.1226 8589.5449 -7862.6855 8586.7891 c
+-7863.5054 8585.3438 -7864.5918 8583.8848 -7865.9102 8582.5059 C
+-7865.2153 8580.8633 L
+-7865.1816 8580.8945 -7865.1465 8580.9238 -7865.1143 8580.957 c
+-7865.084 8580.9883 -7865.0566 8581.0176 -7865.0273 8581.0469 c
+-7865.0278 8581.0469 -7865.0278 8581.0469 -7865.0278 8581.0449 C
+-7851.3408 8567.3574 L
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+-7844.0938 8568.4961 -7843.8398 8572.2949 -7845.9346 8574.3926 c
+f*U
+0.0215 0.086 0.4085 0 k
+0 D
+-7852.582 8558.9258 m
+-7853.5337 8559.5957 L
+-7851.6846 8560.1113 -7849.7656 8561.2285 -7848.1138 8562.8828 c
+-7847.4063 8563.5889 -7846.7998 8564.3418 -7846.2954 8565.1182 C
+-7845.1382 8564.6973 L
+-7845.6553 8563.7246 -7846.3374 8562.793 -7847.1802 8561.9512 c
+-7848.7695 8560.3594 -7850.6758 8559.3428 -7852.582 8558.9258 C
+f0.0205 0.082 0.3895 0 k
+-7846.2954 8565.1182 m
+-7846.7998 8564.3418 -7847.4063 8563.5889 -7848.1138 8562.8828 c
+-7849.7656 8561.2285 -7851.6846 8560.1113 -7853.5337 8559.5957 C
+-7853.585 8559.6309 L
+-7855.4082 8564.5537 L
+-7854.2114 8564.9219 -7852.9878 8565.6436 -7851.9302 8566.7012 c
+-7851.7202 8566.9141 -7851.5264 8567.1328 -7851.3408 8567.3574 C
+-7846.3262 8565.1289 L
+-7846.2954 8565.1182 L
+fUu0.445 0.356 0.267 0 k
+-7893.8496 8609.9961 m
+-7871.957 8586.9688 L
+-7872.2007 8586.6494 -7872.5752 8586.6133 -7872.8887 8586.6592 C
+-7877.1802 8591.2891 -7888.3145 8603.4561 -7892.7266 8608.2793 C
+-7893.5649 8609.3516 -7894 8609.9932 -7893.8496 8609.9961 C
+f0.15 0.12 0.09 0 k
+-7893.834 8609.9961 m
+-7892.6606 8609.7031 -7871.6934 8588.0029 Y
+-7871.6934 8587.502 -7871.7993 8587.1758 -7871.957 8586.9688 C
+-7893.8496 8609.9961 L
+-7893.8442 8609.9961 -7893.8418 8610 -7893.834 8609.9961 c
+f0.2 0.16 0.12 0 k
+-7892.7266 8608.2793 m
+-7888.3145 8603.4561 -7877.1802 8591.2891 -7872.8887 8586.6592 C
+-7873.2002 8586.7041 -7873.4526 8586.8301 Y
+-7874.603 8587.1328 -7888.5742 8602.9619 -7892.7266 8608.2793 C
+fUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 37)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7892.9502 8609.2324 m
+-7843.0391 8609.2324 L
+-7843.0391 8545.1152 L
+-7892.9502 8545.1152 L
+-7892.9502 8609.2324 L
+nu0 O
+0 0 0 1 k
+0 R
+0 0 0 1 K
+0 w-7843.2358 8545.1152 m
+-7843.6064 8545.248 -7843.9858 8545.2832 -7844.3833 8545.2031 c
+-7844.4863 8545.168 l
+-7844.5254 8545.1602 -7844.5703 8545.1787 -7844.6025 8545.1992 c
+-7844.9434 8545.3926 l
+-7848.7129 8547.2959 -7852.0962 8549.8965 -7854.5 8553.4473 c
+-7855.9634 8555.5918 -7857.123 8557.8789 -7858.7993 8559.8564 c
+-7859.1729 8560.209 -7859.1758 8560.7725 -7858.834 8561.1309 c
+-7858.4951 8561.501 -7857.918 8561.5078 -7857.561 8561.165 c
+-7857.4038 8561.21 l
+-7857.2642 8561.1289 -7857.0742 8561.0703 -7857.0234 8560.957 c
+-7855.853 8558.2031 -7855.1895 8555.5137 -7853.4336 8553.1387 c
+-7851.1719 8550.0947 -7848.1777 8547.9941 -7845.0298 8546.0234 c
+-7844.3672 8545.6055 L
+-7844.4966 8545.6348 L
+-7843.7695 8545.6426 l
+-7843.791 8545.6113 -7843.8008 8545.5957 -7843.8223 8545.5645 C
+-7843.6064 8545.5234 -7843.377 8545.4746 -7843.1626 8545.4336 c
+-7843.0762 8545.4238 -7843.0186 8545.3389 -7843.0391 8545.2383 c
+-7843.0503 8545.1523 -7843.1382 8545.1084 -7843.2358 8545.1152 c
+-7843.2358 8545.1152 l
+b-7859.2222 8558.9951 m
+-7859.5742 8558.8066 -7859.9658 8558.6719 -7860.248 8558.3887 c
+-7866.4521 8552.1719 -7876.6802 8551.2734 -7884.0488 8557.6855 C
+-7884.1582 8557.7813 -7884.1582 8557.957 -7884.063 8558.0645 C
+-7881.0527 8556.9434 -7872.8838 8558.375 -7869.3223 8561.4121 C
+-7869.2534 8561.4668 -7869.1465 8561.4531 -7869.1055 8561.3711 C
+-7869.0503 8561.3047 -7869.0664 8561.1953 -7869.1328 8561.1563 C
+-7872.5625 8558.0859 -7877.0674 8556.29 -7881.6729 8556.748 C
+-7878.8535 8555.1855 -7875.6313 8554.4941 -7872.3984 8554.6885 c
+-7867.7144 8554.9717 -7863.4634 8557.1191 -7859.3711 8559.2793 c
+-7859.291 8559.3193 -7859.1978 8559.293 -7859.1553 8559.2109 C
+-7859.1016 8559.1309 -7859.1426 8559.0352 -7859.2222 8558.9951 c
+b-7868.647 8560.3359 m
+-7870.2266 8564.3613 -7872.3911 8568.3203 -7875.8018 8571.0762 c
+-7875.9648 8571.2119 -7875.9946 8571.4492 -7875.8711 8571.6055 c
+-7875.7344 8571.7676 -7875.5049 8571.7793 -7875.3481 8571.6563 c
+-7871.123 8569.5967 -7868.1904 8565.1309 -7868.1626 8560.4014 c
+-7868.1626 8560.4014 l
+-7868.1328 8560.2676 -7868.2354 8560.1348 -7868.3633 8560.1221 c
+-7868.5039 8560.1055 -7868.6318 8560.1973 -7868.647 8560.3359 c
+-7868.647 8560.3359 l
+b-7862.9414 8565.0176 m
+-7863.042 8565.1816 -7863.1152 8565.3838 -7863.2617 8565.4824 c
+-7866.0806 8567.3906 -7868.9785 8568.6309 -7871.8848 8570.1328 c
+-7872.0503 8570.209 -7872.1118 8570.418 -7872.0313 8570.5703 c
+-7871.9512 8570.7227 -7871.7559 8570.7793 -7871.5898 8570.7041 c
+-7868.439 8569.3232 -7864.313 8568.5 -7862.6729 8565.1797 c
+-7862.6289 8565.1113 -7862.6455 8565.0146 -7862.7266 8564.9648 c
+-7862.7959 8564.9199 -7862.897 8564.9492 -7862.9414 8565.0176 c
+-7862.9414 8565.0176 l
+b-7862.6602 8565.918 m
+-7862.4438 8566.4297 -7862.1431 8566.8896 -7862.0503 8567.4355 c
+-7861.2183 8572.2773 -7861.1152 8577.042 -7862.248 8581.6875 c
+-7862.248 8581.6875 l
+-7862.3418 8581.9531 -7862.2114 8582.2441 -7861.9438 8582.3389 c
+-7861.6777 8582.4336 -7861.3882 8582.3125 -7861.2935 8582.0479 c
+-7859.293 8576.8115 -7859.897 8570.7373 -7862.3711 8565.7832 c
+-7862.4063 8565.7002 -7862.498 8565.6689 -7862.582 8565.6914 c
+-7862.6641 8565.7275 -7862.6978 8565.835 -7862.6602 8565.918 c
+-7862.6602 8565.918 l
+b-7861.5352 8581.5938 m
+-7858.8984 8579.2275 -7856.6816 8576.252 -7855.853 8572.7363 c
+-7855.853 8572.7363 l
+-7855.7246 8572.1816 -7856.0742 8571.623 -7856.6416 8571.4902 c
+-7857.1992 8571.375 -7857.7578 8571.7246 -7857.8862 8572.2793 c
+-7858.5649 8575.5313 -7859.8711 8578.6729 -7861.7954 8581.3867 c
+-7861.7954 8581.3867 l
+-7861.8462 8581.4551 -7861.834 8581.5576 -7861.7695 8581.6201 c
+-7861.6992 8581.6699 -7861.5977 8581.6582 -7861.5352 8581.5938 c
+-7861.5352 8581.5938 l
+b-7846.3711 8574.1826 m
+-7847.7114 8569.8301 -7850.2598 8566.0693 -7853.689 8563.1533 C
+-7853.729 8563.0723 -7853.8242 8563.0322 -7853.9038 8563.0859 C
+-7853.9863 8563.127 -7854.0122 8563.2207 -7853.9722 8563.3018 C
+-7853.957 8563.7891 -7853.7144 8564.2334 -7853.4458 8564.5313 c
+-7848.4063 8570.1621 -7844.9902 8578.7197 -7847.3433 8585.9551 C
+-7847.0762 8580.4512 -7848.7241 8574.3008 -7852.1362 8569.6738 c
+-7853.1606 8568.2695 -7854.7422 8568.1211 -7856.3081 8568.2031 C
+-7856.4023 8568.1895 -7856.4834 8568.2432 -7856.4961 8568.3369 c
+-7856.5098 8568.4189 -7856.4551 8568.5137 -7856.3623 8568.5254 C
+-7853.1479 8569.7695 -7851.4878 8573.2246 -7850.084 8576.1943 c
+-7848.415 8579.7441 -7847.7017 8583.6387 -7848.0054 8587.5 C
+-7848.0454 8587.6777 -7848.1138 8589.3975 -7847.9775 8589.4102 C
+-7847.8306 8589.4395 -7847.709 8589.3438 -7847.6802 8589.1943 C
+-7847.645 8589.0449 -7844.6426 8579.7988 -7846.3711 8574.1826 c
+b-7854.4863 8561.4912 m
+-7853.3945 8557.6211 -7851.1094 8554.251 -7848.4824 8551.2383 c
+-7848.3306 8551.1045 -7848.3145 8550.8867 -7848.4502 8550.7354 c
+-7848.5752 8550.6006 -7848.8047 8550.582 -7848.957 8550.7178 c
+-7852.3306 8553.332 -7853.4487 8557.541 -7854.7954 8561.375 c
+-7854.7954 8561.375 l
+-7854.8262 8561.4648 -7854.7754 8561.5586 -7854.6982 8561.5869 c
+-7854.6094 8561.6191 -7854.5166 8561.5684 -7854.4863 8561.4912 c
+-7854.4863 8561.4912 l
+b-7848.5313 8586.1094 m
+-7848.5991 8586.0566 -7848.707 8586.083 -7848.748 8586.1504 C
+-7848.9634 8586.4746 -7850.6914 8588.5195 -7851.3926 8589.1406 c
+-7856.1719 8593.3945 -7859.5137 8597.9609 -7867.5391 8601.7227 c
+-7874.4512 8604.9639 -7877.1113 8607.5957 -7884.3862 8605.8262 c
+-7887.687 8605.0293 -7889.0313 8604.5313 -7890.4351 8599.4551 C
+-7891.9473 8593.2988 -7890.8672 8595.7832 -7891.084 8588.4385 c
+-7891.2222 8583.6973 -7894 8572.4551 -7881.5254 8558.2598 C
+-7881.4199 8558.1484 -7881.4336 8557.9961 -7881.5337 8557.9072 C
+-7881.6328 8557.8027 -7881.7959 8557.8164 -7881.8862 8557.916 C
+-7887.5786 8562.7168 -7891.0234 8569.6582 -7892.3145 8576.9424 c
+-7893.2871 8582.4668 -7892.9199 8587.25 -7892.666 8593.6367 c
+-7892.5688 8596.0938 -7893.6855 8603.0723 -7888.9102 8607.0625 c
+-7885.3926 8610 -7880.3911 8609.5469 -7876.3545 8608.1563 c
+-7870.6992 8606.2119 -7865.9727 8603.1465 -7860.8711 8599.6094 c
+-7857.2656 8597.125 -7849.2881 8587.2852 -7848.4785 8586.3262 C
+-7848.4351 8586.2588 -7848.4502 8586.1504 -7848.5313 8586.1094 C
+b-7883.0503 8573.3057 m
+-7882.168 8572.5029 -7881.7017 8573.8457 -7881.4297 8574.6016 c
+-7881.1626 8575.3574 -7880.189 8575.25 -7880.5127 8575.5732 c
+-7880.8369 8575.8975 -7880.8369 8575.9521 -7881.3232 8575.5195 c
+-7881.8086 8575.0879 -7881.8086 8575.7363 -7882.5649 8575.25 c
+-7883.3198 8574.7627 -7883.645 8573.8457 -7883.0503 8573.3057 c
+b-7875.6519 8577.9492 m
+-7875.3657 8577.5918 -7874.6802 8577.5723 -7874.4648 8577.8945 c
+-7874.25 8578.2197 -7873.3306 8578.2734 -7873.4937 8578.5967 c
+-7873.6543 8578.9219 -7873.6016 8579.1387 -7874.0874 8578.9219 c
+-7874.5737 8578.7051 -7874.4121 8579.2998 -7874.897 8579.084 c
+-7875.3833 8578.8672 -7875.8687 8578.2197 -7875.6519 8577.9492 c
+b-7867.6074 8583.0791 m
+-7867.1206 8582.7559 -7865.8794 8583.5117 -7866.4727 8583.5117 c
+-7867.0674 8583.5117 -7866.311 8584.2676 -7866.8521 8584.4834 c
+-7867.3906 8584.6992 -7867.2832 8584.4297 -7867.6074 8584.6445 c
+-7867.9297 8584.8613 -7868.3633 8585.2393 -7868.5239 8584.4297 c
+-7868.6855 8583.6191 -7868.3633 8583.6191 -7867.9849 8583.3496 c
+-7867.6074 8583.0791 -7867.6074 8583.0791 y
+b-7882.2402 8583.3496 m
+-7881.1074 8583.2422 -7881.8633 8583.998 -7881.269 8584.4834 c
+-7880.6738 8584.9697 -7879.918 8585.6172 -7880.729 8585.4004 c
+-7881.5391 8585.1855 -7882.9961 8585.6719 -7882.9434 8584.5381 c
+-7882.8887 8583.4033 -7882.6328 8583.3867 -7882.2402 8583.3496 c
+b-7876.5703 8591.6113 m
+-7876.1016 8591.3438 -7876.6802 8591.7197 -7876.0303 8591.6113 c
+-7875.3833 8591.5039 -7874.7886 8591.6113 -7875.2207 8591.8281 c
+-7875.6519 8592.0439 -7876.3008 8592.1523 -7876.4634 8591.9893 c
+-7876.625 8591.8281 -7876.9473 8591.8281 -7876.5703 8591.6113 c
+b-7867.0674 8591.1797 m
+-7867.4785 8590.1797 -7866.0962 8590.4238 -7865.4473 8590.7461 c
+-7864.7998 8591.0723 -7863.8262 8590.4775 -7864.4209 8590.9102 c
+-7865.0137 8591.3418 -7864.7998 8590.9102 -7865.3926 8591.2334 c
+-7865.9873 8591.5566 -7866.6895 8592.0977 -7867.0674 8591.1797 c
+b-7882.6738 8597.0664 m
+-7882.7222 8596.0752 -7881.8086 8596.957 -7881.269 8597.0117 c
+-7880.729 8597.0664 -7880.0801 8597.0664 -7880.2432 8597.2813 c
+-7880.4038 8597.498 -7880.459 8597.498 -7881.1626 8597.7129 c
+-7881.8633 8597.9297 -7882.6191 8598.1445 -7882.6738 8597.0664 c
+b-7883.1582 8591.6113 m
+-7884.0664 8591.9746 -7884.293 8591.8809 -7884.5625 8592.2051 c
+-7884.834 8592.5293 -7885.1558 8593.2314 -7885.5352 8592.0977 c
+-7885.9121 8590.9629 -7885.4282 8589.7764 -7885.0479 8589.9375 c
+-7884.6714 8590.0996 -7884.293 8590.7461 -7883.8618 8590.9629 c
+-7883.4297 8591.1797 -7882.6191 8591.3945 -7883.1582 8591.6113 c
+bUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 41)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7813 8610 L
+-7813 8505 L
+-7894 8505 L
+-7894 8610 L
+nuuu0 O
+0 0 0 1 k
+-7875.8057 8522.4258 m
+-7876.0742 8520.6621 -7877.1602 8519.291 -7878.5239 8519.3965 c
+-7879.8862 8519.502 -7880.707 8521.0234 -7880.7432 8522.8066 c
+-7880.748 8523.0693 -7880.6743 8524.2441 -7880.6304 8524.4775 C
+-7880.6382 8524.582 -7880.6191 8524.6738 -7880.6104 8524.7803 c
+-7880.5142 8526.0254 -7879.3574 8527.3604 -7877.9414 8527.25 c
+-7876.5249 8527.1406 -7875.4897 8525.8613 -7875.6367 8524.4727 c
+-7875.644 8524.4072 -7875.6958 8523.626 -7875.707 8523.5625 C
+-7875.6816 8523.2852 -7875.7598 8522.7256 -7875.8057 8522.4258 c
+f-7886.2646 8531.7334 m
+-7886.9946 8539.916 -7881.5015 8539.1191 v
+-7878.3682 8538.0186 -7879.4414 8535.1211 v
+-7879.6426 8533.752 -7881.7847 8532.498 v
+-7882.146 8532.25 -7882.7632 8531.1016 v
+-7883.1294 8529.5977 -7884.5186 8529.2979 v
+-7886.0762 8529.251 -7886.2646 8531.7334 v
+f-7860.7646 8540.4971 m
+F-7860.0762 8538.3408 m
+-7860.7847 8537.1934 -7863.8848 8537.6279 Y
+-7864.811 8537.6885 -7865.3799 8537.1113 Y
+-7867.8394 8533.0918 -7871.0386 8533.8857 -7871.4082 8533.9932 C
+-7871.4097 8533.9863 L
+-7874.999 8534.6045 -7875.2666 8539.6035 V
+-7875.4912 8540.3828 -7876.335 8540.7695 V
+-7879.2695 8541.8613 -7879.3481 8543.208 V
+-7879.8999 8545.1152 -7877.6006 8545.7422 V
+-7875.6792 8546.2568 -7873.7886 8543.8945 V
+-7872.6113 8542.6797 -7869.5762 8541.9395 V
+-7869.5728 8541.9531 L
+-7866.3594 8541.0459 -7864.6392 8541.5889 Y
+-7861.8521 8542.7676 -7860.4063 8541.4014 Y
+-7858.6826 8539.7559 -7860.0762 8538.3408 Y
+f-7873.9834 8521.8789 m
+-7874.5854 8520.2002 -7874.2822 8518.4775 -7873.0327 8517.9229 c
+-7871.7842 8517.3672 -7870.3384 8518.3164 -7869.4585 8519.8672 c
+-7869.3286 8520.0957 -7868.8359 8521.165 -7868.7632 8521.3906 C
+-7868.7065 8521.4785 -7868.6792 8521.5684 -7868.6362 8521.667 c
+-7868.1289 8522.8086 -7868.5122 8524.5303 -7869.8105 8525.1074 c
+-7871.1089 8525.6855 -7872.6279 8525.0527 -7873.1582 8523.7617 c
+-7873.1831 8523.7002 -7873.5078 8522.9883 -7873.5298 8522.9268 C
+-7873.6831 8522.6963 -7873.8809 8522.166 -7873.9834 8521.8789 c
+f-7859.7129 8524.9316 m
+-7855.1802 8531.7822 -7860.3911 8533.6943 v
+-7863.6714 8534.2168 -7864.103 8531.1572 v
+-7864.5786 8529.8564 -7863.29 8527.7354 v
+-7863.0903 8527.3447 -7863.0938 8526.04 v
+-7863.4858 8524.5449 -7862.4082 8523.6182 v
+-7861.0591 8522.8359 -7859.7129 8524.9316 v
+fUu-7834.7358 8574.1074 m
+-7834.3687 8572.3623 -7834.9048 8570.6963 -7836.2183 8570.3164 c
+-7837.5322 8569.9375 -7838.8345 8571.0752 -7839.4937 8572.7324 c
+-7839.5903 8572.9775 -7839.9326 8574.1025 -7839.9746 8574.3369 C
+-7840.0176 8574.4326 -7840.0322 8574.5244 -7840.0625 8574.6279 c
+-7840.4087 8575.8271 -7839.7935 8577.4805 -7838.4282 8577.875 c
+-7837.063 8578.2695 -7835.645 8577.4365 -7835.2969 8576.085 c
+-7835.2793 8576.0205 -7835.0552 8575.2705 -7835.0425 8575.207 C
+-7834.9214 8574.9551 -7834.7983 8574.4053 -7834.7358 8574.1074 c
+f-7848.2705 8578.6172 m
+-7851.8242 8586.0244 -7846.3999 8587.2061 v
+-7843.0801 8587.2754 -7843.0688 8584.1846 v
+-7842.7778 8582.8311 -7844.3433 8580.9072 v
+-7844.5942 8580.5459 -7844.7695 8579.2539 v
+-7844.5854 8577.7188 -7845.7793 8576.9492 v
+-7847.2222 8576.3594 -7848.2705 8578.6172 v
+f-7827.4648 8595.7695 m
+F-7826.063 8593.9912 m
+-7826.3247 8592.6689 -7829.3799 8591.9883 Y
+-7830.27 8591.7197 -7830.5986 8590.9795 Y
+-7831.4922 8586.3535 -7834.7666 8585.9746 -7835.1494 8585.9453 C
+-7835.1494 8585.9395 L
+-7838.7271 8585.2588 -7840.731 8589.8467 V
+-7841.2153 8590.4961 -7842.1416 8590.5625 V
+-7845.272 8590.5557 -7845.8169 8591.7891 V
+-7847.0039 8593.3809 -7845.0713 8594.7764 V
+-7843.4526 8595.9316 -7840.853 8594.3818 V
+-7839.3242 8593.6582 -7836.2222 8594.0293 V
+-7836.2231 8594.042 L
+-7832.896 8594.3213 -7831.4766 8595.4326 Y
+-7829.2793 8597.5146 -7827.4463 8596.7432 Y
+-7825.2554 8595.8057 -7826.063 8593.9912 Y
+f-7832.8374 8574.2354 m
+-7832.813 8572.4512 -7831.9258 8570.9453 -7830.5601 8570.8633 c
+-7829.1943 8570.7803 -7828.1743 8572.1768 -7827.895 8573.9385 c
+-7827.854 8574.1973 -7827.7666 8575.3711 -7827.7778 8575.6094 C
+-7827.7559 8575.7109 -7827.7617 8575.8037 -7827.7559 8575.9121 c
+-7827.6807 8577.1592 -7828.644 8578.6367 -7830.0625 8578.7217 c
+-7831.4814 8578.8066 -7832.6826 8577.6826 -7832.7246 8576.2871 c
+-7832.7271 8576.2217 -7832.7822 8575.4404 -7832.7798 8575.375 C
+-7832.8433 8575.1045 -7832.8423 8574.54 -7832.8374 8574.2354 c
+f-7821.0186 8581.5625 m
+-7819.1777 8589.5684 -7824.7271 8589.5303 v
+-7827.9834 8588.8691 -7827.3154 8585.8516 v
+-7827.3032 8584.4668 -7825.353 8582.9326 v
+-7825.0278 8582.6377 -7824.5742 8581.415 v
+-7824.417 8579.876 -7823.083 8579.3877 v
+-7821.5454 8579.1279 -7821.0186 8581.5625 v
+fUU1 Ap
+-7894 8610 m
+-7894 8505 L
+-7813 8505 L
+-7813 8610 L
+-7894 8610 L
+nUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 42)
+0 A
+u0 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 45)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8567.918 m
+-7895 8611 L
+-7808.2217 8611 L
+-7808.2217 8567.918 L
+-7895 8567.918 L
+nuu0 O
+0 0 0 1 k
+-7835.2217 8597.2363 m
+-7835.2217 8605.0742 L
+-7823.2217 8598.1445 L
+-7811.2217 8591.2168 L
+-7823.2217 8584.2891 L
+-7835.2217 8577.3613 L
+-7835.2217 8585.4824 L
+-7893.9351 8571.7168 L
+-7880.9878 8590.8027 L
+-7895 8611 L
+-7835.2217 8597.2363 L
+f0 1 1 0.1 k
+0 R
+0 0 0 1 K
+-7833.2217 8594.2363 m
+-7833.2217 8602.0742 L
+-7821.2217 8595.1445 L
+-7809.2217 8588.2168 L
+-7821.2217 8581.2891 L
+-7833.2217 8574.3613 L
+-7833.2217 8582.4824 L
+-7891.9351 8568.7168 L
+-7877.2754 8588.3594 L
+-7891.9351 8608 L
+-7833.2217 8594.2363 L
+bUUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 50)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8610 m
+-7766.877 8610 L
+-7766.877 8562.415 L
+-7894 8562.415 L
+-7894 8610 L
+nu*u
+0 O
+0.9529 0.949 0.1961 0.0745 k
+-7867.793 8594.417 m
+-7867.8232 8594.2676 L
+-7869.9849 8588.3643 -7870.9438 8585.6377 -7871.2754 8584.2891 c
+-7871.3657 8584.2891 L
+-7871.6953 8585.6074 -7872.7754 8588.335 -7874.9673 8594.2676 c
+-7874.9966 8594.417 L
+-7867.793 8594.417 l
+f1 D
+-7878.1182 8602.9678 m
+-7879.6191 8606.5371 -7880.3994 8608.709 -7878.1182 8608.917 c
+-7878.1182 8609.9678 L
+-7880.6992 8609.9375 -7883.5806 8609.917 -7886.3418 8609.917 c
+-7890.0649 8609.917 -7892.5273 8609.9375 -7894 8609.9678 c
+-7894 8608.917 L
+-7892.1064 8608.709 -7891.0542 8606.5674 -7883.5513 8589.5029 c
+-7871.6953 8562.415 L
+-7869.8638 8562.415 L
+-7858.1582 8589.5029 L
+-7850.8047 8606.5078 -7849.7246 8608.709 -7847.8887 8608.917 c
+-7847.8887 8609.9678 L
+-7849.5142 8609.9375 -7851.916 8609.917 -7855.5767 8609.917 c
+-7858.5488 8609.917 -7861.6694 8609.9375 -7864.7026 8609.9678 c
+-7864.7026 8608.917 L
+-7862.481 8608.709 -7863.3218 8606.5078 -7864.7617 8602.9678 C
+-7878.1182 8602.9678 l
+f*U
+*u
+0 D
+-7823.0762 8578.0811 m
+-7823.0762 8574.4717 -7825.3535 8572.0947 -7829.1294 8572.0947 c
+-7830.2383 8572.0947 -7831.0767 8572.2158 -7831.5273 8572.2451 c
+-7831.5273 8584.5479 L
+-7830.8672 8584.6084 -7830.208 8584.6084 -7829.729 8584.6084 c
+-7828.2002 8584.6084 -7826.7026 8584.127 -7825.6841 8583.4053 c
+-7824.3945 8582.5332 -7823.0762 8580.7881 -7823.0762 8578.1416 C
+-7823.0762 8578.0811 l
+f1 D
+-7842.0806 8582.3926 m
+-7842.0806 8566.6445 -7842.0806 8564.4287 -7844.542 8564.2783 c
+-7844.542 8563.3184 L
+-7843.042 8563.2588 -7840.3174 8563.1992 -7837.5664 8563.1689 c
+-7835.6538 8563.1084 -7832.3945 8563.0186 -7830.1479 8562.9775 c
+-7826.582 8562.9775 -7823.585 8563.4258 -7821.0049 8564.2627 c
+-7816.353 8565.8477 -7811.9702 8569.8525 -7811.9702 8577.6602 c
+-7811.9702 8582.7432 -7814.4014 8586.3193 -7816.5034 8588.0605 c
+-7817.583 8589.0215 -7818.8135 8589.832 -7819.7744 8590.3125 c
+-7819.7744 8590.4629 L
+-7817.5234 8593.4912 -7815.6025 8596.0625 -7809.3906 8604.6426 c
+-7807.5 8607.0645 -7805.9102 8608.7383 -7804.7402 8608.9775 c
+-7804.7402 8610 L
+-7806.6602 8610 -7809 8609.8848 -7811.1294 8609.8848 c
+-7813.3511 8609.8848 -7814.8521 8610 -7816.4424 8610 c
+-7817.6729 8610 -7818.7241 8609.9404 -7819.5039 8609.2725 c
+-7823.0151 8603.8477 -7826.9121 8597.7559 -7830.1182 8592.7139 c
+-7830.5078 8592.7139 -7830.957 8592.7139 -7831.5273 8592.7139 c
+-7831.5273 8595.2852 L
+-7831.5273 8606.5264 -7831.437 8608.7686 -7829.1895 8608.9775 c
+-7829.1895 8609.9697 L
+-7830.6279 8609.9404 -7833.9194 8609.915 -7836.6992 8609.915 c
+-7839.9287 8609.915 -7842.8921 8609.9404 -7844.5122 8609.9697 c
+-7844.5122 8608.9775 L
+-7842.0518 8608.7686 -7842.0806 8606.5264 -7842.0806 8589.5918 C
+-7842.0806 8582.3926 l
+f*U
+*u
+0 D
+-7791.4561 8589.5928 m
+-7791.4561 8606.4941 -7791.4561 8608.6484 -7794.2832 8608.9775 C
+-7794.2832 8609.9697 l
+-7792.3887 8609.9404 -7789.0542 8609.915 -7785.7822 8609.915 c
+-7782.6294 8609.915 -7779.5688 8609.9404 -7777.2881 8609.9697 C
+-7777.2881 8608.9775 l
+-7780.2578 8608.9775 -7780.2881 8606.5244 -7780.2881 8589.5928 C
+-7780.2881 8572.1514 L
+-7772.8193 8572.1514 l
+-7769.999 8572.1514 -7768.5298 8572.96 -7767.8994 8575.2627 C
+-7766.9072 8575.2627 l
+-7766.9072 8570.4697 -7766.877 8566.415 -7766.877 8563.1709 c
+-7771.3486 8563.2012 -7776.748 8563.2314 -7782.0601 8563.2314 C
+-7789.7446 8563.2314 l
+-7794.5537 8563.2314 -7799.9966 8563.2012 -7804.9614 8563.1709 c
+-7804.9614 8566.3848 -7804.9326 8570.4697 -7804.9326 8575.2627 C
+-7803.9072 8575.2627 l
+-7803.3657 8573.1094 -7801.771 8572.1514 -7798.9438 8572.1514 C
+-7791.4561 8572.1514 l
+-7791.4561 8589.5928 L
+f*U
+UU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 62)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8593.9043 m
+-7856.7305 8585.3408 L
+-7895 8585.3408 L
+-7895 8593.9043 L
+-7856.7305 8593.9043 L
+f-7856.7305 8597.0967 m
+-7856.7305 8596.4229 L
+-7895 8596.4229 L
+-7895 8597.0967 L
+-7856.7305 8597.0967 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 63)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8611 m
+-7895 8572.7305 L
+-7856.7305 8572.7305 L
+-7856.7305 8611 L
+-7895 8611 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8589.8262 m
+-7856.7305 8598.3896 L
+-7869.3408 8598.3896 L
+-7869.3408 8611 L
+-7877.9038 8611 L
+-7877.9063 8589.8262 L
+-7877.9038 8589.8262 L
+-7877.9038 8589.8252 L
+-7856.7305 8589.8262 L
+f-7856.7305 8587.3076 m
+-7880.4233 8587.3076 L
+-7880.4233 8611 L
+-7881.0967 8611 L
+-7881.0977 8586.6328 L
+-7856.7305 8586.6328 L
+-7856.7305 8587.3076 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 64)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7895 8610.999 m
+-7895 8572.7285 L
+-7856.7305 8572.7285 L
+-7856.7305 8610.999 L
+-7895 8610.999 L
+n0 O
+1 0.14 0.09 0 k
+-7856.7305 8585.3389 m
+-7882.3896 8585.3389 L
+-7882.3896 8610.999 L
+-7873.8262 8611 L
+-7873.8262 8593.9033 L
+-7856.7305 8593.9033 L
+-7856.7305 8585.3389 L
+f-7856.7305 8596.4219 m
+-7871.3081 8596.4219 L
+-7871.3081 8611 L
+-7870.6338 8611 L
+-7870.6338 8597.0957 L
+-7856.7305 8597.0957 L
+-7856.7305 8596.4219 L
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 65)
+0 A
+u1 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.0625 8583.4609 m
+-7894.6025 8583.4609 L
+-7894.6025 8611 L
+-7867.0625 8611 L
+-7867.0625 8583.4609 L
+n0 O
+0 0.55 1 0.12 k
+-7866.8418 8596.7002 m
+-7895 8596.7002 L
+-7895 8597.8252 L
+-7866.8418 8597.8252 L
+-7866.8418 8596.7002 L
+fu0 0.55 1 0.3 k
+-7893.9814 8584.5215 m
+-7894.4102 8586.5254 -7893.1865 8590.1514 -7890.0874 8593.251 c
+-7886.9878 8596.3496 -7883.3457 8597.6602 -7881.3594 8597.1455 C
+-7881.3594 8597.1455 L
+-7880.875 8595.1895 -7882.1519 8591.5117 -7885.25 8588.4141 c
+-7888.3457 8585.3184 -7892.0122 8584.1064 -7893.9814 8584.5215 C
+f0 0.39 0.7 0.12 k
+-7893.9814 8609.9912 m
+-7894.4102 8607.9883 -7893.1865 8604.3613 -7890.0874 8601.2617 c
+-7886.9878 8598.1641 -7883.3457 8596.8535 -7881.3594 8597.3672 C
+-7881.3594 8597.3672 L
+-7880.875 8599.3242 -7882.1519 8603.001 -7885.25 8606.0996 c
+-7888.3457 8609.1953 -7892.0122 8610.4063 -7893.9814 8609.9912 C
+fUu0 0.55 1 0.3 k
+-7880.1782 8609.9912 m
+-7880.6074 8607.9883 -7879.3838 8604.3613 -7876.2842 8601.2617 c
+-7873.1855 8598.1641 -7869.543 8596.8535 -7867.5576 8597.3672 C
+-7867.5566 8597.3672 L
+-7867.0718 8599.3242 -7868.3496 8603.001 -7871.4473 8606.0996 c
+-7874.543 8609.1953 -7878.209 8610.4063 -7880.1782 8609.9912 C
+f0 0.39 0.7 0.12 k
+-7880.1782 8584.5215 m
+-7880.6074 8586.5254 -7879.3838 8590.1514 -7876.2842 8593.251 c
+-7873.1855 8596.3496 -7869.543 8597.6602 -7867.5576 8597.1455 C
+-7867.5566 8597.1455 L
+-7867.0718 8595.1895 -7868.3496 8591.5117 -7871.4473 8588.4141 c
+-7874.543 8585.3184 -7878.209 8584.1064 -7880.1782 8584.5215 C
+fUU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 67)
+0 A
+u0 Ap
+800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.085 m
+-7895 8583.085 L
+-7895 8610.624 L
+-7867.4609 8610.624 L
+-7867.4609 8583.085 L
+n0 O
+0 0.55 1 0.12 k
+-7881.7598 8601.3623 m
+-7881.7598 8611 L
+-7880.6343 8611 L
+-7880.6343 8601.3623 L
+-7881.7598 8601.3623 L
+f0 0.55 1 0.3 k
+-7885.4233 8596.876 m
+-7884.3096 8595.1553 -7880.8809 8593.457 -7876.4966 8593.457 c
+-7872.1152 8593.457 -7868.6138 8595.1064 -7867.5718 8596.874 C
+-7867.5718 8596.874 L
+-7868.6138 8598.6006 -7872.1152 8600.2979 -7876.4966 8600.2979 c
+-7880.875 8600.2979 -7884.3242 8598.5615 -7885.4233 8596.876 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 69)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7867.4609 8583.4609 m
+-7895 8583.4609 L
+-7895 8611 L
+-7867.4609 8611 L
+-7867.4609 8583.4609 L
+n0 O
+0 0.55 1 0.3 k
+-7885.4233 8597.252 m
+-7884.3096 8595.5313 -7880.8809 8593.833 -7876.4966 8593.833 c
+-7872.1152 8593.833 -7868.6138 8595.4824 -7867.5718 8597.25 C
+-7867.5718 8597.25 L
+-7868.6138 8598.9766 -7872.1152 8600.6738 -7876.4966 8600.6738 c
+-7880.875 8600.6738 -7884.3242 8598.9375 -7885.4233 8597.252 C
+fU%AI8_EndBrushPattern
+%AI8_BeginBrushPattern
+(New Pattern 83)
+0 A
+u800 Ar
+0 J 0 j 1 w 4 M []0 d%AI3_Note:0 D
+0 XR
+-7894 8609.9355 m
+-7680.4009 8609.9355 L
+-7680.4009 8602.1348 L
+-7894 8602.1348 L
+-7894 8609.9355 L
+n0 O
+0 0 0 1 k
+-7894 8606.0352 m
+-7883.9858 8608.5273 -7877.187 8609.875 -7865.2007 8609.9355 c
+-7852.2183 8610 -7787.2002 8609.9355 y
+-7722.1816 8610 -7709.2002 8609.9355 v
+-7697.2129 8609.875 -7690.415 8608.5273 -7680.4009 8606.0352 C
+-7690.415 8603.543 -7697.2129 8602.1953 -7709.2002 8602.1348 c
+-7722.1816 8602.0693 -7787.2002 8602.1348 y
+-7852.2183 8602.0693 -7865.2007 8602.1348 v
+-7877.187 8602.1953 -7883.9858 8603.543 -7894 8606.0352 C
+fU%AI8_EndBrushPattern
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+4 Bn
+%AI5_BeginGradient: (Black, White)
+(Black, White) 0 2 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0 %_Br
+[
+0 0 50 100 %_BS
+%_0 0 50 100 Bs
+1 0 50 0 %_BS
+%_1 0 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Chrome)
+(Chrome) 0 6 Bd
+[
+0
+<
+464646454545444444444343434342424241414141404040403F3F3F3E3E3E3E3D3D3D3C3C3C3C3B
+3B3B3B3A3A3A39393939383838383737373636363635353535343434333333333232323131313130
+3030302F2F2F2E2E2E2E2D2D2D2D2C2C2C2B2B2B2B2A2A2A2A292929282828282727272626262625
+2525252424242323232322222222212121202020201F1F1F1F1E1E1E1D1D1D1D1C1C1C1B1B1B1B1A
+1A1A1A1919191818181817171717161616151515151414141413131312121212111111101010100F
+0F0F0F0E0E0E0D0D0D0D0C0C0C0C0B0B0B0A0A0A0A09090909080808070707070606060505050504
+04040403030302020202010101010000
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+1F1E1E1E1E1E1E1E1E1E1D1D1D1D1D1D1D1D1C1C1C1C1C1C1C1C1B1B1B1B1B1B1B1B1B1A1A1A1A1A
+1A1A1A19191919191919191818181818181818181717171717171717161616161616161615151515
+15151515151414141414141414131313131313131312121212121212121211111111111111111010
+1010101010100F0F0F0F0F0F0F0F0F0E0E0E0E0E0E0E0E0D0D0D0D0D0D0D0D0C0C0C0C0C0C0C0C0C
+0B0B0B0B0B0B0B0B0A0A0A0A0A0A0A0A090909090909090909080808080808080807070707070707
+07060606060606060606050505050505050504040404040404040303030303030303030202020202
+02020201010101010101010000000000
+>
+1 %_Br
+0
+0.275
+1
+<
+6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544
+434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F
+>
+1 %_Br
+0
+<
+00000101010102020202030303040404040505050606060607070707080808090909090A0A0A0A0B
+0B0B0C0C0C0C0D0D0D0D0E0E0E0F0F0F0F1010101111111112121212131313141414141515151516
+161617171717181818181919191A1A1A1A1B1B1B1C1C1C1C1D1D1D1D1E1E1E1F1F1F1F2020202021
+212122222222232323232424242525252526262627272727282828282929292A2A2A2A2B2B2B2B2C
+2C2C2D2D2D2D2E2E2E2E2F2F2F303030303131313232323233333333343434353535353636363637
+373738383838393939393A3A3A3B3B3B3B3C3C3C3D3D3D3D3E3E3E3E3F3F3F404040404141414142
+42424343434344444444454545464646
+>
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+<
+00000101020203030304040505050606070708080809090A0A0B0B0B0C0C0D0D0D0E0E0F0F101010
+1111121212131314141515151616171718181819191A1A1A1B1B1C1C1D1D1D1E1E1F1F1F20202121
+222222232324242525252626272727282829292A2A2A2B2B2C2C2D2D2D2E2E2F2F2F303031313232
+32333334343435353636373737383839393A3A3A3B3B3C3C3C3D3D3E3E3F3F3F4040414142424243
+4344444445454646474747484849494A4A4A4B4B4C4C4C4D4D4E4E4F4F4F50505151515252535354
+54545555565657575758585959595A5A5B5B5C5C5C5D5D5E5E5E5F5F606061616162626363646464
+6565666666676768686969696A6A6B6B
+>
+1 %_Br
+1
+0 %_Br
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+<
+4D4C4C4C4B4B4B4A4A4A4A4949494848484747474746464645454544444444434343424242414141
+414040403F3F3F3E3E3E3E3D3D3D3C3C3C3B3B3B3B3A3A3A39393938383838373737363636353535
+35343434333333323232323131313030302F2F2F2F2E2E2E2D2D2D2C2C2C2C2B2B2B2A2A2A292929
+2928282827272726262626252525242424232323232222222121212020201F1F1F1F1E1E1E1D1D1D
+1C1C1C1C1B1B1B1A1A1A191919191818181717171616161615151514141413131313121212111111
+101010100F0F0F0E0E0E0D0D0D0D0C0C0C0B0B0B0A0A0A0A09090908080807070707060606050505
+04040404030303020202010101010000
+>
+0
+0
+1 %_Br
+[
+1 0 50 92 %_BS
+%_1 0 50 92 Bs
+0 0.275 1 0.12 1 50 59 %_BS
+%_0 0.275 1 0.12 1 50 59 Bs
+0 0.275 1 0.42 1 50 50 %_BS
+%_0 0.275 1 0.42 1 50 50 Bs
+1 0 50 49 %_BS
+%_1 0 50 49 Bs
+1 0 50 41 %_BS
+%_1 0 50 41 Bs
+1 0.3 0 0 1 50 0 %_BS
+%_1 0.3 0 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Rainbow)
+(Rainbow) 0 6 Bd
+[
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+0
+1 %_Br
+1
+<
+0708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E
+2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F50515253545556
+5758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E
+7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6
+A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCE
+CFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6
+F7F8F9FAFBFCFDFEFF
+>
+0
+0
+1 %_Br
+1
+<
+00000000000000000000000000000000000001010101010101010101010101010101010101010101
+01010101010101010101010101010202020202020202020202020202020202020202020202020202
+02020202020202020202030303030303030303030303030303030303030303030303030303030303
+03030303030304040404040404040404040404040404040404040404040404040404040404040404
+04040505050505050505050505050505050505050505050505050505050505050505050505050606
+06060606060606060606060606060606060606060606060606060606060606060607070707070707
+07070707070707070707070707070707
+>
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+0
+1 %_Br
+<
+000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021222324252627
+28292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F
+505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071727374757677
+78797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F
+A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF
+F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
+>
+0
+1
+0
+1 %_Br
+0
+<
+FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8
+D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0
+AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A8988
+87868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160
+5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938
+37363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A19181716151413121110
+0F0E0D0C0B0A09080706050403020100
+>
+1
+0
+1 %_Br
+[
+0 1 0 0 1 50 100 %_BS
+%_0 1 0 0 1 50 100 Bs
+1 1 0 0 1 50 80 %_BS
+%_1 1 0 0 1 50 80 Bs
+1 0.0279 0 0 1 50 60 %_BS
+%_1 0.0279 0 0 1 50 60 Bs
+1 0 1 0 1 50 40 %_BS
+%_1 0 1 0 1 50 40 Bs
+0 0 1 0 1 50 20 %_BS
+%_0 0 1 0 1 50 20 Bs
+0 1 1 0 1 50 0 %_BS
+%_0 1 1 0 1 50 0 Bs
+BD
+%AI5_EndGradient
+%AI5_BeginGradient: (Yellow & Orange Radial)
+(Yellow & Orange Radial) 1 2 Bd
+[
+0
+<
+0001010203040506060708090A0B0C0C0D0E0F10111213131415161718191A1B1C1D1D1E1F202122
+232425262728292A2B2B2C2D2E2F303132333435363738393A3B3C3D3E3E3F404142434445464748
+494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60606162636465666768696A6B6C6D6E6F
+707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C
+>
+<
+FFFFFFFFFEFEFEFEFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBFBFBFBFAFAFAFAFAFAF9F9F9F9F9
+F9F8F8F8F8F8F8F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F5F5F5F4F4F4F4F4F3F3F3F3F3F3F2F2F2F2
+F2F2F1F1F1F1F1F0F0F0F0F0F0EFEFEFEFEFEFEEEEEEEEEEEDEDEDEDEDEDECECECECECEBEBEBEBEB
+EBEAEAEAEAEAE9E9E9E9E9E9E8E8E8E8E8E8E7E7E7E7E7E6E6E6E6E6E6
+>
+0
+1 %_Br
+[
+0 0 1 0 1 52 19 %_BS
+%_0 0 1 0 1 52 19 Bs
+0 0.55 0.9 0 1 50 100 %_BS
+%_0 0.55 0.9 0 1 50 100 Bs
+BD
+%AI5_EndGradient
+%AI5_End_NonPrinting--
+%AI5_BeginPalette
+0 0 Pb
+1 1 1 1 ([Registration]) 0 Xs
+([Registration]) Pc
+0 0 0 0 k
+(C=0 M=0 Y=0 K=0) Pc
+0 0 0 1 k
+(C=0 M=0 Y=0 K=100) Pc
+0 0.1 1 0 k
+(C=0 M=10 Y=100 K=0) Pc
+0 0.5 0 0 k
+(C=0 M=50 Y=0 K=0) Pc
+0 0.5 1 0 k
+(C=0 M=50 Y=100 K=0) Pc
+1 0.55 1 0 k
+(C=100 M=55 Y=100 K=0) Pc
+1 0.9 0.1 0 k
+(C=100 M=90 Y=10 K=0) Pc
+0.15 1 1 0 k
+(C=15 M=100 Y=100 K=0) Pc
+0.45 0.9 0 0 k
+(C=45 M=90 Y=0 K=0) Pc
+0.5 0.4 0.3 0 k
+(C=50 M=40 Y=30 K=0) Pc
+0.5 0.85 1 0 k
+(C=50 M=85 Y=100 K=0) Pc
+0.75 0.05 1 0 k
+(C=75 M=5 Y=100 K=0) Pc
+0.75 0.9 0 0 k
+(C=75 M=90 Y=0 K=0) Pc
+0.8 0.05 0 0 k
+(C=80 M=5 Y=0 K=0) Pc
+Bb
+2 (Black, White) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Black, White) Pc
+Bb
+2 (Chrome) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Chrome) Pc
+Bb
+2 (Rainbow) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Rainbow) Pc
+Bb
+0 0 0 0 Bh
+2 (Yellow & Orange Radial) -7895 8611 0 0 1 0 0 1 0 0 Bg
+0 BB
+(Yellow & Orange Radial) Pc
+(Brick) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Brick) Pc
+(Confetti) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Confetti) Pc
+(Leaves - Fall ) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Leaves - Fall ) Pc
+(Stripes) 0 0 1 1 0 0 0 0 0 [1 0 0 1 0 0] p
+(Stripes) Pc
+PB
+%AI5_EndPalette
+%AI5_Begin_NonPrinting
+Np
+%AI8_BeginPluginObject
+(Adobe Brush Manager Order)
+(Adobe Brush Manager Order)
+( Adobe Calligraphic Brush Tool/ 6 pt Flat / Adobe Calligraphic Brush T) -
+(ool/ 10 pt Oval/ Adobe Calligraphic Brush Tool/ 12 pt Oval / Adobe Cal) -
+(ligraphic Brush Tool/ 20 pt Oval/ Adobe Calligraphic Brush Tool/ 25 pt) -
+( Round / Adobe Calligraphic Brush Tool/ 50 pt Flat/ Adobe Scatter Brus) -
+(h Tool/ Dog Tracks/ Adobe Scatter Brush Tool/ Fall Leaf/ Adobe Scatter) -
+( Brush Tool/ Ladybug/ Adobe Scatter Brush Tool/ Push Pin/ Adobe Scatte) -
+(r Brush Tool/ Strawberry/ Adobe Scatter Brush Tool/ Twinkle Star / Ado) -
+(be ArtOnPath Brush Tool/ Marker/ Adobe ArtOnPath Brush Tool/ Tapered S) -
+(troke/ Adobe ArtOnPath Brush Tool/ Arrow/ Adobe ArtOnPath Brush Tool/ ) -
+(Paintbrush/ Adobe ArtOnPath Brush Tool/ Type/ Adobe PatternOnPath Brus) -
+(h Tool/ Double Lines/ Adobe PatternOnPath Brush Tool/ Laurel/ Adobe Pa) -
+(tternOnPath Brush Tool/ Rope /) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(6 pt Flat )
+(1 4 8 10 10 90 90 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(10 pt Oval)
+(1 1 19 15 15 130 130 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(12 pt Oval )
+(1 7 17 45 45 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(20 pt Oval)
+(1 20 20 20 100 40 80 0 2 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(25 pt Round )
+(1 10 40 100 100 0 0 2 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Calligraphic Brush Tool)
+(50 pt Flat)
+(1 40 60 0 0 44 44 0 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Arrow)
+(1 / New Pattern 45/ / / / / 5 0.898039 0 0 /  2 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Marker)
+(1 / New Pattern 8/ / / / / 0 0 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Paintbrush)
+(1 / New Pattern 5/ / / / / 1 0.5 0.85 1 0.45 /  0 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Tapered Stroke)
+(1 / New Pattern 83/ / / / / 1 0 0 0 1 /  1 1 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe ArtOnPath Brush Tool)
+(Type)
+(1 / New Pattern 50/ / / / / 1 0.952941 0.94902 0.196078 0.0745098 /  1) -
+( 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Double Lines)
+(1 / New Pattern 62/ New Pattern 63/ New Pattern 64/ / / 1 1 0.14 0.09 ) -
+(0 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Laurel)
+(1 / New Pattern 65/ New Pattern 42/ New Pattern 67/ / New Pattern 69/ ) -
+(1 0 0.55 1 0.3 /  1 0 1 0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe PatternOnPath Brush Tool)
+(Rope )
+(1 / New Pattern 1/ / / New Pattern 3/ New Pattern 6/ 5 0 0 0 /  1 0 1 ) -
+(0 1 0 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Dog Tracks)
+(1 /New Pattern 41/ 1 0 0 0 1 / 0 1 1 0 1 1 0 0 0 0 -90 -90 0 1 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Fall Leaf)
+(1 /New Pattern 34/ 1 0.0745 0.9 0.9019 0.18 / 0 0.602793 1 1 0.1 1 1 -) -
+(1 1 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Ladybug)
+(1 /New Pattern 10/ 5 0.898039 0 0 / 0 1 1 0 0.803911 1.2 1 -1.55 1.55 ) -
+(1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Push Pin)
+(1 /New Pattern 36/ 1 0.025 0.1 0.475 0 / 0 1 1 0 0.401676 1 1 -1.06145) -
+( 1.06 1 -180 180 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Strawberry)
+(1 /New Pattern 37/ 1 0 0 0 1 / 0 0.803911 1 1 0.803911 1 1 -0.5 0.5 1 ) -
+(-75 75.419 1 0 0) .
+%AI8_EndPluginObject
+%AI8_BeginPluginObject
+(Adobe Scatter Brush Tool)
+(Twinkle Star )
+(1 /New Pattern 2/ 0 1 / 1 0.5 1 1 0.25 1 1 -0.5 0.5 1 0 0 0 0 0) .
+%AI8_EndPluginObject
+%AI5_End_NonPrinting--
+%AI5_Begin_NonPrinting
+Np
+%AI8_PluginGroupInfo
+(Adobe Path Blends) (Adobe Blends Plugin) (Live Blends.aip)
+%AI8_PluginGroupInfo
+(Adobe PatternOnPath Brush Tool) (Adobe Pattern Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe ArtOnPath Brush Tool) (Adobe Art Brush Plugin) (ArtOnPath.aip)
+%AI8_PluginGroupInfo
+(Adobe Calligraphic Brush Tool) (Adobe Calligraphic Brush Plugin) (Calligraphic Brush Tool.aip)
+%AI8_PluginGroupInfo
+(Adobe Scatter Brush Tool) (Adobe Scatter Brush Plugin) (Scatter Brush Tool.aip)
+%AI5_End_NonPrinting--
+%%EndSetup
+%AI5_BeginLayer
+1 1 1 1 0 0 1 0 79 128 255 0 50 Lb
+(Layer 1) Ln
+0 A
+0 O
+0.0745 0.0157 0.0275 0 0.9294 0.9804 0.9569 Xa
+0 R
+0 0 0 1 K
+800 Ar
+0 J 1 j 2.8346 w 1 M []0 d%AI3_Note:0 D
+0 XR
+295.3364 737.0059 m
+444.1553 630.707 l
+153.604 630.707 l
+295.3364 737.0059 l
+b1 Ap
+0.0314 0.3059 0.2039 0.0039 0.9882 0.6902 0.6706 Xa
+217.3838 602.3608 m
+141.7314 602.3608 L
+141.7314 659.0542 L
+217.3838 659.0542 L
+217.3838 602.3608 L
+b0.3961 0.0941 0 0 0.6078 0.7765 0.949 Xa
+451.6768 602.3608 m
+373.29 602.3608 L
+373.29 659.0542 L
+451.6768 659.0542 L
+451.6768 602.3608 L
+b0 To
+1 0 0 1 388.2842 623.6211 0 Tp
+0 Tv
+TP
+0 Tr
+0 0 0 1 k
+0 j 1 w 4 M%_ 0 50 XQ
+/_Helvetica 22.6772 21.1125 -5.1022 Tf
+0 Ts
+100 100 Tz
+0 Tt
+%_0 0 100 100 Xu
+%AI55J_GlyphSubst: GlyphSubstNone 
+1 TA
+%_ 0 XL
+0 TY
+0 TV
+36 0 Xb
+XB
+0 0 5 TC
+100 100 200 TW
+25 TG
+0 0 0 Ti
+0 Ta
+0 1 2 2 3 Th
+0 Tq
+240 Tg
+0 0 Tl
+0 Tc
+0 Tw
+(Style) Tx 1 0 Tk
+(\r) TX 
+TO
+0 To
+1 0 0 1 152.8174 623.6211 0 Tp
+0 Tv
+TP
+0 Tr
+(Logic) Tx 1 0 Tk
+(\r) TX 
+TO
+0 Ap
+0.0745 0.0157 0.0275 0 0.9294 0.9804 0.9569 Xa
+0 R
+0 0 0 1 K
+1 j 2.8346 w 1 M295.3364 630.707 m
+295.3364 729.9199 l
+B1 Ap
+0.2431 0.0314 0.1765 0.0039 0.7569 0.8784 0.7765 Xa
+345.5557 602.3604 m
+242.2476 602.3604 L
+242.2476 659.0537 L
+345.5557 659.0537 L
+345.5557 602.3604 L
+b0 To
+1 0 0 1 252.8169 623.6206 0 Tp
+0 Tv
+TP
+0 Tr
+0 0 0 1 k
+0 j 1 w 4 M(Content) Tx 1 0 Tk
+(\r) TX 
+TO
+0 0.1 0.36 0 k
+0 R
+0 0 0 1 K
+1 j 2.8346 w 1 M373.29 701.5732 m
+218.9414 701.5732 L
+218.9414 758.2661 L
+373.29 758.2661 L
+373.29 701.5732 L
+b0 To
+1 0 0 1 229.6685 722.833 0 Tp
+0 Tv
+TP
+0 Tr
+0 0 0 1 k
+0 j 1 w 4 M(Management) Tx 1 0 Tk
+(\r) TX 
+TO
+LB
+%AI5_EndLayer--
+%%PageTrailer
+gsave annotatepage grestore showpage
+%%Trailer
+Adobe_Illustrator_AI5 /terminate get exec
+Adobe_shading_AI8 /terminate get exec
+Adobe_ColorImage_AI6 /terminate get exec
+Adobe_typography_AI5 /terminate get exec
+Adobe_cshow /terminate get exec
+Adobe_level2_AI5 /terminate get exec
+%%EOF
diff --git a/non-releases/trunk_before_flattening/misc/graphics/xml.apache.org-bars.psd b/non-releases/trunk_before_flattening/misc/graphics/xml.apache.org-bars.psd
new file mode 100644
index 0000000..68b4941
--- /dev/null
+++ b/non-releases/trunk_before_flattening/misc/graphics/xml.apache.org-bars.psd
Binary files differ
diff --git a/non-releases/trunk_before_flattening/mount-table.xml.sample b/non-releases/trunk_before_flattening/mount-table.xml.sample
new file mode 100644
index 0000000..86904db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/mount-table.xml.sample
@@ -0,0 +1,46 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<mount-table>
+  <!--
+    The mount table allows to mount directories external to the Cocoon webapp without
+    changing the main sitemap. To activate the mount-table, just copy or rename this file
+    to "mount-table.xml" to see it automatically activated.
+    
+    Each mount below will direct requests starting with the given uri-prefix to the corresponding
+    sitemap. The syntax is exactly the same as the one of <map:mount>.
+    
+    The mount-table is especially useful for two purposes:
+    - for all users, to mount into Cocoon external directories (demos, prototypes, projects) without
+      having to change the main Cocoon sitemap. This allows these mounts to "survive" a update to a
+      more recent version of Cocoon.
+    
+    - for cocoon contributors, to mount the source of Cocoon examples instead of their copy placed in
+      build/webapp by the build process. This avoids many of the hassles related to editing a copy of
+      the sources, often leading to sync problems.
+  -->
+  
+  <!--
+      example: mount the woody source samples at "woody-samples/"     
+      (don't forget the / at the end of the path name)
+   -->
+  <mount uri-prefix="woody-samples/" src="../../src/blocks/woody/samples/"/>
+
+  
+  <!-- example: mount a prototype located elsewhere on the filesystem at "proto/"
+       (kept commented as the path is not likely to exist on your filesystem) -->
+  <mount uri-prefix="proto/" src="file://c:/my/projects/prototype/"/>
+  
+</mount-table>
diff --git a/non-releases/trunk_before_flattening/pom.xml b/non-releases/trunk_before_flattening/pom.xml
new file mode 100644
index 0000000..5c97bd9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | This is the main Maven file
+    | @version $Id$
+    +-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.cocoon</groupId>
+  <artifactId>cocoon</artifactId>
+  <packaging>pom</packaging>
+  <version>2.2.0-SNAPSHOT</version>
+  <name>Apache Cocoon</name>
+  <url>http://cocoon.apache.org</url>
+  <modules>
+    <module>core</module>
+<!--
+    <module>core/test-core</module>
+    <module>webapp</module>
+    <module>src/blocks</module>
+    <module>src/mocks</module>
+-->
+  </modules>
+  <repositories>
+    <repository>
+      <id>apache-maven2</id>
+      <name>Apache Maven2 Repository</name>
+      <url>http://cvs.apache.org/maven-snapshot-repository</url>
+    </repository>
+    <repository>
+      <id>apache-cvs</id>
+      <name>Apache CVS Repository</name>
+      <url>http://cvs.apache.org/repository</url>
+      <layout>legacy</layout>
+    </repository>
+    <repository>
+      <id>maven-snapshot</id>
+      <name>Maven snapshot Repository</name>
+      <url>http://snapshots.maven.codehaus.org/maven2/</url>
+    </repository>
+  </repositories>
+<!--
+  <scm>
+    <connection>http://svn.apache.org/repos/asf/cocoon/trunk</connection>
+    <url>http://svn.apache.org/repos/asf/cocoon/trunk</url>
+  </scm>
+-->
+  <distributionManagement>
+    <repository>
+      <id>apache-maven-snapshot</id>
+      <name>repository</name>
+      <url>scpexe://cvs.apache.org/x1/www/cvs.apache.org/maven-snapshot-repository</url>
+    </repository>
+    <snapshotRepository>
+      <id>apache-maven-snapshot</id>
+      <name>repository</name>
+      <url>scpexe://cvs.apache.org/x1/www/cvs.apache.org/maven-snapshot-repository</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.wagon</groupId>
+         <artifactId>wagon-ssh-external</artifactId>
+         <version>1.0-alpha-6-SNAPSHOT</version>
+      </extension>
+    </extensions>
+  </build>
+</project>
diff --git a/non-releases/trunk_before_flattening/props.xargs b/non-releases/trunk_before_flattening/props.xargs
new file mode 100644
index 0000000..9b22a39
--- /dev/null
+++ b/non-releases/trunk_before_flattening/props.xargs
@@ -0,0 +1,63 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+
+# ------------------------------------------------------------------------
+# Knopflerfish OSGI initialization file
+# Properties used by both init.xargs and restart.xargs
+# ------------------------------------------------------------------------
+
+# The Service Platform ID should be used by bundles needing to
+# a unique ID for the platform itself
+-Dorg.osgi.provisioning.spid=knopflerfish
+
+# Initial startup verbosity, 0 is low verbosity
+-Dorg.knopflerfish.verbosity=0
+
+
+# URL to bundle repository
+-Doscar.repository.url=http://www.knopflerfish.org/repo/repository.xml
+
+# Various debug flags
+-Dorg.knopflerfish.framework.debug.packages=false
+-Dorg.knopflerfish.framework.debug.errors=true
+-Dorg.knopflerfish.framework.debug.classloader=false
+-Dorg.knopflerfish.framework.debug.startlevel=false
+-Dorg.knopflerfish.framework.debug.ldap=false
+
+# Comma-separated list of packges exported by system classloader
+-Dorg.osgi.framework.system.packages=
+
+# Flag for publicly exporting the bundle: special URL handler, might be a security risk
+-Dorg.knopflerfish.osgi.registerbundleurlhandler=true
+
+# Web server properties
+-Dorg.knopflerfish.http.dnslookup=false
+-Dorg.osgi.service.http.port=8888
+
+-Dorg.knopflerfish.startlevel.use=true
+
+# Log service properties
+-Dorg.knopflerfish.log.out=false
+-Dorg.knopflerfish.log.level=info
+-Dorg.knopflerfish.log.grabio=true
+-Dorg.knopflerfish.log.file=true
+
+#consoletelnet properties
+-Dorg.knopflerfish.consoletelnet.user=admin
+-Dorg.knopflerfish.consoletelnet.pwd=admin
+-Dorg.knopflerfish.consoletelnet.port=23
+
+# cocoon properties
+# Lazy mode doesn't work yet
+-Dorg.apache.cocoon.core.LazyMode=false
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/restart.xargs b/non-releases/trunk_before_flattening/restart.xargs
new file mode 100644
index 0000000..e01e6f8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/restart.xargs
@@ -0,0 +1,23 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+
+# ------------------------------------------------------------------------
+# Knopflerfish OSGI initialization file
+# This one is used when -init is not present or when fwdir exists 
+# ------------------------------------------------------------------------
+
+# load common properties
+-xargs props.xargs
+
+-launch 0
diff --git a/non-releases/trunk_before_flattening/settings.xml b/non-releases/trunk_before_flattening/settings.xml
new file mode 100644
index 0000000..066dbe2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/settings.xml
@@ -0,0 +1,23 @@
+<settings>
+  <localRepository>tempRepo</localRepository>
+  <mirrors>
+    <mirror>
+      <mirrorOf>central</mirrorOf>
+      <id>ibiblioEuropeanMirror</id>
+      <url>http://mirrors.dotsrc.org/maven2</url>
+    </mirror>
+    <!-- 
+    <mirror>
+      <mirrorOf>central</mirrorOf>
+      <id>ibiblioAustralianMirror</id>
+      <url>http://public.planetmirror.com/pub/maven2</url>
+    </mirror>    
+     -->
+  </mirrors>
+  <servers>
+    <server>
+      <id>apache-maven-snapshot</id>
+      <username>jheymans</username>
+    </server>
+  </servers>
+</settings>
diff --git a/non-releases/trunk_before_flattening/src/confpatch/cocoon-reload.xweb b/non-releases/trunk_before_flattening/src/confpatch/cocoon-reload.xweb
new file mode 100644
index 0000000..5108545
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/confpatch/cocoon-reload.xweb
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xweb xpath="/web-app/servlet/init-param[param-name='allow-reload']/param-value"
+      if-prop="config.allow-reloads"
+      remove="/web-app/servlet/init-param[param-name='allow-reload']/param-value/text()"
+      unless="self::node()[. = 'yes']"
+>yes</xweb>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/confpatch/enable-uploads.xweb b/non-releases/trunk_before_flattening/src/confpatch/enable-uploads.xweb
new file mode 100644
index 0000000..ae6779e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/confpatch/enable-uploads.xweb
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xweb xpath="/web-app/servlet/init-param[param-name='enable-uploads']/param-value"
+      if-prop="config.enable-uploads"
+      remove="/web-app/servlet/init-param[param-name='enable-uploads']/param-value/text()"
+      unless="self::node()[. = 'true']"
+>true</xweb>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/confpatch/mount-table.xmap b/non-releases/trunk_before_flattening/src/confpatch/mount-table.xmap
new file mode 100644
index 0000000..0f87927
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/confpatch/mount-table.xmap
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xmap xpath="/sitemap/pipelines/pipeline"
+    unless="match[@type='mount-table']"
+    insert-after="match[contains(@pattern,'api')]" 
+    replace-properties="true">
+
+    <!--+
+        | Find a match in the "mount-table.xml" file, if present. It allows to mount other
+        | directories without touching this main sitemap (and thus loosing changes on rebuild).
+        +-->
+    <map:match type="mount-table" pattern="${build.mounttable}">
+      <map:mount src="{src}" uri-prefix="{uri-prefix}"/>
+    </map:match>
+</xmap>
diff --git a/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/JavaArchiveFilter.java b/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/JavaArchiveFilter.java
new file mode 100644
index 0000000..3975cde
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/JavaArchiveFilter.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.File;
+import java.io.FileFilter;
+
+/**
+ * Implements a filter for java archives.
+ *
+ * @version $Id$
+ * @deprecated To be removed in Cocoon 2.3
+ */
+public class JavaArchiveFilter implements FileFilter {
+
+    public boolean accept(File file) {
+        String name = file.getName().toLowerCase();
+        return (name.endsWith(".jar") || name.endsWith(".zip"));
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/MRUBucketMap.java b/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/MRUBucketMap.java
new file mode 100644
index 0000000..49c8f2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/deprecated/java/org/apache/cocoon/util/MRUBucketMap.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * A MRUBucketMap is an efficient ThreadSafe implementation of a Map with
+ * addition of the removeLast method implementing LRU removal policy.
+ * <br />
+ * MRUBucketMap is based on the Avalon's BucketMap.
+ *
+ * @deprecated Use a corresponding map from commons-collections
+ * @version $Id$
+ */
+public final class MRUBucketMap implements Map {
+    
+    private static final int DEFAULT_BUCKETS = 255;
+    private final Node[] buckets;
+    private final Object[] locks;
+    private final Node header = new Node();
+    private int size;
+
+    /**
+     * Creates map with default number of buckets.
+     */
+    public MRUBucketMap() {
+        this( DEFAULT_BUCKETS );
+    }
+
+    /**
+     * Creates map with specified number of buckets.
+     */
+    public MRUBucketMap( int numBuckets ) {
+        int size = Math.max( 17, numBuckets );
+
+        // Ensure that bucketSize is never a power of 2 (to ensure maximal distribution)
+        if( size % 2 == 0 ) {
+            size--;
+        }
+
+        this.buckets = new Node[ size ];
+        this.locks = new Object[ size ];
+
+        for( int i = 0; i < size; i++ ) {
+            this.locks[ i ] = new Object();
+        }
+
+        this.header.mru_next = this.header.mru_previous = this.header;
+    }
+
+    private final int getHash( Object key ) {
+        final int hash = key.hashCode() % this.buckets.length;
+        return ( hash < 0 ) ? hash * -1 : hash;
+    }
+
+    public Set keySet() {
+        Set keySet = new HashSet();
+
+        for( int i = 0; i < this.buckets.length; i++ ) {
+            synchronized( this.locks[ i ] ) {
+                Node n = this.buckets[ i ];
+
+                while( n != null ) {
+                    keySet.add( n.key );
+                    n = n.next;
+                }
+            }
+        }
+
+        return keySet;
+    }
+
+    /**
+     * Returns the current number of key, value pairs.
+     */
+    public int size() {
+        return this.size;
+    }
+
+    /**
+     * Put a reference in the Map.
+     */
+    public Object put( final Object key, final Object value ) {
+        if( null == key || null == value ) {
+            return null;
+        }
+
+        int isNew = 0;
+        Node node;
+        Object oldValue = null;
+
+        int hash = getHash( key );
+
+        synchronized( this.locks[ hash ] ) {
+            Node n = this.buckets[ hash ];
+            if( n == null ) {
+                node = new Node();
+                node.key = key;
+                node.value = value;
+                this.buckets[ hash ] = node;
+                isNew = 1;
+            } else {
+                // Set n to the last node in the linked list.  Check each key along the way
+                //  If the key is found, then change the value of that node and return
+                //  the old value.
+                for( Node next = n; next != null; next = next.next ) {
+                    n = next;
+
+                    if( n.key.equals( key ) ) {
+                        oldValue = n.value;
+                        n.value = value;
+                        break;
+                    }
+                }
+
+                if (oldValue == null) {
+                    // The key was not found in the current list of nodes,
+                    // add it to the end in a new node.
+                    node = new Node();
+                    node.key = key;
+                    node.value = value;
+                    n.next = node;
+                    isNew = 1;
+                } else {
+                    // The key was found in the list. Move it to the head.
+                    node = n;
+                }
+            }
+        }
+
+        synchronized ( this.header ) {
+            if (isNew == 0) {
+                // Remove
+                node.mru_previous.mru_next = node.mru_next;
+                node.mru_next.mru_previous = node.mru_previous;
+            }
+            // Move node to the head.
+            node.mru_previous = this.header;
+            node.mru_next = this.header.mru_next;
+            node.mru_previous.mru_next = node;
+            node.mru_next.mru_previous = node;
+            this.size += isNew;
+        }
+
+        return oldValue;
+    }
+
+    public Object get( final Object key ) {
+        if( null == key ) {
+            return null;
+        }
+
+        Node n;
+
+        int hash = getHash( key );
+
+        synchronized( this.locks[ hash ] ) {
+            n = this.buckets[ hash ];
+
+            while( n != null ) {
+                if( n.key.equals( key ) ) {
+                    break;
+                }
+
+                n = n.next;
+            }
+        }
+
+        if( n != null ) {
+            synchronized( this.header ) {
+                // Remove
+                n.mru_previous.mru_next = n.mru_next;
+                n.mru_next.mru_previous = n.mru_previous;
+                // Add first
+                n.mru_previous = this.header;
+                n.mru_next = this.header.mru_next;
+                n.mru_previous.mru_next = n;
+                n.mru_next.mru_previous = n;
+            }
+            return n.value;
+        }
+
+        return null;
+    }
+
+    public boolean containsKey( final Object key ) {
+        if( null == key ) {
+            return false;
+        }
+
+        int hash = getHash( key );
+
+        synchronized( this.locks[ hash ] ) {
+            Node n = this.buckets[ hash ];
+
+            while( n != null ) {
+                if( n.key.equals( key ) ) {
+                    return true;
+                }
+
+                n = n.next;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean containsValue( final Object value ) {
+        if( null == value ) {
+            return false;
+        }
+
+        synchronized( this.header ) {
+            for( Node n = this.header.mru_next; n != this.header; n = n.mru_next ) {
+                if( n.value.equals( value ) ) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public Collection values() {
+        Set valueSet = new HashSet();
+
+        synchronized( this.header ) {
+            for( Node n = this.header.mru_next; n != this.header; n = n.mru_next ) {
+                valueSet.add( n.value );
+            }
+        }
+
+        return valueSet;
+    }
+
+    public Set entrySet() {
+        Set entrySet = new HashSet();
+
+        synchronized( this.header ) {
+            for( Node n = this.header.mru_next; n != this.header; n = n.mru_next ) {
+                entrySet.add( n );
+            }
+        }
+
+        return entrySet;
+    }
+
+    /**
+     * Add all the contents of one Map into this one.
+     */
+    public void putAll( Map other ) {
+        Iterator i = other.keySet().iterator();
+
+        while( i.hasNext() ) {
+            Object key = i.next();
+            put( key, other.get( key ) );
+        }
+    }
+
+    public Object remove( Object key ) {
+        if( null == key ) {
+            return null;
+        }
+
+        Node n;
+
+        int hash = getHash( key );
+
+        synchronized( this.locks[ hash ] ) {
+            n = this.buckets[ hash ];
+            Node prev = null;
+
+            while( n != null ) {
+                if( n.key.equals( key ) ) {
+                    // Remove this node from the linked list of nodes.
+                    if( null == prev ) {
+                        // This node was the head, set the next node to be the new head.
+                        this.buckets[ hash ] = n.next;
+                    } else {
+                        // Set the next node of the previous node to be the node after this one.
+                        prev.next = n.next;
+                    }
+
+                    break;
+                }
+
+                prev = n;
+                n = n.next;
+            }
+        }
+
+        if (n != null) {
+            synchronized(this.header) {
+                // Remove
+                n.mru_previous.mru_next = n.mru_next;
+                n.mru_next.mru_previous = n.mru_previous;
+                this.size--;
+            }
+
+            return n.value;
+        }
+
+        return null;
+    }
+
+    public final boolean isEmpty() {
+        return this.size == 0;
+    }
+
+    public final void clear() {
+        synchronized ( this.header ) {
+            for( int i = 0; i < this.buckets.length; i++ ) {
+                this.buckets[ i ] = null;
+            }
+
+            this.header.mru_next = this.header.mru_previous = this.header;
+            this.size = 0;
+        }
+    }
+
+    public Map.Entry removeLast() {
+        Node node = this.header.mru_previous;
+        if (node == this.header) {
+            throw new NoSuchElementException("MRUBucketMap is empty");
+        }
+
+        remove(node.key);
+        node.mru_next = null;
+        node.mru_previous = null;
+        return node;
+    }
+
+    private static final class Node implements Map.Entry {
+        
+        protected Object key;
+        protected Object value;
+        protected Node next;
+
+        protected Node mru_previous;
+        protected Node mru_next;
+
+        public Object getKey() {
+            return this.key;
+        }
+
+        public Object getValue() {
+            return this.value;
+        }
+
+        public Object setValue( Object val ) {
+            Object retVal = this.value;
+            this.value = val;
+            return retVal;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/documentation/forrest.properties b/non-releases/trunk_before_flattening/src/documentation/forrest.properties
new file mode 100644
index 0000000..56883ea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/forrest.properties
@@ -0,0 +1,106 @@
+# Copyright 2002-2004 The Apache Software Foundation
+#
+# Licensed 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.
+
+##############
+# Properties used by forrest.build.xml for building the website
+# These are the defaults, un-comment them if you need to change them.
+##############
+
+# Prints out a summary of Forrest settings for this project
+#forrest.echo=true 
+
+# Project name (used to name .war file)
+#project.name=my-project
+
+# Specifies name of Forrest skin to use
+#project.skin=tigris
+#project.skin=pelt
+
+# comma separated list, file:// is supported
+#forrest.skins.descriptors=http://forrest.apache.org/skins/skins.xml,file:///c:/myskins/skins.xml
+
+##############
+# behavioural properties
+#project.menu-scheme=tab_attributes
+#project.menu-scheme=directories
+
+##############
+# layout properties
+
+# Properties that can be set to override the default locations
+#
+# Parent properties must be set. This usually means uncommenting
+# project.content-dir if any other property using it is uncommented
+
+project.status=../../status.xml
+project.content-dir=src
+project.forrest-configuration=src/forrest-configuration
+project.raw-content-dir=${project.content-dir}/content
+project.conf-dir=${project.forrest-configuration}/conf
+#project.sitemap-dir=${project.forrest-configuration}
+project.sitemap=${project.forrest-configuration}/sitemap.xmap
+project.xdocs-dir=${project.content-dir}/content/xdocs
+project.resources-dir=${project.forrest-configuration}/resources
+project.stylesheets-dir=${project.resources-dir}/stylesheets
+project.images-dir=${project.resources-dir}/images
+project.schema-dir=${project.resources-dir}/schema
+project.skins-dir=${project.forrest-configuration}/skins
+project.skinconf=${project.content-dir}/skinconf.xml
+project.lib-dir=${project.forrest-configuration}/lib
+project.classes-dir=${project.forrest-configuration}/classes
+project.translations-dir=${project.content-dir}/translations
+
+##############
+# validation properties
+
+# This set of properties determine if validation is performed
+# Values are inherited unless overridden.
+# e.g. if forrest.validate=false then all others are false unless set to true.
+#forrest.validate=true
+#forrest.validate.xdocs=${forrest.validate}
+#forrest.validate.skinconf=${forrest.validate}
+#forrest.validate.sitemap=${forrest.validate}
+#forrest.validate.stylesheets=${forrest.validate}
+#forrest.validate.skins=${forrest.validate}
+#forrest.validate.skins.stylesheets=${forrest.validate.skins}
+
+# *.failonerror=(true|false) - stop when an XML file is invalid
+#forrest.validate.failonerror=true
+
+# *.excludes=(pattern) - comma-separated list of path patterns to not validate
+# e.g.
+#forrest.validate.xdocs.excludes=samples/subdir/**, samples/faq.xml
+#forrest.validate.xdocs.excludes=
+
+
+##############
+# General Forrest properties
+
+# The URL to start crawling from
+#project.start-uri=linkmap.html
+# Set logging level for messages printed to the console
+# (DEBUG, INFO, WARN, ERROR, FATAL_ERROR)
+#project.debuglevel=ERROR
+# Max memory to allocate to Java
+#forrest.maxmemory=64m
+# Any other arguments to pass to the JVM. For example, to run on an X-less
+# server, set to -Djava.awt.headless=true
+#forrest.jvmargs=
+# The bugtracking URL - the issue number will be appended
+#project.bugtracking-url=http://issues.apache.org/bugzilla/show_bug.cgi?id=
+#project.bugtracking-url=http://issues.apache.org/jira/browse/
+# The issues list as rss
+#project.issues-rss-url=
+#I18n Property only works for the "forrest run" target.
+#project.i18n=true
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/no-comments.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/no-comments.xml
new file mode 100644
index 0000000..ce7d12d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/no-comments.xml
@@ -0,0 +1 @@
+<comments/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/no-generated-document.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/no-generated-document.xml
new file mode 100644
index 0000000..f812773
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/no-generated-document.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2002-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<html><body/></html>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/content_en.html
new file mode 100644
index 0000000..28ff62f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/content_en.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>Building your own Cocoon project using Ant</title></head>

+<body>

+<h1>Cocoon Blocks</h1>

+<h2>What is a block?</h2>

+tbw<br>

+<h2>Core blocks, non-core blocks and external blocks</h2>

+<p>The main goal of Cocoon blocks is to reduce Cocoon to a core.&nbsp;

+All functionality that isn't&nbsp; absolutly necessary to run Cocoon,

+is put into a block. But some of those blocks are needed by the most of

+our users and therefore they will also be part of a Cocoon

+distribution. Those blocks (Javaflow, Cocoon Forms, XML-Templating) are

+calledCore Blocks . (This doesn't mean that core blocks can't be

+released between Cocoon releases! Core blocks can be compared to the

+JDT or Ant plug-in of Eclipse which are part of every Eclipse

+distribution.)<br>

+<br>

+All other blocks (Non-Core Blocks) should sooner or later become

+independant from Cocoon and need to be downloaded and installed

+separatly. This is a major refactoring and will take time until it is

+finished. Some of these blocks may become their own projects, some will

+remain under the umbrella of the Cocoon project and some will move away

+to other hosts like cocoondev.org or Sourceforge.<br>

+<br>

+External blocks have never been part of a Cocoon.</p>

+<h2>Lifecycle of blocks</h2>

+tbw<br>

+<br>

+</body></html>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/meta.xml
new file mode 100644
index 0000000..69605bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/blocks/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://www.poetz.cc">Reinhard Poetz</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/content_en.html
new file mode 100644
index 0000000..8dea518
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/content_en.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Actions</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in Cocoon" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document lists all of the available actions of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+      
+<p>This document lists all of the available actions of Apache Cocoon and
+         describes their purpose.</p>
+    
+    
+<h1>Overview</h1>
+      
+<p>See the concepts document
+        <a href="../concepts/actions.html">Creating and Using Actions</a>.
+      </p>
+    
+    
+<h1>The Actions in Apache Cocoon</h1>
+      
+<p>Forthcoming...</p>
+      
+<ul>
+        
+<li>
+<a href="database-actions.html">Database Actions</a>
+</li>
+        
+<li>
+<a href="sendmail-action.html">Sendmail Action</a>
+</li>
+        
+<li>
+<a href="session-action.html">Session Action</a>
+</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/meta.xml
new file mode 100644
index 0000000..905a569
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/actions/actions.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/content_en.html
new file mode 100644
index 0000000..5a51516
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/content_en.html
@@ -0,0 +1,292 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>actions</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+</head>
+<body>
+<pre class="code">This is the proposal for a Action sitemap component. It shows the 
+basic ideas behind actions. For more information look at the javadoc  
+comments in the file Action.java in the org.apache.cocoon.acting 
+package. For a possible implementation look at the file HelloAction.java 
+or at the other actions in the same package. 
+ 
+To give you an overview of the discussion about sitemap Actions here is 
+an excerpt from the cocoon-dev mailing list: 
+ 
+------------------------------------&lt;&lt;&gt;&gt;------------------------------------- 
+ 
+Peter Donald wrote: 
+&gt; 
+&gt; At 04:15  9/9/00 +0200, you wrote: 
+&gt; &gt;  &lt;match type="uri" pattern="myapp/**"&gt; 
+&gt; &gt;    &lt;!-- the following Matcher make the overall request 
+&gt; &gt;         analysis and makes important information available 
+&gt; &gt;         to subsequent components through the objectModel and 
+&gt; &gt;         a Map for substitution in src= attributes. 
+&gt; &gt;         Maybe a Controller sitemap component would be more 
+&gt; &gt;         appropriate 
+&gt; &gt;    --&gt; 
+&gt; &gt;    &lt;match type="myapp-controller" pattern="not really used"&gt; 
+&gt; &gt;      &lt;select type="myapp-action-selector"&gt; 
+&gt; &gt;        &lt;when test="add"&gt; 
+&gt; &gt;          &lt;!-- here the {1} is delivered by the matcher 
+&gt; &gt;               "myapp-controller" 
+&gt; &gt;          --&gt; 
+&gt; &gt;          &lt;generate src="myapp/{1}/remove.xsp"/&gt; 
+&gt; &gt;        &lt;/when&gt; 
+&gt; &gt;        &lt;when test="remove"&gt; 
+&gt; &gt;          &lt;generate src="myapp/{1}/remove.xsp"/&gt; 
+&gt; &gt;        &lt;/when&gt; 
+&gt; &gt;        &lt;otherwise&gt; 
+&gt; &gt;          &lt;generate src="myapp/{1}/index.xml"/&gt; 
+&gt; &gt;        &lt;/otherwise&gt; 
+&gt; &gt;      &lt;/select&gt; 
+&gt; &gt;      &lt;select type="browser"&gt; 
+&gt; &gt;        &lt;when test="netscape"&gt; 
+&gt; &gt;          &lt;transform src="myapp/{1}/style-ns.xsl"/&gt; 
+&gt; &gt;          &lt;serialize type="html"/&gt; 
+&gt; &gt;        &lt;/when&gt; 
+&gt; &gt;        &lt;when test="wap"&gt; 
+&gt; &gt;          &lt;transform src="myapp/{1}/style-wap.xsl"/&gt; 
+&gt; &gt;          &lt;serialize type="wap"/&gt; 
+&gt; &gt;        &lt;/when&gt; 
+&gt; &gt;        &lt;otherwise&gt; 
+&gt; &gt;          &lt;transform src="myapp/{1}/style-ie.xsl"/&gt; 
+&gt; &gt;          &lt;serialize type="html"/&gt; 
+&gt; &gt;        &lt;/otherwise&gt; 
+&gt; &gt;      &lt;/select&gt; 
+&gt; &gt;    &lt;/match&gt; 
+&gt; &gt;  &lt;/match&gt; 
+&gt; &gt;  &lt;-- here we catch all requests not handled by the match above 
+&gt; &gt;      and redirect them to the login screen or an error page 
+&gt; &gt;  --&gt; 
+&gt; &gt;  &lt;match pattern="myapp/**"&gt; 
+&gt; &gt;    &lt;redirect-to uri="myapp/login"/&gt; 
+&gt; &gt;  &lt;/match&gt; 
+&gt; &gt;Well, this example might not be the best one but I think its 
+&gt; &gt;good enough to start a discussion about it. What do you think? 
+&gt; 
+&gt; I like the approach but before an implementation can be defined there is a 
+&gt; few questions that must be answered first. Namely 
+&gt; 
+&gt; * What is an Action ? 
+&gt; * How will you use actions ? 
+&gt; 
+&gt; What is an Action ? 
+&gt; ------------------- 
+&gt; 
+&gt; In the above case you have associated an Action with a resource. ie the 
+&gt; Remove action is associated with myapp/{1}/remove.xsp resource. Do actions 
+&gt; have to be associated with a resource or are they independent of resources. 
+&gt; I would say that they are independent - an Action framework should be able 
+&gt; to be used via multiple interfaces whether via cocoon, turbine, telnet, 
+&gt; mail etc. So the "ShutdownRealWorldMachine" action is accessible via the C2 
+&gt; interface, a telnet interface or via any number of other methods. 
+ 
+The example above is probably misleading because we don't have a Action 
+component in the sitemap so far. Generally speaking I think a Sitemap 
+Action is an object that acts upon an application model based on data 
+supplied by the environments objectModel (ie Request). It's its 
+responsibility to make some data available to the Sitemap engine as 
+further selection/matching criteria (a List object) as well as in the 
+objectModel for other sitemap components 
+ 
+Suppose the Interface of an Actions is like this: 
+ 
+   public Interface Action { 
+       public List act (Map objectModel); 
+   } 
+ 
+and also suppose that the nested elements of the &lt;map:act&gt; elements are 
+skipped if the action returns a null value instead of a List. 
+ 
+ &lt;match type="uri" pattern="myapp/**"&gt; 
+   &lt;act type="myaction"&gt; 
+     &lt;select type="action-selector"&gt; 
+       &lt;when test="remove"/&gt; 
+         &lt;generate src="myapp/{1}/remove.xsp"/&gt; 
+       &lt;/when&gt; 
+       ... 
+     &lt;/select&gt; 
+   &lt;/act&gt; 
+ &lt;/match&gt; 
+ 
+The List object supplied by the action is used by the sitemap engine to 
+replace occurrences like {1} from certain attributes like src= but this 
+is optional. So the Action is not really associated to a resource. It's 
+the selector which does this association. 
+ 
+&gt; An action is essentially a snippet of code that is executed in response to 
+&gt; a request in a certain context (or Environment in C2s case). The action can 
+&gt; add and change the context/environment data. 
+ 
+Agreed. 
+ 
+&gt; How granular can actions be ? 
+ 
+You should be able to be as granular as you want. 
+ 
+&gt; Does session validation count as an action ? 
+ 
+Why not? 
+ 
+&gt; How about authorisation and authentication ? 
+ 
+I still suppose to leave authentication to the container but I know 
+someone will do it with a sitemap component :/ 
+Authorisation is more dependant on the application context and there are 
+the possibilities to use AuthorisationMatchers, AuthorisationSelectors, 
+AuthorisationActions or a authorisation logicsheet, what ever suit your 
+needs best. 
+ 
+&gt; What about form validation ? 
+ 
+Even here, it depends. If you only want to validate form data a Selector 
+can be used to achieve that and in the &lt;map:when&gt; elements you 
+regenerate the resource if validation fails or choose an action to put 
+the form data into your application model and generate the next screen 
+or whatever. 
+ 
+&gt; When I program actions I use a extremely granular approach. 
+ 
+No problem, you should be able to do things like that 
+ 
+ &lt;match type="uri" pattern="myapp/**"&gt; 
+   &lt;act type="session validation"&gt; 
+     &lt;act type="form-validation"&gt; 
+       &lt;select type="validation-check"&gt; 
+         &lt;when test="ok"&gt; 
+           &lt;act type="model-update"/&gt; 
+           &lt;generate src="next-page"/&gt; 
+         &lt;/when&gt; 
+         &lt;otherwise&gt; 
+           &lt;generate src="this-page"/&gt; 
+         &lt;/otherwise&gt; 
+       &lt;/select&gt; 
+     &lt;/act&gt; 
+   &lt;/act&gt; 
+   &lt;generate src="login"/&gt; 
+ &lt;/match&gt; 
+ 
+&gt; There is also the idea of latent actions. For instance the latent Action is 
+&gt; transmitted between end-user and cocoon until they are activated. Actions 
+&gt; may also be made latent (or deactivated) in a couple of cases. Like when 
+&gt; you try to submit form but are not logged in - it will save action/form 
+&gt; data (or put action into latent state) and then after login commit the 
+&gt; action (or re-activate action). 
+ 
+Isn't this a matter how components play together? 
+ 
+&gt; How will you use actions ? 
+&gt; --------------------------- 
+&gt; 
+&gt; In many cases when I program to a an actions approach each request can 
+&gt; result in many actions being executed. For instance it is not uncommon for 
+&gt; an action chain to occur like the following. 
+&gt; 
+&gt; SessionValidatorAction --&gt; RoleAssignerAction --&gt; FormValidationAction --&gt; 
+&gt; FormDBEntryAction 
+&gt; 
+&gt; The SessionValidatorAction will check the session and if not exist then it 
+&gt; will put a magic token in environment so that after action is executed then 
+&gt; the rest of action-chain and output resource is ignored and the user is 
+&gt; redirected to a login page. 
+&gt; 
+&gt; The RoleAssignerAction (lame name I know ;-&gt;) will check if the current 
+&gt; user implements a certain role and if not redirect them to appropriate 
+&gt; NoEntry.html type page. 
+&gt; ... 
+&gt; 
+&gt; So when I design a sitemap for a web-application I want to somehow be able 
+&gt; to do the following. 
+&gt; 
+&gt; * Anything under webapp/ must run SessionValidatorAction 
+&gt; * Anything under webapp/admin must run RoleAssignerAction and check for 
+&gt; "admin" role 
+&gt; * Then specific resources webapp/a.xml, webapp/b.xml and webapp/admin/c.xml 
+&gt; must run FormValidationAction with appropriate form schema and the 
+&gt; appropriate FormDBEntryAction 
+ 
+Didn't get the last one? What is a FormDBEntryAction for? Probably an 
+XSP page? 
+ 
+&gt; * A user can also arbitrarily submit an action from any page (via post 
+&gt; request or perhaps a ?action=blah tacked onto URL) that must be executed. 
+ 
+  &lt;match type="uri" pattern="webapp/**"&gt; 
+    &lt;act type="session-validation"/&gt; 
+    &lt;match type="uri" pattern="webapp/admin"&gt; 
+      &lt;act type="assign-role"&gt; 
+        &lt;select type="role-selector"&gt; 
+          &lt;when test="admin"&gt; 
+            &lt;match type="uri" pattern="webapp/admin/c.xml"&gt; 
+              &lt;act type="form-validation src="admin/form-schema-c.xsd"/&gt; 
+              &lt;!-- the following next-page action has knowledge of the 
+                   sequence of pages and returns a List with the first 
+element 
+                   corresponding to the "next page" appropriate 
+depending on 
+                   values in the objectModel signaling successful 
+validation by 
+                   the previous action (type="form-validation"). The 
+following 
+                   three lines could be put into a sitemap resource 
+definition 
+                   and replaced by &lt;redirect-to resource="next-page"/&gt; 
+              --&gt; 
+              &lt;act type="next-page"&gt; 
+                &lt;generate src="{1}"/&gt; 
+              &lt;/act&gt; 
+            &lt;/match&gt; 
+          &lt;otherwise&gt; 
+            &lt;match type="uri-regexp" pattern="webapp/(a|b)\.xml"&gt; 
+              &lt;act type="form-validation src="form-schema-{1}.xsd"/&gt; 
+              &lt;act type="next-page"&gt; 
+                &lt;generate src="{1}"/&gt; 
+              &lt;/act&gt; 
+            &lt;/match&gt; 
+          &lt;/when&gt; 
+        &lt;/select&gt; 
+      &lt;/act&gt; 
+    &lt;/match&gt; 
+  &lt;/match&gt; 
+ 
+&gt; 
+&gt; ---------------------------------------------------------------------------- 
+&gt; --------- 
+&gt; 
+&gt; So what would I want to see in a Cocoon-Application framework ??? 
+&gt; 
+&gt; Well actions are independent of resources and exist in a separate namespace. 
+&gt; 
+&gt; Each request can in theory result in a action-pipeline. 
+&gt; 
+&gt; Each action can add stuff to it's context (or Environment). 
+&gt; 
+&gt; Each action can in theory short-cut the action pipeline and move to another 
+&gt; action-resource pipeline and also store remaining submitted actions as 
+&gt; latent actions. 
+&gt; 
+&gt; An action pipeline must not necessarily be associated with a resource (it 
+&gt; should instead be able to specify a resource that it goes to post processing). 
+&gt; 
+&gt; It may also be good to have an action that's sole purpose is to extract 
+&gt; explicit action requests and execute/store them (ActionExtractorAction + 
+&gt; ActionDispatcherAction ???) 
+ 
+Please answer these question yourself after you've read my explanations. 
+ 
+&gt; But anyways I mean in no way to imply C2 is bad and if you want to add 
+&gt; hooks into sitemap generation to allow for this sort of stuff (or even 
+&gt; better do it yourself ;&gt;) I would gladly switch all my development across 
+&gt; to C2 and I suspect many others would too :P. 
+ 
+Implementing the framework to use actions like I've mentioned through 
+out this mail is a matter of an hour or two. But you're right 
+implementing general actions for general usage is another thing. 
+ 
+Giacomo</pre>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/meta.xml
new file mode 100644
index 0000000..b3e76dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-actions2/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/actions.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/content_en.html
new file mode 100644
index 0000000..a68ee48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/content_en.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Augment Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in @doctitle@" name="DC.Subject">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the Augment transformer." name="DC.Description">
+</head>
+<body>
+  
+<h1>Augment Transformer</h1>
+   
+<p>
+    The AugmentTransformer 
+    augments all <span class="codefrag">href</span> attributes with the full path to the request.
+    If a <span class="codefrag">href</span> is already a full HTTP URL, or HTTPS URL the value of
+    href is not changed.
+   </p>
+   
+<p>
+    The AugmentTransformer has serveral configuration options. These options
+    may be specified by each request.
+   </p>
+   
+<dl>
+     
+<dt>mount</dt>
+     
+<dd>If this request parameter is specified it defines the URI relative
+       to the servlet's context-path. If no mount parameter is specified the 
+       resolution is calculated relative to the request URI.
+     </dd>
+   
+</dl>
+   
+   
+<ul>
+    
+<li>Name : augment</li>
+    
+<li>Class: org.apache.cocoon.transformation.AugmentTransformer</li>
+    
+<li>Cacheable: no.</li>
+   
+</ul>
+   
+<p>
+    A simple example might help to use the AugmentTransformer effectivly:
+   </p>
+   
+<p>
+    Add the AugmentTransformer to the components in your sitemap.xmap
+   </p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:transformers default="xslt"&gt;
+  ...
+    &lt;map:transformer name="augment"
+      src="org.apache.cocoon.transformation.AugmentTransformer"&gt;
+    &lt;/map:transformer&gt;
+  ...
+</pre>
+   
+<p>
+     Next define in your pipeline to use the AugmentTransformer
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="**book-**.xml"&gt;
+  &lt;map:generate src="docs/{1}book.xml"/&gt;
+  &lt;map:transform type="augment"&gt;
+    &lt;map:parameter name="mount" value="samples/flow/"/&gt;
+  &lt;/map:transform&gt;
+  ...
+</pre>
+
+   
+<p>
+     In the example above all href attributes which do not start with <span class="codefrag">http</span>, or
+     <span class="codefrag">https</span> are augmented.
+   </p>
+   
+<p>
+     Assuming Cocoon is deployed at <span class="codefrag">http://localhost:8080/cocoon</span> a 
+     href <span class="codefrag">href="overview.html"</span> is augmented 
+     to <span class="codefrag">href="http://localhost:8080/cocoon/samples/flow/overview.html"</span>.
+   </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/meta.xml
new file mode 100644
index 0000000..5b32e1e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-augment-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/augment-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/content_en.html
new file mode 100644
index 0000000..6c84fba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/content_en.html
@@ -0,0 +1,813 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Authentication Framework</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Introduction</h1>
+     
+<p>One central point in building a web application is authentication and authorization. The Cocoon
+        authentication framework is a flexible module for authentication, authorization and user management. 
+        A user can be legitimated using any information available via any source, e.g. an existing database,
+        LDAP or the file system. With this mechanism it is very easy to use an exisiting user
+        management/authentication system within Cocoon.</p>
+     
+<p>The basic concept of the authentication framework is to protect documents generated by Cocoon. 
+        By document we refer to the result of a request to Cocoon, this can either be the result
+        of a pipeline or of a reader defined in the sitemap.</p>
+     
+<p>A document is protected by a so called (authentication) handler. A document is associated to a 
+       defined handler to be protected. A user can only request this document if he is authenticated 
+       against this handler.</p>
+     
+<p>A handler can be used to protect several documents in the same way. If a user is authenticated 
+        he can access all these documents. It is possible to use different handlers, to product documents 
+        in different ways.</p>
+     
+<p>The use of the authentication framework and its components is described in the following
+        chapters.</p>
+     
+<div class="note">As you will see, the user management of the authentication framework is very flexible.
+       You can design your application without taking into account, which backend is used for the 
+       user management. This can be the file-system, a SQL database, an XML database, a LDAP directory, 
+       just anything. Simply by developing the <em>authentication resource</em>, you can connect to any 
+       system. And another advantage is the flexible switching between user databases. You can for example 
+       use the file-system for the development process and switch than later on to a LDAP system on the 
+       production system. This can be done by simply changing the <em>authentication resource</em>. If you 
+       test this resource on your production system, you don't have to test your whole application again. 
+       (Although in general this might be a good idea...).
+     </div>
+  
+  
+<h1>Sitemap-Components</h1>
+     
+<p>The authentication Framework adds some actions to the sitemap: the <em>auth-protect</em>
+        action, the <em>auth-login</em> action, the <em>auth-logout</em> action
+        and the <em>auth-loggedIn</em> action. The <em>authentication-manager</em> gets
+        the configuration for the authentication framework and the actions controle the pipelines. 
+        The <em>auth-login</em> and the <em>auth-logout</em> action control the
+        authentication whereas the <em>auth-loggedIn</em> action controls the application
+        flow.</p>
+    
+<div align="center">
+<img class="figure" alt="Overview" src="images/authentication-fw.jpg" height="360" width="480"></div>
+  
+  
+<h1>Protecting Documents</h1>
+     
+<p>One feature of the framework is the user authentication. A document can be
+        accessible for everyone or it can be protected using this framework. The process of
+        requesting a document can be described as follows:</p>
+     
+<ol>
+        
+<li>The user request a document (original document).
+        </li>
+        
+<li>The authentication framework checks if this document is protected. If no protection
+          is specified, the response to the request is this original document.
+        </li>
+        
+<li>If the document is protected, the framework checks, if the user is
+          authenticated to view it.
+        </li>
+        
+<li>If the user is authenticated, the response is the original
+          document. If not the framework redirects to a special redirect-to document. This
+          redirect-to document is freely configurable and can for example contain
+          information about the unauthorized access and in addition a login form.
+        </li>
+        
+<li>Using the login form an authentication resource can be called
+          with the corresponding user information (e.g. user id and password). This
+          authentication resource uses the framework for the authentication process.
+        </li>
+        
+<li>In case of a successful authentication the framework can redirect to
+          the original document (or to any configured start document).
+        </li>
+        
+<li>If the authentication fails another document is invoked by
+          the framework displaying information to the user.
+        </li>
+     
+</ol>
+     
+<p>This process is only one example for a use-case of the framework. It
+        can be configured for any authentication scheme. All resources are freely
+        configurable.</p>
+     
+<h2>The Authentication handler</h2>
+<p>The basic object for authentication is the so called (authentication)
+          handler. It controlles the access to the documents. Each document in the
+          sitemap can be related to exactly one authentication handler. All documents belonging
+          to the same handler are protected in the same way. If a user has access to the
+          handler, the user has the same access rights for all documents of this
+          handler.</p>
+<p>Each authentication handler needs the following mandatory
+          configuration:</p>
+<ul>
+          
+<li>A unique name.
+          </li>
+          
+<li>The authentication resource: A Cocoon pipeline trying to authenticate a user.
+              (We will see later on, that there are more possibilities than using a pipeline).
+          </li>
+          
+<li>The redirect-to document: This document is displayed when a not 
+              authorized user tries to access a protected document.
+          </li>
+        
+</ul>
+     
+<h2>The Configuration of a Handler</h2>
+<p>So let's have a look at the configuration. A handler can be configured in the sitemap.
+        It is a so-called component configuration for the authentication manager. This
+        configuration takes place in the <em>map:pipelines</em> section of a sitemap:</p>
+<pre class="code">
+&lt;map:sitemap&gt;
+    ...component definitions...
+
+&lt;map:pipelines&gt;
+  &lt;map:component-configurations&gt;
+    &lt;authentication-manager&gt;
+      &lt;handlers&gt;
+        &lt;handler name="portalhandler"&gt;
+          &lt;redirect-to uri="cocoon:/sunspotdemoportal"/&gt;
+          &lt;authentication uri="cocoon:raw:/sunrise-authuser"/&gt;
+        &lt;/handler&gt;
+      &lt;/handlers&gt;
+    &lt;/authentication-manager&gt;
+  &lt;/map:component-configurations&gt;
+&lt;map:pipeline&gt;
+   ... document pipelines following here:
+</pre>
+<p>Using a unique name for each handler (only alphabetical characters
+          and digits are allowed for the handler name), the framework manages different
+          handlers. So various parts of the sitemap can be protected in different ways.
+        </p>
+<p>A handler is inherited to a sub sitemap. Each sub sitemap can define
+           its own handlers. These handlers are only available to the sub sitemap
+           (and of course to its sub sitemaps). However, it is not possible to
+           redefine (overwrite) a previously defined handler in a sub sitemap.</p>
+     
+<h2>Protecting Documents</h2>
+<p>A document can be protected by associating it to a defined handler.
+        This is done by using the <em>auth-protect</em> action and the handler parameter:</p>
+<pre class="code">&lt;map:match pattern="protectedresource"&gt;
+  &lt;map:act type="auth-protect"&gt;
+    &lt;map:parameter name="handler" value="portalhandler"/&gt;
+    &lt;map:generate src="source/resource.xml"/&gt;
+    &lt;map:serialize type="xml"/&gt;
+  &lt;/map:act&gt;
+&lt;/map:match&gt;</pre>
+<p>If this document is requested, the action checks if the user is authenticated against the
+           defined handler. If not, the action automatically redirects to the <em>redirect-to</em> document 
+           configured in the handler. (In the example above this is the pipeline defined by <em>cocoon:/sunspotdemoportal</em>.</p>
+<p>If the user is authenticated, the commands inside the <em>map:act</em> will be execute and
+           the user gets the document itself.</p>
+<p>So, the <em>auth-protect</em> action must be included in the pipeline of the
+          document. It gets the handler information as a parameter. If the pipeline does 
+          not use the <em>auth-protect</em> action or the parameter <em>handler</em> is missing, 
+          the document is accessible by any user.</p>
+<div class="note">You will see learn later on how to efficiently protect several documents with a handler.</div>
+     
+<h2>The redirect-to document</h2>
+<p>If the requested document is not accessible to the user, the authentication framework
+          redirects to the configured <em>redirect-to</em> document. This document is a mandatory
+          configuration of the authentication handler as we have seen above.</p>
+<p>This <em>redirect-to</em> document is an unprotected pipeline in the
+          sitemap. For tracking which document was originally requested by the user, 
+          the <em>redirect-to</em> pipeline gets the request parameter <em>resource</em> 
+          with that value. In addition all parameters specified inside the <em>redirect-to</em> 
+          tag of the handler configuration are passed to the pipeline as well.</p>
+<p>For example, the <em>redirect-to</em> document can contain a form for the user
+          authentication. This form should invoke the real authentication process that is
+          described below. However, the document you show when an unauthorized access
+          is made, can be controlled by you by defining this <em>redirect-to</em>
+          document.</p>
+     
+     
+<h1>Authenticating a User</h1>
+        
+<p>Usually, the <em>redirect-to</em> document of a handler contains a form for the user 
+           to authenticate. But of course, you are not limited to this. No matter how the
+           <em>redirect-to</em> document looks like, the user has "somewhere" the abilitiy
+           to authenticate, so in most cases the user has a form where he can enter
+           his information (e.g. user name and password). You have to write a pipeline
+           presenting this form to the user. When the form is submitted, the authentication
+           process has to be started inside the authentication framework. As a submit
+           of a form invokes a request to Cocoon, a pipeline in the sitemap is triggered.
+           We refer to this pipeline with <em>login pipeline</em>.</p>
+     
+<h2>The Login Process</h2>
+<p>The authentication process is started by invoking the <em>auth-login</em> action.
+          So, the <em>login pipeline</em> has to contain this action:</p>
+<pre class="code">&lt;map:match pattern="login"&gt;
+  &lt;map:act type="auth-login"&gt;
+    &lt;map:parameter name="handler" value="portalhandler"/&gt;
+    &lt;map:parameter name="parameter_userid" value="{request-param:name}"/&gt;
+    &lt;map:parameter name="parameter_password" value="{request-param:password}"/&gt;
+    &lt;map:redirect-to uri="authentication-successful"/&gt;
+  &lt;/map:act&gt;
+  &lt;!-- authentication failed: --&gt;
+  &lt;map:generate src="auth_failed.xml"/&gt;
+  &lt;map:transform src="tohtml.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;</pre>
+<p>The <em>auth-login</em> action uses the handler parameter to call the
+          <em>authentication resource</em> of this handler. This <em>authentication resource</em> needs to
+          know the information provided by the user, e.g. in the form. For each piece of information an own
+          parameter is created. The name of this parameter has to start with "parameter_". 
+          So in the example above, the <em>authentication resource</em> gets two parameters: userid and password. As
+          the values of these parameters were sent by a form they need to be passed on
+          to the <em>authentication resource</em>. If you use "{request-param:...}" for the value of a
+          parameter, the <em>auth-login</em> action will pass the actual value of that request
+          parameter to the <em>authentication resource</em> (by using the input modules concept
+          of Cocoon).</p>
+<div class="note">You might be wondering why we explicitly pass the request parameters on to the
+          internal pipeline call. Note that the <em>authentication resource</em> of the
+          portalhandler is defined by <em>cocoon:raw</em>. By using this, no request
+          parameter of the original request is passed on to the internal pipeline by
+          default and therefore we have to define them explicitly. If you use
+          <em>cocoon:</em> then the parameters of the form are by default passed on
+          to the <em>authentication resource</em> and we could omit the parameter definition
+          from above. But we feel that it is safer to explicitly define them.</div>
+<p>If the user is not already authenticated with this handler, the framework calls
+          the <em>authentication resource</em> and passes it the parameters. If this
+          authentication is successful, the action returns a map and the sitemap
+          commands inside the <em>map:act</em> are executed. A session is created on
+          the server (if not already done) as well.</p>
+<p>If the authentication fails, the action does not deliver a map and
+        therefore the commands inside the <em>map:act</em> are skipped. The error
+          information delivered by the <em>authentication resource</em> is stored into the
+          <em>temporary</em> context. So you can get the information using either the
+          <em>session transformer</em> or the <em>session-context input module</em>.</p>
+<div class="note">As you can see from the example above, you are not limited in defining
+          the information the user has to provide. This can be either one field, two or
+          as many fields as you need.</div>
+     
+<h2>The authentication resource</h2>
+<p>The last chapter described the authentication process but left out
+          details about the authentication itself. This chapter closes this gap.</p>
+<p>The authentication can be done by different components:</p>
+<ul>
+          
+<li>A sitemap resource (pipeline).
+          </li>
+          
+<li>A distant resource, e.g. requested via HTTP.
+          </li>
+          
+<li>A java class.
+          </li>
+        
+</ul>
+<p>The first two are actually similar as in both cases a URI is called. So we
+          will talk about them in the next chapter. Authentication using a java class
+          is the topic of the following chapter.</p>
+<h3>Using a URI as the authentication resource</h3>
+<p>Using this flexible approach nearly any kind of authentication is
+          possible (e.g. database, LDAP). The <em>authentication resource</em> is another
+          mandatory configuration of the authentication handler:</p>
+<pre class="code">&lt;autentication-manager&gt;
+  &lt;handlers&gt;
+    &lt;!-- Now follows the handlers configuration --&gt;
+    &lt;handler name="portalhandler"&gt;
+      &lt;!-- The login resource --&gt;
+      &lt;redirect-to uri="cocoon:/sunspotdemoportal"/&gt;
+      &lt;authentication uri="cocoon:raw:/sunrise-authuser"/&gt;
+    &lt;/handler&gt;
+  &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+<p>If the <em>authentication resource</em> is a sitemap resource or a remote
+          resource, this resource is requested by the framework with the given parameters from
+          the <em>auth-login</em> action (see previous chapter). In addition all parameters inside 
+          the <em>authentication</em> tag of the handler configuration are passed to the resource. 
+          The response of this resource must contain valid XML conforming to the following scheme:</p>
+<pre class="code">&lt;authentication&gt;
+    &lt;ID&gt;Unique ID of the user in the system&lt;/ID&gt;
+    &lt;role&gt;rolename&lt;/role&gt; &lt;!-- optional --&gt;
+    &lt;data&gt;
+        Any additional optional information can be supplied here. 
+        This will be stored in the session for later retrieval
+    &lt;/data&gt;
+&lt;/authentication&gt;</pre>
+<p>The XML is very simply, only the root element <em>authentication</em> and the <em>ID</em>
+         element with a valid unique ID for the user in this handler is required. Everything else is optional.
+        </p>
+<p>The framework checks the response of the authentication resource for the
+          given scheme: the root node must be named <em>authentication</em> and one child called
+          <em>ID</em> must be present. In this case the authentication is successfull and
+          the framework creates an authentication session context and stores the XML inside.</p>
+<p>The mandatory information inside this XML scheme, the <em>ID</em> tag, is
+          an unique identification for the given user inside the web application or
+          more precisly inside this handler. The <em>role</em> is optional and can for example 
+          be used for categorizing users and displaying different functionality inside the Cocoon portal
+          engine).</p>
+<div class="note">As stated, the <em>role</em> element is optional, you can use your own
+        categorization and exchange it with a <em>roles</em> element or a <em>group</em>
+        element or leave it out, if you don't need it. In addition you can add any
+        other element there as well and access the information later on.</div>
+<p>Using the <em>data</em> node the <em>authentication resource</em> can pass any
+          information of the user into the session. From there you can retrieve the
+          information as long as the session is valid.</p>
+<p>If the authentication is not successful, the resource must create
+          an XML with the root node <em>authentication</em>, but of course without
+          the <em>ID</em> tag. In addition a <em>data</em> node can be added containing 
+          more information about the unsuccessful attempt. This data
+          node is then stored into the <em>temporay</em> context (see previous
+          chapter).</p>
+<div class="note">It is advisable to make an internal pipeline for the <em>authentication resource</em>.
+           An internal pipeline is not directly accessible by a user.</div>
+<h3>Using a Java class as the authentication resource</h3>
+<p>Using a class is an alternative for using a pipeline.
+           You can define this class in the handler configuration as an attribute
+           <em>authenticator</em> of the <em>authentication</em> element, e.g.:</p>
+<pre class="code">&lt;autentication-manager&gt;
+  &lt;handlers&gt;
+    &lt;!-- Now follows the handlers configuration --&gt;
+    &lt;handler name="portalhandler"&gt;
+      &lt;!-- The login resource --&gt;
+      &lt;redirect-to uri="cocoon:/sunspotdemoportal"/&gt;
+      &lt;authentication authenticator="mypkg.MyAuthenticator"/&gt;
+    &lt;/handler&gt;
+  &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+<p>This class must conform to the <em>Authenticator</em> interface. This
+            interface provides a method that tries to authenticate a User and 
+            delivers XML that is stored in the session on success. So, the behaviour 
+            is similar to the pipeline.</p>
+     
+<h2>Logging out</h2>
+<p>The logout process is triggered by the "auth-logout"
+          action:</p>
+<pre class="code">&lt;map:act type="auth-logout"&gt;
+  &lt;map:parameter name="handler" value="unique"/&gt;
+&lt;/map:act&gt;</pre>
+<p>This action logs the user out of the given handler and removes all
+          information about this handler stored in the session.</p>
+  
+  
+<h1>User Management</h1>
+     
+<p>In addition to the authentication the framework manages all kinds of
+        information belonging to the user in XML format. For this reason the framework
+        creates an own session context called <em>authentication</em>. All information 
+        is stored in this context.</p>
+     
+<p>The authentication information (the "authentication" scheme retrieved
+        from the authentication resource) is stored in this context, so you can
+        retrieve and change the information using the session transformer and the
+        usual getxml, setxml etc. commands, so we suggest you to read the session
+        context document.</p>
+     
+<div class="note">The <em>authentication</em> context is only available to the
+       <em>session transformer</em> if the pipeline, the transformer is
+       running in, is associated to the (authentication) handler. Or putting
+       it in other words: you have to use the <em>auth-project</em> action
+       in that pipeline. Otherwise the <em>authentication</em> context
+       is not available.</div>
+     
+<h2>Getting information from the context</h2>
+<p>Each information from within the context is gettable using an XML
+          tag:</p>
+<pre class="code">&lt;session:getxml context="authentication" path="/authentication/ID"/&gt; &lt;!-- Get the ID --&gt;
+&lt;session:getxml context="authentication" path="/authentication/data/username"/&gt;</pre>
+<p>The path expression is an absolute XPath-like expression where only
+          concrete nodes and attributes are allowed. The session transformer replaced
+          the tag with the value of the first node found in the context, this can either
+          be text or XML.</p>
+     
+<h2>Setting information in the context</h2>
+<p>Using another tag information can be stored into the
+          context:</p>
+<pre class="code">&lt;session:setxml context="authentication" path="/authentication/data/usersername"&gt;
+    Mr. Sunshine
+&lt;/session:setxml&gt;</pre>
+<p>Again the path is an absolute XPath-like expression where only
+          concrete nodes and attributes are allowed. If the requested node exists,
+          the framework changes the value of that node. If the node does not exists, the framework
+          adds it to the context with the given value.</p>
+<p>The tag is removed from the resource.</p>
+  
+  
+<h1>Application Management</h1>
+     
+<p>A very useful feature for building and maintaining web applications
+        is the application management. It allows to configure different
+        applications and to manage the user data for these applications.</p>
+     
+<h2>Configuring an Application</h2>
+<p>A "authentication" application is related to one authentication handler, so an
+          application is part of the authentication handler configuration:</p>
+<pre class="code">&lt;autentication-manager&gt;
+    &lt;handlers&gt;
+        &lt;handler name="unique"&gt;
+             ....redirect-to/authentication configuration
+             &lt;applications&gt; &lt;!-- the applications for this handler --&gt;
+                 &lt;application name="unique"&gt;
+                     &lt;load uri="loadapp"/&gt; &lt;!-- optional --&gt;
+                     &lt;save uri="saveapp"/&gt; &lt;!-- optional --&gt;
+                 &lt;/application&gt;
+             &lt;/applications&gt;
+        &lt;/handler&gt;
+    &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+<p>A configuration for an application consists of a unique name (only
+          alphabetical characters and digits are allowed for the application name) and
+          optional load and save resources. The application configuration can contain
+          application specific configuration values for the various parts of the
+          application, e.g. information for a portal.</p>
+<p>On a successful authentication the framework invokes for each application
+          of the handler the load resource (if present). The content or result of the
+          load resource is stored into the session context.</p>
+<p>The user does not always visit all sides or all applications at
+          once. So it is not necessary to load all applications in advance when not all
+          information is needed. Each application can specify if the data is loaded on
+          successful authentication or the first time needed:</p>
+<pre class="code">....&lt;application name="unique" loadondemand="true"/&gt;...</pre>
+<p>The load resource gets several parameters: all values of the
+          subnodes of the "authentication" node from the authentication context (e.g. ID, role
+          etc.) and the parameter "application" with the unique name of the application.
+          This unique name must not contain one of the characters '_', ':' or '/'.</p>
+<p>In addition the load and save resource get all parameters specified
+          inside the load / save tag of the handler configuration.</p>
+     
+<h2>Configuring the resources</h2>
+<p>For managing the application the framework needs to know to which
+          application a resource belongs. So in addition to the handler parameter the
+          auth-protect action gets the application name as a second parameter:</p>
+<pre class="code">&lt;map:match pattern="protectedresource"&gt;
+  &lt;map:action type="auth-protect"&gt;
+    &lt;map:parameter name="handler" value="unique handler name"/&gt;
+    &lt;map:parameter name="application" value="unique application name"/&gt;
+    
+    &lt;map:generate src="source/resource.xml"/&gt;
+            ...
+  &lt;/map:action&gt;
+&lt;/map:match&gt;
+</pre>
+<p>With this mechanism each application resource can easily access its
+          and only its information. If a resource has no "application" parameter it can
+          not access information of any application.</p>
+     
+<h2>Getting, setting and saving application information</h2>
+<p>Analogue to the access of the authentication data a resource can
+          access its application data:</p>
+<pre class="code">&lt;session:getxml context="authentication" path="/application/username"/&gt;
+&lt;session:setxml context="authentication"  path="/application/shoppingcart"&gt;&lt;item1/&gt;&lt;item2/&gt;&lt;/session:setxml&gt;</pre>
+<p>The path underlies the same restrictions and rules as always, but
+          it has to start with "/application/". </p>
+  
+  
+<h1>Module Management</h1>
+     
+<p>In addition to the application management the framework offers a facility
+        called module management. It enhances the application management by the
+        possibility to configure components for the application. For example the Cocoon
+        portal engine needs information about where the portal profile
+        for the user is retrieved from, where the layout is stored etc. Now each portal
+        needs this information. Assuming that a portal is an application each
+        application needs this information. As only the portal engine itself knows what
+        information it needs, the module management is a standarized way for
+        configuring such components.</p>
+     
+<p>The module configuration is part of the application
+        configuration:</p>
+     
+<pre class="code">&lt;autentication-manager&gt;
+  &lt;handlers&gt;
+    &lt;handler name="unique"&gt;
+      ....redirect-to/authentication configuration
+      &lt;applications&gt;  &lt;!-- the applications for this handler --&gt;
+        &lt;application name="unique"&gt;
+          ...
+          &lt;configuration name="portal"&gt;
+            ...portal configuration
+          &lt;/configuration&gt;
+        &lt;/application&gt;
+      &lt;/applications&gt;
+    &lt;/handler&gt;
+  &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+     
+<p>So whenever the portal engine is asked to build the portal it can
+        easily retrieve its configuration from the current application by getting the
+        module configuration named "portal".</p>
+  
+  
+<h1>User Administration</h1>
+     
+<p>Using the framework it is possible to add new roles to the system and to
+        add new users. For this purpose, there are several optional entries for the
+        authentication handler which provide the needed functionality:</p>
+     
+<pre class="code">&lt;autentication-manager&gt;
+  &lt;handlers&gt;
+    &lt;handler name="unique"&gt;
+             ...redirect-to/authentication configuration...
+
+      &lt;!-- Optional resource for loading user information --&gt;
+      &lt;load-users uri="cocoon:raw://financeresource-sunrise-loaduser"/&gt;
+
+      &lt;!-- Optional resource for loading roles information--&gt;
+      &lt;load-roles uri="cocoon:raw://financeresource-sunrise-roles"/&gt;
+
+      &lt;!-- Optional resource for creating a new user --&gt;
+      &lt;new-user uri="cocoon:raw://financeresource-sunrise-newuser"/&gt;
+
+      &lt;!-- Optional resource for creating a new role --&gt;
+      &lt;new-role uri="cocoon:raw://financeresource-sunrise-newrole"/&gt;
+
+      &lt;!-- Optional resource for changing user information --&gt;
+      &lt;change-user uri="cocoon:raw://financeresource-sunrise-newuser"/&gt;
+
+      &lt;!-- Optional resource for deleting a role --&gt;
+      &lt;delete-role uri="cocoon:raw://financeresource-sunrise-delrole"/&gt;
+
+      &lt;!-- Optional resource for deleting a user--&gt;
+      &lt;delete-user uri="cocoon:raw://financeresource-sunrise-deluser"/&gt;
+    &lt;/handler&gt;
+  &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+     
+<p>The entries are described in the following subchapters. All tags can
+        have additional parameter definitions which are passed to the given resource,
+        e.g:</p>
+     
+<pre class="code">&lt;!-- Optional resource for deleting a user--&gt;
+&lt;delete-user uri="cocoon:raw://financeresource-sunrise-deluser"&gt;
+  &lt;connection&gt;database&lt;/connection&gt;
+  &lt;url&gt;db:usertable&lt;/url&gt;
+&lt;/delete-user&gt;</pre>
+     
+<h2>Getting Roles</h2>
+<p>The <em>load-roles</em> resource is invoked from the framework whenever
+          it needs information about the available roles. This resource gets the
+          parameter "type" with the value "roles" and should deliver an XML schema with
+          the root node "roles" and for each role a subelement "role" with a text child
+          of the rolename:</p>
+<pre class="code">&lt;roles&gt;
+  &lt;role&gt;admin&lt;/role&gt;
+  &lt;role&gt;guest&lt;/role&gt;
+  &lt;role&gt;user&lt;/role&gt;
+&lt;/roles&gt;</pre>
+     
+<h2>Getting Users</h2>
+<p>The <em>load-users</em> resource is called whenever information
+          about the available users is needed. There are three different uses of this
+          resource:</p>
+<ul>
+          
+<li>Loading all users: The resource gets the parameter "type"
+             with the value "users". It should then deliver all users in the system.
+          </li>
+          
+<li>Loading all users of one role. The resource gets the
+             parameters "type" with the value "users" and "role" with the rolename.
+          </li>
+          
+<li>Load information of one user. The resource gets the
+             parameters "type" with the value "user", "role" with the rolename and "ID" with
+             the authentication ID of the user.
+          </li>
+        
+</ul>
+<p>The XML format of the resource should look like the
+          following:</p>
+<pre class="code">&lt;users&gt;
+  &lt;user&gt;
+    &lt;ID&gt;authentication ID&lt;/ID&gt;
+    &lt;role&gt;rolename&lt;/role&gt;
+    &lt;data&gt;
+       ... application specific data ...
+    &lt;/data&gt;
+  &lt;/user&gt;
+  &lt;user&gt;
+    ...
+  &lt;/user&gt;
+    ...
+&lt;/users&gt;</pre>
+     
+<h2>Creating a new role</h2>
+<p>The <em>new-role</em> resource creates a new role in the system. It
+          gets the parameters "type" with the value "role" and "role" with the new
+          rolename.</p>
+     
+<h2>Creating a new user</h2>
+<p>The <em>new-user</em> resource creates a new user with a role. It
+          gets the parameters <em>"type"</em> with the value <em>"user"</em>,
+          <em>"role"</em> with the rolename and <em>"ID"</em> with the new ID for this
+          user.</p>
+     
+<h2>Changing information of a user</h2>
+<p>The <em>change-user</em> resources changes information of a user.
+          It gets the parameters "type" with the value "user", "role" with the rolename
+          and "ID" with the ID of the user. In addition all - application specific -
+          information of this user is send as parameters.</p>
+     
+<h2>Delete a user</h2>
+<p>The <em>delete-user</em> resource should delete a user. It gets the
+          parameters "type" with the value "user", "role" with the rolename and "ID" with
+          the ID of the user.</p>
+     
+<h2>Delete a role</h2>
+<p>The <em>delete-role</em> resources deletes a role. It gets the
+          parameters "type" with the value "role" and "role" with the rolename .</p>
+  
+  
+<h1>Configuration Summary</h1>
+     
+<p>Here is a brief summary of the authentication handler configuration: </p>
+
+     
+<pre class="code">&lt;autentication-manager&gt;
+  &lt;handlers&gt;
+    &lt;handler name="unique"&gt;
+      &lt;!-- The redirect-to resource --&gt;
+      &lt;redirect-to uri="cocoon:raw://loginpage"/&gt;
+      &lt;!-- Authentication resource --&gt;
+      &lt;authentication uri="cocoon:raw://authenticationresource"/&gt;
+
+      &lt;load uri="cocoon:raw://authenticationsaveresource"&gt;
+        &lt;!-- optional parameters --&gt;
+      &lt;/load&gt;
+      &lt;!-- optional save resource --&gt;
+      &lt;save uri="cocoon:raw://authenticationsaveresource"&gt;
+        &lt;!-- optional parameters --&gt;
+      &lt;/save&gt;
+
+      &lt;applications&gt;
+        &lt;!-- the applications for this handler --&gt;
+        &lt;application name="unique"&gt;
+
+          &lt;!-- Loading/Saving --&gt;
+          &lt;load uri="cocoon:raw://loadapp"&gt;
+            &lt;!-- optional --&gt;
+            &lt;!-- optional parameters --&gt;
+          &lt;/load&gt;
+          &lt;save uri="cocoon:raw://saveapp"&gt;
+            &lt;!-- optional --&gt;
+            &lt;!-- optional parameters --&gt;
+          &lt;/save&gt;
+          &lt;!-- module configurations: --&gt;
+
+          &lt;configuration name="portal"&gt;
+            ...portal configuration
+          &lt;/configuration&gt;
+        &lt;/application&gt;
+      &lt;/applications&gt;
+
+    &lt;/handler&gt;
+  &lt;/handlers&gt;
+&lt;/autentication-manager&gt;</pre>
+  
+  
+<h1>Pipeline Patterns</h1>
+     
+<p>As explained in the previous chapters, the framework uses the <em>auth-protect</em>
+        action for authentication and protecting documents. This chapter shows some
+        common used pipeline patterns for using this framework.</p>
+     
+<h2>Single protected document</h2>
+<p>For protecting a document with an authentication handler only the <em>auth-protect</em>
+          action with the parameter configuration for the handler is required.</p>
+<p>Pattern:</p>
+<ol>
+          
+<li>Pipeline matching
+          </li>
+          
+<li>Using the <em>auth-protect</em> action for protecting
+          </li>
+        
+</ol>
+<p>Example:</p>
+<pre class="code">&lt;map:match pattern="protected"&gt;
+  &lt;map:act type="auth-protect"&gt;  &lt;!-- protect the resource --&gt;
+    &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+    &lt;map:generate src="resource.xml"/&gt;
+    &lt;map:transform src="toHTML"/&gt;
+    &lt;map:serialize/&gt;
+  &lt;/map:act&gt;
+&lt;/map:match&gt;</pre>
+<p>It is very important that the <em>auth-protect</em> action wrapps the real
+          pipeline, as the pipeline is only invoked if the action grants access. The
+          matching must be done before the action is checked as the action performs a
+          redirect for this document.</p>
+     
+<h2>Multiple protected documents</h2>
+<p>Often you want to protect a bunch of documents in the same way. One
+          solution is to use the single protected document pattern for each document.
+          With the multiple protected document pattern you only have to use the action
+          once for all documents and not within each document pipeline.</p>
+<p>The prerequisite for this is a common matching pattern for the
+          documents:</p>
+<ol>
+          
+<li>Pipeline pattern matching
+          </li>
+          
+<li>Using the <em>auth-protect</em> action for protection
+          </li>
+          
+<li>Pipeline matching
+          </li>
+        
+</ol>
+<p>Example:</p>
+<pre class="code">&lt;map:match pattern="protected-*"&gt;
+  &lt;map:act type="auth-protect"&gt; &lt;!-- protect the resource --&gt;
+    &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+    &lt;map:match pattern="protected-first"&gt;
+      &lt;map:generate src="resource1.xml"/&gt;
+      &lt;map:transform src="toHTML"/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:match&gt;
+        ....
+    &lt;map:match pattern="protected-second"&gt;
+      &lt;map:generate src="resource2.xml"/&gt;
+      &lt;map:transform src="toHTML"/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:match&gt;
+  
+  &lt;/map:act&gt;
+&lt;/map:match&gt;</pre>
+<p>Very important - as explained with the single document pattern - is
+          the leading match before the action is performed. The second match is required
+          to check which pipeline to use.</p>
+     
+<h2>Controlling the Application Flow</h2>
+<p>If you want to create documents which behave different wheather you
+          are logged in or not, the <em>auth-loggedIn</em> action is the component to
+          controll your application flow. This action checks if the user is authenticated
+          for a given handler and calls all sitemap components inside the <em>act</em>
+          tag.</p>
+<pre class="code">&lt;map:match pattern="startpage"&gt;
+
+  &lt;map:act type="auth-loggedIn"&gt;  &lt;!-- check authentication --&gt;
+    &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+    &lt;map:redirect-to uri="loggedInStartPage"/&gt;
+  &lt;/map:act&gt;
+
+  &lt;map:generate src="startpage.xml"/&gt;
+  &lt;map:transform src="toHTML"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;</pre>
+<p>In the example above, if the user is already logged he is
+          redirected to the <em>loggedInStartPage</em> document. If he is not logged in
+          for the given handler, the usual start page is generated.</p>
+<p>The <em>auth-protect</em> action returns - if the user is logged in for the
+          given handler - all values from the context to the sitemap, e.g. ID, role etc.
+          These values can be used within the other components:</p>
+<pre class="code">&lt;map:match pattern"protected"&gt;
+  &lt;map:act type="auth-protect"&gt;  &lt;!-- protect the resource --&gt;
+    &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+    &lt;!-- Append the ID of the user to the file name --&gt;
+    &lt;map:generate src="resource_{ID}.xml"/&gt;
+    &lt;map:transform src="toHTML"/&gt;
+    &lt;map:serialize/&gt;
+
+  &lt;/map:act&gt;
+&lt;/map:match&gt;</pre>
+<p>But the <em>auth-loggedIn</em> action does not give the included pipeline
+          access to the authentication context belonging to the handler. If you want this, you
+          have to nest the <em>auth-protect</em> action inside!</p>
+<pre class="code">&lt;map:match pattern"start"&gt;
+
+  &lt;map:act type="auth-loggedIn"&gt;  &lt;!-- check authentication --&gt;
+    &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+    &lt;map:act type="auth-protect"&gt;  &lt;!-- give access to the context --&gt;
+      &lt;map:parameter name="handler" value="myhandler"/&gt;
+
+      &lt;map:generate src="getinfofromcontext.xml"/&gt;
+      &lt;map:transform type="session"/&gt;
+      &lt;map:transform src="toHTML"/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:act&gt;
+  &lt;/map:act&gt;
+
+&lt;/map:match&gt;</pre>
+     
+<h2>Session Handling</h2>
+<p>If a user is authenticated the user has a session. However, care has to be taken that
+        the session tracking works, which means that Cocoon can detect that a follow up request
+        of the user belongs to the same session.</p>
+<p>The easiest way is to use the <em>encodeURL</em> transformer as the last transformation
+        step in your pipeline. For more information about session handling, have a look in 
+        the <a href="session.html">chapter about sessions</a>.</p>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/meta.xml
new file mode 100644
index 0000000..e4a7692
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-authentication-fw-authentication/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/webapps/authentication.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/content_en.html
new file mode 100644
index 0000000..8b8ee9b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/content_en.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Axis RPC Reader in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the AxisRPCReader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>AxisRPCReader</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">template</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">AxisRPCReader</span> allows to serve SOAP requests from 
+            your Cocoon application.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Axis</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.AxisRPCReader</td>
+        
+</tr>
+        <!-- uncomment folling tr iff AxisRPCReader is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">no</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        A general description of AxisRPCReader
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        A usage scenario of AxisRPCReader
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:match pattern="rpcrouter"&gt;
+  &lt;map:read type="soap-rpc" mime-type="text/xml"/&gt;
+&lt;/map:match&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:readers...
+  &lt;map:reader name="soap-rpc"
+    src="org.apache.cocoon.reading.AxisRPCReader"
+    logger="sitemap.reader.soap-rpc" 
+    &gt;
+    &lt;!-- optional reader configuration --&gt;
+    ...
+  &lt;/map:readers&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          Explain the sitemap reader configuration, options when declaring template reader
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          Explain the sitemap reader setup, ie options when using template reader
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+        
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        As a prerequisite for AxisRPCReader to work properly, the Avalon 
+        component SoapServer has to be configured in 
+        the <span class="codefrag">cocoon.xconf</span> file. 
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-25-02: initial creation by Bernhard Huber
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        Links to related components pages.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/meta.xml
new file mode 100644
index 0000000..897c360
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-axis-axisrpc-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/axisrpc-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/content_en.html
new file mode 100644
index 0000000..63471cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/content_en.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Fragment Extractor Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the fragment extractor generator of Cocoon" name="DC.Description">
+</head>
+<body>
+    
+<h1>Fragment Extractor Generator</h1>
+      
+<p> FragmentExtractor is a transformer-generator pair which is designed to allow
+ sitemap managers to extract certain nodes from a SAX stream and move them
+ into a separate pipeline. The main use for this is to extract inline SVG
+ images and serve them up through a separate pipeline, usually serializing
+ them to PNG or JPEG format first.</p>
+      
+<ul>
+        
+<li>Name : extractor</li>
+        
+<li>Class: org.apache.cocoon.generation.FragmentExtractorGenerator</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<pre class="code">
+     
+  &lt;map:generate type="extractor"/&gt;
+     
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/meta.xml
new file mode 100644
index 0000000..cc432c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/extractor-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/content_en.html
new file mode 100644
index 0000000..f1028b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/content_en.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Fragment Extractor Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the Fragment Extractor transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Fragment Extractor Transformer</h1>
+      
+<p>This transformer sieves an incoming stream of xml with embedded SVG images
+ and replaces the images with an xlink locator pointing to the image.</p>
+      
+<ul>
+        
+<li>Name : extractor</li>
+        
+<li>Class: org.apache.cocoon.transformation.FragmentExtractorTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/meta.xml
new file mode 100644
index 0000000..a5e1811
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-extractor-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/extractor-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/content_en.html
new file mode 100644
index 0000000..2ac9b55
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/content_en.html
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The SVG Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ross Burton" name="DC.Creator">
+</head>
+<body>
+    
+<h1>SVG Serializer</h1>
+      
+<h2>Introduction</h2>
+<p>
+          The SVG Serializer is an advanced serializer which accepts
+          valid Scalable Vector Graphic documents (currently to the
+          2000-08-02 Candidate Recommendation specification) and
+          renders it to an image which is served just like any other
+          document in Cocoon.
+        </p>
+<p>
+          Why would you want to do this? Well, charts can be produced from the
+          same data which generates tables, graphical images with text labels
+          all following a standard theme can be generated or normal pages can be
+          beautified.
+        </p>
+<div class="note">
+          For examples of this serializer, see the Cocoon welcome
+          page in the distribution (<span class="codefrag">[cocoon
+          root]/welcome</span>).
+        </div>
+<p>
+          So how does this serializer work?
+        </p>
+<ol>
+          
+<li>Parse and validate SVG document</li>
+          
+<li>Call Batik's <span class="codefrag">Transcoder</span> to encode this image as an image file, and return it to the user.</li>
+        
+</ol>
+<p>
+          The SVG xml document must have a root element &lt;svg&gt;, using xml namespace
+          it is recommended to use the prefix <em>em</em>, and the namespace uri
+          <em>http://www.w3.org/2000/svg</em>.
+        </p>
+  
+      
+<h2>Usage</h2>
+<p>The best way to explain how this serializer works is to show some examples.</p>
+<h3>Basic Example</h3>
+<p>This is a basic example of the serializer.</p>
+<pre class="code">
+&lt;map:serializers&gt;
+  &lt;map:serializer&gt;
+    &lt;map:serializer name="svg2jpeg" mime-type="image/jpeg" 
+        src="org.apache.cocoon.serialization.SVGSerializer"&gt;
+      &lt;parameter name="transcoder" 
+          value="org.apache.batik.transcoder.image.JPEGTranscoder"/&gt;
+  &lt;/map:serializer&gt;
+&lt;map:serializers&gt;
+...
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="sample.jpeg"&gt;
+    &lt;map:generate type="file" src="sample.svg"/&gt; 
+    &lt;map:serialize type="svg2jpeg"/&gt;
+  &lt;/map:match&gt;  
+&lt;/map:pipeline&gt;
+       </pre>
+<p>
+            When the resource <span class="codefrag">sample.jpeg</span> is requested, a SAX event
+            stream is generated from the file <span class="codefrag">sample.svg</span>, which is
+            serialized using the <span class="codefrag">svg2jpeg</span> serializer. This
+            serializer is configured to use a specific transcoder. The MIME type
+            is specified so that Cocoon can tell the client which type the
+            document is. It can be seen that in general the use of this
+            serializer is identical to that of the other serializers.
+          </p>
+<p>
+            The parameter <em>transcoder</em> selects explicitly a batik transcoder.
+            You may want to rely on the default <em>mime-type</em> to 
+            transcoder association, omitting the transcoder parameter
+          </p>
+<table>
+            
+<tr>
+<th colspan="1" rowspan="1">mime-type</th><th colspan="1" rowspan="1">transcoder-class</th>
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">image/jpeg</td><td colspan="1" rowspan="1">org.apache.batik.transcoder.image.JPEGTranscoder</td>
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">image/jpg</td><td colspan="1" rowspan="1">org.apache.batik.transcoder.image.JPEGTranscoder</td>
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">image/png</td><td colspan="1" rowspan="1">org.apache.batik.transcoder.image.PNGTranscoder</td>
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">image/tiff</td><td colspan="1" rowspan="1">org.apache.batik.transcoder.image.TIFFTranscoder</td>
+</tr>
+          
+</table>
+<h3>Advanced Example</h3>
+<p>This is a more advanced sample of using the SVG Serializer.</p>
+<pre class="code">
+&lt;map:serializers&gt;
+  &lt;map:serializer&gt;
+    &lt;map:serializer name="svg2jpeg" mime-type="image/jpeg" 
+        src="org.apache.cocoon.serialization.SVGSerializer"&gt;
+      &lt;parameter name="transcoder" 
+          value="org.apache.batik.transcoder.image.JPEGTranscoder"/&gt;
+      &lt;parameter name="background_color" type="color" value="#00FF00"/&gt;
+  &lt;/map:serializer&gt;
+&lt;map:serializers&gt;
+...
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="sample.jpeg"&gt;
+    &lt;map:generate type="file" src="sample.svg"/&gt; 
+    &lt;map:serialize type="svg2jpeg"/&gt;
+  &lt;/map:match&gt;  
+&lt;/map:pipeline&gt;
+       </pre>
+<p>
+            In this example another parameter is given to the serializer,
+            <span class="codefrag">background_color</span>. This parameter is passed to the
+            transcoder. The <span class="codefrag">type</span> argument specifies the type of
+            data to convert the <span class="codefrag">value</span> to. In this example the
+            string "#00FF00" is converted to a <span class="codefrag">Color</span> object, which
+            is passed to the transcoder as the background colour to
+            use.
+          </p>
+<p>
+            For a list of the parameters available for each transcoder, refer to
+            the Batik API docs.
+          </p>
+<div class="fixme">rossb@apache.org:
+      
+                  Create a document summarising the transcoder hints
+          </div>
+<p>
+            The following table summarizes most useful general SVG ImageTranscoder parameters,
+            all of these parameters are mapped to Batik's SVG ImageTranscoder hints.
+          </p>
+<table>
+            
+<tr>
+<td colspan="1" rowspan="1">width</td><td colspan="1" rowspan="1">float</td><td colspan="1" rowspan="1">Specifies the width of the rasterized image explictly.
+              If no height is specified the aspect ratio is kept.</td>
+            
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">height</td><td colspan="1" rowspan="1">float</td><td colspan="1" rowspan="1">Specifies the width of the rasterized image explictly.
+              If no width is specified the aspect ration is kept.</td>
+            
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">background_color</td><td colspan="1" rowspan="1">color</td><td colspan="1" rowspan="1">
+              Defines the background color
+              to use for opaque image formats, or the background color that may
+              be used for image formats that support alpha channel.
+              A color value of format <span class="codefrag">RRGGBB</span>, 
+              or <span class="codefrag">#RRGGBB</span> sets the background color of the rasterized image, by default
+              the background color is white.</td>
+            
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">language</td><td colspan="1" rowspan="1">string</td><td colspan="1" rowspan="1">to set the default language to use 
+              (may be used by a &lt;switch&gt; SVG element for example), by default language is
+              set to <span class="codefrag">en</span>.</td>
+            
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">user_stylesheet_ur</td><td colspan="1" rowspan="1">string</td><td colspan="1" rowspan="1">to fix the URI of a user stylesheet</td>
+            
+</tr>
+            
+<tr>
+<td colspan="1" rowspan="1">pixel_to_mm</td><td colspan="1" rowspan="1">float</td><td colspan="1" rowspan="1">to specify the pixel to millimeter conversion factor, by default
+              its value is <span class="codefrag">0.264583</span> (96dpi).</td>
+            
+</tr>
+          
+</table>
+<p>
+            For this to work reliably with any transcoder, some magic must be
+            done.
+          </p>
+<ol>
+            
+<li>First, the parameter name is transformed to upper-case and then "KEY_" is
+            prepended. This is to match the internal naming scheme of the hints
+            in the Batik <span class="codefrag">Transcoder</span> interfaces.
+            </li>
+            
+<li>This name is then
+            looked up via Reflection to ensure it is a valid parameter on the
+            specified transcoder.
+            </li>
+            
+<li>Then the value is converted to the type
+            specified in the <span class="codefrag">type</span> attribute (currently supported
+            types are string, float, integer, boolean and color) and passed to
+            the transcoder.
+            </li>
+          
+</ol>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/meta.xml
new file mode 100644
index 0000000..9ee4778
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svg-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/svg-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/content_en.html
new file mode 100644
index 0000000..54955e0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/content_en.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SVG/JPEG Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the svg/jpeg serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>SVG/JPEG Serializer</h1>
+    
+<p>
+      The SVG/JPEG serializes an xml svg document to a jpeg image.
+      The serialization uses the Batik's JPEGTranscoder internally.
+    </p>
+    
+<ul>
+      
+<li>Name : svg2jpeg</li>
+      
+<li>Class: org.apache.cocoon.serialization.SVGSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        A minimal sitemap configuration snippet declaring the svg2jpeg serializer:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2jpeg"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/jpeg"
+    logger="sitemap.serializer.svg2jpeg"
+  &gt;
+  &lt;/map:serializer&gt;
+</pre>
+<p>
+        A sitemap pipeline snippet using the svg2jpeg serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="svg/*.jpg"&gt;
+  &lt;map:generate src="docs/samples/svg/{1}.svg"/&gt;
+  &lt;map:serialize type="svg2jpeg"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+        In the declaration section of the svg2jpeg a number of parameters can be specified.
+        The following snippet set the background color explicitly:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2jpeg"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/jpeg"
+    logger="sitemap.serializer.svg2jpeg"
+  &gt;
+    &lt;parameter name="background_color" type="color" value="#ff00ff"/&gt;
+  &lt;/map:serializer&gt;
+</pre>
+    
+<h2>JPEGTranscoder Parameters</h2>
+<p>
+        General ImageTranscoder parameters are described
+        at the <a href="svg-serializer.html">SVG Serializer</a> user documentation.
+      </p>
+<p>
+        The following section presents JPEGTranscoder specific parameters configurable for the JPEGTranscoder.
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Parameter</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">quality</td><td colspan="1" rowspan="1">float</td><td colspan="1" rowspan="1">Specifies the JPEG quality as value between 0.0 and 1.0,
+          1.0 specifies highest quality. Usually a value of 0.9 is choosen.</td>
+        
+</tr>
+      
+</table>
+    
+<h2>Further Reading</h2>
+<p>
+        Further details about JPEGTranscoder, ImageTranscoder is available 
+        at <a class="external" href="http://xml.apache.org/batik">Batik</a>.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/meta.xml
new file mode 100644
index 0000000..87e23eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgjpeg-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/svgjpeg-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/content_en.html
new file mode 100644
index 0000000..c2f3904
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/content_en.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SVG/PNG Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the svg/png serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>SVG/PNG Serializer</h1>
+    
+<p>
+      The SVG/PNG serializes an xml svg document to a png image.
+      The serialization uses the Batik's PNGTranscoder internally.
+    </p>
+    
+<ul>
+      
+<li>Name : svg2png</li>
+      
+<li>Class: org.apache.cocoon.serialization.SVGSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        A minimal sitemap configuration snippet declaring the svg2png serializer:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2png"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/png"
+    logger="sitemap.serializer.svg2png"
+  &gt;
+  &lt;/map:serializer&gt;
+</pre>
+<p>
+        A sitemap pipeline snippet using the svg2png serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="svg/*.png"&gt;
+  &lt;map:generate src="docs/samples/svg/{1}.svg"/&gt;
+  &lt;map:serialize type="svg2png"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+        In the declaration section of the svg2png a number of parameters can be specified.
+        The following snippet set the background color explicitly:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2png"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/png"
+    logger="sitemap.serializer.svg2png"
+  &gt;
+    &lt;parameter name="background_color" type="color" value="#ff00ff"/&gt;
+  &lt;/map:serializer&gt;
+</pre>
+    
+<h2>PNGTranscoder Parameters</h2>
+<p>
+        General ImageTranscoder parameters are described
+        at the <a href="svg-serializer.html">SVG Serializer</a> user documentation.
+      </p>
+<p>
+        The following section presents PNGTranscoder specific parameters configurable 
+        for the PNGTranscoder.
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Parameter</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">force_transparent_white</td><td colspan="1" rowspan="1">boolean</td><td colspan="1" rowspan="1">It controls whether the encoder should
+          force the image's fully transparent pixels to be fully transparent
+          white instead of fully transparent black.  This is usefull when the
+          encoded PNG is displayed in a browser which does not support PNG
+          transparency and lets the image display with a white background instead
+          of a black background. <br> However, note that the modified image
+          will display differently over a white background in a viewer that
+          supports transparency.</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">gamma</td><td colspan="1" rowspan="1">float</td><td colspan="1" rowspan="1">Controls the gamma correction of the png image;
+          by default its value is approx <span class="codefrag">2.22</span>.
+          </td>
+        
+</tr>
+      
+</table>
+    
+<h2>Further Reading</h2>
+<p>
+        Further details about PNGTranscoder, ImageTranscoder is available 
+        at <a class="external" href="http://xml.apache.org/batik">Batik</a>.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/meta.xml
new file mode 100644
index 0000000..d5fd444
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgpng-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/svgpng-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/content_en.html
new file mode 100644
index 0000000..325826a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/content_en.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SVG/TIFF Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the svg/tiff serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>SVG/TIFF Serializer</h1>
+    
+<p>
+      The SVG/TIFF serializes an xml svg document to a tiff image.
+      The serialization uses the Batik's TIFFTranscoder internally.
+    </p>
+    
+<ul>
+      
+<li>Name : svg2tiff</li>
+      
+<li>Class: org.apache.cocoon.serialization.SVGSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        A minimal sitemap configuration snippet declaring the svg2tiff serializer:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2tiff"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/tiff"
+    logger="sitemap.serializer.svg2tiff"
+  &gt;
+  &lt;/map:serializer&gt;
+</pre>
+<p>
+        A sitemap pipeline snippet using the svg2tiff serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="svg/*.tiff"&gt;
+  &lt;map:generate src="docs/samples/svg/{1}.svg"/&gt;
+  &lt;map:serialize type="svg2tiff"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+        In the declaration section of the svg2tiff a number of parameters can be specified.
+        The following snippet set the background color explicitly:
+      </p>
+<pre class="code">
+&lt;map:serializers..
+  &lt;map:serializer name="svg2tiff"
+    src="org.apache.cocoon.serialization.SVGSerializer"
+    mime-type="image/tiff"
+    logger="sitemap.serializer.svg2tiff"
+  &gt;
+    &lt;parameter name="background_color" type="color" value="#ff00ff"/&gt;
+  &lt;/map:serializer&gt;
+</pre>
+    
+<h2>TIFFTranscoder Parameters</h2>
+<p>
+        General ImageTranscoder parameters are described
+        at the <a href="svg-serializer.html">SVG Serializer</a> user documentation.
+      </p>
+<p>
+        The following section presents TIFFTranscoder specific parameters configurable 
+        for the TIFFTranscoder.
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Parameter</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+  
+<tr>
+<td colspan="1" rowspan="1">force_transparent_white</td><td colspan="1" rowspan="1">boolean</td><td colspan="1" rowspan="1">It controls whether the encoder should
+          force the image's fully transparent pixels to be fully transparent
+          white instead of fully transparent black.  This is usefull when the
+          encoded TIFF is displayed in a viewer which does not support TIFF
+          transparency and lets the image display with a white background instead
+          of a black background.
+          However, note that the modified image will display differently
+          over a white background in a viewer that supports
+          transparency.</td>
+        
+</tr>
+     
+</table>
+    
+<h2>Further Reading</h2>
+<p>
+        Further details about TIFFTranscoder, ImageTranscoder is available 
+        at <a class="external" href="http://xml.apache.org/batik">Batik</a>.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/meta.xml
new file mode 100644
index 0000000..7a01c59
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgtiff-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/svgtiff-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/content_en.html
new file mode 100644
index 0000000..4317c38
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/content_en.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SVG/XML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the svg/xml serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>SVG/XML Serializer</h1>
+    
+<p>
+      The SVG serializer serializes sax events to SVG XML.
+      The output of the SVG serializer is SVG XML; the SVG XML is not 
+      rasterized to any image format by this serializer.
+    </p>
+    
+<ul>
+      
+<li>Name : svgxml</li>
+      
+<li>Class: org.apache.cocoon.serialization.XMLSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        The SVG XML serializer is declared in the sitemap serializers section.
+      </p>
+<pre class="code">
+&lt;map:serializers ...
+...
+  &lt;map:serializer name="xml"
+    src="org.apache.cocoon.serialization.XMLSerializer"
+    mime-type="text/xml"  
+    doctype-public="-//W3C//DTD SVG 1.0//EN"
+    doctype-system="http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd";
+    logger="sitemap.serializer.xml" 
+    pool-max="32"&gt;
+    &lt;!-- serializer configurations --&gt;
+...    
+  &lt;/map:serializer&gt;
+...
+      </pre>
+<p>
+        The declaration of the SVG serializer shall use following 
+        XML serializer configuration parameters
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Name</th><th colspan="1" rowspan="1">Value</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-public</td><td colspan="1" rowspan="1">-//W3C//DTD SVG 1.0//EN</td>
+          <td colspan="1" rowspan="1">specifies the SVG XML public document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-system</td><td colspan="1" rowspan="1">http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd</td>
+          <td colspan="1" rowspan="1">specifies the SVG XML system document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">mime-type</td><td colspan="1" rowspan="1">text/xml</td>
+          <td colspan="1" rowspan="1">Following mime-type may be used, too:
+            <span class="codefrag">image/svg+xml</span>, <span class="codefrag">application/xml</span>.
+            The mime-type <span class="codefrag">text/xml</span> is the most general one.
+          </td>
+        
+</tr>
+      
+</table>
+    
+<h2>Pipeline Usage</h2>
+<p>
+        Using the SVG XML serializer in a pipeline is just setting the 
+        serializer type to svgxml. The following code snippet uses the svxml serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="svg"&gt;
+...
+  &lt;map:serialize type="svgxml"/&gt;
+&lt;/map:match&gt;
+...
+      </pre>
+    
+<h2>Further Reading</h2>
+<p>
+        As SVG serializer uses the XML serializer internally, you might 
+        want to read the complete list of valid XML configuration parameters.
+        It is available at <a href="xml-serializer.html">XML serializer</a>
+        user documentation.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/meta.xml
new file mode 100644
index 0000000..2172727
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-batik-svgxml-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/svgxml-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/content_en.html
new file mode 100644
index 0000000..49ae332
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/content_en.html
@@ -0,0 +1,350 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ScriptAction in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the ScriptAction of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>ScriptAction</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td>
+          <td colspan="1" rowspan="1">script</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td>
+          <td colspan="1" rowspan="1">The <span class="codefrag">ScriptAction</span> component is used to executes any
+          script that can be run by the BSF.</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td>
+          <td colspan="1" rowspan="1">Action</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td>
+          <td colspan="1" rowspan="1">bsf</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td>
+          <td colspan="1" rowspan="1">org.apache.cocoon.action.ScriptAction</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td>
+          <td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td>
+          <td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>A simple action that executes any script that can be run by the BSF
+      system. BSF supports script languages like javascript, python, etc.</p>
+    
+    
+<h1>Usage</h1>
+      
+<p>This Action is used for quick prototyping of Action, realizing an
+      Action in a script language instead of java language.</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>The following sample executes the <span class="codefrag">script action/my-action.js</span>
+        for each URI matching pattern <span class="codefrag">*.vm</span>. If the ScriptAction
+        succeeds, the pipeline continues, invoking the VelocityGenerator, and
+        serializing the XML stream.</p>
+<pre class="code">&lt;map:match pattern="*.vm"&gt;
+  &lt;map:action type="script" src="action/my-action.js"&gt;
+    &lt;map:generate type="velocity" src="{1}.vm"/&gt;
+    &lt;map:serialize/&gt;
+  &lt;/map:action&gt;
+&lt;/map:match&gt;
+</pre>
+      
+<h2>Sitemap component configuration example</h2>
+<p>The following sample configures an ScriptAction, naming it
+        <span class="codefrag">script</span>.</p>
+<pre class="code">&lt;map:actions...
+  &lt;map:action name="script"
+    src="org.apache.cocoon.acting.ScriptAction"&gt; 
+    logger="sitemap.action.script"/&gt;    
+    &lt;!-- optional action configuration --&gt;
+    ...
+&lt;/map:actions&gt;
+</pre>
+      
+<h2>Configuration</h2>
+<p>ScriptAction has no configuration options.</p>
+      
+<h2>Setup</h2>
+<p>ScriptAction determines the name of the script getting executed
+        from its <span class="codefrag">src</span> attribute.</p>
+<p>The language of the script file is auto-detected by the BSF system
+        from the extension of the script.
+        </p>
+<p>The next table lists the default mapping of BSF:</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">Script language</th>
+            <th colspan="1" rowspan="1">Extension</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">javascript</td>
+            <td colspan="1" rowspan="1">js</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jacl</td>
+            <td colspan="1" rowspan="1">jacl</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">netrexx</td>
+            <td colspan="1" rowspan="1">nrx</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">java</td>
+            <td colspan="1" rowspan="1">java</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">javaclass</td>
+            <td colspan="1" rowspan="1">class</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">bml</td>
+            <td colspan="1" rowspan="1">bml</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">vbscript</td>
+            <td colspan="1" rowspan="1">vbs</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jscript</td>
+            <td colspan="1" rowspan="1">jss</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">perlscript</td>
+            <td colspan="1" rowspan="1">pls</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">perl</td>
+            <td colspan="1" rowspan="1">pl</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jpython</td>
+            <td colspan="1" rowspan="1">py</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">lotusscript</td>
+            <td colspan="1" rowspan="1">lss</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">xslt</td>
+            <td colspan="1" rowspan="1">xslt</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">pnuts</td>
+            <td colspan="1" rowspan="1">pnut</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">beanbasic</td>
+            <td colspan="1" rowspan="1">bb</td>
+          
+</tr>
+        
+</table>
+<p>ScriptAction registers following objects before invoking the
+        script:</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">name</th>
+            <th colspan="1" rowspan="1">Object Typ</th>
+            <th colspan="1" rowspan="1">Comment</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">resolver</td>
+            <td colspan="1" rowspan="1">SourceResolver</td>
+            <td colspan="1" rowspan="1">Cocoon's source resolver</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">objectModel</td>
+            <td colspan="1" rowspan="1">Map</td>
+            <td colspan="1" rowspan="1">Cocoon's object model</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">parameters</td>
+            <td colspan="1" rowspan="1">Parameters</td>
+            <td colspan="1" rowspan="1">Cocoon's action parameter</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">actionMap</td>
+            <td colspan="1" rowspan="1">Map</td>
+            <td colspan="1" rowspan="1">Used for passing objects from the script back to the
+            ScriptAction, and to Cocoon's sitemap</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">logger</td>
+            <td colspan="1" rowspan="1">Logger</td>
+            <td colspan="1" rowspan="1">Cocoon's logger of this ScriptAction</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">request</td>
+            <td colspan="1" rowspan="1">Request</td>
+            <td colspan="1" rowspan="1">Request provided by the object model</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">scriptaction</td>
+            <td colspan="1" rowspan="1">Action</td>
+            <td colspan="1" rowspan="1">The instance of this ScriptAction</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">manager</td>
+            <td colspan="1" rowspan="1">Manager</td>
+            <td colspan="1" rowspan="1">Cocoon's manager of this ScriptAction</td>
+          
+</tr>
+        
+</table>
+<p>These objects are accessible from within the script.</p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>ScriptAction checks the existence of the key <span class="codefrag">scriptaction-continue</span>
+        in the <span class="codefrag">actionMap</span>. If this key exists ScriptAction returns
+        <span class="codefrag">actionMap</span>, otherwise <span class="codefrag">null</span> is returned.</p>
+<p>Objects available in the <span class="codefrag">actionMap</span> are available in
+        the sitemap.</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>Using ScriptAction relies heavily on the setting of the key
+      <span class="codefrag">scriptaction-continue</span> in the <span class="codefrag">mapAction</span>.</p>
+      
+<p>Be aware to provide script language implementation, beside BSF implementation.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>07-24-03: initial creation</p>
+      
+<p>04-02-04: Updated to Jakarta BSF</p>
+    
+    
+<h1>Copyright</h1>
+      
+<p>Copyright (C) 1999-2004 The Apache Software Foundation. All rights
+      reserved.</p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+<!-- Links to related components pages. -->A general documentation
+      about actions is available at <a href="../concepts/actions.html">Actions</a>.</p>
+      
+<p>Further Documentation visit <a class="external" href="http://jakarta.apache.org/bsf/index.html">Jakarta BSF Project</a>.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/meta.xml
new file mode 100644
index 0000000..10c9a65
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-action/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/actions/script-action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/content_en.html
new file mode 100644
index 0000000..62633a8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/content_en.html
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ScriptGenerator in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the ScriptGenerator of
+    Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>ScriptGenerator</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td>
+          <td colspan="1" rowspan="1">script</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td>
+          <td colspan="1" rowspan="1">The <span class="codefrag">ScriptGenerator</span> component is used to generate
+          XML by invoking a script.</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td>
+          <td colspan="1" rowspan="1">Generator, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td>
+          <td colspan="1" rowspan="1">bsf</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td>
+          <td colspan="1" rowspan="1">org.apache.cocoon.generation.ScriptGenerator</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td>
+          <td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td>
+          <td colspan="1" rowspan="1">no</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>The ScriptGenerator executes arbitrary scripts using the Apache BSF
+      framework and additional interpreter (Rhino, Jython, etc.) as a Cocoon
+      Generator.</p>
+    
+    
+<h1>Usage</h1>
+      
+<p>The ScriptGenerator is used primarily for prototyping a Cocoon
+      generator. Moreover if the generator's XML output is low and the
+      logic processing is high.</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>The following sample uses the ScriptGenerator for generating XML
+        content for URIs matching the pattern <span class="codefrag">*.js</span>. The output of
+        the script invoked by ScriptGenerator is serialized by the default
+        serializer.</p>
+<pre class="code">
+&lt;map:match pattern="*.js"&gt;
+  &lt;map:generate type="script" src="{0}" &gt;
+  &lt;/map:generate&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+        </pre>
+      
+<h2>Sitemap component configuration example</h2>
+<p>The following sample declares the ScriptGenerator in the
+        sitemap's component section. The ScriptGenerator can be used in
+        the sitemap's section using <span class="codefrag">type</span> value <span class="codefrag">script</span>.
+        In this sample no extra script language is declared.</p>
+<pre class="code">
+&lt;map:generators...
+  &lt;map:generator name="script" 
+    src="org.apache.cocoon.generation.ScriptGenerator"
+    logger="sitemap.generation.scriptgenerator" 
+  /&gt;
+    &lt;!-- optional generator configuration --&gt;
+    ...
+&lt;/map:generators&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>The ScriptGenerator allows registering additional script languages.</p>
+<p>List the newly registered language inside the <span class="codefrag">add-language</span>
+        element, each language is defined in <span class="codefrag">language</span> element, by
+        specifying the name of the language using the <span class="codefrag">name</span>
+        attribute, and the language BSF adaptor using the attribute
+        <span class="codefrag">src</span>.</p>
+<p>Each registered language should be mapped to at least one
+        extension, as the language detection of ScriptGenerator is based on
+        the script's extension.</p>
+<p>The following sample register an new language foobar, the BSF
+        adaptor class is <span class="codefrag">foo.bar.ScriptLanguage</span>, and it is
+        associated with the extensions <span class="codefrag">foo</span>, and <span class="codefrag">bar</span>.</p>
+<pre class="code">&lt;add-language&gt;
+  &lt;language name="foobar" src="foo.bar.ScriptLanguage"&gt;
+    &lt;extension&gt;foo&lt;/extension&gt;
+    &lt;extension&gt;bar&lt;/extension&gt;
+  &lt;/language&gt;
+  ...
+&lt;/add-language&gt;
+</pre>
+<p>The next table lists the default mapping of BSF:</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">Extension</th>
+            <th colspan="1" rowspan="1">Script language</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">javascript</td>
+            <td colspan="1" rowspan="1">js</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jacl</td>
+            <td colspan="1" rowspan="1">jacl</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">netrexx</td>
+            <td colspan="1" rowspan="1">nrx</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">java</td>
+            <td colspan="1" rowspan="1">java</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">javaclass</td>
+            <td colspan="1" rowspan="1">class</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">bml</td>
+            <td colspan="1" rowspan="1">bml</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">vbscript</td>
+            <td colspan="1" rowspan="1">vbs</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jscript</td>
+            <td colspan="1" rowspan="1">jss</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jscript</td>
+            <td colspan="1" rowspan="1">jss</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">perlscript</td>
+            <td colspan="1" rowspan="1">pls</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">perl</td>
+            <td colspan="1" rowspan="1">pl</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">jpython</td>
+            <td colspan="1" rowspan="1">py</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">lotusscript</td>
+            <td colspan="1" rowspan="1">lss</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">xslt</td>
+            <td colspan="1" rowspan="1">xslt</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">pnuts</td>
+            <td colspan="1" rowspan="1">pnut</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">beanbasic</td>
+            <td colspan="1" rowspan="1">bb</td>
+          
+</tr>
+        
+</table>
+<p></p>
+      
+<h2>Setup</h2>
+<p>ScriptGenerator registers following objects before invoking the
+        script:</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">Name</th>
+            <th colspan="1" rowspan="1">Object Typ</th>
+            <th colspan="1" rowspan="1">Comment</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">resolver</td>
+            <td colspan="1" rowspan="1">Resolver</td>
+            <td colspan="1" rowspan="1">Cocoon's resolver</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">source</td>
+            <td colspan="1" rowspan="1">Source</td>
+            <td colspan="1" rowspan="1">src attribute of this ScriptGenerator</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">objectModel</td>
+            <td colspan="1" rowspan="1">Map</td>
+            <td colspan="1" rowspan="1">Cocoon's objectModel</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">parameters</td>
+            <td colspan="1" rowspan="1">Parameters</td>
+            <td colspan="1" rowspan="1">paramters of this ScriptGenerator</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">output</td>
+            <td colspan="1" rowspan="1">StringBuffer</td>
+            <td colspan="1" rowspan="1">XML content, forwarded into Cocoon's XML pipeline</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">logger</td>
+            <td colspan="1" rowspan="1">Logger</td>
+            <td colspan="1" rowspan="1">logger of this ScriptGenerator</td>
+          
+</tr>
+        
+</table>
+<p>The script shall write XML content into the StringBuffer object
+        <span class="codefrag">output.</span> The content of <span class="codefrag">output</span> is parsed by
+        the ScriptGenerator and forwarded into the sitemap pipeline.</p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>none</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>ScriptGenerator expects the script to write the XML content into the
+      passed object <span class="codefrag">output</span>.</p>
+      
+<p>Be aware to provide script language implementation, beside BSF
+      implementation.</p>
+    
+    
+<h1>History</h1>
+      
+<p>07-24-03: initial creation</p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+<!-- Links to related components pages. -->A general documentation
+      about generators is available at <a href="../concepts/sitemap.html">generators</a>.</p>
+      
+<p>Further Documentation about Apache BSF is available <a class="external" href="http://jakarta.apache.org/bsf/index.html">here</a>.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/meta.xml
new file mode 100644
index 0000000..c1914e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-bsf-script-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/script-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/content_en.html
new file mode 100644
index 0000000..b9f49e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/content_en.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Lexical Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stephan Michels" name="DC.Creator">
+<meta content="This document describes the lexical transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Lexical Transformer</h1>
+   
+<p>The lexical transformer tokenizes the content of special marked
+     elements of a SAX stream, by using a lexicon file.</p>
+
+   
+<ul>
+    
+<li>Name: lexer</li>
+    
+<li>Class: org.apache.cocoon.transformation.LexicalTransformer</li>
+    
+<li>Cacheable: yes - uses the last modification date of the lexicon
+      document for validation.</li>
+   
+</ul>
+
+   
+<p>The lexer parses the following elements from the SAX stream, and
+      replaces them through generated documents.
+   </p>
+
+   
+<pre class="code">
+&lt;text xmlns="http://chaperon.sourceforge.net/schema/text/1.0"&gt;
+ [Text, which should be parsed]
+&lt;/text&gt;
+</pre>
+
+   
+<p>The lexical transformer will replace these elements by a list of
+    lexemes (tokens).
+   </p>
+
+   
+<pre class="code">
+&lt;lexemes xmlns="http://chaperon.sourceforge.net/schema/lexemes/1.0"&gt;
+ &lt;lexeme symbol="..." text="..."/&gt;
+ &lt;lexeme symbol="..." text="..."/&gt;
+ &lt;lexeme symbol="..." text="..."/&gt;
+&lt;/lexemes&gt;
+</pre>
+
+   
+<p>A detailed explanation of function and the lexicon format can be found at <a class="external" href="http://chaperon.sourceforge.net/">Chaperon</a>.</p>
+
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/meta.xml
new file mode 100644
index 0000000..222c218
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-lexer-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/lexer-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/content_en.html
new file mode 100644
index 0000000..f290ece
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/content_en.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Parser Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stephan Michels" name="DC.Creator">
+<meta content="This document describes the parser transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Parser Transformer</h1>
+   
+<p>The parser transformer builds a syntax tree of a list of lexemes
+      (tokens), by using a grammar file.</p>
+
+   
+<ul>
+    
+<li>Name: parser</li>
+    
+<li>Class: org.apache.cocoon.transformation.ParserTransformer</li>
+    
+<li>Cacheable: yes - uses the last modification date of the grammar
+      document for validation.</li>
+   
+</ul>
+
+   
+<p>The parser uses the following elements from the SAX stream, and
+      replaces them through a syntax tree.</p>
+
+   
+<pre class="code">
+&lt;lexemes xmlns="http://chaperon.sourceforge.net/schema/lexemes/1.0"&gt;
+ &lt;lexeme symbol="word" text="..."/&gt;
+ &lt;lexeme symbol="word" text="..."/&gt;
+ &lt;lexeme symbol="word" text="..."/&gt;
+ &lt;lexeme symbol="punctation" text="..."/&gt;
+&lt;/lexemes&gt;
+</pre>
+
+   
+<p>The parser transformer will replace those elements with a syntax tree.
+   </p>
+
+   
+<pre class="code">
+&lt;paragraph xmlns="http://chaperon.sourceforge.net/schema/syntaxtree/1.0"&gt;
+ &lt;sentence&gt;
+  &lt;word&gt;...&lt;/word&gt;
+  &lt;word&gt;...&lt;/word&gt;
+  &lt;word&gt;...&lt;/word&gt;
+  &lt;punctation&gt;...&lt;/punctation&gt;
+ &lt;/sentence&gt;
+&lt;/paragraph&gt;
+</pre>
+
+   
+<p>A detailed explanation of function and the grammar format can be found at <a class="external" href="http://chaperon.sourceforge.net/">Chaperon</a>.</p>
+
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/meta.xml
new file mode 100644
index 0000000..ec0060e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-parser-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/parser-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/content_en.html
new file mode 100644
index 0000000..fdb2071
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/content_en.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Pattern Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stephan Michels" name="DC.Creator">
+<meta content="This document describes the pattern transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Pattern Transformer</h1>
+   
+<p>The pattern transformer recognizes special texts part using patterns,
+      and replaces them with XML elements. This transformer use a lexicon
+      file to specify the pattern.</p>
+
+   
+<ul>
+    
+<li>Name: pattern</li>
+    
+<li>Class: org.apache.cocoon.transformation.PatternTransformer</li>
+    
+<li>Cacheable: yes - uses the last modification date of the lexicon
+      document for validation.</li>
+   
+</ul>
+
+   
+<p>The pattern transformer parses all text elements from the SAX stream,
+    and replaces the special text parts.</p>
+
+   
+<pre class="code">
+&lt;myelement&gt;
+ bla blah Hello World bla
+&lt;/myelement&gt;
+</pre>
+
+   
+<p>The pattern transformer will replace these special text parts with
+     a lexeme (token).</p>
+
+   
+<pre class="code">
+&lt;myelement&gt;
+ bla blah &lt;lexeme xmlns="http://chaperon.sourceforge.net/schema/lexemes/1.0" 
+                  symbol="Hello World"
+                  text="Hello World"/&gt; bla
+&lt;/myelement&gt;
+</pre>
+
+   
+<p>A detailed explanation of function and the lexicon format can be found at <a class="external" href="http://chaperon.sourceforge.net/">Chaperon</a>.</p>
+
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/meta.xml
new file mode 100644
index 0000000..94ddf2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-chaperon-pattern-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/pattern-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/content_en.html
new file mode 100644
index 0000000..0db0ee7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/content_en.html
@@ -0,0 +1,424 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Database Actions</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Introduction</h1>
+    
+<p>
+    Two different sets of actions exist, that deal with (object) relational
+    database access through JDBC. The original database actions provide a
+    relatively simple interface to store, modify, delete and retrieve data.
+    They are oriented towards usage of request parameters for input and
+    request attributes together with sitemap variables for output and do
+    not support auto increment column types. In addition, the description of
+    the database structure is split over several files since these actions
+    attempt to use all tables in a provided description.
+    </p>
+    
+<p>
+    The modular database actions provide similar functionality. In contrast
+    to the original actions they allow to store the database meta data in a
+    single file and to switch input and output flexible through the use of
+    modules. Even for auto increment columns specific modules exist that
+    cover a wide range of database management systems.
+    </p>
+      
+<p>
+        For an overview of column types supported by the modular database
+        actions, see javadocs for JDBCTypeConversions. The types supported by
+        the original actions are documented in AbstractDatabaseAction.
+      </p>
+  
+
+  
+<h1>Original Database Actions</h1>
+    
+<p>
+    The original database actions have evolved quite a bit and at different
+    speeds. The add action is certainly the most complete one, providing
+    support for multiple tables and rows. However, the interface has become
+    a bit inconsistent.
+    </p>
+    
+<p>
+    If an error occurs, the original database actions will throw an
+    exception.
+    </p>
+    
+<h2>Describing the Structure of your DB - descriptor.xml</h2>
+<p>
+      The key to database actions is a file that describes database meta
+      data in XML. The original actions will ignore all but the first table
+      and act only on one row. Only the add action will try to access all
+      tables that are contained in this description. As a consequence, each
+      HTML form needs to have a corresponding descriptor file if different
+      tables are affected.
+    </p>
+<p>
+      The file name has no meaning and does not need to be
+      <span class="codefrag">descriptor.xml</span> - it can even be a Cocoon pipeline. The
+      name of the root element in a descriptor file is ignored. Only
+      <span class="codefrag">table</span> elements nested on first level inside the root
+      element are parsed by the actions. All unknown elements or attributes
+      are ignored.
+    </p>
+<p>
+      For each table a <span class="codefrag">table</span> element needs to be present. 
+    </p>
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+
+&lt;employee&gt;
+  &lt;connection&gt;personnel&lt;/connection&gt;
+  &lt;table name="employee"&gt;
+    &lt;keys&gt;
+      &lt;key param="employee" dbcol="id" type="int" mode="manual"/&gt;
+    &lt;/keys&gt;
+    &lt;values&gt;
+      &lt;value param="name" dbcol="name" type="string"/&gt;
+      &lt;value param="department" dbcol="department_id" type="int"/&gt;
+    &lt;/values&gt;
+  &lt;/table&gt;
+&lt;/employee&gt;
+  
+    </pre>
+<p>
+      Describes a single table named "employee". In addition a database
+      connection is specified. See <a href="../../developing/datasources.html">here</a> for more
+      information on database connections. 
+    </p>
+<h3>Key Columns</h3>
+<p>
+      Tables may or may not have key columns. A key column is a column
+      that is part of the primary key. Actually, candidate keys should do
+      as well.
+      </p>
+<p>
+      All key columns are contained in a <span class="codefrag">keys</span> child element
+      of the <span class="codefrag">table</span> element. Each column has a
+      <span class="codefrag">key</span> element to define its properties. The
+      <span class="codefrag">dbcol</span> attribute holds the column name,
+      <span class="codefrag">type</span> is the JDBC type name for this column (have a
+      look at AbstactDatabaseAction source for valid type names),
+      <span class="codefrag">param</span> specifies the name of the request parameter to
+      use, and <span class="codefrag">mode</span> sets how the value for this column is
+      obtained on adding a row.
+      </p>
+<p>
+      Through the mode attribute the behaviour of the add action can be
+      changed.
+      </p>
+<p>
+      Default mode is "automatic" and to let the database create the key
+      value by setting this value to <span class="codefrag">null</span>. The created value
+      can not be read back from the database and will not be available as
+      request attribute or sitemap variable.
+      </p>
+<p>
+      A mode of "manual" will query the database for the maximum current
+      value, add 1 to it and use that for a value.
+      </p>
+<p>
+      A mode of "form" will use the corresponding request parameter.
+      </p>
+<p>
+      A mode of "request-attribute" will use the corresponding request
+      attribute. The name specified in the <span class="codefrag">param</span> attribute
+      will be automatically prefixed with the class name.
+      </p>
+<p>
+      Key values will be propagated to sitemap variables and - prefixed
+      with the class name - request attributes.
+      </p>
+<h3>Other Columns</h3>
+<p>
+      All other columns are contained in a <span class="codefrag">values</span> child
+      element of the <span class="codefrag">table</span> element. Each column has a
+      <span class="codefrag">value</span> element to define its properties. Properties are
+      similar to those for key columns. A <span class="codefrag">mode</span> attribute
+      does not exist for value columns. Instead, request parameters and
+      request attributes are tried in this order for the specified
+      parameter. 
+      </p>
+<p>
+      Request attribute names are <em>not</em> prefixed with the class
+      name. Thus, to insert the value of a key column of the previous row
+      or previous table into a value column, it needs to be named
+      <span class="codefrag">org.apache.cocoon.acting.AbstractDatabaseAction:key:table:dbcol</span>. 
+      </p>
+<p>
+      Value columns are propagated to request attributes with class name
+      prefix. They are not available for the sitemap.
+      </p>
+  
+  
+<h1>Modular Database Actions</h1>
+    
+<p>
+    The modular database actions were mainly created to make auto increment
+    columns available, handle input and output flexibly, and have a
+    consistent interface. A successful action will return the number of
+    rows affected in a sitemap parameter named <span class="codefrag">row-count</span>. The
+    added features required to change the descriptor file format in
+    incompatible ways.
+    </p>
+    
+<p>
+    It can be configured if an exception will be thrown when an error
+    occurs.
+    </p>
+    
+<h2>Describing the Structure of your DB - descriptor.xml</h2>
+<p>
+      Like the original actions, the modular actions need meta data in an
+      XML file. However, that file may contain any number of tables, not
+      just the ones needed for a single request. The tables actually used
+      are referenced through a <span class="codefrag">table-set</span>. Unknown elements and
+      attributes are ignored. This way a descriptor file can be shared with
+      other actions like the form validator.
+    </p>
+<p>
+      For the flexible input and output handling, the modular database
+      actions rely on <a href="../concepts/modules.html">modules</a>.
+      Have a look at those before proceeding.
+    </p>
+<p>
+          The following is a snippet from a descriptor file. 
+        </p>
+<pre class="code">
+
+&lt;root&gt;
+   &lt;connection&gt;personnel&lt;/connection&gt;
+   &lt;table name="user" alias="user"&gt;
+      &lt;keys&gt;
+         &lt;key name="uid" type="int" autoincrement="true"&gt;
+            &lt;mode name="auto"  type="autoincr"/&gt;
+         &lt;/key&gt;
+      &lt;/keys&gt;
+      &lt;values&gt;
+         &lt;value name="name"      type="string"&gt;&lt;/value&gt;
+         &lt;value name="firstname" type="string"&gt;&lt;/value&gt;
+         &lt;value name="uname"     type="string"&gt;&lt;/value&gt;
+      &lt;/values&gt;   
+   &lt;/table&gt;
+
+        </pre>
+<p>
+          The <span class="codefrag">table</span> element has an additional attribute
+          <span class="codefrag">alias</span> which is an alternative name to reference
+          the table from a table set. The descriptor file is searched
+          top down for tables whose <span class="codefrag">name</span> or
+          <span class="codefrag">alias</span> match. The <span class="codefrag">alias</span>n attribute
+          is useful if a complex join expression is used as table
+          name. In such a case modifications like update, insert,
+          delete will likely fail.
+        </p>
+<p>
+      Another application of aliases if different numbers of columns should
+      be affected by an operation. or if a table contains several candidate
+      keys that are used alternatively. This way, different views to a
+      table can be created.
+    </p>
+<h3>Key Columns</h3>
+<p>
+      The descriptor file resembles the one for the original actions. One
+      major difference is the absence of <span class="codefrag">dbcol</span> and
+      <span class="codefrag">param</span> attributes. Instead there is a <span class="codefrag">name</span>
+      attribute which corresponds to the <span class="codefrag">dbcol</span> attribute and
+      specifies the database column name.
+      </p>
+<p>
+      If a column is an auto increment column, the similar named attribute
+      indicates this. Auto increment columns will be handled differently
+      on insert operations.
+      </p>
+<p>
+      Instead of specifying a parameter name, the actions support to use
+      different input modules for each operation through the nested
+      <span class="codefrag">mode</span> elements. This is described in more detail below.
+      </p>
+<p>
+      Note here though, that not every column needs a <span class="codefrag">mode</span>
+      element: The actions default to the module defined as
+      <span class="codefrag">request</span> which is in a default installation to obtain
+      the values from request parameters. The name of the parameter
+      defaults to table name dot column name.
+      </p>
+<h3>Other Columns</h3>
+<p>
+            Apart from the fact that the auto increment columns are only
+      supported for key columns, everything said above applies to value
+      columns as well.
+          </p>
+<h3>Operation Mode Types</h3>
+<p>
+      Basically, two different mode types exist:
+      <span class="codefrag">autoincrement</span> which is used whenever data shall be
+      inserted into a table and this particular key column has the
+      auto increment attribute set and <span class="codefrag">others</span> for all other
+      requirements.
+          </p>
+<p>
+            In addition, a table-set can specify different mode types to use
+      instead of the predefined type names. Through this, and the fact
+      that every mode can specify a different input module, it is easy to
+      use different input modules for different tasks and forms.
+          </p>
+<p>
+            One special mode type name exists that matches all requested ones:
+      <span class="codefrag">all</span> This makes it easier to configure only some
+      columns differently for each table-set.
+          </p>
+<h3>How to obtain Values</h3>
+<p>
+      As said above, these actions default to reading from request
+      parameters with a default parameter name. By specifying
+      <span class="codefrag">mode</span> elements, this can be overridden. Any component
+      that implements the <span class="codefrag">InputModule</span> interface can be used
+      to obtain values. How to make such modules known to Apache Cocoon
+      is described  <a href="../concepts/modules.html">elsewhere</a>. 
+      </p>
+<p>
+      Beside using different input modules, their parameters can be set
+      in place, for example to override parameter names, configure a
+      random generator or a message digest algorithm.
+      </p>
+<pre class="code">
+
+   &lt;table name="user_groups"&gt;
+      &lt;keys&gt;
+         &lt;key name="uid" type="int"&gt;
+            &lt;mode name="request" type="request"&gt;
+               &lt;parameter&gt;user_groups.uid&lt;/parameter&gt;
+            &lt;/mode&gt;
+            &lt;mode name="attribute" type="attrib"&gt;
+               &lt;parameter&gt;org.apache.cocoon.components.modules.output.OutputModule:user.uid[0]&lt;/parameter&gt;
+            &lt;/mode&gt;
+         &lt;/key&gt;
+         &lt;key name="gid" type="int" set="master"&gt;
+            &lt;mode name="request" type="all"&gt;
+               &lt;parameter&gt;user_groups.gid&lt;/parameter&gt;
+            &lt;/mode&gt;
+         &lt;/key&gt;
+      &lt;/keys&gt;
+   &lt;/table&gt;
+
+      </pre>
+<p>
+      The above example shows just that: the <span class="codefrag">parameter</span>
+      element is not read by the database action itself but the
+      complete <span class="codefrag">mode</span> configuration object is passed to the
+      input module. Both the request attribute and the request parameter
+      input modules understand this parameter attribute which takes
+      precedence over the default one.
+      </p>
+<p>
+      Another feature when obtaining values is tied to the
+      <span class="codefrag">type</span> attribute: Different modes can be used in
+      different situations. The basic setup uses two different mode
+      types: <span class="codefrag">autoincrement</span> when inserting in key columns
+      that have an indicator that they are indeed auto increment columns
+      and <span class="codefrag">others</span> for insert operations on all other columns
+      and all other operations on all columns.
+      </p>
+<p>
+      Table-sets can override the default names for these two mode type
+      name categories with arbitrary names except the special name
+      <span class="codefrag">all</span>. A mode that carries the type name "all" is used
+      with all requested type names. Lookup obeys first match principle
+      so that all modes are tested from top to bottom and the first that
+      matches is used.
+      </p>
+<h3>How to store Values e.g. in your Session</h3>
+<p>
+      All modular database action can be configured to use any component
+      that implements the <span class="codefrag">OutputModule</span> interface to store
+      values. The output module is chosen on declaring the action in the
+      sitemap or dynamically with a sitemap parameter. If no output
+      module is specified, the default it to use the request attribute
+      module.
+      </p>
+<p>
+      The interface does not allow to pass configuration information to
+      the output module. This has to be done when the module is declared
+      e.g. in cocoon.xconf.
+      </p>
+<h3>Inserting Multiple Rows - Sets</h3>
+<p>
+      Once common task is to work on more than one row. If the rows are
+      in different tables, this is catered for by table-sets. Operating
+      on multiple rows of one table requires to mark columns that should
+      vary and among those one, that determines the number of rows to
+      work on.
+      </p>
+<p>
+      This is done with sets. All columns that cary a <span class="codefrag">set</span>
+      attribute can vary, those, that don't, are kept fixed during the
+      operation. The column that is used to determine the number of rows
+      is required to have a value of <span class="codefrag">master</span> while all others
+      need to have a value of <span class="codefrag">slave</span> for the set
+      attribute. There may be only one master in a set.
+      </p>
+<p>
+      Sets can be tagged either on column or on mode level but not both
+      for a single column.
+      </p>
+<h3>Select Your Tables - Table-Sets</h3>
+<p>
+      Tables that should be used during an operation can be grouped
+      together with a table-set. A table-set references tables by their
+      name or their alias.
+      </p>
+<p>
+      In addition, a table-set can override the mode type names for the
+      two categories "autoincrement" and "others".
+      </p>
+<p>
+      Operations spanning multiple tables in a table-set are done in a
+      single transaction. Thus, if one fails, the other is rolled back.
+      </p>
+<pre class="code">
+
+
+   &lt;table name="groups"&gt;
+      &lt;keys&gt;
+         &lt;key name="gid" type="int" autoincrement="true"&gt;
+            &lt;mode name="auto" type="autoincr"/&gt;
+         &lt;/key&gt;
+      &lt;/keys&gt;
+      &lt;values&gt;
+         &lt;value name="gname" type="string"/&gt;
+      &lt;/values&gt;   
+   &lt;/table&gt;
+   
+   &lt;table-set name="user"&gt;
+      &lt;table name="user"/&gt;
+   &lt;/table-set&gt;
+
+   &lt;table-set name="groups"&gt;
+      &lt;table name="groups"/&gt;
+   &lt;/table-set&gt;
+
+   &lt;table-set name="user+groups"&gt;
+      &lt;table name="user"/&gt;
+      &lt;table name="user_groups" others-mode="attrib"/&gt;
+   &lt;/table-set&gt;
+
+   &lt;table-set name="user_groups"&gt;
+      &lt;table name="user_groups" others-mode="request"/&gt;
+   &lt;/table-set&gt;
+
+&lt;/root&gt;
+
+      </pre>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/meta.xml
new file mode 100644
index 0000000..1c06fe4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-actions/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/actions/database-actions.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/content_en.html
new file mode 100644
index 0000000..681a7bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/content_en.html
@@ -0,0 +1,285 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>DatabaseReader</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the DatabaseReader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>DatabaseReader</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">databasereader</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">DatabaseReader</span> component is used 
+            to serve data from a database
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Database</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.DatabaseReader</td>
+        
+</tr>
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">yes</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        This Reader pulls a resource from a database.  It is configured with
+        the Connection to use, parameters specify the table and column
+        to pull the image from, and source specifies the source key information.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+      
+</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The following pipeline snippet uses a <span class="codefrag">Database Reader</span> 
+          for serving <em>PNG</em> images from a database.
+        </p>
+<pre class="code">
+&lt;map:match pattern="images/*.png"&gt;
+  &lt;map:read type="databasereader" 
+    src="{1}" 
+    mime-type="image/png"&gt;
+    &lt;!-- option sitemap parameters --&gt;
+    &lt;map:parameter name="table" value="images"/&gt;
+    &lt;map:parameter name="image" value="image"/&gt;
+    &lt;map:parameter name="key" value="name"/&gt;
+    &lt;map:parameter name="where" value="publishing = 1"/&gt;
+    &lt;map:parameter name="order-by" value="created"/&gt;
+    &lt;map:parameter name="last-modified" value="last-modified"/&gt;
+  &lt;/map:read&gt;
+&lt;/map:match&gt;
+        </pre>
+<p>
+          The snippet above make following assumption about the database
+        </p>
+<ul>
+          
+<li>A database table <span class="codefrag">images</span> holds the <em>PNG</em> image data.</li>
+          
+<li>The database table has <span class="codefrag">image</span> column storing the image data as <span class="codefrag">BLOB</span>.
+          </li>
+          
+<li>The database table has <span class="codefrag">key</span> column which must match the value of 
+            of <span class="codefrag">{1}</span>.
+          </li>
+          
+<li>The database table has <span class="codefrag">publishing</span> column indicating by value <span class="codefrag">1</span>
+            that the image data is allowed to get published.
+          </li>
+          
+<li>The database table has <span class="codefrag">created</span> column, indicating the creation date of
+            the image data, and used if the <span class="codefrag">key</span> is not a primary key, serving
+            images in a LIFO fashion.
+          </li>
+          
+<li>The database table has <span class="codefrag">last-modified</span> column of type <span class="codefrag">TIMESTAMP</span>
+            indicating the last modification date of the image data.
+          </li>
+        
+</ul>
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:readers...
+  &lt;map:reader name="databasereader" 
+    src="org.apache.cocoon.reading.DatabaseReader"
+    logger="sitemap.reader.databasereader" 
+    pool-max="32"/&gt;
+    &lt;!-- optional reader configuration --&gt;
+    ...
+  &lt;/map:readers&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          In the <span class="codefrag">Database Reader</span> declaration section following configuration 
+          options are available
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Configurationname</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">use-connection</td><td colspan="1" rowspan="1">Data source name</td>
+            <td colspan="1" rowspan="1">The name of a database selector, configured in the
+              <span class="codefrag">cocoon.xconf</span> file.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">invalidate</td><td colspan="1" rowspan="1"> never | always </td>
+            <td colspan="1" rowspan="1">
+              This option configures the caching behaviour if lastModifed
+              has value of <span class="codefrag">-1</span>.
+            </td>
+          
+</tr>
+        
+</table>
+      
+<h2>Setup</h2>
+<p>
+          The <span class="codefrag">DatabaseReader</span> accepts following setup parameters
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Parametername</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">table</td><td colspan="1" rowspan="1">database table name</td>
+            <td colspan="1" rowspan="1">The database table name</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">image</td><td colspan="1" rowspan="1">database column name</td>
+            <td colspan="1" rowspan="1">The column name of the image data</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">key</td><td colspan="1" rowspan="1">database key column name</td>
+            <td colspan="1" rowspan="1">The key column name of the image data matching the src attribute of
+              the &lt;map:read&gt; sitemap usage.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">where</td><td colspan="1" rowspan="1">database where expression</td>
+            <td colspan="1" rowspan="1">Optional parameter specifying SQL where expression.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">order-by</td><td colspan="1" rowspan="1">database order-by expression</td>
+            <td colspan="1" rowspan="1">Optional parameter specifying an SQL order-by expression.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">last-modified</td><td colspan="1" rowspan="1">timestamp column name</td>
+            <td colspan="1" rowspan="1">Optional parameter a <span class="codefrag">TIMESTAMP</span> column name, added
+              to the <span class="codefrag">SELECT</span> clause of the SQL query. 
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">content-type</td><td colspan="1" rowspan="1">database column name</td>
+            <td colspan="1" rowspan="1">Optional parameter a column name, if specified the column
+              value overrides the <span class="codefrag">mime-type</span> attribute of the
+              &lt;map:read&gt; sitemap usage.
+            </td>
+            
+</tr>
+        
+</table>
+<p>
+          The key value is derived from the <span class="codefrag">src</span> attribute
+          of the <span class="codefrag">Database Reader</span> usage..
+        </p>
+<p>
+          The <span class="codefrag">Database Reader</span> builds internally following SQL query:
+        </p>
+<pre class="code">
+SELECT {image} [, last-modified] [, {order-by-column} ] from {table}
+  WHERE {key} = {src} [ AND {where} ]
+  [ORDER BY {order-by}]
+        </pre>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">Database Reader</span> needs a datasource name, it is referenced
+        by the configuration element <span class="codefrag">use-connection</span>. The datasource name
+        has to be configured in the Cocoon database configuration <span class="codefrag">cocoon.xconf</span>.
+      </p>
+      
+<p>
+        If the parameter <span class="codefrag">last-modified</span> ends with <span class="codefrag">" DESC"</span> this
+        suffix is truncated as it is appended to the SQL clause, noted as {order-by-column}
+        in the SQL query snippet above.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-25-02: created initial version by Bernhard Huber
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages -->
+      
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/meta.xml
new file mode 100644
index 0000000..086c79c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-database-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/database-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-sql-transformer/content_en.xdoc b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-sql-transformer/content_en.xdoc
new file mode 100644
index 0000000..29201fb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-databases-sql-transformer/content_en.xdoc
@@ -0,0 +1,538 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
+
+<document>
+  <header>
+    <title>SQL Transformer</title>
+    <version>$Id$</version>
+    <authors>
+      <person name="Sven Beauprez" email="Sven.Beauprez@the-ecorp.com"/>
+      <person name="Davanum Srinivas" email="dims@yahoo.com"/>
+    </authors>
+  </header>
+  <body>
+    <s1 title="Introduction">
+      <p>
+        The purpose of the SQLTransformer is to query a database and translate
+        the result to XML. To retrieve the information from the database, you
+        are not restricted to use simple SQL statements (e.g. select, insert,
+        update), it is also possible to use stored procedures. In combination
+        with other transformers (e.g. FilterTransformer), this one can be very
+        powerful.
+      </p>
+      <ul>
+        <li>Name: sql</li>
+        <li>Class: org.apache.cocoon.transformation.SQLTransformer</li>
+        <li>Cacheable: no</li>
+      </ul>
+    </s1>
+    <s1 title="Basic functionality">
+      <p>
+        To be able to query a database, we need XML that describes exactly what
+        we want to do. The general structure of this input XML is as follows:
+      </p>
+      <source>
+      <![CDATA[
+  <page>
+    <sql:execute-query xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:query>
+      <!-- here comes the SQL statement or stored procedure -->
+      </sql:query>
+    </sql:execute-query>
+  </page>
+   ]]></source>
+      <p>
+        Nothing prevents you from putting other XML around the
+        <code>execute-query</code> element. Any element not in the SQL namespace
+        will stay untouched. The format of the SQL statement or the stored
+        procedure is exactly the same as if you would call it directly from java
+        with a prepared statement or a callable statement.
+      </p>
+      <p>The query element has the following optional attributes:</p>
+      <ol>
+        <li>
+          <strong>name</strong>:
+          Naming a query implicates naming the corresponding rowset (see below).
+          When you have a sequence of queries you want to execute, it can be
+          handy give them a name. To process the retrieved data of a certain
+          query, you can use another transformer to check the name of the rowset
+          and to execute the necessary business logic on it.
+          <br/>
+          usage: <code>&lt;sql:query name="myName"&gt;</code>
+        </li>
+        <li>
+          <strong>isstoredprocedure</strong>:
+          When you want to use stored procedures, you have to explicitly add
+          this attribute to the query element. By default, the transformer
+          assumes that you want to execute a SQL statement.
+          <br/>
+          usage: <code>&lt;sql:query isstoredprocedure="true"&gt;</code>
+        </li>
+      </ol>
+      <p>Here is an example of how the input XML might look like:</p>
+      <source>
+      <![CDATA[
+  <page>
+   <title>Hello</title>
+   <content>
+    <para>This is my first Cocoon page filled with sql data!</para>
+    <sql:execute-query xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+     <sql:query name="department">
+       select id,name from department_table
+     </sql:query>
+    </sql:execute-query>
+   </content>
+  </page>
+   ]]></source>
+      <p>
+        You can use the file generator to retrieve the XML from the filesystem.
+        To invoke the SQLTransformer you have to add following to the sitemap:
+      </p>
+      <source>
+      <![CDATA[
+  <map:transform type="sql">
+    <map:parameter name="use-connection" value="personnel"/>
+    <map:parameter name="show-nr-of-rows" value="true"/>
+    <map:parameter name="clob-encoding" value="UTF-8"/>
+  </map:transform>
+   ]]></source>
+      <p>
+        The <code>use-connection</code> parameter defines which connection,
+        defined under the datasources element in <code>cocoon.xconf</code>, the
+        SQLTransformer has to use to retrieve the data.
+      </p>
+      <p>
+        The <code>show-nr-of-rows</code> instructs the transformer to count the
+        number of rows in the resultset explicitly and to set the result as
+        attribute to the rowset element. This attribute is only useful in
+        combination with a sql statement, not with stored procedures. If a
+        stored procedure returns a resultset and you want to know how many rows
+        it contains, you have to count the number of rows in another transformer
+        or your stored procedure has to return it also (last solution is the
+        best one).
+      </p>
+      <p>
+        The <code>clob-encoding</code> parameter defines what encoding should be
+        used in getting content from CLOB columns.
+      </p>
+      <p>The output XML will look as follows:</p>
+      <source>
+      <![CDATA[
+  <page>
+   <title>Hello</title>
+   <content>
+    <para>This is my first Cocoon page filled with sql data!</para>
+    <sql:rowset nrofrows="2" name="department"
+                xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:row>
+        <sql:id>1</sql:id>
+        <sql:name>Programmers</sql:name>
+      </sql:row>
+      <sql:row>
+        <sql:id>2</sql:id>
+        <sql:name>Loungers</sql:name>
+      </sql:row>
+    </sql:rowset>
+   </content>
+  </page>
+   ]]></source>
+      <p>
+        If you use this in combination with the <code>simple-sql2html.xsl</code>
+        stylesheet,
+      </p>
+      <source>
+      <![CDATA[
+  <map:transform src="stylesheets/simple-sql2html.xsl"/>
+   ]]></source>
+      <p>you will get a more visually attractive page.</p>
+      <p>See below for a more in depth example with stored procedures.</p>
+      <p>
+        By now you should be able to use the SQLTransformer, but there are some
+        more options you might find useful...
+      </p>
+    </s1>
+    <s1 title="Advanced functionality">
+      <s2 title="Substitution">
+        <p>
+          Sometimes you need more information before you can execute a query,
+          e.g. the name of the user that is currently logged on your site. This
+          information is only available at runtime and hence can only be
+          substituted in the query when available.
+        </p>
+        <p>
+          To pass this information to the SQL statement, the input XML has to
+          look like this:
+        </p>
+        <source>
+        <![CDATA[
+  <page>
+    <sql:execute-query xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:query>
+        select id,name from employee_table where name =
+            '<sql:substitute-value name="username"/>'
+      </sql:query>
+    </sql:execute-query>
+  </page>
+     ]]></source>
+        <p>
+          The substitution is done by the SQLTransformer before it executes the
+          query (before it calls the method <code>prepareStatement</code>!). For
+          this, the transformer has to be given the necessary values via the
+          sitemap (as parameter):
+        </p>
+        <source>
+        <![CDATA[
+  <map:transform type="sql">
+    <map:parameter name="use-connection" value="personnel"/>
+    <map:parameter name="show-nr-of-rows" value="true"/>
+    <map:parameter name="username" value="Stefano Mazzocchi"/>
+  </map:transform>
+     ]]></source>
+        <p>
+          Whenever the transformer encounters a <code>substitute-value</code>
+          element for which the attribute <code>name</code> contains the value
+          <code>username</code>, it will replace this element with the value
+          <code>Stefano Mazzocchi</code>.
+        </p>
+        <p>The output XML will be as follow:</p>
+        <source>
+        <![CDATA[
+  <page>
+    <sql:rowset nrofrows="1" xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:row>
+        <sql:id>2</sql:id>
+        <sql:name>Stefano Mazzocchi</sql:name>
+      </sql:row>
+    </sql:rowset>
+  </page>
+     ]]></source>
+        <p>
+          It is also possible to use substitution in combination with stored
+          procedures.
+        </p>
+      </s2>
+      <s2 title="Ancestors">
+        <p>This functionality is best described by a simple example.</p>
+        <p>Take following input XML:</p>
+        <source>
+        <![CDATA[
+  <page>
+    <sql:execute-query xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:query name="department">
+        select id, name from department_table
+      </sql:query>
+      <sql:execute-query>
+        <sql:query name="employee">
+          select id, name from employee_table where department_id =
+              <sql:ancestor-value name="id" level="1"/>
+        </sql:query>
+      </sql:execute-query>
+    </sql:execute-query>
+  </page>
+     ]]></source>
+        <p>
+          The first query will retrieve all <code>id</code>'s and
+          <code>name</code>'s from the <code>department_table</code> table. For
+          each <code>id</code> that comes from the
+          <code>department_table</code>, the second query, in which the
+          <code>ancestor-value</code> element will be replaced by the
+          <code>id</code>, will be executed. The above example will be
+          transformed to the following XML:
+        </p>
+        <source>
+        <![CDATA[
+  <page>
+    <sql:rowset nrofrows="2" name="department"
+                xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:row>
+        <sql:id>1</sql:id>
+        <sql:name>Programmers</sql:name>
+        <sql:rowset nrofrows="2" name="employee">
+          <sql:row>
+            <sql:id>1</sql:id>
+            <sql:name>Donald Ball</sql:name>
+          </sql:row>
+          <sql:row>
+            <sql:id>2</sql:id>
+            <sql:name>Stefano Mazzocchi</sql:name>
+          </sql:row>
+        </sql:rowset>
+      </sql:row>
+      <sql:row>
+        <sql:id>2</sql:id>
+        <sql:name>Loungers</sql:name>
+        <sql:rowset nrofrows="1" name="employee">
+          <sql:row>
+            <sql:id>3</sql:id>
+            <sql:name>Pierpaolo Fumagalli</sql:name>
+          </sql:row>
+        </sql:rowset>
+      </sql:row>
+    </sql:rowset>
+  </page>
+     ]]></source>
+      </s2>
+      <s2 title="in- and out-parameters">
+        <p>
+          Stored procedures can return data as a parameter. To make use of this
+          functionality in java, you have to register these parameters as
+          <em>out parameters</em>. Since this information is application
+          specific, the SQLTransformer uses reflection to retrieve the data in
+          the right format. For this, an extra element is needed in the input
+          XML:
+        </p>
+        <source>
+        <![CDATA[
+  <sql:out-parameter nr="1"
+                     name="code"
+                     type="java.sql.Types.INTEGER"/>
+     ]]></source>
+        <p>where:</p>
+        <ol>
+          <li>
+            <strong>nr</strong>:
+            The targeted parameter number that will return data of a certain
+            type.
+          </li>
+          <li>
+            <strong>type</strong>:
+            The type of data that will be returned (defined in
+            <code>java.sql.Types</code> or in database specific drivers, e.g.
+            <code>oracle.jdbc.driver.OracleTypes</code>). Once the stored
+            procedure returns data in the parameters, the stored procedure tries
+            to process them. If the returned parameter is an instance of
+            <code>ResultSet</code>, it will be translated to XML as we saw
+            before. In all the other situations the SQLTransformer will convert
+            the parameter to a string.
+          </li>
+        </ol>
+        <p>
+          This is an example of how to call an oracle stored procedure and
+          process it with the SQLTransformer:
+        </p>
+        <source>
+        <![CDATA[
+  <page>
+    <sql:execute-query xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+      <sql:query isstoredprocedure="true" name="namesearch">
+        begin QUICK_SEARCH.FIND_NAME('<sql:substitute-value
+            name="username"/>',?,?,?); end;
+      </sql:query>
+      <sql:out-parameter nr="1" name="code"
+                         type="java.sql.Types.INTEGER"/>
+      <sql:out-parameter nr="2" name="nrofrows"
+                         type="java.sql.Types.INTEGER"/>
+      <sql:out-parameter nr="3" name="resultset"
+                         type="oracle.jdbc.driver.OracleTypes.CURSOR"/>
+    </sql:execute-query>
+  </page>
+     ]]></source>
+        <p>
+          The SQLTransformer will create 3 elements, respectively
+          <code>code</code>, <code>nrofrows</code> and <code>resultset</code>
+          under the element <code>namesearch</code>. Since the type
+          <code>oracle.jdbc.driver.OracleTypes.CURSOR</code> corresponds to a
+          <code>ResultSet</code>, a <code>rowset</code> element will be created,
+          containing all the data of the resultset. It is also possible to use
+          an <em>in-parameter</em> element, e.g.
+          <code>&lt;sql:in-parameter nr="1" value="1"/&gt;</code>. This
+          functionality is only provided to be complete, because it is available
+          in Java itself. You can also use the <em>in-parameter</em> in
+          combination with a SQL statement. Used in combination with an
+          <em>out-parameter</em>, a <em>?-parameter</em> can be an
+          <em>in-parameter</em> and an <em>out-parameter</em> at the same time.
+        </p>
+      </s2>
+    </s1>
+    <s1 title="Combined with other transformers">
+      <s2 title="FilterTransformer">
+        <p>
+          When you query a database and it returns too many rows to process at
+          once, you might want to take a block of elements, process this block
+          and ignore the rest for now. You can best compare it to a search on
+          Google: they only return 10 results in one time, for more results you
+          have to click on another block (page). It wouldn't be wise to process
+          more than 10 elements in the pipeline if you only need to display 10
+          elements.
+        </p>
+        <p>
+          Assume that a query returns 56 row elements (by using the
+          SQLTransformer) and that you only want to display the first 10
+          elements:
+        </p>
+        <p>Output XML from the SQLTransformer:</p>
+        <source>
+        <![CDATA[
+  <sql:rowset nrofrows="56" name="test"
+              xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+    <sql:row>
+      <!-- db record -->
+    </sql:row>
+    <sql:row>
+      <!-- db record -->
+    </sql:row>
+
+    ...
+
+    <sql:row>
+      <!-- db record -->
+    </sql:row>
+  </sql:rowset>
+     ]]></source>
+        <p>
+          By adding following lines to the sitemap, just under the
+          SQLTransformer, you restrict the results to 10 elements in the first
+          block:
+        </p>
+        <source>
+        <![CDATA[
+  <map:transform type="filter">
+    <map:parameter name="element-name" value="row"/>
+    <map:parameter name="count" value="10"/>
+    <map:parameter name="blocknr" value="1"/>
+  </map:transform>
+     ]]></source>
+        <p>output XML:</p>
+        <source>
+        <![CDATA[
+  <sql:rowset nrofrows="56" name="test"
+              xmlns:sql="http://apache.org/cocoon/SQL/2.0">
+    <block id="1">
+      <sql:row>
+        <!-- db record -->
+      </sql:row>
+
+      <!-- total of 10 rows -->
+
+      <sql:row>
+        <!-- db record -->
+      </sql:row>
+    </block>
+    <block id="2"/>
+    <block id="3"/>
+    <block id="4"/>
+    <block id="5"/>
+    <block id="6"/>
+  </sql:rowset>
+     ]]></source>
+        <p>
+          To make it more dynamically, put something like
+          <code>{reqCount}</code> and <code>{reqBlock}</code> in the values for
+          <em>count</em> and <em>blocknr</em> respectively. These can be
+          parameters from the request and they can be passed to the sitemap with
+          an action.
+        </p>
+        <p>
+          The FilterTransformer is a standalone component; you don't need to use
+          it in combination with the SQLTransformer.
+        </p>
+      </s2>
+      <s2 title="WriteDOMSessionTransformer">
+        <p>
+          If you only use the FilterTransformer in combination with the
+          SQLTransformer, you have to query the database each time the user
+          wants to see another part of the result. You can better store the
+          result in the session after the first request and retrieve the result
+          from the session for the subsequent requests. This can be done by
+          using a selector, which checks if the data is available in the session
+          or not.
+        </p>
+        <p>
+          WriteDOMSessionTransformer can build a DOM starting from a given
+          element (which will be the root of the DOM tree) and store it in the
+          session. If you want to store the result of a query, you have to add
+          following to the sitemap:
+        </p>
+        <source>
+        <![CDATA[
+  <map:transform type="writeDOMsession">
+    <map:parameter name="dom-name" value="DBresult"/>
+    <map:parameter name="dom-root-element" value="rowset"/>
+  </map:transform>
+     ]]></source>
+        <p>
+          The transformer will build a DOM tree with <code>rowset</code> as root
+          element and will store it in the session with the name
+          <code>DBresult</code>.
+        </p>
+        <note>
+          Most of the times, it is not smart to keep the output XML of the
+          SQLTransformer in the session. Check if it is better to do the
+          necessary transformations first, so that you get a smaller DOM, and
+          then put the result in the session. You probably will be able to use
+          the FilterTransformer on the transformed XML also.
+        </note>
+        <p>
+          The WriteDOMSessionTransformer is a standalone component, you don't
+          need to use it in combination with the SQLTransformer.
+        </p>
+      </s2>
+      <s2 title="ReadDOMSessionTransformer">
+        <p>
+          Simply transforms a DOM to SAX events, which can be used further on in
+          the pipeline. Once you stored the result of a query in the session
+          with the WriteDOMSessionTransformer, you can read it again with the
+          ReadDOMSessionTransformer:
+        </p>
+        <source>
+        <![CDATA[
+  <map:transform type="readDOMsession">
+    <map:parameter name="dom-name" value="DBresult"/>
+    <map:parameter name="trigger-element" value="users"/>
+    <map:parameter name="position" value="after"/>
+  </map:transform>
+     ]]></source>
+        <p>
+          In this example the SAX events, that come from the DOM tree stored in
+          the session with name <code>DBresult</code>, will be added after the
+          <code>users</code> element. This means as soon that the transformer
+          encounters the end element <code>users</code>, it will start to
+          generate SAX events from the DOM tree. There are three possible
+          positions, <code>before</code>, <code>in</code> and
+          <code>after</code>:
+        </p>
+        <ol>
+          <li>
+            <strong><code>before</code></strong> means that when the transformer
+            encounters the <code>users</code> element, it will FIRST translate
+            the DOM tree to SAX events and THEN it will continue to forward the
+            other SAX events (starting with <code>users</code>).
+          </li>
+          <li>
+            <strong><code>in</code></strong> means that the transformer will
+            forward the start element event for <code>users</code> and that it
+            IMMEDIATELY starts to generate SAX events from the DOM tree. After
+            that, it will continue to forward the child elements of users and
+            then all the other elements.
+          </li>
+          <li>
+            <strong><code>after</code></strong> means that the transformer
+            starts to generate SAX events from the DOM tree just after it has
+            forwarded the end element <code>users</code>.
+          </li>
+        </ol>
+        <p>
+          The ReadDOMSessionTransformer is a standalone component, you don't
+          need to use it in combination with the WriteDOMSessionTransformer.
+        </p>
+      </s2>
+      <p>That's it,</p>
+      <p>Sven Beauprez</p>
+    </s1>
+  </body>
+</document>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/content_en.html
new file mode 100644
index 0000000..be7d1dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/content_en.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>DELI Quick Start Guide</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Mark H. Butler" name="DC.Creator">
+</head>
+<body>
+		
+<h1>DELI Quick Start Guide</h1>
+
+<p>If you are seeing the 'DELI is switched off' message when you try the test pages then you need to enable DELI. If you do not
+want to rebuild Cocoon, just
+add the following lines to the deployed <span class="codefrag">cocoon.xconf</span>:</p>
+				
+<pre class="code">
+&lt;deli class="org.apache.cocoon.components.deli.DeliImpl"&gt;
+   &lt;parameter name="deli-config-file" value="deli/config/deliCocoonConfig.xml"/&gt;
+&lt;/deli&gt;
+</pre>
+
+<p>However if you are developing with Cocoon and need DELI you may prefer to make the same change to the <span class="codefrag">deli.xconf</span> file in 
+<span class="codefrag">src\java\components\deli</span>. When you build Cocoon, this file is inserted into the <span class="codefrag">cocoon.xconf</span> file.</p>
+
+
+<p>By default DELI recognises Internet Explorer, Netscape, Opera, Amaya
+and the Nokia WAP development kit as legacy browsers. If you are 
+using a different browser, you may need to edit the 
+<span class="codefrag">legacyDevices.xml</span>, the DELI legacy device support file. For more 
+details see the <a href="deli.html">DELI documentation</a>.</p>
+
+		
+	
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/meta.xml
new file mode 100644
index 0000000..905b611
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-deli-quick/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/deliquick.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/content_en.html
new file mode 100644
index 0000000..f58f170
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/content_en.html
@@ -0,0 +1,729 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>DELI</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Mark H. Butler" name="DC.Creator">
+</head>
+<body>
+		
+<h1>Introduction</h1>
+			
+<p>In order for a web server 
+to provide optimized content to different clients it requires a description of the 
+capabilities of the client. Two new compatible standards have been created for 
+describing delivery context based on the 
+<a class="external" href="http://www.w3.org/RDF/">Resource Description Framework (RDF)</a>: 
+<a class="external" href="http://www.w3.org/Mobile/CCPP/">Composite Capabilities / Preferences Profile (CC/PP)</a> 
+created by the <a class="external" href="http://www.w3.org">W3C</a> and 
+<a class="external" href="http://www1.wapforum.org/tech/terms.asp?doc=WAP-248-UAProf-20010530-p.pdf">User Agent Profile (UAProf)</a> 
+created by the 
+<a class="external" href="http://www.wapforum.org">WAP Forum</a>. 
+These standards allow the efficient transmission of 
+delivery context information to the server even via low bandwidth wireless networks. 
+Instead of sending an entire profile with every request, 
+a client only sends a reference to a profile, stored on a third device known 
+as a profile repository, along with a list of differences specific to this particular 
+client. The process of reassembling the final profile from 
+the profile references and differences is known as profile resolution.</p>
+			
+<p>
+				
+<a class="external" href="http://www-uk.hpl.hp.com/">HP Labs</a> 
+has produced an open-source library called DELI that allows Java servlets to resolve HTTP requests 
+containing CC/PP or UAProf information and query the resolved 
+profile. This document describes how DELI may be used
+within Apache Cocoon. For more information on the DELI library please refer to the 
+<a class="external" href="http://www-uk.hpl.hp.com/people/marbut/">DELI web-site</a>.
+DELI currently uses 
+<a class="external" href="http://www.hpl.hp.com/semweb/jena-top.html">Jena</a>, an RDF 
+Framework developed at HP Labs. For more details of Jena see Brian McBride's 
+<a class="external" href="http://www-uk.hpl.hp.com/people/bwm/papers/20001221-paper/">paper</a> 
+and the HP Labs 
+<a class="external" href="http://www.hpl.hp.com/semweb/">Semantic Web activity</a> homepage.</p>
+		
+		
+<h1>CC/PP</h1>
+			
+<p>CC/PP is described in 
+<a class="external" href="http://www.w3.org/TR/CCPP-struct-vocab/">CC/PP Structure and Vocabularies</a>, 
+<a class="external" href="http://www.w3.org/TR/2000/WD-CCPP-ra-20000721/">CC/PP Requirements and Architecture</a> and 
+<a class="external" href="http://www.w3.org/TR/2000/WD-CCPP-ta-20000721/">CC/PP Terminology and Abbreviations</a>.
+A CC/PP profile is broadly constructed as a two level hierarchy: 
+a profile has a number of components and each component has a number 
+of attributes. A protocol for transmitting CC/PP profiles has been
+<a class="external" href="http://www.w3.org/TR/NOTE-CCPPexchange">proposed</a> but is based on an experimental 
+variant of HTTP known as <a class="external" href="http://www.w3.org/Protocols/HTTP/ietf-http-ext/">HTTP-ex</a> so is not compatible with existing servers. 
+Therefore DELI uses the W-HTTP protocol proposed by UAProf. This has identical functionality to the CC/PP 
+protocol based on HTTP-ex, but is compatible with HTTP/1.1.</p>
+		
+		
+<h1>UAProf</h1>
+			
+<p>The UAProf specification is based on the CC/PP specification. Like CC/PP, 
+a UAProf profile is a two level hierarchy composed of components and 
+attributes. Unlike CC/PP, the UAProf specification also proposes a vocabulary 
+- a specific set of components and attributes - to describe the next 
+generation of WAP phones. 
+The specification also describes two protocols for transmitting the profile 
+&gt;from the client to the server. Currently DELI only supports the W-HTTP protocol.</p>
+			
+<p>Profiles using the UAProf vocabulary consist of six components: 
+HardwarePlatform, SoftwarePlatform, NetworkCharacteristics, BrowserUA, 
+WapCharacteristics and PushCharacteristics. These components contain attributes. 
+In DELI each attribute has a distinct name and has an associated collection type, 
+attribute type and resolution rule. In UAProf there are three collection types:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">Simple</span> contains a single value e.g. ColorCapable in HardwarePlatform. </li>
+				
+<li>
+					
+<span class="codefrag">Bag</span> contains multiple unordered values e.g. BluetoothProfile in the 
+HardwarePlatform component.</li>
+				
+<li>
+					
+<span class="codefrag">Seq</span> contains multiple ordered values e.g. Ccpp-AcceptLanguage 
+in the SoftwarePlatform component.</li>
+			
+</ul>
+			
+<p>In addition attributes can have one of four attribute types:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">String</span> e.g. BrowserName in BrowserUA.</li>
+				
+<li>
+					
+<span class="codefrag">Boolean</span> e.g. ColorCapable in HardwarePlatform.</li>
+				
+<li>
+					
+<span class="codefrag">Number</span> is a positive integer e.g. BitsPerPixel in HardwarePlatform.</li>
+				
+<li>
+					
+<span class="codefrag">Dimension</span> is a pair of positive integers e.g. ScreenSize in HardwarePlatform.</li>
+			
+</ul>
+			
+<p>Finally attributes are associated with a resolution rule:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">Locked</span> indicates the final value of an attribute is the first 
+occurrence of the attribute outside the default description block.</li>
+				
+<li>
+					
+<span class="codefrag">Override</span> indicates the final value of an attribute is the last occurrence 
+of the attribute outside the default description block.</li>
+				
+<li>
+					
+<span class="codefrag">Append</span> indicates the final value of the attribute is the 
+list of all occurrences of the attribute outside the default 
+description block.</li>
+			
+</ul>
+			
+<p>The UAProf vocabulary is described using the file <span class="codefrag">uaprofspec.xml</span>. 
+This describes the attribute name, component, 
+collectionType, attributeType and resolution rule of each component. 
+The vocabulary description file has the following format:</p>
+			
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;vocabspec&gt;
+	&lt;attribute&gt;
+		&lt;name&gt;CcppAccept&lt;/name&gt;
+		&lt;component&gt;SoftwarePlatform&lt;/component&gt;
+		&lt;collectionType&gt;Bag&lt;/collectionType&gt;
+		&lt;attributeType&gt;Literal&lt;/attributeType&gt;
+		&lt;resolution&gt;Append&lt;/resolution&gt;
+	&lt;/attribute&gt;
+&lt;/vocabspec&gt;
+</pre>
+			
+<p>DELI can also read vocabularies described using RDF schemas. The WAP Forum have 
+			published two such schemas to describe the two versions of UAProf currently in use. However 
+			RDF Schema does not provide an easy way of describing attributeType or resolution rule. 
+			Therefore the UAProf schemas store this information in the comments field for each attribute. 			
+			Therefore DELI also parses the comments fields to create the vocabulary. This is not an ideal 
+			solution so hopefully a more robust way of representing this information will be used in later versions of UAProf.</p>
+		
+		
+<h1>W-HTTP Protocol</h1>
+			
+<p>An 
+example W-HTTP request using this protocol is shown below:</p>
+			
+<pre class="code">
+GET /ccpp/html/ HTTP/1.1
+Host: localhost
+x-wap-profile:"http://127.0.0.1:8080/ccpp/profiles/test09defaults.rdf", 
+  "1-Rb0sq/nuUFQU75vAjKyiHw=="
+x-wap-profile-diff:1;&lt;?xml version="1.0"?&gt;
+ &lt;rdf:RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
+  xmlns:prf="http://www.wapforum.org/profiles/UAPROF/ccppschema-20010430#"&gt;
+  &lt;rdf:Description rdf:ID="MyDeviceProfile"&gt;
+     &lt;prf:component&gt;
+       &lt;rdf:Description rdf:ID="HardwarePlatform"&gt;
+          &lt;rdf:type 
+  rdf:resource="http://www.wapforum.org/profiles/UAPROF/ccppschema-
+    20010426#HardwarePlatform"/&gt;
+  		&lt;prf:BitsPerPixel&gt;16&lt;/prf:BitsPerPixel&gt;
+       &lt;/rdf:Description&gt;
+     &lt;/prf:component&gt;
+  &lt;/rdf:Description&gt;
+ &lt;/rdf:RDF&gt;
+</pre>
+			
+<p>The first two lines
+describe the resource that is being requested by the client, 
+http://localhost/ccpp/html, and the method being used to make 
+the request, GET, and the protocol being used HTTP/1.1. The 
+remaining lines of the request describe the device delivery context. 
+This is specified using a profile reference and a profile-diff. 
+The profile is referenced via the x-wap-profile line and has the URI</p>
+			
+<pre class="code">
+http://127.0.0.1:8080/ccpp/profiles/test09defaults.rdf. 
+</pre>
+			
+<p>After the profile reference, there is a value</p>
+			
+<pre class="code">
+1-Rb0sq/nuUFQU75vAjKyiHw== 
+</pre>
+			
+<p>known as a profile-diff digest. 
+The first part of the profile-diff-digest, 1-, is the profile-diff 
+sequence number. This is used to indicate the order of the 
+profile-diffs and to indicate which profile-diff the profile-diff 
+digest refers to. The remainder of the profile-diff digest is 
+generated by applying the 
+<a class="external" href="http://www.faqs.org/rfcs/rfc1321.html">MD5 message digest algorithm</a> and Base64 
+algorithm to the corresponding profile-diff. The MD5 algorithm 
+takes as input a message of arbitary length and produces as output 
+a 128-bit "fingerprint" or "message-digest" of the input. 
+The 
+<a class="external" href="http://www.faqs.org/rfcs/rfc2045.html">Base64 algorithm</a> takes as input arbitary binary data and 
+produces as output printable encoding data.</p>
+			
+<p>After the profile-diff digest, the next line contains the 
+x-wap-profile-diff. This request header field also has a 
+profile-diff sequence number which indicates that this 
+profile-diff corresponds to the previous 
+profile-diff-digest. The profile-diff itself consists of the XML 
+fragment which spans the remainder of the request. Multi-line 
+request header fields are permitted by the HTTP/1.1 specification 
+as long as each subsequent line starts with either a tab character 
+or a whitespace. </p>
+			
+<p>When the server receives a HTTP request with UAProf 
+request headers, it has to perform profile resolution 
+i.e. retrieve the referenced profile(s) and any further 
+profiles referenced via default blocks. It then has to 
+merge these profiles and the profile-diffs while 
+applying the UAProf resolution rules.</p>
+		
+		
+<h1>Configuring DELI</h1>
+			
+<p>In order to use DELI, you need to enable the DELI component.
+In addition, you may want to configure DELI using <span class="codefrag">deliConfig.xml</span>, the DELI 
+configuration file or <span class="codefrag">legacyDevices.xml</span>, the
+DELI legacy device support file.</p>
+			
+<h2>Cocoon.xconf</h2>
+<p>In order to use DELI you need to configure Deli and specify
+the configuration file. You can either
+do this in <span class="codefrag">deli.xconf</span> in which case you will need to rebuild
+Cocoon or change the deployed <span class="codefrag">cocoon.xconf</span> in the web-server WEB-INF directory:</p>
+<pre class="code">
+  &lt;deli class="org.apache.cocoon.components.deli.DeliImpl"&gt;
+    &lt;parameter name="deli-config-file" value="deli/config/deliConfig.xml"/&gt;
+  &lt;/deli&gt;
+</pre>
+			
+<h2>Sitemap.xmap</h2>
+<p>In order to make profile information available to your stylesheet then you
+				 need to add <span class="codefrag">&lt;map:parameter name="use-deli" value="true"/&gt;</span> to the 
+				match that specifies your stylesheet in <span class="codefrag">sitemap.xmap</span>. Here is the match used for the deli test stylesheet:
+ </p>
+<pre class="code">
+   &lt;map:match pattern="deli.html"&gt;
+     &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+     &lt;map:transform src="stylesheets/deli_test.xsl" type="deli"&gt;
+         &lt;map:parameter name="use-deli" value="true"/&gt;
+     &lt;/map:transform&gt;
+     &lt;map:serialize type="html"/&gt;
+   &lt;/map:match&gt;
+</pre>
+			
+<h2>Main Configuration File</h2>
+<p>DELI also has its own
+configuration files that are found in the <span class="codefrag">resources\deli\config</span> directory. 
+The most important one, <span class="codefrag">deliConfig.xml</span> is used to configure the main DELI options:</p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;deli&gt;
+ &lt;localProfilesFile&gt;WEB-INF/deli/config/localProfiles.xml&lt;/localProfilesFile&gt;
+ &lt;localProfilesPath&gt;WEB-INF/deli/legacyProfiles&lt;/localProfilesPath&gt;
+ &lt;useLocalProfilesIfNoCCPP&gt;true&lt;/useLocalProfilesIfNoCCPP&gt;
+ &lt;useLocalProfilesInAdditionToCCPP&gt;false&lt;/useLocalProfilesInAdditionToCCPP&gt;
+ &lt;debug&gt;false&lt;/debug&gt;
+ &lt;printDefaults&gt;true&lt;/printDefaults&gt;
+ &lt;printProfileBeforeMerge&gt;false&lt;/printProfileBeforeMerge&gt;
+ &lt;processUndefinedAttributes&gt;true&lt;/processUndefinedAttributes&gt;
+ &lt;useCapabilityClasses&gt;false&lt;/useCapabilityClasses&gt; 
+ &lt;capabilityClassFile&gt;WEB-INF/deli/config/capClass.xml&lt;/capabilityClassFile&gt; 
+ &lt;namespaceConfigFile&gt;WEB-INF/deli/config/namespaceConfig.xml&lt;/namespaceConfigFile&gt;
+ &lt;!-- note that the default uri is also hardcoded --&gt;
+ &lt;rdfsUri&gt;http://www.w3.org/1999/PR-rdf-schema-19990303#&lt;/rdfsUri&gt;
+ &lt;rdfsUri&gt;http://www.w3.org/TR/PR-rdf-schema#&lt;/rdfsUri&gt;
+&lt;/deli&gt;
+</pre>
+<p>This file can contain a number of configuration directives described in 
+in the following sections:</p>
+<h3>Caching options</h3>
+<p>The caching options control how the server
+caches referenced profiles. DELI can either cache 
+profiles indefinitely or update stale profiles after a set 
+interval. It is also possible to configure the maximum size 
+of the profile cache.</p>
+<table>
+						
+<tr>
+							
+<th colspan="1" rowspan="1">Element Name</th>
+							<th colspan="1" rowspan="1">Default Value</th>
+							<th colspan="1" rowspan="1">Description</th>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">maxCachedProfileLifetime</td>
+							<td colspan="1" rowspan="1">24 hours</td>
+							<td colspan="1" rowspan="1">The maximum lifetime of a cached profile in hours.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">maxCacheSize</td>
+							<td colspan="1" rowspan="1">100</td>
+							<td colspan="1" rowspan="1">The maximum number of profiles in the profile cache.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">refreshStaleProfiles</td>
+							<td colspan="1" rowspan="1">false</td>
+							<td colspan="1" rowspan="1">Do we refresh cached profiles after the maximum lifetime has expired?</td>
+						
+</tr>
+					
+</table>
+<h3>Debugging options</h3>
+<p>The debugging options are used to control the 
+information that DELI prints to the Servlet engine console.</p>
+<table>
+						
+<tr>
+							
+<th colspan="1" rowspan="1">Element Name</th>
+							<th colspan="1" rowspan="1">Default Value</th>
+							<th colspan="1" rowspan="1">Description</th>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">debug</td>
+							<td colspan="1" rowspan="1">true</td>
+							<td colspan="1" rowspan="1">Is the automatic debug log information turned on?</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">printDefaults</td>
+							<td colspan="1" rowspan="1">true</td>
+							<td colspan="1" rowspan="1">Print both default and override values of attributes for debugging purposes?</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">printProfileBeforeMerge</td>
+							<td colspan="1" rowspan="1">false</td>
+							<td colspan="1" rowspan="1">Print the profile before merging for debugging purposes?</td>
+						
+</tr>
+					
+</table>
+<h3>Legacy device options</h3>
+<p>As already mentioned DELI can support legacy devices 
+by recognising the user-agent string supplied by a client 
+and mapping it on to a profile. In order to use this facility 
+it is necessary to supply an XML file that contains information 
+about legacy device user-agent strings and the corresponding 
+profile URLs. The format for the legacy device file is
+described in a subsequent section. </p>
+<table>
+						
+<tr>
+							
+<th colspan="1" rowspan="1">Element Name</th>
+							<th colspan="1" rowspan="1">Default Value</th>
+							<th colspan="1" rowspan="1">Description</th>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">useLocalProfilesIfNoCCPP</td>
+							<td colspan="1" rowspan="1">true</td>
+							<td colspan="1" rowspan="1">Use the legacy device database if devices send no CC/PP information?</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">localProfilesFile</td>
+							<td colspan="1" rowspan="1">legacyDevice.xml</td>
+							<td colspan="1" rowspan="1">The file containing the legacy device database.</td>
+						
+</tr>
+					
+</table>
+<h3>Protocol options</h3>
+<p>It is 
+possible to switch on whitespace normalisation in profile-diffs 
+prior to calculating the profile-diff-digest so that additional 
+whitespaces added by the proxy are ignored. To use this option clients must also support whitespace normalisation.</p>
+<table>
+						
+<tr>
+							
+<th colspan="1" rowspan="1">Element Name</th>
+							<th colspan="1" rowspan="1">Default Value</th>
+							<th colspan="1" rowspan="1">Description</th>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">normaliseWhitespaceInProfileDiff</td>
+							<td colspan="1" rowspan="1">true</td>
+							<td colspan="1" rowspan="1">Is whitespace normalisation of the profile-diff prior to calculating the profile-diff-digest turned on?</td>
+						
+</tr>
+					
+</table>
+<h3>Vocabulary options</h3>
+<p>DELI has a number of vocabulary options. Firstly 
+it is possible to configure the vocabulary using an 
+XML file, or if you are using UAProf using a UAProf RDF Schema.
+You can find examples of both approaches in this distribution.
+Secondly it is possible to 
+specify the URI to be used for the RDF namespace. 
+Thirdly it is possible to set the string used to represent 
+components and defaults in the vocabulary. This is important 
+because the two standards currently use different cases for 
+the first letter of default elements (CC/PP uses "default" 
+whereas UAProf uses "Default"). </p>
+<table>
+						
+<tr>
+							
+<th colspan="1" rowspan="1">Element Name</th>
+							<th colspan="1" rowspan="1">Default Value</th>
+							<th colspan="1" rowspan="1">Description</th>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">vocabularyFile</td>
+							<td colspan="1" rowspan="1">uaprofspec.xml</td>
+							<td colspan="1" rowspan="1">The file containing the vocabulary specification.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">schemaVocabularyFile</td>
+							<td colspan="1" rowspan="1">ccppschema-20000405.rdfs</td>
+							<td colspan="1" rowspan="1">The file containing the vocabulary specification as an UAProf RDF Schema. 
+							Use the attribute <span class="codefrag">namespace</span> to configure which namespace the schema corresponds to.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">rdfUri</td>
+							<td colspan="1" rowspan="1">http://www.w3.org/1999/02/22-rdf-syntax-ns#</td>
+							<td colspan="1" rowspan="1">The namespace used for RDF constructs.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">componentProperty</td>
+							<td colspan="1" rowspan="1">component</td>
+							<td colspan="1" rowspan="1">The name for components.</td>
+						
+</tr>
+						
+<tr>
+							
+<td colspan="1" rowspan="1">defaultProperty</td>
+							<td colspan="1" rowspan="1">Default</td>
+							<td colspan="1" rowspan="1">The name for defaults</td>
+						
+</tr>
+					
+</table>
+			
+<h2>Configuring Legacy Devices</h2>
+<p>It is easy to configure DELI to recognise legacy 
+devices via user-agent strings. A user-agent string is a string sent by the client to 
+the server as part of the HTTP request. It allows different browsers to be identified.  
+The legacy device configuration file maps user-agent 
+strings on to profile either on the local filestore or on a profile repository. 
+By default this is done in the <span class="codefrag">legacyDevice.xml</span> file which 
+has the following format:</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;devices&gt;
+&lt;!-- Alcatel --&gt;
+  &lt;device&gt;
+    &lt;ua value="Alcatel-BF4/2.0" profile="Alcatel_OT512.rdf"/&gt;
+  &lt;/device&gt;
+  &lt;device&gt;
+    &lt;ua value="Alcatel-BE4/1.0" profile="Alcatel_OT301.rdf"/&gt;
+  &lt;/device&gt;
+&lt;/devices&gt;
+</pre>
+<p>Where <span class="codefrag">vale</span> is a device unique string found in 
+the user-agent string of the device and <span class="codefrag">profile</span> is either a local file or a URL
+for the appropriate legacy profile. </p>
+		
+		
+<h1>Writing CC/PP and UAProf aware stylesheets</h1>
+			
+<p>Once you have got DELI running on Cocoon, the next
+step in creating a CC/PP aware site is to create some stylesheets that
+use profile information. DELI makes CC/PP or UAProf attributes available
+to XSLT stylesheets as parameters. In the process of doing this, DELI 'flattens' the profiles
+by omitting the component information. Hence to retrieve the
+<span class="codefrag">CcppAccept</span> attribute you use the XPath <span class="codefrag">deli-capabilities/browser/CcppAccept</span>
+whereas to retrieve the <span class="codefrag">ScreenSize</span> attribute you use the
+XPath <span class="codefrag">deli-capabilities/browser/ScreenSize</span>. 
+In addition where attributes contain multiple values e.g. Bags or Sequences
+those values are separated using <span class="codefrag">&lt;li&gt;</span> elements. 
+Hence to retrieve the individual elements you use the XPath 
+<span class="codefrag">deli-capabilities/browser/CcppAccept/li</span>. 
+The following code demonstrates how to retrieve both a simple and a complex
+attribute. For more complex examples see the <span class="codefrag">deli_test.xsl</span> stylesheet with Cocoon.</p>
+			
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
+ &lt;xsl:param name="deli-capabilities"/&gt;
+ &lt;xsl:template match="/"&gt;
+  &lt;xsl:if test="contains($deli-capabilities/browser/CcppAccept/li,'wml')"&gt;
+   &lt;xsl:call-template name="wmldevice"/&gt;
+  &lt;/xsl:if&gt;
+  &lt;xsl:if test="not(contains($deli-capabilities/browser/CcppAccept/li,'wml'))"&gt;
+   &lt;xsl:call-template name="htmldevice"/&gt;
+  &lt;/xsl:if&gt;
+ &lt;/xsl:template&gt;
+
+ &lt;xsl:template name="wmldevice"&gt;
+  &lt;wml&gt;
+   &lt;card id="init" newcontext="true"&gt;
+    &lt;p&gt;
+     &lt;xsl:call-template name="capabilities"/&gt;
+    &lt;/p&gt;
+   &lt;/card&gt;
+  &lt;/wml&gt;
+ &lt;/xsl:template&gt;
+
+ &lt;xsl:template name="htmldevice"&gt;
+  &lt;html&gt;
+   &lt;head&gt;
+    &lt;title&gt;Test Page for DELI in Cocoon&lt;/title&gt;
+   &lt;/head&gt;
+   &lt;body&gt;
+    &lt;xsl:call-template name="capabilities"/&gt;
+   &lt;/body&gt;
+  &lt;/html&gt;
+ &lt;/xsl:template&gt;
+
+ &lt;xsl:template name="capabilities"&gt;
+  &lt;xsl:if test="$deli-capabilities/browser/ImageCapable"&gt;
+   ImageCapable: &lt;xsl:value-of select="$deli-capabilities/browser/ImageCapable"/&gt;
+   &lt;br/&gt;
+  &lt;/xsl:if&gt;
+  &lt;xsl:if test="$deli-capabilities/browser/CcppAccept"&gt;
+   CcppAccept:
+   &lt;xsl:for-each select="$deli-capabilities/browser/CcppAccept/li"&gt;
+    &lt;xsl:value-of select="."/&gt;, 
+   &lt;/xsl:for-each&gt;
+   &lt;br/&gt;
+  &lt;/xsl:if&gt;
+ &lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+
+</pre>
+		
+		
+<h1>Incorporating DELI into other Cocoon components</h1>
+
+<p>If you want to use DELI in other Cocoon components, DELI needs to go through an 
+initialization phase in order to read in configuration files. This occurs in 
+<span class="codefrag">initialization()</span> in DeliImpl.java in the Cocoon DELI component in this line:</p>
+
+<pre class="code">
+Workspace.getInstance().configure(this.servletContext, this.deliConfig);
+</pre>
+
+<p>i.e. it constructs a DELI workspace object. In addition, DeliImpl.java has a number 
+of methods to get profile information, but the one which is of most use is <span class="codefrag">getProfile()</span>. 
+For examples of how to call DELI, see DeliTransformer.java - here are the relevant pieces.</p>
+
+
+<p>First import DELI:</p>
+
+<pre class="code">
+import org.apache.cocoon.components.deli.Deli;
+</pre>
+
+<p>Then in service(), initialize DELI:</p>
+
+<pre class="code">
+if (this.manager.hasComponent(Deli.ROLE)) {
+ if (this.getLogger().isDebugEnabled()) {
+     getLogger().debug("Looking up " + Deli.ROLE);
+}
+this.deli = (Deli) this.manager.lookup(Deli.ROLE);
+} else {
+  if (this.getLogger().isDebugEnabled()) {
+    getLogger().debug("Deli is not available");
+}
+}
+</pre>
+
+<p> Then in getLogicSheetParameters, call DELI to get 
+a profile and convert it into a DOM tree to give to XSLT as a parameter:</p>
+
+<pre class="code">
+if (this.deli != null &amp;&amp; this._useDeli) {
+  try {
+   Request request = ObjectModelHelper.getRequest(objectModel);
+   if (map == null) {
+    map = new HashMap();
+  }
+
+  org.w3c.dom.Document deliCapabilities = this.deli.getUACapabilities(request);
+  map.put("deli-capabilities", deliCapabilities);
+  } catch (Exception e) {
+    getLogger().error("Error setting DELI info", e);
+  }
+}
+</pre>
+
+<p>
+However, you don't want to pipe DELI to XSLT so here is some more 
+example code showing how to use DELI in Cocoon if you want to use the 
+DELI API directly:</p>
+
+
+<p>Import the deli component and the DELI API:</p>
+
+<pre class="code">
+import org.apache.cocoon.components.deli.Deli;
+
+import com.hp.hpl.deli.Profile;
+import com.hp.hpl.deli.ProfileAttribute;
+</pre>
+
+
+<p>Add code to initialize the service method as before</p>
+
+<pre class="code">
+  public void service(ServiceManager manager) throws ServiceException
+  {
+    try
+    {
+      deli = (Deli)manager.lookup(Deli.ROLE);
+    } 
+    catch(ServiceException ce)
+    {
+      logger.log(Level.ERROR, "Cannot get ref to Deli", ce);
+      ce.printStackTrace();
+    }
+  }
+</pre>
+
+<p>Some example code that shows how to extract WmlDeckSize from a 
+DELI profile</p>
+
+<pre class="code">
+try
+{
+ Profile theProfile = deli.getProfile(request);
+ if(theProfile != null)
+ {
+   ProfileAttribute attrib = theProfile.getAttribute("WmlDeckSize");
+   if(attrib != null)
+   {
+      Vector temp = (Vector)attrib.get();
+      if(temp != null)
+      {
+          deckSizeString = temp.get(0).toString();
+          System.out.println("Determined WmlDeckSize from DELI: " + deckSizeString);
+      }
+   }
+ }
+ if(deckSizeString == null)
+ {
+    deckSizeString = "1100";
+    System.out.println("Using fallback WmlDeckSize of " + deckSizeString);
+ }
+}
+catch(Exception ex)
+{
+    System.out.println(ex.toString());
+    ex.printStackTrace();
+}
+}
+</pre>
+		
+		
+<h1>More information ?</h1>
+			
+<p>For more information on the DELI library please refer to the 
+<a class="external" href="http://www-uk.hpl.hp.com/people/marbut/">DELI web-site</a>.</p>
+		
+	
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/meta.xml
new file mode 100644
index 0000000..b50113b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-deli-index/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/deli.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/content_en.html
new file mode 100644
index 0000000..e14ab63
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/content_en.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>PCL Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="John Morrison" name="DC.Creator">
+<meta content="This document describes the pcl serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+        
+<h1>PCL Serializer</h1>
+            
+<p>The pcl serializer takes fo xml events as input. By using the
+                     FOP project it creates pcl out of the sax events.</p>
+                  
+<p>This serializer is optional and requires the fop package
+                     in the lib directory when building cocoon 2. However,
+                     the distribution includes this package already.</p>
+            
+<ul>
+                
+<li>Name : fo2pcl</li>
+                
+<li>Class: org.apache.cocoon.serialization.PCLSerializer</li>
+                
+<li>Cacheable: yes.</li>
+            
+</ul>
+        
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/meta.xml
new file mode 100644
index 0000000..6554d51
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pcl-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/pcl-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/content_en.html
new file mode 100644
index 0000000..0afe9d7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/content_en.html
@@ -0,0 +1,191 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>PDF Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="John Morrison" name="DC.Creator">
+<meta content="This document describes the pdf serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+        
+<h1>PDF Serializer</h1>
+            
+<p>The PDF serializer takes
+                <a class="external" href="http://www.w3.org/TR/xsl">XSL FO</a> SAX events as input.
+                By using the <a class="external" href="http://xml.apache.org/fop/">FOP</a> project
+                it creates PDF out of the SAX events.</p>
+            
+<p>This serializer is optional and requires the FOP package in the lib
+                directory when building Cocoon 2. However, the distribution includes
+                this package already.</p>
+            
+<ul>
+                
+<li>Name : fo2pdf</li>
+                
+<li>Class: org.apache.cocoon.serialization.FOPSerializer</li>
+                
+<li>Cacheable: yes</li>
+            
+</ul>
+        
+        
+<h1>FOP and Embedding Fonts</h1>
+          
+<p>Dynamically generating a PDF file (with embedded fonts) in Cocoon
+            is basically 8 steps:</p>
+          
+<ol>
+            
+<li>Create the font(s) metric file(s).</li>
+            
+<li>Create a custom configuration file for FOP (Cocoons PDF renderer),
+              which tells it what fonts are available and where to find them.</li>
+            
+<li>Create your xml (left as an exercise for the reader ;)</li>
+            
+<li>Create your xslt (again, up to you)</li>
+            
+<li>In the sitemap, tell the fo2pdf serializer where your custom
+              configuration file is located.</li>
+            
+<li>Add a match for your PDF (I'm sure you can do the rest...).</li>
+            
+<li>Start Cocoon.</li>
+            
+<li>Request your PDF.</li>
+          
+</ol>
+          
+<p>Easy yeah? OK. Step-by-step...</p>
+
+          
+<h2>Create the font(s) metric file(s).</h2>
+<div class="note">All java calls have nothing else in the classpath or ext directory.
+                Also, instructions which have wrapped should be entered as one single
+                instruction.</div>
+<p>The instruction to generate a font metric file is:</p>
+<p>Windows:</p>
+<pre class="code">
+$ cd %PATH_TO_COCOON%\lib
+$ java -cp optional\fop-0.20.4.jar;core\xercesImpl-2.0.0.jar;core\xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  %PATH_TO_FONT% %PATH_TO_METRICS_DIR%\%FONT_NAME%.xml
+            </pre>
+<p>Unix:</p>
+<pre class="code">
+$ cd $PATH_TO_COCOON/lib
+$ java -cp optional/fop-0.20.4.jar;core/xercesImpl-2.0.0.jar;core/xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  $PATH_TO_FONT  $PATH_TO_METRICS_DIR/$FONT_NAME.xml
+            </pre>
+<h3>Example: Create the Arial metric files.</h3>
+<p>For the sake of the rest of this tutorial, I'm going to be using
+                Windows NT, converting the Arial family of fonts and storing the metrics
+                files in the location <span class="codefrag">D:\fop-fonts</span>.</p>
+<p>My TTF files are located in <span class="codefrag">C:\WINNT\Fonts</span>. If you are
+                running on Linux/Windows 9x/ME/2000/XP please alter as appropriate.</p>
+<div class="note">I normally use Cygwin; a Unix shell environment which runs on Windows.
+                If I slip some Unix into here, please excuse me (although I'd welcome
+                the feedback...).</div>
+<p>Start a command session (as appropriate to your env), then change
+                to Cocoon libs directory.</p>
+<pre class="code">$ cd %PATH_TO_COCOON%\lib</pre>
+<p>Create the metrics directory (D:\fop-fonts)</p>
+<pre class="code">$ mkdir d:\fop-fonts</pre>
+<p>Create the metrics for arial.ttf, arialb.ttf, arialbi.ttf, ariali.ttf</p>
+<pre class="code">
+$ java -cp optional\fop-0.20.4.jar;core\xercesImpl-2.0.0.jar;core\xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  C:\WINNT\Fonts\arial.ttf D:\fop-fonts\arial.ttf.xml
+$ java -cp optional\fop-0.20.4.jar;core\xercesImpl-2.0.0.jar;core\xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  C:\WINNT\Fonts\arialb.ttf  D:\fop-fonts\arialb.ttf.xml
+$ java -cp optional\fop-0.20.4.jar;core\xercesImpl-2.0.0.jar;core\xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  C:\WINNT\Fonts\arialbi.ttf D:\fop-fonts\arialbi.ttf.xml
+$ java -cp optional\fop-0.20.4.jar;core\xercesImpl-2.0.0.jar;core\xml-apis.jar \
+  org.apache.fop.fonts.apps.TTFReader \
+  C:\WINNT\Fonts\ariali.ttf  D:\fop-fonts\ariali.ttf.xml
+</pre>
+<p>If everything went to plan, you should now have the metrics for
+                the Arial fonts in your fop-fonts directory.</p>
+          
+<h2>Create a custom configuration file</h2>
+<p>I normally store this with the metrics file in the fop-fonts
+              directory (called config.xml (ensure there's not a font called
+              config ;)) although I fully qualify all the filenames just incase I
+              move it ;)</p>
+<p>I also find it useful to retain the <span class="codefrag">.ttf</span> as it is also
+              possible to add other types of fonts (if you want to read the FOP
+              docs) and the <span class="codefrag">.ttf</span> tells me where to locate the font.</p>
+<pre class="code">
+&lt;configuration&gt;
+  &lt;fonts&gt;
+    &lt;font metrics-file="D:/fop-fonts/arial.ttf.xml" 
+          kerning="yes" embed-file="C:/WINNT/Fonts/arial.ttf"&gt;
+      &lt;font-triplet name="Arial" style="normal" weight="normal"/&gt;
+      &lt;font-triplet name="ArialMT" style="normal" weight="normal"/&gt;
+    &lt;/font&gt;
+    &lt;font metrics-file="D:/fop-fonts/arialb.ttf.xml" 
+          kerning="yes" embed-file="C:/WINNT/Fonts/arialb.ttf"&gt;
+      &lt;font-triplet name="Arial" style="normal" weight="bold"/&gt;
+      &lt;font-triplet name="ArialMT" style="normal" weight="bold"/&gt;
+    &lt;/font&gt;
+    &lt;font metrics-file="D:/fop-fonts/arialbi.ttf.xml"
+          kerning="yes" embed-file="C:/WINNT/Fonts/arialbi.ttf"&gt;
+      &lt;font-triplet name="Arial" style="italic" weight="bold"/&gt;
+      &lt;font-triplet name="ArialMT" style="italic" weight="bold"/&gt;
+    &lt;/font&gt;
+    &lt;font metrics-file="D:/fop-fonts/ariali.ttf.xml"
+          kerning="yes" embed-file="C:/WINNT/Fonts/ariali.ttf"&gt;
+      &lt;font-triplet name="Arial" style="italic" weight="normal"/&gt;
+      &lt;font-triplet name="ArialMT" style="italic" weight="normal"/&gt;
+    &lt;/font&gt;
+  &lt;/fonts&gt;
+&lt;/configuration&gt;
+</pre>
+<p>There are other things you can add to this file, look at the FOP
+              documentation for further information.</p>
+<p>If you are wondering why each font has been added twice, it has to do
+              with the font lookup. If the font is specified as 'Arial' and the
+              weight is 'bold' then FOP searches for a matching
+              <span class="codefrag">&lt;font-triplet/&gt;</span>, then uses the parent
+              <span class="codefrag">&lt;font/&gt;</span> tag to get the actual font information.
+              If the font is specified as 'ArialMT' (it's proper name) it will still
+              work. Think of it as an alias capability.</p>
+          
+<h2>Sitemap and fo2pdf serializer.</h2>
+<p>All that remains is to tell the serializer, where your config file is
+              located. Find the line in your sitemap which looks like:</p>
+<pre class="code">
+&lt;map:serializer name="fo2pdf"
+                src="org.apache.cocoon.serialization.FOPSerializer"
+                mime-type="application/pdf"/&gt;
+</pre>
+<p>and replace it with:</p>
+<pre class="code">
+&lt;map:serializer name="fo2pdf"
+                src="org.apache.cocoon.serialization.FOPSerializer"
+                mime-type="application/pdf"&gt;
+  &lt;user-config&gt;D:/fop-fonts/config.xml&lt;/user-config&gt;
+&lt;/map:serializer&gt;
+</pre>
+<p>You can use absolute paths like above or relative ones. The relative
+              paths will be resolved to the sitemap's directory. Furthermore it's possible
+              to use Cocoon protocols like <span class="codefrag">cocoon://</span> or
+              <span class="codefrag">context://</span>.</p>
+<div class="note">In an older version of Cocoon (2.0.3 and earlier) the config file
+              location was specified by using an attribute 'src' on
+              &lt;user-config/&gt;. If you still have this in your sitemap, it's
+              recommended to change it to the above provided configuration.</div>
+          
+<p>And that's it. Oh, one final thing to remember: the cache isn't aware
+            of your config file; <strong>always</strong> delete your cache-dir
+            after modifying your config file.</p>
+        
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/meta.xml
new file mode 100644
index 0000000..302f7b4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-pdf-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/pdf-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/content_en.html
new file mode 100644
index 0000000..ac37646
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/content_en.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>PS Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="John Morrison" name="DC.Creator">
+<meta content="This document describes the ps serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+        
+<h1>PS Serializer</h1>
+            
+<p>The ps serializer takes fo xml events as input. By using the
+                     FOP project it creates ps out of the sax events.</p>
+                  
+<p>This serializer is optional and requires the fop package
+                     in the lib directory when building cocoon 2. However,
+                     the distribution includes this package already.</p>
+            
+<ul>
+                
+<li>Name : fo2ps</li>
+                
+<li>Class: org.apache.cocoon.serialization.PSSerializer</li>
+                
+<li>Cacheable: yes.</li>
+            
+</ul>
+        
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/meta.xml
new file mode 100644
index 0000000..89a1d19
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-fop-ps-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/ps-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/content_en.html
new file mode 100644
index 0000000..3b002ff
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/content_en.html
@@ -0,0 +1,360 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to Contribute a Patch via Bugzilla</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Overview</h1>
+
+<p>
+Bugzilla is the Internet-based mechanism to facilitate contributions to any
+Apache project. This includes changes to code and documents
+(Patches), and also reports of flaws in the system (Bugs), and suggestions
+for enhancement.
+</p>
+
+<p>
+In this How-to we will concentrate on the Patch tracking capabilities of
+Bugzilla. We will explain how to create your Bugzilla account,
+how to enter a patch description, and finally how to attach the actual patch
+file.
+</p>
+
+
+  
+<h1>Intended Audience</h1>
+
+<p>
+This document is meant for first-time users of Bugzilla.
+The web interface can be daunting, so this concise explanation will help
+you to start. After your first patch submission, you can proceed to make more
+substantial contributions.
+</p>
+
+
+<p>
+As our example we use the contribution of a simple documentation patch for
+the Apache Cocoon project. The principles apply to any project.
+</p>
+
+
+  
+<h1>Prerequisites</h1>
+
+<p>
+Bugzilla contributors should:
+</p>
+
+<ul>
+
+<li>Understand what a Patch is and how to make one
+(see <a href="howto-patch.html">How to Prepare a Patch</a>).
+Note that a new complete document is still just a "patch",
+though it does need separate treatment to a normal "diff".
+</li>
+
+<li>Understand that Bugzilla is the Apache Bug Database. Bugzilla does not
+distinguish between a Bug report, a Patch submission, and an Enhancement suggestion. They are all <em>"Bugs"</em> as far as Bugzilla is concerned.
+</li>
+
+</ul>
+
+
+
+	
+<h1>Steps</h1>
+
+<p>
+Here is how to proceed. Go to
+<a class="external" href="http://issues.apache.org/bugzilla/">Bugzilla</a>
+in another browser window.
+</p>
+
+	
+<h2>1. Create your Bugzilla Account</h2>
+<p>
+Follow the link the home page to "Open a new Bugzilla account".
+Do not worry, you will not be sent spam email nor bombarded with advertisements
+by setting up this account. It is purely a workgroup tool.
+</p>
+<p>
+Note that you can conduct queries in Bugzilla and review submissions without
+having an account. However, to make a contribution you must have an account.
+This ensures legitimacy. It also enables the system to send you
+email automatically when your patch is applied by a Cocoon committer.
+</p>
+
+	
+<h2>2. Enter a new bug report</h2>
+<p>
+Follow the "Enter a new bug report" link from the Bugzilla home page. First,
+you will be asked to select the relevant project ... choose Cocoon 2 of course.
+Next, you will be asked to provide your account details. Following that, you
+will be presented an input form for the various details ...
+</p>
+
+	
+<h2>3. Specify Version</h2>
+<p>
+This is the version of Cocoon that you prepared your patch against. Choose
+<span class="codefrag">Current CVS</span> if you have an up-to-date local working copy
+of HEAD branch or a very recent nightly build. Otherwise choose the relevant
+release version. This is a very important step, as you will confuse the
+committer if your changes do not match the repository. If you are unsure, then
+please say so in the description at step 12.
+</p>
+
+	
+<h2>4. Specify Component</h2>
+<p>
+Follow the "Component" link for description of the available
+components. If you do not know which component is relevant, then just use
+<span class="codefrag">core</span>.
+</p>
+
+	
+<h2>5. Specify Platform</h2>
+<p>
+This is really meant for bug reporting. Perhaps it could be relevant for a
+patch. You would usually specify the <span class="codefrag">All</span> option.
+</p>
+
+	
+<h2>6. Specify Operating System (OS)</h2>
+<p>
+Really meant for bug reporting. Perhaps it could be relevant for a patch.
+You would usually specify the <span class="codefrag">All</span> option.
+</p>
+
+	
+<h2>7. Specify Severity</h2>
+<p>
+The impact that would arise if your patch is not applied. For a documentation
+patch, the severity would usually be the default <span class="codefrag">Normal</span>.
+However, if it addressed some serious lack or fixed a misguided configuration
+statement, then the impact could be <span class="codefrag">major</span>.
+</p>
+<p>
+(The <span class="codefrag">enhancement</span> option would not be used for a patch, as it is
+intended for suggesting something that should be done. Use this option wisely.
+It would be better to discuss it on the mailing list first.)
+</p>
+
+	
+<h2>8. Specify Initial State</h2>
+<p>
+Use the <span class="codefrag">New</span> option.
+</p>
+
+	
+<h2>9. Specify Assigned To</h2>
+<p>
+Leave it blank. Your patch will be automatically assigned to the
+<span class="codefrag">cocoon-dev</span> mailing list. When a committer takes on your patch,
+that committer will assign the bug to their own email address. This pevents
+duplication of effort by other committers.
+</p>
+<p>
+The Cc field can be used if you need the bug reports, and any follow-up, to be
+copied to some other person. Remember that your report will be sent
+automatically to the <span class="codefrag">cocoon-dev</span> mailing list, so you do not need
+to Cc anyone there.
+</p>
+
+	
+<h2>10. Specify URL</h2>
+<p>
+If the patch refers to a particular document, then provide the website URL.
+If it refers to an issue with one of the local Cocoon Samples, then provide
+the localhost URL.
+</p>
+
+	
+<h2>11. Carefully choose the Summary</h2>
+<p>
+The summary will become the all-important title of the bug. Use it wisely. You want
+to draw attention to your patch. Just as with posting email to the listervers,
+choosing a poor title may cause your posting to be easily overlooked.
+Use up all the characters available ... about 60 maximum.
+</p>
+<p>
+Start the Summary with the <span class="codefrag">[PATCH]</span> tag. This will ensure that it
+is included in the Cocoon automated patch queue summary posted to the mailing
+lists. The patch queue summary reminds people what patches are pending. If you
+omit this tag, then your patch may easily be overlooked.
+</p>
+
+	
+<h2>12. Description</h2>
+<p>
+Provide a brief explanation of what your patch does. Supply any instructions
+to help the committer apply your patch efficiently. Note any issues that may
+remain. It may help to list each file that you are submitting and briefly
+describe what it is. A committer will need to provide a descriptive log message
+when committing your work. Providing a clear description here will help them.
+</p>
+<p>
+Consider writing the Description and Summary text before you start entering
+your patch report. You could save it in a local text file beforehand and
+then copy-and-paste it when the time comes.
+</p>
+<p>
+If this were a bug report, then it would need extensive description.
+</p>
+
+	
+<h2>13. Send the patch report</h2>
+<p>
+Review your options, then press the <strong>Commit</strong> button. This will
+add an entry to the bug database and email a report to the 
+<span class="codefrag">cocoon-dev</span> mailing list and a copy to you. Your submission will be
+assigned a unique Bug Number which you can use to review its progress.
+</p>
+<p>
+The next steps will show you how to attach your patch to the report that you
+have just created ...
+</p>
+
+	
+<h2>14. Create an attachment of the actual patch</h2>
+<p>
+You will be presented with a status screen saying that your bug report
+was accepted and that email was sent to <span class="codefrag">cocoon-dev</span> mailing list.
+</p>
+<p>
+Now you have a choice ... proceed to review your bug report by selecting the
+link "Back to Bug #XXXXX". If you forgot to mention something,
+then you can add more comments. From that screen, follow the link
+"Create a new attachment".
+Otherwise follow the link from this status screen to "Attach a file to
+this bug".
+</p>
+
+	
+<h2>15. Specify the file to be uploaded</h2>
+<p>
+Provide the local pathname to your patchfile, e.g.
+<span class="codefrag">/home/me/work/cocoon/patch/howto-bugzilla.tar.gz</span>
+
+</p>
+
+	
+<h2>16. Describe the attachment</h2>
+<p>
+Provide a concise one line description, e.g.
+<span class="codefrag">Gzipped TAR archive with new docs and diffs</span>
+
+</p>
+
+	
+<h2>17. Specify the contentType of the attachment</h2>
+<p>
+If it is a Gzipped TAR archive (*.tar.gz) or a .zip archive, then select
+"<span class="codefrag">Binary file (application/octet-stream)</span>".
+If it is just a single xml document, then select
+"<span class="codefrag">Plain text (text/plain)</span>".
+If the patch is just a single diff file, then select
+"<span class="codefrag">Patch file (text/plain, diffs)</span>".
+</p>
+
+	
+<h2>18. Submit the attachment</h2>
+<p>
+When you are ready, press the <strong>Submit</strong> button. As for Step 13,
+you will be presented with a status screen saying that your attachment
+was accepted and that email was sent to <span class="codefrag">cocoon-dev</span> mailing list.
+</p>
+
+	
+<h2>19. Be patient</h2>
+<p>
+Now your patch will wait inside Bugzilla until one of the Cocoon committers
+assigns the patch to their own email address and starts to process it to apply
+it to the master CVS repository. As the registered owner of the Bug, you will
+be sent an automatic email at each of these stages.
+</p>
+
+	
+<h2>20. Add more description or attachments if necessary</h2>
+<p>
+Until the patch is applied by the committer and the Bug report is closed, you
+can still add more to your bug report. However, only do this when
+absolutely necessary because the patch should not be
+changing while the committer is trying to commit it. If you just want to make
+further changes, then it would be better to wait until your patch is
+applied. Then you can make a new patch. Remember that the committer has full
+veto and may decide to make some slight modifications to your patch. So it
+is far better to wait.
+</p>
+
+	
+<h2>21. Adding subsequent patches to the same document or program</h2>
+<p>
+If you want to make more patches to the same file, then please open a new Bug
+rather than re-open the old one. After all, once the original patch is
+applied by the committer, its corresponding Bug report is closed.
+</p>
+
+	
+
+  
+<h1>Real World Extension</h1>
+
+<p>Contributing patches, in the form of documentation or code, is a vital way to give back to the Cocoon community. For example, you might consider contributing a timely patch in the form of a new FAQ, how-to, or tutorial. Or, you may also consider submitting a patch which updates Cocoon's existing user and developer guides. </p>
+	
+
+  
+<h1>Tips</h1>
+
+  
+<h2>Setting user preferences</h2>
+<p>
+You can configure certain preferences, though the Bugzilla defaults work just
+fine.
+</p>
+
+  
+<h2>Review the bugzilla documentation</h2>
+<p>
+There are various explanations of terminology and procedures ... follow the
+links should you need to know more.
+</p>
+
+  
+<h2>Search Bugzilla</h2>
+<p>
+Bugzilla has a very powerful search interface. Now that you have a login
+account, Bugzilla can remember customized queries which you can run with a
+single click.
+</p>
+
+	
+
+  
+<h1>References</h1>
+	
+<ul>
+
+<li>
+Bugzilla is at 
+<a class="external" href="http://issues.apache.org/bugzilla/">http://issues.apache.org/bugzilla/</a>
+
+</li>
+
+<li>
+Helpful Bug Writing Guidelines are available directly from the
+Bug entry interface.
+</li>
+	
+</ul>
+	
+	
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/meta.xml
new file mode 100644
index 0000000..7dacc66
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-bugzilla/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-bugzilla.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/content_en.html
new file mode 100644
index 0000000..3190358
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/content_en.html
@@ -0,0 +1,324 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to Prepare a Patch</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Overview</h1>
+
+
+<p>
+A "Patch" is the set of differences between two versions of the
+same file. Patches are used to send someone the exact changes that you have
+made to your version of a program or a document. They can then apply that
+patch to their version to merge the changes and bring their version up-to-date
+with your version.
+</p>
+
+
+<p>
+As our example we use the contribution of a simple documentation patch for
+the Apache Cocoon project. The principles apply to any project and to any
+type of file, e.g. <span class="codefrag">*.xml, *.java, *.txt</span>
+
+</p>
+
+
+  
+<h1>Intended Audience</h1>
+
+<p>
+Anyone who wants to contribute to a project. This document addresses the
+basics, so as to get new people started.
+</p>
+
+
+<p>
+Our example describes the use of command-line tools for a UNIX system.
+Other tools can be used, as long as they produce a "unified diff"
+</p>
+
+
+  
+<h1>Prerequisites</h1>
+
+<p>
+Contributers should have:
+</p>
+
+<ul>
+
+<li>The source code of the documents as a local working copy of the CVS
+repository. If you are working with the current CVS HEAD then you will
+have already done a <span class="codefrag">'cvs checkout cocoon-2.1'</span>
+(see <a class="external" href="http://cocoon.apache.org/community/contrib.html#cvshowto">CVS Usage Precis</a>).
+However, see below for other ways of obtaining source for diff comparison.
+</li>
+
+<li>The tools with which to prepare a patch. On UNIX the "cvs"
+program has the <span class="codefrag">'cvs diff -u'</span> command.
+</li>
+
+</ul>
+
+
+
+	
+<h1>Steps</h1>
+
+<p>
+Here is how to proceed.
+</p>
+
+	
+<h2>1. Understand what a patch is</h2>
+<p>
+A "Patch" is the set of differences between two versions of the
+same file. A patch comprises one or more "diff" files. These diffs
+are produced by the program of the same name: <span class="codefrag">diff</span>.
+</p>
+<p>
+Here is an example of a single diff for the Cocoon Contribution page,
+where we are suggesting a minor text change. Do not get frightened. These
+are just human-readable instructions to the "patch" program.
+</p>
+<pre class="code">
+Index: contrib.xml
+===================================================================
+RCS file: /home/cvspublic/cocoon-2.1/src/documentation/xdocs/contrib.xml,v
+retrieving revision 1.7
+diff -u -r1.7 contrib.xml
+--- contrib.xml 30 Apr 2002 07:44:52 -0000      1.7
++++ contrib.xml 26 May 2002 04:08:23 -0000
+@@ -208,7 +208,7 @@
+    to create a patch. (The commands are for Linux.)
+   &lt;/p&gt;
+
+- &lt;s2 title="How to Establish your Local Repository"&gt;
++ &lt;s2 title="How to Establish your Local Working Copy"&gt;
+
+   &lt;p&gt;
+    This will checkout the current copy of the master cvs repository and
+</pre>
+<p>
+That is a "unified diff" ... there a some lines of context on each
+side of the changes. This patch is basically saying "Change the text
+on line 208".
+</p>
+<ul>
+ 
+<li>lines to be deleted are preceded with <strong>-</strong>
+</li>
+ 
+<li>lines to be added are preceded with <strong>+</strong>
+</li>
+ 
+<li>contextual lines with no leader remain the same</li>
+
+</ul>
+
+	
+<h2>2. Modify your document and ensure consistency</h2>
+<p>
+Let us now go though the process of preparing that patch.
+Go ahead and edit your local copy of the document at
+<span class="codefrag">$COCOON_HOME/src/documentation/xdocs/contrib.xml</span>
+
+</p>
+<p>
+Ensure that it is valid XML using your favourite XML editor or an external
+validating parser. Please do not leave it up to the poor committer to fix
+broken XML.
+</p>
+<p>
+Run <span class="codefrag">build docs</span> to be sure that links are not broken and that
+the new document is presented as you intend it to be.
+</p>
+
+	
+<h2>3. Get ready</h2>
+<p>
+If you are using the HEAD of CVS then ensure that your working copy is
+up-to-date. Of course, if you are using a previous public release version of
+Cocoon, then it is already up-to-date.
+</p>
+
+	
+<h2>4. Generate the differences</h2>
+<p>
+Prepare the diff file. CVS will contact the remote repository, ensure that your
+working copy is up-to-date, then compare your local copy with the master repository.
+</p>
+<pre class="code">
+cd src/documentation/xdocs
+cvs diff -u contrib.xml &gt; $WORK/cocoon/patch/contrib.xml.diff
+</pre>
+
+	
+<h2>5. Pack it up</h2>
+<p>
+With a patch that involves multiple separate diffs and/or new whole xml files,
+then please pack them into a compressed archive,
+e.g. <span class="codefrag">my-patch.tar.gz</span> or <span class="codefrag">my-patch.zip</span>
+
+</p>
+<p>
+Also, if it helps to make your contribution clearer, then you might replicate
+the directory structure. Only bother with this for a complex patch.
+</p>
+<pre class="code">
++---$WORK/cocoon/patch
+|   +---howto
+|   |   +---book.xml.diff ........... differences to book.xml to link the 2 docs
+|   |   +---howto-new-topic-a.xml ... a complete new document
+|   |   +---howto-new-topic-b.xml ... a complete new document
+|   +---link
+|   |   +---livesites.xml.diff
+|   |   +---books.xml.diff
+|   |   
+</pre>
+
+	
+<h2>6. Describe the patch</h2>
+<p>
+Prepare a brief explanation of what your patch does. Get this ready in a text
+file before you go to Bugzilla. See further hints about this in the
+"Description" section of the How-to Bugzilla.
+</p>
+<p>
+What version of CVS did you patch against? Was it HEAD branch? Was it
+a nightly build? Was it a public release? 
+</p>
+
+	
+<h2>7. Submit via Bugzilla</h2>
+<p>
+To contribute your patch to a specific project, use Bugzilla - The Apache
+Bug Database. The procedure is explained in 
+<a href="howto-bugzilla.html">How to Contribute a Patch via Bugzilla</a>.
+</p>
+
+	
+
+  
+<h1>Real World Extension</h1>
+   
+<h2>Multiple diffs in a single patch</h2>
+<p>
+A patchfile can contain the differences to various individual documents.
+For example, the following command does that ...
+</p>
+<pre class="code">
+cd src/documentation/xdocs
+cvs diff -u contrib.xml userdocs/concepts/sitemap.xml &gt; my-patch.diff
+</pre>
+<p>
+However, be careful not to go overboard with this technique. Often it is
+better to produce individual diffs and then pack them all into one .zip
+archive. When producing multiple diffs in one patchfile, try to limit it
+to one particular topic, i.e when fixing the same broken external link
+in various pages, then it would be fine to produce a single diff. Consider
+the committer - they will find it hard to apply your patch if it also
+attempts to fix other things.
+</p>
+
+   
+<h2>Other ways of obtaining source for diff comparison</h2>
+<p>
+Ideally you will prepare your patches against a CVS repository. There are
+other ways to do this. They do create more work for the committers, however
+it may be the only way that you can do it. We would certainly rather receive
+your patch however it comes.
+</p>
+<p>
+You could get the source document via the web interface to CVS. Here are
+the steps ...
+</p>
+<ul>
+
+<li>get the <a class="external" href="http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/documentation/xdocs/contrib.xml?rev=HEAD&content-type=text/xml">relevant XML file via ViewCVS</a>
+</li>
+
+<li>save the file to your local disk: <span class="codefrag">./contrib.xml.orig</span>
+</li>
+
+<li>create a copy of the file: <span class="codefrag">./contrib.xml</span>
+</li>
+
+<li>make your modifications and validate the XML</li>
+
+<li>use the "diff" command (i.e. not 'cvs diff') as follows
+<br>
+<span class="codefrag">diff -u contrib.xml.orig contrib.xml &gt; patch/contrib.xml.diff</span>
+</li>
+
+<li>proceed as for Step 5.</li>
+
+</ul>
+<p>
+There is another method if all else fails. You could save the public HTML page
+that was generated by Cocoon (currently static) and then prepare your diffs
+against the HTML source. This is obviously much harder for the committer, and
+should only ever be used for minor text edits. Here are the steps ...
+</p>
+<ul>
+
+<li>save the relevant web page 
+(<a class="external" href="http://cocoon.apache.org/community/contrib.html">contrib.html</a>)
+to your local disk: <span class="codefrag">./contrib.html.orig</span>
+</li>
+
+<li>create a copy of the file: <span class="codefrag">./contrib.html</span>
+</li>
+
+<li>make your modifications and  view the page with your browser</li>
+
+<li>use the "diff" command (i.e. not 'cvs diff') as follows
+<br>
+<span class="codefrag">diff -u contrib.html.orig contrib.html &gt; patch/contrib.html.diff</span>
+</li>
+
+<li>proceed as for Step 5.</li>
+
+</ul>
+	
+
+  
+<h1>Tips</h1>
+
+<ul>
+ 
+<li>Please review your diffs before you submit your patch to Bugzilla</li>
+
+</ul>
+
+	
+
+  
+<h1>References</h1>
+	
+<ul>
+
+<li>
+The UNIX manual pages '<span class="codefrag">man diff</span>' and '<span class="codefrag">man patch</span>'.
+</li>
+
+<li>
+CVS usage information is at
+<a class="external" href="http://www.cvshome.org/">www.cvshome.org</a> and your local
+'<span class="codefrag">info cvs</span>' pages or '<span class="codefrag">man cvs</span>' pages or user
+documentation. This includes guidance about using <span class="codefrag">cvs diff -u</span>
+
+</li>
+	
+</ul>
+
+	
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/meta.xml
new file mode 100644
index 0000000..892acd3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-howto-patch/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-patch.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/content_en.html
new file mode 100644
index 0000000..9e48f1d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/content_en.html
@@ -0,0 +1,226 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apache License</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stefano Mazzocchi" name="DC.Creator">
+</head>
+<body>
+
+<h1>Apache License</h1>
+
+<pre class="code">
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+</pre>
+ 
+ 
+<p>There are also licenses for additional products that are distributed with
+  Apache Cocoon. Please find those documents in the <span class="codefrag">legal/</span>
+  directory of your distribution.
+ </p>
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/meta.xml
new file mode 100644
index 0000000..fe0af6c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-global-license/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>license.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/content_en.html
new file mode 100644
index 0000000..bc382e7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/content_en.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>JSP Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the jsp generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>JSP Generator</h1>
+      
+<p>The JspGenerator selects a JSPEngine component. The JSPEngine component
+                          launches a JSP servlet engine of your servlet container, 
+                          feeds the HttpRequest into the 
+                          JSP servlet engine, and pipes the jsp response as SAX events into Cocoon.
+                          The JSP page is specified by the HttpRequest.
+                        </p>
+                        
+<p>
+                          This way you can continue to use your JSP pages. 
+                          Your migration from JSP to XSP may be done step by step. 
+                          You may specify your JSP pages either as JSP scriptlets or as JSP-XML.
+                          But keep in mind that your JSP output should be valid XML.
+                        </p>
+      
+<ul>
+        
+<li>Name : jsp</li>
+        
+<li>Class: org.apache.cocoon.generation.JspGenerator</li>
+        
+<li>Cacheable: no</li>
+      
+</ul>
+
+<pre class="code">
+&lt;map:generate type="jsp"/&gt;
+</pre>
+    
+                
+<h1>JSPEngine</h1>
+                  
+<p>As JSP servlet engines are implemented differently, you may have to
+                    select the appropriate JSPEngine component. 
+                    The default is a JSPEngine working with Tomcat's JSP servlet engine Jasper.
+                    You may override the cocoon.roles by your own my.roles, as described 
+                    in the <a href="../../faq/index.html">FAQs</a>.
+                  </p>
+                  
+<p>The JSPEngine component of Tomcat's JSPEngine is implemented in JSPEngineImpl. 
+                    If you want to use another JSPEngine component, you may specify it in a my.roles file.
+                    The following sample specify in file WEB-INF/my.roles a JSPEngine workging with WebLogicServer:
+                  </p>
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;role-list&gt;
+  &lt;role name="org.apache.cocoon.components.jsp.JSPEngine"
+    shorthand="jsp-engine"
+    default-class="org.apache.cocoon.components.jsp.JSPEngineImplWLS"/&gt;
+&lt;/role-list&gt;
+</pre>
+                  
+<p>Defining the file my.roles this way you must ensure that your 
+                    cocoon.xconf refernces my.roles, like that:
+                  </p>
+
+<pre class="code">
+...
+&lt;cocoon version="2.0" user-roles="WEB-INF/my.roles"&gt;
+...
+</pre>
+
+                  
+<p>Currently there are tree JSPEngine components available:
+                  </p>
+                  
+<table>
+                    
+<tr>
+<th colspan="1" rowspan="1">JSPEngine</th><th colspan="1" rowspan="1">ServletEngine</th>
+</tr>
+                    
+<tr>
+<td colspan="1" rowspan="1">JSPEngineImpl</td><td colspan="1" rowspan="1">Tomcat, generic jsp servlet class</td>
+</tr>
+                    
+<tr>
+<td colspan="1" rowspan="1">JSPEngineImplWLS</td><td colspan="1" rowspan="1">WebLogic 5.1, 6.0(?)</td>
+</tr>
+                    
+<tr>
+<td colspan="1" rowspan="1">JSPEngineImplNamedDispactcherInclude</td><td colspan="1" rowspan="1">Generic JSP Servlet</td>
+</tr>
+                  
+</table>
+                  
+<p>The next sections describe the settings of the JSPEngine components.
+                  </p>
+                  
+<h2>JSPEngineImpl</h2>
+<p>This JSPEngine is the default engine selected in cocoon.roles. 
+                      By default it uses Tomcats' JASPER  JSP servlet engine.
+                    </p>
+<p>Running under a different JSP servlet engine, you can try to change the settings
+                      in cocoon.xconf, by modifying parameter name servlet-class to your needs.
+                    </p>
+<pre class="code">
+&lt;jsp-engine&gt;
+  &lt;parameter name="servlet-class"
+             value="my.servlet.MyJspServletOfMyServletEngine"/&gt;
+&lt;/jsp-engine&gt;
+</pre>
+<p>JSPEngineImpl instances directly the JSP servlet engine class, and services
+                      HttpRequest to this instance.
+                    </p>
+<p>JSPEngineImplNamedDispatcherInclude delegates the selection of a JSP servlet engine
+                      instance to the servlet engine. It selects by servlet-name, and not by servlet-class.
+                      This is the key differences of these two implementations.
+                    </p>
+                  
+<h2>JSPEngineImplWLS</h2>
+<p>This JSPEngine is implemented especially for WebLogic 5.1. WebLogic 6.0, and WebLogic 6.1
+                      may work, too. JSPEngineImplWLS finds the named request dispatch for jsp, the jsp response
+                      is piped into Cocoon.
+                    </p>
+<p>The name of the JSP servlet is by default set to '*.jsp'. This is the default servlet name
+                      of the JSP servlet engine under WLS. You may adopt the parameter servlet-name to your needs.
+                    </p>
+<p>If you want to specify a different JSP servlet name, you can change the settings
+                      in cocoon.xconf, by modifying the parameter servlet-name.
+                    </p>
+<pre class="code">
+&lt;jsp-engine&gt;
+  &lt;parameter name="servlet-name"
+             value="MyNameOfMyJspServletOfMyServletEngine"/&gt;
+&lt;/jsp-engine&gt;
+</pre>
+                  
+<h2>JSPEngineImplNamedDispatcherInclude</h2>
+<p>This JSPEngine is implemented like JSPEnginImplWLS without using any WebLogic classes.
+                      You may try to use this JSPEngine if JSPEngineImpl does not meet your requirements.
+                    </p>
+<p>The name of the JSP servlet is by default set to '*.jsp'. This is the default servlet name
+                      of the jsp servlet engine under WLS. You may adopt the parameter servlet-name to your needs.
+                    </p>
+<p>If you want to specify a different JSP servlet name, you can change the settings
+                      in cocoon.xconf, by modifying the parameter servlet-name.
+                    </p>
+<pre class="code">
+&lt;jsp-engine&gt;
+  &lt;parameter name="servlet-name"
+             value="MyNameOfMyJspServletOfMyServletEngine"/&gt;
+&lt;/jsp-engine&gt;
+</pre>
+                
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/meta.xml
new file mode 100644
index 0000000..a4e1312
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/jsp-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/content_en.html
new file mode 100644
index 0000000..ff44f83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/content_en.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>JSP Reader in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the JSP Reader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>JSPReader</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">jsp</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">JSPReader</span> component is used to serve JSP page output data
+            in a sitemap pipeline.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Jsp</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.JSPReader</td>
+        
+</tr>
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">no</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">JSPReader</span> forwards requests to a <em>JSP</em> engine, and
+        passing the <em>JSP</em> response immediatly as is.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">JSPReader</span> is useful iff you want to serve the <em>JSP</em>
+        response without any further Cocoon processing steps.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The following sitemap snippet uses the <span class="codefrag">JSPReader</span> to feed
+          <span class="codefrag">htm</span> requests by <em>JSP</em> files.
+        </p>
+<pre class="code">
+...
+&lt;map:match pattern="*.htm"&gt;
+  &lt;map:read type="jsp" src="{1}.jsp" mime-type="text/html" /&gt;
+&lt;/map:match&gt;
+...
+        </pre>
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:readers...
+  &lt;map:reader name="jsp" 
+    src="org.apache.cocoon.reading.JSPReader"
+    logger="sitemap.reader.jsp" 
+  /&gt;
+...
+        </pre>
+      
+<h2>Configuration</h2>
+<p>
+          The <span class="codefrag">JSP Reader</span> has no configuration options.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          The <span class="codefrag">JSP Reader</span> has no setup options.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+        
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">JSP Reader</span> depends on the accessibilty of a
+        <span class="codefrag">JSP</span> engine from within the Cocoon servlet.
+        A <em>JSP</em> must be properly configured for using the 
+        <span class="codefrag">JSP Reader</span>.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-25-02: created initial version by Bernhard Huber
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        Feeding <em>JSP</em> and passing the content into further Cocoon processing
+        the <em>JSPGenerator</em> is appropriate for this task.
+      </p>
+      
+<p>
+        Moreover setting up a preprocessing <em>Servlet  Filter</em> would be the most
+        general solution to feeding <em>JSP</em> content.
+      </p>
+      <!-- Links to related components pages -->
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/meta.xml
new file mode 100644
index 0000000..9b00251
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-jsp-jsp-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/jsp-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/content_en.html
new file mode 100644
index 0000000..4824e64
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/content_en.html
@@ -0,0 +1,365 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Search Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the search generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Search Generator</h1>
+      
+<p>
+        The search generator creates xml content resulting from an indexing search.
+        Speaking simply, SearchGenerator takes a query-string passes it to search engine.
+        The hits delivered by the search engine are wrapped into xml output and fed into 
+        the pipeline.
+      </p>
+      
+<p>
+        The xml content generated by SearchGenerator is described later.
+      </p>
+      
+<ul>
+        
+<li>Name : search</li>
+        
+<li>Class: org.apache.cocoon.generation.SearchGenerator</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<pre class="code">
+&lt;map:generate type="search"/&gt;
+</pre>
+
+<p>or</p>
+
+<pre class="code">
+&lt;map:generate type="search"&gt;
+  &lt;query&gt;your query string&lt;/query&gt;
+&lt;/map:generate&gt;
+</pre>
+    
+    
+<h1>Configuration</h1>
+      
+<p>
+        Configuring of the SearchGenerator involves mainly setting up 
+        configuration needed by avalon component used for searching.
+        As today SearchGenerator uses the Avalon component
+        <span class="codefrag">org.apache.cocoon.components.search.LuceneCocoonSearcher</span>
+        for searching, the configuration is tailored for this component.
+      </p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Parameter Name</th><th colspan="1" rowspan="1">Default</th><th colspan="1" rowspan="1">Description</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">analyzer</td><td colspan="1" rowspan="1">org.apache.lucene.analysis.standard.StandardAnalyzer</td>
+          <td colspan="1" rowspan="1">
+            This parameter defines the analyzer to use for searching. Take care to use a
+            compatible analyzer as used when generating the index.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">index</td><td colspan="1" rowspan="1">index</td>
+          <td colspan="1" rowspan="1">
+            This parameter defines a filesystem directory, expecting to be the 
+            location of the lucene filesystem index directory.
+            Relative directory names are resolved relative to Cocoon's 
+            working directory.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">query-string</td><td colspan="1" rowspan="1">queryString</td>
+          <td colspan="1" rowspan="1">
+            This parameter specifies the name of the query parameter name used
+            for passing the query-string, eg. 
+            <span class="codefrag">http://foo/bar?queryString=cocoon</span>, for generating
+            xml content for query "cocoon".
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">page-length</td><td colspan="1" rowspan="1">PageLength</td>
+          <td colspan="1" rowspan="1">
+            This parameter specifies the name of the query parameter name used
+            for passing the page length. The page length specifies the number of
+            hits generated into the xml content. A negative page length value
+            will generate all hits into the xml content.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">start-index</td><td colspan="1" rowspan="1">StartIndex</td>
+          <td colspan="1" rowspan="1">
+            This parameter specifies the name of the query parameter name used
+            for passing the start index of the hits result. This query parameter
+            has higher precedence than query parameter defined by
+            start-next-index, and start-previous-index.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">start-next-index</td><td colspan="1" rowspan="1">StartNextIndex</td>
+          <td colspan="1" rowspan="1">
+            This parameter specifies the name of the query parameter name used
+            for passing the start index of the hits result. 
+            Use this if you have a form defining both next and previous
+            navigation control.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">start-previous-index</td><td colspan="1" rowspan="1">StartPreviousIndex</td>
+          <td colspan="1" rowspan="1">
+            This parameter specifies the name of the query parameter name used
+            for passing the start index of the hits result.
+            Use this if you have a form defining both next and previous 
+            navigation control.
+          </td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Query Parameters</h1>
+      
+<p>
+        This generator accepts following query parameters, the table below assumes
+        the default settings of the setup parameters.
+      </p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Query Parameter Name</th><th colspan="1" rowspan="1">Default</th><th colspan="1" rowspan="1">Description</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">queryString</td><td colspan="1" rowspan="1">No default</td>
+          <td colspan="1" rowspan="1">
+            Specifies the query string, parsable by the search engine.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">pageLength</td><td colspan="1" rowspan="1">10</td>
+          <td colspan="1" rowspan="1">
+            This value specifies the number of hits displayed per page.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">startIndex</td><td colspan="1" rowspan="1">0</td>
+          <td colspan="1" rowspan="1">
+            Start displaying hits starting from this index (counting starts 
+            at 0).
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">startNextIndex</td><td colspan="1" rowspan="1">0</td>
+          <td colspan="1" rowspan="1">
+            Start displaying hits starting from this index (counting start at 0).
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">startPreviousIndex</td><td colspan="1" rowspan="1">0</td>
+          <td colspan="1" rowspan="1">
+            Start displaying hits starting from this index (counting starts 
+            at 0). 
+          </td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Using SearchGenerator</h1>
+      
+<p>
+        Using the SearchGenerator needs some configuration steps regarding
+        <span class="codefrag">cocoon.xconf</span>, and the sitemap mounting a pipeline
+        defining a SearchGenerator generation step. Moreover you will 
+        have to define some XSLT processing for reendering the xml content
+        of the SearchGenerator.
+      </p>
+      
+<p>
+        As SearchGenerator uses some avalon components be sure to configure
+        your <span class="codefrag">cocoon.xconf</span> properly. The avalon
+        component <span class="codefrag">org.apache.cocoon.components.search.LuceneCocoonSearcher</span>
+        is used by the SearchGenerator.
+        Usually this component is specified in 
+        <span class="codefrag">cocoon.roles</span> and the <span class="codefrag">cocoon.xconf</span> file
+        for the default cocoon webapp.
+      </p>
+      
+<p>
+        Inside of a sitemap you have to define the SearchGenerator in the
+        generator componenets section.
+      </p>
+      
+<p>
+        Moreover you have to match a URI to the SearchGenerator processing, the
+        following example matches the URI <span class="codefrag">findIt</span> to the 
+        SearchGenerator processing. The stylesheet <span class="codefrag">search2html.xsl</span>
+        transforms the xml content of SearchGenerator to html:
+      </p>
+
+<pre class="code">
+&lt;map:match pattern="findIt"&gt;
+  &lt;map:generate type="search"/&gt;
+  &lt;map:transform type="log"/&gt;
+  &lt;map:transform src="stylesheets/search2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+    
+    
+<h1>DTD</h1>
+      
+<p>XML generated by SearchGenerator uses namespace 
+      <span class="codefrag">http://apache.org/cocoon/search/1.0</span>.
+      The DTD of XML generated by SearchGenerator:
+      </p>
+
+<pre class="code">
+&lt;!ELEMENT results (hits,navigation)?&gt;
+
+&lt;!ATTLIST results
+   date CDATA #IMPLIED
+   query-string CDATA #IMPLIED
+   start-index CDATA #IMPLIED
+   page-length CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT hits (hit)*&gt;
+&lt;!ATTLIST hits
+   total-count CDATA #IMPLIED
+   count-of-pages CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT hit (#PCDATA)&gt;
+&lt;!ATTLIST hit
+   rank CDATA #REQUIRED
+   score CDATA #IMPLIED
+   uri CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT field (#PCDATA)&gt;
+&lt;!ATTLIST field
+   name CDATA #REQUIRED
+&gt;
+
+&lt;!ELEMENT navigation (navigation-page)*&gt;
+&lt;!ATTLIST navigation
+   total-count CDATA #IMPLIED
+   count-of-pages CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT navigation-page EMPTY&gt;
+&lt;!ATTLIST navigation
+   start-index CDATA #IMPLIED
+&gt;
+</pre>
+    
+    
+<h1>Example</h1>
+      
+<p>The search generator generates following xml content, for the query
+        <span class="codefrag">query-string=cocoon&amp;start-index=0&amp;page-length=10</span>.
+      </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;search:results date="1008437081064" 
+ query-string="cocoon" start-index="0" page-length="10"
+ xmlns:search="http://apache.org/cocoon/search/1.0"
+ xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
+ &lt;search:hits total-count="125" count-of-pages="13"&gt;
+   &lt;search:hit rank="0" score="1.0" 
+     uri="http://localhost:8080/cocoon/documents/hosting.html"/&gt;
+   &lt;search:hit rank="1" score="1.0" 
+     uri="http://localhost:8080/cocoon/documents/hosting.html"/&gt;
+   &lt;search:hit rank="2" score="1.0"
+     uri="http://localhost:8080/cocoon/documents/hosting.html"/&gt;
+   &lt;search:hit rank="3" score="0.93121004"
+     uri="http://localhost:8080/cocoon/documents/userdocs/actions/actions.html"/&gt;
+   &lt;search:hit rank="4" score="0.93121004"
+     uri="http://localhost:8080/cocoon/documents/userdocs/actions/actions.html"/&gt;
+   &lt;search:hit rank="5" score="0.7112235"
+     uri="http://localhost:8080/cocoon/documents/mail-archives.html"/&gt;
+   &lt;search:hit rank="6" score="0.70967746"
+     uri="http://localhost:8080/cocoon/documents/userdocs/
+     serializers/link-serializer.html"/&gt;
+   &lt;search:hit rank="7" score="0.6881721"
+     uri="http://localhost:8080/cocoon/documents/userdocs/
+     serializers/text-serializer.html"/&gt;
+   &lt;search:hit rank="8" score="0.6881721"
+     uri="http://localhost:8080/cocoon/documents/userdocs/
+     serializers/vrml-serializer.html"/&gt;
+   &lt;search:hit rank="9" score="0.6666666" 
+     uri="http://localhost:8080/cocoon/documents/userdocs/
+     serializers/svgpng-serializer.html"/&gt;
+ &lt;/search:hits&gt;
+ &lt;search:navigation total-count="125" count-of-pages="13"
+   has-next="true" has-previous="false" next-index="10" previous-index="0"&gt;
+   &lt;search:navigation-page start-index="0"/&gt;
+   &lt;search:navigation-page start-index="10"/&gt;
+   &lt;search:navigation-page start-index="20"/&gt;
+   &lt;search:navigation-page start-index="30"/&gt;
+   &lt;search:navigation-page start-index="40"/&gt;
+   &lt;search:navigation-page start-index="50"/&gt;
+   &lt;search:navigation-page start-index="60"/&gt;
+   &lt;search:navigation-page start-index="70"/&gt;
+   &lt;search:navigation-page start-index="80"/&gt;
+   &lt;search:navigation-page start-index="90"/&gt;
+   &lt;search:navigation-page start-index="100"/&gt;
+   &lt;search:navigation-page start-index="110"/&gt;
+   &lt;search:navigation-page start-index="120"/&gt;
+ &lt;/search:navigation&gt;
+&lt;/search:results&gt;
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/meta.xml
new file mode 100644
index 0000000..a902913
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-search-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/search-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/content_en.html
new file mode 100644
index 0000000..f35ec43
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/content_en.html
@@ -0,0 +1,393 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XML Searching</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Search resources in Apache Cocoon" name="DC.Subject">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="Jeremy Quinn" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>
+        This document describes indexing, and searching XML documents
+        in Apache Cocoon.
+      </p>
+      
+<p>
+        Indexing is the process of fetching XML documents from an Apache Cocoon
+        instance, and building an index file.
+        Searching is the process of querying the once built index.
+      </p>
+      
+<p>
+        See also Wiki: 
+        <a class="external" href="http://wiki.apache.org/cocoon/LuceneIndexTransformer">LuceneIndexTransformer</a>
+      
+</p>
+    
+ 
+    
+<h1>Decomposition of XMLSearching</h1>
+      
+<p>
+        The indexing process is split up into crawling, fetching URL resource, 
+        and generating the index.
+      </p>
+      
+<p>
+        The searching process is split up into searching, 
+        and feeding search result into the
+        Apache Cocoon pipeline.
+      </p>
+      
+<h2>Crawling</h2>
+<p>
+          The crawling process is specified by  
+        </p>
+<ol>
+          
+<li>Base URL to start crawling from</li>
+          
+<li>Included, and excluded URLs</li>
+          
+<li>Cocoon view to use for requesting links from an XML resource</li>
+        
+</ol>
+<p>
+          Specifying the base URL determines the protocol for fetching XML resources.
+          The  implementation offers to specify <span class="codefrag">http:</span> URLs, 
+          crawling an Apache Cocoon instance deployed in a servlet-engine.
+          Alternatively you may specify an URI, e.g.: <span class="codefrag">/documents/index.html</span>,
+          offering to crawl the local Apache Cocoon instance only, either
+          servlet-deployed, or in commandline-mode.
+        </p>
+      
+<h2>Fetching URL resource</h2>
+<p>
+          This processing step fetches the URL resource from Apache Cocoon.
+        </p>
+<p>
+          Apache Cocoon offers the feature of views.
+          This feature is used to fetch the 'bare' content of an URL.
+        </p>
+<p>
+          The crawling component described above is used by the this processing step
+          to retrieve a link of an XML document. 
+          The link name is augmented by a cocoon view name for fetching the XML resource.
+        </p>
+<p>
+          The Avalon component <span class="codefrag">CocoonCrawler</span> defines the interface
+          of a crawler.
+        </p>
+<p>
+          The Avalon component <span class="codefrag">SimpleCocoonCrawlerImpl</span> is the implementation. 
+          It can be configured to use a specific view, or default to the 'content' view.
+        </p>
+      
+<h2>Generating index</h2>
+<p>
+          A xml resource is fed into a indexing engine.
+          Generating an index specifies which elements of an XML resources
+          should get indexed, how the elements are stored in the index.
+          Moreover the physical file location of the index is specified by
+          this processing step.
+        </p>
+<p>
+          The current implementation splits up an XML resource the following way:
+        </p>
+<ul>
+          
+<li>Use an Lucene Analyzer for splitting up text</li>
+          
+<li>Each XML element is indexed using its name as Lucene field name.</li>
+          
+<li>Each XML attribute is indexed using its element name and the attribute name
+            as field name. An attribute has following field name 
+            <span class="codefrag">{element-name}@{attribute-name}</span>.
+          </li>
+          
+<li>XML elements that match the names you configured in cocoon.xconf are added as stored fields.</li>
+        
+</ul>
+<p>
+          The Avalon component <span class="codefrag">LuceneCocoonIndexer</span> defines the interface
+          of an indexer.
+        </p>
+<p>
+          The Avalon component <span class="codefrag">LuceneXMLIndexer</span> defines an interface
+          for building an lucene index from an XML document. It uses an SAX content handler
+          for parsing an XML document, and generating Lucene fields, the current 
+          index layout is implemented by <span class="codefrag">SimpleLuceneXMLIndexerImpl</span>,
+          and <span class="codefrag">LuceneIndexContentHandler</span>.
+        </p>
+
+      
+<h2>Searching</h2>
+<p>
+          This process uses a search engine for querying the index. 
+          The input of this process is a search query string, the result is the
+          search result of the search engine.
+        </p>
+<p>
+          The Avalon component <span class="codefrag">LuceneCocoonSearcher</span> defines an interface
+          for searching a Lucene index.
+        </p>
+      
+<h2>Feeding Search Results</h2>
+<p>
+          This is the final step for presenting information stored in the index.
+          The result of search engine is feed into the Cocoon processing pipeline.
+        </p>
+<p>
+          A GUI for the searching process may be developed using any
+          java enabled script language, like JSP, or XSP. 
+          Moreover a sitemap generator component <span class="codefrag">SearchGenerator</span>
+          is provided which transforms the search result to XML, and feeds it
+          into the Cocoon processing pipeline.
+        </p>
+    
+    
+    
+<h1>Interdependencies</h1>
+      
+<p>
+        As both Avalon components <span class="codefrag">LuceneXMLIndexer</span>, and 
+        <span class="codefrag">LuceneCocoonSearcher</span> may use the same Lucene index, you must
+        take care of the Lucene index structure in both components.
+      </p>
+      
+<p>
+        The current implementation uses following Lucene index layout
+      </p>
+      
+<ul>
+        
+<li>Lucene field <span class="codefrag">body</span> indexed field of the pure text of an XML document.
+          The <span class="codefrag">body</span> field is the default field name for searching. Thus the
+          query-string <span class="codefrag">foo</span>, and <span class="codefrag">body:foo</span> is equivalent.
+        </li>
+        
+<li>Each XML element generates a Lucene field having the same name as the XML element name.
+          For example searching for occurences of <span class="codefrag">Cocoon</span> inside of an XML abstract
+          element, use query-string <span class="codefrag">abstact:Cocoon</span>.
+        </li>
+        
+<li>Each XML attribute generates a Lucene field having the name
+          <span class="codefrag">{element-name}@{attribute-name}</span>. 
+          For example searching for occurrences of <span class="codefrag">Cocoon</span> inside of an XML title attribute
+          of s1 element, use query-string <span class="codefrag">s1@title:Cocoon</span>.
+        </li>
+        
+<li>
+          The Lucene field <span class="codefrag">url</span> stores the URI of the indexed document. As
+          all fields described above are only indexed information, and no XML document 
+          is stored inside the Lucene index, this field is the only reference to the 
+          XML document resource.
+        </li>
+        
+<li>
+          The Lucene field <span class="codefrag">uid</span> stores an unique id for implementing updating
+          the index. This field is used for checking if the XML resource is newer than
+          the information stored in the Lucene index.
+        </li>
+        
+<li>
+          Further Stored fields can be added, depending on your configuration. 
+          Stored fields are returned in the hits found by the engine.
+        </li>
+      
+</ul>
+    
+      
+    
+<h1>Configuration</h1>
+      
+<p>
+        Configuring the indexing, and searching Avalon components is specified
+        in the <span class="codefrag">cocoon.xconf</span> file.
+      </p>
+      
+<h2>example</h2>
+<p>This would set up the crawler to crawl all of your site, except pages in the 'search' section, also we are telling the crawler to use a non-standard cocoon-view for getting the links in documents, called <span class="codefrag">my-search-links</span>. </p>
+<pre class="code">
+&lt;cocoon-crawler logger="core.search.crawler"&gt;
+  &lt;exclude&gt;.*/search/.*&lt;/exclude&gt;
+  &lt;link-view-query&gt;cocoon-view=my-search-links&lt;/link-view-query&gt;
+&lt;/cocoon-crawler&gt;
+</pre>
+<p>This tells the indexer to use the non-standard 'my-search-content' view to retrieve the content for indexing. Also it tells the indexer that we would like to have any <span class="codefrag">title</span> or <span class="codefrag">subtitle</span> XML elements in the document added to the index as stored fields, so they can be retrieved and displayed to the user with any hits they get.</p>
+<pre class="code">
+&lt;lucene-xml-indexer logger="core.search.lucene"&gt;
+  &lt;store-fields&gt;title, subtitle&lt;/store-fields&gt;
+  &lt;content-view-query&gt;cocoon-view=my-search-content&lt;/content-view-query&gt;
+&lt;/lucene-xml-indexer&gt;
+</pre>
+      
+<p>
+        Setting up the sitemap component SearchGenerator takes place in the
+        <span class="codefrag">sitemap.xmap</span> file.
+      </p>
+      
+<h2>example</h2>
+<p>This would generate a document from a search, getting the query and other information from request parameters.</p>
+<pre class="code">
+&lt;map:generate type="search"/&gt;
+</pre>
+<p>This would generate a document from a search, getting the query from the sitemap parameter '1' and other information from request parameters.</p>
+<pre class="code">
+&lt;map:generate type="search"&gt;
+  &lt;map:parameter name="query" value="{1}"/&gt;
+&lt;/map:generate&gt;  
+</pre>
+    
+    
+    
+<h1>Implementation notes</h1>
+      
+<p>
+        The package <span class="codefrag">org.apache.cocoon.components.search</span> holds
+        all searching relevant components.
+        The current implementation uses
+        <a class="external" href="http://jakarta.apache.org/lucene">Jakarta Lucene</a>
+        as its indexing, and searching engine.
+      </p>
+      
+<p>
+        SearchGenerator is sitemap generator and is available in
+        the package <span class="codefrag">org.apache.cocoon.generation</span>.
+      </p>
+      
+<p>
+        The package <span class="codefrag">org.apache.cocoon.components.crawler</span> holds
+        all crawling relevant sources.
+      </p>
+    
+    
+    
+<h1>WebApp Sample usage</h1>
+      
+<p>
+        The Cocoon sample webapplication has a link for generating,
+        an index of the Cocoon documentation, and searching the 
+        Cocoon documentation.
+      </p>
+      
+<p>
+        The following list describes step by step how to make use of
+        webapp sample page:
+      </p>
+      
+<ol>
+        
+<li>Go to the page "Search the docs".
+        </li>
+        
+<li>Create an index, follow the link "create".
+          Creating an index may take some time, as the implementation
+          accesses the XML resources via http: protocol.
+        </li>
+        
+<li>Next you may query the index, by following the 
+          link "XSP", or "Cocoon Generators". Typing in a query will
+          result in the table of hits orderer by relevance.
+        </li>
+      
+</ol>
+      
+<p>
+        As a result of the creation step, there should exist an
+        Lucene index in the directory <span class="codefrag">index</span> 
+        below the temporary working directory of the servlet engine.
+      </p>
+      
+<p>
+        The "XSP" link for searching shows an XSP implementation of
+        invoking the Avalon component <span class="codefrag">CocoonSearch</span>. 
+        Using this approach gives fine grained control
+        over the searching process.
+      </p>
+      
+<p>
+        The "Cocoon Generator" links defines in the sitemap using
+        the SearchGenerator, and transforming the XML search result to HTML.
+        This approach tries to minimize your effort of using searching,
+        as you need to adapt the XSLT transformation step only to your
+        needs.
+      </p>
+    
+    
+<h1>Extending the Sample</h1>
+      
+<p>
+        It is easy to extend the search sample to display more information about the search hit than just the url of the resource.</p>
+      
+<p>In order to show, for example, the title and summary of a document, these first need to be added to the search index as 'Stored Fields'. Then when the documents are found during a search, that information is available to display, from the search engine itself.</p>
+      
+<p>First, decide which fields you want to store.</p>
+      
+<p>Decide where is the best place in your pipeline for content to be extracted for indexing, it might not always be the default view 'content'.</p>
+      
+<p>Next, decide if you need an XSLT transformation on your documents, to make them more suitable for indexing. This may include deciding on one of several titles in your document, what part of your document gets added to the summary etc. You might want to strip certain tags out because you don't want their content searched. You might be able to raise hit scores on documents by re-arranging content, or keeping larger amounts of content in fewer tags.</p>
+      
+<p>Now you tell the search engine (in cocoon.xconf) which tags you'd like storing.</p>
+
+<pre class="code">
+&lt;lucene-xml-indexer logger="core.search.lucene"&gt;
+  &lt;store-fields&gt;title, summary&lt;/store-fields&gt;
+  &lt;content-view-query&gt;cocoon-view=search-content&lt;/content-view-query&gt;
+&lt;/lucene-xml-indexer&gt;
+</pre>
+      
+<p>This example tells the indexer to store any tags called 'title' or 'summary' it finds in your documents. It also tells the indexer to get it's content from the view called 'search-content'.</p>
+
+<pre class="code">
+&lt;map:view from-label="search" name="search"&gt;
+  &lt;map:transform src="search-filter.xsl"/&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:view&gt;
+</pre>
+      
+<p>This is how you might setup that custom view in your sitemap. You would then add a label attribute <span class="codefrag">label="search"</span> to the appropriate place in your pipelines. See the section on views for more information.</p>
+      
+<p>After you have re-indexed the site, when you do searches, the new fields will be available in the XML output by Lucene, in the form of a <span class="codefrag">search:field</span> tag, you will need to modify your XSLT that displays the hits to show this.</p>
+
+<pre class="code">
+&lt;xsl:template match="search:hit"&gt;
+  &lt;tr&gt;
+    &lt;td&gt;
+      &lt;xsl:value-of select="format-number( @search:score, '### %' )"/&gt;
+    &lt;/td&gt;
+    &lt;td&gt;
+      &lt;xsl:value-of select="@search:rank"/&gt;
+    &lt;/td&gt;
+    &lt;td&gt;
+      &lt;a target="_blank" href="{@search:uri}"&gt;
+        &lt;xsl:attribute name="title"&gt;
+          &lt;xsl:value-of select="search:field[@search:name='summary']"/&gt;
+        &lt;/xsl:attribute&gt;
+        &lt;xsl:value-of select="search:field[@search:name='title']"/&gt;
+      &lt;/a&gt;
+    &lt;/td&gt;
+  &lt;/tr&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+<p>This is how the search sample's xslt might be changed. All the fields you made for each document are available to you as <span class="codefrag">search:field</span> elements in the <span class="codefrag">search:hit</span> elements. The code above assumes you only had one 'title' and one 'summary' per document.</p>
+    
+    
+<h1>Summary</h1>
+      
+<p>
+        This document gives an overview of the components for
+        using an indexing, and searching engine in Cocoon.
+        It described the component decomposition of the Cocoon
+        XMLSearch subsystem.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/meta.xml
new file mode 100644
index 0000000..70e2650
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-lucene-xml-searching/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/xmlsearching.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/content_en.html
new file mode 100644
index 0000000..e83028c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/content_en.html
@@ -0,0 +1,375 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Sendmail Action</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Frank Ridderbusch" name="DC.Creator">
+<meta content="Jon Evans" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Description</h1>
+      
+<p>
+        The Sendmail action is an action which makes the capability of sending
+        an email message available to the sitemap. This includes attaching
+        binary files which come either from another Cocoon pipeline or from
+        HTML file uploads. The Sendmail action make the primary methods of the
+        <a class="external" href="http://java.sun.com/products/javamail/">Java Mail API</a>
+        available to the sitemap.
+      </p>
+      
+<p>
+        The Sendmail action is an alternative to the
+        <a href="../xsp/sendmail.html">Sendmail logicsheet</a>.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        Before the Sendmail action can be used, it must be activated - either in
+        Cocoon's main sitemap, or in a subsitemap which is used for your
+        application. Include the following <span class="codefrag">map:action</span> element
+        as child respectively grandchild of the <span class="codefrag">map:components</span>
+        -&gt; <span class="codefrag">map:actions</span> elements.
+      </p>
+      
+<pre class="code">
+
+&lt;map:components&gt;
+  &lt;map:actions&gt;
+     &lt;map:action name="sendmail" logger="sitemap.action.sendmail"
+                  src="org.apache.cocoon.acting.Sendmail"/&gt;
+  &lt;/map:actions&gt;
+&lt;/map:components&gt;
+
+      </pre>
+    
+    
+<h1>Example Code</h1>
+      
+<p>
+        This example uses a simple HTML form which provides entry fields for
+        <span class="codefrag">subject</span>, <span class="codefrag">cc</span>, <span class="codefrag">uploaded_file1</span> and
+        the email <span class="codefrag">body</span>.
+      </p>
+      
+<pre class="code">
+
+&lt;form action="/cocoon/mail/send-a-mail"
+      method="POST"
+     enctype="multipart/form-data"&gt;
+  &lt;input type="text" name="subject" size="56" /&gt;
+  &lt;input type="text" name="cc" size="56" /&gt;
+  &lt;input type="file" name="uploaded_file1" size="56" /&gt;
+  &lt;textarea name="body" rows="5" cols="72"&gt;
+  &lt;/textarea&gt;
+&lt;/form&gt;
+
+      </pre>
+      
+<p>
+        Please keep in mind that it is important to use
+        <span class="codefrag">enctype="multipart/form-data"</span> if you want to upload files
+        which should be attached to an email message.
+      </p>
+      
+<p>The posted HTTP request data is processed by this sitemap fragment.</p>
+      
+<pre class="code">
+
+&lt;map:match pattern="mail/*"&gt;
+  &lt;map:act type="sendmail"&gt;
+    &lt;!-- To override defaults specified in cocoon.xconf:
+    &lt;map:parameter name="smtp-host" value="localhost"/&gt;
+    &lt;map:parameter name="smtp-user" value="john"/&gt;
+    &lt;map:parameter name="smtp-password" value="john"/&gt;
+    --&gt;
+    &lt;map:parameter name="from" value="cocoon@localhost"/&gt;
+    &lt;map:parameter name="to" value="mailinglist@somewhere.com"/&gt;
+    &lt;map:parameter name="subject" value="{request-param:subject}"/&gt;
+    &lt;map:parameter name="body" value="{request-param:body}"/&gt;
+    &lt;map:parameter name="cc" value="{request-param:cc}"/&gt;
+    &lt;map:parameter name="bcc" value="censor@somewhere.com"/&gt;
+    &lt;map:parameter name="attachments"
+                   value="uploaded_file1 context://welcome.xml"/&gt;
+    &lt;map:generate src="mail/{status}.xml"/&gt;
+    &lt;map:serialize type="xml"/&gt;
+  &lt;/map:act&gt;
+&lt;/map:match&gt;
+
+      </pre>
+      
+<p>
+        The input modules are used to supply some of the input parameters for
+        the Sendmail action. In this example, apart from the
+        <span class="codefrag">uploaded_file1</span> request parameter, a second file is attached
+        to the email message, using the Cocoon protocol notation (the file
+        <span class="codefrag">welcome.xml</span> from the Cocoon context directory). The result
+        of sending the email message is passed back into the sitemap through the
+        <span class="codefrag">status</span> parameter and is used to provide the user with a
+        feedback. (The transformation is left as an exercise to the reader).
+      </p>
+      
+<p>
+        Please consider the security implications if you let a user specify an
+        email address in an input form. A malicious user might abuse this to
+        send SPAM emails. So, this example is probably only useful in an
+        intranet application, where users can mostly be considered well behaved.
+      </p>
+    
+    
+<a name="parameters"></a>
+    
+<h1>Input/Output Parameter Reference</h1>
+      
+<p>
+        The following is the list of parameters which can be passed from the
+        sitemap into the Sendmail action.
+      </p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Name:</th>
+          <th colspan="1" rowspan="1">Required?</th>
+          <th colspan="1" rowspan="1">Description:</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">smtp-host</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            The IP address or the name of the host, which should deliver the
+            email message. Better known as the mail transfer agent or short MTA.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">smtp-user</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            User name
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">smtp-password</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Password
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">to</td>
+          <td colspan="1" rowspan="1">yes</td>
+          <td colspan="1" rowspan="1">
+            Sets the destination/to address of the email message. This can be a
+            list of comma separated email addresses.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">cc</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Sets the recipients of a carbon copy of this email. This can be a
+            list of comma separated email addresses.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">bcc</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Sets the recipients of a black carbon copy of the email. This can be
+            a list of comma separated email addresses.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">from</td>
+          <td colspan="1" rowspan="1">yes</td>
+          <td colspan="1" rowspan="1">Sets the from address of the message.</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">subject</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">Sets the subject line of the message.</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">body</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Sets the body text of the message. This parameter is ignored if the
+            <span class="codefrag">src</span> parameter is specified.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">src</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            A url specifying the source of the text body of the email. If
+            <span class="codefrag">src</span> is specified, the <span class="codefrag">body</span> parameter is
+            ignored.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">srcMimeType</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            The optional mime type of the source of the text body of the email
+            if you specified <span class="codefrag">src</span>.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">charset</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Sets the character set for encoding the message. This tag has only
+            an effect if no attachments are send.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">attachment</td>
+          <td colspan="1" rowspan="1">no</td>
+          <td colspan="1" rowspan="1">
+            Sets the attachment for this email. This is a blank separated list.
+            If an argument contains a ":", it is assumed that a Cocoon internal
+            protocol is specified (ex: <span class="codefrag">context://welcome.xml</span>). This
+            means that the attachment comes from a Cocoon pipeline (internally
+            an <span class="codefrag">org.apache.excalibur.source.Source</span> object). If the
+            argument does not contain a colon, the argument names a request
+            parameter which is a file upload through a HTML form (internally an
+            <span class="codefrag">org.apache.cocoon.components.request.multipart.FilePart</span>
+            object).
+          </td>
+        
+</tr>
+<!-- [CH] I believe deleting attachments should be handled at a different place
+     [JH] Aren't uploads not already deleted by default?
+        <tr>
+          <td>keep-attachment</td>
+          <td>no</td>
+          <td>
+            This is a boolean parameter, which defaults to <code>false</code>.
+            This means, that any uploads are delete from Cocoons upload
+            directory.
+          </td>
+        </tr>
+-->
+      
+</table>
+      
+<p>
+        The following is the list of parameters which are passed from Sendmail
+        action back into the sitemap.
+      </p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Name:</th>
+          <th colspan="1" rowspan="1">Description:</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">status</td>
+          <td colspan="1" rowspan="1">
+            This parameter can take three values: <span class="codefrag">success</span>,
+            <span class="codefrag">user-error</span> and <span class="codefrag">server-error</span>.
+            <span class="codefrag">success</span> means that the email message has been
+            successfully delivered to the mail transfer host.
+            <span class="codefrag">user-error</span> means that there was a problem with at least
+            one of the specified email addresses (to, cc, bcc or from).
+            <span class="codefrag">server-error</span> means that there was some problem
+            delivering the message to the mail transfer host. In effect, this
+            parameter can be used to inform the user about the outcome of
+            sending the email message.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">message</td>
+          <td colspan="1" rowspan="1">
+            This parameter contain some explanatory text if the message couldn't
+            be delivered. It is unset if the email message had been successfully
+            sent.
+          </td>
+        
+</tr>
+      
+</table>
+    
+    
+<a name="hint"></a>
+    
+<h1>Additional Hint</h1>
+      
+<p>
+        Cocoon provides the capability to automatically parse a file upload out
+        of an incoming HTTP request. Depending on the setting of the parameter
+        <span class="codefrag">autosave-uploads</span> (default is <span class="codefrag">false</span>) in
+        Cocoon's <span class="codefrag">web.xml</span> file, the file upload is either stored in
+        memory (<span class="codefrag">false</span>) for further processing or stuffed into
+        Cocoons upload directory (<span class="codefrag">true</span>).
+      </p>
+      
+<p>
+        In theory, it should be equal whether the file upload data comes from
+        memory of from file. In my particular setup (Linux, Tomcat 4.0.4,
+        Mozilla 1.3 and JDK 1.4.1_02) I was unable to get the file uploading
+        working with <span class="codefrag">autosave-upload=false</span>. Somehow the attached
+        binary data was distorted (a GIF file does not appear to be a GIF any
+        more).
+      </p>
+      
+<p>
+        With <span class="codefrag">autosave-upload=true</span> it worked flawlessly, even
+        attaching multiple files.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/meta.xml
new file mode 100644
index 0000000..a20ae69
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-mail-sendmail-action/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/actions/sendmail-action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/content_en.html
new file mode 100644
index 0000000..6b51fac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/content_en.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>LDAP Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the LDAP transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>LDAP Transformer</h1>
+      
+<p>
+                   The <span class="codefrag">LDAPTransformer</span> is a class that can be plugged into a pipeline
+                   to transform the SAX events which passes through this transformer into queries
+                   to an ldap interface and transforms the response to SAX events which are passed
+                   on in the pipeline.
+                  </p>
+      
+<ul>
+        
+<li>Name : ldap</li>
+        
+<li>Class: org.apache.cocoon.transformation.LDAPTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+      
+<p>This transformer is optional and not available in the binary distribution.
+                     However if you want to use it, you have to retrieve the jndi package,
+                     copy the jar file into the lib directory of Cocoon and rebuild.
+                  </p>
+                  
+<p>
+ The file will be specified in a parameter tag in the sitemap pipeline to the
+ transformer as follows:
+</p>
+ 
+<pre class="code">
+  &lt;map:transform type="ldap"/&gt;
+  </pre>
+  
+<p>
+ The following DTD is valid:<br>
+ &lt;!ELEMENT execute-query (attribute+ | show-attribute? | scope? | initializer? | authentication? | error-element? | sax-error?  doc-element? | row-element? | version? | serverurl? | rootdn? | password? | deref-link? | count-limit? | searchbase, filter)&gt;<br>
+ &lt;!ELEMENT execute-increment (attribute | show-attribute? | scope? | initializer? | authentication? | error-element? | sax-error? | doc-element? | row-element? | version? | serverurl? | rootdn? | password? | deref-link? | count-limit? | searchbase, filter)&gt;<br>
+ increments (+1) an integer attribute on a directory-server (ldap)<br>
+ 
+<br>
+ &lt;!ELEMENT initializer (#PCDATA)&gt;* (default: "com.sun.jndi.ldap.LdapCtxFactory")<br>
+ &lt;!ELEMENT authentication (#PCDATA)&gt;* (default: "simple")<br>
+ &lt;!ELEMENT version (#PCDATA)&gt;* (default: "2")<br>
+ &lt;!ELEMENT serverurl (#PCDATA)&gt;*<br>
+ &lt;!ELEMENT port (#PCDATA)&gt;* (default: 389)<br>
+ &lt;!ELEMENT rootdn (#PCDATA)&gt;*<br>
+ &lt;!ELEMENT password (#PCDATA)&gt;*<br>
+ &lt;!ELEMENT scope (ONELEVEL_SCOPE | SUBTREE_SCOPE | OBJECT_SCOPE)&gt;* (default: ONELEVEL_SCOPE)<br>
+ &lt;!ELEMENT searchbase (#PCDATA)&gt;*<br>
+ &lt;!ELEMENT doc-element (#PCDATA)&gt;* (default: "doc-element")<br>
+ &lt;!ELEMENT row-element (#PCDATA)&gt;* (default: "row-element")<br>
+ &lt;!ELEMENT error-element (#PCDATA)&gt;* (default: "ldap-error") (in case of error returned error tag)<br>
+ &lt;!ELEMENT sax_error (TRUE  | FALSE)&gt;* (default: FALSE) (throws SAX-Exception instead of error tag)<br>
+ &lt;!ELEMENT attribute (#PCDATA)&gt;<br>
+ &lt;!ELEMENT show-attribute (TRUE | FALSE)&gt; (default: TRUE)<br>
+ &lt;!ELEMENT filter (#PCDATA | execute-query)&gt;<br>
+ &lt;!ELEMENT deref-link (TRUE | FALSE)&gt; (default: FALSE)<br>
+ &lt;!ELEMENT count-limit (#PCDATA)&gt; (integer default: 0 -&gt; no limit)<br>
+ &lt;!ELEMENT time-limit (#PCDATA)&gt; (integer default: 0 -&gt; infinite)<br>
+ &lt;!ELEMENT debug (TRUE  | FALSE)&gt;* (default: FALSE)<br> 
+can also be defined as parameter in the sitemap.
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/meta.xml
new file mode 100644
index 0000000..a3d2016
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-naming-ldap-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/ldap-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/content_en.html
new file mode 100644
index 0000000..b20174f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/content_en.html
@@ -0,0 +1,371 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HSSF Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Andrew C. Oliver" name="DC.Creator">
+<meta content="Marcus W. Johnson" name="DC.Creator">
+<meta content="J&ouml;rg Heinicke" name="DC.Creator">
+<meta content="This document describes the HSSF serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+        
+<h1>HSSF Serializer</h1>
+            
+<p>The HSSF serializer catches SAX events and creates a spreadsheet in the
+                XLS format used by Microsoft Excel (but the output looks just dandy in
+                <a class="external" href="http://www.gnome.org/gnumeric">Gnumeric</a> or
+                <a class="external" href="http://www.openoffice.org">OpenOffice.org</a> as well).
+            </p>
+            
+<p>The HSSF Serializer supports most of the functionality supplied by the
+                <a class="external" href="http://jakarta.apache.org/poi/hssf">HSSF API</a> which is
+                part of the
+                <a class="external" href="http://jakarta.apache.org/poi">Jakarta POI project</a>.
+            </p>
+            
+<ul>
+                
+<li>Name: xls</li>
+                
+<li>Class: org.apache.cocoon.serialization.HSSFSerializer</li>
+                
+<li>Cacheable: no</li>
+            
+</ul>
+        
+        
+<h1>Usage</h1>
+            
+<p>Using the HSSF Serializer is fairly simple. You'll need a sitemap of
+                course. Once you have that, well, you're half there. Add </p>
+            
+<pre class="code">
+&lt;map:serializer name="xls"
+                src="org.apache.cocoon.serialization.HSSFSerializer"
+                locale="us"/&gt;
+            </pre>
+            
+<p>into the <span class="codefrag">&lt;map:serializers/&gt;</span> section of your sitemap.
+                The locale is optional and is used only to validate numbers. Please note
+                that numbers not in US-default format may not be compatible with Gnumeric
+                (it's less cosmopolitan then the HSSF Serializer ;-) ). Setting the locale
+                lets you use default number formats from other locales. Set this to a two
+                letter lowercase country code. See java.util.Locale for details.
+            </p>
+            
+<p>Next, set up an entry for each URL or set of URLs (via matching rules)
+                resembling this:
+            </p>
+            
+<pre class="code">
+&lt;map:match pattern="hello.xls"&gt;
+    &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+    &lt;map:transform src="stylesheets/page/simple-page2xls.xsl"/&gt;
+    &lt;map:serialize type="xls"/&gt;
+&lt;/map:match&gt;
+            </pre>
+            
+<p>The most important question is now, which what XML the serializer is fed.
+                You will get it answered in the next paragraph.</p>
+        
+        
+<h1>Required XML Format</h1>
+            
+<p>The HSSF Serializer expects data in the same XML language as the popular
+                spreadsheet progam Gnumeric. You have different possibilities to get such
+                a document:</p>
+            
+<ul>
+                
+<li>You can create and save a spreadsheet using Gnumeric.</li>
+                
+<li>You can write it yourself using the
+                    <a class="external" href="http://cvs.gnome.org/lxr/source/gnumeric/gnumeric.xsd">
+                    Schemas</a> or DTDs available at the
+                    <a class="external" href="http://www.gnome.org/gnumeric">Gnumeric's website</a>
+                    or in Gnumeric's CVS repository.
+                </li>
+                
+<li>You can take one of the samples delivered with Cocoon and start from
+                    there.</li>
+                
+<li>Or you use the empty workbook from appendix A in
+                    <a class="external" href="http://www.superlinksoftware.com/gnumeric-xml.pdf">
+                    The Gnumeric File Format PDF</a> (all further references to 'PDF'
+                    mean this file), which can further simplified to the following:<br>
+                
+</li>
+            
+</ul>
+            
+<pre class="code">
+&lt;gmr:Workbook xmlns:gmr="http://www.gnome.org/gnumeric/v7"&gt;
+    &lt;gmr:SheetNameIndex&gt;
+        &lt;gmr:SheetName&gt;Sheet1&lt;/gmr:SheetName&gt;
+    &lt;/gmr:SheetNameIndex&gt;
+    &lt;gmr:Sheets&gt;
+        &lt;gmr:Sheet&gt;
+            &lt;gmr:Name&gt;Sheet1&lt;/gmr:Name&gt;
+            &lt;gmr:MaxCol&gt;-1&lt;/gmr:MaxCol&gt;
+            &lt;gmr:MaxRow&gt;-1&lt;/gmr:MaxRow&gt;
+            &lt;gmr:Cells&gt;
+                &lt;!-- add your cells here --&gt;
+            &lt;/gmr:Cells&gt;
+        &lt;/gmr:Sheet&gt;
+    &lt;/gmr:Sheets&gt;
+&lt;/gmr:Workbook&gt;
+            </pre>
+            
+<p>While HSSFSerializer ignores the bulk of the elements, it is suggested
+                you provide at a minimum the basic elements as in the list below. As a
+                general rule, if Gnumeric in the versions 0.7 - 1.04 will load the XML
+                (provided it is tar'd and gzipped as expected), then the HSSFSerializer
+                should be able to handle it.</p>
+            
+<p>As a general guideline the following elements are supported in this
+                release. For the nesting have a look into the sample files or the PDF.
+            </p>
+            
+<ul>
+                
+<li>
+                    
+<span class="codefrag">gmr:Workbook</span> -  Required. Basically the root element.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Sheets</span> - Required. Container for the spreadsheets.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Sheet</span> - Required for each sheet. For the attributes
+                    have a look at the example above or into the PDF.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Name</span> - Required? Defines the sheet's name as it
+                    appears on the little tabs under the workbook in your favorite GUI
+                    spreadsheet application.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:MaxRow</span>, <span class="codefrag">gmr:MaxCol</span> - Used to set the
+                    dimensions for the sheet. This can be wrong and your spreadsheet
+                    application may not care, but some other ports depend upon this, so
+                    we set it to be compatible.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Rows</span>, <span class="codefrag">gmr:Cols</span> - Used to determine the
+                    default row or column width in points via the attribute
+                    <span class="codefrag">DefaultSizePts</span>.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:RowInfo</span>, <span class="codefrag">gmr:ColInfo</span> - Used to
+                    determine the row height/column width for a specific row/column in
+                    points.<br>
+                    Attributes:
+                    <ul>
+                        
+<li>
+<span class="codefrag">No</span> - row/column number</li>
+                        
+<li>
+<span class="codefrag">Unit</span> - row/column height</li>
+                    
+</ul>
+                    The count of the rows/columns starts with 0.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Cells</span> - Required. Container for all cells.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Cell</span> - Defines the actual column and row number as
+                    well as the data type.<br>
+                    Attributes:
+                    <ul>
+                        
+<li>
+<span class="codefrag">Row</span> - row number</li>
+                        
+<li>
+<span class="codefrag">Col</span> - col number</li>
+                        
+<li>
+                            
+<span class="codefrag">ValueType</span> - the data type<br>
+                            If you don't specify the data type, the cell content will not
+                            be shown! The type is determined by a numerical key, where
+                            the following are known: 10 - empty, 20 - boolean,
+                            30 - integer, 40 - float, 50 - error, 60 - string,
+                            70 - cell range, 80 - array
+                        </li>
+                    
+</ul>
+                
+</li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Content</span> - Defines the start of the value contained
+                    in the cell. This is obsolete as of Gnumeric 1.03. It's not
+                    recommended to use it, because it may not be supported in future
+                    versions. With POI release 1.5.1 I didn't use <span class="codefrag">gmr:Content</span>,
+                    but I had to specify '10' as <span class="codefrag">ValueType</span> on empty cells.
+                    Otherwise I got strange output.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Styles</span> - Required if you want to use styles.
+                    Container for <span class="codefrag">gmr:StyleRegion's</span>.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:StyleRegion</span> - Defines the region that the style
+                    applies to.<br>
+                    Attributes:
+                    <ul>
+                        
+<li>
+<span class="codefrag">startRow</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">startCol</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">endRow</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">endCol</span> - self-explanatory</li>
+                    
+</ul>
+                    Again: The count of the rows/columns starts with 0.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Style</span> - Specifies the style for a StyleRegion.<br>
+                    Attributes:
+                    <ul>
+                        
+<li>
+                            
+<span class="codefrag">HAlign</span> - specifies the horizontal alignment.<br>
+                            Possible values: 1 - general, 2 - left, 4 - right, 8 - center,
+                            16 - fill, 32 - justify, 64 - center across selection
+                        </li>
+                        
+<li>
+                            
+<span class="codefrag">VAlign</span> - specifies the vertical alignment.<br>
+                            Possible values: 1 - top, 2 - bottom, 4 - center, 8 - justify
+                        </li>
+                        
+<li>
+                            
+<span class="codefrag">WrapText</span> - specifies whether to wrap text around
+                            or not<br>
+                            Possible values: 0 - don't wrap, 1 - do wrap
+                        </li>
+                        
+<li>
+                            
+<span class="codefrag">Shade</span> - kind a stupid flag<br>
+                            If you're setting a background color and want it filled ...
+                            use Shade="1".
+                        </li>
+                        
+<li>
+                            
+<span class="codefrag">Format</span> - number format to use.<br>
+                            Generally, Excel and Gnumeric have the same formats.
+                        </li>
+                    
+</ul>
+                
+</li>
+                
+<li>
+                    
+<span class="codefrag">gmr:Font</span> - Defines the font used for the style region.<br>
+                    Attributes:
+                    <ul>
+                        
+<li>
+<span class="codefrag">Bold</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">Italic</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">Underline</span> - self-explanatory</li>
+                        
+<li>
+<span class="codefrag">StrikeThrough</span> - self-explanatory</li>
+                    
+</ul>
+                    Set the values of the attributes to 0 or 1 to disable or enable a
+                    specific font style.
+                </li>
+                
+<li>
+                    
+<span class="codefrag">gmr:StyleBorder</span> - Defines the borders that are used for
+                    a style region. It contains one element for each possible border
+                    specifying the style and the color of the border.
+                </li>
+            
+</ul>
+            
+<p>For more specific information on the Gnumeric file format, especially on
+                some more interesting attributes or attribute values or the nesting of
+                the elements, I only can recommend you to read the PDF or to have a look
+                at the sample files. If you want it more complicated, you can also get
+                the information from the Schema file (look above for the link).</p>
+        
+        
+<h1>Automatic Excel Spreadsheet Generation</h1>
+            
+<p>Hmm, I don't want to say to much on this. I showed you the XML the
+                serializer wants to have. Now it's up to you to generate this XML
+                dynamically. The best way to do this is using a XSLT stylesheet. You need
+                some information on this? Hmm, have a look at the
+                <a class="external" href="http://www.w3.org/Style/XSL/">W3C's XSL page</a>. From
+                there you get many links to tutorials, articals, the surprisingly
+                readable XSLT spec and so on.
+            </p>
+        
+        
+<h1>Future Features</h1>
+            
+<p>So HSSF Serializer is well on its way to being darn near everything you
+                need to create fancy smancy reports in Excel or OpenOffice. (And you can
+                just serialize the output from your stylesheets as XML for Gnumeric
+                version).</p>
+            
+<ul>
+                
+<li>Add support for formulas. (not yet supported by HSSF)</li>
+                
+<li>Add support for custom data formats. (not yet supported by HSSF)</li>
+            
+</ul>
+        
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/meta.xml
new file mode 100644
index 0000000..cc53332
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-poi-xls-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/xls-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/content_en.html
new file mode 100644
index 0000000..d5e7e96
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/content_en.html
@@ -0,0 +1,168 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The Portal Basket</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Overview</h1>
+   
+<p>This document describes the basket portlet. This is a special functionality that can
+      be used inside your portal application to implement a per user basket.
+   </p>
+   
+<p>
+     The sample portal that comes with the Cocoon distribution contains a working sample
+     for the basket. So, you can test it out of the box and skip the next chapter. 
+   </p>
+   
+<p>
+     If you don't need the basket functionality have a look at the end of the next chapter
+     to see what you can remove from the portal.
+   </p>
+  
+  
+<h1>Generel Configuration</h1>
+   
+<p>
+     Each coplet that is able to be added to the basket, gets a button "add" in the
+     window title. For rendering this title, you need to add the <em>basket</em>
+     renderer to the render that is rendering your window. Add the following aspect to your
+     <em>window</em> renderer:
+   </p>
+   
+<pre class="code">
+&lt;aspect type="basket"/&gt;
+   </pre>
+   
+<p>
+      The basket uses a manager component that manages the persistence of the baskets. You
+      have to add this component to your cocoon.xconf and configure the directory that
+      is used to store the baskets accordingly:
+   </p>
+   
+<pre class="code">
+      &lt;component class="org.apache.cocoon.portal.coplets.basket.BasketManager" 
+                 role="org.apache.cocoon.portal.coplets.basket.BasketManager"&gt;
+        &lt;parameter name="directory" value="D:/baskets"/&gt;
+      &lt;/component&gt;
+   </pre>
+   
+<p>
+    The default directory is the work directory.
+   </p>
+   
+<p>
+    If you need a different persistence strategy, subclass this component and configure
+    it accordingly.
+   </p>
+   
+<p>
+    If you don't need the basket functionality, remove the above component definition,
+    remove the aspect renderer usage and configuration.
+   </p>
+  
+  
+<h1>Coplets as Basket Content</h1>
+   
+<p>
+    The basket allows to add a coplet or the content of a coplet to the basket. If a
+    coplet should be able to be added to the basket, it has to be configured accordingly.
+    Add one of the following two attributes to the coplet to either allow to add the coplet
+    or the content of the coplet to a basket:
+   </p>
+
+<pre class="code">
+&lt;attribute&gt;
+  &lt;name&gt;basket-link&lt;/name&gt;
+  &lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;true&lt;/value&gt;
+&lt;/attribute&gt;
+&lt;attribute&gt;
+  &lt;name&gt;basket-content&lt;/name&gt;
+  &lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;true&lt;/value&gt;
+&lt;/attribute&gt;
+</pre>
+   
+<p>
+    The attributes have to be added to the coplet data configuration of a coplet.
+   </p>
+  
+  
+<h1>URLs as Basket Content</h1>
+   
+<p>
+    The basket allows to add a URL or the content of a URL to the basket. You can add this
+    feature to your coplet by using the <em>basket transformer</em>. This transformer listens
+    for the <em>add-item</em> element and transform this into an html link:
+   </p>
+
+<pre class="code">
+&lt;p xmlns:basket="http://apache.org/cocoon/portal/basket/1.0"&gt;
+&lt;basket:add-item href="http://cocoon.apache.org"&gt;Add&lt;/basket:add-item&gt;
+&lt;/p&gt;
+</pre>
+   
+<p>
+    With the example from above you add the link to a URI to the basket. If you add
+    the attribute <em>content</em> with the value <em>true</em> to the <em>add-item</em>
+    element, not the URI but the content of the URI is added to the basket.
+   </p>
+  
+  
+<h1>Viewing the content of the basket</h1>
+   
+<p>
+    The <em>basket</em> generator streams out the contents of the basket as XML.
+    You can use this generator in your pipeline to render the content of the
+    current user basket.
+   </p>
+   
+<p>
+    This generator has also a management functionality buildin. By adding the
+    parameter <em>admin-mode</em> with the value <em>true</em> to the generator,
+    the generator streams out the admin functions as XML. These functions allow
+    to delete a basket for a user and to see all user baskets.
+   </p>
+  
+  
+<h1>Persistence</h1>
+   
+<p>
+    Each basket is persisted using the basket manager component. The default
+    installation persists each basket of a user into a separate file in the   
+    temporary directory. You can change the location of the directory by
+    configuring the basket manager in the cocoon.xconf.
+   </p>
+   
+<p>
+    If you need a different persistence strategy, you can subclass the
+    basket manager and for example store the baskets in a database etc.
+   </p>
+  
+  
+<h1>Viewing items</h1>
+   
+<p>
+     The user is able to select a single item and display the contents in
+     a different coplet. Therefore the <em>basket generator</em> needs
+     two additional parameters: the <em>show-coplet</em> and the
+     <em>show-layout</em> parameter.
+   </p>
+   
+<p>
+     The <em>show-layout</em> parameter defines a coplet layout element in
+     the portal layout of the user that will display the selected item.
+   </p>
+   
+<p>
+     The <em>show-coplet</em> parameter defines a coplet data that will
+     be used to create an instance that will display the content.
+   </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/meta.xml
new file mode 100644
index 0000000..ae856b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-basket/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/basket.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/content_en.html
new file mode 100644
index 0000000..c7caaf3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/content_en.html
@@ -0,0 +1,357 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configuring Coplets</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Overview</h1>
+   
+<p>This document gives an overview over configuring coplets.
+     The sample portal that comes with the Cocoon distribution contains several
+     samples.
+   </p>
+   
+<p>
+    The configuration of a coplet is done in several steps that are outlined
+    in the next chapters. We use the provided sample as a base. This sample
+    stores all profiles in XML documents that are all stored in the
+    samples/portal directory. So all file and directory names are relative
+    to this directory. It's not required that you store the configuration
+    in XML files, you can also store them in a database, an LDAP system etc.
+    This is also configurable and customizable.
+   </p>
+  
+  
+<h1>Configuring Coplets</h1>
+   
+<p>
+    Configuring coplets is like defining a class and creating their instances.
+    So in fact, you define the available coplets (= classes) and each portal
+    view gets some instances of these coplets. 
+   </p>
+   
+<p>
+    In addition to the classes and the instances, we have coplet types which can
+    be seen as a classification of the coplet classes. There are different coplet
+    types, uri based coplets, JSR-168 coplets, application coplets etc. The coplet
+    type defines, how the coplet works or how the coplet gets it's content. For 
+    example, the uri based coplet triggers a uri to get the coplet - this can be
+    an http request or an internal cocoon pipeline request.
+   </p>
+   
+<p>
+    Another exsample is the JSR-168 coplet type. This type allows to use JSR-168
+    compliant portlets for fetching the content. So let's start with the coplet
+    types:
+   </p>
+   
+<h2>Available Coplet Types</h2>
+<p>
+     Before you can define your available coplets, you have to define the
+     available coplet types, or the so called coplet base data. The current
+     exsample contains an XML document for this (the file is in the
+     profiles/copletbasedata directory and is called portlal.xml). This is
+     an excerpt from the file:
+   </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-base-data id="URICoplet"&gt;
+      &lt;coplet-adapter&gt;uri&lt;/coplet-adapter&gt;
+   &lt;/coplet-base-data&gt;
+&lt;/coplets&gt;
+...
+          </pre>
+<p>
+    In the example above, we define one coplet type, the <em>URICoplet</em>,
+    that uses the <em>uri coplet adapter</em>. By this we define a type,
+    that uses URIs to get the content of a coplet. A uri can either be
+    targetted at a different server (using http, ftp etc.) or it can
+    be an internal cocoon pipeline (using cocoon:).
+   </p>
+<p>
+    You can add different coplet types with additional configuration here,
+    but rarely have to touch this file as most is preconfigured already.
+   </p>
+  
+<h2>Available Coplets</h2>
+<p>
+    Based on the coplet types, you can define the available coplets in your
+    portal application (= classes). In the example portal an own configuration
+    file contains these so called coplet datas (it's in the profiles/copletdata
+    directory and has the filename portal.xml). Here is an excerpt:
+   </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;cocoon:/news/liverss?feed=http://radio.weblogs.com/0107211/rss.xml&lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;buffer&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;true&lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;error-uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;cocoon:/news/CZ_weblog.rss&lt;/value&gt;
+      &lt;/attribute&gt;
+   &lt;/coplet-data&gt;
+&lt;/coplets&gt;
+...
+   </pre>
+<p>
+    Each coplet data contains a unique id and additional configuration. A required
+    configuration is the underlying coplet base data. In the example above,
+    the <em>URICoplet</em> is used that we have configured in the previous chapter.
+   </p>
+<p>
+    The above configured coplet data requires some configuration. This configuration
+    depends on the coplet type. In this case we use the URICoplet and this needs
+    of course the URI to fetch the content from for this coplet. This configuration is
+    passed in the different attributes you see above. Each attribute has a name and value.
+   </p>
+<p>
+    The set of coplet datas defines the set of available coplets a user can
+    choose from. If a user chooses to view a coplet, an instance of this coplet
+    data is created. If, e.g. the user chooses the same coplet twice,
+    two instances are created. This is useful for configurable coplets where
+    the user can choose the same coplet with different configurations.
+   </p>
+  
+<h2>Selected Coplets</h2>
+<p>
+    The selected coplets are described by the set of coplet instance datas This is
+    again another XML document (that is stored in profiles/copletinstancedata and
+    has the name portal.xml). Here is an excerpt:
+   </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-instance-data id="CZ Weblog-1" name="standard"&gt;
+      &lt;coplet-data&gt;CZ Weblog&lt;/coplet-data&gt;
+   &lt;/coplet-instance-data&gt;
+&lt;/coplets&gt;
+...
+   </pre>
+<p>
+     The coplet instance data refers to its coplet data (the class) by specifying the
+     unique ID. The instance itself has a unique ID as well that is referenced
+     from the portal view. This id of the instance has only the be unique within
+     the scope of a user. Different users can have different instances with the
+     same id.
+   </p>
+<p>
+     In addition, a coplet instance data could have own configuration information.
+     This configuration depends on the coplet type and on the coplet (class).
+   </p>
+ 
+ 
+<h1>Common Coplet Configuration</h1>
+  
+<p>
+   As outlined above, a coplet can be configured at various places. In general,
+   configuration values are most often configured at the coplet type (coplet
+   base data) and may be overwritten by the coplet class (coplet data).
+  </p>
+  
+<p>
+   The coplet base data takes the information as config entries whereas 
+   the coplet data uses attributes. Apart from that the keys and 
+   the data types are the same. Let's have a look at an example:
+  </p>
+   
+<pre class="code">
+...
+   &lt;coplet-base-data id="URICoplet"&gt;
+      &lt;coplet-adapter&gt;uri&lt;/coplet-adapter&gt;
+      &lt;configuration&gt;
+      	&lt;name&gt;buffer&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;true&lt;/value&gt;
+      &lt;/configuration&gt;
+   &lt;/coplet-base-data&gt;
+   ...
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;buffer&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;false&lt;/value&gt;
+      &lt;/attribute&gt;
+   &lt;/coplet-data&gt;
+...
+   </pre>
+   
+<p>
+    As you can see in the exsample above, there is no real difference in configuring
+    a coplet type (base data) and a coplet class (coplet data) apart that the first
+    one uses the element name <em>configuration</em> and the last one uses 
+    <em>attribute</em>.
+   </p>
+  
+<h2>Output Buffering</h2>
+<p>
+    Each coplet can be configured with the boolean value <em>buffer</em>
+    (default is false) that defines if the xml data stream from the coplet 
+    is buffered before it is streamed in the main portal pipeline. 
+   </p>
+<p>
+    If the stream is not buffered and an exception occurs during the
+    streaming of the one coplet, then the whole portal might be rendered invalid.
+    Therefore you should turn on buffering whenever you can't guarantee
+    that the output of a coplet is always valid XML.
+   </p>
+  
+<h2>Delivery Timeout</h2>
+<p>
+    Usually the portal waits forever(!) for a coplet to deliver it's content.
+    If you want to fine-tune this behaviour, you can configure a <em>timeout</em>
+    value. This integer value (default is endless) defines the
+    maximum time (in seconds) the coplet has to deliver it's content.
+   </p>
+<p>
+    If the timeout is reached the content is assumed as not
+    gettable. If you set a timeout, the content is automatically
+    buffered and the <em>buffer</em> configuration is ignored.
+   </p>
+ 
+ 
+<h1>The URICoplet</h1>
+  
+<p>
+   This section describes the URICoplet and the different possibilities to
+   configure it. For general configuration see the previous chapter.
+  </p>
+  
+<h2>The Content Location and Parameter Handling</h2>
+<p>
+    A URICoplet uses a uri to fetch the coplet. This configuration is obviously
+    a configuration of the coplet class (and not of the coplet type) as each
+    coplet uses a different location.
+   </p>
+<p>
+    The attribute <em>uri</em> takes the complete uri (as a string) to fetch the
+    content from:
+   </p>
+<pre class="code">
+...
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+      	  cocoon:/news/liverss?feed=http://radio.weblogs.com/0107211/rss.xml
+      	&lt;/value&gt;
+      &lt;/attribute&gt;
+   &lt;/coplet-data&gt;
+...
+   </pre>
+<p>
+    If you're using the cocoon protocol to call internal pipelines, you can also
+    configure the boolean attribute <em>handleParameters</em> (default is false),
+    that defines if the coplet handles request parameters itself. This should
+    be used for coplets that process request parameters (have forms for example).
+    In that case, the parameters from the request are only forwarded to the
+    coplet, if they are meant for this coplet. All other coplets that use
+    request parameters don't get them in this request-response-cycle.
+   </p>
+  
+<h2>Error Handling</h2>
+<p>
+    Usually, in the case of an error during rendering the content of a coplet,
+    a message is included in the coplet window instead of the coplet content.
+    If you want to customize this, you can specifiy the attribute <em>error-uri</em>
+    that should contain a valid uri that deliveres the content for a better
+    error message.
+   </p>
+ 
+ 
+<h1>Coplet Rendering</h1>
+  
+<p>
+   Each coplet can be configured for supporting different features, like minimizing
+   or removing. These are aspect configurations that are configured similar to 
+   attributes.
+  </p>
+  
+<h2>Sizing</h2>
+<p>
+    By default, the window size of a coplet can be changed by the user.
+    The user can choose between maximized and minimized.
+   </p>
+<p>
+    This is configurable by the boolean aspect <em>sizable</em> on
+    the coplet data (class). The default is true:
+   </p>
+<pre class="code">
+...
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;aspect&gt;
+      	&lt;name&gt;sizable&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+      	  false
+      	&lt;/value&gt;
+      &lt;/aspect&gt;
+   &lt;/coplet-data&gt;
+...
+   </pre>
+<p>
+    In addition the size of a coplet (minimized/maximized) can be preconfigured
+    as well by the integer aspect value <em>size</em>. The value <em>0</em>
+    means minimized and <em>1</em> is maximized (with 1 as the default).
+   </p>
+<pre class="code">
+...
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;aspect&gt;
+      	&lt;name&gt;size&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Integer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+      	  0
+      	&lt;/value&gt;
+      &lt;/aspect&gt;
+   &lt;/coplet-data&gt;
+...
+   </pre>
+  
+<h2>Mandatory Coplets</h2>
+<p>
+    By default, the user can delete any coplet from his portal view. However
+    important coplets can be configured as <em>mandatory</em>. In this case,
+    the remove icon is not displayed, and the coplet can never be removed 
+    by the user.
+   </p>
+<p>
+    This is configurable by the boolean aspect <em>mandatory</em> on
+    the coplet data (class). The default is false:
+   </p>
+<pre class="code">
+...
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;aspect&gt;
+      	&lt;name&gt;mandatory&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+      	  true
+      	&lt;/value&gt;
+      &lt;/aspect&gt;
+   &lt;/coplet-data&gt;
+...
+   </pre>
+ 
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/meta.xml
new file mode 100644
index 0000000..2ff34ae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-coplets/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/coplets.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/content_en.html
new file mode 100644
index 0000000..560a82d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/content_en.html
@@ -0,0 +1,427 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Portal: Event Handling</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Overview</h1>
+   
+<p>
+     This document gives an overview of the event handling of the portal engine.
+   </p>
+   
+<p>
+     The sample portal that comes with the Cocoon distribution contains several
+     working samples for event handling.
+   </p>
+  
+  
+<h1>Introduction</h1>
+    
+<p>
+      The event handling is a central mechanism used in the portal engine. Every
+      change (changes in status or layout, links etc) is propagated through an
+      event. The portal uses the publisher/subscribe paradigm, so each component
+      that is interested in a specific event can subscribe itself for this type
+      of event. In addition each component can send out events.
+    </p>
+    
+<p>
+      The processing of a portal request (a request send to the Cocoon portal)
+      is divided into two phases: event handling and rendering. In the first phase
+      all events are processed. For example if the user clicks a link this
+      triggers an event that is published. Any receiver of this event might
+      in turn fire new events that are published as well.
+    </p>
+    
+<p>
+      When all events are processed, the first phase is finished and the second
+      phase, the rendering, is started. At this point of time all event handling
+      and all information exchange should be finished.
+    </p>
+  
+  
+<h1>Events and the request/response cycle</h1>
+    
+<p>
+      In the Portal, an event is represented by a Java object. This event object
+      contains all necessary information to process the event. So, in most cases an
+      event contains the object to modify, what to modify and the value to set.
+      For example, the minimize event for minimizing a coplet, contains the
+      coplet, the information to change the window state and the value "minimize" 
+      to set.
+    </p>
+    
+<p>
+      There are different types of events: a type for changing the window state,
+      a type for removing a coplet, a type for links that are clicked by the user etc.
+      Each event type is represented by a Java class (or interface).
+    </p>
+    
+<p>
+      A component that processes for example the window state request is subscribed 
+      to this minimize event (or: the corresponding class/interface)
+      and when such an event is fired, it changes the window state of the
+      coplet to minimize. Every data this component needs is stored in
+      the event. This is a very important detail: the event is not directly processed
+      (in this case) by the object that is changed (the coplet) but by a central
+      subscribed component that changes the coplet. This is because of the
+      publisher/subscribe mechanism used: many components in the portal can subscribe
+      to the same event type if they are interested. So, each component that is
+      interested in an event needs all information about this event. That's why
+      all data is stored in the event itself.
+    </p>
+    
+<p>
+      Let's have a look how such an event is created:
+    </p>
+    
+<pre class="code">
+Event event;
+event = new ChangeCopletInstanceAspectDataEvent(
+            copletInstanceData,
+            "size", 
+            SizingStatus.STATUS_MINIMIZEDD);
+    </pre>
+    
+<p>
+      
+<em>Event</em> is just a marker interface, the concrete implementation
+      <em>ChangeCopletInstanceAspectDataEvent</em> implements this interface
+      and requires three pieces of information: the CopletInstanceData,
+      the information about what to change (size) and the new value.
+    </p>
+    
+<p>
+      All events must implement the marker interface <em>Event</em>, so if
+      a component is interested in all Events it could subscribe itself
+      using this event type.
+    </p>
+    
+<p>
+      If you want to fire an event, you have to publish it. Therefore you
+      need the event manager, a central portal component. You can lookup this
+      component, fire the event and release the manager again. If you fire
+      the event, the event is directly published to all subscribed components.
+    </p>
+    
+<pre class="code">
+EventManager manager = null;
+try {
+    manager = serviceManager.lookup(EventManager.ROLE);
+    manager.getPublisher().publish(event);
+} finally {
+    serviceManager.release(manager);
+}
+    </pre>
+    
+<p>
+      As noted above, the event will be directly fired. But usually in a portal
+      application, events are not fired directly but are invoked by some user
+      action. This means, the user clicks on a link in the browser, the
+      request is targetted at Cocoon and the portal invokes (fires) the correct events.
+    </p>
+    
+<p>
+      For this, a link (or a form action) must know, which event it should
+      fire, if it is clicked. So, in other words, a link is associated with
+      a concrete event. But on the other site, an event is a Java object and we can only use
+      strings in URLs. So how does this work?
+    </p>
+    
+<p>
+      The part of the portal that generates the link, creates the event object
+      with all necessary data, transforms this event into a usable URI and this
+      URI is the target of the link. When the user clicks on this link, the portal
+      transforms the URI back into the Java event object and fires the event.
+    </p>
+    
+<p>
+      The transformation Event-&gt;URI-&gt;Event is done by another portal component,
+      the link service. Most portal components (apart from the event manager)
+      are available through another central component, the portal service. So
+      you need to have access to the portal service component. (Renderers e.g.
+      don't have to lookup the service by itself, they get it as a method
+      parameter).
+    </p>
+    
+<pre class="code">
+PortalService service = null;
+try {
+    service = serviceManager.lookup(PortalService.ROLE);
+    LinkService ls = service.getComponentManager().getLinkService();
+
+    String uri = getLinkURI( event );
+
+    // create a link that references the uri
+} finally {
+    serviceManager.release(service);
+}
+    </pre>
+    
+<p>
+      That's all you have to do: create the event object, get the link service,
+      transform the event into a URI using the service and then create the
+      (html) link using the URI. Everything else is handled by the portal for you.
+    </p>
+    
+<p>
+      In addition, you can transform several events into one single link. So
+      you can create links, the user can click, that do several things at
+      the same time (minimizing one coplet and maximizing another one etc.).
+      The link service offers corresponding methods for this.
+    </p>
+  
+  
+<h1>Changing the State of a Coplet</h1>
+    
+<p>
+      In most cases you want to change the state of a coplet because the user
+      performed an action. The portal engine provides you with some events
+      that you can directly use.
+    </p>
+    
+<ul>
+      
+<li>CopletJXPathEvent</li>
+      
+<li>ChangeCopletInstanceAspectDataEvent</li>
+    
+</ul>
+    
+<p>
+      The <em>CopletJXPathEvent</em> requires again three pieces of information:
+      the coplet instance data to change, the JXPath expression that defines the
+      data to change and the value:
+    </p>
+    
+<pre class="code">
+Event event = new CopletJXPathEvent(copletInstanceData, 
+                                    "attributes/username", 
+                                    username); 
+    </pre>
+    
+<p>
+      In the previous chapter, we already saw an example of the usage of the
+      <em>ChangeCopletInstanceAspectDataEvent</em>.
+    </p>
+    
+<p>
+      It is of course possible that you write your own events for 
+      changing the state of a coplet. But in this case make sure that
+      your own event implements the interface <em>CopletInstanceEvent</em>.
+      This helps the portal engine in tracking if a coplet has been changed.
+    </p>
+  
+  
+<h1>Subscribing to Events</h1>
+    
+<p>
+      If you are interested in events, you can subscribe to a specific event
+      type. As events are Java objects, you subscribe for all events of a
+      specific interface or class (and all of the subclasses).
+      Subscribing is done using the event manager:
+    </p>
+    
+<pre class="code">
+EventManager manager = null;
+try {
+    manager = serviceManager.lookup(EventManager.ROLE);
+    manager.getRegister().subscribe( myComponent );
+} finally {
+    serviceManager.release(manager);
+}
+    </pre>
+    
+<p>
+      The component you subscribe must implement the Subscriber interface:
+    </p>
+    
+<pre class="code">
+Subscriber interface:
+
+public Class getEventType();
+
+public void inform( Event event );
+    </pre>
+    
+<p>
+      The getEventType() method returns the class/interfaces of the events
+      the component is interested and each time such an event occurs,
+      the inform() method is invoked.
+    </p>
+    
+<p>
+      For example one central component in the portal subscribes for
+      all events dealing with coplets, so it returns <em>CopletInstanceEvent</em>
+      as the class (interface) in getEventType().
+    </p>
+  
+  
+<h1>Inter Coplet Communication</h1>
+    
+<p>
+      A very interesting feature of the portal is inter-coplet communication.
+      The demo portal already has a simple sample where the name of an
+      image selected in an image gallery is transfered to a different coplet.
+    </p>
+    
+<p>
+      Now, there is only one (minor) problem: in the cocoon portal coplets 
+      (or more precisly CopletInstanceData objects) are not components but
+      just data objects. So, a coplet can't directly register itself as 
+      a subcriber for events. 
+    </p>
+    
+<p>
+      Remember that we mentioned earlier on a central component that processes 
+      the change events for coplets? So, this is basically one possibility: if
+      you want to pass information from one coplet to another one, create
+      a CopletJXPathEvent and pass the information to the other coplet.
+    </p>
+    
+<p>
+      Imagine a form coplet where the user can enter a city. When this form is
+      processed by the form coplet, it can generate one (or more) CopletJXPathEvents
+      and push the entered city information to a weather coplet and a hotel guide
+      coplet. So, these two coplets display the information about the selected
+      city.
+    </p>
+  
+  
+<h1>The Coplet Transformer</h1>
+    
+<p>
+      Apart from the possibility to create events from within your Java code,
+      it's also possible to create events from within a pipeline by using
+      for example the coplet transformer. It listens for elements with the
+      namespace "http://apache.org/cocoon/portal/coplet/1.0".
+    </p>
+    
+<h2>The coplet element</h2>
+<p>
+        The coplet element has nothing to do with events :) It can be used
+        to include information about the current coplet in the SAX stream:
+      </p>
+<pre class="code">
+...
+  &lt;coplet:coplet select="attributes/name"/&gt;
+...
+      </pre>
+<p>
+        The coplet element can only be used inside a coplet pipeline, but
+        not in the main portal pipeline. The select attribute defines an
+        JXPath expression that is used to fetch the value that is included
+        in the stream.
+      </p>
+    
+<h2>The link element</h2>
+<p>
+        The link element creates a link that will trigger an event if the 
+        user clicks this link:
+      </p>
+<pre class="code">
+...
+  &lt;coplet:link coplet="COPLET_ID" path="JXPATH" value="TO_SET"/&gt;
+  &lt;coplet:link layout="LAYOUT_ID" path="JXPATH" value="TO_SET"/&gt;
+...
+      </pre>
+<p>
+        This element generates an HTML link which will eiter trigger an
+        event to change a coplet instance data or a layout based on
+        the JXPath and the value provided.
+      </p>
+  
+  
+<h1>Configuring Subscribers</h1>
+    
+<p>
+      In the previous chapters we saw one possibility to subscribe: dynamically
+      in some Java code. This requires that - of course - this code is executed
+      at some point of time. This is a solution for dynamic subscribers, which
+      means a subscriber that is only "available" if a specific feature of 
+      the portal is used. If the feature is available, the "feature" subscribes
+      itself (or another component).
+    </p>
+    
+<p>
+      However, this adds an exta burdon to the development of own events and
+      their subscribers. Therefore it is possible to configure subscribers
+      in the cocoon.xconf. These subscribers are instantiated by the
+      portal engine on startup of Cocoon and subscribed by the portal
+      engine.
+    </p>
+    
+<p>
+      You have two possibilites, you can either subscribe Avalon components or
+      classes. In the first case, you configure the role of the component.
+      Then the portal engine looks up this component and subscribes it.
+    </p>
+    
+<p>
+      If you configure a class, the portal engine creates an instance of this
+      class using the no-argument constructor and subscribes this instance.
+      For convenience, this instance can implement the Avalon lifecycle
+      interface like LogEnabled or Serviceable.
+    </p>
+    
+<p>
+      The configuration takes place in the cocoon.xconf as a configuration for
+      the event manager:
+    </p>
+    
+<pre class="code">
+...
+ &lt;component class="org.apache.cocoon.portal.event.impl.DefaultEventManager" 
+            logger="portal" 
+            role="org.apache.cocoon.portal.event.EventManager"&gt;
+    ...
+    &lt;!-- add a new instance of each class as a subscriber: --&gt;
+    &lt;subscriber-classes&gt;
+        &lt;class name="org.apache.cocoon.portal.event.subscriber.impl.DefaultJXPathEventSubscriber"/&gt;
+    &lt;/subscriber-classes&gt;
+    &lt;!-- add each component as a subscriber (the component should be thread safe): --&gt;
+    &lt;subscriber-roles&gt;
+        &lt;role name="org.apache.cocoon.portal.samples.location.LocationEventSubscriber"/&gt;
+    &lt;/subscriber-roles&gt;
+ &lt;/component&gt;
+...
+    </pre>
+    
+<p>
+      In the sample configuration above, one class is subscribed (the
+      <em>DefaultJXPathEventSubscriber</em>) and one Avalon component
+      (the <em>LocationEventSubscriber</em>).
+    </p>
+    
+<p>
+      So, if you write your own events and your own subscribers you can either dynamically
+      add them during execution or statically add them by configuration as shown above.
+    </p>
+  
+  
+<h1>Further Information</h1>
+    
+<p>
+      The event.impl package contains all currently processed events, so you can
+      study the events and see how to create them. In general most events are
+      created inside the renderers, especially the renderer aspects that render
+      specific details (e.g. the sizing buttons for a coplet). So, you can have
+      a look at the code as well.
+    </p>
+    
+<p>
+      There are several transformers that help in creating events inside a Cocoon
+      pipeline. For example the <em>coplet transformer</em> can be used to
+      create links that contain events to change the status of a coplet or a layout   
+      object. The gallery sample uses this transformer as a demo.
+    </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/meta.xml
new file mode 100644
index 0000000..5c0ead7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-events/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/events.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/content_en.html
new file mode 100644
index 0000000..d591af1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/content_en.html
@@ -0,0 +1,288 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Portal: Using forms</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Overview</h1>
+   
+<p>This document gives an overview over how to use forms within the portal engine.
+   </p>
+   
+<p>
+     The sample portal that comes with the Cocoon distribution contains a working sample
+     for form handling. 
+   </p>
+  
+  
+<h1>Including Applications</h1>
+    
+<p>
+     The portal allows to include a complete web application (with forms, links etc.)
+     that is build with Cocoon. Therefore it's possible to develop the forms
+     like you usually do with Cocoon without thinking about the portal. When you
+     are finished just include this application into the portal as a coplet.
+     The following shows you how to configure such an application as a coplet.
+    </p>
+    
+<p>
+      For including complete applications, the portal offers a specific coplet adapter,
+      the caching URI adapter. This is configured as the coplet base type: <em>CachingURICoplet</em>.
+      So each coplet you configure has to use this base type.
+    </p>
+    
+<p>
+      For each application you have to configure a coplet data object in the profile:
+    </p>
+    
+<pre class="code">
+...
+   &lt;coplet-data id="app-test-two" name="standard"&gt;
+      &lt;title&gt;Application Test&lt;/title&gt;
+      &lt;coplet-base-data&gt;CachingURICoplet&lt;/coplet-base-data&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;buffer&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" 
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+            true
+        &lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;handleParameters&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" 
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+             true
+        &lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" 
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+            cocoon:/coplets/html/application
+        &lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;temporary:application-uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" 
+               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
+            cocoon://samples/flow/jxcalc/
+        &lt;/value&gt;
+      &lt;/attribute&gt;
+   &lt;/coplet-data&gt;
+...
+    </pre>
+    
+<p>
+      As usual, the coplet data gets a unique id, a title and in this case the reference 
+      to the <em>CachingURICoplet</em>. In addition the <em>buffer</em> attribute is used
+      to buffer the output of the coplet which avoids broken responses in the case of a
+      malformed stream comming from the included application.
+    </p>
+    
+<p>
+      The <em>handleParameters</em> attribute has to be set to <em>true</em> as well, as 
+      the application has to handle it's own request parameters (for links or forms).
+    </p>
+    
+<p>
+      The <em>uri</em> attribute points to a Cocoon pipeline that will include your
+      application. This is not the pipeline of your application itself. The starting
+      URI for your application has to be configured using the attribute 
+      <em>temporary:application-uri</em>.
+    </p>
+    
+<p>
+      With this configuration you can configure instances of the coplet for each
+      user. In addition a user can have several instances of the same application.
+      If you look at the provided samples, you see two instances of a flow example
+      and two instances of a forms sample at the same time for each user.
+    </p>
+    
+<p>
+      However, if you allow several instances per user of the same application,
+      this application has to be developed with this aspect in mind. More about
+      this topic later on.
+    </p>
+    
+<p>
+      So, basically this is all you have to do. Develop your application standalone
+      without the example and include it as outlined above. You can for example
+      invoke the sample above (cocoon://samples/flow/jxcalc/) directly without the
+      portal.
+    </p>
+  
+  
+<h1>Building forms</h1>
+    
+<p>
+      In this chapter we demonstrate using a sample how to build forms that can
+      be used within the portal. We will use Cocoon flow to define the logic for
+      the form, but for your own form you can of course use a different approach
+      as well. If you want to have complex forms, you can also use Cocoon forms
+      (Woody), but you have to be careful with correctly using JavaScript on
+      the client, which means you have to add the JavaScript to the response in
+      the main portal pipeline and not by the form itself. Or you avoid using
+      JavaScript on the client :)
+    </p>
+    
+<p>
+      As outlined in the previous chapter, you can define your form handling application
+      without taking care about the portal, so let's start developing it.
+    </p>
+    
+<h2>A Sample</h2>
+<p>
+        We will use flow for the logic. Each time the application is invoked, the same
+        URI is used; this URI calls a flow function. Inside this function we check
+        whether we have to display the form or a different (result) page.
+        So our sitemap looks like this:
+      </p>
+<pre class="code">
+...
+      &lt;map:match pattern="form"&gt;
+        &lt;map:call function="form"/&gt;
+      &lt;/map:match&gt;
+...
+    </pre>
+<p>
+        We have one single function in the flow, that checks if a session
+        attribute already contains a value or not. If no value is stored
+        in the session, this means that either the form has to be displayed
+        or the user just submitted some values. So we have to distinguish these
+        two cases as well:
+      </p>
+<pre class="code">
+...
+function form() {
+    // is the value stored in the session?
+    if ( cocoon.session.getAttribute("form") == null ) {
+        // No: is this a submit?
+        var name = cocoon.request.getParameter("name");
+        if ( name == null ) {
+            // No: display the form
+            cocoon.sendPage("page/form", {});
+        } else {
+            // It's a submit, so process the value
+            cocoon.session.setAttribute("form", name);
+            cocoon.sendPage("page/received", {"name" : name});         
+        }
+    } else {
+        // just display the value
+        var name = cocoon.session.getAttribute("form");
+        cocoon.sendPage("page/content", {"name" : name});         
+    }
+}...
+      </pre>
+<p>
+        This schema allows to use the same pipeline for all purposes. However,
+        if you want a different design, you could e.g. use a different pipeline
+        for processing the form data etc.
+      </p>
+<p>
+        In each case, the view is called which is a Cocoon pipeline. For
+        example the pipeline for the form reads an XML document that looks like
+        this:
+      </p>
+<pre class="code">
+...
+&lt;page&gt;
+    &lt;title&gt;Form&lt;/title&gt;
+    &lt;content&gt;
+      &lt;form method="post" action="form"&gt;
+        &lt;para&gt;Please enter your &lt;strong&gt;name&lt;/strong&gt;: &lt;input type="text" name="name"/&gt;&lt;/para&gt;
+        &lt;input type="submit" name="submit" value="Enter"/&gt;
+      &lt;/form&gt;
+    &lt;/content&gt;
+&lt;/page&gt;
+}...
+      </pre>
+<p>
+        As already pointed out, you develop your application like you would do without
+        the portal. Note in the sample above that the target of the form is the
+        <em>form</em> pipeline, containing the call to the flow.
+      </p>
+<p>
+        So, how does this work? Each link (or target of a form action) is rewritten
+        by the portal engine. The link is transformed into an event. When now the
+        user activates such a link (or form) the event is send to the portal and
+        the portal updates the URI to call for the portlet. The <em>portal-html-eventlink</em>
+        transformer does the rewriting of all links and forms in combination
+        with the <em>portal-coplet</em> transformer that is one of the last
+        transformers in the main portal pipeline.
+      </p>
+<p>
+        Each application portlet that isn't changed during this single request/response
+        cycle, isn't "activated" which means the corresponding application pipeline
+        is not called.
+      </p>
+<p>
+        The portal caches the response of an application and serves the coplet out
+        of the cache until an action for this coplet is triggered.
+      </p>
+    
+<h2>Several instances of an application</h2>
+<p>
+        If you allow the user to have several instances of the same application,
+        the application has to be aware of this fact. Imagine that each instance
+        should have its own data set, but as the user is the same, the session
+        is shared by the instances. So, a unique identifier for each instance
+        is required.
+      </p>
+<p>
+        The portal framework already supplies this identifier and passes it
+        as a request parameter to the pipeline of your application. The name
+        of the parameter is <em>copletid</em> and the value is the unique id.
+        In our sample, we pass this identifier to the flow script using an
+        input module:
+      </p>
+<pre class="code">
+...
+      &lt;map:match pattern="form"&gt;
+        &lt;map:call function="form"&gt;
+          &lt;map:parameter name="copletId" value="{request-param:copletid}"/&gt;
+        &lt;/map:call&gt;
+      &lt;/map:match&gt;
+...
+      </pre>
+<p>
+        In the flow script, we can now use this identifier to calculate a unique
+        session key to store the information:
+      </p>
+<pre class="code">
+    // get the coplet id
+    var cid = cocoon.parameters["copletId"];
+    var key = cid + "/myform";
+      </pre>
+<p>
+        From now on you can use this key to get/store session attributes etc. In
+        addition you can use all features available to flow, like looking up
+        components and using them.
+      </p>
+    
+<h2>Extending the Sample</h2>
+<p>
+        Although the sample is very simple (or more precisly the form is very simple)
+        it demonstrates a possible way to build coplets that handle forms. You can
+        use this as a guideline for your own forms.
+      </p>
+<p>
+        If you need, e.g. validation of the form, you can simply add the validation
+        in the flow script and return a corresponding view in the case of a
+        validation error. If you need a more complex processing, e.g. sending an
+        email, you can simply add this in the flow script as well. Or you can
+        code the logic into a Java class and call this class from the flow script.
+      </p>
+<p>
+        In addition, you can use Cocoon forms with all the nice features (widgets,
+        validation, binding etc.) as well. You only have to provide a working set
+        of stylesheets that work in the portal.
+      </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/meta.xml
new file mode 100644
index 0000000..6411c30
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-forms/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/forms.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/content_en.html
new file mode 100644
index 0000000..c3d37bc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/content_en.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Webapps Developer Documentation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+ 
+<p>This section contains several documents about developing a portal with Cocoon.</p>
+ 
+<p>The <a href="../webapps/portal.html">portal framework</a> is a stable
+   portal framework that uses the authentication framework. It can
+   be used to quickly develop portal applications.</p> 
+
+<p>The new <a href="portal-block.html">portal engine</a> is a new
+  implementation of a portal engine which focuses on more flexibility
+  and ease-of-use. In addition it supports the JSR-168. The current state of 
+  this engine is <em>alpha</em> which means that the engine can still change 
+  in some aspects.</p>
+
+ 
+  
+<h1>Features</h1>
+  
+<p>The portal framework is a portal server that runs inside Cocoon - or to be more 
+     precise inside the Cocoon servlet. It contains a portlet container that is
+     called coplet container. Coplet stands for <em>Cocoon Portlet</em> and is the 
+     Cocoon equivalent to portlet.</p>
+  
+<p>Due to the highly extensible nature of Cocoon, the portal is configurable and 
+     extensible as well and provides many hooks and switches to easily adapt the 
+     portal for specific needs. As the portal is integrated in Cocoon it has the 
+     advantage that all features of Cocoon can easily be used. Cocoon is very strong 
+     in fetching data from various source and delivering it in the various output formats 
+     requested by different clients (like HTML, WML, PDF etc.).</p>
+  
+<p>With the latest features, like the form handling framework, the authentication framework
+     and the flow concept, it is very easy to develop and maintain complex applications with 
+     Cocoon. And these applications can in turn be viewed as portlets inside a portal. 
+     But even by just using the flexible pipeline concept from Cocoon it's possible to 
+     develop complex and nice looking portals.</p>
+  
+<p>The portal view is described by an XML document. This document contains the layout and 
+     the ordering of the selected portlets. The layout is a tree-like structure, it can for 
+     example contain rows, columns or tabs in any ordering or nesting. This allows the 
+     description of the portal view in a parent-child relationship. Even complex layouts 
+     with portlets spanning several columns or tabs inside a single column are possible.</p>
+  
+<p>For each portlet a placeholder is defined in the XML document. Special components, 
+     so called renderers, are used to generate (or render) the portal view. Each layout object 
+     (each row, column etc.) has an configurable renderer associated that generates the output 
+     of the portal for this layout object. For example a renderer for a row could create the 
+     required HTML tags.</p>
+  
+<p>The renderers can either directly generate the required format (like HTML) or they can 
+     create an XML document that is later transformed by Cocoon to the format requested by 
+     the client using a stylesheet. This depends on the requirements of the application and 
+     how it is developed. The output of all involved renderers is aggregated and this creates 
+     the (layout) document for the portal view.</p>
+  
+<p>After the layout is rendered, the placeholders for the different portlets are replaced 
+     with the content from the portlets. Therefore the portlet container is asked to deliver 
+     the content of a given portlet and this content is inserted at the correct places 
+     in the portal view.</p>
+  
+<p>In Cocoon a portlet can have different types:</p>
+  
+<ul>
+    
+<li>Static: Reading a static file, like an HTML document or a PDF file</li>
+    
+<li>URI: Reads information using a URI</li>
+    
+<li>Pipeline: Uses the Cocoon pipelining concept to dynamically generate the content</li>
+    
+<li>Custom Types: If the need arises, it's possible to develop a custom type and use it.</li>
+  
+</ul>
+  
+<p>In Cocoon, the use of the pipeline type is possibly the most common one right now.</p>
+  
+<p>The complete configuration (the portal view, the available portlets, their settings) is done 
+     using XML documents. So it is possible to develop a portal application by just changing the 
+     configuration without any Java coding. However if the need arises nearly any part of the 
+     portal can be changed/extended by writing an additional component (in Java) and plugging it 
+     into the portal engine (by configuration). For example, one component - the profile 
+     manager - is responsible for getting the profile of the current user (the user associated 
+     to the current request). A profile contains the portal view (layout, ordering etc.) and the configuration of the 
+     different portlets for this user.</p>
+  
+<p>There is one implementation that reads this profile from any database accessible from 
+     Cocoon on a per user base. The profile can for example be stored in a database, on a 
+     file system or in a WebDAV repository. Therefore every user has their own portal view 
+     and can customize this to their needs. Another implementation is more <em>static</em>. 
+     This means every user gets the same layout and the same portlets. So in fact the portal 
+     can be used for web pages that have a portal like structure but don't have any 
+     personalization at all.</p>
+  
+<p>All changes that may occur inside a portal are propagated through a flexible event management.
+     The event handling follows the usual publisher/subscribe pattern. A component, for example a 
+     portlet, that is interested in a special event can subscribe for all events of this kind. 
+     The component is notified when such an event occurs and can react on this event by changing 
+     its status, sending new events or whatever is appropriate.</p>
+  
+<p>This event handling is for example used to change preferences, to change the portal profile 
+      or to change the status of a portlet. For example, events can be sent to add a new portlet 
+      to the portal view or to minimize a portlet. In addition this event handling can be used 
+      for communication between portlets. Imagine a portlet where the user chooses a city he wants 
+      to travel to. This selection is broadcast to other portlets using the event handling. Another 
+      portlet, displaying the current weather information of a city, receives this event and displays 
+      the weather information for the city selected in a different portlet. This is a very simple 
+      example for inter portlet communication but it shows the potential.</p>
+  
+<p>As Cocoon and therefore the portal as well is based on the request response cycle, a request 
+     for displaying the portal view triggers two tasks that are executed one after the other. 
+     The first task is the event handling phase. In this phase all events that are triggered by the 
+     request are processed and published. For example if the user clicks on the minimize button of 
+     a portlet, a request is sent to Cocoon and a minimize event for the portlet is published 
+     triggering the status change by some receiver of the event.</p>
+  
+<p>This processing of the request information can trigger new events that are published as well and
+     so on. When all events are published and consumed, the second task is executed that actually 
+     renders the portal view as described above. And the portal view is sent as a response back to 
+     the client. On the client the user can navigate through the portal and trigger some action like 
+     minimizing, enlarging a single portlet to a full screen mode temporarily hiding the other 
+     portlets and so on.</p>
+  
+<p>Some installations of the Cocoon portal are going far beyond these usual use cases. They use 
+     the included components for example to create a view to a complete web application running on 
+     a different server. One single portlet shows the application and a click/action in this portlet 
+     triggers a request to Cocoon that is forwarded to the distant application and the new <em>state</em>
+     of the application is then displayed in the portlet again.</p>
+  
+<p>But by using Cocoon this can even go further: stylesheets can be used to change the layout 
+     of the integrated application. So you can give an application a totally different lock and feel 
+     using a portlet.</p>
+  
+<p>And - of course - SoC (separation of concerns) applies to developing portals with Cocoon as
+     well, so you can develop your portal in groups each group concentrating on their concern.</p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/meta.xml
new file mode 100644
index 0000000..4afdcab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-index/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/content_en.html
new file mode 100644
index 0000000..b0f0fbc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/content_en.html
@@ -0,0 +1,596 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configuring the Cocoon Portal</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Joel Greenyer" name="DC.Creator">
+<meta content="
+        This document describes the use and configuration 
+        of the (new) cocoon portal block.
+    " name="DC.Description">
+</head>
+<body> 
+    
+<h1>Introducing the Cocoon Portal</h1>
+      
+<p>
+        This document describes the use and configuration 
+        of the (new) cocoon portal that you can find in the "portal" block.
+        (Don't mix this with the older portal version that you can
+        find in the "portal-fw" block.)
+      </p>
+      
+<h2>Important parts of the Cocoon Portal</h2>
+<p>TBD
+        </p>
+      
+<h2>How is a portal page created by Cocoon?</h2>
+<p>TBD
+        </p>
+      
+<h2>I want to build my own portal! An approach</h2>
+<p>TBD
+        </p>
+    
+
+    
+<h1>Configuring the Portal contents</h1>
+      
+<p>
+        The configuration of a coplet is done in several steps that are outlined
+        in the next chapters.
+      </p>
+      
+<h2>Configuring Coplets</h2>
+<p>
+          Configuring coplets is like defining a class and creating their instances.
+          So in fact, you define the available coplets (= classes) and each portal
+          view gets some instances of these coplets. 
+        </p>
+<h3>Available Coplet Types</h3>
+<p>
+          Before you can define your available coplets, you have to define the
+          available coplet types, or the so called coplet base data. The current
+          sample contains an XML document for this:
+          </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-base-data id="URICoplet"&gt;
+      &lt;coplet-adapter&gt;uri&lt;/coplet-adapter&gt;
+   &lt;/coplet-base-data&gt;
+&lt;/coplets&gt;
+...
+          </pre>
+<p>In the example above, we define one coplet type, the <em>URICoplet</em>,
+             that uses the <em>uri coplet adapter</em>. By this we define a type,
+             that uses URIs to get the content of a coplet.</p>
+<p>You can add different coplet types with additional configuration here,
+             but rarely have to touch this file.</p>
+<h3>Available Coplets</h3>
+<p>
+          Based on the coplet types, you can define the available coplets in your
+          portal application (= classes). In the example portal an own configuration
+          file contains these so called coplet datas. Here is an excerpt:
+          </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-data id="CZ Weblog" name="standard"&gt;
+      &lt;title&gt;CZ's Weblog&lt;/title&gt;
+      &lt;coplet-base-data&gt;URICoplet&lt;/coplet-base-data&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;cocoon:/news/liverss?feed=http://radio.weblogs.com/0107211/rss.xml&lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;buffer&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.Boolean" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;true&lt;/value&gt;
+      &lt;/attribute&gt;
+      &lt;attribute&gt;
+      	&lt;name&gt;error-uri&lt;/name&gt;
+      	&lt;value xsi:type="java:java.lang.String" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;cocoon:/news/CZ_weblog.rss&lt;/value&gt;
+      &lt;/attribute&gt;
+   &lt;/coplet-data&gt;
+&lt;/coplets&gt;
+...
+          </pre>
+<p>Each coplet data contains a unique id and additional configuration. A required
+          configuration is the underlying coplet base data. In the example above,
+          the <em>URICoplet</em> is used here.
+          </p>
+<p>The above configured coplet data requires some configuration, like the
+          URI to invoke to fetch the content for this coplet. This configuration is
+          passed in the different attributes you see above. Each attribute has
+          a name and value.
+          </p>
+<p>The set of coplet datas defines the set of available coplets a user can
+          choose from. If a user chooses to view a coplet, an instance of this coplet
+          data is created. If, e.g. the user chooses the same coplet twice,
+          two instances are created. This is useful for configurable coplets where
+          the user can choose the same coplet with different configurations.
+          </p>
+<h3>Selected Coplets</h3>
+<p>
+          The selected coplets are described by the set of coplet instance datas.
+          </p>
+<pre class="code">
+...
+&lt;coplets&gt;
+   &lt;coplet-instance-data id="CZ Weblog-1" name="standard"&gt;
+      &lt;coplet-data&gt;CZ Weblog&lt;/coplet-data&gt;
+   &lt;/coplet-instance-data&gt;
+&lt;/coplets&gt;
+...
+          </pre>
+<p>
+          The coplet instance data refers to its coplet data by specifying the
+          unique ID. The instance itself has a unique ID as well that is referenced
+          from the portal view.
+          </p>
+<p>
+          In addition, a coplet instance data could have own configuration information.
+          </p>
+      
+<h2>Configuring the arrangement of the defined Coplets</h2>
+<p>
+        The portal view defines the ordering and arrangement of the coplets. This
+        view is defined in a hierarchical manner by nesting layout objects. At
+        each place, a coplet is located, a reference to a coplet instance data
+        is included.
+        </p>
+<p>
+        The Cocoon portal provides several predefined layout elements you can use
+        for your portal view to create a nice layout:
+        </p>
+<ul>
+          
+<li>row - a row of items</li>
+          
+<li>column - a column of items</li>
+          
+<li>tab - a tab</li>
+        
+</ul>
+<p>
+        These are the "high-level" objects, you can use to define your
+        structure. You can nest them in any order to create a complex
+        layout. The layout is defined in an XML document as well, so let's
+        have a look at an example:
+        </p>
+<pre class="code">
+...
+&lt;composite-layout name="row"&gt;
+  &lt;item&gt;
+    &lt;coplet-layout name="coplet"&gt;
+      &lt;coplet-instance-data&gt;Portal-Intro-1&lt;/coplet-instance-data&gt;
+    &lt;/coplet-layout&gt;
+  &lt;/item&gt;
+  &lt;item&gt;
+    &lt;coplet-layout name="coplet"&gt;
+      &lt;coplet-instance-data&gt;Portal-Bottom-1&lt;/coplet-instance-data&gt;
+    &lt;/coplet-layout&gt;
+  &lt;/item&gt;
+&lt;/composite-layout&gt;
+...
+        </pre>
+<p>
+        In the example above, we define a row containing two coplets. This is done
+        by selecting the row layout and defining the childs (or items) of this
+        layout. In this case the items are two new layout objects, the coplet
+        layouts that can contain a coplet. The coplet layout has a reference
+        to the coplet instance data.
+        </p>
+      
+<h2>The Rendering Process</h2>
+<p>
+        Each layout object has a defined renderer that is used to render this
+        layout object. You can find the renderers in the cocoon.xconf. Each renderer
+        has a unique name that is used to identify this renderer.
+        </p>
+<p>
+        A central component, the layout factory (configured in the cocoon.xconf as
+        well), contains a list of all available layout objects, like the row,
+        the column etc. The configuration for each layout object contains also
+        the corresponding renderer information. So, here is the configuration
+        which renderer will be used to render the layout object.
+        </p>
+<p>
+        A renderer itself can be configured in various ways. The portal engine uses
+        so called aspects (don't mess them with AOP), that are used to enhance
+        to features of renderer, allowing - simplifying - a multiple inheritance
+        which is not possible in Java. Have a look at the cocoon.xconf for
+        the different renderer configurations.
+        </p>
+    
+
+    
+<h1>Create a new skin for your portal</h1>
+        
+<p>This section will explain the concepts of the portal layout, 
+        considering the <span class="codefrag">skins/basic/</span> skin provided with cocoon, 
+        and will describe how to create a new skin by extending the 
+        existing stylesheets.</p>
+        
+<div class="note">The skin path can be changed in the portal's sitemap. There is 
+        a <span class="codefrag">global-variable</span> specifying the path to the skin folder.</div>
+          
+<p>The basic cocoon portal skin    is a nice and simple example how to visualize a portal. 
+          There are several elements that allow to customize the look and feel of the portal.
+          A portal with the basic skin consists of </p>
+          
+<ul>
+              
+<li>a <em>header</em>
+</li>
+              
+<li>a <em>tab row</em>
+</li>
+              
+<li>a <em>content section</em> containing the coplet windows</li>
+              
+<li>and a <em>footer </em>
+</li>
+          
+</ul>
+        
+<div align="center">
+<img class="figure" alt="Parts of the portal" src="images/portal-parts.gif" height="300" width="400"></div>    
+        
+<p>The tab row is actually a part of the content section. As well, a tab row can
+        be provided to any coplet window.</p>
+          
+<h2>The skin's stylesheets</h2>
+<p>If we take a look at the <span class="codefrag">skins/basic/styles</span> directory, we 
+              find a number of stylesheets:
+              </p>
+<ul>
+                  
+<li>
+<span class="codefrag">portal-page.xsl</span>: Creates final HTML page</li>
+                  
+<li>
+<span class="codefrag">tab.xsl</span>: layout of the tab row.</li>
+                  
+<li>
+<span class="codefrag">window.xsl</span>: coplet window layout</li>
+                  
+<li>
+<span class="codefrag">column.xsl</span>: layout of a column</li>
+                  
+<li>
+<span class="codefrag">row.xsl</span>: layout of a row</li>
+                  
+<li>
+<span class="codefrag">login-page.xsl</span>: layout of the login page</li>
+              
+</ul>
+<p>The <span class="codefrag">window.xsl</span> stylesheet determines the layout of a
+              coplet window. Normally, a coplet window will contain a header row with a
+              title and buttons like minimize, close, etc.</p>
+<p>These coplet windows are arranged in rows and columns to create
+              the arrangement typical for portals. There can be several rows per column
+              and several columns in the content section. So the thinking is a little
+              different than in usual HTML tables.</p>
+<p>The content section or content row usually has a tab row located at the top 
+              and the coplet windows are arranged below. The layout of the tabs is
+              specified in the <span class="codefrag">tab.xsl</span> stylesheet.</p>
+<p>The <span class="codefrag">portal-page.xsl</span> stylesheet encapsulates the content section
+              with the tab row and allows to define a page header and a footer.
+              This is probably the first stylesheet we want to take a closer look at.
+              </p>
+<div class="note">The <span class="codefrag">tab.xsl</span>, <span class="codefrag">column.xsl</span>,
+              <span class="codefrag">row.xsl</span> and <span class="codefrag">window.xsl</span> stylesheets
+              are used by the portal components directly and won't be found 
+              anywhere in the sitemap. The <span class="codefrag">cocoon.xconf</span>
+              defines which stylesheets will be used by the portal.</div>
+              
+<h2>The portal-page.xsl</h2>
+<p>
+                      Here is the place to change the design of the header and footer row. 
+                      This stylesheet is used to construct the final HTML page, which displays
+                      the portal. The code sample here displays the main template match node of the
+                      stylesheet.
+                  </p>
+<pre class="code">
+...
+&lt;xsl:template match="/"&gt;
+&lt;html&gt;
+ &lt;head&gt;
+  &lt;link type="text/css" rel="stylesheet" href="page.css"/&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+  &lt;table bgColor="#ffffff" border="0" 
+  cellPadding="0" cellSpacing="0" width="100%"&gt;
+  &lt;tbody&gt; 
+
+  &lt;!-- header row --&gt;
+  &lt;tr&gt;
+  &lt;td colspan="2"&gt; 
+   &lt;table border="2" cellPadding="0" cellSpacing="0" width="100%"&gt;
+    &lt;tbody&gt; 
+     &lt;tr&gt; 
+      &lt;td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"&gt;
+      &lt;/td&gt;
+     &lt;/tr&gt;
+     &lt;tr&gt; 
+      &lt;td bgcolor="#CCCCCC" height="100" align="center" 
+      valign="middle" width="100%"&gt;
+      &lt;font size="80pt"&gt;Cocoon Portal&lt;/font&gt;
+      &lt;/td&gt;
+     &lt;/tr&gt;
+     &lt;tr&gt; 
+      &lt;td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"&gt;
+      &lt;/td&gt;
+     &lt;/tr&gt;
+    &lt;/tbody&gt;
+   &lt;/table&gt;
+  &lt;/td&gt;
+  &lt;/tr&gt;
+
+  &lt;!-- content/tab row --&gt;
+  &lt;tr&gt;
+  &lt;td&gt;
+   &lt;xsl:apply-templates/&gt;
+  &lt;/td&gt;
+  &lt;/tr&gt;
+  
+  &lt;!-- footer row --&gt;
+  &lt;tr&gt;
+  &lt;td colspan="2"&gt; 
+   &lt;table border="2" cellPadding="0" cellSpacing="0" width="100%"&gt;
+    &lt;tbody&gt; 
+     &lt;tr&gt; 
+      &lt;td colspan="2" noWrap="" height="10" bgcolor="#DDDDDD"&gt;
+       &lt;img height="1" src="sunspotdemoimg-space.gif" width="1"/&gt;
+      &lt;/td&gt;
+     &lt;/tr&gt;
+     &lt;tr&gt; 
+      &lt;td colspan="2" noWrap="" height="30" bgcolor="#CCCCCC"&gt;
+       &lt;img height="1" src="sunspotdemoimg-space.gif" width="1"/&gt;
+      &lt;/td&gt;
+     &lt;/tr&gt;
+    &lt;/tbody&gt;
+   &lt;/table&gt;
+  &lt;/td&gt;
+  &lt;/tr&gt;
+ &lt;/tbody&gt;
+ &lt;/table&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+&lt;/xsl:template&gt;
+...
+            </pre>
+          
+<h2>The tab.xsl</h2>
+<p>From the <span class="codefrag">portal-page.xsl</span> stylesheet, we will now
+              move upwards in the XSL transformation steps and take a look at the
+              stylesheet that was processed before, the <span class="codefrag">tab.xsl</span>.</p>
+<p>Again, this source snippet shows the main template match node of the stylesheet:</p>
+<pre class="code">...
+&lt;!-- Process a tab  --&gt;
+&lt;xsl:template match="tab-layout"&gt;
+&lt;!-- ~~~~~ Begin body table ~~~~~ --&gt;
+&lt;table border="2" cellpadding="0" cellspacing="0" width="100%"&gt;
+ &lt;!-- ~~~~~ Begin tab row ~~~~~ --&gt;
+ &lt;tr&gt;
+ &lt;td&gt;
+ &lt;table summary="tab bar" border="2" cellpadding="0" 
+    cellspacing="0" width="100%"&gt;
+  &lt;tr vAlign="top"&gt;
+   &lt;xsl:for-each select="named-item"&gt;
+    &lt;xsl:choose&gt;
+     &lt;xsl:when test="@selected"&gt;
+     &lt;!-- ~~~~~ begin selected tab ~~~~~ --&gt;
+     &lt;td valign="middle" bgcolor="#DDDDDD"&gt;
+      &lt;b&gt;
+       &lt;a href="{@parameter}"&gt;
+        &lt;font color="#000000"&gt;
+         &lt;xsl:value-of select="@name"/&gt;
+        &lt;/font&gt;
+       &lt;/a&gt;
+      &lt;/b&gt;
+     &lt;/td&gt;
+     &lt;!-- ~~~~~ end selected tab ~~~~~ --&gt;
+    &lt;/xsl:when&gt;
+    &lt;xsl:otherwise&gt;
+     &lt;!-- ~~~~~ begin non selected tab ~~~~~ --&gt;
+     &lt;td valign="middle" bgcolor="#CCCCCC" &gt;
+      &lt;div class="tab"&gt;
+       &lt;a href="{@parameter}"&gt;
+        &lt;xsl:value-of select="@name"/&gt;
+       &lt;/a&gt;
+      &lt;/div&gt;
+     &lt;/td&gt;
+     &lt;!-- ~~~~~ end non selected tab ~~~~~ --&gt;
+    &lt;/xsl:otherwise&gt;
+   &lt;/xsl:choose&gt;
+   &lt;/xsl:for-each&gt;
+   &lt;!-- ~~~~~ last "blank" tab ~~~~~ --&gt;
+    &lt;td width="99%" bgcolor="#CCCCCC" align="right"&gt;
+    &lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;/table&gt;
+  &lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;!-- ~~~~~ End tab row ~~~~~ --&gt;
+
+  &lt;!-- ~~~~~ Begin content row ~~~~~ --&gt;
+  &lt;tr&gt;
+   &lt;td bgcolor="#FFFFFF"&gt;
+    &lt;xsl:apply-templates/&gt;
+   &lt;/td&gt;
+  &lt;/tr&gt;
+  &lt;!-- ~~~~~ End content row ~~~~~ --&gt;
+&lt;/table&gt;
+&lt;/xsl:template&gt;
+...</pre>
+<p>The first row that is created here contains the definition of the tabs. 
+        The <span class="codefrag">&lt;xsl:choose&gt;</span> element differentiates between the
+        currently selected tab and all other tabs. The <span class="codefrag">@selected</span>
+        attribute is generated by the portal and can be accessed as shown
+        above. As well, the portal provides the tab's <span class="codefrag">@parameter</span>
+        (usually the tab's link) and <span class="codefrag">@name</span> attributes. </p>
+<div class="note">Depending on the configuration of the portal, it is possible
+        that tabbed areas are nested inside each other. So be careful how a tab
+        row might look in the middle of another content section.</div>
+<p>Nice looking tabs can become pretty complex, take a look at the 
+        <span class="codefrag">tab.xml</span> stylesheet in the <span class="codefrag">skins/common/</span>
+        skin to see another example.</p>
+<p>Below the tabs, another table cell is defined that will be filled 
+        with the contents of the tabbed area. This content will have been processed
+        by the <span class="codefrag">columns.xsl</span> stylesheet before - and before that by the 
+        <span class="codefrag">row.xsl</span> stylesheet.</p>
+      
+<h2>The column.xsl and row.xsl</h2>
+<p>The <span class="codefrag">column.xsl</span> and <span class="codefrag">row.xsl</span> stylesheets
+          define the look of the tables in which the coplet windows will be placed.
+          Usually, nothing exciting happens in these stylesheets. Here is a listing of the
+          important parts, just to give a complete overview.
+          </p>
+<p>The main template match node of the <span class="codefrag">column.xsl</span> stylesheet:</p>
+<pre class="code">...
+&lt;!-- Process a Column  --&gt;
+&lt;xsl:template match="column-layout"&gt;
+ 
+   ...
+ 
+ &lt;table border="{$border}" cellSpacing="0" cellpadding="0" 
+    width="100%"&gt;
+  &lt;xsl:if test="@bgcolor"&gt;
+   &lt;xsl:attribute name="bgcolor"&gt;
+    &lt;xsl:value-of select="@bgcolor" /&gt; 
+   &lt;/xsl:attribute&gt;
+  &lt;/xsl:if&gt;
+  &lt;tr vAlign="top"&gt;
+   &lt;xsl:for-each select="item"&gt;
+    &lt;td&gt;
+     &lt;xsl:if test="@bgcolor"&gt;
+      &lt;xsl:attribute name="bgcolor"&gt;
+       &lt;xsl:value-of select="@bgcolor" /&gt; 
+      &lt;/xsl:attribute&gt;
+     &lt;/xsl:if&gt;
+     &lt;xsl:if test="@width"&gt;
+      &lt;xsl:attribute name="width"&gt;
+       &lt;xsl:value-of select="@width" /&gt; 
+      &lt;/xsl:attribute&gt;
+     &lt;/xsl:if&gt;
+     &lt;xsl:apply-templates /&gt;
+    &lt;/td&gt;
+   &lt;/xsl:for-each&gt;
+  &lt;/tr&gt;
+ &lt;/table&gt;
+&lt;/xsl:template&gt;
+...</pre>
+<p>The main template match node of the <span class="codefrag">row.xsl</span> stylesheet:</p>
+<pre class="code">...
+&lt;!-- Process a row  --&gt;
+&lt;xsl:template match="row-layout"&gt;
+
+   ...
+   
+ &lt;table border="{$border}" cellSpacing="10" width="100%"&gt;
+  &lt;xsl:if test="@bgcolor"&gt;
+   &lt;xsl:attribute name="bgcolor"&gt;
+    &lt;xsl:value-of select="@bgcolor" /&gt; 
+   &lt;/xsl:attribute&gt;
+  &lt;/xsl:if&gt;
+  &lt;xsl:for-each select="item"&gt;
+   &lt;tr vAlign="top"&gt;
+    &lt;xsl:if test="@bgcolor"&gt;
+     &lt;xsl:attribute name="bgcolor"&gt;
+      &lt;xsl:value-of select="@bgcolor" /&gt; 
+     &lt;/xsl:attribute&gt;
+    &lt;/xsl:if&gt;
+    &lt;td&gt;
+     &lt;xsl:apply-templates /&gt;
+    &lt;/td&gt;
+   &lt;/tr&gt;
+  &lt;/xsl:for-each&gt;
+ &lt;/table&gt;
+&lt;/xsl:template&gt;
+...</pre>
+      
+<h2>The window.xsl</h2>
+<p>The <span class="codefrag">window.xsl</span> stylesheet determines the design of the coplet
+          windows and probably takes the most design effort compared to the other stylesheets.
+          A coplet window consists of a table header with the window title and a number
+          of buttons like close, minimize, maximize etc. The basic skin provides some
+          images in the <span class="codefrag">images/</span> subfolder. The rest of the window will
+          be filled with the coplet content, depending on the configuration of
+          the coplet.</p>
+<p>A slightly more complex example can be found in the 
+          <span class="codefrag">skins/common/</span> skin.</p>
+<p>The listing below shows the main template match node:</p>
+<pre class="code">...
+&lt;xsl:template match="window"&gt;
+
+   ...
+ 
+&lt;table border="2" cellSpacing="0" cellpadding="0" width="100%"&gt;
+ &lt;tr vAlign="top"&gt;
+  &lt;td bgColor="{$bgColor}" valign="middle"&gt;
+   &lt;font&gt;
+    &lt;xsl:attribute name="color"&gt;#ffffff&lt;/xsl:attribute&gt;
+    &lt;xsl:attribute name="face"&gt;Arial&lt;/xsl:attribute&gt;
+    &lt;xsl:attribute name="size"&gt;2&lt;/xsl:attribute&gt;    
+    &lt;xsl:choose&gt;
+     &lt;xsl:when test="@title"&gt;
+      &lt;b&gt;&lt;xsl:value-of select="@title"/&gt;&lt;/b&gt;
+     &lt;/xsl:when&gt;
+     &lt;xsl:otherwise&gt;
+      &lt;b&gt;&lt;xsl:value-of select="title"/&gt;&lt;/b&gt;
+     &lt;/xsl:otherwise&gt;
+    &lt;/xsl:choose&gt;    
+   &lt;/font&gt;
+  &lt;/td&gt;
+  &lt;td align="right" bgColor="{$bgColor}"&gt;
+   &lt;xsl:if test="fullscreen-uri"&gt;
+    &lt;a href="{fullscreen-uri}"&gt;
+     &lt;img src="customize.gif" border="0" alt="Full Screen"/&gt;
+    &lt;/a&gt;
+   &lt;/xsl:if&gt;
+   &lt;xsl:if test="maxpage-uri"&gt;
+    &lt;a href="{maxpage-uri}"&gt;
+     &lt;img src="show.gif" border="0" alt="Max Page"/&gt;
+    &lt;/a&gt;
+   &lt;/xsl:if&gt;
+   &lt;xsl:if test="maximize-uri"&gt;
+    &lt;a href="{maximize-uri}"&gt;
+     &lt;img src="maximize.gif" border="0" alt="Maximize"/&gt;
+    &lt;/a&gt;
+   &lt;/xsl:if&gt;
+   &lt;xsl:if test="minimize-uri"&gt;
+    &lt;a href="{minimize-uri}"&gt;
+     &lt;img src="minimize.gif" border="0" alt="Minimize"/&gt;
+    &lt;/a&gt;
+   &lt;/xsl:if&gt;
+   &lt;xsl:if test="remove-uri"&gt;
+    &lt;a href="{remove-uri}"&gt;
+     &lt;img src="delete.gif" border="0" alt="Delete"/&gt;
+    &lt;/a&gt;
+   &lt;/xsl:if&gt;
+  &lt;/td&gt;
+ &lt;/tr&gt;
+  &lt;tr&gt;
+   &lt;td colSpan="2"&gt;
+    &lt;xsl:apply-templates select="content"/&gt;
+   &lt;/td&gt;
+  &lt;/tr&gt;
+&lt;/table&gt;
+&lt;/xsl:template&gt;
+...</pre>
+  
+
+    
+<h1>Further topics</h1>
+      
+<p>
+      
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/meta.xml
new file mode 100644
index 0000000..12139fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-portal-block/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/portal-block.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/content_en.html
new file mode 100644
index 0000000..6b2db9a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/content_en.html
@@ -0,0 +1,154 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configuring Profiles</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Overview</h1>
+   
+<p>
+    This document gives an overview over configuring profiles.
+   </p>
+   
+<p>
+    The portal engine uses a component for managing the profile of the
+    current user. There are different implementations already available.
+    The static profile manager gives ever user the same profile whereas
+    the default profile manager chooses the profile of the user based
+    on the role and the user. In this chapter we describe this mechanism
+    and how it can be configured.
+   </p>
+  
+  
+<h1>Authentication</h1>
+   
+<p>
+    The portal engine uses the authentication framework to authenticate
+    a user. This is the default configuration that is also used in the
+    provided sample. However, the portal is not tied to that framework
+    so whenever the need arises you can implement your own authentication
+    mechanism and use it in the portal.
+   </p>
+   
+<p>
+    When the authentication framework is used for authenticating the user,
+    the profile is selected (or can be selected) on the role the user is in.
+    Therefore the authentication framework has to deliver the role name
+    of the user in the authentication XML (for more information about the
+    authentication, read the <a href="../webapps/authentication.html">authentication framework</a> documentation.)
+   </p>
+   
+<p>
+    The current sample of the portal returns already a role for the registered
+    users (the two roles guest and admin are used).
+   </p>
+  
+  
+<h1>Profile Loading</h1>
+   
+<p>
+    When a user logs into the portal, the profile for this user is loaded
+    and then stored in the session. As explained in the chapters about
+    coplets, the profile of a user consists of several parts: the coplet base
+    data (coplet types), the coplet data (classes), the coplet instance datas
+    (instances) and the layout (ordering of the coplets).
+   </p>
+   
+<p>
+    In the following we describe the default setting of the portal. All
+    profiles are stored as XML files in a distinct directory. However, if
+    you want to store your profiles in a different location, you can
+    configure this location or you can also store the profiles in a 
+    database or any other persistence layer.
+   </p>
+   
+<h2>Coplet Types</h2>
+<p>
+     Each part is described in a different XML configuration file. The coplet
+     base data (coplet types) is a global setting that is not user/role
+     dependent. All other parts can differ based on the current user and his
+     role.
+    </p>
+<p>
+     The default location for this profile is <em>profiles/copletbasedata/portal.xml</em>.
+    </p>  
+   
+<h2>Available Coplets</h2>
+<p>
+     The coplet data (=classes) defines the set of available coplets for the
+     current user. The user can choose any of these coplets in his view.
+     If a user has selected a coplet, an instance of this coplet is created.
+    </p>
+<p>
+     The list of available/allowed coplets is defined in three steps.
+    </p>
+<ol>
+     
+<li>First the global list with coplets for all users is read.</li>
+     
+<li>Then a list with coplets for the current role is read and added 
+       to the global list. This list is optional.</li>
+     
+<li>Finally, a list with coplets for the current user is added
+       to the list. This list is also optional.</li>
+    
+</ol>
+<p>
+     By default all profiles for the coplet data are stored in the directory
+     <em>profiles/copletdata</em>. The global profile has the filename
+     <em>portal.xml</em>. The file name for the different role profiles
+     is <em>portal-role-NAME_OF_ROLE.xml</em>. And the name of the
+     profile for the user is <em>portal-user-USER_NAME.xml</em>.
+    </p>
+<p>
+     In most cases it's sufficient to add the coplets that are available
+     to all users in the global list. In addition you will define some
+     role based profiles for the different roles where you add coplets
+     that are only available for this role, like some administration
+     coplets that are only meant for administrators.
+    </p>
+<p>
+     It is currently not possible to disable a coplet in a role or user
+     profile that has been enabled in the global (or role profile). The
+     reverse isn't possible as well (disabling in global, enabling in
+     role)!
+    </p>  
+   
+<h2>The Portal View</h2>
+<p>
+     The portal view for a user consists of two parts: the select coplets
+     (= the coplet instances) and the layout. The layout defines the ordering
+     and the arrangement of the coplets.
+    </p>
+<p>
+     Usually each user has his own portal view. The layout for the user
+     is defined in <em>profiles/layout/portal-user-USER_NAME.xml</em>
+     and the instances are defined in <em>profiles/copletinstancedata/portal-user-USER_NAME.xml</em>.
+    </p>
+<p>
+     However, in some cases each user of a distinct role has the same
+     portal view, so you can define role based portal views.
+     The two configuration files are in the <em>profiles/layout</em>
+     and in the <em>profiles/copletinstancedata</em> directory
+     and have the name <em>portal-role-NAME_OF_ROLE.xml</em>.
+    </p>
+<p>
+     This role based portal view is also used when a user logs into the
+     portal for the first time and hasn't "created" his own portal view yet.
+    </p>
+<p>
+     In addition you can define a global setting for the portal view
+     with the two configuration files in the two above mentioned directories.
+     Give them both the name <em>portal.xml</em>. This portal view is used
+     whenever the user doesn't have an own portal view and no role based
+     view exists.
+    </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/meta.xml
new file mode 100644
index 0000000..d612c98
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-portal-profiles/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/portal/profiles.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/content_en.html
new file mode 100644
index 0000000..45052f8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/content_en.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Profile Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bruno Dumon" name="DC.Creator">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the profile generator of 
+Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Profile Generator</h1>
+      
+<p>The profile generator creates xml from the current profiler
+        measurement results of cocoon.</p>
+      
+<p>If you just want to use the Cocoon profiler, look at <a href="../concepts/profiler.html">this document</a>.</p>
+      
+<ul>
+        
+<li>Name : profile</li>
+        
+<li>Class: org.apache.cocoon.components.profiler.ProfilerGenerator</li>
+        
+<li>Cacheable: no</li>
+      
+</ul>
+
+      
+<p>When no parameters are specified, the profiler generator will simply
+        generate all available information. Here is some example output:</p>
+
+      
+<pre class="code">&lt;profilerinfo date="Mar 24, 2003 5:10:56 PM" xmlns="http://apache.org/cocoon/profiler/1.0"&gt;
+  &lt;pipeline count="2" key="4704447257427244431" processingTime="378" uri="caching-testsite.html"&gt;
+    &lt;average time="189"&gt;
+      &lt;component offset="0" role="file" source="test.xml" time="1"/&gt;
+      &lt;component offset="1" role="xslt" source="test2page.xsl" time="58"/&gt;
+      &lt;component offset="2" role="xslt" source="page2html.xsl" time="115"/&gt;
+      &lt;component offset="3" role="html" time="2"/&gt;
+    &lt;/average&gt;
+    &lt;result index="0" time="128"&gt;
+      &lt;component index="0" processing="0" role="file" setup="0"
+        source="test.xml" time="0"/&gt;
+      &lt;component index="1" processing="0" role="xslt" setup="59"
+        source="test2page.xsl" time="59"/&gt;
+      &lt;component index="2" processing="0" role="xslt" setup="65"
+        source="page2html.xsl" time="65"/&gt;
+      &lt;component index="3" processing="0" role="html" setup="0" time="0"/&gt;
+    &lt;/result&gt;
+    &lt;result index="1" time="250"&gt;
+      &lt;component index="0" processing="1" role="file" setup="1"
+        source="test.xml" time="2"/&gt;
+      &lt;component index="1" processing="1" role="xslt" setup="56"
+        source="test2page.xsl" time="57"/&gt;
+      &lt;component index="2" processing="21" role="xslt" setup="145"
+        source="page2html.xsl" time="166"/&gt;
+      &lt;component index="3" processing="5" role="html" setup="0" time="5"/&gt;
+    &lt;/result&gt;
+  &lt;/pipeline&gt;
+  &lt;pipeline count="1" key="-1812911851413592444" processingTime="190" uri="noncaching-testsite.html"&gt;
+    &lt;average time="190"&gt;
+      &lt;component offset="0" role="file" source="test.xml" time="1"/&gt;
+      &lt;component offset="1" role="xslt" source="test2page.xsl" time="86"/&gt;
+      &lt;component offset="2" role="xslt" source="page2html.xsl" time="70"/&gt;
+      &lt;component offset="3" role="html" time="19"/&gt;
+    &lt;/average&gt;
+    &lt;result index="0" time="190"&gt;
+      &lt;component index="0" processing="1" role="file" setup="0"
+        source="test.xml" time="1"/&gt;
+      &lt;component index="1" processing="3" role="xslt" setup="83"
+        source="test2page.xsl" time="86"/&gt;
+      &lt;component index="2" processing="7" role="xslt" setup="63"
+        source="page2html.xsl" time="70"/&gt;
+      &lt;component index="3" processing="19" role="html" setup="0" time="19"/&gt;
+    &lt;/result&gt;
+  &lt;/pipeline&gt;
+&lt;/profilerinfo&gt;</pre>
+
+      
+<p>The output consists of a <span class="codefrag">profilerinfo</span> element containing
+        a number of <span class="codefrag">pipeline</span> elements.  Each pipeline is
+        identified by a key. The pipeline element contains one
+        <span class="codefrag">average</span> element (containing the average results) and one
+        or more <span class="codefrag">result</span> elements for the individual results
+        (by default only the last 10 results are remembered). Each result element
+        contains a number of <span class="codefrag">component</span> elements, one for each
+        component (generator, transformer, serializer) in the pipeline.</p>
+
+      
+<p>All elements have the namespace
+        <span class="codefrag">http://apache.org/cocoon/profiler/1.0</span>.</p>
+
+      
+<p>On the component element, there are three attributes indicating timings:</p>
+      
+<dl>
+        
+<dt>setup</dt>
+        
+<dd>time spent in the component's setup method</dd>
+        
+<dt>processing</dt>
+        
+<dd>time spent processing the SAX events</dd>
+        
+<dt>time</dt>
+        
+<dd>sum of the processing and setup times</dd>
+      
+</dl>
+
+      
+<p>The output of the profiler generator can be tuned using the following
+        request parameters:</p>
+
+      
+<dl>
+        
+<dt>key</dt>
+        
+<dd>limit the output to the pipeline with this key</dd>
+        
+<dt>result</dt>
+        
+<dd>to be used in combination with key, causes only the result with
+          this index to be included. In this case some additional information
+          about the environment (request parameters and session attributes)
+          will be returned.</dd>
+        
+<dt>component</dt>
+        
+<dd>to be used in combination with key and result. When this parameter
+          is specified, the XML that was generated by the component with this
+          index will be included in the output (as child of the specified
+          component element).</dd>
+        
+<dt>fragmentonly</dt>
+        
+<dd>to be used in combination with key, result and component. If this
+          parameter is true, only the XML that was generated by the specified
+          component will be returned, without additional profiler information
+          around it.</dd>
+      
+</dl>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/meta.xml
new file mode 100644
index 0000000..6ac3627
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-profiler-profiler-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/profile-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/content_en.html
new file mode 100644
index 0000000..ace4721
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/content_en.html
@@ -0,0 +1,405 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Portal Syndication with Web Services and Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ivelin Ivanov" name="DC.Creator">
+<meta content="This document describes the Web Service ProxyGenerator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>What Is Web Syndication?</h1>
+      
+<p>Web Site Syndication has gained popularity as more and more web sites cross reference each
+        other, not only by a single hyperlink, but also by embedding parts of their content. The
+        idea was pioneered by Netscape with their Rich Site Summary (RSS)
+        (<a class="external" href="http://www.oasis-open.org/cover/rss.html">http://www.oasis-open.org/cover/rss.html</a>)
+        XML format. RSS was developed in early 1999 to populate Netscape's My Netscape portal with
+        external newsfeeds ("channels"). Since then RSS has taken on a life of its own and now
+        thousands of Web sites use RSS as a "what's new" mechanism to drive traffic their way.
+      </p>
+      
+<p>The current RSS 1.0 standard is an application of Resource Description Framework (RDF)
+        (<a class="external" href="http://www.w3.org/TR/rdf-schema/">http://www.w3.org/TR/rdf-schema/</a>). RDF
+        is a framework for describing and interchanging metadata. The RDF framework is extensible
+        and allows adding new types of entities. It also gives meaning to resources to enable
+        automated processing of Web resources.
+      </p>
+      
+<p>RSS is unarguably an example of an organically grown and widely accepted standard. For long
+        it was not endorsed by any of the popular standards committees. Even so it quickly became
+        popular and found a large number of creative uses. Lately though it has reached its limits.
+        There is a demand for more advanced portal syndication which RSS cannot satisfy.
+      </p>
+    
+
+    
+<h1>Going beyond RSS with Web Services</h1>
+      
+<p>Latest generation web portals demand more than simply posting cross linked news stories
+        from RSS. Embedding and personalizing rich content and behavior from remote portals is
+        becoming necessity. Limited success has been achieved through complex and sophisticated
+        backend integration via proprietary or Web Services compliant protocols. Recognizing the
+        growing demand, influential organizations have attempted to develop new languages such as:
+      </p>
+
+      
+<h2>Web Services Experience Language (WSXL)</h2>
+<p>
+          (<a class="external" href="http://www.webservices.org/index.php/article/articleview/345/">http://www.webservices.org/index.php/article/articleview/345/</a>)
+        </p>
+<p>
+          
+<em>"WSXL is a Web services centric component model for interactive Web applications. WSXL
+            is designed to achieve two main goals: enable businesses to distribute Web applications
+            through multiple revenue channels and enable new services or applications to be created
+            by leveraging existing applications across the Web."
+          </em>
+        
+</p>
+
+      
+<h2>Web Services Inspection Language (WSIL)</h2>
+<p>
+          (<a class="external" href="http://www.webservices.org/index.php/article/articleview/85/">http://www.webservices.org/index.php/article/articleview/85/</a>)
+        </p>
+<p>
+          
+<em>"The specification allows a Web services provider to publish a WS-Inspection (WSIL)
+            document which lists the services on offer and their corresponding WSDL (Web services
+            description language) files. The convention is that the WSIL document should be called
+            "inspection.wsil" and be located at a common entry point to the web site. This paves the
+            way for future Web services "crawlers" to locate and parse WSIL documents for Web
+            service search engines."        
+          </em>
+        
+</p>
+
+      
+<h2>Web Services for Remote Portals (WSRP)</h2>
+<p>
+          (<a class="external" href="http://www.oasis-open.org/committees/wsrp/">http://www.oasis-open.org/committees/wsrp/</a>)
+        </p>
+<p>
+          
+<em>"Defining an XML and Web services standard that will allow the plug-n-play of visual,
+            user-facing Web services with portals or other intermediary Web applications"
+          </em>
+        
+</p>
+
+      
+<h2>Web Services for Interactive Applications</h2>
+<p>
+          (<a class="external" href="http://www.oasis-open.org/committees/wsia/">http://www.oasis-open.org/committees/wsia/</a>)
+        </p>
+<p>
+          
+<em>"Create an XML and web services centric framework for interactive web applications.
+            The designs must achieve two main goals: enable businesses to distribute web
+            applications through multiple revenue channels, and enable new services or applications
+            to be created by leveraging existing applications across the Web."
+          </em>
+        
+</p>
+
+      
+<p>While these efforts are certainly worthwhile and promising, it will most likely take years
+        before they pass the filters of real life use before they can claim widespread adoption. All
+        of them ask for a thick infrastructure layer to support implementations. While possible, it
+        is unlikely that mainstream deployment will be achieved instantly.
+      </p>
+      
+<p>Not all is lost though. Fortunately, there is way to satisfy a large portion of the
+        syndication requirements by applying already established technologies and tools. We will
+        illustrate the architecture of a possible solution using an open source framework for XML
+        Publishing - Apache Cocoon.
+      </p>
+    
+
+    
+<h1>Apache Cocoon</h1>
+      
+<p>
+        (<a class="external" href="http://cocoon.apache.org/index.html">http://cocoon.apache.org/index.html</a>)
+      </p>
+      
+<p>
+        
+<em>"Apache Cocoon is an XML publishing framework that raises the usage of XML and XSLT
+          technologies for server applications to a new level. Designed for performance and
+          scalability around pipelined SAX processing, Cocoon offers a flexible environment based
+          on a separation of concerns between content, logic and style. To top this all off,
+          Cocoon's centralized configuration system and sophisticated caching help you to create,
+          deploy and maintain rock-solid XML server applications".
+        </em>
+      
+</p>
+      
+<p>First, let's describe a typical use case scenario: User logs in to a familiar portal and
+        happily surfs about. At some point the user clicks on a link which leads to a strange page.
+        It has the portal logo, even shows the same login id but still looks very different and
+        unfriendly ... After some time and frustration the user gets used to switching back and
+        forth between the two faces of the portal ... while looking for another provider which
+        offers both services in a coherent graphical interface.
+      </p>
+      
+<p>For those who have never had similar experience, we will give a popular example. Yahoo! Autos
+        (<a class="external" href="http://autos.yahoo.com/finance.html?refsrc=autos/insurance">http://autos.yahoo.com/finance.html?refsrc=autos/insurance</a>)
+        offers an easy to use interactive catalog of cars. However when it comes to insuring an
+        automobile, applying for a loan or buying a car, the web site hyperlinks to a co-branded
+        page of another company. For example Lending Tree
+        (<a class="external" href="https://www.lendingtree.com/newauto/secure/ctl_borrower.asp?page=loan_selection&verb=continue&O_loan_type=LOAN_TYPE_AUTO&bp=yahooautos&source=40050&alliance=true&SITEID=&templxlname=&templxssn1=&templxssn2=&templxssn3=">https://www.lendingtree.com/newauto/.....</a> )
+        will show Yahoo! Autos logo at the top of the screen, however the rest of the page looks
+        very different than any other Yahoo! page. All the personalization spoils that a Yahoo! user
+        enjoys are lost as soon as the application for a loan begins. Not only the colors and layout
+        are different. A login session with Yahoo! does not carry over to Lending Tree. On top of
+        that a pop-up window appears when switching between the two sites, which reads "You are
+        about to view pages over a secure connection ...". When added up these "negligible"
+        inadequacies, lead to an overall poor experience, which is certainly not the original
+        intent of the Yahoo! content producers.
+      </p>
+      
+<p>Now as we have an idea of how things are not supposed to work, we will show that
+        outsourcing interactive components to a third party site, while preserving the look &amp;
+        feel of the original portal is still possible when done right. As we mentioned Cocoon offers
+        a solution. Since Cocoon is a very sophisticated framework, an indepth analysis of its
+        features is beyond the scope of this text to cover.
+      </p>
+    
+
+    
+<h1>Web Services Proxy to the rescue</h1>
+      
+<p>The latest version of Cocoon is 2.1 and it has a new Web Service Proxy component. It is
+        this component which we shall focus on for the reminder of the text. To follow the rest of
+        the article, it will be useful (but not essential) to have a basic knowledge of Cocoon 2.
+      </p>
+      
+<p>Combined with the XMLForm (which is not part of Cocoon anymore)
+        component of Cocoon 2 and XSLT, the Web Service Proxy component allows vendors to share
+        interactive content with little effort. The Web Service Proxy takes advantage of the fact
+        that a Cocoon web application produces XML content, which is later translated into multiple
+        presentation formats, like HTML or WML. Once the proxy is plugged in the Cocoon sitemap, it
+        transparently pipes browser requests to a remote web application and returns the response
+        back to the sitemap for local styling. Receiving a client independent XML format, allows the
+        local site to pull content and style it with XSLT with the desired Look &amp; Feel.
+      </p>
+      
+<p>
+        
+<strong>
+          Q. Ok, styling presentation is easy to understand, but how is a form submitted to the original site?
+        </strong>
+      
+</p>
+      
+<p>The XMLForm component is the answer. It uses W3C XForms included in the XML content which
+        allows the end user to directly interact with the remote server through the embedding site.
+        The form markup in the XML content of an embedded page uses relative URL address for the
+        target action, when the end user submits, the form data is sent to the containing site,
+        which captures the form data and the relative URL. The Web Service Proxy then takes this
+        information and re-submits it to the original site. It then reads the XML response and makes
+        it available to the sitemap for styling again.
+      </p>
+      
+<p>
+        
+<strong>Q. Hmm ... a typical web application maintains a user session while navigating.
+          How is the containing site propagating the end user session to the embedded site?
+        </strong>
+      
+</p>
+      
+<p>The answer is simple. The Web Service Proxy simply hooks to the end user session and
+        automatically starts its own session with the remote site. If the remote site requires
+        authentication, then the developer of the local web site has to pass the user credentials
+        as parameters to the WebServiceProxyGenerator.
+      </p>
+      
+<p>
+        
+<strong>Q. What transport protocols are supported?</strong>
+      
+</p>
+      
+<p>HTTP 1.0, HTTP 1.1, HTTPS.</p>
+      
+<p>Below we will illustrate the architecture of the solution with some example code and
+        figures.
+      </p>
+      
+<div align="center">
+<img class="figure" alt="Figure 1 - Traditional Http Proxy vs Cocoon Web Service Proxy" src="images/wsproxy_Proxies.png"></div>
+      
+<p>
+        
+<em>Figure 1 - Architecture of the Web Service Proxy Solution. As opposed to a traditional
+          proxy server, the Web Services Proxy captures user input and allows the web site to remain
+          coherent even when the functionality for some of its components is delivered remotely.
+        </em>
+      
+</p>
+      
+<div align="center">
+<img class="figure" alt="Figure 2 - Illustration of the data flow for a composite page" src="images/wsproxy_CompositePage.png"></div>
+      
+<p>
+        
+<em>Figure 2 - Illustration of the data flow for a composite page. Some of the content is
+          locally constructed, the rest is obtained remotely. Finally the same styling is applied
+          and the user facing page appears consistent.
+        </em>
+      
+</p>
+      
+<p>Now we will show a snippet of the sitemap which employs the Web Service Proxy. Notice its
+        brevity! The Web Service Proxy completely handles the content and navigation logic between
+        the two portals. Only stylesheets are additionally required to translate the remotely
+        retrieved documents into a user friendly format.
+      </p>
+      
+<pre class="code">
+  &lt;?xml version="1.0"?&gt;
+  &lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+
+    &lt;!-- =========================== Components ================== --&gt;
+    &lt;map:components&gt;
+      &lt;map:generators default="file"&gt;
+        &lt;map:generator name="wsproxy" logger="sitemap.generator.wsproxy"
+          src="org.apache.cocoon.generation.WebServiceProxyGenerator"/&gt;
+      &lt;/map:generators&gt;
+    &lt;/map:components&gt;
+
+    &lt;!-- =========================== Pipelines =================== --&gt;
+    &lt;map:pipelines&gt;
+      &lt;map:pipeline&gt;
+        &lt;!-- Interactive Web Application Syndication  --&gt;
+        &lt;map:match pattern="*"&gt;
+          &lt;map:generate type="wsproxy" label="xml"
+            src="http://{request:serverName}:{request:serverPort}{request:contextPath}/samples/xmlform/wizard?cocoon-view=xml"/&gt;
+          &lt;map:transform src="stylesheets/newWizard2html.xsl"/&gt;
+          &lt;map:transform src="context://samples/stylesheets/xmlform/xmlform2html.xsl"/&gt;
+          &lt;map:serialize type="html"/&gt;
+        &lt;/map:match&gt;
+      &lt;/map:pipeline&gt;
+    &lt;/map:pipelines&gt;
+  &lt;/map:sitemap&gt;
+   </pre>
+
+      
+<div align="center">
+<img class="figure" alt="Figure 3 - sequence diagram" src="images/wsproxy_Sequence.png"></div>
+      
+<p>
+        
+<em>Figure 3 - Above is a sequence diagram outlining the interaction between the key
+          participants in a syndication session.
+        </em>
+      
+</p>
+      
+<div align="center">
+<img class="figure" alt="screen shot 1" src="images/wsproxy_Screenshot1.png"></div>
+      
+<p>
+        
+<em>Figure 4 - Sample screenshot from a remotely enabled application as it appears
+          standalone.
+        </em>
+      
+</p>
+      
+<div align="center">
+<img class="figure" alt="screen shot 2" src="images/wsproxy_Screenshot2.png"></div>
+      
+<p>
+        
+<em>Figure 5 - Sample screenshot from the same application embedded in another web
+          application.
+        </em>
+      
+</p>
+
+      
+<p>The content of the original XML page behind these two screenshot follows:</p>
+      
+<pre class="code">
+  &lt;?xml version="1.0"?&gt;
+  &lt;document xmlns:xf="http://apache.org/cocoon/xmlform/1.0"&gt;
+    &lt;xf:form id="form-feedback" view="userIdentity" action="wizard" method="GET"&gt;
+      &lt;xf:caption&gt;Personal Information&lt;/xf:caption&gt;
+      &lt;error&gt;
+        &lt;xf:violations class="error"/&gt;
+      &lt;/error&gt;
+      &lt;xf:textbox ref="firstName"&gt;
+        &lt;xf:caption&gt;First Name&lt;/xf:caption&gt;
+        &lt;xf:violations class="error"/&gt;
+      &lt;/xf:textbox&gt;
+      ...
+      &lt;xf:selectMany ref="role" selectUIType="listbox"&gt;
+        &lt;xf:caption&gt;Professional roles&lt;/xf:caption&gt;
+        &lt;xf:item&gt;
+          &lt;xf:caption&gt;Geek&lt;/xf:caption&gt;
+          &lt;xf:value&gt;Geek&lt;/xf:value&gt;
+        &lt;/xf:item&gt;
+        &lt;xf:item&gt;
+          &lt;xf:caption&gt;Hacker&lt;/xf:caption&gt;
+          &lt;xf:value&gt;Hacker&lt;/xf:value&gt;
+        &lt;/xf:item&gt;
+        ...
+      &lt;/xf:selectMany&gt;
+      ...
+      &lt;!-- hidden model attribute --&gt;
+      &lt;xf:hidden ref="hidden"&gt;
+        &lt;xf:value&gt;true&lt;/xf:value&gt;
+      &lt;/xf:hidden&gt;
+      ...
+      &lt;xf:submit id="next" class="button"&gt;
+        &lt;xf:caption&gt;Next&lt;/xf:caption&gt;
+      &lt;/xf:submit&gt;
+    &lt;/xf:form&gt;
+
+    &lt;xf:output ref="count" id="show_count" form="form-feedback" class="info"&gt;
+      &lt;xf:caption&gt;Visits Count&lt;/xf:caption&gt;
+    &lt;/xf:output&gt;
+  &lt;/document&gt;
+   </pre>
+
+      
+<p>The listing above contains markup in the XMLForm namespace. It is a presentation
+        independent way to specify input controls. Being XForms compliant it is easy to learn and
+        use. The XSLT stylesheets used to convert the XML above are very simple and will not be
+        listed here. They can found in the Cocoon 2.1 distribution.
+      </p>
+    
+
+    
+<h1>Conclusion</h1>
+      
+<p>The Web Service Proxy component is tightly integrated with the Cocoon framework and is
+        particularly convenient to use in combination with XMLForm to enable syndication of website
+        functionality. With the presented sample, we only scratched the service of the possible
+        applications. It is easy to see though for a creative mind how it can be extended in
+        multiple directions. Although the solution we offered is conveniently applied with Cocoon,
+        the concepts are generally applicable outside the framework as well. Exposing a Web
+        Application functionality via XML is not just a "neat" feature any more. It opens the gates
+        to a constellation of opportunities, not possible with the classical Model-2 approach where
+        the business logic is directly tied to a graphical output like HTML.
+      </p>
+
+      
+<h2>Have more questions?</h2>
+<p>Look at the online demo available in the Cocoon distribution in the samples:
+          <span class="codefrag">http://{host}:{port}/{contextPath}/samples/proxy/</span>.
+        </p>
+<p>Then study the source code and if you still have questions, join the cocoon users email
+          list and ask. If you have ideas for improvement then you are more than welcome to discuss
+          it on the cocoon development email list and eventually submit a patch through the Apache
+          bug tracking system.
+        </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/meta.xml
new file mode 100644
index 0000000..21e4e1e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-proxy-webserviceproxy-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/wsproxy-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/content_en.html
new file mode 100644
index 0000000..fc4d962
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/content_en.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session Action</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the session action." name="DC.Description">
+</head>
+<body>
+  
+<h1>Session Action</h1>
+   
+<p>
+    The session action helps in managing the session of a user on
+    the server. It can create and terminate a session. The function
+    is controlled by a parameter named 'action'.
+   </p>
+   
+<p>For more information on session handling and session contexts
+      have a look at the <a href="../../developing/webapps/session.html">Session Context documentation</a>.</p>
+   
+<h2>Creating a Session</h2>
+<p>
+      To create a session (if it not already exists) simply add the
+      action in your pipeline:
+     </p>
+<pre class="code">
+
+    &lt;map:act type="session"/&gt;
+  
+</pre>
+<p>This is the equivalent to specify the 'action' parameter
+       with the value 'create':</p>
+<pre class="code">
+
+    &lt;map:act type="session"&gt;
+        &lt;map:parameter name="action" value="create"/&gt;
+    &lt;/map:act&gt;
+  
+</pre>
+   
+<h2>Terminating a Session</h2>
+<p>Terminating a session is as easy as creating a session, simply
+      add the action to your pipeline and set the 'action' parameter
+      to 'terminate':</p>
+<pre class="code">
+
+    &lt;map:act type="session"&gt;
+        &lt;map:parameter name="action" value="terminate"/&gt;
+    &lt;/map:act&gt;
+  
+</pre>
+<p>This terminates the session immediately.</p>
+<p>You can optionally specifiy the 'mode' parameter which controlls
+        the termination of the session. You have the choice between
+        'immediately' (the default) and 'if-unsued'. If you use the
+        mode 'if-unused', the session is only terminated, if no session
+        context exists for the user:</p>
+<pre class="code">
+
+    &lt;map:act type="session"&gt;
+        &lt;map:parameter name="action" value="terminate"/&gt;
+        &lt;map:parameter name="mode" value="if-unused"/&gt;
+    &lt;/map:act&gt;
+  
+</pre>
+   
+   
+<h1>Configuration</h1>
+   
+<ul>
+    
+<li>Name : session</li>
+    
+<li>Class: org.apache.cocoon.webapps.session.acting.SessionAction</li>
+   
+</ul>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/meta.xml
new file mode 100644
index 0000000..d6e4a44
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-action/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/actions/session-action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/content_en.html
new file mode 100644
index 0000000..5cd8ef6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/content_en.html
@@ -0,0 +1,336 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session Contexts</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Introduction</h1>
+     
+<p>This chapter describes the concept of the session context provided
+       by the session framework (session-fw block).</p>    
+    
+<p>The session framework provides the concept of so called (session) contexts.
+      A session context is a data storage in the session that can contain
+      arbitrary data in XML format.</p>
+      
+<p>You can define your own contexts for your application. For example,
+       if you build a web shop, you can create a context called <em>shop</em>
+       and store the basket of the user in it.</p>
+      
+<p>The <em>session transformer</em> is the main component used for
+       storing and retrieving information from such a context.</p>
+     
+<div class="note">The chapter "Special Contexts" explains some special
+        contexts which do not require a session. They are available everytime. These
+        special contexts are the request context and the
+        temporary context.</div>
+   
+     
+<h1>session Transformer</h1>
+        
+<p>The <em>session transformer</em> is responsible for interpreting the tags
+          and performing the actions required. The session transformer is configured
+          in the sitemap and can be used inside a pipeline. All tags must be prefixed
+          with the session namespace. So the actual tag used in the document will read
+          <em>&lt;session:xxxx&gt;</em>. The current namespace URI for the session 
+          transformer is <em>"http://apache.org/cocoon/session/1.0"</em>.</p>
+     
+<h2>Context-Tags</h2>
+<p>A context is basically an application specific block of XML data in
+          the users session. Each context has a unique name.</p>
+<p>The command <em>createcontext</em> is used to create a new context.
+          A <em>name</em> attribute must be given to the context in order to identify it.
+          The following names may not be used: request, response, session,
+          context, temp, portal or authentication. If a context of the same name already exists
+          then this command will have no effect.</p>
+<p>
+<em>&lt;createcontext name="mycontext"/&gt;</em>
+</p>
+<p>In order to delete a context the command <em>deletecontext</em> is
+          provided. Again a <em>name</em> attribute must be provided.</p>
+<p>
+<em>&lt;deletecontext name="mycontext"/&gt;</em>
+</p>
+<p>Once created, XML data can then be stored inside or read from a
+          given context.</p>
+     
+<h2>Accessing context data</h2>
+<p>The data in a context can be dynamically accessed using the
+          following commands.</p>
+<p></p>
+<p>
+<em>getxml</em> allows data to be read out of a context. A
+          <em>path</em> attribute describes the source of the data inside the context and
+          consists of an XPath expression. All <em>path</em> values must be absolute and
+          only nodes and attributes can be accessed. </p>
+<p>An optional default value can also be provided to allow for the
+          nonexistence of the requested data.</p>
+<p>
+<em>&lt;getxml context="mycontext"
+          path="/User/Name"/&gt;</em>
+</p>
+<p>
+<em>&lt;getxml context="mycontext"
+          path="/User/Name"&gt;Matthew&lt;/getxml&gt;</em>
+</p>
+<p>Attributes can also be accessed.</p>
+<p>
+<em>&lt;getxml context="mycontext"
+          path="/User/Name/@Age"/&gt;</em>
+</p>
+<p>
+<em></em>
+</p>
+<p>Data can be written into a context using the <em>setxml</em>
+          command. It is possible to set values or nodes as the following examples
+          show.</p>
+<p>
+<em>&lt;setxml context="mycontext"
+          path="/User/Name"/&gt;Carsten&lt;/setxml&gt;</em>
+</p>
+<p>
+<em>&lt;setxml context="mycontext"
+          path="/User/"/&gt;&lt;Name&gt;Carsten&lt;/Name&gt;&lt;/setxml&gt;</em>
+</p>
+<p></p>
+<p>Using the <em>setxml</em> command causes all the nodes below the
+          target node to be deleted. If you wish to maintain the nodes and manipulate
+          individual branches of the XML tree - then the session transformer offers the
+          <em>mergexml</em> command.</p>
+<p></p>
+<p>Use the <em>removexml</em> command to remove nodes from the
+          context.</p>
+<p>
+<em>&lt;removexml context="mycontext"
+          path="/User/"/&gt;</em>
+</p>
+<h3>Example</h3>
+<p>The following example shows the use of several commands and in
+             particular how the <em>mergexml</em> command can be used to manipulate context
+             data.</p>
+<pre class="code">&lt;resource xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;session:createcontext name="trackdemo"/&gt;
+  &lt;!-- build context data --&gt;
+  &lt;session:setxml context="trackdemo" path="/"&gt;
+    &lt;context&gt;
+      &lt;users&gt;
+        &lt;user id="1"&gt;
+          &lt;name&gt;Carsten&lt;/name&gt;
+        &lt;/user&gt;
+      &lt;/users&gt;
+    &lt;/context&gt;
+  &lt;/session:setxml&gt;
+  &lt;session:mergexml context="trackdemo" path="/context"&gt;
+    &lt;users&gt;
+      &lt;user id="1"&gt;
+        &lt;name&gt;Ziegeler&lt;/name&gt;
+        &lt;developer&gt;true&lt;/developer&gt;
+      &lt;/user&gt;
+      &lt;user id="2"&gt;
+        &lt;name&gt;Walter&lt;/name&gt;
+      &lt;/user&gt;
+    &lt;/users&gt;
+  &lt;/session:mergexml&gt;
+  &lt;session:getxml context="trackdemo" path="/"/&gt;
+&lt;/resource&gt;</pre>
+<p>In the above example, a context for storing data is added. Using
+             the <em>setxml</em> command data is then stored into the context. The following
+             <em>mergexml</em> command then changes the name of user-1 and adds a further
+             tag. As there is no original user-2 the complete subtree is then added to the
+             context.</p>
+     
+<h2>Reading and writing contexts</h2>
+<p>Aside from the described means of accessing data in a context,
+          the session transformer also provides for the reading and writing of contexts. This can be
+          used to write an application context out to a database or to read an
+          application context in from a file.</p>
+<p>The session transformer offers a very flexible way of defining the source of the
+          context data. It is possible to specify a resource (defined in the sitemap) or
+          a Java class. Using a resource allows for example the context data to be read
+          from a database using the SQL Transformer. As this source is a Cocoon
+          pipeline, the data can be generated and transformed before passing into the
+          context. </p>
+<p>When a context is created, it can get additional save and load URIs
+          which are used for loading/saving to/from the context:</p>
+<p>
+<em>&lt;createcontext name="mycontext" load="cocoon://load-from-db"
+          save="cocoon://save-to-db"/&gt;</em>
+</p>
+<p>These URIs can then be used inside a document to load data into a
+          context:</p>
+<p>
+<em>&lt;loadxml context="mycontext"/&gt;</em>
+</p>
+<p>This example would then load the context data via the resource
+          <em>load-from-db</em> which must be defined in the sitemap.</p>
+<p>Parameters can be passed to and interpreted by the uri or the Java
+          class. This allows the context data to be read dependent on say the current
+          user.</p>
+<p>
+<em>&lt;loadxml
+          context="mycontext"&gt;&lt;user&gt;ben&lt;/user&gt;&lt;/loadxml&gt;</em>
+</p>
+<p>The resource addressed by the uri will receive the parameters as
+          request-parameters. In addition the name of the context will always be passed
+          as <em>contextname</em>.</p>
+<p>Writing context data works in the same manner.</p>
+<p>
+<em>&lt;savexml context="mycontext"/&gt;</em>
+</p>
+<p>Both commands can use the optional <em>path</em> attribute:</p>
+<p>
+<em>&lt;loadxml context="mycontext" path="/user"/&gt;</em>
+</p>
+<p>
+<em>&lt;savexml context="mycotnext" path="/user"/&gt;</em>
+</p>
+<p>The first command will read xml from the uri and store it in the
+          context under the node <em>user</em>, the second one saves only the xml subtree
+          under the node <em>user</em> to the uri. The resource addressed by the uri will
+          be passed in addition to the <em>contextname</em> parameter the <em>path</em>
+          parameter with the corresponding value. If the <em>path</em> attribute is not
+          present the <em>path</em> parameter will get the value <em>"/"</em>.</p>
+  
+  
+<h1>Special Contexts</h1>
+     
+<p>Cocoon creates and maintains special contexts that allow the
+        applications to access the environment. This allows the read-only access
+        to such things as the current request using the same XPath
+        commands previously described. These context do not require any session, they
+        are always available and change on every request.</p>
+     
+<h2>The Request Context - Accessing the Environment, Part One</h2>
+<p>The request context is an XML description of the current
+          (HTTP) request. This context is a special read only context that
+          can be accessed with the usual commands:</p>
+<p>
+<em>&lt;getxml context="request" path="/parameter"/&gt;</em>
+</p>
+<p>For example, if you want to get the value of a parameter with the
+          name <em>username</em> you can include the following command in your XML and it
+          will be replaced with the value of the parameter:</p>
+<p>
+<em>&lt;getxml context="request"
+          path="/parameter/username"/&gt;</em>
+</p>
+<p>If you wish to obtain the complete querystring as it was
+          passed into Cocoon - without converting the data to XML - then you can use
+          the "/querystring" path:</p>
+<p>
+<em>&lt;getxml context="request"
+          path="/querystring"/&gt;</em>
+</p>
+<p>The result will be a string in the format
+          "?param=aaa&amp;...".</p>
+<p>The complete context you can access via these commands has the
+          following XML format:</p>
+<pre class="code">&lt;parameter&gt;
+  &lt;!-- All parameters: parameter names build the elements with the value of the first parameter with
+                          this name as text node child --&gt;
+  &lt;firstparameter&gt;value of parameter&lt;/firstparameter&gt;
+  &lt;secondparameter&gt;value of parameter&lt;/secondparameter&gt;
+&lt;/parameter&gt;
+
+&lt;querystring&gt;the querystring with a leading '?' or empty&lt;querystring&gt;
+  (The querystring contains only parameters send by the GET method)
+
+&lt;parametervalues&gt;
+  &lt;!-- All parameters. The tags are all inside the cinclude transformer namespace.
+    The generated XML can be used without modification for the
+    cinclude:includexml command. --&gt;
+  &lt;cinclude:parameters&gt;
+    &lt;cinclude:parameter&gt;
+      &lt;cinclude:name&gt;1st parameter name&lt;/cinclude:name&gt;
+      &lt;cinclude:value&gt;1st parameter value&lt;/cinclude:value&gt;
+    &lt;/cinclude:parameter&gt;
+             ...
+    &lt;cinclude:parameter&gt;
+      &lt;cinclude:name&gt;2nd parameter name&lt;/cinclude:name&gt;
+      &lt;cinclude:value&gt;2nd parameter value&lt;/cinclude:value&gt;
+    &lt;/cinclude:parameter&gt;
+  &lt;/cinclude:parameters&gt;
+  &lt;!-- If a parameter has more than one value, for each value a
+      &lt;session:param&gt; block is generated. --&gt;
+&lt;/parametervalues&gt;
+
+&lt;attributes&gt;
+  &lt;!-- lists all attributes, attribute names build the elements
+        with the values as text node childs --&gt;
+&lt;/attributes&gt;
+
+&lt;headers&gt;
+  &lt;!-- lists all headers, header names build the elements
+       with the values as text node childs --&gt;
+&lt;/headers&gt;
+
+&lt;cookies&gt;
+  &lt;!-- lists all cookies --&gt;
+  &lt;cookie name="..."&gt;
+    &lt;value&gt;the cookie value&lt;/value&gt;
+    &lt;name&gt;the name of the cookie&lt;/name&gt;
+    &lt;comment&gt;value&lt;/comment&gt;
+    &lt;domain&gt;value&lt;/domain&gt;
+    &lt;path&gt;value&lt;/path&gt;
+    &lt;maxAge&gt;value&lt;/maxAge&gt;
+    &lt;secure&gt;value&lt;/secure&gt;
+    &lt;version&gt;value&lt;/version&gt;
+  &lt;/cookie&gt;
+&lt;/cookies&gt;
+
+&lt;characterEncoding&gt;value&lt;/characterEncoding&gt;
+&lt;contentLength&gt;value&lt;/contentLength&gt;
+&lt;contentType&gt;value&lt;/contentType&gt;
+&lt;protocol&gt;value&lt;/protocol&gt;
+&lt;remoteAddress&gt;value&lt;/remoteAddress&gt;
+&lt;remoteHost&gt;value&lt;/remoteHost&gt;
+&lt;scheme&gt;value&lt;/scheme&gt;
+&lt;serverName&gt;value&lt;/serverName&gt;
+&lt;serverPort&gt;value&lt;/serverPort&gt;
+&lt;method&gt;value&lt;/method&gt;
+&lt;contextPath&gt;value&lt;/contextPath&gt;
+&lt;pathInfo&gt;value&lt;/pathInfo&gt;
+&lt;pathTranslated&gt;value&lt;/pathTranslated&gt;
+&lt;remoteUser&gt;value&lt;/remoteUser&gt;
+&lt;requestedSessionId&gt;value&lt;/requestedSessionId&gt;
+&lt;requestURI&gt;value&lt;/requestURI&gt;
+&lt;servletPath&gt;value&lt;/servletPath&gt;
+&lt;isRequestedSessionIdFromCookie&gt;value&lt;/isRequestedSessionIdFromCookie&gt;
+&lt;isRequestedSessionIdFromCookie&gt;value&lt;/isRequestedSessionIdFromCookie&gt;
+&lt;isRequestedSessionIdValid&gt;value&lt;/isRequestedSessionIdValid&gt;</pre>
+     
+<h2>The Temporary Context</h2>
+<p>The temporary context with the name <em>temporary</em> is available on
+          each request. It is independent from the session and has no content when a new
+          request starts. It can be used like any other context except that the content
+          is lost/deleted when the current response is finished.</p>
+<p>Using the tempory context it is possible to store any XML
+          information for processing the current request.</p>
+  
+  
+<h1>Session-Context Input Module</h1>
+    
+<p>In addition to the <em>session transformer</em>, the <em>session-context input module</em>
+      can be used directly in the sitemap to get information out of a context.</p>
+    
+<p>The information for the input module consists of two parts, the first
+      one being the context name and the second one the path inside the
+      context. Let's have a look at an example:</p>
+    
+<pre class="code">
+&lt;map:generate src="{session-context:request/method}.xml"/&gt;      
+    </pre>
+    
+<p>
+      In the example above, either <em>GET.xml</em> or <em>POST.xml</em> is
+      read by the <em>file generator</em>, depending on the value from
+      the context <em>request</em> using the xpath <em>method</em>.
+    </p>
+      
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/meta.xml
new file mode 100644
index 0000000..85730c9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-contexts/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/webapps/contexts.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/content_en.html
new file mode 100644
index 0000000..6639250
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/content_en.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session Management</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Introduction</h1>
+     
+<p>This chapter describes the basic Cocoon session management using
+        the session transformer.</p>    
+
+     
+<p>The chapter "Special Contexts" explains some special
+        contexts which do not require a session. They are available everytime. These
+        special contexts are the request context and the
+        temporary context.</p>
+  
+  
+<h1>Session Tracking</h1>
+    
+<p>If a user has a session, Cocoon is able to connect new requests from this user
+       to the session of the user. This is done by session tracking. Basically,
+       the session tracking of Cocoon uses the session tracking of the environment,
+       which is usually the servlet engine.
+    </p>
+    
+<p>There are two methods for session tracking: cookies and url rewriting. If you
+       use cookies, you don't have to care about session tracking. Just refer to
+       the documentation of your servlet engine on how to turn on cookies for session
+       handling.</p>
+    
+<p>URL rewriting instead is a little bit complicated. For url rewriting, each link
+       the user can select, needs a special session ID appended to this link. 
+       Unfortunately, this is not done automatically by Cocoon or the servlet engine.
+       You can either do this by hand or you can use the <em>encodeURL</em> transformer
+       just before the <em>html serializer</em>.
+    </p>
+  
+  
+<h1>Sessions</h1>
+     
+<p>The session action is responsible for creating and
+        terminating a session. It is controlled by a sitemap parameter named "action".
+        This parameter can have the values "create" and "terminate". If no parameter is
+        set, it defaults to "create".</p>
+     
+<p>The action either creates a new session immediately (if not already
+        available), or terminates it (if available).</p>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/meta.xml
new file mode 100644
index 0000000..2b5e8ec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-session-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/webapps/session.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/content_en.html
new file mode 100644
index 0000000..7a6417c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/content_en.html
@@ -0,0 +1,149 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Simple Forms</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Introduction</h1>
+     
+<p>This chapter describes the (simple) form handling approach of
+       the session framework.</p>    
+     
+<div class="note">Cocoon provides several approaches for form handling. This
+       chapter explains one of them.</div>
+  
+  
+<h1>Form Handling</h1>
+     
+<p>To get feedback or information from a user, forms are commonly used
+        to present input field in the browser. The usual approach for form handling in
+        web application consists of two steps. The first request presents the form to
+        the user. This form initiates a second request that processes the form
+        values.</p>
+     
+<p>Cocoon supports this two step process, in addition Cocoon offers
+        a single step approach.</p>
+     
+<h2>The common approach</h2>
+<p>The common approach consists of two steps or of creating two
+          resources. The first resource defines the form: All input fields are declared,
+          each gets a unique name. This form invokes the second resource.</p>
+<p>This resource uses the session transformer to get the values
+          provided by the user. The values are added by the browser to the parameters of
+          the request. So using the request context and <em>getxml</em>, the values can
+          be fetched.</p>
+<p>If you want to create a form with two values - forename and surname
+          of the user, you could generate a base xml file with the information about this
+          form:</p>
+<pre class="code">&lt;page&gt;
+  &lt;form&gt;
+    &lt;action&gt;form-handling-page&lt;/action&gt;
+    &lt;input name="forename" type="text"/&gt;
+    &lt;input name="surname" type="text"/&gt;
+  &lt;/form&gt;
+&lt;/page&gt;</pre>
+<p>A stylesheet can transform this into valid html. The action tag
+          indicates that the "form-handling-page" should be invoked by submitting the
+          values.</p>
+<p>The "form-handling-page" is a pipeline which is declared in the
+          sitemap and uses the session transformer. It could also read the following
+          xml:</p>
+<pre class="code">&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;forename&gt;
+    &lt;session:getxml context="request" path="/parameter/forename"/&gt;
+  &lt;/forename&gt;
+  &lt;surname&gt;
+    &lt;session:getxml context="request" path="/parameter/surname"/&gt;
+  &lt;/surname&gt;
+&lt;/page&gt;</pre>
+<p>As the form values are appended to the request, <em>getxml</em>
+          with specifying the path (which is the parameter name used for the input field)
+          inserts the value submitted by the user into the xml stream.</p>
+<p>If you want to write the information in a session context, you must
+          wrap the whole xml inside a setxml:</p>
+<pre class="code">&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;session:setxml context="userdata" path="/user"&gt;
+    &lt;forename&gt;
+      &lt;session:getxml context="request" path="/parameter/forename"/&gt;
+    &lt;/forename&gt;
+    &lt;surname&gt;
+      &lt;session:getxml context="request" path="/parameter/surname"/&gt;
+    &lt;/surname&gt;
+  &lt;/session:setxml&gt;
+&lt;/page&gt;</pre>
+<p>The user data is now stored inside the session context "userdata",
+          so the context has the following content:</p>
+<pre class="code">&lt;user&gt;
+  &lt;forename&gt;Walter&lt;/forename&gt;
+  &lt;surname&gt;Walterson&lt;/surname&gt;
+&lt;/user&gt;</pre>
+     
+<h2>The Session Framework approach</h2>
+<p>The previous chapter showed the common approach for handling form
+          values. It forces the user to create two resources for a single form
+          handling.</p>
+<p>Cocoon offers an advanced approach. Only one single resource is
+          created. This resources contains the information about the input fields used
+          and in addition the information about where the submitted values should be
+          stored inside the session.</p>
+<p>The example from the previous chapter could look like this:</p>
+<pre class="code">&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;session:form name="myform"&gt;
+    &lt;session:action&gt;the-next-page&lt;/session:action&gt;
+    &lt;session:content&gt;
+      &lt;session:inputxml name="forename" type="text" context="userdata" path="/user/forename"/&gt;
+      &lt;session:inputxml name="surname" type="text" context="userdata" path="/user/surname"/&gt;
+    &lt;/session:content&gt;
+  &lt;/session:form&gt;
+&lt;/page&gt;</pre>
+<p>The form tag starts the form definition. The name attribute is
+          required to distinct between different forms on the same page. The action tag
+          defines the url invoked by the form and the content tag describes the content
+          of the form: its input fields.</p>
+<p>The <em>inputxml</em> tag tells Cocoon that the following request
+          contains form values which should be stored in the specified context under the
+          given path. The session transformer transforms by removing the namespace and
+          the context attribute:</p>
+<pre class="code">&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;form action="the-next-page"&gt;
+    &lt;inputxml name="forename" type="text"/&gt;
+    &lt;inputxml name="surname" type="text"/&gt;
+  &lt;/form&gt;
+&lt;/page&gt;</pre>
+<p>A stylesheet can now generate the appropriate html (or any other
+          format). The main difference is, that the resource invoked by submitting the
+          values has not to care about the form as Cocoon maintains the form handling.
+          The only prerequisit is that a session for the current user and a session
+          context to store the information exists.</p>
+<p>The Cocoon approach allows a very easy way of form handling where
+          the resource which creates the form also handles the form.</p>
+<p>For editing values - if the context already contains information
+          about the user - <em>inputxml</em> inserts the current value inside the tag. So
+          the xml streamed would after a second run would look like this:</p>
+<pre class="code">&lt;page xmlns:session="http://apache.org/cocoon/session/1.0"&gt;
+  &lt;form action="the-next-page"&gt;
+    &lt;inputxml name="forename" type="text"&gt;Walter&lt;/inputxml&gt;
+    &lt;inputxml name="surname" type="text"&gt;Walterson&lt;/inputxml&gt;
+  &lt;/form&gt;
+&lt;/page&gt;</pre>
+<p>Like <em>getxml</em> it is also possible to provide default values
+          for the input field, if the context does not contain any information:</p>
+<pre class="code">&lt;session:inputxml name="forename" context="userdata" path="/user/forename"&gt;
+     Defaultname
+&lt;/session:inputxml&gt;</pre>
+<p>But as always there is one drawback with this approach as well, you
+           have to put the <em>session-form-manager</em> action somewhere so
+           that it is called when the form values are submitted. As this
+           action does no harm, it can simply be put as the first action in your
+           main sitemap:</p>
+<pre class="code">
+        &lt;map:act type="session-form-manager"/&gt;
+        </pre>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/meta.xml
new file mode 100644
index 0000000..7c6ed76
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-session-fw-webapp-forms/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/webapps/forms.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/content_en.html
new file mode 100644
index 0000000..40ae93a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/content_en.html
@@ -0,0 +1,147 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Velocity Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in @doctitle@" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the Velocity template generator." name="DC.Description">
+</head>
+<body>
+  
+<h1>Velocity Generator</h1>
+  
+<p>
+   Allows Velocity template to be used as a generator. 
+   Builds upon the Velocity servlet functionality - overrides 
+   the output method in order to pipe the results into SAX events.
+  </p>
+  
+  
+<ul>
+   
+<li>Name : velocity</li>
+   
+<li>Class: org.apache.cocoon.generation.VelocityGenerator</li>
+   
+<li>Cacheable: ????.</li>
+  
+</ul>
+  
+<pre class="code">
+
+&lt;map:generate type="velocity"/&gt;
+
+  </pre>
+
+  
+<p>
+   Cocoon Generator that produces dynamic XML SAX events
+   from a Velocity template file.
+  </p>
+ 
+  
+<h2>Sitemap Configuration</h2>
+<p>
+    Attributes:
+   </p>
+<dl>
+    
+<dt>usecache (optional; default: 'false')</dt> 
+    
+<dd>
+     set to 'true' to enable template caching on the 'cocoon'
+     resource loader
+    </dd>
+   
+    
+<dt>checkInterval (optional; default: '0')</dt>
+    
+<dd>
+     This is the number of seconds between modification checks when
+     caching is turned on.  When this is an integer &gt; 0, this represents
+     the number of seconds between checks to see if the template was
+     modified. If the template has been modified since last check, then
+     it is reloaded and reparsed. Otherwise nothing is done. When &lt;= 0,
+     no modification checks will take place, and assuming that the
+     property cache (above) is true, once a template is loaded and
+     parsed the first time it is used, it will not be checked or
+     reloaded after that until the application or servlet engine is
+     restarted.
+    </dd>
+   
+</dl>
+<p>
+   Child Elements:
+   </p>
+<dl>
+    
+<dt>&lt;property name="propertyName" value="propertyValue"/&gt;
+     (optional; 0..n)</dt>
+    
+<dd>
+     An additional property to pass along to the Velocity template
+     engine during initialization
+    </dd>
+    
+    
+<dt>&lt;resource-loader name="loaderName" class="javaClassName"/&gt;
+     (optional; 0..n; children: property*)</dt>
+    
+<dd>
+     The default configuration uses the 'cocoon' resource loader
+     which resolves resources via the Cocoon SourceResolver. Additional
+     resource loaders can be added with this configuration
+     element. Configuration properties for the resource loader can be
+     specified by adding a child property element of the resource-loader
+     element. The prefix '&lt;name&gt;.resource.loader.' is
+     automatically added to the property name.
+    </dd>
+    
+    
+<dt>&lt;export-object key="objectMapKey" name="velocityContextName"/&gt;
+     (optional; 0..n)</dt>
+    
+<dd>
+     Export the object specified by <em>key</em> from the Cocoon
+     object map to the Velocity context of the template.  The object can
+     be accessed from the template as <em>name</em>. Be careful to use a
+     valid VTL variable name.
+    </dd>
+   
+</dl>
+<p>
+    Default Java objects exported to the Velocity context:
+   </p>
+<dl>
+    
+<dt>request (org.apache.cocoon.environment.Request)</dt>
+    
+<dd>The Cocoon current request</dd>
+    
+    
+<dt>template (java.lang.String)</dt>
+    
+<dd>The path of the template file currently being evaluated</dd>
+    
+    
+<dt>response (org.apache.cocoon.environment.Response)</dt>
+    
+<dd>The Cocoon response associated with the current request</dd>
+    
+    
+<dt>context (org.apache.cocoon.environment.Context)</dt>
+    
+<dd>The Cocoon context associated with the current request</dd>
+    
+    
+<dt>parameters (org.apache.avalon.framework.parameters.Parameters)</dt>
+    
+<dd>Any parameters passed to the generator in the pipeline</dd>
+   
+</dl>
+ 
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/meta.xml
new file mode 100644
index 0000000..8c4a3aa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-velocity-velocity-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/velocity-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/content_en.html
new file mode 100644
index 0000000..bc89642
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/content_en.html
@@ -0,0 +1,405 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Web3</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Web3 Connectivity Toolkit" name="DC.Subject">
+<meta content="Michael Gerzabek" name="DC.Creator">
+</head>
+<body>
+		
+<h1>About</h1>
+			
+<p>
+				
+<a class="external" href="http://www.efp.cc/web3">EFP Consulting Austria</a> produced an open-source library called Web3
+				that allows you to integrate SAP R/3 seamlessly into Cocoon 2. With these components you are able to call Remote 
+				Function Calls via an easy to use XML-syntax. For most BAPIs and Remote enabled Function Calls you simply need 
+				a text editor.
+			</p>
+			
+<p>This toolkit offers you ...</p>
+				
+<ul>
+					
+<li>... synchron communication to any SAP system above release 3.1H.</li>
+					
+<li>... easy to use ABAP function calls from outside R/3 with a se37-like markup-syntax.</li>
+				
+</ul>
+			
+<div class="note">
+				The following guide helps you to setup cocoon with your SAP R/3. Reasonably this guide cannot answer
+				all questions dealing with your environment. For further questions be advised to contact your favorite SAP Consultant.
+			</div>
+		
+		
+<h1>Installing SAP R/3 (TM) JavaConnector</h1>
+			
+<p>
+					Be sure to proper install the appropriate SAP Java-Connector from <a class="external" href="http://service.sap.com/connectors">
+					www.sap.com</a>. To install the connector refer to the included documentations.
+			</p>
+		
+		
+<h1>Configuring cocoon.xconf</h1>
+			
+<p>
+					With Web3 you have a flexible Toolkit where you can connect to multiple R/3 System within one single Cocoon-
+					Instance. Enter your backend configuration into cocoon.xconf like this:
+			</p>
+			
+<h2>Items</h2>
+<table>
+					Configuration elements
+					<tr>
+						
+<th colspan="1" rowspan="1">Element</th>
+						<th colspan="1" rowspan="1">Description</th>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">web3</td>
+						<td colspan="1" rowspan="1">Declare your logger here.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">pool</td>
+						<td colspan="1" rowspan="1">The pool element is the logical unit of all your SAP settings.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">client</td>
+						<td colspan="1" rowspan="1">The systems client you log onto.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">user, password, language</td>
+						<td colspan="1" rowspan="1">...</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">route</td>
+						<td colspan="1" rowspan="1">The route to your SAP system. Please refer to your <a class="external" href="http://help.sap.com">SAP help</a> to prepare the connection string.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">system</td>
+						<td colspan="1" rowspan="1">The system-number of your SAP system you log onto.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">gateway, program-id</td>
+						<td colspan="1" rowspan="1">Are mandatory and not used within Web3's szenario.</td>
+					
+</tr>
+				
+</table>
+<table>
+                    Specifics on the pool element
+					<tr>
+                       
+<td colspan="1" rowspan="1">@trace</td><td colspan="1" rowspan="1">a <span class="codefrag">boolean</span> switch whether to use JCO's facility to trace the 	communication layer or not.</td>
+                    
+</tr>
+                    
+<tr>
+					   
+<td colspan="1" rowspan="1">@level</td><td colspan="1" rowspan="1">if @trace is <span class="codefrag">true</span> set the trace-level to your prefered value. Please refer to the JCO's documentation about tracing.</td>
+                    
+</tr>
+                    
+<tr>
+					   
+<td colspan="1" rowspan="1">@size</td><td colspan="1" rowspan="1">denotes the pool-size of your sap connection pool. Be aware that this is a hard-limited pool.</td>
+                    
+</tr>
+				
+</table>
+			
+<p>
+				A configuration in your cocoon.xconf would look like this:
+			</p>
+
+				
+<pre class="code">&lt;web3 logger="core.web3"&gt;
+	&lt;backend name="indy"&gt;
+		&lt;pool level="0" size="10" trace="false"&gt;
+			&lt;client&gt;100&lt;/client&gt;
+			&lt;user&gt;user&lt;/user&gt;
+			&lt;password&gt;secret-passphrase&lt;/password&gt;
+			&lt;language&gt;DE&lt;/language&gt;
+			&lt;route&gt;indy&lt;/route&gt;
+			&lt;system&gt;00&lt;/system&gt;
+			&lt;gateway&gt;sapgw00&lt;/gateway&gt;
+			&lt;program-id&gt;USR-GR02&lt;/program-id&gt;
+		&lt;/pool&gt;
+	&lt;/backend&gt;
+	&lt;backend name="hugo"&gt;
+	...
+&lt;/web3&gt;</pre>
+
+		
+
+		
+<h1>Implementing your own RFC's</h1>
+			
+<p>First of all you have to setup your markup with the right Namespace</p>
+			
+<pre class="code">&lt;page xmlns:rfc="http://apache.org/cocoon/Web3-Rfc/1.0"&gt;
+	...
+&lt;/page&gt;</pre>
+			
+<p>After doing so you can enter RFC-mappings with the following syntax. You will see this is a very easy task and you will enjoy
+			using Web3 to do the stuff for you within your SAP environment :)</p>
+			
+<h2>Web3 rfc-Syntax</h2>
+<p>
+					Data definitions (metadata) are created and managed in the ABAP Dictionary. The ABAP Dictionary permits a central 
+					description of all the data used in the system without redundancies. New or modified information is automatically provided 
+					for all the system components. This ensures data integrity, data consistency and data security.
+				</p>
+<p>
+					The syntax used within this markup builds upon these facts. So do not wonder if you find the corresponding logical
+					units in the Cocoon frontend.
+				</p>
+<table>
+					Markup
+					<tr>
+						
+<th colspan="1" rowspan="1">Element</th>
+						<th colspan="1" rowspan="1">Description</th>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_include">rfc:include</a>
+						</td>
+						<td colspan="1" rowspan="1">Starts a mapping for the specified RFC.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_import">rfc:import</a>
+						</td>
+						<td colspan="1" rowspan="1">Container element for structures and fields.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_tables">rfc:tables</a>
+						</td>
+						<td colspan="1" rowspan="1">Container element for tables.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_structure">rfc:structure</a>
+						</td>
+						<td colspan="1" rowspan="1">Container element for fields.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_table">rfc:table</a>
+						</td>
+						<td colspan="1" rowspan="1">Container element for structures.</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							<a href="#rfc_field">rfc:field</a>
+						</td>
+						<td colspan="1" rowspan="1">The data-fields.</td>
+					
+</tr>
+				
+</table>
+
+			
+<a name="rfc_include"></a>
+			
+<h2>rfc:include</h2>
+<p>First when you start to map a RFC keep in mind to get the parameters from your SAP system. Therefore you
+				may want to use se37 where all relevant parameters are listed. The <span class="codefrag">@name</span> has to be the name of
+				the RFC you want to map. </p>
+<p>Since many RFC's return hierarchical data split into tables you will encounter some
+				problems in xslt when rendering these data to trees. So you may implement <span class="codefrag">org.apache.cocoon.components.web3.Web3Streamer</span> to get a proper XML to work with. You can set your own streamer in the
+				<span class="codefrag">@streamer</span>.</p>
+<table>
+					Attributes
+					<tr>
+						
+<th colspan="1" rowspan="1">Attribute</th>
+						<th colspan="1" rowspan="1">Description</th>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							@name
+						</td>
+						<td colspan="1" rowspan="1">The name of the SAP RFC</td>
+					
+</tr>
+					
+<tr>
+						
+<td colspan="1" rowspan="1">
+							@streamer
+						</td>
+						<td colspan="1" rowspan="1">The class-name of your function streamer. Most of the time you won't need to implement it anyway.</td>
+					
+</tr>
+				
+</table>
+<p></p>
+			
+<a name="rfc_import"></a>
+			
+<h2>rfc:import</h2>
+<p>
+					When requesting a RFC you have to fill the import parameterlist. The import parameterlist lists all relevant parameters
+					that have to be provided to get proper results from your R/3.</p>
+<p>se37 can provide you with the relevant information.
+				</p>
+			
+<a name="rfc_tables"></a>
+			
+<h2>rfc:tables</h2>
+<p>
+					Some highly complex RFC's have also tables in their calling interface. You may need to read the SAP documentation of the
+					BAPI you gotta call and when to make use of one of them.
+				</p>
+			
+<a name="rfc_structure"></a>
+			
+<h2>rfc:structure</h2>
+<p>
+					A structure comprises fields. A field can refer to an elementary type (via a data element or by directly specifying the data type and length in the structure definition), another structure or a table type. A structure can therefore be nested to any depth.
+				</p>
+<div class="note">At the time the facility to use nested structures has not been tested!</div>
+			
+<a name="rfc_table"></a>
+			
+<h2>rfc:table</h2>
+<p>
+					A table consists of a collection of structures with same structure type. To keep it simple we can sloppily say a table is like
+					a SQL-database-table.
+				</p>
+			
+<a name="rfc_field"></a>
+			
+<h2>rfc:field</h2>
+<p>
+					Fields, also called data elements are the smallest indivisible units of the complex types and are used to specify the types 
+					in structures and columns of tables. A field describes either an elementary type or a reference type.</p>
+<p>
+					In ABAP exist predefined types and custom defined types. But don't worry about the horrible task of converting into the right
+					type. This task is excellently done for you by the JavaConnector.
+				</p>
+<div class="note">
+					Keep in mind that the communication format for numbers and date is US. So supply <span class="codefrag">Date</span> information
+					in format YYYY-MM-DD with the slashes and <span class="codefrag">number</span> information like DDDDD.DD where the dot is the comma!
+				</div>
+			
+<p>If you want to check your RFC mappings for syntactically correctness you may want to use the enclosed <span class="codefrag">dtd</span>'s.</p>
+		
+		
+<h1>A more complex example</h1>
+			
+<p>
+				The included example demonstrates a more complex function call. Keep in mind that the correct execution
+				depends on the local customizing settings of the connected SAP System.
+			</p>
+			
+<pre class="code">&lt;page xmlns:rfc="http://apache.org/cocoon/Web3-Rfc/1.0"&gt;
+  &lt;rfc:include name="XXX" streamer="XXX"&gt;
+    &lt;rfc:import&gt;
+      &lt;rfc:structure name="XXX"&gt;
+        &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+        &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+        &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+      &lt;/rfc:structure&gt;
+      &lt;rfc:tables&gt;
+        &lt;rfc:table name="XXX"&gt;
+          &lt;rfc:structure name="1"&gt;
+            &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+            &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+            &lt;rfc:field name="XXX"&gt;YYY&lt;/rfc:field&gt;
+          &lt;/rfc:structure&gt;
+        &lt;/rfc:table&gt;
+      &lt;/rfc:tables&gt;
+    &lt;/rfc:import&gt;
+  &lt;/rfc:include&gt;
+&lt;/page&gt;</pre>
+		
+		
+<h1>Setting up the sitemap</h1>
+			
+<p>There are two ways to setup your Web3Transformer in the sitemap.</p>
+			
+<h2>Global Configuration</h2>
+<p>If you have to deal only with one R/3 Instance you may
+				configure your <span class="codefrag">org.apache.cocoon.transformation.Web3RfcTransformer</span>
+				global like stated in the following sitemap snippet.</p>
+<pre class="code">
+&lt;map:transformer name="rfc" 
+                 src="org.apache.cocoon.transformation.Web3RfcTransformer" 
+                 logger="web3.transformation"&gt;
+  &lt;system&gt;indy&lt;/system&gt;
+&lt;/map:transformer&gt;
+</pre>
+              
+<h2>Parametrized Configuration</h2>
+<p>If you have setup several R/3 pools you can parametrize the
+                   <span class="codefrag">org.apache.cocoon.transformation.Web3RfcTransformer</span> as stated next</p>
+<pre class="code">
+&lt;map:transform type="rfc"&gt;
+  &lt;map:parameter name="backend" value="indy"/&gt;
+&lt;/map:transform&gt;
+</pre>
+		
+		
+<h1>Further questions</h1>
+			
+<p>
+				Enjoy using Web3. For further questions feel free to contact the author 
+				<a href="mailto:michael.gerzabek.at.at.efp.cc">Michael Gerzabek</a>
+			
+</p>
+		
+		
+<div align="center">
+<img class="figure" alt="Built with Apache Cocoon" src="images/cocoon-built.gif"></div>
+	
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/meta.xml
new file mode 100644
index 0000000..c2bfb4f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-web3-sap-r3/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/web3.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/content_en.html
new file mode 100644
index 0000000..a3e1605
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/content_en.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XML:DB Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gianugo Rabellino" name="DC.Creator">
+<meta content="This document describes the XML:DB generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Warning!</h1>
+      
+<p>
+        The XML:DB generators are currently unmaintained and going to be 
+        deprecated soon. Please use the XML:DB pseudo-protocol instead.
+      </p>  
+    
+    
+<h1>XML:DB Generator</h1>
+      
+<p>
+         Generates XML documents out of an XML:DB compliant database. XML:DB
+         is a generic API developed by the XML:DB group in order to allow access
+         via a consistent API to the upcoming XML databases such as dbXML,
+         Ozone and eXist (as of now only the first one has an almost compliant
+         API implementation).
+         For the sake of this document, an XML:DB compliant database can be 
+         seen as a filesystem where directories are called "collections" and 
+         files are called "resources".
+      </p>
+      
+<ul>
+        
+<li>Name: xmldb</li>
+        
+<li>Class: org.apache.cocoon.generation.XMLDBGenerator</li>
+        
+<li>Cacheable: no</li>
+      
+</ul>
+      
+<p>
+         The generator needs to be configured in a "JDBCish" way: a driver 
+         (a class name) must be provided, together with a "base" URI. An example
+         configuration, based on the stock dbXML implementation, will look like 
+         this:
+      </p>
+
+<pre class="code">
+&lt;map:generator name="xmldb"
+               src="org.apache.cocoon.generation.XMLDBGenerator"
+               label="content"&gt;
+  &lt;driver&gt;org.dbxml.client.xmldb.DatabaseImpl&lt;/driver&gt;
+  &lt;base&gt;xmldb:dbxml:///db/&lt;/base&gt;
+&lt;/map:generator&gt;
+</pre>
+      
+<p>
+         Note that the content of the "base" tag will be prepended to the 
+         requested resource. It's important to keep a trailing slash at the
+         end of the <span class="codefrag">base</span> tag.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/meta.xml
new file mode 100644
index 0000000..def8f83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldb-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/xmldb-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/content_en.html
new file mode 100644
index 0000000..0ecaf89
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/content_en.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XML:DB Collection Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gianugo Rabellino" name="DC.Creator">
+<meta content="This document describes the XML:DB
+     Collection generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Warning!</h1>
+      
+<p>
+        The XML:DB generators are currently unmaintained and going to be 
+        deprecated soon. Please use the XML:DB pseudo-protocol instead.
+      </p>  
+    
+    
+<h1>XML:DB Collection Generator</h1>
+      
+<p>
+        As for the filesystem there are two generators provided (a file
+        generator and a directory generator), so is for XML:DB, which 
+        can roughly be tought as an XML filesystem, where Collections
+        stand for directories and Resources stand for (XML) files.
+      </p>
+      
+<p>
+        This generator outputs a list of collections and resources
+        given a starting collection. It can be used together with
+        the XMLDBGeneratot, and coupled with the appropriate XSLT, 
+        to easily navigate any XML:DB compliant database. 
+      </p>
+      
+<ul>
+        
+<li>Name: xmldbcollection</li>
+        
+<li>Class: org.apache.cocoon.generation.XMLDBCollectionGenerator</li>
+        
+<li>Cacheable: no</li>
+      
+</ul>
+      
+<p>
+         The configuration is the same of the XMLDBGenerator: it needsi
+         a driver (a class name) and base URI. An example
+         configuration, based on the stock dbXML implementation, will look like 
+         this:
+      </p>
+
+<pre class="code">
+&lt;map:generator name="xmldbcollection"
+               src="org.apache.cocoon.generation.XMLDBGenerator"
+               label="content"&gt;
+  &lt;driver&gt;org.dbxml.client.xmldb.DatabaseImpl&lt;/driver&gt;
+  &lt;base&gt;xmldb:dbxml:///db/&lt;/base&gt;
+&lt;/map:generator&gt;
+</pre>
+      
+<p>
+         Note that the content of the "base" tag will be prepended to the 
+         requested resource. It's important to keep a trailing slash at the
+         end of the <span class="codefrag">base</span> tag.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/meta.xml
new file mode 100644
index 0000000..42d56b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xmldb-xmldbcollection-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/xmldbcollection-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/content_en.html
new file mode 100644
index 0000000..dc97927
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/content_en.html
@@ -0,0 +1,678 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ESQL Taglib</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Donald A. Ball Jr." name="DC.Creator">
+<meta content="Robin Green" name="DC.Creator">
+</head>
+<body>
+
+    
+<h1>Description</h1>
+
+    
+<p>The ESQL logicsheet is an XSP logicsheet that performs sql queries and
+    serializes their results as XML. This allows you to work with data from a
+    wide variety of different sources when using Apache Cocoon.
+   </p>
+
+   
+<p>It has a number of important advantages over the old (deprecated) SQL
+    logicsheet and SQL processor. For example, it allows you to mix esql with
+    other logicsheets. It also supports prepared statements (which gives you
+    automatic parameter escaping), multiple encodings in a single query and
+    even multiple resultsets on one statement (if supported from database)!</p>
+
+    
+<p>The name was chosen merely to emphasise the fact that this is an
+    extended version of the old sql logicsheet - esql still uses standard SQL
+    syntax. In fact, it is just a conversion wrapper around your JDBC database
+    driver, so it supports no more and no less SQL syntax than your JDBC driver
+    supports.
+    </p>
+  
+
+  
+<h1>Installation</h1>
+   
+<p>Check your <span class="codefrag">cocoon.xconf</span> for this line and add it if it's not already there:</p>
+   
+<pre class="code">
+&lt;builtin-logicsheet&gt;
+  &lt;parameter name="prefix" value="esql"/&gt;
+  &lt;parameter name="uri" value="http://apache.org/cocoon/SQL/v2"/&gt;
+  &lt;parameter name="href"
+  value="resource://org/apache/cocoon/components/language/markup/xsp/java/esql.xsl"/&gt;
+&lt;/builtin-logicsheet&gt;
+</pre>
+  
+
+  
+<h1>Configuration</h1>
+   
+<p>Map the</p>
+   
+<pre class="code">http://apache.org/cocoon/SQL/v2</pre>
+   
+<p>namespace to the esql prefix. Elements in the esql taglib namespace will be interpreted as input to 
+    the esql taglib and will be stripped from the output.</p>
+   
+<p>This is typically done like this:</p>
+   
+<pre class="code">
+&lt;xsp:page
+      language="java"
+      xmlns:xsp="http://apache.org/xsp"
+      xmlns:esql="http://apache.org/cocoon/SQL/v2"
+&gt;
+. . .
+&lt;/xsp:page&gt;
+</pre>
+    
+   
+<h2>Connection</h2>
+<p>Esql can use connection pools configured in <span class="codefrag">cocoon.xconf</span> or
+   individually set up connections.</p>
+<p>
+<span class="codefrag">esql:pool</span> gives the name of the connection pool to use.</p>
+<p>Individually configured connections use the <span class="codefrag">esql:driver,
+    esql:dburl, esql:username, esql:password</span> tags. Their meaning
+   should be obvious.</p>
+<h3>Connection Options</h3>
+<p>Per default, esql will try to switch a connection to <em>autocommit</em>
+   mode. This is because it prevents hanging transactions that hold locks and
+   disturb further database accesses. Esql can be forced to not use
+   autocommit, by giving the
+   <span class="codefrag">&lt;esql:autocommit&gt;false&lt;/esql:autocommit&gt;</span> nested
+   element to <span class="codefrag">esql:connection</span>.</p>
+<div class="note">Even if a connection is configured with autocommit off in
+   <span class="codefrag">cocoon.xconf</span>, esql will switch autocommit on if not
+   instructed to do otherwise.</div>
+<p>Other options like limiting the size of the resultset are discussed
+   below.</p>
+
+  
+
+  
+<h1>Usage and Examples</h1>
+   
+<p>At the moment documentation on esql is quite thin on the ground -
+    however, it should be enough to get you started. In the
+    <span class="codefrag">docs/samples/xsp</span> directory you will find
+    <span class="codefrag">esql.xsp</span>, which is an example of two esql queries,
+    demonstrating "nested" queries and dynamic prepared statements. However,
+    much more comprehensive is the <strong>schema</strong> in
+    <span class="codefrag">esql.xsd</span> which is a formal specification, written in the W3C
+    standard language XML Schema, of every single esql element and attribute.
+    It is fairly human-readable and includes comments for the purpose of each
+    tag.</p>
+
+   
+<p>A fairly common example is to list a query result in a table. Notice that
+    esql:results and esql:no-results are mutual exclusive. So only one of them
+    will be in your XML tree. This example takes a connection from a datasource
+    defined in <span class="codefrag">cocoon.xconf</span>:</p>
+
+   
+<pre class="code">
+&lt;esql:connection&gt;
+  &lt;esql:pool&gt;connectionName&lt;/esql:pool&gt;
+  &lt;esql:execute-query&gt;
+    &lt;esql:query&gt;SELECT mycolumn1,mycolumn2 FROM table&lt;/esql:query&gt;
+    &lt;esql:results&gt;
+      &lt;table&gt;
+        &lt;esql:row-results&gt;
+          &lt;tr&gt;
+             &lt;td&gt;&lt;esql:get-string column="mycolumn1"/&gt;&lt;/td&gt;
+             &lt;td&gt;&lt;esql:get-string column="mycolumn2"/&gt;&lt;/td&gt;
+          &lt;/tr&gt;
+        &lt;/esql:row-results&gt;
+      &lt;/table&gt;
+    &lt;/esql:results&gt;
+    &lt;esql:no-results&gt;
+       &lt;p&gt;Sorry, no results!&lt;/p&gt;
+    &lt;/esql:no-results&gt;
+  &lt;/esql:execute-query&gt;
+&lt;/esql:connection&gt;
+</pre>
+
+   
+<h2>Dynamic Queries</h2>
+<p>When a query contains dynamic parts, e.g. a value that is to be matched,
+     esql offers two different possibilities to achieve that. First, as the 
+     query is really a string, it can be constructed like any other string by 
+     concattenation.
+    </p>
+<pre class="code">
+    &lt;xsp:logic&gt;
+       String orderBy = null;
+       switch(type) {
+       case 1: orderBy = "order by name"; break;
+       case 2: orderBy = "order by salary"; break;
+       default: orderBy = "";
+       }
+    &lt;/xsp:logic&gt;
+
+    &lt;!-- ... --&gt;
+
+    &lt;esql:query&gt;&lt;xsp:expr&gt;"SELECT name, salary FROM employee "+orderBy&lt;/xsp:expr&gt;&lt;/esql:query&gt;
+
+</pre>
+<p>Note, however, that here any string will be part of the actual
+     statement. In this example it does no harm as the value for the
+     <span class="codefrag">orderBy</span> variable is completely under the control of
+     your code. Any malicious attacker could not inject his or her own
+     code. Thus this technique should not be used when values returned
+     from the client have to be used.
+    </p>
+<p>The second variant is to use a PreparedStatement for dynamic 
+     parameters. Since the driver is supposed to keep parameters
+     distinct from the statement, no code can be injected this way. In
+     addition, your DBMS puts more effort into optimizing the
+     statement. PreparedStatements are created whenever a
+     <span class="codefrag">&lt;esql:parameter/&gt;</span> tag appears in a query. 
+    </p>
+<pre class="code">
+    &lt;esql:query&gt;SELECT name, salary FROM employee 
+                WHERE name=&lt;esql:parameter&gt;&lt;xsp:expr&gt;name&lt;/xsp:expr&gt;&lt;/esql:parameter&gt;&lt;/esql:query&gt;
+
+   </pre>
+
+   
+<h2>Refering to Results</h2>
+<p>A select query usually returns one ResultSet. This case is handled by
+     the <span class="codefrag">esql:results</span> tag and its content. However, many special
+     cases exist, e.g. an error occurs or an update query is used. Esql
+     provides different tags for these cases.
+    </p>
+<p>If an empty result set is returned, the <span class="codefrag">esql:no-results</span>
+     block is used.</p>
+<h3>Errors</h3>
+<p>In case of an error, usually signalled by an Exception during setup or
+      execution of a query, the <span class="codefrag">esql:error-results</span> block is
+      evaluated. If no such tag exists, the exception is rethrown and
+      processing is stopped. Withing the tag, <span class="codefrag">esql:get-message</span>,
+      <span class="codefrag">esql:get-stacktrace</span>, and <span class="codefrag">esql:to-string</span> allow
+      access to the error message.</p>
+<h3>Limiting the number of rows returned</h3>
+<p>Esql allows to display only a part of the result set using the
+      <span class="codefrag">esql:use-limit-clause</span>. If your DBMS is supported, the DBMS
+      generates only the indicated rows, otherwise a number of rows are skipped
+      and retrieval is stopped after a given number of rows. It works like a
+      fixed-size window to the result set, paging through it.</p>
+<p>These parameters are set for a connection.</p>
+<p>If the <span class="codefrag">esql:use-limit-clause</span> is empty or set to "auto",
+      esql tries to determine automatically which method to use, depending on
+      the connection URL.</p>
+<p>
+<span class="codefrag">esql:skip-rows</span> and <span class="codefrag">esql:max-rows</span> tags specify
+      how many rows should be skipped at the beginning and how many rows should
+      be retrieved at maximum.</p>
+<p>In this context the <span class="codefrag">esql:previous-results</span> and
+      <span class="codefrag">esql:more-results</span> blocks hold code and content that is only
+      used if this sliding window has previous or following windows.</p>
+<pre class="code">
+&lt;esql:connection&gt;
+  &lt;esql:pool&gt;connectionName&lt;/esql:pool&gt;
+  &lt;esql:execute-query&gt;
+    &lt;esql:query&gt;SELECT mycolumn1,mycolumn2 FROM table&lt;/esql:query&gt;
+    &lt;esql:use-limit-clause&gt;auto&lt;/esql:use-limit-clause&gt;
+    &lt;esql:skip-rows&gt;&lt;xsp:expr&gt;skiprows&lt;/xsp:expr&gt;&lt;/esql:skip-rows&gt;
+    &lt;esql:max-rows&gt;10&lt;/esql:max-rows&gt;
+    &lt;esql:results&gt;
+      &lt;table&gt;
+        &lt;esql:row-results&gt;
+        &lt;esql:previous-results&gt;previous rows available&lt;/esql:previous-results&gt;
+        &lt;esql:more-results&gt;more rows available&lt;/esql:more-results&gt;
+          &lt;tr&gt;
+             &lt;td&gt;&lt;esql:get-string column="mycolumn1"/&gt;&lt;/td&gt;
+             &lt;td&gt;&lt;esql:get-string column="mycolumn2"/&gt;&lt;/td&gt;
+          &lt;/tr&gt;
+        &lt;/esql:row-results&gt;
+      &lt;/table&gt;
+    &lt;/esql:results&gt;
+    &lt;esql:error-results&gt;An error occurred&lt;/esql:error-results&gt;
+    &lt;esql:no-results&gt;
+       &lt;p&gt;Sorry, no results!&lt;/p&gt;
+    &lt;/esql:no-results&gt;
+  &lt;/esql:execute-query&gt;
+&lt;/esql:connection&gt;
+</pre>
+<h3>Updates</h3>
+<p>In JDBC, updates, inserts, and deletes are "update queries". For those,
+      no results are available but an update count is returned, indicating,
+      how many rows were affected.</p>
+<p>Code or content that depends on this has to be placed inside the
+      <span class="codefrag">esql:update-results</span> tag. It is used whenever at least one
+      row was affected. The update count can be accessed through the
+      <span class="codefrag">esql:get-update-count</span> tag.
+     </p>
+<p>If no rows where affected, the <span class="codefrag">esql:no-results</span> block is
+      used.</p>
+<pre class="code">
+&lt;esql:connection&gt;
+  &lt;esql:pool&gt;connectionName&lt;/esql:pool&gt;
+  &lt;esql:execute-query&gt;
+    &lt;esql:query&gt;update table set price=price*1.17&lt;/esql:query&gt;
+    &lt;esql:error-results&gt;An error occurred&lt;/esql:error-results&gt;
+    &lt;esql:update-results&gt;
+       &lt;esql:get-update-count/&gt; prices adjusted.
+    &lt;/esql:update-results&gt;
+    &lt;esql:no-results&gt;
+       &lt;p&gt;Sorry, no prices adjusted!&lt;/p&gt;
+    &lt;/esql:no-results&gt;
+  &lt;/esql:execute-query&gt;
+&lt;/esql:connection&gt;
+</pre>
+
+   
+<h2>Groups</h2>
+<p>For more complex lists, often nested queries are needed. Esql allows
+     arbitrary nesting of queries. However, you can do table joins and then
+     insert a header whenever a "watched" column value changes using the
+     <span class="codefrag">&lt;esql:group/&gt;</span> and <span class="codefrag">&lt;esql:member/&gt;</span>
+     tags.  It follows the nesting ideology of <span class="codefrag">&lt;xsp:logic&gt; ...
+      &lt;xsp:content&gt;&lt;/&gt;&lt;/&gt;</span>You can nest
+     <span class="codefrag">&lt;esql:group&gt;</span> and <span class="codefrag">&lt;esql:member&gt;</span>
+     indefinately. <span class="codefrag">group-on</span> can be an attribute of
+     <span class="codefrag">group</span> or a text node. The value of the text node has
+     precedence over the attribute. The value can be the column name or the
+     column number. 
+     </p>
+<pre class="code">
+&lt;esql:execute-query&gt;
+  &lt;esql:query&gt;
+    select committeeName, title, firstName, middleName, lastName, suffix, status 
+    from committeeMember left join directoryInformation using(userid)
+         left join committee on committee.id=committeeMember.committeeid 
+    order by committeeName asc
+  &lt;/esql:query&gt;
+  &lt;esql:results&gt;
+    &lt;esql:row-results&gt;
+      &lt;esql:group group-on="committeeName"&gt;
+        &lt;h2&gt;&lt;esql:get-string column="committeeName"/&gt;&lt;/h2&gt;
+        &lt;ul&gt;
+          &lt;esql:member&gt;
+            &lt;li&gt;
+              &lt;esql:get-string column="title"/&gt;
+              &lt;esql:get-string column="firstName"/&gt;
+              &lt;esql:get-string column="middleName"/&gt;
+              &lt;esql:get-string column="lastName"/&gt;
+              &lt;esql:get-string column="suffix"/&gt;
+            &lt;/li&gt;
+          &lt;/esql:member&gt;
+        &lt;/ul&gt;
+      &lt;/esql:group&gt;
+    &lt;/esql:row-results&gt;
+  &lt;/esql:results&gt;
+&lt;/esql:execute-query&gt;
+    </pre>
+<p>One important limitation of the grouping feature is, that <em>no access
+      to a column may appear after closing a group.</em> The value will belong
+     to the following row or cause an error if no next row exists. If this is
+     needed, consider swapping columns using XSLT or embedded JAVA. Hence the
+     following example is illegal:</p>
+
+    
+<pre class="code">
+&lt;esql:execute-query&gt;
+  &lt;esql:query&gt;
+    select committeeName, committeeTitle, title, firstName, middleName, 
+           lastName, suffix, status 
+    from committeeMember left join directoryInformation using(userid)
+         left join committee on committee.id=committeeMember.committeeid 
+    order by committeeName asc
+  &lt;/esql:query&gt;
+  &lt;esql:results&gt;
+    &lt;esql:row-results&gt;
+      &lt;esql:group group-on="committeeName"&gt;
+        &lt;h2&gt;&lt;esql:get-string column="committeeName"/&gt;&lt;/h2&gt;
+        &lt;ul&gt;
+          &lt;esql:member&gt;
+            &lt;li&gt;
+              &lt;esql:get-string column="title"/&gt;
+              &lt;esql:get-string column="firstName"/&gt;
+              &lt;esql:get-string column="middleName"/&gt;
+              &lt;esql:get-string column="lastName"/&gt;
+              &lt;esql:get-string column="suffix"/&gt;
+            &lt;/li&gt;
+          &lt;/esql:member&gt;
+        &lt;/ul&gt;
+      &lt;/esql:group&gt;
+      &lt;esql:get-string column="committeeTitle"/&gt;&lt;!-- illegal !! --&gt;
+    &lt;/esql:row-results&gt;
+  &lt;/esql:results&gt;
+&lt;/esql:execute-query&gt;
+    </pre>
+
+
+   
+<h2>Stored Procedure Support</h2>
+<p>In order to use stored procedures replace
+     <span class="codefrag">&lt;esql:query/&gt;</span> with <span class="codefrag">&lt;esql:call/&gt;</span>, use
+     either DBMS specific syntax or JDBC escape syntax <span class="codefrag">{? =
+      foo(?)}</span>. If your jdbc driver requires to use the
+     <span class="codefrag">executeQuery()</span> method instead of the <span class="codefrag">execute()</span>
+     method (like e.g. INFORMIX does), set <span class="codefrag">needs-query="true"</span>
+     attribute.</p>
+<p>If a result set is returned through the (only) return parameter of a
+     stored procedure, e.g. <span class="codefrag">resultset-from-object="1"</span> as attribute
+     to <span class="codefrag">&lt;esql:call/&gt;</span>to automatically use this result set.
+     For a more general alternative see further below.</p>
+<p>Parameters for a stored procedure call may be of
+   <span class="codefrag">direction="in|out|inout"</span> with the usual JDBC meaning. In
+   addition a <span class="codefrag">type</span> needs to be supplied for "out" and "inout"
+   parameters. This would be the same "XXX" as used in a <span class="codefrag">get-XXX</span>
+   JDBC-method call. Alternatively, you can use a fully qualified field name,
+   e.g. "java.sql.Types.CHAR"</p>
+<p>
+<span class="codefrag">&lt;esql:call-results/&gt;</span> (child of
+     <span class="codefrag">&lt;esql:execute-query/&gt;</span>) may contain code that will
+     always be executed whether the query returned a result or not. For example
+     most stored procedures will not return a result set but several out
+     parameters.</p>
+<p>All <span class="codefrag">&lt;esql:get-xxx/&gt;</span> tags accept a new attribute
+     <span class="codefrag">from-call="yes"</span> to indicate that the value is retrieved from
+     the CallableStatement rather than the current ResultSet. Obviously, this
+     only works after a call to a stored procedure.</p>
+<p>Retrieve a ResultSet from any column and use it like the result of a
+     nested query with the <span class="codefrag">esql:use-results</span> tag. It behaves
+     exactly like nesting queries. Thus the <span class="codefrag">ancestor</span> attribute can
+     be used to access e.g. the original query.</p>
+<p>Example:</p>
+<pre class="code">
+&lt;esql:call&gt;{? = foo(&lt;esql:parameter direction="in"
+  type="Int"&gt;&lt;xsp:expr&gt;1&lt;/xsp:expr&gt;&lt;/esql:parameter&gt;)}
+&lt;/esql:call&gt;
+&lt;esql:call-results&gt;
+  &lt;esql:use-results&gt;
+    &lt;esql:result&gt;&lt;xsp:expr&gt;(ResultSet)&lt;esql:get-object column="1" from-call="true"/&gt;&lt;/xsp:expr&gt;&lt;/esql:result&gt;
+    &lt;esql:results&gt;
+      &lt;esql:row-results&gt;
+        &lt;esql:get-string column="1"/&gt;
+      &lt;/esql:row-results&gt;
+    &lt;/esql:results&gt;
+  &lt;/esql:use-results&gt;
+&lt;/esql:call-results&gt;
+</pre>
+<p>Example:</p>
+<pre class="code">
+&lt;esql:query&gt;select name, list_of_aliases from table&lt;/esql:query&gt;
+&lt;esql:results&gt;
+  &lt;esql:row-results&gt;
+    &lt;p&gt;
+      &lt;esql:get-string column="name"/&gt;: 
+      &lt;esql:use-results&gt;
+        &lt;esql:result&gt;&lt;xsp:expr&gt;&lt;esql:get-array column="list_of_aliases"/&gt;.getResultSet()&lt;/xsp:expr&gt;&lt;/esql:result&gt;
+        &lt;esql:results&gt;
+          &lt;esql:row-results&gt;
+            &lt;esql:get-string column="1"/&gt;
+          &lt;/esql:row-results&gt;
+        &lt;/esql:results&gt;
+      &lt;/esql:use-results&gt;
+    &lt;/p&gt;
+  &lt;/esql:row-results&gt;
+&lt;/esql:results&gt;
+</pre>
+
+   
+<h2>Multiple Results</h2>
+<p>If multiple results are returned from a stored procedure or a query, the
+     <span class="codefrag">esql:results</span> block is reused. However, it is supported to
+     have different blocks for each result. Since a result can either be a
+     ResultSet or an UpdateCount, both are counted independently. The nth
+     ResultSet will be handled by the nth <span class="codefrag">esql:results</span> block, or -
+     if there are fewer blocks - the last one.</p>
+<p>The same holds true for <span class="codefrag">esql:update-results</span> and
+     <span class="codefrag">esql:no-results</span> blocks as well.</p>
+<div class="note">Support for multiple results is not widely available with DBMSs.
+   Therefore support is disabled by default. Use the
+   <span class="codefrag">&lt;esql:allow-multiple-results&gt;yes&lt;/esql:allow-multiple-results&gt;</span> 
+   parameter to the &lt;esql:connection/&gt;.</div>
+<p>Example: Suppose stored procedure <span class="codefrag">bar</span> returns an update
+     count, another update count, a result set, an update count, and a
+     last result set.</p>
+<pre class="code">
+&lt;esql:call&gt;{? = bar(&lt;esql:parameter direction="in"
+type="Int"&gt;&lt;xsp:expr&gt;1&lt;/xsp:expr&gt;&lt;/esql:parameter&gt;)}
+&lt;/esql:call&gt;
+&lt;esql:results&gt;
+  &lt;!-- this is used for the first result set --&gt;
+&lt;/esql:results&gt;
+&lt;esql:results&gt;
+  &lt;!-- this is used for the second and 
+       all following result sets --&gt;
+&lt;/esql:results&gt;
+&lt;esql:update-results&gt;
+  &lt;!-- this is used for the first update count --&gt;
+&lt;/esql:update-results&gt;
+&lt;esql:no-results&gt;
+  &lt;!-- this is used for the first update count --&gt;
+&lt;/esql:no-results&gt;
+&lt;esql:update-results&gt;
+  &lt;!-- this is used for the second and 
+       all following update counts --&gt;
+&lt;/esql:update-results&gt;
+&lt;esql:no-results&gt;
+  &lt;!-- this is used for the second and 
+       all following update counts --&gt;
+&lt;/esql:no-results&gt;
+</pre>
+
+   
+<p>The ultimate reference, is of course the source code, which is an XSLT
+    logicsheet contained in the file
+    <span class="codefrag">src/org/apache/cocoon/components/language/markup/xsp/java/esql.xsl</span>
+</p>
+
+   
+<p>Of course, we would be very grateful for any improvements on this
+    documentation or further examples - please send them to <a href="mailto:users.at.cocoon.apache.org">users.at.cocoon.apache.org</a>!</p>
+   
+  
+
+
+  
+<h1>Template Descriptions</h1>
+   
+<table>
+    
+<tr>
+     
+<th colspan="1" rowspan="1">Tag</th>
+     <th colspan="1" rowspan="1">Description</th>
+    
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-columns</td>
+          <td colspan="1" rowspan="1">results in a set of elements whose names are the names of the columns. the elements each have one text child, whose value is the value of the column interpreted as a string. No special formatting is allowed here. If you want to mess around with the names of the elements or the value of the text field, use the type-specific get methods and write out the result fragment yourself. For Cocoon 2 only, this outputs structured types as well. Here sql-list or sql-set contains several sql-list-item or sql-set-item element that again contain the actual data.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-string</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a string</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-date</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a date. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-time</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a time. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-timestamp</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a timestamp. if a format attribute exists, its value is taken to be a date format string as defined in java.text.SimpleDateFormat, and the result is formatted accordingly.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-boolean</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as true or false</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-double</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a double. if a format attribute exists, its value is taken to be a decimal format string as defined in java.text.DecimalFormat, and the result is formatted accordingly.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-float</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a float. if a format attribute exists, its value is taken to be a decimal format string as defined in java.text.DecimalFormat, and the result is formatted accordingly.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-int</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as an integer</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-long</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a long</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-short</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a short</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-ascii</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a clob</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-object</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as an object</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-array</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as an java.sql.Array. This is frequently used for collection 
+          datatypes like lists, sets, bags etc.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-struct</td>
+          <td colspan="1" rowspan="1">returns the value of the given column as a java.sql.Struct. This is frequently used for row types.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-xml</td>
+          <td colspan="1" rowspan="1">returns the value of the given column interpreted as an xml fragment.
+ The fragment is parsed by the default xsp parser and the document element is returned.
+ If a root attribute exists, its value is taken to be the name of an element to wrap around the contents of
+ the fragment before parsing.</td>
+ 
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:results//esql:get-column-count</td>
+          <td colspan="1" rowspan="1">returns the number of columns in the resultset.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-row-position|esql:results//esql:get-row-position</td>
+          <td colspan="1" rowspan="1">returns the position of the current row in the result set</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-column-name</td>
+          <td colspan="1" rowspan="1">returns the name of the given column. the column must be specified by number, not name.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-column-label</td>
+          <td colspan="1" rowspan="1">returns the label of the given column. the column must be specified by number, not name.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:get-column-type-name</td>
+          <td colspan="1" rowspan="1">returns the name of the type of the given column. the column must be specified by number, not name.</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:row-results//esql:is-null</td>
+          <td colspan="1" rowspan="1">allows null-column testing. Evaluates to a Java expression, which is true when the referred column contains a null-value for the current resultset row</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:error-results//esql:get-message</td>
+          <td colspan="1" rowspan="1">returns the message of the current exception</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:error-results//esql:to-string</td>
+          <td colspan="1" rowspan="1">returns the current exception as a string</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:error-results//esql:get-stacktrace</td>
+          <td colspan="1" rowspan="1">returns the stacktrace of the current exception</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:results/esql:get-metadata</td>
+          <td colspan="1" rowspan="1">returns the metadata associated with the current resultset</td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">esql:results/esql:get-resultset</td>
+          <td colspan="1" rowspan="1">returns the current resultset</td>
+          
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">esql:group</td>
+      <td colspan="1" rowspan="1">Allows header elements around groups of consecutive records with identical values in column named by @group-on.  Facilitates a single query with joins to be used in lieu of some nested queries.</td>
+          
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">esql:member</td>
+      <td colspan="1" rowspan="1">Used in conjunction with and nested inside esql:group.  Formatting for individual records goes within esql:member. Header stuff goes in between group and member.</td>
+      
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">@*|node()</td>
+          <td colspan="1" rowspan="1">used internally to determine which column is the given column. if a column attribute exists and its value is a number, it is taken to be the column's position. if the value is not a number, it is taken to be the column's name. if a column attribute does not exist, an esql:column element is assumed to exist and to render as a string (after all of the xsp instructions have been evaluated), which is taken to be the column's name.</td>
+          
+</tr>
+       
+</table>
+      
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/meta.xml
new file mode 100644
index 0000000..aedf9d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-esql/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/esql.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/content_en.html
new file mode 100644
index 0000000..0f4735a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/content_en.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>User Documentation - XSP</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Ricardo Rocha" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+
+  
+<p>
+    Here will soon appear an overview of the user perspective of XSP.   
+  </p>
+
+  
+<p>The actual user documentation is available from the side-panel.
+  </p>
+
+ 
+
+  
+<h1>XSP learning map</h1>
+    
+<p>As I find that there is enough information about XSP available (only
+      not together), I give you a list of pointers in the sequence you should read
+      them.</p> 
+    
+<ol>
+      
+<li>Get Cocoon <a href="../../installing/index.html">up and running</a>. Surf
+    to <span class="codefrag">[webhost]/cocoon/slides/slides?section=4</span> and following. This
+    gives you a first insight in the XSP ground idea.</li>
+    
+<li>Read the XSP Logicsheets page. This tells you how to use and make
+      your own XSP logicsheets and XSP pages.</li>
+    
+<li>If you're still hungry for more, read the XSP Internals page. This
+      describes how XSP's are handled internally by Cocoon.</li>
+    
+</ol>
+   
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/meta.xml
new file mode 100644
index 0000000..d4dff54
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-index/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/content_en.html
new file mode 100644
index 0000000..8b18c84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/content_en.html
@@ -0,0 +1,1939 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XSP Internals</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ricardo Rocha" name="DC.Creator">
+</head>
+<body>
+   
+<h1>Index</h1>
+     
+<p>
+       This document presents Apache Cocoon's dynamic markup language
+       framework and its use in implementing XSP:
+     </p>
+
+     
+<ul>
+       
+<li>
+         
+<a href="#markup-to-code">
+           Markup-to-code Transformation
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#cocoon-generators">
+           XSP and Cocoon Generators
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#programming-language">
+           The Programming Language Processor
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#compiled-languages">
+           Compiled Languages
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#interpreted-languages">
+           Interpreted Languages
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#markup-language">
+           The Markup Language Processor
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#xsp-language">
+           The XSP Markup Language
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#dom-xsp">
+           The DOM-XSP Markup Language
+         </a>
+       
+</li>
+       
+<li>
+        
+<a href="#program-generator">
+          The Program Generator
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#named-components">
+           Named Components
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#sitemap-configuration">
+           XSP Sitemap Configuration
+         </a>
+       
+</li>
+     
+</ul>
+  
+
+ 
+<a name="markup-to-code"></a>
+ 
+<h1>Markup-to-code Transformation</h1>
+  
+<p>
+    XSP is based on a general-purpose markup-to-code transformation engine
+    built around three key abstractions:
+  </p>
+
+  
+<ul>
+   
+<li>
+<strong>Dynamic Markup Language</strong>.
+       An namespace-qualified XML vocabulary providing
+       <em>code embedding</em>
+       directives.
+
+       An associated
+       <em>dynamic markup language processor</em>
+       transforms static markup interspersed with code embedding directives
+       into an equivalent
+       <em>source program string</em>
+       written in a
+       <em>target programming language</em>.
+
+       Upon execution, the generated program will rebuild the original XML
+       document as augmented by dynamic content emitted by the embedded code.
+   </li>
+   
+<li>
+<strong>Programming Language</strong>.
+       A procedural language in which the dynamic markup processor generates
+       source code from an input XML document. Its associated
+       <em>programming language processor</em>
+       is responsible for compiling, loading and executing the generated code
+       within the boundaries of its calling environment.
+   </li>
+   
+<li>
+<strong>Program Generator</strong>.
+       A component that integrates markup and programming language processors
+       to build and execute markup-generating programs derived from XML
+       documents. Beyond this "glue" role, this component is responsible for
+       persistently storing generated programs as well as automatically
+       rebuilding them should their source XML documents change on disk after
+       program generation.
+   </li>
+  
+</ul>
+
+  
+<div class="note">
+    Despite its particular usage for XSP,
+    <a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
+      <span class="codefrag">ProgramGenerator</span>
+    </a>
+    is not restricted to run in a server pages environment.
+  </div>
+ 
+
+ 
+<a name="cocoon-generators"></a>
+ 
+<h1>XSP and Cocoon Generators</h1>
+  
+<p>
+    As a rule, XSP pages are translated into Cocoon
+    <a href="../../apidocs/org/apache/cocoon/generation/Generator.html">
+      <span class="codefrag">Generator</span>'s.
+    </a>
+  
+</p>
+
+  
+<h2>Server Pages Generator Proxy</h2>
+<p>
+      
+<span class="codefrag">Generator</span>'s created by XSP are invoked exclusively through
+      <a href="../../apidocs/org/apache/cocoon/generation/ServerPagesGenerator.html">
+        <span class="codefrag">ServerPagesGenerator</span>,
+      </a>
+      a proxy that uses Cocoon's
+      <a href="#program-generator"><span class="codefrag">ProgramGenerator</span></a>
+      component to load pages and subsequently delegates actual SAX event
+      generation to them.
+    </p>
+<div class="note">
+      The terms <span class="codefrag">Generator</span> and <span class="codefrag">ProgramGenerator</span> are
+      somewhat confusing. Here, <span class="codefrag">Generator</span> refers to a Cocoon
+      <span class="codefrag">org.apache.cocoon.generation.Generator</span> instance responsible
+      for the initial feeding of Cocoon's SAX pipeline.
+      <span class="codefrag">ProgramGenerator</span>, on the other hand, refers to a Cocoon
+      component responsible for building and executing programs derived from XML
+      documents containing dynamic markup:
+      <a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
+        <span class="codefrag">org.apache.cocoon.components.language.generator.ProgramGenerator</span>
+      </a>
+    
+</div>
+<p>
+      
+<span class="codefrag">ServerPagesGenerator</span>
+      attempts to cope with a not unlikely
+      possibility: <em>premature</em> termination of proxied generator
+      execution.
+      "Premature" here means that the invoked generator may return after
+      starting one or more SAX events but without properly ending them.
+    </p>
+<p>
+      While this not an expected scenario in "manual" SAX programming, server
+      pages may well need to terminate in the middle of document production:
+    </p>
+<pre class="code">
+  &lt;page&gt;
+    &lt;title&gt;For Your Eyes Only&lt;/title&gt;
+
+    &lt;xsp:logic&gt;
+      if (!request.getParameter("pet").equals("Cheetah")) {
+        &lt;p&gt;
+          Hey, you're not Tarzan!
+        &lt;/p&gt;
+
+        /*** Unclosed SAX events here! ***/
+        return;
+      }
+    &lt;/xsp:logic&gt;
+    &lt;!-- Multi-racial Jane affair description follows --&gt;
+    . . .
+  &lt;/page&gt;
+</pre>
+<p>
+      The server pages generator proxy is defined in the sitemap as follows:
+    </p>
+<pre class="code">
+. . .
+&lt;map:generator
+  name="serverpages"
+  src="org.apache.cocoon.generation.ServerPagesGenerator"/&gt;
+. . .
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    . . .
+    &lt;map:match pattern="/samples/*.xsp"&gt;
+      &lt;map:generate type="serverpages" src="../samples/documents/{1}.xsp"&gt;
+        &lt;!--
+          &lt;parameter name="markup-language" value="xsp"/&gt;
+          &lt;parameter name="programming-language" value="java"/&gt;
+        --&gt;
+      &lt;/map:generate&gt;
+      &lt;map:transform type="xslt" src="../samples/stalemates/simple-page.xsl"/&gt;
+      &lt;map:serialize type="html" mime-type="text/html"/&gt;
+    &lt;/map:match&gt;
+    . . .
+  &lt;/map:pipeline&gt;
+&lt;/map:pipelines&gt;
+</pre>
+<p>
+      Note that parameters <span class="codefrag">markup-language</span> and
+      <span class="codefrag">programming-language</span> default to
+      <em>xsp</em> and <em>java</em> respectively.
+    </p>
+<p>
+      The complete XSP sitemap configuration is explained
+      <a href="#sitemap-configuration">below</a>.
+    </p>
+
+  
+<h2>XSP Generators and Compiled Languages</h2>
+<p>
+     For the Java language (and other compiled languages like
+     <a class="external" href="http://www.mozilla.org/rhino/"><em>Rhino</em></a>
+     Javascript),
+     XSP pages are translated into classes extending
+     <a href="../../apidocs/org/apache/cocoon/generation/AbstractServerPage.html">
+       <span class="codefrag">AbstractServerPage</span>
+     </a>.
+     This class, in turn, extends
+     <a href="../../apidocs/org/apache/cocoon/generation/ComposerGenerator.html">
+       <span class="codefrag">ComposerGenerator</span>
+     </a>,
+     which gives it access to commonly used components such as
+     <em>parser</em> or <em>cocoon</em> itself (typically used as
+     <span class="codefrag">EntityResolver</span> for request URI's).
+   </p>
+<p>
+     
+<span class="codefrag">AbstractServerPage</span> implements
+       <span class="codefrag">org.apache.arch.Modifiable</span>.
+     This
+     is tested by <span class="codefrag">ProgramGenerator</span> to assert whether the page has
+     been invalidated as a result of files it depends on having changed on disk.
+     These files are typically
+     <a href="#logicsheet"><em>logicsheets</em></a>
+     and template files included by means of XInclude.
+   </p>
+<div class="note">
+     As of this writing, XInclude support is still unimplemented but
+     will be based on
+     <a href="mailto:balld.at.webslingerZ.com">Donald Ball</a>'s
+     (possibly extended)
+     <a href="../../apidocs/org/apache/cocoon/transformation/XIncludeTransformer.html">
+       <span class="codefrag">XIncludeTransformer</span>.
+     </a>
+   
+</div>
+<p>
+     
+<span class="codefrag">AbstractServerPage</span> implements <span class="codefrag">Modifiable</span>
+     by means of two <em>static</em> variables:
+     <span class="codefrag">dateCreated</span> and
+     <span class="codefrag">dependencies</span> (a, possibly empty, array of
+     <span class="codefrag">File</span>'s pointing to logicsheets and other files included
+     during the code generation stage).
+   </p>
+<p>
+     
+<span class="codefrag">AbstractServerPage</span> also provides a boolean
+     <span class="codefrag">hasContentChanged()</span> method that is tested by
+     <span class="codefrag">ServerPagesGenerator</span> to assert whether dynamic content should
+     not be regenerated for a given request. The default implementation
+     unconditionally returns <span class="codefrag">true</span>, but can be overridden by XSP
+     pages based on their interpretation of the Cocoon <span class="codefrag">request</span>
+     object.  This is an <em>experimental</em> feature that will become
+     meaningful only when a SAX-event caching mechanism is added to Cocoon.
+   </p>
+<p>
+     Finally, <span class="codefrag">AbstractServerPage</span> also provides a number of utility
+     methods used to shorten the generation of SAX events not requiring a
+     namespace.
+   </p>
+ 
+
+
+ 
+<a name="programming-language"></a>
+ 
+<h1>The Programming Language Processor</h1>
+   
+<p>
+     A Cocoon's
+     <a href="../../apidocs/org/apache/cocoon/components/language/programming/ProgrammingLanguage.html">
+       <span class="codefrag">ProgrammingLanguage</span>
+     </a>
+     processor exposes the
+     following methods:
+   </p>
+
+   
+<ul>
+     
+<li>
+<span class="codefrag">load</span>.
+         Load a program from a file in a given directory,
+         compiling it, if necessary, using a given encoding.
+     </li>
+     
+<li>
+<span class="codefrag">instantiate</span>
+         Create a new instance of a previously loaded program
+     </li>
+     
+<li>
+<span class="codefrag">unload</span>
+         Discard a previously loaded program performing any
+         necessary cleanup
+     </li>
+     
+<li>
+<span class="codefrag">getSourceExtension</span>
+         Return the canonical source file extension used by
+         this programming language
+     </li>
+     
+<li>
+<span class="codefrag">getCodeFormatter</span>
+         Return an (optional) instance of
+          <a href="../../apidocs/org/apache/cocoon/components/language/programming/CodeFormatter.html">
+           <span class="codefrag">CodeFormatter</span>
+         </a>
+         used to beautify source code written in this programming language
+     </li>
+     
+<li>
+<span class="codefrag">quoteString</span>
+         Escape a string constant according to the programming language rules
+     </li>
+   
+</ul>
+
+   
+<p>
+     A default implementation (<a href="../../apidocs/org/apache/cocoon/components/language/programming/AbstractProgrammingLanguage.html">
+       <span class="codefrag">AbstractProgrammingLanguage</span>
+     </a>) is
+     provided that extends
+       <span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
+     and retrieves language-related sitemap parameters.
+   </p>
+
+   
+<h2>Filenames and Encoding</h2>
+<p>
+       
+<span class="codefrag">load</span> and <span class="codefrag">unload</span> are passed a file/directory
+       pair used to locate the program.
+     </p>
+<p>
+       The <span class="codefrag">baseDirectory</span> should be an absolute pathname
+       pointing to the top-level directory (also known as <em>repository</em>)
+       containing the program file.
+     </p>
+<p>
+       The <span class="codefrag">filename</span> is a path, <em>relative to the
+       <span class="codefrag">baseDirectory</span></em>, pointing to the program file.
+     </p>
+<p>
+       Source program filenames are built by concatenating the repository's
+       <span class="codefrag">baseDirectory</span> name, the given <span class="codefrag">filename</span>,
+       the dot extension separator and the language-specific source or
+       object <em>extensions</em>. The cross-platform
+       <span class="codefrag">File.separator</span> is used to ensure portability.
+     </p>
+<div class="note">
+       The <span class="codefrag">filename</span> must <strong>not</strong> contain any
+       source or object extension. It may, though, contain subdirectories
+       depending on its position within the repository tree. Also,
+       programming languages <strong>must</strong> define a source extension
+       even when their actual compilers/interpreters do not enforce this. This
+       is also true of <em>object</em> extensions for compiled languages.
+       Furthermore, the dot character is <em>always</em> used as the
+       extension separator.
+     </div>
+<p>
+       Finally, the (optional) <span class="codefrag">encoding</span> argument specifies the
+       how the source program file contents are encoded. This argument can be
+       <span class="codefrag">null</span> to specify the platform's default encoding.
+     </p>
+
+
+   
+<a name="program-load"></a>
+   
+<h2>Loading Programs</h2>
+<p>
+       Currently, programs returned by the <span class="codefrag">load</span> operation are
+       "plain" Java <span class="codefrag">Object</span>'s and are not required to implement
+       any interface or to extend any particular class.
+     </p>
+<div class="note">
+       This may change in the future so that the loaded program may be
+       required to provide dependency information (for automatic reloading)
+       as well as source code information (for debugging purposes).
+     </div>
+<p>
+       Compiled programs attempt to locate the <em>object program</em> first.
+       If found, it's loaded in a language-specific way and then returned to
+       the calling environment.
+       Failing that, the source file is located and the language-specific
+       <a href="#compiler">compiler</a> is invoked prior to actual
+       program loading.
+     </p>
+<p>
+       Of course, it is an error for the source program file not to exist as
+       a readable, regular operating system file.
+     </p>
+
+   
+<a name="program-unload"></a>
+   
+<h2>Unloading Programs</h2>
+<p>
+       When a previously loaded program is no longer needed (or becomes
+       "outdated" as explained below) the language processor may need to
+       perform cleanup actions, such as releasing memory or (in the case
+       of Java-like compiled languages)
+       <a href="#class-loader-reinstantiation">
+       reinstantiating the class loader</a>.
+     </p>
+<p>
+       Loaded programs may become outdated as a consequence of events external
+       to the programming language processor. In a server pages environment,
+       this is the result of the source XML document (or any of the files
+       it depends on) having changed on disk.
+     </p>
+<p>
+       The base class
+       <span class="codefrag">AbstractProgrammingLanguage</span>
+       implements
+       this method <em>as <span class="codefrag">final</span></em> to delete the unloaded
+       <em>source</em> program file and delegate actual unloading to
+       method <span class="codefrag">doUnload</span>.
+     </p>
+<p>
+       Method <span class="codefrag">doUnload</span> is <em>not</em> defined as
+       <span class="codefrag">abstract</span> in order to relieve interpreted subclasses
+       from having to implement an empty method when no cleanup is
+       required.
+     </p>
+<div class="note">
+       Currently, only the <span class="codefrag">program</span> object is being passed
+       to <span class="codefrag">unload</span>. It may be possible for some interpreted
+       languages to also require knowing what file the program was originally
+       loaded from. In this case, instantiation should take place through
+       the program object itself, rather than through the language processor
+       (see <em>Program Instantiation</em> below)
+     </div>
+
+   
+<a name="program-instantiation"></a>
+   
+<h2>Instantiating Programs</h2>
+<p>
+       The <span class="codefrag">program</span> object returned by <span class="codefrag">load</span> must
+       act as an factory capable of creating <em>program instance</em>
+       objects on demand.
+     </p>
+<p>
+       Currently, instantiation is performed by the language processor
+       given a previously loaded <span class="codefrag">program</span>.
+     </p>
+<p>
+       Compiled programs use a language-specified
+       <a href="#class-loader">class loader</a> to create
+       a new program instance.
+     </p>
+<div class="note">
+      For compiled languages, it is possible to guarantee that a
+      generated program implements a given interface or extends a
+      given class. For interpreted languages, though, it may be
+      necessary to pass an additional <span class="codefrag">prototype</span> object
+      to <span class="codefrag">load</span> as to ensure that created instances conform
+      to a given Java type expected behavior.
+     </div>
+
+   
+<a name="source-extension"></a>
+   
+<h2>Source Extensions</h2>
+<p>
+       All languages are required to return a <em>source extension</em>.
+       This extension is used to locate source files for subsequent
+       interpretation or compilation.
+     </p>
+
+   
+<a name="code-formatting"></a>
+   
+<h2>Code Formatting</h2>
+<p>
+       Programming languages may provide a
+       <a href="../../apidocs/org/apache/cocoon/components/language/programming/CodeFormatter.html">
+         <span class="codefrag">CodeFormatter</span>
+       </a>
+       instance used by code generators to beautify source code.
+     </p>
+<p>
+       Interface
+       <span class="codefrag">CodeFormatter</span>
+       exposes a single method:
+       <span class="codefrag">formatCode</span>. <span class="codefrag">formatCode</span> takes as
+       arguments a <span class="codefrag">String</span> containing the source code to
+       be beautified and an <span class="codefrag">encoding</span> to be preserved
+       during string conversions.
+     </p>
+<p>
+       Code formatters can be associated with a programming language
+       by specifying a <span class="codefrag">code-formatter</span> parameter in its
+       sitemap configuration:
+     </p>
+<pre class="code">
+&lt;parameter name="code-formatter"
+  value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/&gt;
+</pre>
+<div class="note">
+       Currently,
+       <a class="external" href="http://astyle.sourceforge.net/">Jstyle</a>
+       is being used for Java source formatting. This open source project
+       appears to be stagnated and lacks advanced formatting options
+       present in other (unfortunately, not open-sourced) products like
+       <a class="external" href="http://www.jindent.com/">Jindent</a>.
+     </div>
+
+   
+<a name="string-quoting"></a>
+   
+<h2>String Quoting</h2>
+<p>
+       Method <span class="codefrag">quoteString</span> applies the programming language string
+       constant escaping rules to its input argument.
+     </p>
+<p>
+       This method exists to assist markup language code generators in
+       escaping <span class="codefrag">Text</span> XML nodes.
+     </p>
+ 
+
+ 
+<a name="compiled-languages"></a>
+ 
+<h1>Compiled Languages</h1>
+   
+<p>
+     Compiled languages extend the <span class="codefrag">ProgrammingLanguage</span>
+     abstraction by introducing the notions of <em>compilation</em>
+     and <em>object extension</em>.
+   </p>
+
+   
+<p>
+     A base implementation
+    <a href="../../apidocs/org/apache/cocoon/components/language/programming/CompiledProgrammingLanguage.html">
+       (<span class="codefrag">CompiledProgrammingLanguage</span>)
+     </a>
+     is provided that adds the following protected variables and
+     abstract/overridable methods:
+   </p>
+
+   
+<ul>
+     
+<li>Variable <span class="codefrag">compilerClass</span>. Used to create instances
+         of the language's
+         <a href="#compiler">compiler</a>.
+     </li>
+     
+<li>Variable <span class="codefrag">deleteSources</span>. Used to state whether
+         intermediate source files should be deleted after successful
+         compilation
+     </li>
+     
+<li>Method <span class="codefrag">getObjectExtension</span>. Used to build object
+         filenames
+     </li>
+     
+<li>Method <span class="codefrag">loadProgram</span>. Used to perform actual program
+         load after source and (possibly) object files have been located
+     </li>
+     
+<li>Method <span class="codefrag">doUnload</span>. Used to perform cleanup after
+         program unloading
+     </li>
+   
+</ul>
+
+   
+<div class="note">
+     Object files are not required to be <em>Java class files</em>.
+     It's up the the compiled programming language processor to handle
+     object files.
+   </div>
+
+   
+<p>
+     Compiled programming languages must specify their preferred compiler
+     as a sitemap parameter:
+   </p>
+
+
+<pre class="code">
+&lt;component-instance name="java"
+  class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
+  . . .
+  &lt;parameter name="compiler"
+    value="org.apache.cocoon.components.language.programming.java.Jikes"/&gt;
+  . . .
+&lt;/component-instance&gt;
+</pre>
+
+   
+<a name="object-extension"></a>
+   
+<h2>Object Extensions</h2>
+<p>All compiled languages are required to return a <em>source extension</em>.
+     This extension is used to locate object files for subsequent loading.</p>
+
+   
+<a name="object-load"></a>
+   
+<h2>Object Program Loading</h2>
+<p>
+       Concrete compiled programming languages must implement the abstract
+       method <span class="codefrag">loadProgram</span> to actually load an <em>object</em>
+       program resulting from compilation.
+     </p>
+
+   
+<a name="compilation"></a>
+   
+<h2>Program Compilation</h2>
+<p>
+       Compilation is delegated to a sitemap-specified
+       <span class="codefrag">LanguageCompiler</span> instance, as explained below.
+     </p>
+
+   
+<a name="compiler"></a>
+   
+<h2>Compilers</h2>
+<p>
+       Interface
+      <a href="../../apidocs/org/apache/cocoon/components/language/programming/LanguageCompiler.html">
+         <span class="codefrag">LanguageCompiler</span>
+       </a>
+       defines the
+       initialization and behavior for all compilers.
+     </p>
+<p>
+       Methods exposed by this interface are:
+     </p>
+<ul>
+       
+<li>
+<span class="codefrag">setFile</span>. Used to specify the source file to
+           be compiled. This should be an absolute filename
+       </li>
+       
+<li>
+<span class="codefrag">setSource</span>. Used to specify the directory where
+           dependent source files (if any) are stored
+       </li>
+       
+<li>
+<span class="codefrag">setDestination</span>. Used to specify the directory where
+           the generated object files should be placed
+       </li>
+       
+<li>
+<span class="codefrag">setClasspath</span>. Used to specify the class loading
+           path used by the compiler. While this option is named after
+           Java's <em>classpath</em> system variable, its semantics are
+           language-independent
+       </li>
+       
+<li>
+<span class="codefrag">setEncoding</span>. Used to specify the encoding used
+           by the input source file
+       </li>
+       
+<li>
+<span class="codefrag">compile</span>. The compiler's workhorse (boolean)
+       </li>
+       
+<li>
+<span class="codefrag">getErrors</span>. Used to retrieve a list of compilation
+           error messages should compilation fail
+       </li>
+     
+</ul>
+<a name="compiler-error"></a>
+<h3>Compiler Errors</h3>
+<p>
+         Error message producer by the compiler must be collected and
+         massaged by the <span class="codefrag">LanguageCompiler</span> in order to
+         wrap each of them as a <span class="codefrag">CompilerError</span> instance.
+       </p>
+<p>
+         Class
+         <a href="../../apidocs/org/apache/cocoon/components/language/programming/CompilerError.html">
+           <span class="codefrag">CompilerError</span>
+         </a>
+         exposes the following
+         methods:
+       </p>
+<ul>
+         
+<li>
+<span class="codefrag">getFile</span>. Returns the program filename originating
+             the error
+         </li>
+         
+<li>
+<span class="codefrag">isError</span>. Asserts whether the error is a server
+             error or simply a warning
+         </li>
+         
+<li>
+<span class="codefrag">getStartLine</span>. Returns the starting line of the
+             offending code
+         </li>
+         
+<li>
+<span class="codefrag">getStartColumn</span>. Returns the starting column (within
+              the starting line) of the offending code
+         </li>
+         
+<li>
+<span class="codefrag">getEndLine</span>. Returns the ending line of the
+             offending code
+         </li>
+         
+<li>
+<span class="codefrag">getEndColumn</span>. Returns the ending column (within
+              the ending line) of the offending code
+         </li>
+         
+<li>
+<span class="codefrag">getMessage</span>. Returns the actual error message text
+         </li>
+       
+</ul>
+<a name="java-compilers"></a>
+<h3>Java Compilers</h3>
+<p>
+         For the Java language, 2 pluggable compilers are available:
+       </p>
+<ul>
+           
+<li>
+<em>Javac</em>. A wrapper to Sun's builtin compiler
+           </li>
+           
+<li>
+<em>Jikes</em>. A wrapper to IBM's <em>Jikes</em> compiler
+           </li>
+         
+</ul>
+<p>
+           Both of these compilers are based on
+           <a href="../../apidocs/org/apache/cocoon/components/language/programming/java/AbstractJavaCompiler.html">
+             <span class="codefrag">AbstractJavaCompiler</span>.
+           </a>
+         
+</p>
+<a name="other-compilers"></a>
+<h3>Other Compilers</h3>
+<p>
+         Since
+         <a class="external" href="http://www.mozilla.org/rhino/"><em>Rhino</em></a>
+         Javascript provides its own, only compiler (<em>jsc</em>),
+         class <span class="codefrag">JavascriptLanguage</span> doesn't use the compiler
+         class initialized by <span class="codefrag">CompiledProgrammingLanguage</span>.
+       </p>
+
+   
+<a name="object-unload"></a>
+   
+<h2>Object Program Unloading</h2>
+<p>
+       
+<span class="codefrag">CompiledProgrammingLanguage</span> extends the default
+       implementation provided by
+       <span class="codefrag">AbstractProgrammingLanguage</span>
+       by deleting the <em>object</em> program file and
+       delegating actual unloading to the
+       <span class="codefrag">doUnload</span> method.
+     </p>
+<p>
+       Method <span class="codefrag">doUnload</span> provides an empty default implementation
+       that can be overridden by derived compiled languages should unloading
+       cleanup be actually required.
+     </p>
+<a name="class-loader-reinstantiation"></a>
+<p>
+       For Java-based compiled languages (i.e., those using
+       <em>class files</em> as their object format, unloading implies
+       reinstantiating their
+       <a href="#class-loader">class loader</a>
+       such that it "forgets" about previously loaded classes thus
+       becoming able to refresh class files updates since their last
+       load.
+     </p>
+<p>
+       This is a commonly-used workaround for the (somewhat buggy)
+       standard Java class loader, which doesn't provide for an
+       explicit method for reloading class files.
+     </p>
+
+   
+<a name="class-loader"></a>
+   
+<h2>The Cocoon Class Loader</h2>
+<p>
+       To circumvent standard Java class loaders limitation, Cocoon provides a
+       simple customized class loader
+       <a href="../../apidocs/org/apache/cocoon/components/classloader/RepositoryClassLoader.html">
+       (<span class="codefrag">RepositoryClassLoader</span>)
+     </a>
+       that features:
+     </p>
+<ul>
+       
+<li>A directory-based extensible classpath that can grow at execution
+           time
+       </li>
+       
+<li>Class reloading by means of reinstantiation
+       </li>
+     
+</ul>
+<p>
+       
+<span class="codefrag">RepositoryClassLoader</span> extends
+       <span class="codefrag">java.lang.ClassLoader</span> adding an
+       <span class="codefrag">addDirectory</span> method that adds the directory pointed to
+       by its <span class="codefrag">String</span> argument to its local classpath.
+     </p>
+<p>
+       Access to <em>protected</em> <span class="codefrag">RepositoryClassLoader</span> class
+       is proxied through interface
+       <a href="../../apidocs/org/apache/cocoon/components/classloader/ClassLoaderManager.html">
+         <span class="codefrag">ClassLoaderManager</span>.
+       </a>
+       This interface exposes the following methods:
+     </p>
+<ul>
+       
+<li>
+<span class="codefrag">addDirectory</span>. Passed to the proxied
+           <span class="codefrag">RepositoryClassLoader</span>
+       
+</li>
+       
+<li>
+<span class="codefrag">loadClass</span>. Passed to the proxied
+           <span class="codefrag">RepositortyClassLoader</span>
+       
+</li>
+       
+<li>
+<span class="codefrag">reinstantiate</span>. Used to discard the previous
+           class loader and create a new one
+       </li>
+     
+</ul>
+<p>
+       Class
+       <a href="../../apidocs/org/apache/cocoon/components/classloader/ClassLoaderManagerImpl.html">
+         <span class="codefrag">ClassLoaderManagerImpl</span>
+       </a>
+       implements
+       <span class="codefrag">ClassLoaderManager</span> in a singleton-like fashion that
+       ensures that only one instance of this class loader exists,
+       thus ensuring the reinstantiation mechanism works properly.
+     </p>
+<p>
+       The class loader can be specified in the sitemap on a per-language
+       basis:
+     </p>
+<pre class="code">
+&lt;component-instance name="java"
+  class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
+  . . .
+  &lt;parameter name="class-loader"
+    value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
+&lt;/component-instance&gt;
+</pre>
+<p>
+       Alternatively, the class loader can be specified in the sitemap as
+       a global component:
+     </p>
+<pre class="code">
+&lt;component
+  role="class-loader"
+  class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
+</pre>
+ 
+
+ 
+<a name="interpreted-languages"></a>
+ 
+<h1>Interpreted Languages</h1>
+   
+<p>
+     Interpreted languages for which a Java-based interpreter exists
+     are supported by means of IBM's outstanding
+     <a class="external" href="http://www.alphaworks.ibm.com/tech/bsf">
+       Bean Scripting Framework
+     </a> (BSF).
+   </p>
+
+   
+<p>
+     Currently, BSF supports:
+   </p>
+
+   
+<ul>
+     
+<li>Mozilla Rhino</li>
+     
+<li>NetRexx</li>
+     
+<li>Jacl</li>
+     
+<li>JPython</li>
+     
+<li>VBScript (Win32 only)</li>
+     
+<li>JScript (Win32 only)</li>
+     
+<li>PerlScript (Win32 only)</li>
+     
+<li>BML (Not applicable to server pages)</li>
+     
+<li>LotusXSL (Not applicable to server pages)</li>
+   
+</ul>
+
+   
+<div class="note">
+     Interpreted language support is still unimplemented!<br>
+     While BSF is extremely easy to use and very stable, there's still
+     a challenge in writing code-generation logicsheets for each of this
+     languages; this task requires familiarity with XSP internals, XSLT
+     and, above all, the programming language at hand...
+   </div>
+
+   
+<div class="note">
+     Despite being supported by BSF, Rhino Javascript is separately
+     supported by Cocoon as a compiled language in order to take
+     advantage of automatic class reloading and persistent class file
+     storage.
+   </div>
+
+   
+<div class="note">
+     Since <span class="codefrag">ProgramGenerator</span> clients will typically require
+     that program instances implement a given interface or extend a given
+     class, method <span class="codefrag">instantiate</span> in interface
+     <span class="codefrag">ProgrammingLanguage</span> may need to be augmented with a
+     <span class="codefrag">prototype</span> interface that can be used by each language
+     processor to ensure that the program instance can act as a Java
+     object of the given type.
+   </div>
+ 
+
+ 
+<a name="markup-language"></a>
+ 
+<h1>The Markup Language Processor</h1>
+   
+<p>
+     A Cocoon's
+     <a href="../../apidocs/org/apache/cocoon/components/language/markup/MarkupLanguage.html">
+       <span class="codefrag">MarkupLanguage</span>
+     </a>
+     processor exposes the
+     following methods:
+   </p>
+
+   
+<ul>
+     
+<li>
+<span class="codefrag">getEncoding</span>.
+         Return the encoding to be used in program generation and
+         compilation or <span class="codefrag">null</span> to use the platform's
+         default encoding
+     </li>
+     
+<li>
+<span class="codefrag">generateCode</span>.
+         Given a DOM <span class="codefrag">Document</span> written in a given
+         <em>markup language</em>, generate an equivalent  program in a given
+         <em>programming language</em>)
+     </li>
+   
+</ul>
+
+   
+<p>
+     A base markup language processor implementation is provided in
+     class
+     <a href="../../apidocs/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.html">
+       <span class="codefrag">AbstractMarkupLanguage</span>.
+     </a>
+     This class extends
+       <span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
+     to set the markup language's
+     associated namespace using the following required parameters:
+   </p>
+   
+   
+<ul>
+     
+<li>
+<span class="codefrag">prefix</span>.
+         The markup language's namespace prefix
+     </li>
+     
+<li>
+<span class="codefrag">uri</span>.
+         The markup language's namespace URI
+     </li>
+   
+</ul>
+
+
+<pre class="code">
+&lt;component-instance name="xsp"
+  class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
+  &lt;parameter name="prefix" value="xsp"/&gt;
+  &lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
+&lt;/component-instance&gt;
+</pre>
+
+   
+<p>
+     
+<span class="codefrag">AbstractMarkupLanguage</span> adds a number of
+     abstract/overridable methods that must be implemented by concrete
+     markup language processors:
+   </p>
+
+   
+<ul>
+     
+<li>
+<span class="codefrag">preprocessDocument</span>.
+         Augment the input DOM <span class="codefrag">Document</span> to prepare it for
+         simpler, faster logicsheet-based code generation
+     </li>
+     
+<li>
+<span class="codefrag">getLogicsheets</span>.
+         Return the list of logicsheets declared in the input document
+         according to the syntax of the markup language at hand
+     </li>
+     
+<li>
+<span class="codefrag">addDependency</span>.
+         Add a dependency on an external file. This is used to inform
+         the concrete markup language processor about XML documents
+         included by means of XInclude as well as any intervening
+         logicsheet
+     </li>
+   
+</ul>
+
+   
+<div class="note">
+     
+<span class="codefrag">AbstractMarkupLanguage</span> is currently tied to
+     logicsheets as the <em>only</em> means of generating source
+     code. While logicsheets provide a very powerful means for
+     code generation, good design dictates that the actual code
+     generation mechanism should be decoupled from the dynamic
+     markup language abstraction.
+   </div>
+
+   
+<div class="note">
+     The current code generation strategy is DOM-based. In principle,
+     this is adequate because document preprocessing may need random
+     access to document nodes. Code generation is being reconsidered,
+     however, to overcome this and make it possible to reuse Cocoon's
+     SAX-based filtering pipeline.
+   </div>
+
+   
+<a name="markup-encoding"></a>
+   
+<h2>Markup Encoding</h2>
+<p>
+       All markup languages must provide a way to declare the XML
+       document's encoding so that it is preserved during code generation,
+       beautifying and compilation.
+     </p>
+<p>
+       This is required for proper i18n support, where the default
+       encoding usually replaces "exotic" characters with question marks.
+     </p>
+<div class="note">
+       Ideally, it should be possible to determine the source XML document's
+       <span class="codefrag">encoding</span> from its declaring
+       <span class="codefrag">&lt;?xml?&gt;</span> processing instruction. Unfortunately,
+       XML parsers (both DOM and SAX) don't seem to provide access to it,
+       thus forcing server pages authors to redundantly specify it.
+     </div>
+
+    
+<a name="logicsheet-class"></a>
+    
+<h2>The Logicsheet class</h2>
+<a name="logicsheet"></a>
+<p>
+        A <em>logicsheet</em> is an XML filter used to translate user-defined
+        dynamic markup into equivalent code embedding directives for a given
+        markup language.
+      </p>
+<p>
+        Logicsheets lie at the core of XSP's promise to separate logic from
+        content and presentation: they make dynamic content generation
+        capabilities available to content authors not familiar with (and
+        not interested in) programming.
+      </p>
+<p>
+        For a detailed description of logicsheets, see
+        <a href="logicsheet-concepts.html">Logicsheet Concepts</a>.
+      </p>
+<p>
+        Logicsheets are represented in class
+        <a href="../../apidocs/org/apache/cocoon/components/language/markup/Logicsheet.html">
+          <span class="codefrag">Logicsheet</span>.
+        </a>
+        This
+        class exposes the following methods:
+      </p>
+<ul>
+        
+<li>
+<span class="codefrag">setInputSource</span>.
+            Set the <span class="codefrag">InputSource</span> pointing to the XSLT
+            stylesheet to be used for dynamic tag transformation
+        </li>
+        
+<li>
+<span class="codefrag">apply</span>.
+            Apply the stylesheet to a given document
+        </li>
+      
+</ul>
+<p>
+        
+<span class="codefrag">Logicsheet</span> takes care of preserving all namespaces
+        defined in the input document. This is necessary when multiple
+        logicsheets are applied and multiple namespaces are used in the
+        input document.
+      </p>
+<div class="note">
+        Currently, <span class="codefrag">Logicsheet</span> is a concrete class. It should
+        be redefined as an interface in order to decouple it from the use
+        of XSLT stylesheets. Again, while stylesheets are the "obvious" way
+        to implement logicsheets, a user-supplied XML filter may also be
+        used in some cases.
+        The current implementation uses an ugly
+        hack where a Xalan stylesheet processor is used to perform
+        the transformation without an intervening stylesheet processor
+        wrapping abstraction.
+      </div>
+
+    
+<a name="named-logicsheet"></a>
+    
+<h2>Named Logicsheets</h2>
+<p>
+        As explained in
+        <a href="logicsheet-concepts.html#logicsheet-object">
+          Logicsheet Concepts,
+        </a>
+        logicsheets are typically associated with a single object type whose
+        methods it wraps to make them available as
+        <em>markup commands</em>.
+      </p>
+<p>
+        Markup commands related to a given object type are grouped under a
+        single namespace.
+      </p>
+<p>
+        Class
+        <a href="../../apidocs/org/apache/cocoon/components/language/markup/NamedLogicsheet.html">
+          <span class="codefrag">NamedLogicsheet</span>
+        </a>
+        extends <span class="codefrag">Logicsheet</span>
+        to associate it with a namespace. This class exposes the following
+        additional methods:
+      </p>
+<ul>
+        
+<li>
+<span class="codefrag">setPrefix</span>.
+            To set the logicsheet's namespace prefix</li>
+        
+<li>
+<span class="codefrag">getPrefix</span>.
+            To retrieve the logicsheet's namespace prefix</li>
+        
+<li>
+<span class="codefrag">setUri</span>.
+            To set the logicsheet's namespace URI</li>
+        
+<li>
+<span class="codefrag">getUri</span>.
+            To retrieve the logicsheet's namespace URI</li>
+      
+</ul>
+<p>
+        Named logicsheets are used as
+        <a href="#builtin-logicsheets">
+          builtin logicsheets
+        </a>
+        by <span class="codefrag">AbstractMarkupLanguage</span>
+        to preload logicsheets and make them accessible
+        to dynamic XML documents without explicit declaration.
+      </p>
+<p>
+        This feature relieves page authors from the need to explicitly
+        declare commonly used logicsheets in their documents. Builtin
+        logicsheets are automatically applied if the document declares
+        their same namespace URI.
+      </p>
+<div class="note">
+        The current <span class="codefrag">AbstractMarkupLanguage</span> implementation
+        wrongly binds named logicsheets based on their namespace
+        <em>prefix</em> instead of their URI!
+      </div>
+
+    
+<a name="logicsheet-generator"></a>
+    
+<h2>Logicsheet Code Generators</h2>
+<p>
+        Logicsheets translate dynamic tags to equivalent code-embedding
+        directives expressed in the markup language at hand. They do not,
+        however, actually emit the final source code program.
+      </p>
+<p>
+        Code generation as such (i.e., the final production of a string
+        containing a source program written in a programming language) is
+        the responsibility of class <span class="codefrag">LogicsheetCodeGenerator</span>.
+      </p>
+<p>
+        Class
+        <a href="../../apidocs/org/apache/cocoon/components/language/markup/LogicsheetCodeGenerator.html">
+          <span class="codefrag">LogicsheetCodeGenerator</span>
+        </a>
+        exposes the following methods:
+      </p>
+<ul>
+        
+<li>
+<span class="codefrag">addLogicsheet</span>.
+            Add a logicsheet to the generator's logicsheet list.
+            Logicsheets are applied in the order of their addition.
+        </li>
+        
+<li>
+<span class="codefrag">generateCode</span>.
+            Return a string containing a source program resulting from
+            successively applying added logicsheets.
+        </li>
+      
+</ul>
+<p>
+        Though "regular" logicsheets as such do not emit source code,
+        <span class="codefrag">LogicsheetCodeGenerator</span> expects its <em>last</em>
+        stylesheet to produce <em>a single element</em> containing only
+        a text node.
+      </p>
+<p>
+        This final, programming language-specific logicsheet is
+        responsible for actually expanding code-embedding directives
+        into source code.
+      </p>
+<p>
+        For each supported target programming language, markup languages
+        must provide a <em>core</em> logicsheet.
+      </p>
+<div class="note">
+        
+<span class="codefrag">LogicsheetCodeGenerator</span> is currently implemented as a
+        class.  It should be defined as an interface in order to the decouple
+        the code generator abstraction from its logicsheet-based implementation.
+        This would allow for alternative code-generation strategies to
+        be plugged.
+      </div>
+
+    
+<a name="markup-definition"></a>
+    
+<h2>Markup Language Definition</h2>
+<p>
+        Markup languages are defined in the sitemap as follows:
+      </p>
+<pre class="code">
+&lt;component-type name="markup-language"&gt;
+  &lt;component-instance name="xsp"
+    class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
+    &lt;parameter name="prefix" value="xsp"/&gt;
+    &lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
+
+    &lt;target-language name="java"&gt;
+      &lt;parameter name="core-logicsheet"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/&gt;
+
+      &lt;builtin-logicsheet&gt;
+        &lt;parameter name="prefix" value="xsp-request"/&gt;
+        &lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
+        &lt;parameter name="href"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
+      &lt;/builtin-logicsheet&gt;
+
+      &lt;builtin-logicsheet&gt;
+        &lt;parameter name="prefix" value="xsp-response"/&gt;
+        &lt;parameter name="uri"
+          value="http://apache.org/xsp/response/2.0"/&gt;
+        &lt;parameter name="href"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
+      &lt;/builtin-logicsheet&gt;
+    &lt;/target-language&gt;
+  &lt;/component-instance&gt;
+&lt;/component-type&gt;
+</pre>
+<p>
+        Here, the markup language <em>prefix</em> and <em>uri</em>
+       are defined together with one or more
+       <em>supported programming languages</em>.
+      </p>
+<p>
+        For each supported programming language, a corresponding
+       <em>core logicsheet</em> is defined as a URL pointing to
+       its code-generation stylesheet.
+      </p>
+<a name="builtin-logicsheets"></a>
+<p>
+        Optionally, each supported programming language may define
+       one or more namespace-mapped <em>builtin logicsheets</em>.
+      </p>
+  
+
+ 
+<a name="xsp-language"></a>
+ 
+<h1>The XSP Markup Language</h1>
+   
+<p>
+     So far, programming and markup languages have been described
+     in general, without explicitly referring to the XSP language.
+   </p>
+
+   
+<p>
+     This section describes how the above described framework is
+     used to implement XSP in particular. For a description of
+     logicsheet authoring requirements for XSP in Java, see
+     <a href="logicsheet-concepts.html#java-logicsheets">
+       XSLT Logicsheets and XSP for Java.
+     </a>
+   
+</p>
+
+
+   
+<div class="note">
+     The XSP syntax is being revised to allow for the omission of the
+     root <span class="codefrag">&lt;xsp:page&gt;</span> element. This is convenient
+     for the (typical) case in which all logic has been conveniently
+     placed in logicsheets so that XSP pages do not need to embed any
+     code. In this case, there should be no need for the
+     <span class="codefrag">&lt;xsp:page&gt;</span> element.
+   </div>
+
+   
+<a name="xsp-encoding"></a>
+   
+<h2>Markup Encoding</h2>
+<p>Method <span class="codefrag">getEncoding</span> is implemented by class
+     <a href="../../apidocs/org/apache/cocoon/components/language/markup/xsp/XSPMarkupLanguage.html">
+       <span class="codefrag">XSPMarkupLanguage</span>
+     </a>
+     by retrieving the attribute named
+     <span class="codefrag">encoding</span> in the root <span class="codefrag">&lt;xsp:page&gt;</span> element.</p>
+<div class="note">
+       In absence of a <span class="codefrag">&lt;xsp:page&gt;</span> root element, the
+       encoding will be retrieved from an attribute named
+       <span class="codefrag">xsp:encoding</span> present in the "user" root element.
+     </div>
+
+   
+<a name="xsp-preprocessing"></a>
+   
+<h2>Document Preprocessing</h2>
+<p>
+       
+<span class="codefrag">XSPMarkupLanguage</span> preprocesses its input document
+       by:
+     </p>
+<ul>
+       
+<li>
+         Setting the root element <span class="codefrag">file-name</span> attribute to the
+        <em>base</em> filename of its input source.
+       </li>
+       
+<li>
+         Setting the root element <span class="codefrag">file-path</span> attribute to the
+        <em>base</em> directory name of its input source.
+       </li>
+       
+<li>
+         Setting the root element <span class="codefrag">creation-date</span> attribute to the
+        current system time
+       </li>
+       
+<li>
+         Escaping text nodes according to the rules dictated by the
+        target programming language. This excludes text nodes enclosed
+        in <span class="codefrag">&lt;xsp:logic&gt;</span> and <span class="codefrag">&lt;xsp:expr&gt;</span>
+        elements, as they are to be output as code.
+       </li>
+     
+</ul>
+<div class="note">
+       A feature to be added is collecting all text nodes under the document's
+       root element and replacing them by references to their relative index
+       position. This will allow for the generation of
+       <span class="codefrag">contentHandler.characters</span> method calls that reference
+       <span class="codefrag">char</span> arrays instead of constant <span class="codefrag">String</span>'s.
+       In addition to saving execution time, this will result in decreased
+       program size because common substrings can be output by "reusing"
+       their containing character arrays along with their corresponding
+       offsets and lengths.
+     </div>
+
+   
+<a name="xsp-dependencies"></a>
+   
+<h2>Dependency Tracking</h2>
+<p>
+       File dependencies passed to <span class="codefrag">XSPMarkupLanguage</span> by
+       its <span class="codefrag">AbstractMarkupLanguage</span> superclass are stored
+       in top-level <span class="codefrag">&lt;xsp:dependency&gt;</span> elements.
+     </p>
+<p>
+       These elements are used by XSP code-generation logicsheets to
+       populate the <span class="codefrag">File</span> array defined by the generated
+       classes' <span class="codefrag">AbstractServerPage</span> superclass.
+     </p>
+
+   
+<a name="xsp-builtin"></a>
+   
+<h2>XSP Builtin Logicsheets</h2>
+<p>
+       XSP for Java currently provides only 2 builtin logicsheets:
+       <span class="codefrag">request</span> and <span class="codefrag">response</span>, associated
+       with their corresponding Cocoon counterparts.
+     </p>
+<div class="note">
+       A mechanism is needed for Cocoon to pass additional objects
+       to XSP pages. In particular, for the servlet execution
+       environment, access to servlet objects is a must.
+     </div>
+ 
+
+ 
+<a name="dom-xsp"></a>
+ 
+<h1>The DOM-XSP Markup Language</h1>
+   
+<p>
+     The new, SAX-based XSP version for Cocoon is not backwards
+     compatible with its DOM-based former self.
+   </p>
+
+   
+<p>
+     In order to protect the existing DOM-based XSP code base,
+     a "new" markup language will be added that simply wraps
+     existing XSP version 1 pages, postprocessing their generated
+     documents to convert them into SAX events.
+   </p>
+
+   
+<p>
+     While this solution implies additional overhead, it provides
+     a simple path for migrating existing XSP pages.
+   </p>
+
+   
+<p>
+     In addition to this straight-forward mechanism, the new,
+     SAX-based XSP version will overload the <span class="codefrag">xspExpr</span>
+     method to accept as argument a <span class="codefrag">Node</span> expression
+     and transform it to equivalent SAX events.
+   </p>
+
+   
+<p>
+     For the long run, though, developers are strongly encouraged
+     to replace their "legacy" DOM pages and classes with equivalent,
+     faster SAX counterparts.
+   </p>
+ 
+
+ 
+<a name="program-generator"></a>
+ 
+<h1>The Program Generator</h1>
+   
+<p>
+     The
+     <a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">
+       <span class="codefrag">ProgramGenerator</span>
+     </a>
+     interface exposes a single
+     <span class="codefrag">load</span> method that takes as arguments a <span class="codefrag">File</span>
+     pointing to a source XML document, as well as a <em>markup</em> and
+     <em>programming</em> language name pair.
+   </p>
+
+   
+<p>
+     This method is responsible for locating, loading and instantiating
+     a program derived from the given source document. Failing this,
+     the program is generated and stored in an external, persistent
+     <em>repository</em>.
+   </p>
+
+   
+<p>
+     Once instantiated, the program is kept in an in-memory cache for
+     speeding up subsequent requests.
+   </p>
+
+   
+<p>
+     For each request, the source XML document is checked for changes
+     and the program instance is queried for dependency changes so that
+     the program can be automatically regenerated and reloaded if needed.
+     This default behavior can be disabled by means of a sitemap
+     parameter.
+   </p>
+
+   
+<div class="note">
+     Currently, the program <em>instance</em> (as opposed to the
+     program object itself) is queried for invalidating changes.
+     This should change as a consequence of defining a separate
+     <span class="codefrag">Program</span> abstraction as part of the upcoming
+     addition of debugging support.
+   </div>
+
+   
+<p>
+     A default implementation of <span class="codefrag">ProgramGenerator</span>
+     is provided that uses a
+     <a href="../../apidocs/org/apache/cocoon/components/store/FilesystemStore.html">
+       <span class="codefrag">FilesystemStore</span>
+     </a>
+     as
+     repository:
+     <a href="../../apidocs/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.html">
+       <span class="codefrag">ProgramGeneratorImpl</span>.
+     </a>
+   
+</p>
+
+   
+<a name="program-repository"></a>
+   
+<h2>Program Repository</h2>
+<p>
+       
+<span class="codefrag">FilesystemStore</span> is an implementation of the
+       <span class="codefrag">Store</span> interface that uses a filesystem,
+       hierarchical <em>directory</em> as its persistence
+       mechanism.
+     </p>
+<div class="note">
+       
+<span class="codefrag">FilesystemStore</span> implements <span class="codefrag">Store</span>
+       directly. A higher-level interface (<span class="codefrag">PersistentStore</span>)
+       should be defined to accommodate other sensible persistent
+       storage mechanisms such as relational databases or object
+       databases like
+       <a class="external" href="http://www.ozone-db.org/">Ozone</a>.
+     </div>
+<p>
+       
+<span class="codefrag">FilesystemStore</span> expects the <span class="codefrag">String</span>
+       representation of its <span class="codefrag">key</span>'s to be <em>filenames</em>
+       relative to its directory root.
+     </p>
+<p>
+       Objects returned by <span class="codefrag">FilesystemStore</span>'s
+       <span class="codefrag">get</span> method are <span class="codefrag">File</span>'s pointing to
+       their corresponding entries (or <span class="codefrag">null</span> if their
+       associated file doesn't exit).
+     </p>
+<p>
+       
+<span class="codefrag">FilesystemStore</span> stores Java objects according
+       to the following rules:
+     </p>
+<ul>
+       
+<li>
+<span class="codefrag">null</span> values generate empty directories</li>
+       
+<li>
+<span class="codefrag">String</span> values are dumped to text files</li>
+       
+<li>All other <span class="codefrag">Object</span>'s are serialized</li>
+     
+</ul>
+
+   
+<a name="program-reloading"></a>
+   
+<h2>Program Reloading</h2>
+<p>
+       Unless the <span class="codefrag">auto-reload</span> sitemap option is in effect,
+       <span class="codefrag">ProgramGeneratorImpl</span> will check whether program
+       instances implement interface <span class="codefrag">Modifiable</span> in order
+       to assert whether they should be regenerated and reloaded.
+     </p>
+<p>
+       Method <span class="codefrag">load</span> uses its <span class="codefrag">markupLanguageName</span> and
+       <span class="codefrag">programmingLanguage</span> arguments to retrieve the corresponding
+       <a href="#named-components"><span class="codefrag">NamedComponent</span></a>
+       instances.
+     </p>
+<p>
+       In server pages mode, these parameters are set by the calling
+       <span class="codefrag">ServerPagesGenerator</span> from parameters passed via
+       the sitemap <span class="codefrag">&lt;process&gt;</span> section.
+     </p>
+<p>
+       The appropriate <span class="codefrag">MarkupLanguage</span> and
+       <span class="codefrag">ProgrammingLanguage</span> instances are used to generate and
+       load a program for which an instance is created and then returned to
+       the calling environment.
+     </p>
+ 
+
+ 
+<a name="named-components"></a>
+ 
+<h1>Named Components</h1>
+   
+<p>
+     In order to support pluggable markup and programming languages,
+     a new abstraction was added to Cocoon's <span class="codefrag">arch</span>
+     core interfaces:
+       <span class="codefrag">org.apache.arch.named.NamedComponent</span>.
+   </p>
+
+   
+<p>
+     Interface <span class="codefrag">NamedComponent</span> is simply an extension to
+       <span class="codefrag">org.apache.arch.Component</span>
+     that exposes a <span class="codefrag">getName()</span>
+     method.
+   </p>
+
+   
+<p>
+     
+<span class="codefrag">NamedComponent</span>'s belong to a collection of components
+     sharing the same Java type and are individually identified by a
+     name unique within each collection.
+   </p>
+
+   
+<p>
+     A
+       <span class="codefrag">org.apache.arch.named.NamedComponentManager</span>
+     is a component responsible
+     for storing and locating <span class="codefrag">NamedComponent</span> instances.
+     This interface exposes the following methods:
+   </p>
+
+   
+<ul>
+     
+<li>
+<span class="codefrag">getComponent</span>. Retrieve a <span class="codefrag">NamedComponent</span>
+         instance given its <span class="codefrag">type</span> and <span class="codefrag">name</span>.
+     </li>
+     
+<li>
+<span class="codefrag">getTypes</span>. Return an <span class="codefrag">Enumeration</span> of all
+         known <span class="codefrag">NamedComponent</span> types.
+     </li>
+     
+<li>
+<span class="codefrag">getComponents</span>. Return an <span class="codefrag">Enumeration</span> of
+         all <span class="codefrag">NamedComponents</span> within a given <span class="codefrag">type</span>.
+     </li>
+   
+</ul>
+
+   
+<p>
+     A default implementation is provided for this interface:
+       <span class="codefrag">org.apache.arch.named.NamedComponentManagerImpl</span>.
+   </p>
+
+   
+<p>
+     Class
+       <span class="codefrag">org.apache.arch.named.AbstractNamedComponent</span>
+     provides a base implementation
+     for <span class="codefrag">NamedComponent</span> that extends
+       <span class="codefrag">org.apache.arch.Configurable</span>.
+     This class exposes the following methods:
+   </p>
+   
+   
+<ul>
+     
+<li>
+<span class="codefrag">setConfiguration</span>.
+         Retrieve named-component sitemap configuration values
+         converting parameter name/value pairs into <span class="codefrag">Parameters</span>
+         passed to subclasses for easier initialization
+     </li>
+     
+<li>
+<span class="codefrag">setParameters</span>.
+         An empty method to be overridden by subclasses for parameter-based
+         initialization
+     </li>
+     
+<li>
+<span class="codefrag">setAdditionalConfiguration</span>.
+         An empty method to be overridden by subclasses when parameter-based
+         initialization is not sufficient because there are nested
+         configuration elements in the corresponding sitemap entry
+     </li>
+     
+<li>
+<span class="codefrag">getRequiredParameter</span>.
+         A static convenience method that returns a named parameter as
+         a <span class="codefrag">String</span> throwing an
+         <span class="codefrag">IllegalArgumentException</span>
+         if the parameter was not specified in the sitemap configuration
+     </li>
+   
+</ul>
+ 
+
+ 
+<a name="sitemap-configuration"></a>
+ 
+<h1>XSP Sitemap Configuration</h1>
+    
+<div class="note">
+      The sitemap configuration shown here is likely to change in the
+      near future.
+    </div>
+
+    
+<p>
+      A (rather verbose) sitemap definition for XSP follows:
+    </p>
+
+
+<pre class="code">
+&lt;component role="factory"
+           class="org.apache.avalon.NamedComponentManagerImpl"&gt;
+
+  &lt;component-type name="programming-language"&gt;
+    &lt;component-instance name="java"
+    class="org.apache.cocoon.components.language.programming.java.JavaLanguage"&gt;
+      &lt;parameter name="compiler"
+      value="org.apache.cocoon.components.language.programming.java.Javac"/&gt;
+      &lt;parameter name="code-formatter"
+      value="org.apache.cocoon.components.language.programming.java.JstyleFormatter"/&gt;
+      &lt;parameter name="class-loader"
+      value="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
+      &lt;parameter name="delete-sources" value="false"/&gt;
+    &lt;/component-instance&gt;
+  &lt;/component-type&gt;
+
+  &lt;component-type name="markup-language"&gt;
+    &lt;component-instance name="xsp"
+    class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
+      &lt;parameter name="prefix" value="xsp"/&gt;
+      &lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
+
+      &lt;target-language name="java"&gt;
+        &lt;parameter name="core-logicsheet"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/&gt;
+
+        &lt;builtin-logicsheet&gt;
+          &lt;parameter name="prefix" value="xsp-request"/&gt;
+          &lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
+          &lt;parameter name="href"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
+        &lt;/builtin-logicsheet&gt;
+
+        &lt;builtin-logicsheet&gt;
+          &lt;parameter name="prefix" value="xsp-response"/&gt;
+          &lt;parameter name="uri"
+          value="http://apache.org/xsp/response/2.0"/&gt;
+          &lt;parameter name="href"
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
+        &lt;/builtin-logicsheet&gt;
+      &lt;/target-language&gt;
+    &lt;/component-instance&gt;
+  &lt;/component-type&gt;
+&lt;/component&gt;
+
+&lt;component role="program-generator"
+  class="org.apache.cocoon.components.language.generator.ProgramGeneratorImpl"&gt;
+  &lt;parameter name="repository" value="/tmp/repository"/&gt;
+  &lt;parameter name="auto-reload" value="true"/&gt;
+&lt;/component&gt;
+
+&lt;generator  name="serverpages"
+            class="org.apache.cocoon.generation.ServerPagesGenerator"/&gt;
+
+&lt;!--
+&lt;component
+  role="class-loader"
+  class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"
+/&gt;
+--&gt;
+
+&lt;sitemap&gt;
+  &lt;partition&gt;
+    &lt;process uri="simple-page.xsp" source="../samples/documents/simple-page.xsp"&gt;
+      &lt;generator name="serverpages"&gt;
+        &lt;!--
+        &lt;parameter name="markup-language" value="xsp"/&gt;
+        &lt;parameter name="programming-language" value="java"/&gt;
+        --&gt;
+      &lt;/generator&gt;
+      &lt;filter name="xslt"&gt;
+        &lt;parameter name="stylesheet" value="../samples/documents/simple-page.xsl"/&gt;
+      &lt;/filter&gt;
+      &lt;serializer name="html"&gt;
+        &lt;parameter name="contentType" value="text/html"/&gt;
+      &lt;/serializer&gt;
+    &lt;/process&gt;
+  &lt;/partition&gt;
+&lt;/sitemap&gt;
+</pre>
+
+ 
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/meta.xml
new file mode 100644
index 0000000..502b852
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-internals/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/xsp-internals.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/content_en.html
new file mode 100644
index 0000000..ef3208c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/content_en.html
@@ -0,0 +1,1084 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Logicsheet Concepts</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ricardo Rocha" name="DC.Creator">
+</head>
+<body>
+   
+<h1>Index</h1>
+     
+<p>
+       This document introduces logicsheet design and writing
+       principles:
+     </p>
+
+     
+<ul>
+       
+<li>
+         
+<a href="#logicsheet">Logicsheets</a>
+       
+</li>
+       
+<li>
+         
+<a href="#helper-classes">Logicsheet Helper Classes</a>
+       
+</li>
+       
+<li>
+         
+<a href="#logicsheet-object">Logicsheets and Objects</a>
+       
+</li>
+       
+<li>
+         
+<a href="#xsl-logicsheets">Logicsheets and XSLT</a>
+       
+</li>
+       
+<li>
+         
+<a href="#java-logicsheets">
+     XSLT Logicsheets and XSP for Java
+   </a>
+       
+</li>
+       
+<li>
+         
+<a href="#logicsheet-language">
+     The SiLLy Logicsheet Language
+   </a>
+       
+</li>
+     
+</ul>
+  
+
+  
+<a name="logicsheet"></a>
+  
+<h1>Logicsheets</h1>
+    
+<p>
+      A <em>logicsheet</em> is an XML filter used to translate user-defined,
+      dynamic markup into equivalent code embedding directives for a given
+      markup language.
+    </p>
+
+    
+<p>
+      Logicsheets lie at the core of XSP's promise to separate logic from
+      content and presentation: they make dynamic content generation
+      capabilities available to content authors not familiar with (and
+      not interested in) programming.
+    </p>
+
+    
+<p>
+      Logicsheets are <em>not</em> programming-language independent.
+      They translate dynamic tags to <em>actual code</em> enclosed in
+      code-embedding directives. Fortunately, this dependency can be
+      alleviated by judiciously using
+      <a href="#helper-classes">helper classes</a>.
+    </p>
+
+    
+<p>
+      Logicsheets are used to translate <em>dynamic tags</em> into markup
+      language code-embedding directives. Thus, for example, the dynamic
+      tag:
+    </p>
+
+
+<pre class="code">
+&lt;util:time-of-day format="hh:mm:ss"/&gt;
+</pre>
+
+    
+<p>
+      would be transformed by the <em>util</em> logicsheet into an
+      equivalent XSP expression:
+    </p>
+
+
+<pre class="code">
+&lt;xsp:expr&gt;
+  SimpleDateFormat.getInstance().format(new Date(), "hh:mm:ss")
+&lt;/xsp:expr&gt;
+</pre>
+
+    
+<p>
+      Note that the output of logicsheet processing is <em>not</em>
+      final code, but rather <em>code-embedding markup language directives</em>
+      (<em>&lt;xsp:expr&gt;</em> in this case).
+    </p>
+
+    
+<p>
+      Logicsheets can be applied in sequence so that it's possible for one
+      logicsheet to produce dynamic tags further processed by another
+      logicsheet. Thus, for example:
+    </p>
+
+
+<pre class="code">
+&lt;util:time-of-day&gt;
+  &lt;util:param name="format"&gt;
+    &lt;request:get-parameter name="time-format" default="hh:mm:ss"/&gt;
+  &lt;/util:param&gt;
+&lt;/util:time-of-day&gt;
+</pre>
+
+    
+<p>
+      would be transformed by the <em>util</em> logicsheet into:
+    </p>
+
+
+<pre class="code">
+&lt;xsp:expr&gt;
+  SimpleDateFormat.getInstance().format(
+    new Date(),
+    &lt;request:get-parameter name="time-format" default="hh:mm:ss"/&gt;
+  )
+&lt;/xsp:expr&gt;
+</pre>
+
+    
+<p>
+      which would be transformed by the <em>request</em> logicsheet,
+      in turn, into:
+    </p>
+
+
+<pre class="code">
+&lt;xsp:expr&gt;
+  SimpleDateFormat.getInstance().format(
+    new Date(),
+    XSPRequestHelper.getParameter("name", "hh:mm:ss")
+  )
+&lt;/xsp:expr&gt;
+</pre>
+
+    
+<p>
+      Note in the examples above that dynamic tags can be
+      "overloaded" in the sense that they can take as parameters
+      either <em>constant attribute values</em> or
+      <em>nested parameter elements</em>:
+    </p>
+
+
+<pre class="code">
+&lt;!-- Parameter "format" known at page authoring time --&gt;
+&lt;util:time-of-day format="hh:mm:ss"/&gt;
+
+&lt;!-- Parameter "format" known at request time --&gt;
+&lt;util:time-of-day&gt;
+  &lt;util:param name="format"&gt;
+    &lt;request:get-parameter name="time-format" default="hh:mm:ss"/&gt;
+  &lt;/util:param&gt;
+&lt;/util:time-of-day&gt;
+</pre>
+
+    
+<p>
+      This means that logicsheets must be able to cope with constant
+      strings, complex expressions and nested parameter processing.
+      Also, logicsheets must be capable of reporting parameter value
+      errors and, possibly, halt code generation altogether.
+    </p>
+
+    
+<p>
+      In order to minimize this complexity (and its associated debugging
+      nightmares!), properly designed logicsheets typically make use of
+      <strong>helper classes</strong>.
+    </p>
+  
+
+  
+<a name="helper-classes"></a>
+  
+<h1>Logicsheet Helper Classes</h1>
+    
+<p>
+      A <em>helper class</em> is a Java class containing a collection
+      of <em>static</em> methods whose arguments correspond (one-to-one)
+      with their dynamic tag counterparts.
+    </p>
+
+    
+<p>
+      Consider the following dynamic tag use-case:
+    </p>
+
+
+<pre class="code">
+&lt;sql:create-connection name="demo"&gt;
+&lt;sql:jdbc-driver&gt;
+  oracle.jdbc.driver.OracleDriver
+&lt;/sql:jdbc-driver&gt;
+&lt;sql:connect-url&gt;
+  jdbc:oracle:thin:@localhost:1521:ORCL
+&lt;/sql:connect-url&gt;
+&lt;sql:user-name&gt;
+  &lt;request:get-parameter name="user"/&gt;
+&lt;/sql:user-name&gt;
+&lt;sql:password&gt;
+  &lt;request:get-parameter name="password"/&gt;
+&lt;/sql:password&gt;
+&lt;/sql:create-connection&gt;
+</pre>
+
+    
+<p>
+      A brute-force logicsheet template may be implemented
+      (in XSLT, as discussed <a href="#xsl-logicsheets">below</a>)
+      as:
+    </p>
+
+
+<pre class="code">
+&lt;xsl:template match="sql:create-connection"&gt;
+&lt;!-- *** Argument collection skipped for the sake of brevity *** --&gt;
+&lt;xsp:logic&gt; {
+  Class.forName(&lt;xsl:copy-of select="$jdbc-driver"/&gt;).newInstance();
+
+  Connection myConnection =
+    DriverManager.getConnection(
+      &lt;xsl:copy-of select="$connect-url"/&gt;,
+      &lt;xsl:copy-of select="$user-name"/&gt;,
+      &lt;xsl:copy-of select="$password"/&gt;
+    );
+
+  Session mySession = request.getSession(true);
+
+  Connection previousConnection = (Connection)
+    mySession.getAttribute(
+      "connection." + &lt;xsl:copy-of select="$name"/&gt;
+    );
+
+  if (previousConnection != null) {
+    previousConnection.commit();
+    previousConnection.close();
+  }
+
+  mySession.setAttribute(
+    "connection." + &lt;xsl:copy-of select="$name"/&gt;,
+    myConnection
+  )
+} &lt;/xsp:logic&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+    
+<p>
+      This approach has a number of drawbacks.
+    </p>
+
+    
+<ul>
+      
+<li>
+        Even when using enclosing braces around the <em>&lt;xsp:logic&gt;</em>
+        section, there's always the risk that the page author (or another
+        logicsheet!) has previously defined variables called
+        <span class="codefrag">myConnection</span>, <span class="codefrag">previousConnection</span> or
+        <span class="codefrag">mySession</span>. This will result in multiply-defined variable
+        compilation errors
+      </li>
+      
+<li>
+        Parameter values (like <span class="codefrag">$name</span>) cannot be safely used
+        more than once. As much as they can come from harmless string
+        constants, they can also come from complex expressions involving
+        method/function calls which can have unpredictable side-effects
+        should they be called more than once in the current context
+      </li>
+      
+<li>
+        If another logicsheet (or the page author) has imported a class
+        called <span class="codefrag">Connection</span> the generated code will produce an
+        ambiguous class definition compiler error
+      </li>
+    
+</ul>
+
+    
+<p>
+      It's here that helper classes come to the rescue. By moving all
+      the above logic to a static method <span class="codefrag">createConnection</span>
+      in helper class <span class="codefrag">SQLHelper</span>, we can now rewrite
+      (and simplify!) our logicsheet to read:
+    </p>
+
+
+<pre class="code">
+&lt;xsl:template match="sql:create-connection"&gt;
+&lt;!-- *** Argument collection skipped for the sake of brevity *** --&gt;
+&lt;xsp:logic&gt;
+  SQLHelper.createConnection(
+    &lt;xsl:copy-of select="$name"/&gt;,
+    &lt;xsl:copy-of select="$connect-url"/&gt;,
+    &lt;xsl:copy-of select="$user-name"/&gt;,
+    &lt;xsl:copy-of select="$password"/&gt;,
+    request
+  );
+&lt;/xsp:logic&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+    
+<p>
+      This simple approach brings several benefits:
+    </p>
+
+    
+<ul>
+      
+<li>
+        Safer parameter evaluation, with no unpredictable side
+        effects
+      </li>
+      
+<li>
+        Programming language-independence: expressions calling
+        "native" Java code tend to have the same syntax in all
+        programming languages, thus reducing the need to maintain
+        multiple versions of the same logicsheet
+      </li>
+      
+<li>
+        Simpler debugging: syntax errors can now be traced to bad
+        parameter values, rather than invalid code
+      </li>
+      
+<li>
+        Easier logic maintenance: it takes places at the helper
+        class level, rather than at the logicsheet's
+      </li>
+      
+<li>
+        Reduced generated code size.
+      </li>
+    
+</ul>
+  
+
+  
+<a name="logicsheet-object"></a>
+  
+<h1>Logicsheets and Objects</h1>
+    
+<p>
+      Though not required to do so, each logicsheet typically deals with
+      a single <em>object type</em>.
+    </p>
+
+    
+<p>
+      What objects must be manipulated by means of logicsheets depends
+      mostly on the calling <em>host environment</em>.
+    </p>
+
+    
+<p>
+      Thus, for example, when Cocoon is used as a servlet, XSP pages
+      need access to the underlying servlet engine objects: request,
+      response, session, servlet config, etc.
+    </p>
+
+    
+<p>
+      In general, in order to enable dynamic content generation for each
+      host environment, logicsheets must be written that provide
+      markup-based access to its objects and methods:
+    </p>
+
+
+<pre class="code">
+&lt;request:get-parameter name="part-number"/&gt;
+
+&lt;response:send-redirect location="error-page.xml"/&gt;
+
+&lt;cookie:create name="user-preferences"/&gt;
+</pre>
+
+    
+<p>
+      In general, for each object type required by a server pages
+      application a helper class should be written that:
+    </p>
+
+    
+<ul>
+      
+<li>
+        Provides access to the object's methods and services
+      </li>
+      
+<li>
+        Provides convenience methods to wrap values returned
+        by object methods as XML
+      </li>
+    
+</ul>
+
+    
+<p>
+      Within this discipline, <em>each object type must define a separate,
+      identifying namespace</em>.
+    </p>
+
+    
+<p>
+      Finally, logicsheets may require a <em>preprocessor</em> that augments
+      its input document with extra information prior to markup
+      transformation.
+    </p>
+
+    
+<p>
+      As an example of logicsheet preprocessing, consider an
+      <span class="codefrag">xbean</span> logicsheet providing services similar to the
+      JSP's intrinsic <span class="codefrag">&lt;jsp:useBean&gt;</span> tag:
+    </p>
+
+
+<pre class="code">
+. . .
+&lt;xbean:use-bean id="myCart" class="com.acme.cart.CartBean" scope="session"&gt;
+&lt;xbean:set-property property-name="type" property-value="promotion"/&gt;
+&lt;xbean:set-property property-name="customer" parameter-value="custid"/&gt;
+&lt;/xbean:use-bean&gt;
+. . .
+&lt;p&gt;
+Hello &lt;xbean:get-property bean-id="myCart" property-name="customerName"/&gt;,
+welcome back!
+You have the following discounts:
+&lt;/p&gt;
+
+&lt;xbean:get-property bean-id="myCart" property-name="discount"/&gt;
+. . .
+</pre>
+
+    
+<p>
+      In this case, code to be emitted by the logicsheet will vary
+      wildly depending on whether a given bean property is indexed,
+      multivalued or object-typed; different conversions and traversing
+      code may be needed for each property based on its Java and
+      bean types.
+    </p>
+
+    
+<p>
+      A logicsheet preprocessor could introspect the given bean at code
+      generation time to augment the input document with additional
+      information as to make it possible for an XSLT-based logicsheet
+      to emit appropriate code:
+    </p>
+
+
+<pre class="code">
+. . .
+&lt;xbean:use-bean id="myCart" class="com.acme.cart.CartBean" scope="session"&gt;
+&lt;xbean:set-property
+  property-name="type" property-value="promotion"
+  java-type="String"
+  is-indexed="false"
+/&gt;
+&lt;xbean:set-property property-name="customer" parameter-value="custid"
+  java-type="String"
+  is-indexed="false"
+/&gt;
+&lt;/xbean:use-bean&gt;
+. . .
+&lt;p&gt;
+Hello
+  &lt;xbean:get-property bean-id="myCart" property-name="customerName"
+    java-type="String"
+    is-indexed="false"
+   /&gt;,
+welcome back!
+You have the following discounts
+&lt;/p&gt;
+
+&lt;xbean:get-property bean-id="myCart" property-name="discount"
+java-type="float"
+is-indexed="true"
+/&gt;
+. . .
+</pre>
+
+    
+<p>
+      Using this information, the logicsheet can decide, for a given
+      bean property, whether to generate a simple
+      <span class="codefrag">String.valueOf()</span> or an indexed loop displaying
+      individual property values.
+    </p>
+
+    
+<div class="note">
+      Logicsheet preprocessor is still unimplemented.
+      Preprocessing may be performed as well in XSLT by using
+      <em>extension functions</em>.  Logicsheet preprocessing is meant to be
+      used in those cases where the XSLT processor being used by Cocoon
+      does not support XSLT extensions. (As of this writing, only
+      <a class="external" href="http://xml.apache.org/xalan/">Xalan</a>
+      is known to support XSLT extensions).
+    </div>
+  
+
+  
+<a name="xsl-logicsheets"></a>
+  
+<h1>Logicsheets and XSLT</h1>
+    
+<p>
+      XSLT-based transformation is clearly the obvious choice for
+      implementing logicsheets.
+    </p>
+
+    
+<p>
+      XSLT provides all the capabilities needed for dynamic markup
+      transformation as well for final code generation (described
+      in
+      <a href="xsp-internals.html#logicsheet-generator">
+        Logicsheet Code Generators
+      </a>).
+    </p>
+
+    
+<p>
+      In fact, logicsheet transformations require only a subset of
+      XSLT much more general capabilities:
+    </p>
+
+    
+<ul>
+      
+<li>
+        Transforming an input element into other element(s) and
+        nested text (code)
+      </li>
+      
+<li>
+        Collecting and validating parameters as variables
+      </li>
+      
+<li>
+        Substituting variables as either text or nested elements
+      </li>
+    
+</ul>
+
+    
+<p>
+      Paradoxically, though, the XSLT and XPath expressions required
+      to perform these apparently simple tasks can easily become too
+      verbose, and hard-to-read.
+    </p>
+
+    
+<p>
+      This real disadvantage doesn't stem from XSLT not being appropriate
+      or powerful enough to perform the required transformations, but
+      rather from its directives being too low-level for this particular task.
+    </p>
+
+    
+<p>
+      In a classical XML spirit, the solution to this problem is found in
+      the definition of a higher-level language specifically targeted to
+      code-generation transformations. Documents written in this language
+      are transformed into "regular" XSLT stylesheets and subsequently
+      applied to input documents for code generation.
+    </p>
+
+    
+<p>
+      Such language is described in detail below, under
+      <a href="#logicsheet-language">
+        The SiLLy Logicsheet Language
+      </a>.
+    </p>
+
+    
+<p>
+      In general, XSLT logicsheets <strong>must</strong> preserve all markup
+      not recognized by its own templates:
+    </p>
+
+
+<pre class="code">
+&lt;xsl:template match="@*|node()" priority="-1"&gt;
+&lt;xsl:copy&gt;&lt;xsl:apply-templates select="@*|node()"/&gt;&lt;/xsl:copy&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+    
+<p>
+      Parameters should be passed to dynamic tags by means of <em>both</em>
+      attributes and nested elements. Also, dynamic tag parameters must be
+      accepted <em>both</em> as constant strings and as (potentially complex)
+      expressions. These two requirements are illustrated in the above
+      <em>util</em> logicsheet example:
+    </p>
+
+
+<pre class="code">
+&lt;!-- Parameter "format" known at page authoring time --&gt;
+&lt;util:time-of-day format="hh:mm:ss"/&gt;
+
+&lt;!-- Parameter "format" known at request time --&gt;
+&lt;util:time-of-day&gt;
+&lt;util:param name="format"&gt;
+  &lt;xsp:expr&gt;
+    request.getParameter("format");
+  &lt;/xsp:expr&gt;
+&lt;/util:param&gt;
+&lt;/util:time-of-day&gt;
+</pre>
+
+    
+<p>
+      In order to support this, a number of utility templates have been
+      defined:
+    </p>
+
+
+<pre class="code">
+&lt;!-- Utility templates --&gt;
+&lt;xsl:template name="get-parameter"&gt;
+&lt;xsl:param name="name"/&gt;
+&lt;xsl:param name="default"/&gt;
+&lt;xsl:param name="required"&gt;false&lt;/xsl:param&gt;
+
+&lt;xsl:variable name="qname"&gt;
+  &lt;xsl:value-of select="concat($prefix, ':param')"/&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsl:choose&gt;
+  &lt;xsl:when test="@*[name(.) = $name]"&gt;
+    "&lt;xsl:value-of select="@*[name(.) = $name]"/&gt;"
+  &lt;/xsl:when&gt;
+  &lt;xsl:when test="(*[name(.) = $qname])[@name = $name]"&gt;
+    &lt;xsl:call-template name="get-nested-content"&gt;
+      &lt;xsl:with-param name="content"
+        select="(*[name(.) = $qname])[@name = $name]"/&gt;
+    &lt;/xsl:call-template&gt;
+  &lt;/xsl:when&gt;
+  &lt;xsl:otherwise&gt;
+    &lt;xsl:choose&gt;
+      &lt;xsl:when test="string-length($default) = 0"&gt;
+        &lt;xsl:choose&gt;
+          &lt;xsl:when test="$required = 'true'"&gt;
+            &lt;xsl:call-template name="error"&gt;
+              &lt;xsl:with-param name="message"&gt;
+              [Logicsheet processor]
+                Parameter '&lt;xsl:value-of select="$name"/&gt;'
+              missing in dynamic tag
+              &amp;lt;&lt;xsl:value-of select="name(.)"/&gt;&amp;gt;
+              &lt;/xsl:with-param&gt;
+            &lt;/xsl:call-template&gt;
+          &lt;/xsl:when&gt;
+          &lt;xsl:otherwise&gt;""&lt;/xsl:otherwise&gt;
+        &lt;/xsl:choose&gt;
+      &lt;/xsl:when&gt;
+      &lt;xsl:otherwise&gt;&lt;xsl:copy-of select="$default"/&gt;&lt;/xsl:otherwise&gt;
+    &lt;/xsl:choose&gt;
+  &lt;/xsl:otherwise&gt;
+&lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template name="get-nested-content"&gt;
+&lt;xsl:param name="content"/&gt;
+&lt;xsl:choose&gt;
+  &lt;xsl:when test="$content/*"&gt;
+    &lt;xsl:apply-templates select="$content/*"/&gt;
+  &lt;/xsl:when&gt;
+  &lt;xsl:otherwise&gt;"&lt;xsl:value-of select="$content"/&gt;"&lt;/xsl:otherwise&gt;
+&lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template name="get-nested-string"&gt;
+&lt;xsl:param name="content"/&gt;
+&lt;xsl:choose&gt;
+  &lt;xsl:when test="$content/*"&gt;
+    ""
+    &lt;xsl:for-each select="$content/node()"&gt;
+      &lt;xsl:choose&gt;
+        &lt;xsl:when test="name(.)"&gt;
+          + &lt;xsl:apply-templates select="."/&gt;
+        &lt;/xsl:when&gt;
+        &lt;xsl:otherwise&gt;
+          + "&lt;xsl:value-of select="translate(.,'&amp;#9;&amp;#10;&amp;#13;','   ')"/&gt;"
+        &lt;/xsl:otherwise&gt;
+      &lt;/xsl:choose&gt;
+    &lt;/xsl:for-each&gt;
+  &lt;/xsl:when&gt;
+  &lt;xsl:otherwise&gt;"&lt;xsl:value-of select="$content"/&gt;"&lt;/xsl:otherwise&gt;
+&lt;/xsl:choose&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template name="error"&gt;
+&lt;xsl:param name="message"/&gt;
+&lt;xsl:message terminate="yes"&gt;&lt;xsl:value-of select="$message"/&gt;&lt;/xsl:message&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+    
+<p>
+      Given these utility templates, the example
+      <span class="codefrag">&lt;util:time-of-day&gt;</span> template would look like:
+    </p>
+
+
+<a name="complex-example"></a>
+
+<pre class="code">
+&lt;xsl:template match="sql:create-connection"&gt;
+&lt;xsl:variable name="name"&gt;
+  &lt;xsl:call-template name="get-parameter"&gt;
+    &lt;xsl:with-param name="name"&gt;name&lt;/xsl:with-param&gt;
+    &lt;xsl:with-param name="required"&gt;true&lt;/xsl:with-param&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsl:variable name="jdbc-driver"&gt;
+  &lt;xsl:call-template name="get-parameter"&gt;
+    &lt;xsl:with-param name="name"&gt;jdbc-driver&lt;/xsl:with-param&gt;
+    &lt;xsl:with-param name="required"&gt;true&lt;/xsl:with-param&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsl:variable name="connect-url"&gt;
+  &lt;xsl:call-template name="get-parameter"&gt;
+    &lt;xsl:with-param name="name"&gt;connect-url&lt;/xsl:with-param&gt;
+    &lt;xsl:with-param name="required"&gt;true&lt;/xsl:with-param&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsl:variable name="user-name"&gt;
+  &lt;xsl:call-template name="get-parameter"&gt;
+    &lt;xsl:with-param name="name"&gt;user-name&lt;/xsl:with-param&gt;
+    &lt;xsl:with-param name="required"&gt;true&lt;/xsl:with-param&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsl:variable name="password"&gt;
+  &lt;xsl:call-template name="get-parameter"&gt;
+    &lt;xsl:with-param name="name"&gt;password&lt;/xsl:with-param&gt;
+    &lt;xsl:with-param name="required"&gt;true&lt;/xsl:with-param&gt;
+  &lt;/xsl:call-template&gt;
+&lt;/xsl:variable&gt;
+
+&lt;xsp:logic&gt;
+  SQLHelper.createConnection(
+    &lt;xsl:copy-of select="$name"/&gt;,
+    &lt;xsl:copy-of select="$connect-url"/&gt;,
+    &lt;xsl:copy-of select="$user-name"/&gt;,
+    &lt;xsl:copy-of select="$password"/&gt;,
+    request
+  );
+&lt;/xsp:logic&gt;
+&lt;/xsl:template&gt;
+</pre>
+
+    
+<p>
+      This example shows clearly why we need a
+     <a href="#logicsheet-language">SiLLy</a>
+     language!
+    </p>
+  
+
+  
+<a name="java-logicsheets"></a>
+  
+<h1>XSLT Logicsheets and XSP for Java</h1>
+    
+<p>
+      The Java programming language defines a source program structure that
+     must be take into account for properly generating code:
+    </p>
+
+    
+<ul>
+      
+<li>Package declaration</li>
+     
+<li>Imports</li>
+     
+<li>Class declaration</li>
+     
+<li>Class-level declarations (methods and variables)</li>
+     
+<li>Application-specific method body</li>
+    
+</ul>
+
+    
+<p>
+      The <span class="codefrag">&lt;xsp:page&gt;</span> tag must contain one (and only
+     one) "user" root element.
+    </p>
+
+    
+<p>
+      All markup enclosed within the user root element will be placed
+     inside method <span class="codefrag">generate()</span> of the generated
+     <span class="codefrag">XSPGenerator</span> subclass.
+    </p>
+
+    
+<p>
+      The <span class="codefrag">&lt;xsp:structure&gt;</span>
+      and <span class="codefrag">&lt;xsp:include&gt;</span> tags are used to
+     import "external" classes and <strong>must</strong> be
+     top-level elements (i.e., they must placed directly under
+     the <span class="codefrag">&lt;xsp:page&gt;</span> root element):
+    </p>
+
+
+<pre class="code">
+&lt;xsp:structure&gt;
+&lt;xsp:include&gt;java.sql.*&lt;/xsp:include&gt;
+&lt;xsp:include&gt;java.text.SimpleDateFormat&lt;/xsp:include&gt;
+&lt;/xsp:structure&gt;
+</pre>
+
+    
+<p>
+      The <span class="codefrag">&lt;xsp:logic&gt;</span> tag can be used to
+     generate <em>class-level</em> variable and method declarations
+     when used as a top-level element:
+    </p>
+
+
+<pre class="code">
+&lt;xsp:page&gt;
+&lt;xsp:structure&gt;
+  &lt;xsp:include&gt;java.text.SimpleDateFormat&lt;/xsp:include&gt;
+&lt;/xsp:structure&gt;
+
+&lt;!-- Class-level declarations --&gt;
+&lt;xsp:logic&gt;
+  private static String timeOfDay(String format) {
+    if (format == null || format.length() == 0) {
+      format = "hh:mm:ss";
+    }
+
+    return SimpleDateFormat.getInstance().format(new Date(), format);
+  }
+&lt;/xsp:logic&gt;
+. . .
+&lt;user-root&gt;
+ . . .
+ &lt;p&gt;
+   It's now
+   &lt;xsp:expr&gt;
+     timeOfDay(request.getParameter("timeFormat"));
+   &lt;/xsp:expr&gt;
+ &lt;/p&gt;
+ . . .
+&lt;/user-root&gt;
+&lt;xsp:page&gt;
+</pre>
+
+    
+<p>
+      Thus, when a logicsheet adds to the import or class-level declaration
+     "sections", it <strong>must</strong> preserve all the declarations
+     possibly generated by previous logicsheets:
+    </p>
+
+
+<pre class="code">
+&lt;xsl:template match="xsp:page"&gt;
+&lt;xsp:page&gt;
+  &lt;xsl:apply-templates select="@*"/&gt;
+
+  &lt;xsp:structure&gt;
+    &lt;xsp:include&gt;java.text.*&lt;/xsp:include&gt;
+  &lt;/xsp:structure&gt;
+
+  &lt;xsp:logic&gt;
+    private static int count = 0;
+    private static synchronized int getCounter() {
+      return ++count;
+    }
+    . . .
+  &lt;/xsp:logic&gt;
+
+  &lt;xsl:apply-templates/&gt;
+&lt;/xsp:page&gt;
+&lt;/xsl:template&gt;
+</pre>
+  
+
+ 
+<a name="logicsheet-language"></a>
+ 
+<h1>The SiLLy Logicsheet Language</h1>
+   
+<div class="note">As of today, the SiLLy Logicsheet Language does not exist. What is described below
+     are thoughts on possible implementation of the language.</div>
+   
+<p>
+     In order to overcome the extreme complexity of logicsheet transformations
+     expressed in XSLT, a simpler, higher-level XML transformation language
+     is being defined: <em>Simple Logicsheet Language</em>
+     (or <em>SiLLy</em>, so baptized by Stefano Mazzocchi in a humorous
+     rejection of its first proposed name).
+   </p>
+
+   
+<p>
+     SiLLy templates are much terser and easier to read and write than
+     the XSLT-based examples presented
+     <a href="#complex-example">above</a>:
+   </p>
+
+
+<pre class="code">
+&lt;sll:logicsheet
+  xmlns:sll="http://xml.apache.org/sll"
+  xmlns:xsl="http://www.w3c.org/1999/XSL/Transform"
+&gt;
+  &lt;sll:namespace prefix="sql" uri="http://xml.apache.org/sql"/&gt;
+  
+  &lt;sll:prolog&gt;
+    &lt;xsp:structure&gt;
+      &lt;xsp:include&gt;import SQLHelper;&lt;/xsp:include&gt;
+    &lt;/xsp:structure&gt;
+  &lt;sll:prolog&gt;
+  
+  &lt;sll:element name="create-connection"&gt;
+    &lt;sll:parameter name="name" required="true"/&gt;
+    &lt;sll:parameter name="jdbc-driver"
+      default="oracle.jdbc.driver.OracleDriver"/&gt;
+    &lt;sll:parameter name="connect-url"
+      default="jdbc:oracle:thin:@localhost:1521:ORCL"/&gt;
+    &lt;sll:parameter name="user-name" required="true"/&gt;
+    &lt;sll:parameter name="password" required="true"/&gt;
+  
+    &lt;sll:body&gt;
+      &lt;xsp:logic&gt;
+        SQLHelper.createConnection(
+          &lt;sll:parameter-value select="name"/&gt;,
+          &lt;sll:parameter-value select="jdbc-driver"/&gt;,
+          &lt;sll:parameter-value select="connect-url"/&gt;,
+          &lt;sll:parameter-value select="user-name"/&gt;,
+          &lt;sll:parameter-value select="password"/&gt;,
+          request
+        );
+      &lt;/xsp:logic&gt;
+    &lt;/sll:body&gt;
+  &lt;/sll:element&gt;
+&lt;/sll:logicsheet&gt;
+</pre>
+
+   
+<p>
+     SiLLy logicsheets are translated into an equivalent XSLT stylesheet
+     using XSLT itself.
+   </p>
+
+   
+<div class="note">
+     It is possible (and, indeed, simple) to generate a stylesheet that
+     uses the <span class="codefrag">xsl</span> namespace without ambiguity: XSLT processors
+     are bound to the XSL namespace <em>URI</em>, rather than to its
+     prefix. In addition to this, XSLT defines a
+     <span class="codefrag">&lt;xsl:namespace-alias&gt;</span> directive that can
+     be used to map one namespace's URI to another.
+   </div>
+
+   
+<p>
+     SiLLy provides a limited form of parameter validation: when a dynamic
+     tag parameter is defined as <em>required</em> its absence in the
+     source XML document will trigger the abnormal termination of the
+     code generation process producing a (more or less) meaningful message
+     by means of <span class="codefrag">&lt;xsl:message&gt;</span>
+   
+</p>
+
+   
+<p>
+     It's also possible to specify a list valid values for a parameter.
+     Such list will be used for parameter validation when values passed
+     are constants known at transformation time.
+   </p>
+
+   
+<p>
+     In addition to dynamic <em>tags</em>, SiLLy can also match attributes,
+     and processing instructions.
+   </p>
+
+   
+<p>
+     In absence of a schema or DTD, the following examples illustrate
+     the basic SiLLy matching and transformation capabilities (use-cases
+     are shown as XML comments):
+   </p>
+
+
+<pre class="code">
+
+&lt;!-- &lt;util:time-of-day format="hh:mm aa"/&gt; --&gt;
+&lt;sll:element name="time-of-day" uri="http://www.plenix.org/util" prefix="util"&gt;
+  &lt;sll:parameter name="format" default="hh:mm:ss"/&gt;
+  &lt;sll:body&gt;
+    &lt;xsp:expr&gt;
+      SimpleDateFormat.getInstance().format(
+        new Date(),
+        &lt;sll:parameter-value name="format"/&gt;
+      )
+    &lt;/xsp:expr&gt;
+  &lt;/sll:body&gt;
+&lt;/sll:element&gt;
+
+&lt;!-- &lt;img flag:src="languageCode"/&gt; --&gt;
+&lt;sll:attribute name="src" uri="http://www.plenix.org/translator" prefix="flag"&gt;
+  &lt;sll:body&gt;
+    &lt;xsp:attribute name="src"&gt;&lt;xsp:expr&gt;
+      request.getParameter("&lt;sll:attribute-value/&gt;");
+    &lt;/xsp:expr&gt;.gif&lt;/xsp:attribute&gt;
+  &lt;/sll:body&gt;
+&lt;/sll:attribute&gt;
+
+&lt;!-- &lt;?log Commit point reached?&gt; --&gt;
+&lt;sll:processing-instruction target="log"&gt;
+  &lt;sll:body&gt;
+    &lt;xsp:logic&gt;
+      logger.log("&lt;sll:pi-data/&gt;");
+    &lt;/xsp:logic&gt;
+  &lt;/sll:body&gt;
+&lt;/sll:attribute&gt;
+</pre>
+   
+   
+<div class="note">
+     
+<span class="codefrag">&lt;sll:processing-instruction&gt;</span> is probably
+     overkill
+   </div>
+ 
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/meta.xml
new file mode 100644
index 0000000..2f773f1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-concepts/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/logicsheet-concepts.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/content_en.html
new file mode 100644
index 0000000..5a2d654
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/content_en.html
@@ -0,0 +1,423 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Using Form Validation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+</head>
+<body> 
+  
+<h1>Introduction</h1>
+
+   
+<p>
+    For most web applications input is essential. Apache Cocoon provides
+    variety of modules to support basic interaction like simple syntax checking
+    of input data or writing input data to databases.
+   </p>
+
+   
+<p>
+    A new but already very mature modules is the Cocoon Forms (former Woody) framework.
+    Another, simpler and older implementation is the validation using the
+    <span class="codefrag">FormValidatorAction</span>, which is described here.
+   </p>
+
+   
+<p>
+    To validate user input, an action, the <span class="codefrag">FormValidatorAction</span>, is
+    placed in your pipeline. Together with a descriptor file, that specifies
+    the allowed input, this action validates the request parameters. Based on
+    the result, a different page can be displayed and feedback can be given to
+    the user either using XSP and the <span class="codefrag">formval</span> logicsheet or the
+    <span class="codefrag">SimpleFormTransformer</span>.
+   </p>
+
+   
+<h2>Sitemap Usage</h2>
+<p>
+     To take advantage of the form validator action, create two pages. One for
+     the input form and one indicating the acceptance of the reservation.
+     Create a pipeline in your sitemap so that the confirmation page is only
+     shown when the action completed successfully and the input form is
+     returned otherwise.
+    </p>
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+   &lt;map:match pattern="car-reservation"&gt;
+     &lt;map:act type="form-validator"&gt;
+        &lt;!-- add you favourite database action here --&gt;
+        &lt;map:parameter name="descriptor" value="descriptor.xml"/&gt;
+        &lt;map:parameter name="constraint-set" value="car-reservation"/&gt;
+    &lt;map:generate type="serverpages" src="OK.xsp"/&gt;
+    &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+    &lt;map:serialize/&gt;
+     &lt;/map:act&gt;
+     &lt;map:generate type="serverpages" src="test/ERROR.xsp"/&gt;
+     &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+
+    </pre>
+<p>
+     Note here that you may not use a redirection to point to the pages if you
+     would like to access the validation results e.g. on the error page. A
+     redirection would create a new request object and thus discard the
+     validation results.
+    </p>
+<p>
+     A different example, that does not need serverpages but the
+     <span class="codefrag">SimpleFormTransformer</span>:
+    </p>
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+   &lt;map:match pattern="car-reservation"&gt;
+     &lt;map:act type="req-params"&gt;
+       &lt;map:parameter name="parameters" value="order"/&gt;
+
+       &lt;map:act type="form-validator"&gt;
+         &lt;map:parameter name="descriptor" value="descriptor.xml"/&gt;
+         &lt;map:parameter name="constraint-set" value="car-reservation"/&gt;
+         &lt;!-- add you favourite database action here --&gt;
+
+         &lt;map:generate type="file" src="OK.xml"/&gt;
+         &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+         &lt;map:serialize/&gt;
+       &lt;/map:act&gt;
+     &lt;/map:act&gt;
+     &lt;map:generate type="file" src="test/ERROR.xml"/&gt;
+     &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+     &lt;map:transform type="simple-form"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+
+    </pre>
+<p>
+     Although this looks more complicated at first, it has advantages if you
+     don't want to or cannot use XSP. For example, if the form is stored as
+     XHTML in a database, XSP could not be used to fill the form with values
+     from request parameters or to display detailed error messages.
+    </p>
+<div class="note">
+     Keep in mind that files, here the descriptor file, could be specified
+     using the <span class="codefrag">cocoon:</span> pseudo-protocol. Thus the file could be
+     generated dynamically from another pipeline!
+    </div>
+
+   
+<h2>The Descriptor File</h2>
+<p>
+     For details on the syntax of the descriptor file see javadocs. Basically
+     it consists of two sections, a list of parameters and their properties and
+     a list of constraints or constraint sets. The file syntax is set up so
+     that it can be shared with the database actions.
+    </p>
+<h3>The types recognized by validator and their attributes</h3>
+<table>
+     
+<tr>
+      
+<td colspan="1" rowspan="1"><strong>string</strong></td><td colspan="1" rowspan="1">nullable="yes|no" default="str"</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1"><strong>long</strong></td><td colspan="1" rowspan="1">nullable="yes|no" default="123123"</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1"><strong>double</strong></td><td colspan="1" rowspan="1">nullable="yes|no" default="0.5"</td>
+     
+</tr>
+    
+</table>
+<p>
+     Default value takes place only when specified parameter is nullable and
+     really is null or empty. Long numbers may be specified in decimal, hex or
+     octal values as accepted by java.Lang.decode (String s).
+    </p>
+<h3>Constraints</h3>
+<table>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">matches-regex</td><td colspan="1" rowspan="1">POSIX regular expression</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">one-of</td><td colspan="1" rowspan="1">List of strings, enclosed and separated by <span class="codefrag">|</span></td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">min-len</td><td colspan="1" rowspan="1">positive integer</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">max-len</td><td colspan="1" rowspan="1">positive integer</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">min</td><td colspan="1" rowspan="1">Double / Long</td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">max</td><td colspan="1" rowspan="1">Double / Long</td>
+     
+</tr>
+    
+</table>
+<p>
+     Constraints can be defined globally for a parameter and can be overridden
+     by redefinition in a constraint-set. Thus if e.g. a database field can take
+     at maximum 200 character, this property can be set globally.
+    </p>
+<p>
+     Values in parameter arrays are validated individually and the worst
+     error is reported back.
+    </p>
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+&lt;root&gt;
+
+  &lt;parameter name="persons" type="long" min="1" default="4" nullable="no"/&gt;
+  &lt;parameter name="deposit" type="double" min="10.0" max="999.99"/&gt;
+  &lt;parameter name="email" type="string" max-len="50"
+             matches-regex="^[\d\w][\d\w\-_\.]*@([\d\w\-_]+\.)\w\w\w?$"/&gt;
+  &lt;parameter name="colour" type="string" one-of="|red|green|blue|white|"/&gt;
+
+  &lt;constraint-set name="car-reservation"&gt;
+    &lt;validate name="persons"/&gt;
+    &lt;validate name="deposit" min="50.0"/&gt;
+    &lt;validate name="email"/&gt;
+  &lt;/constraint-set&gt;
+
+&lt;/root&gt;
+
+    </pre>
+<p>
+     The above could for example describe expected input from a reservation
+     form. Specifications in a constraint set take precedence over the general
+     ones.
+    </p>
+
+
+   
+<h2>XSP Usage</h2>
+<p>
+     To give the user some feedback why her/his submitted data was rejected
+     there is a special taglib "xsp-formval". Declare its name space as usual.
+    </p>
+<p>
+     If only interested in validation results, just:
+    </p>
+<pre class="code">
+
+     &lt;xsp-formval:on-ok name="persons"&gt;
+       &lt;myapp:error&gt;(ERROR)&lt;/myapp:error&gt;
+     &lt;/xsp-formval:on-ok&gt;
+
+    </pre>
+<p>
+     Alternatively, if you just want a boolean value from the logicsheet if a
+     test is successful, use this method:
+    </p>
+<pre class="code">
+
+     &lt;xsp:logic&gt;
+     if (!&lt;xsp-formval:is-ok name="persons"/&gt;) {
+          &lt;myapp:error&gt;(ERROR)&lt;/myapp:error&gt;
+         };
+     &lt;/xsp:logic&gt;
+
+    </pre>
+<p>
+     Internationalization issues are a separate concern and are not discussed
+     here.
+    </p>
+<p>
+     Currently the following validation result codes are supported:
+    </p>
+<table>
+     
+<tr>
+<th colspan="1" rowspan="1">tag</th><th colspan="1" rowspan="1">Meaning</th>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-ok</td><td colspan="1" rowspan="1">no error occurred, parameter
+       successfully checked</td>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-error</td><td colspan="1" rowspan="1">some error occurred, this is a result
+       that is never set but serves as a comparison target
+      </td>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-null</td><td colspan="1" rowspan="1">the parameter is null but 
+       isn't allowed to</td>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-toosmall</td><td colspan="1" rowspan="1">either value or length in case of
+       a string is less than the specified minimum</td>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-toolarge</td><td colspan="1" rowspan="1">either value or length in case of
+       a string is greater than the specified maximum</td>
+</tr>          
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-nomatch</td><td colspan="1" rowspan="1">a string parameter's value is not
+       matched by the specified regular expression</td>
+</tr>
+     
+<tr>
+<td colspan="1" rowspan="1">xsp-formval:is-notpresent</td><td colspan="1" rowspan="1">this is returned when the result
+       of a validation is requested but no such result is found in the request
+       attribute </td>
+</tr>
+    
+</table>
+<p>
+     For debugging purposes or if you would like to iterate over the validation
+     results, <span class="codefrag">xsp-formval:results</span> returns a
+     <span class="codefrag">java.util.Map</span> containing them all.
+    </p>
+<p>
+     If you would like to be more specific what went wrong, you can query the
+     descriptor file for attributes.
+    </p>
+<p>
+     First set the url of the file or resource that contains the parameter
+     descriptions and constraint sets.  This needs to be an ancestor to all
+     other tags (of this taglib). Multiple use of this tag is allowed (although
+     probably not necessary).
+    </p>
+<p> You need to do this only if you plan to query the descriptor file or if
+     you'd like to use the shorthand below. 
+    </p>
+<pre class="code">
+
+&lt;xsp-formval:descriptor name="descriptor.xml" constraint-set="reservation"&gt;
+   deposit must be at least EUR
+   &lt;xsp-formval:get-attribute parameter="deposit" name="min"/&gt;
+&lt;/xsp-formval:descriptor&gt;
+
+    </pre>
+<p>
+     If you need to use one parameter a lot, there's a short hand. Use this
+     e.g. if you'd like to set up the properties of an input tag according to
+     the information from the descriptor file or if you'd like to give detailed
+     error messages.
+    </p>
+<p>
+     Note that you can specify additional attributes in the description file
+     that are not understood (and therefore ignored) by the FormValidatorAction
+     but that could be queried here. This might be e.g. the size of the input
+     field which might be different from the max-len a parameter can take.
+    </p>
+<pre class="code">
+
+&lt;xsp-formval:descriptor name="descriptor.xml" constraint-set="car-reservation"&gt;
+  &lt;xsp-formval:validate name="deposit"&gt;
+  &lt;xsp:logic&gt;
+    if (&lt;xsp-formval:is-null/&gt;) {
+      &lt;myapp:error&gt; (you must specify a deposit)) &lt;/myapp:error&gt;
+    } else if ( &lt;xsp-formval:is-toosmall/&gt; ) {
+      &lt;myapp:error&gt;
+        (deposit is too small (&amp;lt; &lt;xsp-formval:get-attribute name="min"/&gt;))
+      &lt;/myapp:error&gt;
+    } else if ( &lt;xsp-formval:is-toolarge/&gt; ) {
+      &lt;myapp:error&gt;
+        (deposit is too large (&amp;gt; &lt;xsp-formval:get-attribute name="max"/&gt;))
+      &lt;/myapp:error&gt;
+    } else {
+      &lt;myapp:error&gt; (ERROR) &lt;/myapp:error&gt;
+    };
+  &lt;/xsp:logic&gt;
+  &lt;/xsp-formval:validate&gt;
+&lt;/xsp-formval:descriptor&gt;
+
+    </pre>
+
+   
+<h2>SimpleFormTransformer</h2>
+<p>
+     An alternative solution to using the <span class="codefrag">formval</span> logicsheet and
+     XSP is to use the <span class="codefrag">SimpleFormTransformer</span>. If fills the form
+     with values obtained from request parameters, overwriting existing
+     values. Hence the data entered by the user is not discarded when it does
+     not validate successfully.
+    </p>
+<div class="note">
+     Beware when using the <span class="codefrag">SimpleFormTransformer</span> together with
+     XSP: The observer behaviour can be very confusing when trying to set a
+     value from XSP and it is silently overwritten by the transformer!
+    </div>
+<p>
+     When a form element carries the attribute <span class="codefrag">fixed="true"</span>, the
+     transformer does not replace the value.
+    </p>
+<p>
+     Feedback can be given to the user through <span class="codefrag">&lt;error/&gt;</span>
+     tags. Error tags need to have a name attribute identical to the input
+     element they refer to. Multiple error elements may be present for any
+     input element. The <span class="codefrag">FormValidatorAction</span> sets a special field
+     <span class="codefrag">*</span> that indicates whether all parameters were validated
+     successfully or not.
+    </p>
+<p>
+     An error element is omitted together with all contents whenever the
+     specified condition is not met. Conditions are either exact or greater
+     equal constraints indicated by the attribute <span class="codefrag">when</span> or
+     <span class="codefrag">when-ge</span> respectively.
+    </p>
+<p>
+     Allowed values for error conditions are: <span class="codefrag">ok, not-present, error,
+      is-null, too-small, too-large, no-match </span>
+    
+</p>
+<pre class="code">
+
+     &lt;input name="email" type="text"/&gt;&lt;error name="email" when-ge="error"&gt;*&lt;/error&gt;
+     &lt;!-- ... --&gt;
+     &lt;error name="email" when="is-null"&gt;Please enter your email address.&lt;/errro&gt;
+     &lt;error name="email" when="no-match"&gt;Please enter a &lt;em&gt;syntacticly&lt;/em&gt; correct
+     email address.&lt;/errro&gt;
+
+    </pre>
+
+   
+<h2>Other Validations</h2>
+<p>
+   In addition to validating form input, other actions exists that validate
+   values from different sources using the same techniques and syntax. For
+   example, the <span class="codefrag">SessionValidatorAction</span> operates on session
+   attributes.
+  </p>
+
+   
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/meta.xml
new file mode 100644
index 0000000..8206da2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet-forms/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/logicsheet-forms.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/content_en.html
new file mode 100644
index 0000000..7a8143e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/content_en.html
@@ -0,0 +1,440 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XSP Logicsheet Guide</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Painter-Wakefield" name="DC.Creator">
+</head>
+<body>
+
+
+<h1>Introduction</h1>
+  
+<p>This document is intended as an introduction and brief tutorial to using and
+  creating Apache Cocoon XSP logicsheets. It is assumed that the reader has a working
+  knowledge of XML and XSLT, and has worked through at least the basic XSP examples
+  supplied with Cocoon.  Although this is not intended as a tutorial for XSP 
+  specifically, much of the material may be helpful in gaining a fuller understanding
+  of XSP.</p>
+
+
+
+<h1>Taglibs and logicsheets</h1>
+  
+<p>There is some confusion over the terms "taglib" and "logicsheet".  Many people
+  will use these terms interchangeably.  The term "taglib" comes from JSP, which 
+  inspired XSP.  An XSP logicsheet is a "tag library" in the sense that it defines
+  a set of custom XML tags which can be used within an XSP program to insert whole
+  blocks of code into the file.  Cocoon comes with several pre-defined "taglibs",
+  such as the request taglib.  Using the request taglib, you can insert the following
+  tag into your XSP code to obtain the HTTP request parameter named "fruit" (e.g., if
+  your URL looks something like "http://myserver.org/index.xml?fruit=apple", the value
+  of "fruit" is "apple"):</p>
+  
+<pre class="code">&lt;request:get-parameter name="fruit"/&gt;</pre>
+
+  
+<p>We will discuss how to use Cocoon's pre-defined taglibs in a later section.  The
+  important thing to understand is that all taglibs are defined by a logicsheet.  A
+  logicsheet, as we will see, is a special kind of XSL stylesheet, whose output is an
+  XSP file.</p>
+
+
+
+<h1>Hello World!</h1>
+  
+<p>We'll start with some simple <span class="codefrag">Hello, World!</span> examples, starting with
+  a simple HTML file, and extending it using Cocoon technologies until we have a
+  working (if trivial) example of XSP using a custom logicsheet.</p>
+
+
+<h2>Simple HTML Example</h2>
+<p>All of the examples in this section will produce HTML output 
+  essentially equivalent to this:</p>
+<pre class="code">
+&lt;html&gt;
+  &lt;body&gt;
+    &lt;h1&gt;Hello, world!&lt;/h1&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+  
+<p>I did say these would be simple examples, didn't I?</p>
+
+
+<h2>Simple XML/XSL Example</h2>
+<p>Here's a simple XML file:</p>
+<pre class="code">
+greeting.xml
+
+&lt;?xml version="1.0"?&gt;
+
+&lt;greeting&gt;Hello, world!&lt;/greeting&gt;
+</pre>
+<p>...and here's the XSL stylesheet that will transform it into an HTML file
+  similar to the one we started this section with:</p>
+<pre class="code">
+greeting.xsl
+
+&lt;?xml version="1.0"?&gt;
+&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
+
+&lt;xsl:template match="/"&gt;
+  &lt;html&gt;
+    &lt;body&gt;
+      &lt;h1&gt;
+        &lt;xsl:value-of select="greeting"/&gt;
+      &lt;/h1&gt;
+    &lt;/body&gt;
+  &lt;/html&gt;
+&lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+</pre>
+<p>So far, nothing exciting.  The input XML has a single element, &lt;greeting&gt;,
+  whose text contents gets spit out in HTML.  The contents of our particular XML
+  file's greeting is, predictably, "Hello, World!"  The point of showing you this
+  is that, as we elaborate our example by adding Java code through XSP, and later
+  with a custom logicsheet, we will continue to use the same stylesheet to format
+  our final output.  So, the input XML will generally look much like the XML file
+  in this most recent trivial example.</p>
+
+
+<h2>Simple XSP Example</h2>
+<p>Next, we continue in our trivial vein by using trivial Java code to make an
+  XSP program, whose output will mimic that of our XML file above.  The output
+  of this file is transformed to HTML by the same XSL stylesheet as above:</p>
+<pre class="code">
+greeting2.xml
+
+&lt;?xml version="1.0"?&gt;
+
+&lt;xsp:page xmlns:xsp="http://apache.org/xsp"&gt;
+
+  &lt;xsp:logic&gt;
+    // this could be arbitrarily complex Java code, JDBC queries, etc.
+    String msg = "Hello, world!";
+  &lt;/xsp:logic&gt;
+
+  &lt;greeting&gt;
+    &lt;xsp:expr&gt;msg&lt;/xsp:expr&gt;
+  &lt;/greeting&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+
+
+<h2>Simple XSP Logicsheet Example</h2>
+<p>Now we are ready to present our final trivial example, using a custom
+  logicsheet.  There are two files shown below.  The first is an XSP file
+  that uses a custom logicsheet, logicsheet.greeting.xsl, which is the second
+  file shown below.</p>
+<pre class="code">
+greeting3.xml
+
+&lt;?xml version="1.0"?&gt;
+
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:greeting="http://duke.edu/tutorial/greeting"&gt;
+
+  &lt;greeting&gt;
+    &lt;greeting:hello-world/&gt;
+  &lt;/greeting&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+<pre class="code">
+logicsheet.greeting.xsl
+
+&lt;?xml version="1.0"?&gt;
+&lt;xsl:stylesheet
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:greeting="http://duke.edu/tutorial/greeting"
+  version="1.0"&gt;
+
+&lt;xsl:template match="xsp:page"&gt;
+ &lt;xsl:copy&gt;
+  &lt;xsl:apply-templates select="@*"/&gt;
+  &lt;xsl:apply-templates/&gt;
+ &lt;/xsl:copy&gt;
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="greeting:hello-world"&gt;
+  &lt;!-- more complex XSLT is possible here as well --&gt;
+  &lt;xsp:logic&gt;
+    // this could be arbitrarily complex Java code, JDBC queries, etc.
+    String msg = "Hello, world!";
+  &lt;/xsp:logic&gt;
+  &lt;xsp:expr&gt;msg&lt;/xsp:expr&gt;
+&lt;/xsl:template&gt;
+
+&lt;!-- This template simply copies stuff that doesn't match other --&gt;
+&lt;!-- templates and applies templates to any children.           --&gt;
+&lt;xsl:template match="@*|node()" priority="-1"&gt;
+ &lt;xsl:copy&gt;
+  &lt;xsl:apply-templates select="@*|node()"/&gt;
+ &lt;/xsl:copy&gt;
+&lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+</pre>
+<p>There are several things to note about these two files.  First, note
+  that we inform the XSP processor that it should apply our custom logicsheet
+  using the processing instruction</p>
+<pre class="code">&lt;?xml-logicsheet href="logicsheet.greeting.xsl"?&gt;</pre>
+<p>There are other ways to associate a logicsheet with an XSP file, which we'll
+  discuss later.  Next, note that our logicsheet defines a new namespace, 
+  <strong>greeting:</strong>, which must be declared in both files using the same URI:</p>
+<pre class="code">xmlns:greeting="http://duke.edu/tutorial/greeting"</pre>
+<p>Note that the URI is completely arbitrary.  I've chosen to construct my
+  namespace URI's by using my institution's web address (http://duke.edu/)
+  followed by the project name (tutorial) and namespace name (greeting).  
+  You may use any scheme you wish for your namespace URI's; however, the URI
+  declared in the logicsheet <strong>must</strong> match the URI declared in the
+  XSP which uses the logicsheet.</p>
+<p>Finally, note that our logicsheet is merely an XSL stylesheet.  It transforms
+  one XML file into another.  What makes it a logicsheet is that it can be applied
+  not just to any XML file, but specifically to an XSP file, and the end result of
+  its transformation is another XSP file.  If you were to apply the logicsheet in
+  this example to the XML file in this example as just a stylesheet (with no XSP
+  processing), you would end up with something like the following (compare to our 
+  earlier XSP example):</p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;xsp:page 
+  xmlns:greeting="http://duke.edu/tutorial/greeting" 
+  xmlns:xsp="http://apache.org/xsp"&gt;
+
+  &lt;greeting&gt;
+    &lt;xsp:logic&gt;
+      // this could be arbitrarily complex Java code, JDBC queries, etc.
+      String msg = &amp;quot;Hello, world!&amp;quot;;
+    &lt;/xsp:logic&gt;
+    &lt;xsp:expr&gt;msg&lt;/xsp:expr&gt;
+  &lt;/greeting&gt;
+&lt;/xsp:page&gt;
+</pre>
+
+
+
+
+<h1>Using Logicsheets (Taglibs)</h1>
+  
+<p>There are two ways to apply a logicsheet, once you have written it.
+  First, as in the previous examples, you can tell XSP explicitly what
+  logicsheets to apply, using the &lt;?xml-logicsheet?&gt; processing instruction
+  right after xml header and before &lt;xsp:page&gt; tag:</p>
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;?xml-logicsheet href="logicsheet.greeting.xsl"?&gt;
+</pre>
+
+  
+<p>There is another way to apply a logicsheet, which doesn't require a
+  processing instruction for each file that uses the logicsheet.  The
+  second way is to declare logicsheet in the cocoon.xconf file.
+  These declarations take the form</p>
+
+<pre class="code">
+&lt;builtin-logicsheet&gt;
+  &lt;parameter name="prefix" value="&amp;lt;logicsheet's prefix&amp;gt;"/&gt;
+  &lt;parameter name="uri" value="&amp;lt;logicsheet's namespace URI&amp;gt;"/&gt;
+  &lt;parameter name="href" value="&amp;lt;URL to file&amp;gt;"/&gt;
+&lt;/builtin-logicsheet&gt;
+</pre>
+
+  
+<p>Cocoon's pre-defined logicsheets are already declared in this file.  For
+  instance, the declaration of the XSP request taglib is the following:</p>
+
+<pre class="code">
+&lt;builtin-logicsheet&gt;
+  &lt;parameter name="prefix" value="xsp-request"/&gt;
+  &lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
+  &lt;parameter name="href"
+             value="resource://.../markup/xsp/java/request.xsl"/&gt;
+&lt;/builtin-logicsheet&gt;
+</pre>
+
+  
+<p>This line associates the <strong>http://apache.org/xsp/request/2.0</strong> 
+  namespace with the logicsheet named in the URL. This URL points to a file 
+  that is stored in the cocoon.jar. To use the request taglib, you must 
+  declare the request namespace in your XSP file:</p>
+
+<pre class="code">
+...
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+&gt;
+...
+</pre>
+
+  
+<div class="note">You should <strong>not</strong> try to apply the xsp-request 
+  taglib using the &lt;?xml-logicsheet?&gt; processing instruction,
+  as this will result in the logicsheet being applied twice.</div>
+
+  
+<p>You can add your own logicsheets to the cocoon.xconf file using the same
+  syntax. The only trick is constructing an appropriate URL. If we wanted to 
+  declare our <strong>greeting:</strong> namespace and logicsheet from the 
+  Hello, World! example above, and if the logicsheet were stored (on a UNIX 
+  filesystem) in the location /cocoon/logicsheets/logicsheet.greeting.xsl, 
+  we'd add this line to cocoon.xconf:</p>
+
+<pre class="code">
+&lt;builtin-logicsheet&gt;
+  &lt;parameter name="prefix" value="greeting"/&gt;
+  &lt;parameter name="uri" value="http://duke.edu/tutorial/greeting"/&gt;
+  &lt;parameter name="href"
+             value="file:///cocoon/logicsheets/logicsheet.greeting.xsl"/&gt;
+&lt;/builtin-logicsheet&gt;
+</pre>
+
+  
+<p>There are some very important differences between using the &lt;?xml-logicsheet?&gt; 
+  processing instruction vs. the cocoon.properties entry to apply a logicsheet.
+  Using cocoon.properties, any time the logicsheet changes, it is necessary to 
+  restart Cocoon.  If you instead use the processing instruction, Cocoon will detect
+  modifications to your logicsheet, and recompile your XSP programs accordingly.
+  Also, if you need to explicitly control the order in which your logicsheets are
+  applied, you need to use the processing instruction.  Logicsheets will be applied
+  in the order in which they appear in processing instructions in your source file.</p>
+
+  
+<p>Whichever method you use, the most important thing to remember is that you must
+  declare, in your XSP program, the namespace for a logicsheet using the same URI as
+  in the logicsheet itself.</p>
+
+
+
+<h1>Logicsheet Development Tips</h1>
+  
+<h2>Development Practices</h2>
+<p>Developing Logicsheets can be a frustrating mental exercise, as it requires you
+  to understand and keep in mind the complex coordination of several different 
+  technologies: XML, XSLT, XSP, and Java.  A bad assumption in any of these areas
+  can lead to an hour of debugging.  Following a few simple practices can reduce the
+  frustration and make logicsheet programming less difficult:</p>
+<dl>
+    
+<dt>Small Increments</dt>
+    
+<dd>As with any software development, it is much easier to debug a small amount
+    of code than a large amount of code.  XSP is no different, except that the 
+    complexity of a large amount of code is multiplied by the number of different
+    technologies.  So, write a tiny bit of code and get it working, or start with a
+    simple piece of code that is already working.  Make small changes, and get each
+    change working before making the next.</dd>
+    
+<dt>Prototype New Ideas</dt>
+    
+<dd>Before trying something you haven't done before (e.g., a new XPath expression,
+    a new Java syntax), prototype it in a simple environment where you can easily see
+    the results of your code.  It is more difficult to debug your changes if the output
+    is filtered through multiple stylesheets and rendered into HTML.  So instead, write
+    a small XSP that you can use to test your code fragment and see the resulting XML.</dd>
+    
+<dt>Use the Source</dt>
+    
+<dd>After transforming your XSP code with your logicsheet, the XSP processor writes
+    the resulting Java code to a file in your repository.  The repository is in a
+    directory specified in cocoon.properties.  Make a shortcut to your repository
+    directory and go there often.  Read the code that resulted from application of your
+    stylesheet.  This lets you debug the Java code as Java code, absent from all of the
+    XML/XSL complications.  It also lets you see exactly the results of XSLT transformation
+    using your logicsheet.</dd>
+    
+<dt>Steal Code</dt>
+    
+<dd>The authors of the logicsheets distributed with Cocoon have already solved
+    numerous problems that you may encounter.  Read their code (it is in the source
+    tree) and borrow from it liberally.  Reading this code is also a good way to
+    gain insight into logicsheet design.</dd>
+  
+</dl> 
+
+  
+<h2>Standard Templates</h2>
+<p>As we discussed earlier, a logicsheet is just an XSLT stylesheet which transforms
+    one XSP source file into another.  Since we are always expecting to act on an XSP 
+    source file, and there is the possibility that other logicsheets may also be acting
+    on the same file (either before or after our logicsheet), there are a few templates
+    which are more or less required in any logicsheet.  The templates below were all
+    pulled from the taglib logicsheets distributed with Cocoon.</p>
+<p>The first of these is simply a template to copy anything you don't directly act
+    upon yourself.  You probably have a template similar to this in most of your
+    stylesheets already.</p>
+<pre class="code">
+&lt;xsl:template match="@*|node()" priority="-1"&gt;
+  &lt;xsl:copy&gt;
+    &lt;xsl:apply-templates select="@*|node()"/&gt;
+  &lt;/xsl:copy&gt;
+&lt;/xsl:template&gt;
+</pre>
+<p>If your code requires any Java imports, or if you want to declare methods or
+    variables at the class level, you will need to have a way to add elements to the
+    &lt;xsp:page&gt; element that is at the root of the source file.  Here is a template
+    to let you do that (from esql.xsl):</p>
+<pre class="code">
+&lt;xsl:template match="xsp:page"&gt;
+  &lt;xsp:page&gt;
+    &lt;xsl:apply-templates select="@*"/&gt;
+    &lt;xsp:structure&gt;
+      // you can put &amp;lt;xsp:include&gt; statements in here to import Java classes
+    &lt;/xsp:structure&gt;
+    &lt;xsp:logic&gt;
+      // put class-level variable declarations and methods here
+    &lt;/xsp:logic&gt;
+  &lt;/xsp:page&gt;
+&lt;/xsl:template&gt;
+</pre>
+<p>Frequently, you may also need to declare variables or perform initialization
+    that needs to occur before any of the code in your custom tags.  You could, of
+    course, require that the users of your logicsheet use one particular tag before
+    using any other, and then put your declarations and initializations in the template
+    matching that one tag.  This may not be the best solution, however, and may be
+    a source of confusion.  Instead, the following template can be used to insert
+    code inside the populateDocument() method, after the standard XSP code (such as
+    declaration of the request and response variables), but before any user code
+    from the source XSP file (including code inserted by your custom tags). The
+    complex XPath expression here just says "match on any child elements of &lt;xsp:page
+    which don't themselves begin with 'xsp:'".  Since the &lt;xsp:page&gt; element always
+    has a single element which isn't in the xsp: namespace, this will be matched once
+    and only once.</p>
+<pre class="code">
+&lt;xsl:template match="xsp:page/*[not(starts-with(name(.), 'xsp:'))]"&gt;
+ &lt;xsl:copy&gt;
+  &lt;xsl:apply-templates select="@*"/&gt;
+  &lt;xsp:logic&gt;
+    // This code ends up inside populateDocument() before any user code
+  &lt;/xsp:logic&gt;
+  &lt;xsl:apply-templates/&gt;
+ &lt;/xsl:copy&gt;
+&lt;/xsl:template&gt; 
+</pre>
+
+  
+<h2>Logicsheets Using Logicsheets</h2>
+<p>Since software tends to build on other software, you will probably find
+    yourself wanting to write logicsheets which make use of other logicsheets,
+    particularly the logicsheets provided with Cocoon.  This is very possible.
+    When using one logicsheet inside another, the most important thing to remember
+    is that you must declare the namespace for the second logicsheet not only in
+    the first logicsheet, but also in any XSP program that uses the first logicsheet,
+    even if it doesn't directly reference any of the tags in the second logicsheet.</p>
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/meta.xml
new file mode 100644
index 0000000..fd9ee50
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-logicsheet/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/logicsheet.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/content_en.html
new file mode 100644
index 0000000..756a824
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/content_en.html
@@ -0,0 +1,688 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Request Logicsheet</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Painter-Wakefield" name="DC.Creator">
+</head>
+<body>
+
+
+<h1>Description</h1>
+
+
+<p>The Request logicsheet (taglib) is an XSP logicsheet that wraps XML tags around
+standard request operations.  Specifically, the Request logicsheet provides an XML
+interface to most methods of the HttpServletRequest object (see the
+<a class="external" href="http://java.sun.com/products/servlet/2.2/javadoc/index.html">
+Java Servlet API Specification, version 2.2
+</a>) for more information.</p>
+
+
+<p>The Request tags provide information about all aspects of the current request,
+such as the request method (GET, POST, etc.), what protocol is in use (http, https),
+cookie information, preferred locale, and so forth.  The Request logicsheet is
+probably used mostly, however, for obtaining field values from a submitted HTML form.
+See xsp-request:get-parameter below for more information on this topic.</p>
+
+
+
+
+<h1>Usage</h1>
+
+
+<p>As an XSP logicsheet, the Request logicsheet can only be used in an XSP page.
+It may be helpful to be familiar with <a href="xsp.html">XSP</a> before
+working with this (or any) logicsheet.</p>
+
+
+<p>To use the Request logicsheet, you must first declare the <em>xsp-request</em>
+namespace, mapping it to the uri <em>http://apache.org/xsp/request/2.0</em>.
+This is typically done like this:</p>
+
+
+<pre class="code">
+&lt;xsp:page
+    xmlns:xsp="http://apache.org/xsp"
+    xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+&gt;
+...
+&lt;/xsp:page&gt;
+</pre> 
+
+
+<p>You may then use any of the elements in the <em>request</em> namespace described
+in the <a href="request.html#id_el">Elements Reference</a> section below.</p>
+
+
+
+
+<h1>Example Code</h1>
+
+
+<p>The following code shows a typical example of using the Request logicsheet.
+The output elements display the request method and the value of the query
+parameter "fruit".  Of course, rather than displaying these values as we've
+done, you might instead store them in elements and process them further through
+an XSLT stylesheet, for instance.</p>
+
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;xsp:page
+    xmlns:xsp="http://apache.org/xsp"
+    xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+&gt;
+  &lt;html&gt;
+    &lt;b&gt;Request method:&lt;/b&gt; &lt;xsp-request:get-method/&gt;
+    &lt;br/&gt;
+    &lt;b&gt;Fruit requested:&lt;/b&gt; &lt;xsp-request:get-parameter name="fruit"/&gt;
+  &lt;/html&gt;
+&lt;/xsp:page&gt;
+</pre> 
+
+
+<p>If your server is www.mydomain.com and you save this XML in your Cocoon
+document tree as /cocoon/request.xml, then you can see the effect of the 
+<em>request</em> elements by opening your browser with the URL
+<span class="codefrag">http://www.mydomain.com/cocoon/request.xml?fruit=apple</span>
+</p>
+
+
+<p>The output should look something like:</p>
+
+<p>
+<strong>Request Method:</strong> GET</p>
+
+<p>
+<strong>Fruit requested:</strong> apple</p>
+
+
+
+
+<h1>XSP Interactions</h1>
+
+
+<p>The Request logicsheet tags may be used interchangeably with XSP code that 
+directly uses the <span class="codefrag">request</span> object.  The <span class="codefrag">request</span> object
+is an instance of the HttpServletRequest class, and is available inside the
+user element in an XSP page.  The Request logicsheet itself uses this object.
+Therefore, the following code snippets function essentially the same:</p>
+
+
+<pre class="code">
+
+<strong>Using the Request logicsheet:</strong>
+
+&lt;xsp:page
+    xmlns:xsp="http://apache.org/xsp"
+    xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+&gt;
+  &lt;page&gt;
+    &lt;fruit&gt;&lt;xsp-request:get-parameter name="fruit"/&gt;&lt;/fruit&gt;
+  &lt;/page&gt;
+&lt;/xsp:page&gt;
+</pre> 
+
+
+<pre class="code">
+
+<strong>Using the request object:</strong>
+
+&lt;xsp:page
+    xmlns:xsp="http://apache.org/xsp"
+&gt;
+  &lt;page&gt;
+    &lt;fruit&gt;&lt;xsp:expr&gt;request.getParameter("fruit")&lt;/xsp:expr&gt;&lt;/fruit&gt;
+  &lt;/page&gt;
+&lt;/xsp:page&gt;
+</pre> 
+
+
+<p>You may freely mix Request elements with other XSP Java code.  Many, if not
+most, Request elements result in String objects.  Thus, the following code
+fragment is valid:</p>
+
+
+<pre class="code">
+&lt;xsp:logic&gt;
+  String fruit = &lt;xsp-request:get-parameter name="fruit"/&gt;;
+  if (fruit != null) {
+    fruit = fruit.toUpperCase();
+  }
+&lt;/xsp:logic&gt;
+&lt;fruit&gt;&lt;xsp:expr&gt;fruit&lt;/xsp:expr&gt;&lt;/fruit&gt;
+</pre> 
+
+
+
+
+<a name="id_el"></a>
+
+<h1>Elements Reference</h1>
+
+
+<p>All Request elements which require or allow for additional information allow
+you to provide the information as either an attribute or a child element.  These
+attributes/child elements are listed in the "Attributes/Child Elements" column
+of the table below.  Unless noted, these are required for the given element; 
+their absence will result in Java compilation errors or exceptions.</p>
+
+<p>The following fragments are equivalent:</p>
+
+
+<pre class="code">
+&lt;xsp-request:get-parameter name="fruit"/&gt;
+</pre> 
+
+
+<pre class="code">
+&lt;xsp-request:get-parameter&gt;
+  &lt;xsp-request:name&gt;fruit&lt;/xsp-request:name&gt;
+&lt;/xsp-request:get-parameter&gt;
+</pre> 
+
+
+<p>All Request elements which get data from the request can output the data
+in two ways.  The <span class="codefrag">as</span> attribute of the element is used to switch
+between the different output options.  The choice is always between some
+default value for <span class="codefrag">as</span> and the value "node".  Using the default
+value for <span class="codefrag">as</span> (which is most easily achieved by leaving out the
+attribute altogether), the Request element will put the result of its operation
+in an &lt;xsp:expr&gt; node.  This allows you to use the result in a Java expression,
+or converts it to text in the output DOM tree.  If you use <span class="codefrag">as="node"</span>,
+however, the output is embedded in a node or nodes, as appropriate.  For instance,
+the following code fragment:</p>
+
+
+<pre class="code">
+&lt;xsp-request:get-parameter as="xml" name="fruit"/&gt;
+</pre> 
+
+
+<p>results in output similar to:</p>
+
+
+<pre class="code">
+&lt;xsp-request:parameter name="fruit"&gt;apple&lt;/xsp-request:parameter&gt;
+</pre> 
+
+
+<p>This is especially useful with elements that return multiple pieces of
+information, such as <span class="codefrag">xsp-request:get-parameter-values</span>.  Without using 
+<span class="codefrag">as="node"</span>, the returned values are written out end to end
+without separation.  If node output is requested, however, each value
+is written out in a separate node, which may then be referenced separately.</p>
+
+
+<p>The elements which provide for node output are marked with a "yes" in the
+"Node?" column of the table below.  Unlike the other attributes used in 
+Request elements, <span class="codefrag">as</span> cannot be supplied as a child element; it
+must be supplied as an attribute, if it is used at all.</p>
+
+
+
+<div class="note">Since these elements are primarily wrappers around HttpServletRequest
+methods, the HttpServletRequest documentation in the
+<a class="external" href="http://java.sun.com/products/servlet/2.2/javadoc/index.html">
+Java Servlet API Specification, version 2.2
+</a> 
+is also helpful in understanding the behavior and usage of these elements.</div>
+
+
+<table>
+All of the Request logicsheet elements, in alphabetic order.
+<tr>
+
+<th colspan="1" rowspan="1">Element Name</th>
+<th colspan="1" rowspan="1">Attributes/Child Elements</th>
+<th colspan="1" rowspan="1">Node?</th>
+<th colspan="1" rowspan="1">Description</th>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets a named attribute set by the servlet container or by a previous 
+xsp-request:set-attribute operation.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-attribute-names</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the names of all available request attributes.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-auth-type</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name of the authentication scheme used to protect this request
+location, if used, e.g., BASIC or SSL.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-character-encoding</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name of the character encoding used in the body of this request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-content-length</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the length, in bytes, of the request body, or -1 if the length is unknown.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-content-type</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the MIME type of the body of the request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-context-path</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the portion of the request URI that indicates the context of the request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-cookies</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets all cookie objects supplied by the client with this request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-date-header</td>
+<td colspan="1" rowspan="1">name, format <em>(optional)</em></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the value of the named request header that represents a date. Use this 
+method with headers that contain dates, such as If-Modified-Since.  The <span class="codefrag">as</span> attribute
+for this element may be "long" (default), "string", "date", or "node".  If "long",
+the returned value is a Java <span class="codefrag">long</span> that represents a Java <span class="codefrag">Date</span>
+value.  If "date", the returned value is a Java <span class="codefrag">Date</span> object.  If "string" or 
+"node", the optional <span class="codefrag">format</span> attribute may be used
+to supply a format string for a Java <span class="codefrag">SimpleDateFormat</span> to format the resulting
+string.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-header</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the string value of the named request header.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-headers</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets all values of the named request header.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-header-names</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the names of all available request headers.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-int-header</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the value of the named request header which represents an integer,
+or -1 if the named header doesn't exist.  The <span class="codefrag">as</span> attribute may
+be set to "int" (default), "string", or "node".</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-locale</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the preferred locale for the client browser, or the default
+server locale if not provided by the client.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-locales</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the locales accepted by the client in order of preference.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-method</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name of the method associated with this request, e.g., GET, POST, or PUT.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-parameter</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the value of the named request parameter.  This is a value from
+the request string (e.g., ?fruit=apple) or from POSTed form data.  If the parameter
+has more than one value, (e.g, ?fruit=apple&amp;fruit=orange), then this gets the first
+value.  See xsp-request:get-parameter-values. Possible attributes:
+form-encoding (depends on the encoding of the page which sends the form data)
+and container-encoding (default per servlet spec: ISO-8859-1 but if your servlet container
+uses another one you can adjust)</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-parameter-names</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the names of all the request parameters.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-parameter-values</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets all values for the named request parameter.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-path-info</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets any additional path information supplied by the client with this request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-path-translated</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets any additional path information after the servlet name but before the query string,
+translated to a real path.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-protocol</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name and version of the protocol the request uses, for example, HTTP/1.1.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-query-string</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the query string for this request (e.g., "?fruit=apple&amp;bread=rye").</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-remote-address</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the IP address of the requesting client.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-remote-host</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the fully-qualified name of the requesting client, or the IP address
+if the name cannot be determined.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-remote-user</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the login name of the user making the request, if a user has been
+authenticated.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-requested-session-id</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the session id contained in the request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-sitemap-uri</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the part of the request URL that was matched in the sitemap.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-requested-url</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Returns the full request URL including server name and port.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-scheme</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name of the scheme used in this request, e.g., http or https.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-server-name</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the name of the server that received the request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-server-port</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the port on which the request was received, e.g., 80 or 443.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-servlet-path</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the part of the request URL that calls the servlet.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-session-attribute</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Gets a given attribute of a session.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-session-id</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the id of the session.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-user-principal</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets a java.security.Principal object containing the name of the user,
+if a user has been authenticated.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:get-uri</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the part of the request URL after the server address and port, up to
+the query string.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:is-secure</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Indicates whether the request was made using a secure protocol such as HTTPS.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:is-user-in-role</td>
+<td colspan="1" rowspan="1">role</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Indicates whether the authenticated user is a member in the named role.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:remove-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Removes the named attribute from the request.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-request:set-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Sets the named attribute to the value represented by any children of the element.
+If the element has a text node as its child, the attribute will be set to the String
+containing the text.</td>
+
+</tr>
+
+
+</table>
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/meta.xml
new file mode 100644
index 0000000..d5df3d1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-request/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/request.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/content_en.html
new file mode 100644
index 0000000..208287e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/content_en.html
@@ -0,0 +1,371 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Sendmail Logicsheet</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Frank Ridderbusch" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Description</h1>
+      
+<p>The Sendmail logicsheet (taglib) is a XSP logicsheet that
+  wraps XML tags around the operation of sending an email
+  message. Specifically, the Sendmail logicsheet provides an XML
+  interface to the primary methods of the Java Mail API for
+  sending an internet mail including the ability to attach any
+  binary data files to the message (see the
+  <a class="external" href="http://java.sun.com/products/javamail/">Java
+    Mail API</a> ) for more
+  information.</p>
+
+      
+<p>The Sendmail logicsheet is an alternative to the <a href="../actions/sendmail-action.html">Sendmail
+    action</a>.</p>
+    
+
+    
+<h1>Usage</h1>
+      
+<p>As an XSP logicsheet, the Sendmail logicsheet can only be used
+  in an XSP page. It may be helpful to be familiar with <a href="xsp.html">XSP</a> before working with this (or any)
+  logicsheet.</p>
+
+      
+<p>Since the Sendmail logicsheet is not activated in the default
+  Cocoon setup, a couple of steps must be taken before an email
+  can be send.</p>
+
+      
+<p>First of all Cocoon must have been compiled with the required
+  Java Mail API libraries. The libraries <span class="codefrag">mail.jar</span>
+  from the Java Mail distribution and the library
+  <span class="codefrag">activation.jar</span> from the Java Activation Framework
+  have to be copied to the location <span class="codefrag">lib/local</span> of
+  Cocoon's source distribution. Cocoon must then be recompiled.
+      </p>
+
+      
+<p>Before the Sendmail logicsheet can be used, some setup in
+  <span class="codefrag">cocoon.xconf</span> is required. See, if the following
+  fragment is already existing.</p>
+
+      
+<pre class="code">
+
+&lt;builtin-logicsheet&gt;
+  &lt;parameter name="prefix" value="sendmail"/&gt;
+  &lt;parameter name="uri" value="http://apache.org/cocoon/sendmail/1.0"/&gt;
+  &lt;parameter name="href"
+   value="resource://org/apache/cocoon/components/language/markup/xsp/java/sendmail.xsl"/&gt;
+&lt;/builtin-logicsheet&gt;
+
+      </pre>
+
+      
+<p>If it is not present, it is easiest to simply locate the
+  entry <span class="codefrag">xsp-response</span> for the Response logicsheet
+  and put the above fragment before the
+  <span class="codefrag">&lt;builtin-logicsheet&gt;</span> of the Response
+  logicsheet entry. This can either be done before recompilation
+  or later, when Cocoon is already deployed. If done later,
+  Cocoon must be reloaded.</p>
+
+      
+<p>To use the Sendmail logicsheet, you must first declare the
+  <em>sendmail</em> namespace, mapping it to the uri
+  <em>http://apache.org/cocoon/sendmail/1.0</em>. These
+  steps will result in code like this:</p>
+
+      
+<pre class="code">
+
+&lt;xsp:page language="java"
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:sendmail="http://apache.org/cocoon/sendmail/1.0"&gt;
+
+...
+
+&lt;/xsp:page&gt;
+
+      </pre>
+
+      
+<p>You may then use any of the elements in the <em>sendmail</em>
+  namespace described in the <a href="sendmail.html#elements">Elements Reference</a>
+  section below.</p>
+    
+
+    
+<h1>Example Code</h1>
+      
+<p>The following code shows an example of using the Sendmail
+  logicsheet. A HTML form is used, to post information about
+  updated documentation to some imaginary mailing list. The XSP
+  page is invoked from a HTML form like this.</p>
+
+      
+<pre class="code">
+
+&lt;form action="/cocoon/xsp/mail/send-a-mail" method="post"
+      enctype="multipart/form-data"&gt;
+
+&lt;input type="text" name="subject" size="56" /&gt;
+...
+&lt;input type="text" name="url1" size="56" /&gt;
+...
+&lt;input type="text" name="url1" size="56" /&gt;
+...
+&lt;input type="file" name="uploaded_file1" size="56" /&gt;
+...
+&lt;input type="file" name="uploaded_file2" size="56" /&gt;
+...
+&lt;textarea name="changes" rows="5" cols="72"&gt;
+&lt;/textarea&gt;
+...
+&lt;/form&gt;
+
+      </pre>
+
+      
+<p>Since the form allows to attach upto two arbitrary files, it
+  is important, that <span class="codefrag">enctype="multipart/form-data"</span>
+  is used. This is the XSP code, that is invoked:</p>
+
+      
+<pre class="code">
+
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;xsp:page language="java"
+    xmlns:xsp="http://apache.org/xsp"
+    xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+    xmlns:sendmail="http://apache.org/cocoon/sendmail/1.0"&gt;
+  &lt;email&gt;
+    &lt;xsp:logic&gt;
+      StringBuffer body = new StringBuffer();
+      body.append("  Documentation:\n----------------\n");
+      body.append("URL: ");
+      body.append(&lt;xsp-request:get-parameter name="url1"/&gt;);
+      body.append("\n");
+      body.append("URL: ");
+      body.append(&lt;xsp-request:get-parameter name="url2"/&gt;);
+      body.append("\n\n");
+      body.append("     Changes:\n----------------\n");
+      body.append(&lt;xsp-request:get-parameter name="changes"/&gt;);
+      body.append("\n\n");
+    &lt;/xsp:logic&gt;
+    &lt;sendmail:send-mail&gt;
+      &lt;sendmail:from&gt;from address&lt;/sendmail:from&gt;
+      &lt;sendmail:to&gt;some maillinglist address&lt;/sendmail:to&gt;
+      &lt;sendmail:subject&gt;&lt;xsp-request:get-parameter name="subject"/&gt;&lt;/sendmail:subject&gt;
+      &lt;!-- Uncomment to override defaults from cocoon.xconf
+      &lt;sendmail:smtphost&gt;localhost&lt;/sendmail:smtphost&gt;
+      &lt;sendmail:smtpuser&gt;localhost&lt;/sendmail:smtpuser&gt;
+      &lt;sendmail:smtppassword&gt;localhost&lt;/sendmail:smtppassword&gt;
+      --&gt;
+      &lt;sendmail:body&gt;&lt;xsp:expr&gt;body.toString()&lt;/xsp:expr&gt;&lt;/sendmail:body&gt;
+      &lt;sendmail:attachment&gt;
+        &lt;sendmail:param name="object"&gt;&lt;xsp:expr&gt;request.get("attachment")&lt;/xsp:expr&gt;&lt;/sendmail:param&gt;
+      &lt;/sendmail:attachment&gt;
+      &lt;sendmail:attachment url="context://welcome.xml" mime-type="text/plain" name="foo.txt"/&gt;
+      &lt;sendmail:attachment url="cocoon:///"            mime-type="text/html"  name="welcome.html"/&gt;
+
+      &lt;sendmail:on-success&gt;
+         &lt;p&gt;
+           Email successfully sent.
+         &lt;/p&gt;
+      &lt;/sendmail:on-success&gt;
+      &lt;sendmail:on-error&gt;
+        &lt;p style="color:red;"&gt;
+           An error occurred: &lt;sendmail:error-message/&gt;
+        &lt;/p&gt;
+      &lt;/sendmail:on-error&gt;
+    &lt;/sendmail:send-mail&gt;
+ &lt;/email&gt;
+&lt;/xsp:page&gt;
+
+      </pre>
+
+      
+<p>Cocoons feature to automatically disassemble the incoming
+  request puts the uploaded files automatically into the upload
+  directory and the files are accessible through the
+  <span class="codefrag">uploaded_file[12]</span> request parameters (make sure,
+  that <span class="codefrag">autosave-uploads</span> is set to <span class="codefrag">true</span>
+  in the <span class="codefrag">WEB-INF/web.xml</span> file of the Cocoon
+  context). By using
+  <span class="codefrag">&lt;xsp:expr&gt;request.get("req-param")&lt;/xsp:expr&gt;</span>
+  you actually get an object of class
+  <span class="codefrag">org.apache.cocoon.servlet.multipart.Part</span>.
+  The <span class="codefrag">&lt;sendmail:send-mail&gt;</span> fragment is
+  replaced with an <span class="codefrag">&lt;error&gt;</span> element, if an
+  error occurs during the sending of the message.</p>
+
+      
+<p>Another noteworthy item is the formatting of the body text
+  through a Java <span class="codefrag">StringBuffer</span>. Any formatting, that
+  would be placed inside the <span class="codefrag">&lt;sendmail:body&gt;</span>
+  element would be lost due to the internal workings of the
+  Sendmail logicsheet.</p>
+
+    
+
+    
+<a name="elements"></a>
+
+    
+<h1>Elements Reference</h1>
+
+      
+<table>
+        All of the Sendmail logicsheet elements, in alphabetic
+        order.
+
+        <tr>
+          
+<th colspan="1" rowspan="1">Element Name</th>
+
+          <th colspan="1" rowspan="1">Attributes/Child Elements</th>
+
+          <th colspan="1" rowspan="1">Description</th>
+        
+</tr>
+
+        
+<tr>
+
+          
+<td colspan="1" rowspan="1">sendmail:attachment</td>
+
+          <td colspan="1" rowspan="1">
+    </td>
+
+          <td colspan="1" rowspan="1">Sets the attachment for this email. Attributes for setting name,
+              mime-type, or an URL (e.g. using cocoon:-protocol!). Parameters
+can be set dynamically using &lt;sendmail:param/&gt; syntax. If an object is
+to be attached, it must be set this way. Use the following
+      expression to obtain the correct object from the request:
+      <span class="codefrag">&lt;xsp:expr&gt;request.get("req-param")&lt;/xsp:expr&gt;</span>.
+          </td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:bcc</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the recipients of a blind carbon copy of the
+      email. This can be a list of comma separated email
+      addresses.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:body</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the body text of the message.</td>
+        
+</tr>
+
+
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:cc</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the recipients of a carbon copy of this email. This
+      can be a list of comma separated email addresses.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:charset</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the character set for encoding the message. This
+      tag has only an effect, if no attachments are send.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:from</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the from address of the message.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:smtphost</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">The IP-address or the name of the host, which should
+      deliver the email message. Better known as the mail
+      transfer agent or short MTA.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:subject</td>
+
+          <td colspan="1" rowspan="1">
+          </td>
+
+          <td colspan="1" rowspan="1">Sets the subject line of the message.</td>
+        
+</tr>
+
+        
+<tr>
+          
+<td colspan="1" rowspan="1">sendmail:to</td>
+
+          <td colspan="1" rowspan="1"></td>
+
+          <td colspan="1" rowspan="1">Sets the destination/to address of the email message.
+      This can be a list of comma separated email
+      addresses.</td>
+        
+</tr>
+
+      
+</table>
+    
+
+    
+<h1>Hint</h1>
+      
+<p>Please read this <a href="../actions/sendmail-action.html#hint">hint</a>,
+  since it applies here as well.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/meta.xml
new file mode 100644
index 0000000..caf8953
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sendmail/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/sendmail.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/content_en.html
new file mode 100644
index 0000000..64b3f9e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/content_en.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Server Pages Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the server pages generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Server Pages Generator</h1>
+      
+<p>????.</p>
+      
+<ul>
+        
+<li>Name : serverpages</li>
+        
+<li>Class: org.apache.cocoon.generation.ServerPagesGenerator</li>
+        
+<li>Cacheable: ????.</li>
+      
+</ul>
+
+<pre class="code">
+     
+  &lt;map:generate type="serverpages"/&gt;
+     
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/meta.xml
new file mode 100644
index 0000000..476c1c2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-serverpages-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/serverpages-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/content_en.html
new file mode 100644
index 0000000..6c151bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/content_en.html
@@ -0,0 +1,405 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session Logicsheet</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Painter-Wakefield" name="DC.Creator">
+</head>
+<body>
+
+
+<h1>Description</h1>
+
+
+<p>The Session logicsheet (taglib) is an XSP logicsheet that wraps XML tags around
+standard session operations.  Specifically, the Session logicsheet provides an XML
+interface to most methods of the HttpSession object (see the
+<a class="external" href="http://java.sun.com/products/servlet/2.2/javadoc/index.html">
+Java Servlet API Specification, version 2.2
+</a>) for more information.</p>
+
+
+<p>Each client gets its own unique session, which is created the first
+time it accesses a page which creates or retrieves a session (see Usage, 
+below).  This session is identified by a unique id, which is generated by
+the servlet server and is passed back and forth to the client either as
+a cookie or as a parameter in the request query string.</p>
+
+
+<p>The Session logicsheet may be used to retrieve information about the
+session itself, such as its creation time, and it may be used to store
+and retrieve information in the session, such as a login name.  The session
+will typically become invalid after some length of time, releasing the
+stored information.  You can query whether a session is new and how long it
+will remain valid between client requests, and you can also set how long
+the session should remain valid.</p>
+
+
+
+
+<h1>Usage</h1>
+
+
+<p>As an XSP logicsheet, the Session logicsheet can only be used in an XSP page.
+It may be helpful to be familiar with <a href="xsp.html">XSP</a> before
+working with this (or any) logicsheet.</p>
+
+
+<p>To use the Session logicsheet, you must first declare the <em>session</em>
+namespace, mapping it to the uri <em>http://apache.org/xsp/session/2.0</em>.
+Also, to ensure that you have a session to work with, you must set the
+<span class="codefrag">create-session</span> attribute in the xsp:page element to true.  This
+will retrieve the existing session, or create a new one if the current one is
+invalid or doesn't exist.  These steps will result in code like this:</p>
+
+
+<pre class="code">
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:xsp-session="http://apache.org/xsp/session/2.0"
+  create-session="true"&gt;
+
+...
+
+&lt;/xsp:page&gt;
+</pre>
+
+
+<p>You may then use any of the elements in the <em>session</em> namespace described
+in the <a href="session.html#elements">Elements Reference</a> section below.</p>
+
+
+
+
+<h1>Example Code</h1>
+
+
+<p>The following code shows an example of using the Session logicsheet.
+This code stores a value in the session under the name "fruit", then
+retrieves it into the output.  It also retrieves the creation time of
+the session as a String.
+Of course, rather than displaying the retrieved values as we've
+done, you might instead store them in elements and process them further,
+through an XSLT stylesheet for instance.</p>
+
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:xsp-session="http://apache.org/xsp/session/2.0"
+  create-session="true"&gt;
+
+  &lt;html&gt;
+    &lt;xsp-session:set-attribute name="fruit"&gt;Apple&lt;/xsp-session:set-attribute&gt;
+    &lt;b&gt;Your fruit is:&lt;/b&gt; &lt;xsp-session:get-attribute name="fruit"/&gt;
+    &lt;br/&gt;
+    &lt;b&gt;Your session was created:&lt;/b&gt; &lt;xsp-session:get-creation-time as="string"/&gt;
+  &lt;/html&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+
+
+<p>The output of this page should look something like:</p>
+
+<p>
+<strong>Your fruit is:</strong> Apple</p>
+
+<p>
+<strong>Your session was created:</strong> Wed Jun 13 17:42:44 EDT 2001</p>
+
+
+
+
+<h1>XSP Interactions</h1>
+
+
+<p>The Session logicsheet tags may be used interchangeably with XSP code that 
+directly uses the <span class="codefrag">session</span> object.  The <span class="codefrag">session</span> object
+is an instance of the HttpSession class, and is available inside the user element
+in an XSP page, if the <span class="codefrag">create-session</span> attribute of the xsp:page element
+has been set to true.  The Session logicsheet itself uses this object.
+Therefore, the following code snippets function essentially the same:</p>
+
+
+<pre class="code">
+
+<strong>Using the Session logicsheet:</strong>
+
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:xsp-session="http://apache.org/xsp/session/2.0"
+  create-session="true"&gt;
+
+  &lt;page&gt;
+    &lt;xsp-session:set-attribute name="fruit"&gt;Apple&lt;/xsp-session:set-attribute&gt;
+    &lt;fruit&gt;&lt;xsp-session:get-attribute name="fruit"/&gt;&lt;/fruit&gt;
+  &lt;/page&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+
+
+<pre class="code">
+
+<strong>Using the session object:</strong>
+
+&lt;xsp:page
+  xmlns:xsp="http://apache.org/xsp"
+  xmlns:xsp-session="http://apache.org/xsp/session/2.0"
+  create-session="true"&gt;
+
+  &lt;page&gt;
+    session.setAttribute("fruit", "Apple");
+    &lt;fruit&gt;&lt;xsp:expr&gt;session.getAttribute("fruit")&lt;/xsp:expr&gt;&lt;/fruit&gt;
+  &lt;/page&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+
+
+<p>You may freely mix Session elements with other XSP Java code, thus:</p>
+
+
+<pre class="code">
+&lt;xsp:logic&gt;
+  String fruit = &lt;xsp-session:get-attribute name="fruit"/&gt;;
+  if (fruit != null) {
+    fruit = fruit.toUpperCase();
+  }
+&lt;/xsp:logic&gt;
+&lt;fruit&gt;&lt;xsp:expr&gt;fruit&lt;/xsp:expr&gt;&lt;/fruit&gt;
+</pre> 
+
+
+
+
+<a name="elements"></a>
+
+<h1>Elements Reference</h1>
+
+
+<p>All Session elements which require or allow for additional information allow
+you to provide the information as either an attribute or a child element.  These
+attributes/child elements are listed in the "Attributes/Child Elements" column
+of the table below.  Unless noted, these are required for the given element; 
+their absence will result in Java compilation errors or exceptions.</p>
+
+<p>The following fragments are equivalent:</p>
+
+
+<pre class="code">
+&lt;xsp-session:get-attribute name="fruit"/&gt;
+</pre> 
+
+
+<pre class="code">
+&lt;xsp-session:get-attribute&gt;&lt;xsp-session:name&gt;fruit&lt;/xsp-session:name&gt;&lt;/xsp-session:get-attribute&gt;
+</pre> 
+
+
+<p>All Session elements which get data from the session can output the data
+in two ways.  The <span class="codefrag">as</span> attribute of the element is used to switch
+between the different output options.  The choice is always between some
+default value for <span class="codefrag">as</span> and the value "node".  Using the default
+value for <span class="codefrag">as</span> (which is most easily achieved by leaving out the
+attribute altogether), the Session element will put the result of its operation
+in an &lt;xsp:expr&gt; node.  This allows you to use the result in a Java expression,
+or converts it to text in the output DOM tree.  If you use <span class="codefrag">as="node"</span>,
+however, the output is embedded in a node or nodes, as appropriate.  For instance,
+the following code fragment:</p>
+
+
+<pre class="code">
+&lt;xsp-session:get-attribute as="node" name="fruit"/&gt;
+</pre> 
+
+
+<p>results in output similar to:</p>
+
+
+<pre class="code">
+&lt;xsp-session:attribute name="fruit"&gt;apple&lt;/xsp-session:attribute&gt;
+</pre> 
+
+
+<p>This is especially useful with elements that return multiple pieces of
+information, such as <span class="codefrag">xsp-session:get-attribute-names</span>.  Without using
+<span class="codefrag">as="node"</span>, the returned values are written out end to end
+without separation.  If node output is requested, however, each value
+is written out in a separate node, which may then be referenced separately.</p>
+
+
+<p>The elements which provide for node output are marked with a "yes" in the
+"Node?" column of the table below.  Unlike the other attributes used in 
+Session elements, <span class="codefrag">as</span> cannot be supplied as a child element; it
+must be supplied as an attribute, if it is used at all.</p>
+
+
+
+<div class="note">Since these elements are primarily wrappers around HttpSession
+methods, the HttpSession documentation in the
+<a class="external" href="http://java.sun.com/products/servlet/2.2/javadoc/index.html">
+Java Servlet API Specification, version 2.2
+</a> 
+is also helpful in understanding the behavior and usage of these elements.</div>
+
+
+<table>
+All of the Session logicsheet elements, in alphabetic order.
+<tr>
+
+<th colspan="1" rowspan="1">Element Name</th>
+<th colspan="1" rowspan="1">Attributes/Child Elements</th>
+<th colspan="1" rowspan="1">Node?</th>
+<th colspan="1" rowspan="1">Description</th>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the value of the named attribute stored in the session.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-attribute-names</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the names of all attributes stored in the session.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-creation-time</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the time when this session was created. The <span class="codefrag">as</span> attribute
+for this element may be "long" (default), "string", or "node".  If "long",
+the returned value is a Java <span class="codefrag">long</span> that represents a Java <span class="codefrag">Date</span>
+value.  If "string", the value is converted to a String representation of the date,
+e.g., "Wed Jun 13 15:57:06 EDT 2001".  If "node", the <span class="codefrag">long</span> value is 
+output in the output node.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-id</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the session id, generally a randomly generated string (server dependent).</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-last-accessed-time</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the last time this session was accessed (the last time a page was
+requested using this session id). The <span class="codefrag">as</span> attribute
+for this element may be "long" (default), "string", or "node".  If "long",
+the returned value is a Java <span class="codefrag">long</span> that represents a Java <span class="codefrag">Date</span>
+value.  If "string", the value is converted to a String representation of the date,
+e.g., "Wed Jun 13 15:57:06 EDT 2001".  If "node", the <span class="codefrag">long</span> value is 
+output in the output node.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:get-max-inactive-interval</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Gets the minimum time, in seconds, that the server will maintain 
+this session between client requests.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:invalidate</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Invalidates the current session.  Any attributes stored in the session
+are lost.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:is-new</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1">yes</td>
+<td colspan="1" rowspan="1">Indicates whether this session was just created.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:remove-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Removes the named attribute from the session.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:set-attribute</td>
+<td colspan="1" rowspan="1">name</td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Stores a named attribute in the session. Place the value
+to be stored as the text contents of this element, e.g.,
+&lt;xsp-session:set-attribute name="fruit"&gt;apple&lt;/xsp-session:set-attribute&gt;.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">xsp-session:set-max-inactive-interval</td>
+<td colspan="1" rowspan="1">interval</td>
+<td colspan="1" rowspan="1">no</td>
+<td colspan="1" rowspan="1">Set the minimum time, in seconds, that the server should
+maintain the current session between client requests.</td>
+
+</tr>
+
+
+<tr>
+
+<td colspan="1" rowspan="1">ignorethisitisjusttopreventwrapping</td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1"></td>
+<td colspan="1" rowspan="1"></td>
+
+</tr>
+
+
+</table>
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/meta.xml
new file mode 100644
index 0000000..058e96d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-session/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/session.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/content_en.html
new file mode 100644
index 0000000..a760947
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/content_en.html
@@ -0,0 +1,242 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session tracking with Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Introduction, Installation and Example" name="DC.Subject">
+<meta content="J&ouml;rg Prante" name="DC.Creator">
+<meta content="
+    This document explains what Apache Cocoon provides to support session tracking.
+    Session tracking is an important feature for web server frameworks
+    because HTTP and related protocols are stateless,
+    but sometimes we need stateful information about visitors of a Cocoon site.
+    For a more precise analysis of a web site, the tracking of visitors
+    should work independent of the visitor's browser and of the visitor's decision
+    whether we enabled cookies or not. Last not least, Cocoon should not
+    be dependant of the method the servlet engine prefers to generate session IDs.
+    In this document, it is described step by step what has to be done to enable
+    Cocoon for session management.
+    " name="DC.Description">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<h2>Goal</h2>
+<p>
+         Maintaining state is a common problem for web server frameworks
+         because HTTP is a stateless protocol. There are many solutions known
+         to obtain stateful information. Client-side storage of state information
+         like the usage of cookies will not be discussed here, since this depends
+         heavily on the client's browser. Since Cocoon is a server-side framework,
+         storing visitor information at the server side will give full access
+         to the list of all visitors, to what they have done, and what they are
+         doing.
+         </p>
+<p>Please always think a little while if you really want to set up
+         session management. Less scalability and performance is the dark
+         side of keeping user sessions at the server-side. Each user session consumes
+         memory, disk, and CPU, and it is always recommended that you be careful to
+         system resources before wasting it.
+         </p>
+<p>
+         If you decided to set up session tracking, Cocoon offers you:
+         </p>
+<ul>
+            
+<li>creation of new session IDs</li>
+            
+<li>full session control by the underlying Servlet API 2.2 servlet engine</li>
+            
+<li>cookie- and URI-based session management</li>
+            
+<li>automatic link rewrite if you like your XSP pages to be URI-session-aware</li>
+          
+</ul>
+
+
+        
+<h2>The xsp-session:encode-url template</h2>
+<p>
+        To enable Cocoon for URI-based session IDs, an XSP template with the name
+        <span class="codefrag">xsp-session:encode-url</span> will do this for you. It uses the
+        <span class="codefrag">encodeURL</span> method from the Servlet API which encodes
+        an URL in a way that a session ID is being attached. Consult your
+        servlet engine documentation for information about what the <span class="codefrag">encodeURL</span>
+        method returns. For example, the Tomcat
+        engine adds a string <span class="codefrag">;jsession=</span> followed by an MD5 hash
+        to the URL, but only if the client's browser does not accept cookies.
+        </p>
+<p>Here is the fragment for the <span class="codefrag">xsp-session:encode-url</span> from session.xsl:</p>
+<pre class="code">
+&lt;!-- encode an URL with the session ID --&gt;
+&lt;xsl:template match="xsp-session:encode-url"&gt;
+  &lt;xsl:variable name="href"&gt;
+      "&lt;xsl:value-of select="@href"/&gt;"
+  &lt;/xsl:variable&gt;
+
+  &lt;xsp:element name="a"&gt;
+    &lt;xsp:attribute name="href"&gt;
+      &lt;xsp:expr&gt;
+        response.encodeURL(String.valueOf(&lt;xsl:copy-of select="$href"/&gt;))
+      &lt;/xsp:expr&gt;
+    &lt;/xsp:attribute&gt;
+    &lt;xsl:value-of select="."/&gt;
+  &lt;/xsp:element&gt;
+
+&lt;/xsl:template&gt;
+</pre>
+<p>
+         As you might wonder, the XSP template constructs a HTML tag <span class="codefrag">&lt;a&gt;</span> with an
+         attribute <span class="codefrag">href</span> which is enough for most of the cases.
+         Other methods, like XLink, are planned to be supported at a later time when
+         final W3C recommendations are out.
+         </p>
+
+         
+<h2>Creating new sessions</h2>
+<p>
+         The best place of a web site where new sessions should be created is the entry point
+         where all or most of the visitors step in. After creating the session, or
+         retrieving an old session, the visitor is redirected to a start page.
+         In Cocoon, you must edit your sitemap in order to
+         specify this interesting point of session creation.
+         The <span class="codefrag">map-redirect-to</span>
+         has an extra attribute <span class="codefrag">session</span>, which can be set to <span class="codefrag">true</span>
+         or <span class="codefrag">false</span>. The former will generate a new session ID if needed
+         by invoking the Servlet API method <span class="codefrag">session = request.getSession(true)</span>,
+         while the latter ignores session ID handling.
+         </p>
+<p>
+         How can Cocoon recognize URIs with appended session IDs? The answer is:
+         Cocoon can match a wildcard against your sessionized pages and keeps happy.
+         So please do not forget to append an asterisk '*' to your patterns in the pipelines.
+         </p>
+<p>
+         This fragment from <span class="codefrag">sitemap.xsl</span> shows how you can add a
+         <span class="codefrag">map:redirect-to</span> to
+         your Cocoon framework with session handling at the root URL for your
+         web application:
+         </p>
+<pre class="code">
+
+ &lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+
+   &lt;map:match pattern=""&gt;
+     &lt;map:redirect-to session="true" uri="welcome"/&gt;
+   &lt;/map:match&gt;
+
+   &lt;map:match pattern="welcome*"&gt;
+    &lt;map:generate type="file" src="site/welcome.xml"/&gt;
+    &lt;map:transform src="stylesheets/welcome.xsl"/&gt;
+    &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+
+   &lt;map:match pattern="**.xsp*"&gt;
+    &lt;map:generate type="serverpages" src="site/{1}.xsp"/&gt;
+    &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+    &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+</pre>
+            
+
+            
+<h1>Example</h1>
+              
+<h2>A simple XSP page with session ID</h2>
+<p>
+              Here you can see the source of an XSP example of how the
+              session feature can be used.
+              The example is located in a file named <span class="codefrag">sessionpage.xsp</span>
+              and it displays the received session ID together with a rewritten
+              link to the page itself. Depending on your browser settings,
+              you will see nothing (because your browser prefers crunching cookies)
+              or a session ID is encoded into the URL. After clicking on the
+              link named "Follow me!", the session ID is taken into the URL, and
+              the session tracking is established.
+              </p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+
+&lt;xsp:page
+   language="java"
+   xmlns:xsp="http://apache.org/xsp"
+   xmlns:xsp-session="http://apache.org/xsp/session/2.0"
+   xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+&gt;
+
+&lt;!-- a simple session page by J&amp;ouml;rg Prante &lt;joerg@7val.com&gt; --&gt;
+
+&lt;page&gt;
+  &lt;title&gt;A Simple URI-based Session Example&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt; &lt;xsp-request:get-uri as="xml"/&gt; &lt;/para&gt;
+    &lt;para&gt; Session ID = &lt;xsp-session:get-id as="xml"/&gt; &lt;/para&gt;
+    &lt;para&gt;
+      Encode URL Test =
+      &lt;xsp-session:encode-url href="sessionpage.xsp"&gt;Follow me!&lt;/xsp-session:encode-url&gt;
+    &lt;/para&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+<p>
+      If you have been successful with installing the session feature and
+      the example file, the following HTML output will be generated by
+      Cocoon from the above <span class="codefrag">sessionpage.xsp</span> example, which shows
+      how the rewritten link looks like. Please don't ask
+      why the session ID in the generated link is different from yours.
+      </p>
+<pre class="code">
+&lt;!DOCTYPE HTML PUBLIC
+    "-//W3C//DTD HTML 4.0//EN"
+    "http://www.w3.org/TR/WD-html-in-xml/DTD/xhtml1-strict.dtd"&gt;
+&lt;html&gt;&lt;head&gt;&lt;title&gt;
+     A Simple URI Session Example
+  &lt;/title&gt;&lt;/head&gt;
+  &lt;body vlink="blue" link="blue" alink="red" bgcolor="white"&gt;
+
+  &lt;h2 style="color: navy; text-align: center"&gt;
+     A Simple URI Session Example
+  &lt;/h2&gt;
+
+  &lt;content&gt;
+
+  &lt;p align="left"&gt;&lt;i&gt;
+     &lt;b xmlns:xsp-response="http://apache.org/xsp/response/2.0"
+        xmlns:xsp-request="http://apache.org/xsp/request/2.0"&gt;
+          sessionpage.xsp&lt;/b&gt;
+  &lt;/i&gt;&lt;/p&gt;
+
+  &lt;p align="left"&gt;&lt;i&gt;
+     Session ID =
+     &lt;xsp-session:id&gt;F3E9575442D1899760A0B231D0042281&lt;/xsp-session:id&gt;
+  &lt;/i&gt;&lt;/p&gt;
+
+  &lt;p align="left"&gt;&lt;i&gt;
+    Encode URL Test =
+    &lt;a href="sessionpage.xsp;jsessionid=F3E9575442D1899760A0B231D0042281"&gt;
+      Follow me!&lt;/a&gt;
+  &lt;/i&gt;&lt;/p&gt;
+  &lt;/content&gt;
+
+&lt;/body&gt;&lt;/html&gt;
+</pre>
+      
+
+      
+<h1>Log analysis of sessions</h1>
+
+      
+<p>
+        To be done.
+      </p>
+
+      
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/meta.xml
new file mode 100644
index 0000000..1d8b3f7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-block-xsp-sessions/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/xsp/sessions.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/content_en.html
new file mode 100644
index 0000000..d620c79
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/content_en.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Browser-Selector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the BrowserSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>BrowserSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">browser</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">BrowserSelector</span> component is used to
+            select appropriate sitemap processing depending on the <span class="codefrag">User-Agent</span>
+            header value.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where BrowserSelector sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.BrowserSelector</td>
+        
+</tr>
+        <!-- uncomment folling tr iff BrowserSelector is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">BrowserSelector</span> tests the user agent header field against
+        the test attribute of the selectors when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">BrowserSelector</span> allows to define brower specific sitemap
+        processing.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:select type="browser"&gt;
+  &lt;map:when test="netscape"&gt;
+  ....
+  &lt;/map:when&gt;
+  &lt;map:when test="explorer"&gt;
+  ...
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+  ...
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+        
+</p>
+<pre class="code">
+&lt;map:selectors...
+  &lt;map:selector name="browser" 
+    src="org.apache.cocoon.selection.BrowserSelector"
+    logger="sitemap.selector.browser" 
+    
+    &lt;browser name="explorer" useragent="MSIE"/&gt;
+    ...
+    &lt;browser name="mozilla5" useragent="Moziall/5"/&gt;
+    &lt;browser name="netscape" useragent="Mozilla"/&gt;
+    
+  &lt;/map:selectors&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          <!-- Explain the sitemap selector configuration, options when declaring browser selector -->
+          The configuration section of <span class="codefrag">BrowserSelector</span> specifies
+          a mapping from user-agent strings to symbolic browser names.
+        </p>
+<p>
+          Each browser element specifies a name attribute holding the symbolic browser name
+          used in the test attribute expression. The attribute useragent contains 
+          a matchable substring of some real user-agent values.
+        </p>
+<p>
+          It is allowed to specify for a browser name more than one entry. This way
+          a symbolic browser name is matched by different user-agent substrings.
+          The snippet belows will yield true for <span class="codefrag">test="wap-handset"</span> if 
+          the user-agent header contains <span class="codefrag">Nokia</span>, <span class="codefrag">UP</span>, or 
+          <span class="codefrag">Wapalizer</span>.
+        </p>
+<pre class="code">
+...
+  &lt;browser name="wap-handset" useragent="Nokia"/&gt;
+  &lt;browser name="wap-handset" useragent="UP"/&gt;
+  &lt;browser name="wap-handset" useragent="Wapalizer"/&gt;
+...
+        </pre>
+      
+<h2>Setup</h2>
+<p>
+          <!-- Explain the sitemap selector setup, ie options when using browser selector -->
+          Setting up a <span class="codefrag">BrowserSelector</span> includes choosing the 
+          <span class="codefrag">&lt;map:when&gt;</span> test expressions, and a 
+         optional <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+        </p>
+<p>
+          The test attribute of the <span class="codefrag">&lt;map:when&gt;</span> clause must match
+          a browser attribute name value. The value of the test attribute in a 
+          <span class="codefrag">&lt;map:when&gt;</span> clause must be declared in a 
+          <span class="codefrag">browser</span> name attribute.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">BrowserSelector</span> has no side effects on the object model, or 
+          any sitemap parameters. 
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">BrowserSelector</span> adds the response header attribute
+        <span class="codefrag">Vary</span> having value <span class="codefrag">User-Agent</span> indicating
+        that the response differ for different user agents. This information
+        especially meaningfull for an http-proxy server.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        28-12-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/meta.xml
new file mode 100644
index 0000000..0fea358
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-browser-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/browser-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/content_en.html
new file mode 100644
index 0000000..300b58f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/content_en.html
@@ -0,0 +1,323 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Caching</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document explains the basic caching algorithm of Apache Cocoon." name="DC.Description">
+</head>
+<body>
+   
+<h1>Goal</h1>
+    
+<p>This document explains the basic caching algorithm of Apache Cocoon.</p>
+   
+   
+<h1>Overview</h1>
+    
+<p>The caching algorithm of Cocoon has a very flexible and powerful design.
+           The algorithms and components used are not hard coded into the core of 
+           Cocoon. They can be configured in the sitemap.</p>
+            
+<p>This document describes the components available for caching,
+               how they can be configured and how to implement your own cacheable components.
+            </p>
+   
+   
+<h1>How to Configure Caching</h1>
+       
+<p>The caching can be turned on and off on a per pipeline setting in the sitemap.
+        This means, for each <em>map:pipeline</em> section in a sitemap, it's possible to
+        turn on/off caching and configure the caching algorithm.</p>
+        
+<p>The following example shows how to turn on caching for a pipeline:</p>
+    
+<pre class="code">
+     
+       &lt;map:pipeline type="caching"&gt;
+          ...
+       &lt;/map:pipeline&gt;
+     
+    </pre> 
+        
+<p>If you know that it doesn't make sense to turn on caching for some of 
+        your pipelines, put them together in their own section and use:</p>
+    
+<pre class="code">
+     
+       &lt;map:pipeline type="noncaching"&gt;
+          ...
+       &lt;/map:pipeline&gt;
+     
+    </pre>
+      
+<p>As you might guess from how the caching is turned on (via a type attribute), you
+         can have different caching (or better pipeline) implementation to choose from. This
+         is similar to choose from a set of generators the generator to use in your pipeline etc.
+         You will find in your main sitemap a section declaring all pipeline implementations.
+         It's in the <em>map:components</em> section:
+      </p>
+    
+<pre class="code">
+     
+       &lt;map:pipes default="caching"&gt;
+          &lt;map:pipe name="caching" src="..."/&gt;
+          &lt;map:pipe name="noncaching" src="..."/&gt;
+       &lt;/map:pipes&gt;
+     
+    </pre>
+      
+<p>Depending on your Cocoon installation you might have different implementations in
+      that section. As with all components, you can define a default for all pipelines and
+      override this whereever it makes sense.</p>
+   
+   
+<h1>The Default Caching Algorithm</h1>
+    
+<p>The default algorithm uses a very easy but effective approach
+           to cache a request: The pipeline process is cached up to the most 
+           possible point.</p>
+        
+<p>Therefore each component in the pipeline is queried by Cocoon if it
+        supports caching. Several components, like the file generator or the xslt
+        transformer support caching. However, dynamic components like the sql transformer
+        or the cinclude transformer do not. Let's have a look at some examples:</p>
+    
+<h2>Simple Examples</h2>
+<p>If you have the following pipeline:</p>
+<p>Generator[type=file|src=a.xml] -&gt; Transformer[type="xslt"|src=a.xsl] -&gt; Serializer</p>
+<p>The file generator is cacheable and generates a key which uses the src 
+             (or the filename) to build the key. The cache uses the last modification date of the xml file
+             to test if the cached content is valid.</p>
+<p>The xslt transformer is cacheable and generates a key which uses
+             the filename to build the unique key. The cache validity object
+             uses the last modification date of the xslt file.</p>
+<p>The default serializer (html) supports the caching as well.</p>
+<p>All three keys are used to build a unique key for this pipeline.
+             The first time it is invoked its response is cached. The second time
+             this pipeline is called, the cached content is get from the cache.
+             If it is still valid, the cached content is directly send to the client.</p>
+        
+<h2>Complex Example</h2>
+<p>Only part of the following pipeline is cached:</p>
+<p>Generator[type=file|src=a.xml] -&gt; Transformer[type="xslt"|src=a.xsl] -&gt; Transformer[type=sql] -&gt; Transformer[type="xslt"|src=b.xsl] -&gt; Serializer</p>
+<p>The file generator is cacheable and generates a key which uses the src 
+             (or the filename) to build the key. The cache uses the last modification date of the xml file
+             to test if the cached content is valid.</p>
+<p>The xslt transformer is cacheable and generates a key which uses
+             the filename to build the unique key. The cache validity object
+             uses the last modification date of the xslt file.</p>
+<p>The sql transformer is not cacheable, so the caching algorithm stops
+          at this point although the last transformer is cacheable again.</p>
+<p>The cached response is the output of the first xslt transformer, so when the
+         next request comes in and the cached content is valid, the cached content is
+         directly feed into the sql transformer. The generator and the first
+         xslt transformer are not executed.</p>
+      
+<h2>Making Components Cacheable</h2>
+<p>This chapter is only for developers of own sitemap components. It details what you have
+          to do when you want that your own sitemap components supports the caching.</p>
+<p>Each sitemap component (generator or transformer) which might be
+            cacheable must implement the CacheableProcessingComponent interface. When the
+            pipeline is processed each sitemap component starting with
+           the generator is asked if it implements this interface. This
+           test stops either when the first component does not implement
+           the CacheableProcessingComponent interface or when the first cacheable component is
+           currently not cacheable for any reasons (more about this in a moment).</p>
+<p>The CacheableProcessingComponent interface declares a method <span class="codefrag">getKey()</span>
+           which must produce a unique key for this sitemap component inside
+           the component space. For example the FileGenerator returns the
+           source argument (the xml document read). All parameters/values
+           which are used for the processing of the request by the generator must
+           be used for this key. If, e.g. the request parameters are used by
+           the component, it must build a key with respect to the current request
+           parameters. The key can be any serializable java object.</p>
+<p>If for any reason the sitemap component detects that the current request
+           is not cacheable it can simply return <span class="codefrag">null</span> as the key. This has
+          the same effect as not declaring the CacheableProcessingComponent interface.</p>
+<p>Now after the key is build for this particular request, it is looked up
+           in the cache if it exists. If not, the new request is generated and cached
+           for further requests.</p>
+<p>If a cached response is found for the key, the caching algorithm checks
+           if this response is still valid. For this check each cacheable component
+           returns a validity object when the method <span class="codefrag">getValidity</span>
+           is invoked. (If a cacheable component returns <span class="codefrag">null</span> it
+           is temporarily not cacheable, like returning <span class="codefrag">null</span> for the key.)</p>
+<p>A <span class="codefrag">SourceValidity</span> object contains all information the component
+           needs to verify if the cached content is still valid. For example the
+           file generator stores the last modification date of the xml document parsed
+           in the validity object.</p>
+<p>When a response is cached all validity objects are stored together with
+            the cached response in the cache. Actually the <span class="codefrag">CachedResponse</span>
+            is stored which encapsulates all this information.</p>
+<p>When a new response is generated and the key is build, the caching
+           algorithm also collects all uptodate cache validity objects. So if the
+           cached response is found in the cache these validity objects are compared.
+           If they are valid (or equal) the cached response is used and feed into
+           the pipeline. If they are not valid any more the cached response is removed
+           from the cache, the new response is generated and then stored together with
+           the new validity objects in the cache.</p>
+   
+   
+<h1>Configuration</h1>
+    
+<p>The caching of Cocoon can be completely configured by different Avalon
+               components. This chapter describes how the various components work
+               together.</p>            
+    
+<h2>Configuration of Pipelines</h2>
+<p>Each pipeline can be configured with a buffer size, and each
+        caching pipeline with the name of the Cache to use.</p>
+<h3>Expiration of Content</h3>
+<p>
+       Utilize the pipeline <span class="codefrag">expires</span> parameter to dramatically reduce
+       redundand requests. Even the most dynamic application pages have a 
+       reasonable period of time during which they are static. 
+       Even if a page doesn't change for just one minute, still use the 
+       <span class="codefrag">expires</span> parameter. Here is an example:
+       </p>
+<pre class="code">
+&lt;map:pipeline&gt;
+  &lt;map:parameter name="expires" value="access plus 1 minutes"/&gt;
+  ...
+&lt;/map:pipeline&gt; 
+</pre>
+<p>
+       The value of the parameter is in a format borrowed from the Apache HTTP module mod_expires.
+       Examples of other possible values are:
+       </p>
+<pre class="code">
+access plus 1 hours
+access plus 1 month
+access plus 4 weeks
+access plus 30 days
+access plus 1 month 15 days 2 hours
+</pre>
+<p>
+       Imagine 1'000 users hitting your web site at the same time.
+       Say that they are split into 5 groups, each of which has the same ISP.
+       Most ISPs use intermediate proxy servers to reduce traffic, hense
+       improving their end user experience and also reducing their operating costs.
+       In our case the 1'000 end user requests will result in just 5 requests to Cocoon.
+       </p>
+<p>
+       After the first request from each group reaches the server, the expires header will
+       be recognized by the proxy servers which will serve the following requests from their cache.
+       Keep in mind however that most proxies cache HTTP GET requests, but will not cache HTTP POST requests.
+       </p>
+<p>
+     To feel the difference, set an expires parameter on one of your pipelines and
+     load the page with the browser. Notice that after the first time, there are no 
+     access records in the server logs until the specified time expires.
+       </p>
+<p>This parameter has effect on all pipeline implementations, even on 
+       the non caching ones. Remember, the caching does not take place in Cocoon,
+       it's either in a proxy inbetween Cocoon and the client or in the client
+       itself.</p>
+<h3>Response Buffering</h3>
+<p>Each pipeline can buffer the response, before it is send to the client.
+            The default buffer size is unlimited (-1), which means when all bytes of
+            the response are available on the server, they are send with one
+            command directly to the client.</p>
+<p>Of course, this slows down the response as the whole response
+            is first buffered inside Cocoon and then send to the client instead of
+            directly sending the parts of the response when they are available.
+            But on the other hand this is very important for error handling. If you
+            don't buffer the response and an error occurs, you might get corrupt
+            pages. Example: you have a pipeline that already send some content
+            to the client and now an exception occurs. This exception "calls"
+            the error handler that generates a new response that is appended
+            to the already send content. If content is already send to the client
+            there is no way of reverting this! So buffering in these cases makes
+            sense.
+           </p>
+<p>If you have a stable application running in production where the
+           error handler is never invoked, you can turn off the buffering, by
+           setting the buffer to <em>0</em>.</p>
+<p>You can set the buffer to any other value higher than 0 which means
+           the content of the response is buffered in Cocoon until the buffer is
+           full. If the buffer is full it's flushed and the next part of the
+           response is buffered again. If you know the maximum size of your
+           content than you can fine tune the buffer handling with this.</p>
+<p>You can set the default buffer size for each pipeline implementation
+            at the declaration of the pipeline. Example:</p>
+<pre class="code">
+     
+        &lt;map:pipe name="noncaching" src="..."&gt;
+            &lt;parameter name="outputBufferSize" value="2048"/&gt;
+        &lt;/map:pipe&gt;
+     
+    </pre>
+<p>The above configuration sets the buffer size to <em>2048</em> for the
+          non caching pipeline. Please note, that the parameter element does not
+          have the sitemap namespace!</p>
+<p>You can override the buffer size in each <em>map:pipeline</em> section:</p>
+<pre class="code">
+     
+        &lt;map:pipeline type="noncaching"&gt;
+            &lt;map:parameter name="outputBufferSize" value="4096"/&gt;
+            ...
+        &lt;/map:pipeline&gt;
+     
+    </pre>
+<p>The above parameters sets the buffer size to <em>4096</em> for this
+          particular pipeline. Please note, that the parameter element does have
+          the sitemap namespace!</p>
+    
+<h2>Configuration of Caches</h2>
+<p>Each cache can be configured with the store to use.</p>
+    
+<h2>Configuration of Stores</h2>
+<p>Have a look at the store configuration.</p>
+    
+    
+<h1>Additional Information for Developers</h1>
+       
+<h2>Java APIs</h2>
+<p>For more information on the java apis refer directly to the
+               javadocs of Cocoon.</p>
+<p>The most important packages are:</p>
+<ol>
+      
+<li>
+<span class="codefrag">org.apache.cocoon.caching</span>: This package declares all interfaces for caching.</li>
+      
+<li>
+<span class="codefrag">org.apache.cocoon.components.pipeline</span>: The interfaces and implementations of the pipelines.</li>
+    
+</ol>
+    
+<h2>The XMLSerializer/XMLDeserializer</h2>
+<p>The caching of the sax events is implemented by two Avalon components: 
+                     The XMLSerializer and the XMLDeserializer. The XMLSerializer gets
+                     sax events and creates an object which is used by the XMLDeserializer
+                     to recreate these sax events.</p>
+<h3>org.apache.cocoon.components.sax.XMLByteStreamCompiler</h3>
+<p>The <span class="codefrag">XMLByteStreamCompiler</span>compiles sax events into a byte stream.</p>
+<h3>org.apache.cocoon.components.sax.XMLByteStreamInterpreter</h3>
+<p>The <span class="codefrag">XMLByteStreamInterpreter</span> is the counterpart of the 
+           <span class="codefrag">XMLByteStreamCompiler</span>. It interprets the byte
+                           stream and creates sax events.</p>
+<h3>Configuration</h3>
+<p>The XMLSerializer and XMLDeserialzer are two Avalon components which
+         can be configured in the cocoon.xconf:</p>
+<pre class="code">
+     
+&lt;xml-serializer
+    class="org.apache.cocoon.components.sax.XMLByteStreamCompiler"/&gt;
+
+&lt;xml-deserializer
+    class="org.apache.cocoon.components.sax.XMLByteStreamInterpreter"/&gt;
+     
+    </pre>
+<p>You must assure that the correct (or matching) deserializer is 
+                     configured for the serializer.</p>
+<p>Both components are poolable, so make sure you set appropriate pool sizes
+               for these components. For more information on component pooling have a look
+               at the Avalon documentation.</p>
+    
+ 
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/meta.xml
new file mode 100644
index 0000000..44a5fbd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-caching/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/caching.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/content_en.html
new file mode 100644
index 0000000..c8f83f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/content_en.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Description of the calendar generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Cocoon Community" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Calendar Generator</h1>
+     
+<p>Here is a sample output:</p>
+
+<pre class="code">
+  &lt;calendar:calendar xmlns:calendar="http://apache.org/cocoon/calendar/1.0"
+      year="2004" month="January" prevMonth="12" prevYear="2003"
+      nextMonth="02" nextYear="2004"&gt;
+    &lt;calendar:week number="1"&gt;
+      &lt;calendar:day number="1" date="January 1, 2004"/&gt;
+      &lt;calendar:day number="2" date="January 2, 2004"/&gt;
+      &lt;calendar:day number="3" date="January 3, 2004"/&gt;
+      &lt;calendar:day number="4" date="January 4, 2004"/&gt;
+    &lt;/calendar:week&gt;
+    ...
+  &lt;/calendar:calendar&gt;
+</pre>
+ 
+<p>The <em>src</em> parameter is ignored.</p>
+   
+  
+<h1>Configuration</h1>
+   
+<p>Configuration options:</p>
+    
+<ul>
+     
+<li>
+<em>month</em> (optional) : Sets the month for the calendar (January is 1). Default is the current month.</li>
+     
+<li>
+<em>year</em> (optional) : Sets the year for the calendar. Default is the current year.</li>
+     
+<li>
+<em>dateFormat</em> (optional) : Sets the format for the date attribute of each node, as described in 
+          java.text.SimpleDateFormat. If unset, the default format for the current locale will be used.</li>
+     
+<li>
+<em>lang</em> (optional) : Sets the ISO language code for determining the locale.</li>
+     
+<li>
+<em>country</em> (optional) : Sets the ISO country code for determining the locale.</li>
+    
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/meta.xml
new file mode 100644
index 0000000..81a6895
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-calendar-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/calendar-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/content_en.html
new file mode 100644
index 0000000..0ccafc9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/content_en.html
@@ -0,0 +1,805 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Entity resolution with catalogs</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Resolve external entities to local or other resources" name="DC.Subject">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Introduction</h1>
+  
+<p>
+   Apache Cocoon has the capability to utilise an entity resolution mechanism. 
+   External entities (e.g. Document Type Definitions (DTDs), character entity
+   sets, XML sub-documents) are resources that are declared by an XML instance
+   document - they exist as separate objects. An entity catalog assists with
+   entity management and the resolution of entities to accessible resources.
+   It also reduces the necessity for expensive and failure-prone network
+   retrieval of the required resources.
+  </p>
+ 
+
+ 
+<h1>Overview</h1>
+  
+<p>
+   "Entities" represent the physical structure of an XML instance document,
+   whereas "elements" represent the logical structure. The complete entity
+   structure of the document defines which pieces need to be incorporated, so
+   as to build the final document. Those entities are objects from some
+   accessible place, e.g. local file system, local network, remote network,
+   generated from a database. Example entities are: DTDs, XML sub-documents,
+   sets of character entities to represent symbols and other glyphs, image
+   files.
+  </p>
+
+  
+<p>
+   So how are you going to define the accessible location of all those pieces?
+   How will you ensure that those resources are reliably available? Entity
+   resolution catalogs to the rescue. These are simple standards-based
+   plain-text files to map public identifiers and system identifiers to local
+   or other resources.
+  </p>
+
+  
+<p>
+   Do you wonder why we cannot use the sitemap to resolve these resources?
+   This is because the resolution of all entities that compose the XML
+   document is under the direct control of the guts of the parser and the XML
+   structure. The parser has no choice - it must incorporate all of the defined    pieces. If it cannot retrieve them, then it is broken and reports an error.
+  </p>
+
+  
+<p>
+   With the powerful catalog support there are no such problems. This document
+   provides the following sections to explain Cocoon capability for
+   resolving entities ...
+  </p>
+
+  
+<ul>
+   
+<li>
+    
+<a href="#background">Background</a>
+    - explains the need, explains some terminology, describes the solution
+   </li>
+   
+<li>
+    
+<a href="#demo1">Demonstration #1</a>
+     - explains a remote resource and how it gets resolved
+   </li>
+   
+<li>
+    
+<a href="#cat">Catalogs overview</a>
+     - briefly explains how catalogs resolve entity declarations
+   </li>
+   
+<li>
+    
+<a href="#demo2">Demonstration #2</a>
+     - explains more detailed need and use of catalogs
+     and shows catalogs in action
+   </li>
+   
+<li>
+    
+<a href="#default">Default configuration</a>
+     - explains the default automated configuration
+   </li>
+   
+<li>
+    
+<a href="#config">Local configuration</a>
+     - explains how to extend the default configuration for your local
+     system requirements and provides an example
+   </li>
+   
+<li>
+    
+<a href="#imp">Implementation notes</a>
+     - describes how support for catalogs is added to Cocoon
+   </li>
+   
+<li>
+    
+<a href="#dev">Development notes</a>
+     - some minor issues need to be addressed
+   </li>
+   
+<li>
+    
+<a href="#notes">Other notes</a>
+     - assorted dot-points
+   </li>
+   
+<li>
+    
+<a href="#summ">Summary</a>
+   
+</li>
+   
+<li>
+    
+<a href="#info">Further information</a>
+     - links to some useful resources
+   </li>
+  
+</ul>
+ 
+
+ 
+<a name="background"></a>
+ 
+<h1>Background</h1>
+  
+<p>
+   The following article eloquently describes the need for all parsers and
+   XML frameworks to be capable of utilising entity resolvers.
+   "<a class="external" href="http://xml.apache.org/commons/components/resolver/">XML Entity
+   and URI Resolvers</a>" by Norman Walsh. Please read that document,
+   then return here to apply entity catalogs to Cocoon.
+  </p>
+
+  
+<p>
+   (Note: The <a class="external" href="http://xml.apache.org/commons/">Apache XML
+   Commons</a> project provides the Java package that has been added to
+   Cocoon as the <span class="codefrag">lib/core/xml-commons-resolver.jar</span> package.
+   There are also
+   API javadocs for <span class="codefrag">resolver</span> that have further information.
+   However, you do not need to know the gory details to understand catalogs
+   and configure them.)
+  </p>
+ 
+
+ 
+<a name="demo1"></a>
+ 
+<h1>Demonstration #1</h1>
+  
+<p>
+   This snippet from an XML instance shows the Document Type Declaration.
+   Notice that it declares its ruleset, the Document Type Definition (DTD),
+   as an external entity. Notice also that the resource is network-based.
+  </p>
+
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V4.1.2.5//EN"
+  "http://www.oasis-open.org/docbook/xml/simple/4.1.2.5/sdocbook.dtd"
+&lt;article&gt;
+ ... content goes here
+&lt;/article&gt;
+</pre>
+
+  
+<p>
+   Now consider what will happen when Cocoon tries to process this XML
+   instance. Whether you have set validation=yes or not, the parser will
+   still want to resolve all of the entities that are required by the XML
+   instance (i.e. the DTD and any other entities that the DTD might declare).
+   So it will happily trundle across the network to get them. It will do this
+   every time that the document is processed. This is obviously a needless
+   overhead. Worse still, what happens if that host is down or the network is
+   congested. Additionally, if your Cocoon is an off-line server then it is
+   always broken because it cannot retrieve the network-based resources.
+  </p>
+ 
+
+ 
+<a name="cat"></a>
+ 
+<h1>Catalogs overview</h1>
+  
+<p>
+   As the Walsh document explained, the secrets to entity resolution are the
+   public identifiers, system identifiers, and the catalog to map between them.
+   Here we provide an overview and show an example catalog which we will then
+   use with the <a href="#demo2">Demonstration #2</a> below.
+  </p>
+
+  
+<h2>External entity declarations</h2>
+<p>
+    To define an external entity in an XML instance document, you must 
+    provide an external declaration consisting of at least a
+    <strong>system identifier</strong> and optionally a 
+    <strong>public identifier</strong>. The system identifier defines the
+    physical location of the external entity. The public identifier is a
+    unique symbolic name that can be used to map to a certain physical location.
+    Note that if you provide both a public and a system identifier, then the
+    public identifier is listed first and the system identifier is not 
+    preceded by the keyword <span class="codefrag">SYSTEM</span>.
+    Here are four separate examples ...
+   </p>
+<pre class="code">
+&lt;!ENTITY pic SYSTEM "images/pic.gif" NDATA gif&gt;
+&lt;!ENTITY % ISOnum PUBLIC
+  "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML" "ISOnum.pen"&gt;
+&lt;!DOCTYPE document SYSTEM "dtd/document-v10.dtd"&gt;
+&lt;!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
+  "http://www.oasis-open.org/docbook/xml/4.1/docbookx.dtd"&gt;
+</pre>
+<p>
+   (In your XML instance document, or DTD, you would include those entities
+   like this ... <span class="codefrag">%ISOnum;</span>)
+  </p>
+<p>
+   None of those system identifiers looks reliable or easily managed.
+   Use a catalog to make them so.
+  </p>
+
+  
+<h2>Simple example catalog</h2>
+<p>
+    The <span class="codefrag">catalog</span> maps public identifiers to their corresponding
+    physical locations. The catalog entries in an OASIS catalog are a simple
+    whitespace-delimited format.
+    (The <a href="#info">specification</a> fully defines the format.) 
+    There about a dozen different types of catalog entry - two important
+    ones are:
+   </p>
+<ul>
+    
+<li>
+<strong>PUBLIC</strong> <span class="codefrag">publicId systemId</span>
+     
+<br>- maps the public identifier <span class="codefrag">publicId</span> to the system
+     identifier <span class="codefrag">systemId</span>
+    
+</li>
+    
+<li>
+<strong>SYSTEM</strong> <span class="codefrag">systemId otherSystemId</span>
+     
+<br>- maps the system identifier <span class="codefrag">systemId</span> to the alternate
+     system identifier <span class="codefrag">otherSystemId</span>
+    
+</li>
+   
+</ul>
+<pre class="code">
+-- this is the default OASIS catalog for Apache Cocoon --
+
+OVERRIDE YES
+
+-- ISO public identifiers for sets of character entities --
+PUBLIC "ISO 8879-1986//ENTITIES Added Latin 1//EN//XML"
+       "ISOlat1.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+       "ISOlat1.pen"
+PUBLIC "ISO 9573-15:1993//ENTITIES Greek Letters//EN//XML"
+       "ISOgrk1.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML"
+       "ISOpub.pen"
+PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+       "ISOtech.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+       "ISOnum.pen"
+
+-- Document Type Definitions --
+PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
+       "document-v10.dtd"
+PUBLIC "-//APACHE//DTD FAQ V1.0//EN"
+       "faq-v10.dtd"
+-- (other declarations removed for brevity) --
+
+-- these entries are used for the catalog-demo sample application --
+OVERRIDE NO
+PUBLIC "-//Arbortext//TEXT Test Override//EN"
+       "catalog-demo/override.txt"
+OVERRIDE YES
+PUBLIC "-//Arbortext//TEXT Test Public Identifier//EN"
+       "catalog-demo/testpub.txt"
+SYSTEM "urn:x-arbortext:test-system-identifier"
+       "catalog-demo/testsys.txt"
+PUBLIC "-//Indexgeo//DTD Catalog Demo v1.0//EN"
+       "catalog-demo/catalog-demo-v10.dtd"
+-- end of entries for the catalog-demo sample application --
+</pre>
+<p>
+    System identifiers can use full pathnames, filenames, relative pathnames,
+    or URLs - in fact, any method that will define and deliver the actual
+    physical entity. If it is just a filename or a relative pathname, then the 
+    Catalog Resolver will look for the resource relative to the location of
+    the catalog.
+   </p>
+<p>
+    When the parser needs to load a declared entity, then it first consults
+    the Catalog Resolver to get a possible mapping to an alternate system
+    identifier. If there is no mapping for an identifier in the catalogs
+    (or in any sub-ordinate catalogs), then Cocoon will carry on to
+    retrieve the resource using the original declared system identifier.
+   </p>
+ 
+
+ 
+<a name="demo2"></a>
+ 
+<h1>Demonstration #2</h1>
+
+  
+<p>
+   See catalogs in action with the 
+   <a href="../../overview.html#samples">Cocoon Samples</a>
+   The demonstration
+   intends to be self-documenting. The top-level XML instance describes its
+   role, and each included external entity reports how it came into being.
+   This example builds upon the example provided by the Walsh article.
+   (Tip: To see the error message that would result from not using a catalog,
+   simply rename the default <span class="codefrag">catalog</span> file before starting
+   Cocoon.)
+  </p>
+
+  
+<p>Here is the source for the top-level XML instance document
+   <span class="codefrag">catalog-demo.xml</span> ...
+  </p>
+
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;!DOCTYPE catalog-demo PUBLIC "-//Indexgeo//DTD Catalog Demo v1.0//EN"
+  "http://www.indexgeo.com.au/dtd/catalog-demo-v10.dtd"
+[
+ &lt;!ENTITY testpub PUBLIC "-//Arbortext//TEXT Test Public Identifier//EN"
+   "bogus-system-identifier.xml"&gt;
+ &lt;!ENTITY testsys SYSTEM "urn:x-arbortext:test-system-identifier"&gt;
+ &lt;!ENTITY testovr PUBLIC "-//Arbortext//TEXT Test Override//EN"
+   "testovr.txt"&gt;
+ &lt;!ENTITY % ISOnum PUBLIC
+   "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+   "ISOnum.pen"&gt;
+ %ISOnum;
+ &lt;!ENTITY note "Note:"&gt;
+]&gt;
+
+&lt;catalog-demo&gt;
+ &lt;section&gt;
+  &lt;para&gt;This sample application demonstrates the use of catalogs for
+   entity resolution. &amp;note; see the Apache Cocoon documentation
+   &lt;link href="../../docs/userdocs/concepts/catalog.html"&gt;Entity resolution
+   with catalogs&lt;/link&gt; for the full background and explanation, and the XML
+   source of this document (catalog-demo.xml).
+  &lt;/para&gt;
+
+  &lt;para&gt;This top-level XML instance document is catalog-demo.xml - it declares
+   three other XML sub-documents as external entities and then includes
+   them in the sections below. The real system identifiers will be looked
+   up in the catalog, to resolve the actual location of the resource.
+  &lt;/para&gt;
+
+  &lt;para&gt;The Document Type Definition (DTD) is declared using both a public
+   identifier and a system identifier. The system identifier for the DTD is
+   a network-based resource (which is deliberately non-existent). However,
+   the catalog overrides that remote DTD to instead use a copy from the
+   local filesystem at the location defined by the catalog entry. Note that
+   it is via the use of a public identifier that we gain this power.
+  &lt;/para&gt;
+
+  &lt;para&gt;The internal DTD subset of the top-level document instance goes on
+   to declare the three external sub-document entities using various means.
+   It also declares and includes the ISOnum set of character entities,
+   so that we can use entities like "&amp;amp;frac12;" (to represent &amp;frac12;).
+   Finally the internal DTD subset declares an internal general entity
+   for &amp;quot;&amp;amp;note;&amp;quot;.
+  &lt;/para&gt;
+ &lt;/section&gt;
+
+ &lt;section&gt;
+  &lt;para&gt;testpub ... this entity is declared with a PUBLIC identifier and a
+   bogus system identifier (which will be overridden by the catalog)
+  &lt;/para&gt;
+  &lt;para&gt;&amp;note; &amp;testpub;&lt;/para&gt;
+ &lt;/section&gt;
+
+ &lt;section&gt;
+  &lt;para&gt;testsys ... this entity is declared with a SYSTEM identifier
+   (which will be resolved by the catalog)
+  &lt;/para&gt;
+  &lt;para&gt;&amp;note; &amp;testsys;&lt;/para&gt;
+ &lt;/section&gt;
+
+ &lt;section&gt;
+  &lt;para&gt;testovr ... is declared with a PUBLIC identifier and a system
+   identifier (the catalog is set to not override this one, so the
+   declared system identifier is used)
+  &lt;/para&gt;
+  &lt;para&gt;&amp;note; &amp;testovr;&lt;/para&gt;
+ &lt;/section&gt;
+
+&lt;/catalog-demo&gt;
+</pre>
+
+  
+<p>
+   Here is the source for one of the included sub-document external entities
+   <span class="codefrag">testpub.txt</span> (a slab of plain text) ...
+  </p>
+
+
+<pre class="code">
+This paragraph is automatically included from the
+testpub.txt external file.
+The entity declaration deliberately used a non-existent file
+as the system identifier. The catalog then used the declared
+public identifer to resolve to a specific location on the local
+filesystem.
+</pre>
+ 
+
+ 
+<a name="default"></a>
+ 
+<h1>Default configuration</h1>
+  
+<p>
+   A default catalog and some base entities (e.g. ISO*.pen character
+   entity sets) are included in the Cocoon distribution at 
+   <span class="codefrag">WEB-INF/entities/</span>
+   - the default catalog is automatically loaded when Cocoon starts.
+  </p>
+
+  
+<p>
+   If you suspect problems, then you can raise the level of the
+   <span class="codefrag">verbosity</span> property (to 2 or 3) and watch the messages going
+   to standard output when Cocoon starts and operates. You would also do
+   this to detect any misconfiguration of your own catalogs.
+  </p>
+ 
+
+ 
+<a name="config"></a>
+ 
+<h1>Local configuration</h1>
+   
+<p>You can extend the default configuration to include local catalogs
+    for site-specific requirements. This is achieved via various means.
+   </p>
+
+  
+<h2>Using cocoon.xconf</h2>
+<p>Parameters (properties) for the resolver component can be specified in the
+   <span class="codefrag">src/webapp/WEB-INF/cocoon.xconf</span>
+    configuration file. See the detailed internal notes - here is a precis.
+   </p>
+<ul>
+    
+<li>
+<span class="codefrag">catalog</span>
+     ... The main catalog file. Its path name is relative to the
+     Cocoon context directory.
+    </li>
+    
+<li>
+<span class="codefrag">local-catalog</span>
+     ... The full filesystem pathname to a single local catalog file.
+    </li>
+    
+<li>
+<span class="codefrag">verbosity</span>
+     ... The level of messages from the resolver
+     (loading catalogs, identifier resolution, etc.).
+     It value may range from 0 (no messages), to 10 detailed log messages.
+    </li>
+   
+</ul>
+
+  
+<h2>Using CatalogManager.properties</h2>
+<p>An annotated <span class="codefrag">CatalogManager.properties</span> file is included
+    with the distribution - modify it to suit your needs. You can add your
+    own local catalogs using the <span class="codefrag">catalogs</span> property.
+    (See the notes inside the properties file).
+   </p>
+<p>
+    The file is at 
+<span class="codefrag">webapp/WEB-INF/classes/CatalogManager.properties</span>
+    thereby making it available to the Java classpath during startup of the
+    servlet engine.
+   </p>
+<p>
+    If you see an error message going to STDOUT when Cocoon starts 
+    (<span class="codefrag">Cannot find CatalogManager.properties</span>) then this means that
+    the properties file is not available to the Java classpath. Note that this
+    does not mean that entity resolution is disabled, rather that no local
+    configuration is being effected. Therefore no local catalogs will be
+    loaded and no entity resolution messages will be received (verbosity
+    level is zero by default).
+   </p>
+<p>
+    That may truly be the intention, and not just a configuration mistake.
+    You can still use <span class="codefrag">cocoon.xconf</span> to effect your local
+    configuration.
+   </p>
+
+  
+<h2>Resolver directives inside your catalog file</h2>
+<p>
+    The actual "catalog" files have a powerful set of directives. 
+    For example, the <strong>CATALOG</strong> directive facilitates the
+    inclusion of a sub-ordinate catalog. The list of resources below will
+    lead to <a href="#info">further information</a> about catalog usage.
+   </p>
+
+  
+<h2>Example local configuration for Simplified DocBook</h2>
+<p>
+   We use the Simplified DocBook XML DTD for some of our documentation.
+   Here are the few steps that we followed to configure Cocoon to be able
+   to process our XML instances.
+  </p>
+<ul>
+   
+<li>
+    Downloaded a recent copy of the Simplified DocBook DTD (the flattened DTD
+    will suffice) from
+    <a class="external" href="http://www.oasis-open.org/docbook/">here</a>
+    and place it at
+    <span class="codefrag">/usr/local/sgml/docbook/simple/sdocbook.dtd</span>
+   
+</li>
+   
+<li>
+    Created a catalog file at 
+    <span class="codefrag">/usr/local/sgml/docbook/simple/sdocbook.cat</span>
+    with a single entry for the Simplified DocBook XML DTD
+   </li>
+   
+<li>
+    Added the parameter (<span class="codefrag">local-catalog</span>) to the
+    <span class="codefrag">WEB-INF/cocoon.xconf</span>
+    (using the full pathname to the <span class="codefrag">sdocbook.cat</span> catalog).
+   </li>
+  
+</ul>
+<pre class="code">
+-- Catalog file (sdocbook.cat) for Simplified DocBook --
+-- See www.oasis-open.org/docbook/ --
+
+-- Driver file for the Simplified DocBook XML DTD --
+PUBLIC "-//OASIS//DTD Simplified DocBook XML V4.1.2.5//EN"
+       "sdocbook.dtd"
+
+-- end of catalog file for Simplified DocBook --
+</pre>
+<p>
+   We could similarly configure Cocoon for the full DocBook XML DTD and
+   related entities. In fact, the DocBook distribution already contains a
+   catalog file. We need only append the pathname to our <span class="codefrag">catalogs</span>
+   property.
+  </p>
+<p>
+   There are a few important starting points for 
+   <a href="#info">further information</a> about using and configuring
+   the DocBook DTDs.
+  </p>
+ 
+
+ 
+<a name="imp"></a>
+ 
+<h1>Implementation notes</h1>
+  
+<p>
+   The SAX <span class="codefrag">Parser</span> interface provides an <span class="codefrag">entityResolver</span>
+   hook to allow an application to resolve the external entities. This is
+   enabled via 
+   <span class="codefrag">org.apache.excalibur.xml.EntityResolver</span>
+  
+</p>
+
+  
+<p>
+   The 
+   <a class="external" href="http://xml.apache.org/commons/">Apache XML Commons</a>
+   project has <span class="codefrag">org.apache.xml.resolver</span>
+   which provides a <strong>CatalogResolver</strong>. This is incorporated
+   into Cocoon via <span class="codefrag">org.apache.excalibur.xml.EntityResolver</span> 
+  
+</p>
+
+  
+<p>
+   
+<a href="#default">Default configuration</a> is achieved via
+   <span class="codefrag">org.apache.cocoon.components.resolver.DefaultResolver.java</span> 
+   which initialises the catalog resolver and loads a default system catalog.
+   The <span class="codefrag">DefaultResolver.java</span> enables <a href="#config">local
+   configuration</a> by applying properties from the
+   <span class="codefrag">CatalogManager.properties</span> file and then further configuration
+   from <span class="codefrag">WEB-INF/cocoon.xconf</span> parameters.
+  </p>
+ 
+
+ 
+<a name="debug"></a>
+ 
+<h1>Debugging the resolver configuration</h1>
+  
+<p>
+    Raise the verbosity level as described in cocoon.xconf and watch the
+    messages that go to standard output.
+  </p>
+  
+<p>
+    The "Resolved public" messages should show that the Public Identifiers
+    are being used to find the local copies of the resources. If a "Resolved
+    public" message does not occur for a particular resource, then Cocoon
+    will be retrieving it from the specified location. Use a packet watching
+    tool like "ngrep" to see the HTTP request for the resource.
+  </p>
+ 
+
+ 
+<a name="dev"></a>
+ 
+<h1>Development notes</h1>
+
+  
+<ul>
+   
+<li>Keep up-to-date with releases of 
+    <a class="external" href="http://www.oasis-open.org/docbook/xmlcharent/">XML Character
+    Entities</a> by OASIS.
+   </li>
+  
+</ul>
+ 
+
+ 
+<a name="notes"></a>
+ 
+<h1>Other notes</h1>
+
+  
+<ul>
+   
+<li>OASIS Catalogs (TR 9401:1995 Entity Management) are plain-text files 
+    with a simple delimited format. There is also a new standard being
+    developed for XML Catalogs, using an xml-based structured plain-text file
+    (gee :-). Links to both standards are provided below. Both catalog formats
+    can be currently used with this entity resolver. However, the latter 
+    standard is not yet settled. OASIS TR9401 catalogs will suffice.
+   </li>
+   
+<li>There has been a recent flood of XML tools - unfortunately, many do not
+    implement entity resolution (other than by brute-force retrieval), so
+    those tools are crippled and cannot be used for serious XML processing.
+    Please ensure that you choose 
+    <a class="external" href="http://www.oasis-open.org/cover/">proper XML tools</a>
+    for the preparation and validation of your XML instance documents.
+   </li>
+   
+<li>The default catalog that is shipped with the Cocoon distribution is
+    deliberately basic. You will need to supplement it with your own catalog
+    devised to suit your particular needs.
+   </li>
+  
+</ul>
+ 
+
+ 
+<a name="summ"></a>
+ 
+<h1>Summary</h1>
+  
+<p>
+   Most XML documents that we would want to serve with Cocoon are already
+   in existence in another information system. The XML document instances have
+   a declaration of their DTD Document Type Definition as an external file.
+   This external DTD also includes entity sets such as ISOnum, ISOlat1, etc.
+   Also the DTD declaration has a Formal Public Identifier and a System
+   Identifier which points to a remote URL. These XML instance documents cannot
+   be altered to make workaround solutions like
+   <span class="codefrag">../dtd/document-1.0.dtd</span>
+  
+</p>
+
+  
+<p>
+   Entity management is effected by providing a standards-based mechanism to
+   resolve public identifiers and system identifiers to local filenames or
+   other identifiers or even to other remote network resources. So references
+   to external DTDs, sets of character entities such as mathematical symbols,
+   fragments of XML documents, complete sub-documents, non-xml data chunks
+   (like images), etc. can all be centrally managed and resolved locally.
+  </p>
+ 
+
+ 
+<a name="info"></a>
+ 
+<h1>Further information</h1>
+  
+<p>
+   Here are some links to documents which extol entity management:
+  </p>
+
+  
+<ul>
+   
+<li>
+<a class="external" href="http://www.oasis-open.org/committees/entity/">OASIS Entity
+    Resolution Technical Committee</a> - see especially the
+    <a class="external" href="http://www.oasis-open.org/specs/a401.html">specification for
+    OASIS Catalogs</a> (TR 9401:1995 Entity Management)
+    and the 
+    <a class="external" href="http://www.oasis-open.org/committees/entity/spec.html">specification for XML Catalogs</a>
+   
+</li>
+   
+<li>
+<a class="external" href="http://www.oasis-open.org/cover/topics.html#entities">SGML/XML Special Topics: Entity Sets and Entity Management</a>
+    at the
+    <a class="external" href="http://www.oasis-open.org/cover/">XML Cover Pages</a>
+</li>
+   
+<li>
+<a class="external" href="http://www.oasis-open.org/cover/topics.html#fpi-fsi">SGML/XML
+    Special Topics: Catalogs, Formal Public Identifiers, Formal System
+    Identifiers</a>
+    at the
+    <a class="external" href="http://www.oasis-open.org/cover/">XML Cover Pages</a>
+</li>
+   
+<li>Arbortext column by Norman Walsh
+    <a class="external" href="http://www.arbortext.com/html/presentations___articles.html">Standard
+    Deviations from Norm</a>
+    
+<br> - Issue Three: 
+    <a class="external" href="http://www.arbortext.com/html/issue_three.html">If You Can Name It, You Can Claim It!</a>
+</li>
+   
+<li>
+    The
+    <a class="external" href="http://xml.apache.org/commons/">Apache XML Commons</a>
+    project provides the
+    entity resolver Java classes (which are used in Cocoon) and evolution of
+    the Arbortext article into
+    <a class="external" href="http://xml.apache.org/commons/components/resolver/">XML
+    Entity and URI Resolvers</a>.
+   </li>
+   
+<li>XML-Deviant article 2000-11-29
+    <a class="external" href="http://www.xml.com/pub/a/2000/11/29/deviant.html">What's in
+     a Name?</a>
+</li>
+   
+<li>
+<a class="external" href="http://www.oasis-open.org/docbook/">DocBook</a>:
+     <a class="external" href="http://www.docbook.org/">The Definitive Guide</a>
+     - Section 2.3 Public Identifiers, System Identifiers, and Catalog Files
+   </li>
+   
+<li>
+     FAQ <a class="external" href="http://www.dpawson.co.uk/docbook/catalogs.html">Catalogs
+     and Docbook</a>
+   
+</li>
+   
+<li>OASIS is the <a class="external" href="http://www.oasis-open.org/docbook/">official
+    home</a> of the DocBook DTDs
+    (see also <a class="external" href="http://docbook.sourceforge.net/">DocBook Open
+    Repository</a> project at SourceForge)
+   </li>
+   
+<li>Organization for the Advancement of Structured Information Standards
+    (<a class="external" href="http://www.oasis-open.org/">OASIS</a>)</li>
+  
+</ul>
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/meta.xml
new file mode 100644
index 0000000..28effbd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-catalog/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/catalog.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/content_en.html
new file mode 100644
index 0000000..bde6554
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/content_en.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: action widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>Used to trigger an action event on the server side. Usually presented
+      as a button the user can press (though this is not required). When an
+      action widget was activated, validation will not be performed. This
+      is because usually it would be strange to have other fields validated
+      when the user's intention wasn't really to submit the form. If you want
+      validation to happen, use the <a href="widget_submit.html">submit widget</a>.
+      After pressing an action
+      button, the form will normally always be redisplayed, unless the event
+      handling code explicitely disables this (by using the method <span class="codefrag">endFormProcessing</span>
+      method on the <span class="codefrag">Form</span> object).</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:action id="..." action-command="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:on-action&gt;
+    ...
+  &lt;/fd:on-action&gt;
+&lt;/fd:action&gt;</pre>
+
+      
+<p>The <strong>action-command</strong> attribute specifies a name
+      that will be part of the event generated by this widget. It can be
+      used to distinguish events originated from this fd:action from another one.</p>
+
+      
+<p>For more information on how event handlers are defined, see
+      <a href="eventhandling.html">Event Handling</a>. The interface
+      to be implemented for Java event listeners is
+      <span class="codefrag">org.apache.cocoon.forms.event.ActionListener</span>.
+      The WidgetEvent subclass is <span class="codefrag">org.apache.cocoon.forms.event.ActionEvent</span>.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/meta.xml
new file mode 100644
index 0000000..27e39a1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-action-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/content_en.html
new file mode 100644
index 0000000..6f5a903
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/content_en.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: aggregatefield widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>TO BE DONE</p>      
+    
+
+    
+<h1>Configuration</h1>
+      
+<p>TO BE DONE</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/meta.xml
new file mode 100644
index 0000000..83423ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-aggregatefield-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_aggregatefield.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/content_en.html
new file mode 100644
index 0000000..61df2f2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/content_en.html
@@ -0,0 +1,758 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Binding Framework</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Intro</h1>
+      
+<p>Likely you will want to use CForms to "edit stuff", such as the properties
+      of a bean or data from an XML document (we'll simply use the term object to
+      refer to either of these). This supposes that before you show the form,
+      you copy the data from the object to the form, and after the form has been
+      validated, you copy the data in the form back to the object. To avoid having
+      to write actual code for this, a binding framework is available.</p>
+
+      
+<p>The same illustration as in the introduction,
+      but now extended with the binding, can be viewed <a href="images/forms_schema_withbinding.png">here</a>.</p>
+
+      
+<p>The basic definition of a binding is as follows (if you don't know Java, just ignore this):</p>
+
+      
+<pre class="code">public interface Binding {
+    public void loadFormFromModel(Widget frmModel, Object objModel);
+    public void saveFormToModel(Widget frmModel, Object objModel);
+}</pre>
+
+      
+<p>A binding can work with any object and can perform the binding in any
+      possible way. Currently one implementation is available, based on
+      <a class="external" href="http://jakarta.apache.org/commons/jxpath/index.html">JXPath</a>.
+      JXPath allows to address data in both beans and XML documents using
+      <a class="external" href="http://www.w3.org/TR/xpath">XPath</a> expressions, so this
+      binding implementation can be used both with beans and XML documents.
+      The rest of this document will focus on this implementation.</p>
+
+      
+<p>The binding is configured using an XML file. This XML file contains
+      elements in the fb namesspace (Forms Binding):</p>
+
+      
+<pre class="code">http://apache.org/cocoon/forms/1.0#binding</pre>
+    
+
+    
+<h1>What does a binding file look like?</h1>
+      
+<p>To give you an idea of what a binding file looks like, below a
+      very simple example is shown.</p>
+
+      
+<pre class="code">&lt;fb:context xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" path="/" &gt;
+    &lt;fb:value id="firstname" path="firstName"/&gt;
+    &lt;fb:value id="lastname" path="lastName"/&gt;
+    &lt;fb:value id="email" path="email"/&gt;
+&lt;/fb:context&gt;</pre>
+
+      
+<p>The id attribute identifies the widget. The path attribute is the address
+      of the items in the target object (a Javabean or an XML document).
+      The paths can be arbitrary JXPath expressions.</p>
+
+      
+<p>[Convention] Let's call all elements in the fb namespace "binding elements".
+      They all cause a binding-related action to be performed.</p>
+
+      
+<p>The <span class="codefrag">fb:context</span> element changes the <a class="external" href="http://jakarta.apache.org/commons/jxpath/apidocs/org/apache/commons/jxpath/JXPathContext.html">JXPath context</a>
+      to the specified path. The path expressions on the binding elements occuring
+      inside the context element will then be evaluated in this context, thus relative
+      to the path specified on the fb:context element.</p>
+
+      
+<p>The <span class="codefrag">fb:value</span> element is used to bind the value of a widget.</p>
+
+      
+<p>The binding framework can do much more than what is shown in the simple
+      example above, so read on for more meat.</p>
+    
+
+    
+<h1>Quick reference of supported binding elements</h1>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Element</th>
+          <th colspan="1" rowspan="1">Description</th>
+          <th colspan="1" rowspan="1">Attributes</th>
+          <th colspan="1" rowspan="1">child elements</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:*</td>
+          <td colspan="1" rowspan="1">common settings for all bindings</td>
+          <td colspan="1" rowspan="1">direction</td>
+          <td colspan="1" rowspan="1">not applicable, see specific elements</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:context</td>
+          <td colspan="1" rowspan="1">changes the JXPath context</td>
+          <td colspan="1" rowspan="1">path</td>
+          <td colspan="1" rowspan="1">any</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:value</td>
+          <td colspan="1" rowspan="1">binds the value of widgets</td>
+          <td colspan="1" rowspan="1">id, path</td>
+          <td colspan="1" rowspan="1">fb:on-update, fd:convertor</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:aggregate</td>
+          <td colspan="1" rowspan="1">binds aggregatefield widgets</td>
+          <td colspan="1" rowspan="1">id, path</td>
+          <td colspan="1" rowspan="1">fb:value</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:repeater</td>
+          <td colspan="1" rowspan="1">binds repeater widgets</td>
+          <td colspan="1" rowspan="1">id, parent-path, row-path, unique-row-id
+          (deprecated), unique-path (deprecated)</td>
+          <td colspan="1" rowspan="1">fd:convertor (deprecated), fb:on-bind,
+          fb:on-delete-row, fb:on-insert-row, fb:unique-row</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:unique-row</td>
+          <td colspan="1" rowspan="1">specifies unique fields for a repeater row</td>
+          <td colspan="1" rowspan="1">none</td>
+          <td colspan="1" rowspan="1">fb:unique-field</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:unique-field</td>
+          <td colspan="1" rowspan="1">specifies unique field for a repeater row</td>
+          <td colspan="1" rowspan="1">id, path</td>
+          <td colspan="1" rowspan="1">fd:convertor</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:set-attribute</td>
+          <td colspan="1" rowspan="1">sets an attribute to a fixed value</td>
+          <td colspan="1" rowspan="1">name, value</td>
+          <td colspan="1" rowspan="1">none</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:delete-node</td>
+          <td colspan="1" rowspan="1">deletes the current context node</td>
+          <td colspan="1" rowspan="1">none</td>
+          <td colspan="1" rowspan="1">none</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:insert-node</td>
+          <td colspan="1" rowspan="1">insert a node in an XML document</td>
+          <td colspan="1" rowspan="1">src, xpath</td>
+          <td colspan="1" rowspan="1">piece of XML that should be inserted</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:insert-bean</td>
+          <td colspan="1" rowspan="1">inserts an object in a list-type bean property</td>
+          <td colspan="1" rowspan="1">addmethod, classname (optional)</td>
+          <td colspan="1" rowspan="1">none</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:simple-repeater</td>
+          <td colspan="1" rowspan="1">binds repeater widgets</td>
+          <td colspan="1" rowspan="1">id, parent-path,row-path, clear-before-load, delete-parent-if-empty</td>
+          <td colspan="1" rowspan="1">any</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:javascript</td>
+          <td colspan="1" rowspan="1">write binding logic in Javascript</td>
+          <td colspan="1" rowspan="1">id, path</td>
+          <td colspan="1" rowspan="1">fb:load-form, fb:save-form</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">fb:custom</td>
+          <td colspan="1" rowspan="1">write binding logic in Java</td>
+          <td colspan="1" rowspan="1">id, path, class, builderclass,factorymethod</td>
+          <td colspan="1" rowspan="1">fb:config</td>
+        
+</tr>
+      
+</table>
+    
+
+    
+<h1>Detailed reference of binding elements</h1>
+      
+<h2>fb:*/@direction</h2>
+<p>All Bindings share the ability to have the two distinct actions
+        they provide (i.e. load and save) been enabled or disabled by setting
+        the attribute direction to one of the following values:</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">value</th>
+            <th colspan="1" rowspan="1">load active?</th>
+            <th colspan="1" rowspan="1">save active?</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">both(default)</td>
+            <td colspan="1" rowspan="1">yes</td>
+            <td colspan="1" rowspan="1">yes</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">load</td>
+            <td colspan="1" rowspan="1">yes</td>
+            <td colspan="1" rowspan="1">no</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">save</td>
+            <td colspan="1" rowspan="1">no</td>
+            <td colspan="1" rowspan="1">yes</td>
+          
+</tr>
+        
+</table>
+<p>The default value 'both' for this attribute makes its use optional.</p>
+<p>
+<strong>NOTE</strong>: this setting replaces the @readonly attribute that
+        was available only on selected bindings.</p>
+
+      
+<h2>fb:context</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>path</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements: any</p>
+<p>The <span class="codefrag">fb:context</span> element changes the JXPath context to the
+        specified path. The path expressions on the binding elements occuring inside
+        the context element will then be evaluated in this context, thus relative to
+        the path specified on the <span class="codefrag">fb:context</span> element.</p>
+<p>The <span class="codefrag">fb:context</span> element is usually used in two occasions.
+        First of all, it is used as the root element of the binding file; because an
+        XML file must always have one root element, and you will usually want to
+        perform more than one binding action.</p>
+<p>Secondly, you use <span class="codefrag">fb:context</span> if you need to address multiple
+        items having a common base path. On the one hand, this saves you on typing
+        and helps readability, and on the other hand, this improves the performance
+        of the binding. To illustrate this with an example, instead of doing this:</p>
+<pre class="code">...
+&lt;fb:value id="firstname" path="info/person/firstName"/&gt;
+&lt;fb:value id="lastname" path="info/person/lastName"/&gt;
+...</pre>
+<p>it is better to do this:</p>
+<pre class="code">...
+&lt;fb:context path="info/person"&gt;
+  &lt;fb:value id="firstname" path="firstName"/&gt;
+  &lt;fb:value id="lastname" path="lastName"/&gt;
+&lt;/fb:context&gt;
+...</pre>
+
+      
+<h2>fb:value</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id</li>
+          
+<li>path</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:on-update (optional)</li>
+          
+<li>fd:convertor (note the fd: namespace!) (optional)</li>
+        
+</ul>
+<p>This binding element is used to bind the value of a widget.</p>
+<p>The <span class="codefrag">fb:on-update</span> element (which itself has no attributes),
+        can contain one or more binding elements that will be executed if the value
+        of the widget has changed, and thus if the object has been updated. For example,
+        you could use the <span class="codefrag">fb:set-attribute</span> binding to set the
+        value of an attribute <span class="codefrag">changed</span> to <span class="codefrag">true</span>.</p>
+<p>The <span class="codefrag">fd:convertor</span> element has the same purpose as the
+        <span class="codefrag">fd:convertor</span> element in the form definition: it converts
+        between objects (numbers, dates) and strings. This is mostly used when
+        binding to XML documents. Suppose you have defined a certain widget in
+        a form definition to have a "date" datatype, and you want to bind to
+        an XML document which contains the date in the XML Schema date representation,
+        then you could define a convertor as follows:</p>
+<pre class="code">&lt;fb:value id="birthday" path="person/birthday"&gt;
+  &lt;fd:convertor datatype="date" type="formatting"&gt;
+    &lt;fd:patterns&gt;
+      &lt;fd:pattern&gt;yyyy-MM-dd&lt;/fd:pattern&gt;
+    &lt;/fd:patterns&gt;
+  &lt;/fd:convertor&gt;
+&lt;/fb:value&gt;</pre>
+<p>The datatype attribute on the <span class="codefrag">fd:convertor</span> element, which you
+        don't have to specify in the form definition, identifies the datatype to which
+        the convertor belongs.</p>
+
+      
+<h2>fb:aggregate</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id</li>
+          
+<li>path</li>
+          
+<li>direction</li>
+        
+</ul>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:value elements</li>
+        
+</ul>
+<p>The <span class="codefrag">fb:aggregate</span> element is used to bind aggregatefields. Remember
+        that aggregatefields are a special type of widget that groups multiple field widgets
+        and lets the user edit their values in one textbox, splitting the values out to the
+        different widgets on submit based on a regexp.</p>
+<p>The <span class="codefrag">fb:aggregate</span> binding allows to bind the values of the individual
+        field widgets out of which an aggregatefield widget consists. The bindings for these
+        field widgets are specified by the fb:value child elements.</p>
+
+      
+<h2>fb:repeater</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id</li>
+          
+<li>parent-path</li>
+          
+<li>row-path</li>
+          
+<li>unique-row-id (deprecated)</li>
+          
+<li>unique-path (deprecated)</li>
+          
+<li>row-path-insert (optional)</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:identity</li>
+          
+<li>fd:convertor (deprecated)</li>
+          
+<li>fb:on-bind</li>
+          
+<li>fb:on-delete-row</li>
+          
+<li>fb:on-insert-row</li>
+        
+</ul>
+<p>
+<strong>NOTE:</strong> The attributes <span class="codefrag">unique-row-id</span> and
+        <span class="codefrag">unique-path</span> and the child element <span class="codefrag">fd:convertor</span>
+        are deprecated in favor of &lt;fb:unique-row&gt;.</p>
+<p>The <span class="codefrag">fb:repeater</span> binding binds repeaters based on the concept
+        that each row in the repeater is identified by one or more widgets uniquely.
+        This unique identification is necessary to know which rows in the repeater
+        correspond to which objects in the target collection. Newly added rows in
+        the repeater can (but should not) have a null value for this identification
+        widget(s). Typically this/these widget(s) will not editable, so in most cases
+        it will be an output widget. If you don't need the identification widget(s)
+        at the client you don't need to add them to the template at all! You only have
+        to specify <span class="codefrag">direction="load"</span> to this/these widget(s) then.
+        This prevents the database IDs from getting to the client.</p>
+<p>The <span class="codefrag">id</span> attribute should contain the id of the repeater.</p>
+<p>The <span class="codefrag">unique-row-id</span> attribute specifies the id of the widget
+        appearing on each repeater row that contains the unique identification for
+        that row. The unique-path attribute contains the corresponding path in the object model.</p>
+<p>
+<strong>NOTE</strong>: Both attributes are deprecated. Please use <span class="codefrag">&lt;fb:identity&gt;</span> instead.</p>
+<p>The <span class="codefrag">parent-path</span> and <span class="codefrag">row-path</span> attributes can best be
+        understood when described differently for XML documents and Javabeans.</p>
+<p>For XML documents: If you have an XML structure like this:</p>
+<pre class="code">&lt;things&gt;
+   &lt;thing ... /&gt;
+   &lt;thing ... /&gt;
+&lt;/things&gt;</pre>
+<p>then the parent-path attribute contains the path to the containing
+        element ("things") and the row-path attribute contains the path to the
+        repeating element ("thing").</p>
+<p>For beans: if your bean has a property "things" which is a Collection
+        [or whathever JXPath supports as lists], then the parent-path should simply
+        contain "." and the row-path "things".</p>
+<p>For both beans and XML documents there is an optional attribute
+        row-path-insert which functions just like the row-path but is used
+        for the nested on-insert-row binding (see below). By default the row-path-insert
+        just takes the value of the row-path. By explicitely setting them different
+        one can exploit one of the following use cases:</p>
+<ul>
+          
+<li>(1) use xpath-predicates in the row-path (note that you can not do that on the row-path-insert)</li>
+          
+<li>(2) save the inserted rows in a different target-node of the backend model.</li>
+        
+</ul>
+<p>A child element <span class="codefrag">fd:convertor</span> can be used to specify the convertor
+        to use in case the unique-id from the model is a String (typical for XML documents)
+        and the matching widget inside the repeater has a different type.</p>
+<p>
+<strong>NOTE:</strong> This element is deprecated at that place as it
+        is only used in combination with the deprecated attributes unique-row-id
+        and unique-path. Please use <span class="codefrag">&lt;fb:identity&gt;</span> instead.</p>
+<p>The three remaining child elements <span class="codefrag">fb:on-bind</span>, <span class="codefrag">fb:on-delete-row</span>,
+        <span class="codefrag">fb:on-insert-row</span> should contain the binding elements that have to
+        be executed in case of these three events.</p>
+<p>The children of the <span class="codefrag">fb:on-bind</span> element are executed when
+        an existing repeater row is updated, or after inserting a new row. The JXPath
+        context is automatically changed to match the current row.</p>
+<p>The children of the <span class="codefrag">fb:on-delete-row</span> element are executed
+        when a repeater row has been deleted. If you want to delete the row, then put
+        a <span class="codefrag">&lt;fb:delete-node/&gt;</span> in there. Alternatively, you could also
+        use the <span class="codefrag">fb:set-attribute</span> binding to set e.g. an attribute status to deleted.</p>
+<p>The children of the <span class="codefrag">fb:on-insert-row</span> are executed in case a
+        new row has been added to the repeater. Typically this will contain a
+        <span class="codefrag">fb:insert-node</span> or a <span class="codefrag">fb:insert-bean</span> binding (see
+        the descriptions of these binding elements for more details).</p>
+<p>The childrens of the <span class="codefrag">fb:unique-row</span> specify the widgets appearing
+        on each repeater row for the unique identification of that row. Each &lt;fb:unique-field&gt;
+        child specifies one widget.</p>
+
+      
+<h2>fb:identity</h2>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:value widget-bindings that make up the identity</li>
+        
+</ul>
+<p>The <span class="codefrag">&lt;fb:identity&gt;</span> is just a container for the child elements
+        specifying the bindings of the identification widgets.</p>
+<p>The nested elements just describe regular value bindings that can
+        declare their own convertor if needed.</p>
+<p>
+<strong>NOTE:</strong> This 'identity' binding is only active in the
+        'load' operation, so specifying the direction="save" is meaningless.</p>
+
+      
+<h2>fb:set-attribute</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>name</li>
+          
+<li>value</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements: none</p>
+<p>Set the value of the attribute specified in the <span class="codefrag">name</span> attribute to the
+        fixed string value specified in the <span class="codefrag">value</span> attribute.</p>
+<p>
+<strong>NOTE:</strong> This binding is never active in the 'load' operation,
+        so there is no need to specify the <span class="codefrag">direction="save"</span> to protect you model
+        from being changed during load.</p>
+
+      
+<h2>fb:delete-node</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements: none</p>
+<p>Deletes the current context node.</p>
+<p>
+<strong>NOTE:</strong> This binding is never active in the 'load' operation,
+        so there is no need to specify the <span class="codefrag">direction="save"</span> to protect you model from
+        being changed during load.</p>
+
+      
+<h2>fb:insert-node</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>src (optional)</li>
+          
+<li>xpath (optional, only in combination with src)</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements: the piece of XML that should be inserted</p>
+<p>This binding element can only be used when the target object is an XML document (DOM-tree).</p>
+<p>It inserts the content of the <span class="codefrag">fb:insert-node</span> element as child
+        of the current context element, or, if a src attribute is specified, retrieves
+        the XML from the specified source and inserts that as child of the current
+        context element. In this last case, you can also supply an xpath attribute
+        to select a specific element from the retrieved source.</p>
+<p>
+<strong>NOTE:</strong> This binding is never active in the 'load' operation,
+        so there is no need to specify the <span class="codefrag">direction="save"</span> to protect you model
+        from being changed during load.</p>
+
+      
+<h2>fb:insert-bean</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>addmethod</li>
+          
+<li>classname (optional)</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>This binding element can only be used when the target object is a Javabean.</p>
+<p>If classname is specified it instantiates a new object of the type specified 
+        in the classname attribute and calls the method specified in the addmethod 
+        attribute on the current context object with the newly instantiated object as argument.
+        If classname is not specified it will just call the addmethod (e.g. if the addmethod creates
+        the new instance itself).</p>
+<p>
+<strong>NOTE:</strong> This binding is never active in the 'load' operation,
+        so there is no need to specify the <span class="codefrag">direction="save"</span> to protect you model
+        from being changed during load.</p>
+
+      
+<h2>fb:simple-repeater</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id</li>
+          
+<li>parent-path (same as in fb:repeater)</li>
+          
+<li>row-path (same as in fb:repeater)</li>
+          
+<li>clear-before-load (default true)</li>
+          
+<li>delete-parent-if-empty (default false)</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements: any</p>
+<p>A simple repeater binding that will replace (i.e. delete then re-add all) its content.</p>
+<p>Works with XML or with JavaBeans if a JXPath factory is set on the binding context.</p>
+
+      
+<h2>fb:javascript</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id</li>
+          
+<li>path</li>
+          
+<li>direction (optional)</li>
+        
+</ul>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:load-form</li>
+          
+<li>fb:save-form</li>
+        
+</ul>
+<p>Specifies the binding using two JavaScript snippets, respectively for loading and saving the form.</p>
+<p>Example:</p>
+<pre class="code">&lt;fb:javascript id="foo" path="@foo"&gt;
+  &lt;fb:load-form&gt;
+    var appValue = jxpathPointer.getValue();
+    var formValue = doLoadConversion(appValue);
+    widget.setValue(formValue);
+  &lt;/fb:load-form&gt;
+  &lt;fb:save-form&gt;
+    var formValue = widget.getValue();
+    var appValue = doSaveConversion(formValue);
+    jxpathPointer.setValue(appValue);
+  &lt;/fb:save-form&gt;
+&lt;/fb:javascript&gt;</pre>
+<p>This example is rather trivial and could be replaced by a simple
+        <span class="codefrag">&lt;fb:value&gt;</span>, but it shows the available variables in the script:</p>
+<ul>
+          
+<li>
+<span class="codefrag">widget:</span> the widget identified by the <span class="codefrag">id</span> attribute,</li>
+          
+<li>
+<span class="codefrag">jxpathPointer:</span> the JXPath pointer corresponding to the <span class="codefrag">path</span> attribute,</li>
+          
+<li>
+<span class="codefrag">jxpathContext</span> (not shown): the JXPath context corresponding to the <span class="codefrag">path</span> attribute</li>
+        
+</ul>
+<p>It's much more interesting to fill a selection list via <span class="codefrag">fb:javascript</span>
+        as there is no built-in element for it at the moment. Imagine your binding bean
+        contains a collection field:</p>
+<pre class="code">&lt;fb:javascript id="selectionListWidget" path="objectCollection" direction="load"&gt;
+  &lt;fb:load-form&gt;
+    var collection = jxpathPointer.getNode();
+    widget.setSelectionList(collection, "id", "name")
+  &lt;/fb:load-form&gt;
+&lt;/fb:javascript&gt;</pre>
+<p>
+<strong>NOTE:</strong>
+</p>
+<ul>
+          
+<li>The <span class="codefrag">&lt;fb:save-form&gt;</span> snippet should be ommitted
+          if the <span class="codefrag">direction</span> attribute is set to load.</li>
+          
+<li>The <span class="codefrag">&lt;fb:load-form&gt;</span> snippet should be ommitted if the
+          <span class="codefrag">direction</span> attribute is set to save.</li>
+          
+<li>The <span class="codefrag">@readonly</span> attribute supported in early versions of this
+          binding has been replaced by the @direction attribute as supported now on all binding elements.</li>
+        
+</ul>
+
+      
+<h2>fb:custom</h2>
+<p>Attributes:</p>
+<ul>
+          
+<li>id (optional, if not provided the containing widget-context will be passed)</li>
+          
+<li>path (optional, if not provided "." is assumed)</li>
+          
+<li>direction (optional)</li>
+          
+<li>class (optional, if not present @builderclass and @factorymethod should be)</li>
+          
+<li>builderclass (optional)</li>
+          
+<li>factorymethod (optional)</li>
+        
+</ul>
+<p>Child elements:</p>
+<ul>
+          
+<li>fb:config</li>
+        
+</ul>
+<p>Allows to specify your own user-defined binding to be written in Java.
+        There are two essential modes of operation reflected in two examples:</p>
+<p>Example 1 - No configuration required:</p>
+<pre class="code">&lt;fb:custom id="custom" path="custom-value"
+      class="org.apache.cocoon.forms.samples.bindings.CustomValueWrapBinding"/&gt;</pre>
+<p>This describes the classname of your user defined binding class.</p>
+<p>Above imposes the following requirements:</p>
+<ol>
+          
+<li>there is a <span class="codefrag">class</span> CustomValueWrapBinding available in the specified package</li>
+          
+<li>it has a default (i.e. no arguments) constructor</li>
+          
+<li>it is a subclass of org.apache.cocoon.forms.binding.AbstractCustomBinding</li>
+        
+</ol>
+<p>This last will impose the implementation of two methods:</p>
+<ul>
+          
+<li>void doLoad(Widget widget, JXPathContext context) throws BindingException;</li>
+          
+<li>void doSave(Widget widget, JXPathContext context) throws BindingException;</li>
+        
+</ul>
+<p>where the available arguments are</p>
+<ul>
+          
+<li>
+<span class="codefrag">widget</span>: the widget identified by the <span class="codefrag">id</span> attribute,</li>
+          
+<li>
+<span class="codefrag">context</span>: the JXPath context corresponding to the <span class="codefrag">path</span> attribute</li>
+        
+</ul>
+<p>Example 2 - with nested configuration:</p>
+<pre class="code">  &lt;fb:custom id="config" path="config-value"
+      builderclass="org.apache.cocoon.forms.samples.bindings.CustomValueWrapBinding"
+      factorymethod="createBinding" &gt;
+      &lt;fb:config prefixchar="[" suffixchar="]" /&gt;
+  &lt;/fb:custom&gt;</pre>
+<p>The additional requirements to your user defined classes are now:</p>
+<ol>
+          
+<li>there is a <span class="codefrag">builderclass</span> CustomValueWrapBinding class having a static <span class="codefrag">factorymethod</span>
+</li>
+          
+<li>that can (optionally) take an org.w3c.dom.Element holding it's configuration</li>
+          
+<li>and return an instance of your own user-defined binding which must be a non abstract subclass of org.apache.cocoon.forms.binding.AbstractCustomBinding</li>
+        
+</ol>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/meta.xml
new file mode 100644
index 0000000..0e4488b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-binding/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/binding.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/content_en.html
new file mode 100644
index 0000000..529ccfc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/content_en.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: booleanfield widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>An fd:booleanfield is a field that has a value of
+      true or false. Usually is rendered as a checkbox.</p>
+
+      
+<p>It is different from a <a href="widget_field.html">field widget</a>
+      with a <span class="codefrag">boolean</span> datatype because an HTML checkbox submits
+      no request parameter if the checkbox is unchecked. If you would render
+      it instead as a listbox with true and false values, you could also
+      use a regular field widget. Since the styling preference might change over
+      time, it is however better to use consistently the fd:booleanfield widget.</p>
+
+      
+<p>A booleanfield cannot be marked as "required", because it is
+      always required. It is either true or false. If you want tripples
+      (true/false/none), use a normal field widget with a selection list.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:booleanfield id="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:on-value-changed&gt;
+     [...]
+  &lt;/fd:on-value-changed&gt;
+&lt;/fd:booleanfield&gt;</pre>
+
+      
+<p>See <a href="widget_field.html">field wiget</a> for a description of the
+      configuration options.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/meta.xml
new file mode 100644
index 0000000..c6adb6f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-booleanfield-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_booleanfield.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/content_en.html
new file mode 100644
index 0000000..107595a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/content_en.html
@@ -0,0 +1,349 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Datatypes</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Context</h1>
+      
+<p>Datatypes are used by certain widgets, more specifically the
+      <a href="widget_field.html">field</a> and
+      <a href="widget_multivaluefield.html">multivaluefield</a>
+      widgets, to allow them to edit different types of data
+      (e.g. strings, numbers, dates). For a general introduction
+      of the relationship between the widget and the datatype,
+      see the documentation of the <a href="widget_field.html">field</a>
+      widget.</p>
+    
+
+    
+<h1>General information</h1>
+      
+<p>In its most basic form a datatype is declared as follows:</p>
+
+      
+<pre class="code">&lt;fd:datatype base="..."&gt;</pre>
+
+      
+<p>The <strong>base</strong> attribute refers to one of the built-in
+      datatypes such as string or long.</p>
+
+      
+<h2>Convertors</h2>
+<p>A datatype needs a convertor. The purpose of a convertor
+        is to convert between string and object representations of values.
+        There is always a default convertor, but you change or configure
+        that using the fd:convertor element. Here's an example for dates:</p>
+<pre class="code">&lt;fd:datatype base="date"&gt;
+  &lt;fd:convertor type="formatting"&gt;
+    &lt;fd:patterns&gt;
+      &lt;fd:pattern&gt;dd/MM/yyyy&lt;/fd:pattern&gt;
+    &lt;/fd:patterns&gt;
+  &lt;/fd:convertor&gt;
+&lt;/fd:datatype&gt;</pre>
+<p>The <strong>type</strong> attribute on the fd:convertor element
+        is optional, if not specified the default one will be used (configured
+        in the cocoon.xconf). Any further content of the fd:convertor element
+        is specific to the convertor implementation and will be documented
+        in a seperate section.</p>
+
+      
+<h2>Selection lists (default implementation)</h2>
+<p>Widgets that have a datatype can also have a selection list.
+        Since selection lists are associated with datatypes, we discuss them here.
+        The selection list can be defined inline or read from an external source.
+        Example of inline declaration:</p>
+<pre class="code">&lt;fd:datatype base="long"/&gt;
+&lt;fd:selection-list&gt;
+  &lt;fd:item value="1"/&gt;
+  &lt;fd:item value="2"/&gt;
+  &lt;fd:item value="3"&gt;
+    &lt;fd:label&gt;three&lt;/fd:label&gt;
+  &lt;/fd:item&gt;
+  &lt;fd:item value="4"/&gt;
+  &lt;fd:item value="5"/&gt;
+&lt;/fd:selection-list&gt;</pre>
+<p>Each item in the selection-list can have a value (specified in the
+        value attribute) and optionally a label (specified in the fd:label element).
+        If no label is specified, the value is used as label. The fd:label
+        element can contain mixed content.</p>
+<p>To set a default selection, just set the value of the widget
+        containing the selection list.</p>
+<p>Example of getting a selection list from an external source:</p>
+<pre class="code">&lt;fd:datatype base="string"/&gt;
+&lt;fd:selection-list src="cocoon:/mychoices.xml"/&gt;</pre>
+<p>All Cocoon-supported protocols can be used. The format of the XML
+        produced by the source should be the same as in case of inline
+        specification of the selection list, thus the root element should
+        be a fd:selection-list element.</p>
+<p>By default, the selection list will be retrieved form the source once,
+        and then become part of the form definition, just like when you would
+        have defined it inline. This has the consequence that if the XML produced
+        by the source changes, you won't see the selection list changed. If you'd
+        like CForms to retrieve the content of the selection list each time it needs
+        it, add an attribute called "dynamic" with value "true", for example:</p>
+<pre class="code">&lt;fd:datatype base="string"/&gt;
+&lt;fd:selection-list src="cocoon:/mychoices.xml" dynamic="true"/&gt;</pre>
+<p>If the datatype is different from string, CForms will need to convert
+        the string values that appear in the selection list to their object
+        equivalent. This conversion is normally done using the same convertor
+        as the datatype in which the selection list appears, but you can also
+        specify a different one. Here's an example for a date selection list:</p>
+<pre class="code">&lt;fd:datatype base="date"/&gt;
+&lt;fd:selection-list&gt;
+  &lt;fd:convertor type="formatting"&gt;
+    &lt;fd:patterns&gt;
+      &lt;fd:pattern&gt;yyyyMMdd&lt;/fd:pattern&gt;
+    &lt;/fd:patterns&gt;
+  &lt;/fd:convertor&gt;
+  &lt;fd:item value="13020711"/&gt;
+  &lt;fd:item value="19120623"/&gt;
+  &lt;fd:item value="19690721"/&gt;
+  &lt;fd:item value="19700506"/&gt;
+  &lt;fd:item value="19781014"/&gt;
+  &lt;fd:item value="20010911"/&gt;
+&lt;/fd:selection-list&gt;</pre>
+<p>If there is a fd:convertor element, it should always be the first
+        child element of the fd:selection-list element. This works of course
+        also for selection lists retrieved from external sources.</p>
+<p>Selection list implementations are pluggable. Everything said until
+        now applies to the default selection list implementation. An alternative
+        implementation can be specified by using a <strong>type</strong> attribute
+        on the fd:selection-list element. The sections below describe the
+        alternative implementations currently available.</p>
+
+      
+<h2>Selection lists: flow-jxpath implementation</h2>
+<p>See the javadoc of the <a class="external" href="http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/blocks/forms/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionListBuilder.java?rev=HEAD">FlowJXPathSelectionListBuilder</a> class for now.</p>
+<p>Example:</p>
+<p>In flowscript:</p>
+<pre class="code">var data = new Object();
+
+data.cityList = new Array(2);
+data.cityList[0] = {value:"AL", label:"Alabama"};
+data.cityList[1] = {value:"AK", label:"Alaska"};
+
+form.showForm("flow/myform.form", data);</pre>
+<p>and the corresponding selection list definition:</p>
+<pre class="code">&lt;fd:selection-list type="flow-jxpath" list-path="cityList" value-path="value" label-path="label" /&gt;</pre>
+<p>Hint: the label can be any kind of object, its toString() method will be called
+        to get the string to be displayed. In case the object supplied as
+        label implements the XMLizable interface, its toSAX method will be called instead.
+        One practical application of this is using i18n labels:</p>
+<pre class="code">importClass (Packages.org.apache.cocoon.forms.util.I18nMessage);
+...
+mylist[0] = {value: "x", label: new I18nMessage("myI18nKey") };</pre>
+
+      
+<h2>Selection lists: enum implementation</h2>
+<p>This type of selection list outputs a list of items corresponding
+        to the possible instances of an enumerated type (see below).</p>
+<p>Example:</p>
+<pre class="code">&lt;fd:selection-list type="enum" class="com.example.Sex"/&gt;</pre>
+<p>outputs:</p>
+<pre class="code">&lt;fi:selection-list&gt;
+  &lt;fi:item value=""/&gt;
+  &lt;fi:item value="com.example.Sex.MALE"&gt;
+    &lt;fi:label&gt;
+      &lt;i18n:text&gt;com.example.Sex.MALE&lt;/i18n:text&gt;
+    &lt;/fi:label&gt;
+  &lt;/fi:item&gt;
+  &lt;fi:item value="com.example.Sex.FEMALE"&gt;
+    &lt;fi:label&gt;
+      &lt;i18n:text&gt;com.example.Sex.FEMALE&lt;/i18n:text&gt;
+    &lt;/fi:label&gt;
+  &lt;/fi:item&gt;
+&lt;/fi:selection-list&gt;</pre>
+<p>If you don't want an initial null value, add a <strong>nullable="false"</strong>
+        attribute to the <strong>fd:selection-list</strong> element. This applies only to
+        <strong>enum</strong> type selection lists.</p>
+    
+
+    
+<h1>Available datatypes</h1>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">CForms datatype</th>
+          <th colspan="1" rowspan="1">Java class</th>
+          <th colspan="1" rowspan="1">Convertors</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">string</td>
+          <td colspan="1" rowspan="1">java.lang.String</td>
+          <td colspan="1" rowspan="1">Strings obviously don't support any convertors, since there's no purpose in converting a string to a string.</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">decimal</td>
+          <td colspan="1" rowspan="1">java.math.BigDecimal</td>
+          <td colspan="1" rowspan="1">formatting (decimal), plain</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">integer</td>
+          <td colspan="1" rowspan="1">java.lang.Integer</td>
+          <td colspan="1" rowspan="1">similar as decimal datatype</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">long</td>
+          <td colspan="1" rowspan="1">java.lang.Long</td>
+          <td colspan="1" rowspan="1">similar as decimal datatype</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">double</td>
+          <td colspan="1" rowspan="1">java.lang.Double</td>
+          <td colspan="1" rowspan="1">similar as decimal datatype</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">date</td>
+          <td colspan="1" rowspan="1">java.util.Date</td>
+          <td colspan="1" rowspan="1">formatting (date), millis</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">enum</td>
+          <td colspan="1" rowspan="1">Enumerated type</td>
+          <td colspan="1" rowspan="1">enum</td>
+        
+</tr>
+      
+</table>
+
+      
+<h2>Enumerated datatype</h2>
+<p>The <strong>enum</strong> datatype is meant to be used with types
+        implementing Joshua Bloch's <a class="external" href="http://developer.java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums">typesafe enum pattern</a>.
+        The following is a possible implementation:</p>
+<pre class="code">package com.example;
+
+public class Sex {
+
+    public static final Sex MALE = new Sex("M");
+    public static final Sex FEMALE = new Sex("F");
+    private String code;
+
+    private Sex(String code) { this.code = code; }
+}</pre>
+<p>The following snippet shows the usage of this type:</p>
+<pre class="code">&lt;fd:field id="sex"&gt;
+  &lt;fd:label&gt;Sex&lt;/fd:label&gt;
+  &lt;fd:datatype base="enum"&gt;
+    &lt;fd:convertor type="enum"&gt;
+      &lt;fd:enum&gt;com.example.Sex&lt;/fd:enum&gt;
+    &lt;/fd:convertor&gt;
+  &lt;/fd:datatype&gt;
+  &lt;fd:selection-list type="enum" class="com.example.Sex"/&gt;
+&lt;/fd:field&gt;</pre>
+<p>If your enumerated type does not provide a <span class="codefrag">toString()</span> method,
+        the enum convertor will use the fully qualified class name, followed by the
+        name of the <span class="codefrag">public static final</span> field referring to each instance,
+        i.e. "<span class="codefrag">com.example.Sex.MALE</span>", "<span class="codefrag">com.example.Sex.FEMALE</span>" and so on.</p>
+<p>If you provide a <span class="codefrag">toString()</span> method which returns something
+        different, you should also provide a <span class="codefrag">fromString(String, Locale)</span>
+        method to convert those strings back to instances.</p>
+<p>The enum datatype is typically used together with the <strong>enum</strong> selection list type.</p>
+    
+
+    
+<h1>Available convertors</h1>
+      
+<h2>formatting (decimal)</h2>
+<p>This convertor uses the <span class="codefrag">java.text.DecimalFormat</span>
+        class (or <span class="codefrag">com.ibm.icu.text.DecimalFormat</span> class if it is
+        present in the classpath). This means it can perform locale-dependent,
+        pattern-based formatting of numbers.</p>
+<p>Configuration pseudo-schema:</p>
+<pre class="code">&lt;fd:convertor type="formatting" variant="integer|number|currency|percent" ? &gt;
+  &lt;fd:patterns&gt;
+    &lt;fd:pattern&gt;....&lt;/fd:pattern&gt; ?
+    &lt;fd:pattern locale="lang-COUNTRY"&gt;....&lt;/fd:pattern&gt; *
+  &lt;/fd:patterns&gt; ?
+&lt;/fd:convertor&gt;</pre>
+<p>The variant attribute and patterns element are optional. By
+        default, the "number" variant is used (or for longs: the "integer" variant).</p>
+<p>You can supply either a locale-independent formatting pattern or
+        locale-dependent formatting patterns. See the
+        <a class="external" href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/DecimalFormat.html">javadoc of the DecimalFormat class</a>
+        for the supported pattern syntax. CForms will always use the pattern
+        that is most specific for the current locale.</p>
+
+      
+<h2>plain</h2>
+<p>This convertor is not locale-dependent. It shows the full
+        precision of the number and uses dot as the decimal separator.</p>
+
+      
+<h2>date convertors</h2>
+<p>The date datatype can be used both for dates as times. The date datatype supports the following convertors:</p>
+<h3>formatting (date)</h3>
+<p>This convertor uses the <span class="codefrag">java.text.SimpleDateFormat</span> class
+          (or <span class="codefrag">com.ibm.icu.text.SimpleDateFormat</span> class if it is present
+          in the classpath). This means it can perform locale-dependent, pattern-based
+          formatting of dates.</p>
+<p>Configuration pseudo-schema:</p>
+<pre class="code">&lt;fd:convertor type="formatting" variant="date|time|datetime" ? style="short|medium|long|full" ?&gt;
+  &lt;fd:patterns&gt;
+    &lt;fd:pattern&gt;....&lt;/fd:pattern&gt; ?
+    &lt;fd:pattern locale="lang-COUNTRY"&gt;....&lt;/fd:pattern&gt; *
+  &lt;/fd:patterns&gt; ?
+&lt;/fd:convertor&gt;</pre>
+<p>Usually you will use either the variant and style attributes or the pattern(s).</p>
+<p>For example, the following convertor configuration:</p>
+<pre class="code">&lt;fd:convertor type="formatting" variant="date" style="short"&gt;</pre>
+<p>Will give the following for July 15, 2003: 7/15/03. Using style medium
+          it gives "Jul 15, 2003", style long gives "July 15, 2003", and style full
+          gives "Tuesday, July 15, 2003". These result are locale-dependent of course.</p>
+<p>Here's an example of using a formatting pattern:</p>
+<pre class="code">&lt;fd:convertor type="formatting"&gt;
+  &lt;fd:patterns&gt;
+    &lt;fd:pattern&gt;dd/MM/yyyy&lt;/fd:pattern&gt;
+  &lt;/fd:patterns&gt;
+&lt;/fd:convertor&gt;</pre>
+<p>Using the same date, this will now give "15/07/2003".</p>
+<p>It is also possible to use different patterns for different
+          locales by using multiple fd:pattern elements with "locale" attributes, for example:</p>
+<pre class="code">&lt;fd:convertor type="formatting"&gt;
+  &lt;fd:patterns&gt;
+    &lt;fd:pattern&gt;MM/dd/yyyy&lt;/fd:pattern&gt;
+    &lt;fd:pattern locale="nl-BE"&gt;dd/MM/yyyy&lt;/fd:pattern&gt;
+    &lt;fd:pattern locale="fr"&gt;dd-MM-yyyy&lt;/fd:pattern&gt;
+  &lt;/fd:patterns&gt;
+&lt;/fd:convertor&gt;</pre>
+<p>In this case, if the locale is "nl-BE", the second pattern will be
+          used; if the locale is "en", the first pattern will be used; and if the
+          locale is "fr-BE" the third pattern will be used (because when fr-BE is
+          not found, it will first search for "fr" before using the locale-indepent pattern).</p>
+<h3>millis</h3>
+<p>The millis convertor for dates uses the number of milliseconds since
+          January 1, 1970, 00:00:00 GMT as string representation. This will likely
+          not be used to present dates to the user, but may be useful in selection
+          lists retrieved from external sources.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/meta.xml
new file mode 100644
index 0000000..f174e1f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-datatypes/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/datatypes.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/content_en.html
new file mode 100644
index 0000000..1b57953
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/content_en.html
@@ -0,0 +1,322 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Event Handling</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Intro</h1>
+      
+<p>Some types of widgets can emit events. For example, the
+      action widget produces ActionEvents and the field widget
+      produces ValueChangedEvents. Next to these events, there are
+      also ProcessingPhaseEvents, fired in between the various
+      phases of the processing of a request.</p>
+
+      
+<p>Handling events can be done in three ways:</p>
+
+      
+<ul>
+        
+<li>by defining event listeners in the form definition (as child
+        of wd:on-action for the action widget, or wd:on-value-changed for
+        the field widget, ...).</li>
+        
+<li>by adding event listeners dynamically on widget instances.</li>
+        
+<li>by registering a <span class="codefrag">FormHandler</span> on the
+        Form object. This FormHandler will receive all events from all widgets.</li>
+      
+</ul>
+    
+
+    
+<h1>When are events processed? (Request processing phases)</h1>
+      
+<p>To answer the question "When are events processed?", we have to
+      look a bit deeper into how a form request is handled. This is separated
+      in a couple of phases, more specifically the following ones:</p>
+
+      
+<ul>
+        
+<li>Any outstanding events are broadcasted to the event listeners.<br>
+        The reason this is done is because events might have been collected while
+        the form was loaded with values by the binding framework.</li>
+        
+<li>ProcessingPhaseListeners are informed that the <span class="codefrag">LOAD_MODEL</span> phase has ended.</li>
+        
+<li>All widgets in the widget tree read their value from the request.
+        If a widget decides it has to produce an event, it is added to a global
+        (i.e. form-level) list (but not yet executed).</li>
+        
+<li>Once all widgets had the opportunity to read their value from the request,
+        the events are broadcasted to the event listeners. This assures that event
+        listeners have access to the values of all widgets in the tree.</li>
+        
+<li>ProcessingPhaseListeners are informed that the <span class="codefrag">READ_FROM_REQUEST</span> phase has ended.</li>
+        
+<li>It is possible that processing ends now. This usually happens when
+        an action widget has caused an event.</li>
+        
+<li>All widgets in the widget tree validate themselves.</li>
+        
+<li>ProcessingPhaseListeners are informed that the <span class="codefrag">VALIDATE</span> phase has ended.</li>
+      
+</ul>
+    
+
+    
+<h1>Recursive event loops</h1>
+      
+<p>Event listeners themselves might call methods on widgets which cause
+      new events to be generated. You have to be careful not to cause recursive
+      event loops by doing this.</p>
+
+      
+<p>For example, calling setValue on a widget
+      in a ValueChangedEvent caused by that widget will schedule a new ValueChangedEvent,
+      which will then again cause the execution of the event listener
+      which will then again call setValue and thus again cause a new event
+      to be generated, and so on.</p>
+    
+
+    
+<h1>Defining event handlers in the form definition</h1>
+      
+<p>Event handlers can be specified as part of the form definition, as child
+      of the various wd:on-xxx elements, such as wd:on-action for the action widget.</p>
+
+      
+<p>Event handlers can be written in either javascript or java.
+      The form definition syntax is as follows:</p>
+
+      
+<pre class="code">&lt;fd:on-xxxx&gt;
+  &lt;javascript&gt;
+    ... some inline javascript code ...
+  &lt;/javascript&gt;
+  &lt;java class="..."/&gt;
+&lt;/fd:on-xxxx&gt;</pre>
+
+      
+<p>You can specify as many <span class="codefrag">&lt;javascript&gt;</span> and/or
+      <span class="codefrag">&lt;java&gt;</span> event listeners as you want.</p>
+
+      
+<h2>Javascript event listeners</h2>
+<p>Objects available in the Javascript snippet:</p>
+<ul>
+          
+<li>
+<span class="codefrag">event</span>: a subclass of WidgetEvent. The reference documentation
+          of the individual widgets mentions which WidgetEvent subclass they provide
+          in their events. You can then check the javadoc for those classes to see
+          what they provide.</li>
+          
+<li>
+<span class="codefrag">viewData</span>: any data that is normally passed from the flowlayer
+          to the view (pipeline). Exact contents depends on which flowscript API version you use.</li>
+          
+<li>if the form processing was started from a flowscript, then everything
+          available from the scope of that flowscript, such as global variables,
+          functions and the <span class="codefrag">cocoon</span> object (see also
+          <a href="../flow/api.html">Flow Object Model</a>).</li>
+        
+</ul>
+<div class="note">It does not make sense to create continuations from the Javascript event
+        handler. In other words, do not call <span class="codefrag">cocoon.sendPageAndWait</span> or <span class="codefrag">form.showForm</span>
+        from there.</div>
+
+      
+<h2>Java event listeners</h2>
+<p>The Java class specified in the class attribute on the java element should
+        implement a certain event listener interface. Which interface depends on the type of widget.
+        See the documentation of the individual widgets for more information.</p>
+    
+
+    
+<h1>Adding event listeners on widget instances</h1>
+      
+<p>Adding event listeners on widgets instances allows to dynamically
+      add event listeners at runtime. This is often convenient: as you
+      control the creation of the event listeners yourself, you can pass
+      them any information you need.</p>
+
+      
+<p>To add an event listener on a widget instance, simply call
+      the appropriate method on the widget (e.g. addValueChangedListener)
+      with an appropriate listener object as argument. You can of course also remove
+      the event listener afterwards (e.g. removeValueChangedListener).</p>
+
+      
+<p>When using flowscript, it is possible to simply assign Javascript
+      functions as event listeners. This is a very easy and powerful way
+      to create event listeners. See the <a href="api_javascript.html">flowscript
+      API section</a> for more information.</p>
+    
+
+    
+<h1>Handling events using the FormHandler</h1>
+      
+<p>To handle events using a FormHandler, write a class implementing the following interface:</p>
+
+      
+<pre class="code">org.apache.cocoon.woody.event.FormHandler</pre>
+
+      
+<p>Alternatively you can extend from the following abstract class:</p>
+
+      
+<pre class="code">org.apache.cocoon.woody.event.AbstractFormHandler</pre>
+
+      
+<p>which will split ActionEvents and ValueChangedEvents to two different methods.
+      See the javadocs of these interfaces and classes for more details.</p>
+
+      
+<p>Once you created the FormHandler, register it on a form instance by calling
+      the method <span class="codefrag">setFormHandler(FormHandler formHandler)</span> on it.</p>
+    
+
+    
+<h1>Overview of supported events</h1>
+      
+<p>The figure below shows the 3 types of events we currently support, each
+      extending from the common WidgetEvent class.</p>
+
+      
+<div align="center">
+<img class="figure" alt="Overview of event types" src="images/forms_event_types.png"></div>
+
+      
+<p>The full types of the event listeners and event objects are:</p>
+
+      
+<pre class="code">org.apache.cocoon.forms.event.ValueChangedListener
+org.apache.cocoon.forms.event.ValueChangedEvent
+
+org.apache.cocoon.forms.event.ActionListener
+org.apache.cocoon.forms.event.ActionEvent
+
+org.apache.cocoon.forms.event.ProcessingPhaseListener
+org.apache.cocoon.forms.event.ProcessingPhaseEvent</pre>
+
+      
+<p>The table below gives an overview of what events are supported on what widgets.</p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Widget</th>
+          <th colspan="1" rowspan="1">Supports ValueChangedEvents</th>
+          <th colspan="1" rowspan="1">Supports ActionEvents</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">field</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">multivaluefield</td>
+          <td colspan="1" rowspan="1">TODO</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">booleanfield</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">repeater</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">output</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">submit</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">action</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">repeater-action</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">row-action</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">aggregatefield</td>
+          <td colspan="1" rowspan="1">TODO</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">upload</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">messages</td>
+          <td colspan="1" rowspan="1"></td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+      
+</table>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/meta.xml
new file mode 100644
index 0000000..bddc1d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-eventhandling/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/eventhandling.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/content_en.html
new file mode 100644
index 0000000..11f73c4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/content_en.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: field widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>The field widget is the most common widget. It is used both for
+      text boxes or selection lists. It can be associated with different
+      datatypes such as string, long or date to ask for different types of data.</p>
+
+      
+<div align="center">
+<img class="figure" alt="Diagram showing the associations between field, datatype, convertor, selection list and validators." src="images/forms_field_datatype_relation.png"></div>
+
+      
+<h2>Datatypes</h2>
+<p>A datatype represents a certain type of data, such as a
+        string, integer, decimal or date. Each datatype matches to a certain
+        Java class. If you associate a field widget with a datatype, its
+        setValue(Object) and getValue() methods will take, respectively
+        return objects that are instances of that Java class (or subclasses
+        thereof).</p>
+<p>Each datatype is associated with a <strong>convertor</strong>.
+        The task of the convertor is to convert from string representation
+        to object representation, and vice versa.</p>
+<p>The string to object conversion usually happens when converting
+        the value entered by the user to an object. This process can
+        fail if the user entered an incorrect string, for example
+        <span class="codefrag">abc</span> when a number is required. In this case
+        an appropriate validation error will be set on the widget.
+        String to object conversion also happens when parsing data
+        in selection lists (if the selection list is retrieved as XML)
+        and can also be used as part of the <a href="binding.html">binding</a>.</p>
+<p>The object to string conversion happens when the state
+        of the widget is spit out as XML, this is mostly when injecting
+        the widget XML in the publishing pipeline.</p>
+<p>By having a field widget associated with a datatype, you can be sure
+        that, after successful validation of the widget, retrieving the value
+        of the widget will give you an object of the correct type.</p>
+<p>The available datatypes and their respective convertors are
+        documented in a <a href="datatypes.html">separate document</a>.</p>
+
+      
+<h2>Selection lists</h2>
+<p>A field widget can furthermore be associated with a selection list.
+        This makes that the field widget could be rendered either as a textbox
+        or a list, depending on whether its datatype has a selection list.
+        The selection list is related with the datatype: the values in
+        the selection list should be of the same type as the datatype.</p>
+<p>Selection list data can be specified directly in the form definition
+        (for short, unchanging lists), retrieved from external sources (i.e.
+        a Cocoon pipeline), or pulled from an oject structure. Full details on
+        selection lists are also in a <a href="datatypes.html">separate document</a>.</p>
+
+      
+<h2>Conclusion</h2>
+<p>If we wouldn't make these datatype and selection list associations,
+        we would need to create specific widgets for each possible combination:
+        StringField, LongField, DateField, StringSelectionList, LongSelectionList, ...</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<p>Configuration example:</p>
+
+      
+<pre class="code">&lt;fd:field id="..." required="true|false"&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:datatype base="..."&gt;
+     [...]
+  &lt;/fd:datatype&gt;
+  &lt;fd:selection-list .../&gt;
+  &lt;fd:validation&gt;
+     [...]
+  &lt;/fd:validation&gt;
+  &lt;fd:on-value-changed&gt;
+     [...]
+  &lt;/fd:on-value-changed&gt;
+&lt;/fd:field&gt;</pre>
+
+      
+<p>The field element takes a required <strong>id</strong> attribute.
+      This id should be unique among all widgets in the same container (i.e. inside
+      the same fd:widgets element).</p>
+
+      
+<p>The <strong>required</strong> attribute is optional, by default it is false.
+      It indicates whether this field is required. This is a static property of the
+      widget. If you want the field to be "conditionally required", then set this
+      to false and use custom validation logic to check the requiredness of the field.</p>
+
+      
+<p>The <strong>fd:label</strong> element contains the label for this widget.
+      This element is optional. It can contain mixed content. For internationalised
+      labels, use i18n-tags in combination with Cocoon's I18nTransformer.</p>
+
+      
+<p>The <strong>fd:hint</strong> element contains a hint for the form control of this widget.
+      This element is optional. It can contain a hint about the input control.
+      For internationalised labels, use i18n-tags in combination with Cocoon's I18nTransformer.</p>
+
+      
+<p>The <strong>fd:help</strong> element contains more help for the form control of this widget.
+      This element is optional. It can contain text help about the input control.
+      For internationalised labels, use i18n-tags in combination with Cocoon's I18nTransformer.</p>
+
+      
+<p>The <strong>fd:datatype</strong> element indicates the datatype for
+      this field. This element is required. The base attribute specifies
+      on which built-in type this datatype should be based. The contents
+      of the fd:datatype element can contain further configuration
+      information for the datatype. The possible datatypes and their
+      configuration options are described <a href="datatypes.html">over here</a>.</p>
+
+      
+<p>The <strong>fd:selection-list</strong> element is used to associate
+      a selection list with this field. See <a href="datatypes.html">Datatypes</a>
+      for more details.</p>
+
+      
+<p>The <strong>fd:validation</strong> element specifies widget validators.
+      See <a href="validation.html">Validation</a> for more details.</p>
+
+      
+<p>The <strong>fd:on-value-changed</strong> element specifies event
+      handlers to be executed in case the value of this field changes.
+      See also <a href="eventhandling.html">Event Handling</a>. The interface to be implemented
+      for Java event listeners is <span class="codefrag">org.apache.cocoon.forms.event.ValueChangedListener</span>.
+      The WidgetEvent subclass is <span class="codefrag">org.apache.cocoon.forms.event.ValueChangedEvent</span>.</p>
+
+      
+<p>
+<strong>Note:</strong> Events used in &lt;fd:on-value-changed&gt;
+      require that the form instance is stored serverside (because otherwise
+      CForms doesn't know what the previous values of the fields were).
+      This is automatically the case when you use flowscript. If you don't use
+      flowscript you could store the form instance in e.g. the session.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/meta.xml
new file mode 100644
index 0000000..a30bc38
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-field-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_field.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/content_en.html
new file mode 100644
index 0000000..6955c0a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/content_en.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apache Cocoon Forms: Forms Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>The FormsGenerator is a Cocoon generator that generates an XML
+      representation of a form instance object.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/meta.xml
new file mode 100644
index 0000000..2783ee9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-formgenerator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/formsgenerator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/content_en.html
new file mode 100644
index 0000000..b763da2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/content_en.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Java API</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>To be done</h1>
+      
+<p>To be done.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/meta.xml
new file mode 100644
index 0000000..59219d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-java-api/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/api_java.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/content_en.html
new file mode 100644
index 0000000..d81b55e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/content_en.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Javascript API</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>To be done</h1>
+      
+<p>To be done.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/meta.xml
new file mode 100644
index 0000000..8eec1a8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-javascript/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/api_javascript.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/content_en.html
new file mode 100644
index 0000000..7e42ae1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/content_en.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: messages widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>TO BE DONE</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<p>TO BE DONE</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/meta.xml
new file mode 100644
index 0000000..ba75c7e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-messages-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_messages.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/content_en.html
new file mode 100644
index 0000000..4589acc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/content_en.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: multivaluefield widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>The fd:multivaluefield is similar to the
+      <a href="widget_field.html">field widget</a> but
+      can take multiple values. Its purpose is to handle those (HTML) form
+      controls which submit their multiple values as multiple (HTTP) request parameters
+      with the same name. A multivaluefield should always have
+      an fd:datatype element combined with a fd:selection-list, since
+      the user will have to select values from this list.</p>
+
+      
+<p>The fd:multivaluefield could be rendered as a list of checkboxes
+      or as a listbox in which the user can select multiple items.
+      The CForms stylesheets also include a styling option to render
+      them as a "double list", i.e. a list of available and selected
+      values.</p>
+
+      
+<p>The setValue and getValue methods of the multivaluefield take
+      respectively return arrays of objects (i.e. Object[]). The type
+      of the objects in these arrays should match the datatype declared
+      for the widget.</p>
+    
+
+    
+<h1>Configuration</h1>
+
+      
+<pre class="code">&lt;fd:multivaluefield id="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:datatype base="..."&gt;
+    [...]
+  &lt;/fd:datatype&gt;
+  &lt;fd:selection-list&gt;
+    [...]
+  &lt;/fd:selection-list&gt;
+  &lt;fd:validation&gt;
+    [...]
+  &lt;/fd:validation&gt;
+  &lt;fd:on-value-changed&gt;
+     [...]
+  &lt;/fd:on-value-changed&gt;
+&lt;/fd:multivaluefield&gt;</pre>
+
+      
+<p>Most of the elements and attributes have the same meaning
+      as for the <a href="widget_field.html">field</a> widget.</p>
+
+      
+<p>Note: A multivaluefield cannot have a required attribute,
+      instead you should use the value-count validator to
+      check the number of values the user has selected.</p> 
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/meta.xml
new file mode 100644
index 0000000..f41e14e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-multivaluefield-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_multivaluefield.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/content_en.html
new file mode 100644
index 0000000..7897b0f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/content_en.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: output widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>An fd:output widget is similar to a field widget, but its value
+      is not editable. The value of an output widget must be set programmatically
+      (or through binding). An output widget does not read its value from
+      the request, so is most useful in the case where the form is stored
+      accross requests (automatically the case when using flowscript). An
+      output widget does not perform any validation, it is always considered
+      to be valid.</p>
+
+      
+<div class="note">It is likely that we'll add a generalized 'readonly' capability
+      to all widgets. When we do that, fd:output will become obsolete and
+      can be replaced by a 'readonly' field wiget. In the meantime you can
+      safely use fd:output since this change won't have much impact.</div>
+
+      
+<p>
+<strong>Possible alternative:</strong> On each widget you can
+      also store additional information
+      (i.e. arbitrary Java objects) in attributes. See the Java API
+      of the Widget interface, methods setAttribute and getAttribute.
+      You can then retrieve these attributes using the JXTemplate generator.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:output id="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:datatype base="..."&gt;
+     [...]
+  &lt;/fd:datatype&gt;
+&lt;/fd:output&gt;</pre>
+
+      
+<p>See <a href="widget_field.html">field widget</a> for a description
+      of the configuration elements.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/meta.xml
new file mode 100644
index 0000000..52d6f07
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-output-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_output.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/content_en.html
new file mode 100644
index 0000000..d24e9a8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/content_en.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: repeater widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>An fd:repeater widget is a widget that repeats a number of other widgets.
+      It can be used to create e.g. tables, repeating subforms, etc.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:repeater id="..." initial-size="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:widgets&gt;
+    [...]
+  &lt;/fd:widgets&gt;
+  &lt;fd:validation&gt;
+     [...]
+  &lt;/fd:validation&gt;
+&lt;/fd:repeater&gt;</pre>
+
+      
+<p>The <strong>fd:widgets</strong> element should contain a number of other widgets to repeat.
+      This can be any of type of widget: field, multivaluefied, booleanfield,
+      or even repeater itself.</p>
+
+      
+<p>The optional <strong>initial-size</strong> attribute allows to specify how much rows should
+      be initially present on the repeater. It mostly avoids to display a table
+      with only table headers. Default value is zero.</p>
+
+      
+<p>For a description of the other elements, see the
+      <a href="widget_field.html">field widget</a>.</p>
+
+      
+<p>Note: The Forms Template Transformer has specific support for specifying
+      a template to use to render each of the rows of a repeater widget. See
+      the CForms samples for an example on how to use this.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/meta.xml
new file mode 100644
index 0000000..d4f9d07
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeater-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_repeater.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/content_en.html
new file mode 100644
index 0000000..82d2294
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/content_en.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: repeater-action widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>This is a specific type of <a href="widget_action.html">action widget</a>
+      that handles the much
+      needed case of adding or removing rows from a repeater.</p>
+    
+
+    
+<h1>Configuration</h1>
+
+      
+<pre class="code">&lt;fd:repeater-action id="..." action-command="delete-rows|add-row" repeater="..." select="..."&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:on-action&gt;
+    ...
+  &lt;/fd:on-action&gt;
+&lt;/fd:repeater-action&gt;</pre>
+
+      
+<p>The <strong>action-command</strong> attribute should have either
+      the value <span class="codefrag">delete-rows</span> or <span class="codefrag">add-row</span>. If
+      <strong>add-row</strong> is specified, the attribute repeater is required.
+      If <strong>delete-rows</strong> is specified, both the repeater and
+      select attributes are required.</p>
+
+      
+<p>The <strong>repeater</strong> attribute should contain the id of the repeater widget
+      on which this repeater-action should act. This must be a sibling of
+      the repeater-action widget (see also row-action for actions inside a row).</p>
+
+      
+<p>The <strong>select</strong> attribute should contain the id of the
+      booleanfield widget (or any type of widget who's getValue() method
+      returns a boolean) that is part of the repeater and used to mark
+      the rows to be deleted.</p>
+
+      
+<p>
+<strong>fd:on-action</strong> allows additional event handlers
+      to be defined, see also <a href="eventhandling.html">Event Handling</a>. The interface to be
+      implemented for Java event listeners is <span class="codefrag">org.apache.cocoon.forms.event.ActionListener</span>.
+      The WidgetEvent subclass is <span class="codefrag">org.apache.cocoon.forms.event.ActionEvent</span>.
+    The event handlers are called <em>after</em> the action is performed except for the
+    <span class="codefrag">delete-rows</span> action where event handlers are called <em>before</em> the
+    selected rows are deleted.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/meta.xml
new file mode 100644
index 0000000..5e68b8f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-repeateraction-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_repeater_action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/content_en.html
new file mode 100644
index 0000000..915421f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/content_en.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: row-action widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>This is a specific type of <a href="widget_action.html">action widget</a>
+      that handles frequent actions
+      occuring on a repeater row, such as adding/removing a row and moving
+      it up and down. These widgets should be placed inside a repeater and
+      act on the current row.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:row-action id="..." action-command="add-after|delete|move-up|move-down"&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:on-action&gt;
+    ...
+  &lt;/fd:on-action&gt;
+&lt;/fd:row-action&gt;</pre>
+
+      
+<p>The <strong>action-command</strong> attribute should have either the
+      value <span class="codefrag">add-after</span>, <span class="codefrag">delete</span>, <span class="codefrag">move-up</span>
+      or <span class="codefrag">move-down</span>.</p>
+
+      
+<p>
+<strong>fd:on-action</strong> allows additional event handlers to
+      be defined, see also <a href="eventhandling.html">Event Handling</a>. The interface to be implemented
+      for Java event listeners is <span class="codefrag">org.apache.cocoon.forms.event.ActionListener</span>.
+      The WidgetEvent subclass is <span class="codefrag">org.apache.cocoon.forms.event.ActionEvent</span>.
+    The event handlers are called <em>after</em> the action is performed except for the
+    <span class="codefrag">delete</span> row action where event handlers are called <em>before</em> the
+    row is deleted.</p>
+
+      
+<p>Where all you want to do is submit a specific row on a repeater,
+      simply add a fd:submit element to the widgets for the repeater.</p>
+
+      
+<p>Then, you can access the submitted row either using an event handler
+      with event.getSourceWidget().getParent(), or from the flow using
+      form.getWidget().getSubmitWidget().getParent(). The row itself has a
+      lookupWidget(widgetName) method that can be used to access specific
+      widgets for the row.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/meta.xml
new file mode 100644
index 0000000..e158cf8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-row-action-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_row_action.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/content_en.html
new file mode 100644
index 0000000..ae3d7ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/content_en.html
@@ -0,0 +1,304 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: A Simple Example</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>A simple CForms example</h1>
+      
+<p>In this example we will show how to create a simple registration
+      form using CForms and flowscript. We will follow to following steps:</p>
+
+      
+<ol>
+        
+<li>Create a form definition file</li>
+        
+<li>Create a template file for the Forms Template Transformer</li>
+        
+<li>Write a bit of flowscript</li>
+        
+<li>Add some pipelines to the sitemap</li>
+      
+</ol>
+
+      
+<p>Here is a screenshot of the form we're going to create:</p>
+
+      
+<div align="center">
+<img class="figure" alt="Screenshot of the sample we're going to create." src="images/forms_registrationform.png"></div>
+    
+
+    
+<h1>Create a form definition file</h1>
+      
+<p>Below the form definition file is displayed. This lists all the widgets
+      in the form, together with their configuration information.</p>
+
+      
+<pre class="code">&lt;fd:form
+  xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"&gt;
+
+  &lt;fd:widgets&gt;
+    &lt;fd:field id="name" required="true"&gt;
+      &lt;fd:label&gt;Name:&lt;/fd:label&gt;
+      &lt;fd:datatype base="string"/&gt;
+      &lt;fd:validation&gt;
+        &lt;fd:length min="2"/&gt;
+      &lt;/fd:validation&gt;
+    &lt;/fd:field&gt;
+
+    &lt;fd:field id="email" required="true"&gt;
+      &lt;fd:label&gt;Email address:&lt;/fd:label&gt;
+      &lt;fd:datatype base="string"/&gt;
+      &lt;fd:validation&gt;
+        &lt;fd:email/&gt;
+      &lt;/fd:validation&gt;
+    &lt;/fd:field&gt;
+
+    &lt;fd:field id="age"&gt;
+      &lt;fd:label&gt;Your age:&lt;/fd:label&gt;
+      &lt;fd:datatype base="long"/&gt;
+      &lt;fd:validation&gt;
+        &lt;fd:range min="0" max="150"/&gt;
+      &lt;/fd:validation&gt;
+    &lt;/fd:field&gt;
+
+    &lt;fd:field id="password" required="true"&gt;
+      &lt;fd:label&gt;Password:&lt;/fd:label&gt;
+      &lt;fd:datatype base="string"/&gt;
+      &lt;fd:validation&gt;
+        &lt;fd:length min="5" max="20"/&gt;
+      &lt;/fd:validation&gt;
+    &lt;/fd:field&gt;
+
+    &lt;fd:field id="confirmPassword" required="true"&gt;
+      &lt;fd:label&gt;Re-enter password:&lt;/fd:label&gt;
+      &lt;fd:datatype base="string"/&gt;
+      &lt;fd:validation&gt;
+        &lt;fd:assert test="password = confirmPassword"&gt;
+          &lt;fd:failmessage&gt;The two passwords are not equal.&lt;/fd:failmessage&gt;
+        &lt;/fd:assert&gt;
+      &lt;/fd:validation&gt;
+    &lt;/fd:field&gt;
+
+    &lt;fd:booleanfield id="spam"&gt;
+      &lt;fd:label&gt;Send me spam&lt;/fd:label&gt;
+    &lt;/fd:booleanfield&gt;
+  &lt;/fd:widgets&gt;
+
+&lt;/fd:form&gt;
+</pre>
+      
+<p>All elements are in the Forms Definition namespace: <strong>fd</strong>.</p>
+
+      
+<p>Every definition file has a <strong>&lt;fd:form&gt;</strong> element as the root element.</p>
+
+      
+<p>The child widgets of the form are defined inside the <strong>&lt;fd:widgets&gt;</strong> element.
+      As you can see, most of the widgets are field widgets. The field widget is the most
+      important widget in CForms. It is very flexible because it can be associated with
+      different datatypes and with a selection list. See the reference docs for more
+      information on this and other widgets.</p>
+
+      
+<p>A nice feature is that the <strong>fd:label</strong> tags can contain mixed content.
+      On the one hand, this can be used to provide rich formatting in the label. But it
+      also enables you to put i18n-elements in there, to be interpreted by the I18nTransformer.
+      This way, internationalisation is done using standard Cocoon techniques.</p>
+    
+
+    
+<h1>Create a template file for the Forms Template Transformer</h1>
+      
+<p>Here's the template for our registration form example:</p>
+
+      
+<pre class="code">&lt;html xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+  xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"&gt;
+  &lt;head&gt;
+    &lt;title&gt;Registration form&lt;/title&gt;
+  &lt;/head&gt;
+  &lt;body&gt;
+    &lt;h1&gt;Registration&lt;/h1&gt;
+    &lt;ft:form-template action="#{$continuation/id}.continue" method="POST"&gt;
+      &lt;ft:widget-label id="name"/&gt;
+      &lt;ft:widget id="name"/&gt;
+      &lt;br/&gt;
+      &lt;ft:widget-label id="email"/&gt;
+      &lt;ft:widget id="email"/&gt;
+      &lt;br/&gt;
+      &lt;ft:widget-label id="age"/&gt;
+      &lt;ft:widget id="age"/&gt;
+      &lt;br/&gt;
+      &lt;ft:widget-label id="password"/&gt;
+      &lt;ft:widget id="password"&gt;
+        &lt;fi:styling type="password"/&gt;
+      &lt;/ft:widget&gt;
+      &lt;br/&gt;
+      &lt;ft:widget-label id="confirmPassword"/&gt;
+      &lt;ft:widget id="confirmPassword"&gt;
+        &lt;fi:styling type="password"/&gt;
+      &lt;/ft:widget&gt;
+      &lt;br/&gt;
+      &lt;ft:widget id="spam"/&gt;
+      &lt;ft:widget-label id="spam"/&gt;
+      &lt;br/&gt;
+
+      &lt;input type="submit"/&gt;
+    &lt;/ft:form-template&gt;
+  &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+      
+<p>The CForms-specific elements here are in the "Forms Template" namespace: <strong>ft</strong>.</p>
+
+      
+<p>The &lt;ft:widget-label&gt; tag will cause the label of a widget to be
+       inserted at the location of the tag. The &lt;ft:widget&gt; tag will cause
+       the XML representation of a widget to be inserted at the location of that tag.
+       The inserted XML will be in the "Forms Instance" namespace: <strong>fi</strong>.</p>
+
+      
+<p>The XML representation of the widget will then be translated to HTML by an
+      XSLT stylesheet (forms-samples-styling.xsl in our case -- see sitemap snippets below).
+      This XSLT only has to handle individual widgets, and not the page as a whole,
+      and is thus not specific for one form but can be reused across forms.</p>
+
+      
+<p>For certain widgets it may be necessary to provide extra presentation hints,
+      such as the width of a text box, the style of a selection list (drop down,
+      radio buttons, ...) or class and style attribute values. This can be done
+      by putting a fi:styling element inside the ft:widget element. This element
+      is in the fi namespace because it will be copied literally. The attributes
+      and/or content of the fi:styling element depend on what is supported by the
+      particular stylesheet used.</p>
+
+      
+<p>As an alternative to the template approach, you could also use the FormsGenerator,
+      which will generate an XML representation of the whole form, and style that with a
+      custom-written XSLT. For most users we recommend the template approach though.</p>
+    
+
+    
+<h1>Write a bit of flowscript</h1>
+      
+<p>Flowscript is Cocoon's solution to handling the flow of a web interaction.
+      It is based on the concept of continuations. If you don't know yet about continuations
+      and flowscript, <a href="../flow/index.html">learn about it here</a>.</p>
+
+      
+<p>Here's the flowscript for our example, <span class="codefrag">registration.js</span>:</p>
+
+      
+<pre class="code">cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");
+
+function registration() {
+    var form = new Form("forms/registration.xml");
+
+    form.showForm("registration-display-pipeline");
+
+    var model = form.getModel();
+    var bizdata = { "username" : model.name }
+    cocoon.sendPage("registration-success-pipeline", bizdata);
+}</pre>
+
+      
+<div class="note">This sample still shows the "old" flowscript API. Will be updated eventually.</div>
+
+      
+<p>The flowscript works as follows:</p>
+
+      
+<p>First we create a Form object, specifying the form definition file to be used.
+      The Form object is actually a javascript wrapper around the "real" Java form instance object.</p>
+
+      
+<p>Then the showForm function is called on the form object. This will (re)display
+      the form to the user until validation of the form succeeded. As parameter to
+      the showForm function, we pass the sitemap pipeline to be used to display the form.</p>
+
+      
+<p>Finally we get some data from the form (the entered name), and call a sitemap
+      pipeline to display this data. This pipeline is based on the JXTemplate generator.</p>
+    
+
+    
+<h1>Add some pipelines to the sitemap</h1>
+      
+<p>First of all, do not forget to register the <span class="codefrag">registration.js</span>
+      file in the map:flow section of the sitemap, as follows:</p>
+
+      
+<pre class="code">&lt;map:flow language="javascript"&gt;
+  &lt;map:script src="flow/registration.js"/&gt;
+&lt;/map:flow&gt;</pre>
+
+      
+<p>And here are the pipelines we need:</p>
+
+      
+<pre class="code">&lt;map:match pattern="registration"&gt;
+  &lt;map:call function="registration"/&gt;
+&lt;/map:match&gt;
+
+&lt;map:match pattern="*.continue"&gt;
+  &lt;map:call continuation="{1}"/&gt;
+&lt;/map:match&gt;
+
+&lt;map:match pattern="registration-display-pipeline"&gt;
+  &lt;map:generate src="forms/registration_template.xml"/&gt;
+  &lt;map:transform type="forms"/&gt;
+  &lt;map:transform type="i18n"&gt;
+    &lt;map:parameter name="locale" value="en-US"/&gt;
+  &lt;/map:transform&gt;
+  &lt;map:transform src="resources/forms-samples-styling.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+
+&lt;map:match pattern="registration-success-pipeline"&gt;
+  &lt;map:generate type="jx" src="forms/registration_success.jx"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;</pre>
+
+      
+<p>The first two are for managing the flowscript: when someone hits the registration
+      URL, we call the registration function in our flowscript.</p>
+
+      
+<p>When a form is submitted, it will be matched by the second matcher,
+      *.continue, which will continue the execution of the flowscript.</p>
+
+      
+<p>The third matcher is for displaying the form, and uses the Forms Template Transformer.</p>
+
+      
+<p>The fourth pipeline is for showing the "success" page using the
+      JXTemplate generator, here is the contents of the registration_succcess.jx page:</p>
+
+      
+<pre class="code">&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;Registration successful&lt;/title&gt;
+  &lt;/head&gt;
+  &lt;body&gt;
+    Registration was successful for ${username}!
+  &lt;/body&gt;
+&lt;/html&gt;</pre>
+    
+
+    
+<h1>Next steps</h1>
+      
+<p>The example we've studied here is quite simple. To have a feel for the power
+      of CForms, take a look at the examples included included in the Forms block.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/meta.xml
new file mode 100644
index 0000000..0bb065d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-sample/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/sample.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/content_en.html
new file mode 100644
index 0000000..a85902a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/content_en.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: submit widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>The submit widget, usually rendered as a button, is used by
+      the user to submit the form. The submit widget is a special kind
+      of action widget, thus also has the same functionality as an action
+      widget, however the submit widget does trigger validation and its
+      purpose is to end the form.</p>
+
+      
+<p>You don't need to use a submit widget to submit a form. For example,
+      in your HTML template you can simply put:</p>
+
+      
+<pre class="code">&lt;input type="submit"/&gt;</pre>
+
+      
+<p>to be able to submit the form. Using a submit widget enables
+      some extra functionality. You can control whether validation
+      should be performed. You can put multiple submit widgets on
+      a form and add different event handlers to them.</p>
+
+      
+<p>While a submit widget has the explicit purpose to submit a
+      form, a form can also be submitted by other widgets. One example
+      is the already mentioned <a href="widget_action.html">action
+      widget</a>. It is however also possible to automatically submit
+      a form when a widget changes its value, so that server-side event
+      value-changed event listeners can be triggerd. This can be specified
+      using <span class="codefrag">&lt;fi:styling submit-on-change="true"/&gt;</span> in
+      the form template (see <a href="xslt.html">XSLT</a> for more
+      information on the <span class="codefrag">fi:styling</span> directive).</p>
+
+      
+<p>To know which widget caused the form to be submitted, use the
+      method <span class="codefrag">getSubmitWidget</span> of the <span class="codefrag">Form</span> object.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:submit id="..." action-command="..." validate="true|false"&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+  &lt;fd:on-action&gt;
+    ...
+  &lt;/fd:on-action&gt;
+&lt;/fd:submit&gt;</pre>
+
+      
+<p>The optional attribute validate, which is true by default, can
+      be used to disable validation. The difference between an action
+      widget and a submit widget with validate="false" is that a submit
+      widget with validate="false" will end form processing, thus the form
+      will not be redisplayed. Ultimately, it is of course the controller
+      who decides this, but the forms hint towards the controller is that
+      it shouldn't be redisplayed, and this is exactly what the flowscript
+      integration library does.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/meta.xml
new file mode 100644
index 0000000..cd10206
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-submit-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_submit.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/content_en.html
new file mode 100644
index 0000000..5770145
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/content_en.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Template Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>The same "ft:" tags as provided by the <a href="templatetransformer.html">template
+      transformer</a> are also available as macros for the
+      <a href="../flow/jxtemplate.html">JXTemplate</a> generator.</p>
+
+      
+<p>Before the availability of these macros, the JXTemplate generator was
+      already often used in the form publishing pipeline. It makes it possible
+      to dynamically include additional data on the form page and to conditionally
+      include parts of the page (and thus conditionally show widgets).
+      Moving the interpretation of the <span class="codefrag">ft:</span> tags directly into
+      generator makes this even more powerful. Think of the possibility
+      of not showing a repeater table if the repeater contains no rows,
+      and this also for nested repeaters.</p>
+    
+
+    
+<h1>Usage</h1>
+      
+<p>Simply remove the FormsTemplateTransformer from your publishing pipeline,
+      and instead include the following jx statement into your template file:</p>
+
+      
+<pre class="code">&lt;jx:import uri="resource://org/apache/cocoon/forms/generation/template.jx"/&gt;</pre>
+
+      
+<p>Note that these macros only work when calling the pipeline from flowscript.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/meta.xml
new file mode 100644
index 0000000..ea61b6a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/templategenerator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/content_en.html
new file mode 100644
index 0000000..9ee9259
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/content_en.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Template Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>The FormsTemplateTransformer (simply "forms transformer" from now on)
+      makes it possible to define the layout for your form without having
+      to write a separate XSLT for each form. If you prefer to do everything
+      with XSLT, you have also the option of using the
+      <a href="formsgenerator.html">FormsGenerator</a>. In general
+      we recommend to use the forms transformer though.</p>
+
+      
+<p>The basic principle is that the forms transformer will replace any
+      &lt;ft:widget id="xyz"/&gt; elements it encounters by the XML representation
+      of the corresponding widgets. These ft:widget elements can be embedded in
+      e.g. a HTML layout. So after passing this template through the forms transformer
+      you'll end up with HTML with here and there a piece of XML describing a widget.
+      This XML description contains all state information of the widget: its value,
+      validation errors, selection-list data if any, and so on. These
+      widget-XML-descriptions will then typically be translated to HTML by an XSLT.
+      This XSLT is then however not form-specific, as it simply needs to know how
+      to translate individual widgets to HTML, and does not have to create the
+      complete page layout. CForms contains just such an XSLT so you don't have
+      to write it yourself (except if you need to do heavy customisation).
+      The image below illustrates this process.</p>
+
+      
+<div align="center">
+<img class="figure" alt="Forms Template Transformer illustration." src="images/forms_template_transformer.png"></div>
+
+      
+<h2>Where the forms transformer looks for the form instance object</h2>
+<p>Each time the forms transformer encounters a ft:form-template element
+        (see further on), it will try to retrieve a CForms form instance object.
+        It looks for it in the following locations:</p>
+<ol>
+          
+<li>if the ft:form-template element has a location attribute, then the
+          value of that attribute will be evaluated as a JXPath expression.
+          The result of this expression should be the form object.</li>
+          
+<li>if a parameter called "attribute-name" was supplied to the
+          forms transformer in the sitemap, then the forms transformer will try
+          to find the form in the request attribute with that name. (request
+          attributes are a temporary storage area that exists for the duration
+          of one request and is often used to communicate objects between
+          different sitemap components such as actions and transformers)</li>
+          
+<li>finally, the forms transformer will look if a CForms form was supplied
+          from a flowscript using the key "CocoonFormsInstance".</li>
+        
+</ol>
+<p>If the form is not found at any of these locations, an exception is thrown.</p>
+    
+
+    
+<h1>Forms transformer element reference</h1>
+      
+<p>The elements to which the forms transformer reacts are all in
+      the "ft" (Forms Template) namespace, which is identified by the following URI:</p>
+
+      
+<pre class="code">http://apache.org/cocoon/forms/1.0#template</pre>
+
+      
+<p>These will generally be replaced by elements in the "fi" (Forms Instance)
+      namespace, which is identified by the following URI:</p>
+
+      
+<pre class="code">http://apache.org/cocoon/forms/1.0#instance</pre>
+
+      
+<h2>ft:form-template</h2>
+<p>The ft:form-template element is always required; all other ft:*
+        elements should occur inside a ft:form-template element. As described
+        earlier, when the forms transformer encounters the ft:form-template
+        element it will try to look up the form instance object.</p>
+<p>ft:form-template elements may not be nested.</p>
+<p>The ft:form-template will by default copy over all attributes appearing
+        on it, except for one attribute called "location", and it will also take
+        special care of the action attribute.</p>
+<p>The <strong>action</strong> attribute can contain JXPath expressions.
+        As with the JXTemplateGenerator, these JXPath expressions must be embedded
+        inside #{ and }. By allowing the use of JXPath expressions, you can
+        embed dynamic data in the action attribute. One of the most common uses
+        is to embed the continuation id (if you're using flowscript), for example:</p>
+<pre class="code">&lt;ft:form-template action="#{$cocoon/continuation/id}.continue" ...</pre>
+<p>The following objects are available in the JXPath context via the cocoon object: 
+        continuation, requests, session and parameters. The context of the JXPath expression is
+        the map passed on from the flowscript (if any).</p>
+<p>The <strong>location</strong> attribute, if present, is used to retrieve
+        the form instance object. The value of the location attribute should be a
+        JXPath expression, and is executed in the same context as the JXPath
+        expressions embedded in the action attribute.</p>
+<p>For example, if your form object is stored in the session using
+        the key "myform", then following expression in the location attribute
+        can be used to retrieve it:</p>
+<pre class="code">&lt;ft:form-template location="getAttribute($session, 'myform')" ...</pre>
+<p>If you'd like to retrieve the key "myform" from a parameters specified in
+        the sitemap, say one called "sessionattr", then the following can be used:</p>
+<pre class="code">&lt;ft:form-template location="getAttribute($session, getParameter($parameters, 'sessionattr'))" ...</pre>
+<p>As mentioned before, ft:form-template elements cannot be nested, but you can
+        have multiple ft:form-template elements on one page. Together with the location
+        attribute, this can be used to handle multiple forms occuring on one template.</p>
+
+      
+<h2>ft:widget</h2>
+<p>The ft:widget element is replaced by the forms transformer by the XML
+        representation of a widget. Which widget is specified by the id attribute.
+        The ft:widget element can contain a fi:styling element containing parameters
+        to influence the styling process (the XSLT). The forms transformer will simply
+        copy the fi:styling element over to its output.</p>
+<p>For example:</p>
+<pre class="code">&lt;ft:widget id="pass"&gt;
+  &lt;fi:styling type="password"/&gt;
+&lt;ft:widget/&gt;</pre>
+<p>will be replaced by:</p>
+<pre class="code">&lt;fi:field id="pass"&gt;
+  [... label, validation errors, ...]
+  &lt;fi:styling type="password"/&gt;
+&lt;/fi:field&gt;</pre>
+<p>Note: it is not recommended to use the older approach, i.e. without
+        the fi:styling element, anymore, since support for it will be dropped
+        at some point in the future. </p>
+
+      
+<h2>ft:widget-label</h2>
+<p>The ft:widget-label element will be replaced by the forms transformer
+        with the label of a certain widget (specified by an id attribute).
+        The label will not be wrapped in another element.</p>
+
+      
+<h2>ft:continuation-id</h2>
+<p>The ft:continuation-id element will be replaced by the forms transformer by:</p>
+<pre class="code">&lt;fi:continuation-id&gt;
+  ID-of-the current-continuation
+&lt;/fi:continuation-id&gt;</pre>
+<p>This might be useful for embedding the continuation ID in a hidden form field, for example.</p>
+
+      
+<h2>Working with repeaters: ft:repeater-widget, ft:repeater-widget-label, ft:repeater-size</h2>
+<p>The ft:repeater-widget element is similar to the ft:widget element but
+        provides special treatment for repeaters. The content of the ft:repeater-widget
+        element will be used as a template to generate each of the rows of the repeater.</p>
+<p>The ft:repeater-widget-label element is used to retrieve the label of a
+        widget contained by a repeater. It requires two attributes: id (identifying
+        the repeater) and widget-id (identifying the widget in the repeater).</p>
+<p>The ft:repeater-size element inserts an element &lt;fi:repeater-size id="..." size="..."/&gt;
+        containing the size (number of rows) of the repeater.</p>
+<p>For an example of how this all fits together, take a look at the samples included in the forms block.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/meta.xml
new file mode 100644
index 0000000..06cb53a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-template-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/templatetransformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/content_en.html
new file mode 100644
index 0000000..237d5bd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/content_en.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: upload widget</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>This widget allows to upload files by using Cocoon's file upload features.
+      For this reason, this widget won't function properly unless <span class="codefrag">enable-uploads</span>
+      is set to <span class="codefrag">true</span> in <span class="codefrag">WEB-INF/web.xml</span>.</p>
+
+      
+<p>Also, don't forget to put the <strong>enctype</strong> attribute as
+      <span class="codefrag">multipart/form-data</span> in the <strong>ft:form-template</strong>
+      element, inside the template file.</p>
+
+      
+<p>To retrieve the uploaded data, simply use the <span class="codefrag">getValue</span>
+      method of the widget, which will in this case return an object of the
+      following type:</p>
+
+      
+<pre class="code">org.apache.cocoon.servlet.multipart.Part</pre>
+
+      
+<p>The <span class="codefrag">setValue</span> method cannot be used with the upload widget.</p>
+
+      
+<p>The uploaded data will be automatically cleaned up when the upload
+      widget instance object is finialized by the JVM.</p>
+    
+
+    
+<h1>Configuration</h1>
+      
+<pre class="code">&lt;fd:upload id="..." mime-types="text/plain, text/xml" required="true|false"&gt;
+  &lt;fd:label&gt;...&lt;/fd:label&gt;
+  &lt;fd:help&gt;...&lt;/fd:help&gt;
+  &lt;fd:hint&gt;...&lt;/fd:hint&gt;
+&lt;/fd:upload&gt;</pre>
+
+      
+<p>The optional <span class="codefrag">mime-types</span> attribute allows to specify a
+      comma-separated list of mime-types which are accepted. The widget will
+      be invalid if the uploaded type isn't of one of the specified content types.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/meta.xml
new file mode 100644
index 0000000..4aa9b48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-upload-widget/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/widget_upload.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/content_en.html
new file mode 100644
index 0000000..731fe57
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/content_en.html
@@ -0,0 +1,324 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Validation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Concept</h1>
+      
+<p>For each widget you can define a number of widget validators. A
+      widget validator can perform some checks on the widget and if these
+      fail, set a validation error on the widget.</p>
+
+      
+<p>Implementation-wise, a widget validator is an object implementing
+      the <span class="codefrag">WidgetValidator</span> interface
+      (<a class="external" href="http://cocoon.apache.org/2.1/apidocs/org/apache/cocoon/forms/validation/WidgetValidator.html">javadoc</a>).</p>
+
+      
+<p>WidgetValidators can either be defined as part of the form definition
+      (inside the <span class="codefrag">fd:validation</span> element) or added to a widget
+      instance at runtime. The former is useful for validators that only act
+      on the data in the form. The latter is useful if the validation logic
+      needs access to other objects you have available in your controller.</p>
+
+      
+<p>The validation logic runs over the widget tree. For each widget first
+      the child widgets are validated and then the widget itself (recursively).
+      The validators on a widget are executed in the order in which they were
+      defined or added. First the ones defined in the form definition are executed, then
+      the ones added on the widget instance. The validation of a widget stops at the
+      first validator that fails (but continues to execute for the other widgets).</p>
+
+      
+<p>For widgets having a datatype and hence a convertor (field and multivaluefield),
+      the convertor could be considered to be the first validator, i.e. it is executed
+      before the other validators (because those operate on the converted value).
+      If the conversion fails a validation error is set on the widget.</p>
+
+      
+<p>Validation errors can only be set on widgets implementing
+      the interface <span class="codefrag">ValidationErrorAware</span>, which currently is not
+      implemented by all widgets. For example, a repeater widget does not
+      implement ValidationErrorAware. However, a validator attached to
+      a repeater could perform inter-row checks on the fields in the
+      different rows of the repeater, and set validation errors on these
+      fields (instead of on the repeater itself).</p>
+
+      
+<p>CForms supplies a number of default widget validators, mostly for performing
+      checks on the value of field widgets. Additionally you can write your
+      own ones in Java or in Javascript.</p>
+    
+
+    
+<h1>Table of widgets supporting ValidationErrorAware</h1>
+      
+<p>These are the widgets on which you can call <span class="codefrag">setValidationError</span>
+      (and <span class="codefrag">getValidationError</span>). This is relevant if you are writing your
+      own validation logic.</p>
+      
+<table>
+        
+<tr>
+          
+<th colspan="1" rowspan="1">Widget</th>
+          <th colspan="1" rowspan="1">Supports ValidationErrorAware</th>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">field</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">multivaluefield</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">booleanfield</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">repeater</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">output</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">submit</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">action</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">repeater-action</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">row-action</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">aggregatefield</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">upload</td>
+          <td colspan="1" rowspan="1"><img alt="yes" src="images/yes_mark.png"></td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">messages</td>
+          <td colspan="1" rowspan="1"></td>
+        
+</tr>
+      
+</table>
+    
+
+    
+<h1>Reference</h1>
+      
+<h2>General remarks</h2>
+<p>For most widget validators, the failmessage (i.e. the message displayed
+        to the user in case the validation failed) can be overridden by specifying
+        a child <strong>fd:failmessage</strong> element inside the validator element. The
+        failmessage can contain mixed content. Example:</p>
+<pre class="code">&lt;fd:field id="yourmail"&gt;
+  &lt;fd:datatype base="string"/&gt;
+  &lt;fd:validation&gt;
+    &lt;fd:email&gt;
+      &lt;fd:failmessage&gt;Not a valid email address!&lt;/fd:failmessage&gt;
+    &lt;/fd:email&gt;
+  &lt;/fd:validation&gt;
+&lt;/fd:field&gt;</pre>
+<p>To provide locale-dependent messages, use i18n tags in
+        combination with the I18nTransformer.</p>
+<p>Often the values that validators will check are specified as
+        expressions. CForms uses for this the <a class="external" href="http://cocoondev.org/xreporter/docs/core/91.html">xReporter expression interpreter</a>.</p>
+<p>Note that you cannot use each validator with each widget. Most validators
+        only work with certain types of widgets, in case of field widgets
+        often expecting a specific datatype. The below table shows the supported combinations
+        for the default validators.</p>
+<table>
+          
+<tr>
+            
+<th colspan="1" rowspan="1">Validator</th>
+            <th colspan="1" rowspan="1">Allowed datatypes</th>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:assert</td>
+            <td colspan="1" rowspan="1">all datatypes</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:email</td>
+            <td colspan="1" rowspan="1">string</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:length</td>
+            <td colspan="1" rowspan="1">string</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:mod10</td>
+            <td colspan="1" rowspan="1">string</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:range</td>
+            <td colspan="1" rowspan="1">integer, long, decimal</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:regexp</td>
+            <td colspan="1" rowspan="1">string</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fd:value-count</td>
+            <td colspan="1" rowspan="1">all array types (use this with multivaluefield)</td>
+          
+</tr>
+        
+</table>
+
+      
+<h2>fd:assert</h2>
+<p>Evaluates the expression specified in the "test" attribute. This expression
+        should have a boolean result, it should evaluate to either true or false.
+        Example: Suppose there are 2 fields widgets <span class="codefrag">password</span> and <span class="codefrag">confirmPassword</span>.
+        We can use assert inside <span class="codefrag">confirmPassword</span> to check if is equals to <span class="codefrag">password</span> widget:</p>
+<pre class="code">&lt;fd:assert test="password = confirmPassword"&gt;
+  &lt;fd:failmessage&gt;The two passwords are not equal.&lt;/fd:failmessage&gt;
+&lt;/fd:assert&gt;</pre>
+
+      
+<h2>fd:email</h2>
+<p>Checks that a value is a valid email address. Example:</p>
+<pre class="code">&lt;fd:email/&gt;</pre>
+<p>Currently this checks the email does not contain any spaces,
+        contains exactly one <span class="codefrag">@</span> symbol with at least one character
+        before it and at least one dot after it.</p>
+
+      
+<h2>fd:length</h2>
+<p>Checks the length of strings. This validator can take 3 attributes:
+        min, max and exact. You can use either of these three separately or
+        min and max together. The values of these attributes are expressions. Example:</p>
+<pre class="code">&lt;fd:length min="2" max="4"/&gt;
+
+Another example:
+
+&lt;fd:length exact="2*2"&gt;
+   &lt;fd:failmessage&gt;Must be 4 characters long!&lt;/fd:failmessage&gt;
+&lt;/fd:length&gt;</pre>
+
+      
+<h2>fd:mod10</h2>
+<p>Uses the "mod10" algorithm used to check the validity of credit card
+        numbers such as VISA. This validator does not require any additional
+        attributes. Example:</p>
+<pre class="code">&lt;fd:mod10&gt;
+   &lt;fd:failmessage&gt;Invalid credit card number.&lt;/fd:failmessage&gt;
+&lt;/fd:mod10&gt;</pre>
+
+      
+<h2>fd:range</h2>
+<p>Checks the numeric range. This validator can take 3 attributes:
+        min, max and exact. You can use either of these three separately or
+        min and max together. The values of these attributes are expressions. Example:</p>
+<pre class="code">&lt;fd:range min="2" max="4"/&gt;
+
+Another example:
+
+&lt;fd:range exact="2*2"/&gt;</pre>
+
+      
+<h2>fd:regexp</h2>
+<p>Checks that a string matches a regular expression. It requires a "pattern"
+        attribute specifying the regexp. The regular expression library used is
+        Jakarta ORO, see <a class="external" href="http://jakarta.apache.org/oro/api/org/apache/oro/text/regex/package-summary.html">here</a> for some information. Example:</p>
+<pre class="code">&lt;fd:regexp pattern="[a-z]{3,5}"&gt;
+   &lt;fd:failmessage&gt;Invalid code!&lt;/fd:failmessage&gt;
+&lt;/fd:regexp&gt;</pre>
+
+      
+<h2>fd:value-count</h2>
+<p>Checks the number of items selected in a multivaluefield.
+        Again works with min, max and exact attributes. Example:</p>
+<pre class="code">&lt;fd:value-count min="2" max="4"/&gt;
+
+Another example:
+
+&lt;fd:value-count exact="2"/&gt;</pre>
+
+      
+<h2>fd:javascript</h2>
+<p>Allows to write a validator using Javascript, embedded directly in the
+        form definition. The widget in question is available in the Javascript
+        snippet as a variable called <span class="codefrag">widget</span>.</p>
+<p>Checkout the samples of Cocoon for an example.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/meta.xml
new file mode 100644
index 0000000..5a08699
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-validation/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/validation.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/content_en.html
new file mode 100644
index 0000000..8bd0e67
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/content_en.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: XSLT</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Intro</h1>
+      
+<p>This page contains information on the default XSLT's provided by CForms,
+      and the fi:styling directives they support. Be sure to read first about
+      the <a href="templatetransformer.html">template transformer</a>.</p>
+
+      
+<p>There are basically 3 XSLTs:</p>
+
+      
+<ul>
+        
+<li>
+<span class="codefrag">forms-samples-styling.xsl</span>: this stylesheet includes two
+        stylesheets: one for widget styling, one for page styling. You can choose
+        between the basic types of it or advanced stylings. Usually, you will
+        make a clone of this stylesheet for your own project, and use the other
+        stylesheets as is.</li>
+        
+<li>
+<span class="codefrag">forms-field-styling.xsl</span>: contains templates that style
+        individual widgets, i.e. templates that translate fi:field, fi:booleanfield
+        fi:action, etc. to HTML.</li>
+        
+<li>
+<span class="codefrag">forms-page-styling.xsl</span>: contains templates for building high-level
+        page layout effects, such as tabbed panes.</li>
+      
+</ul>
+
+      
+<p>Additionally there are 2 XSLTs for advanced widget styling:</p>
+
+      
+<ul>
+        
+<li>
+<span class="codefrag">forms-advanced-field-styling.xsl</span>: contains templates that
+        provide advanced styling of fields, e.g. the "double-listbox" for a
+        multivaluefield. It's indeed an extension of the above basic <span class="codefrag">forms-field-styling.xsl</span>.
+        Furthermore it includes the next stylesheet.</li>
+        
+<li>
+<span class="codefrag">forms-calendar-styling.xsl</span>: contains the styling of a
+        field with type "date" and provides a visual calendar for easy selection
+        of date. So the calendar is an advanced styling too, but because it has
+        much specific stuff we separated it out of <span class="codefrag">forms-advanced-styling.xsl</span>.</li>
+      
+</ul>
+
+      
+<p>From the sitemap you only need to reference the first one, for example as follows:</p>
+
+      
+<pre class="code">&lt;map:transform src="context://samples/forms/resources/forms-samples-styling.xsl"/&gt;</pre>
+    
+
+    
+<h1>fi:styling options</h1>
+      
+<h2>fi:field (without selection list)</h2>
+<p>By default all attributes on the fi:styling element will be copied
+        onto the resulting HTML &lt;input&gt; element. Thus you can put e.g. type,
+        class, style and size attributes on it. For example:</p>
+<pre class="code">&lt;ft:widget id="myfield"&gt;
+  &lt;fi:styling size="50" class="kinky"/&gt;
+&lt;/ft:widget&gt;</pre>
+<p>Some values for the type attribute will cause special effects:</p>
+<ul>
+          
+<li>
+<strong>type="textarea"</strong>: creates a &lt;textarea&gt; instead of an &lt;input&gt; element</li>
+          
+<li>
+<strong>type="htmlarea"</strong>: creates a &lt;textarea&gt; instead of an &lt;input&gt; element,
+          adding support for WYSIWYG editing of HTML using HTMLArea (works with IE 5.5+ under Windows
+          and Mozilla 1.3+, any platform)</li>
+          
+<li>
+<strong>type="output"</strong>: outputs the field's value as uneditable text</li>
+        
+</ul>
+<p>Adding an attribute <strong>submit-on-change="true"</strong> on fi:styling will cause
+        an automatic form submit when the field's value changes.</p>
+
+      
+<h2>fi:field (with selection list)</h2>
+<p>By default, a field with a selection list is rendered as a dropdown box.</p>
+<p>Adding an attribute <strong>list-type="radio"</strong> on fi:styling
+        produces a vertical list of radio buttons instead. Add list-orientation="horizontal"
+        to have a horizontal list of radio buttons.</p>
+<p>Adding an attribute <strong>list-type="listbox"</strong> on fi:styling produces a selection list,
+        use the attribute list-size to specify its size (default 5).</p>
+
+      
+<h2>fi:action</h2>
+<p>By default, creates an &lt;input&gt; of type submit, thus showing a standard button.
+        To have an image button instead, try this:</p>
+<pre class="code">&lt;fi:styling type="image" src="blah.gif"&gt;</pre>
+
+      
+<h2>Other widgets</h2>
+<p>Not yet documented here, but don't be afraid to look at the source of the XSLT's.</p>
+    
+
+    
+<h1>High-level styling with fi:group</h1>
+      
+<p>No documentation yet, checkout the samples and the source of forms-page-styling.xsl.</p>
+
+      
+<p>For storing the state of a tab or choice selection server-side just add a field to
+      the form definition that shall hold this value:</p>
+
+      
+<pre class="code">&lt;fd:field id="state"&gt;
+  &lt;fd:datatype base="integer"/&gt;
+&lt;/fd:field&gt;</pre>
+
+      
+<p>Bind this value to whatever you want. In the form template you need then following code:</p>
+
+      
+<pre class="code">&lt;fi:group&gt;
+  &lt;fi:styling type="choice"/&gt;
+  &lt;fi:state&gt;
+    &lt;ft:widget id="state"/&gt; &lt;!-- refering to the above defined field --&gt;
+  &lt;/fi:state&gt;
+  &lt;fi:items&gt;
+    ...
+  &lt;/fi:items&gt;
+&lt;/fi:group&gt;</pre>
+    
+
+    
+<h1>Miscellaneous</h1>
+      
+<h2>fi:validation-errors</h2>
+<p>The <span class="codefrag">fi:validation-errors</span> tag is used to display all validation
+        errors of all widgets in a form at one location, i.e. a the top of the form.</p>
+<p>The fi:validation-errors tag must be a child of a ft:form-template element.</p>
+<p>You can customise a message to be shown before and after the errors by adding
+        a child header and/or footer element:</p>
+<pre class="code">&lt;fi:validation-errors&gt;
+  &lt;header&gt;&lt;p&gt;Correct these errors please:&lt;/p&gt;&lt;/header&gt;
+  &lt;footer&gt;&lt;p&gt;And then resubmit the form.&lt;/p&gt;&lt;/footer&gt;
+&lt;/fi:validation-errors&gt;</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/meta.xml
new file mode 100644
index 0000000..c8baab6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms-xslt/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/xslt.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/content_en.html
new file mode 100644
index 0000000..8e0b18c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/content_en.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Forms: Introduction</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Apache Cocoon Team" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>Cocoon has an advanced form framework. It is simply called
+      "Forms" or "Cocoon Forms", but mostly referred to as <strong>CForms</strong>.
+      Previously it was called "Woody".</p>
+
+      
+<p>Combined with other Cocoon technologies, such as flowscript and
+      the JXTemplate generator, this provides a solid basis for
+      building webapplications in Cocoon.</p>
+
+      
+<div class="note">
+<strong>WARNING:</strong> CForms is still under development.
+        We are currently working towards its first stable release.</div>
+
+      
+<p>CForms aims to be powerful enough to handle complex use cases
+      while still being simple enough to be used by non-Java-programmers
+      who want to add a form to their site.</p>
+
+      
+<p>Essentially to create a form with CForms you need to define two
+      things:</p>
+
+      
+<ul>
+        
+<li>the form model</li>
+        
+<li>the form template</li>
+      
+</ul>
+
+      
+<p>The form model is defined by a <strong>form definition</strong>. This is
+      an XML file describing the structure of the form, by declaring
+      the widgets it consists of. This file doesn't contain any
+      presentational information. Based on the form definition,
+      a <strong>form instance</strong> can be created. This is a specific instance
+      of the form that will hold actual data. The form defintion
+      is to the form instance what a Java class is to a Java object,
+      or what an XML Schema is to an XML document.</p>
+
+      
+<p>Since the form definition is simply described in an XML file,
+      this means you can create forms without any knowledge of Java.
+      Unlike some other form frameworks, you don't need to write
+      Java classes to hold form data.</p>
+
+      
+<p>As stated before, a form consists of a number of widgets.
+      A <strong>widget</strong> is an object that knows how to read its state from
+      a Request object, how to validate itself, and can generate
+      an XML representation of itself. A widget can remember its
+      state itself, so unlike e.g. Struts, you do not have to write a
+      form bean for that purpose. A widget can hold strongly
+      typed data. For example, you can indicate that a field should
+      contain a date. If you do this, you can be assured that after
+      the form is successfully validated, and you retrieve its value,
+      you will get a Date object. So your own business logic doesn't
+      need to care about converting strings to other types,
+      and all the locale and formatting related issues of this.</p>
+
+      
+<p>CForms contains a flexible set of widgets that should cover
+      most needs. However like everything in CForms, you can add
+      new ones of your own. One special widget is the repeater widget,
+      which "repeats" a number of other widgets multiple times,
+      as is needed to generate table-like structures. Widgets can
+      thus have child widgets, so a form instance is effectively a
+      <strong>widget tree</strong>.</p>
+
+      
+<p>The presentation of the form is (usually) handled by a form template.
+      The form themplate is an XML file (e.g. an XHTML file, but this could be
+      any markup) and on the places you want a widget to appear, you
+      insert a special tag referencing that widget. After processing by
+      the Forms Template Transformer, these tags will be replaced by the
+      XML representation of the widget, which contains all state information
+      of the widget (its value, validation errors, ...). These bits of XML
+      can then be transformed to plain HTML by an XSLT. Note that this XSLT
+      only has to know how to style certain kinds of widgets, but not
+      individual widget instances itself. Thus one template in this XSLT can
+      style all widgets of a certain type that appear on all forms you might have.
+      Cocoon includes a flexible, configurable XSLT that covers most needs.</p>
+
+      
+<p>Below a typical scenario is described to explain how things fit together:</p>
+
+      
+<div align="center">
+<img class="figure" alt="Overview of CForms" src="images/forms_schema.png"></div>
+
+      
+<ul>
+        
+<li>Initially, the controller logic asks the FormManager component
+        to create a form instance based on a form definition (form definitions
+        are cached, so creating an instance is very fast).</li>
+        
+<li>The controller can then optionally pre-populate this form object
+        with some data. To fill the form with data from a bean or XML document,
+        a binding framework is available.</li>
+        
+<li>Then the form is shown by calling a pipeline.</li>
+        
+<li>When the form is submitted, the controller will let the form
+        instance object process the request, so that all widgets can read
+        their value from the request. Some might generate events, which will
+        be handled by event handlers. Validation of the widget tree is also
+        triggered, whereby all widgets will validate themselves based on
+        widget validators described in the form definition. The controller
+        can afterwards perform application-specific validation logic.</li>
+        
+<li>If there were validation errors, the form will be redisplayed.
+        Otherwise the controller will decide what's the next step, for
+        example saving the form data back to a bean or calling some backend
+        process using data from the form.</li>
+      
+</ul>
+
+      
+<p>
+<strong>Next step:</strong> have a look at a <a href="sample.html">concrete sample</a>
+        to get a feel for how things work.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/meta.xml
new file mode 100644
index 0000000..c854f81
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cforms/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/forms/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/content_en.html
new file mode 100644
index 0000000..27af2e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/content_en.html
@@ -0,0 +1,206 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>History of Changes</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+</head>
+<body>
+<p>
+<a href="changes.rss"><img alt="RSS" src="images/rss.png"></a>
+</p>
+  
+<devs>
+    <!-- in strict alphabetical order -->
+    
+<person email="nicolaken@apache.org">
+<a name="NKB"></a>
+</person>
+    
+<person email="crossley@apache.org">
+<a name="DC"></a>
+</person>
+    
+<person email="tcurdt@apache.org">
+<a name="TC"></a>
+</person>
+    
+<person email="huber@apache.org">
+<a name="BH"></a>
+</person>
+    
+<person email="ivelin@apache.org">
+<a name="IAI"></a>
+</person>
+    
+<person email="shannon@apache.org">
+<a name="DS"></a>
+</person>
+  
+</devs>
+  
+<h1>Version 2.1 (March 17 2004)</h1>
+<ul>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      New How-To: i18n within the XMLForm Framework
+    (DS) Thanks to <a href="mailto:m.refaey.at.imkenberg.de">Mohamed El-Refaey</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      New tutorial:
+      <a href="../tutorial/tutorial-generator.html">Write a Custom Generator</a>
+    (DC) Thanks to <a href="mailto:javageoff.at.yahoo.com">Geoff Howard</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added documentation for the WebServiceProxyGenerator component.
+      Explains how to implement Web Syndication.
+    (IAI) Thanks to <a href="mailto:ivelin.at.apache.org">Ivelin Ivanov</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added WSDL descriptor and a REST style resource version
+      of the XMLForm demo.
+    (IAI) Thanks to <a href="mailto:ivelin.at.apache.org">Ivelin Ivanov</a>.</li>
+<li>
+<img class="icon" alt="remove" src="images/remove.jpg">
+      removed XMLForm and JXForms
+    (TC)</li>
+</ul>
+  
+<h1>Version 2.0.3 (July 15 2002)</h1>
+<ul>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Encourage people to help with the mending broken links.
+      Added a
+      <a href="linkstatus.html">linkstatus</a> document describing some
+      tools.
+    (DC)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added section to the 
+      <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">Mailing Lists</a> document to describe
+      the new <span class="codefrag">cocoon-docs</span> mailing list.
+    (DC)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Established the new <span class="codefrag">cocoon-docs</span> mailing list.
+    (NKB)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new How-To for HTML-PDF Publishing.
+    (DS) Thanks to <a href="mailto:bdelacretaz.at.codeconsult.ch">Betrand Delacretaz</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new How-To for Authoring Core Docs.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new How-To for PaginatorTransformer.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added simple user documentation of LinkStatus Generator.
+    (BH)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Encourage people to help with the refactoring of Cocoon samples.
+      Provide a <a href="samples.html">refactoring guidelines</a> document.
+    (DC)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added overview documentation for XMLForm Handling
+    (DC) Thanks to <a href="mailto:andrew.at.luminas.co.uk">Andrew Savory</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      New <a href="../snippet/index.html">Snippet</a> section added, along
+      with first <a href="../snippet/snippet-internal-pipeline.html">Snippet</a>
+      and <a href="../howto/howto-author-snippet.html">Snippet How-To</a>.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added additional FAQs pages: <a href="../faq/faq-actions.html">Actions</a>,
+      <a href="../faq/faq-aggregators.html">Aggregators</a>, and
+      <a href="../faq/faq-xsp.html">XSP</a>.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added Heidi Brannan's new XMLForm's How-To.
+    (IAI) Thanks to <a href="mailto:heidi.at.wkwyw.net">Heidi Brannan</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new draft <a href="../howto/howto-patch.html">How to Prepare a Patch</a>.
+    (DC)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new draft <a href="../howto/howto-bugzilla.html">How to
+      Contribute a Patch via Bugzilla</a>.
+    (DC)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added Tutorial section. Moved existing tutorial to new location. Added
+      draft tutorial contribution.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added <a href="../howto/index.html">How-To section</a>.
+      Added new How to author How-To and FAQ articles.
+    (DS)</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Added new <a class="external" href="http://cocoon.apache.org/link/index.html">Cocoon Links</a> section
+      with a collection of links to various external sources.
+    (DC) Thanks to <a href="mailto:e9625392.at.student.tuwien.ac.at">Andreas Hochsteger</a>. Fixes <a class="external" href="http://issues.apache.org/bugzilla/buglist.cgi?bug_id=8989">8989</a>.</li>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Started new documents for <a href="todo-doc.html">Documentation To Do List</a> and
+      <a href="changes-doc.html">Documentation History of Changes</a>.
+    (DC)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Updated and refactored some planning docs.
+    (DS)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+   Edited <a href="../userdocs/matchers/matchers.html">Matchers</a>, 
+   <a href="../userdocs/selectors/selectors.html">Selectors</a>, and a number of other
+   user guide doc files to address grammar, typos, and general Global English issues.
+    (DS)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Added stylesheet, src/documentation/stylesheets/faqcommon.xsl, which places two
+      FAQs at the bottom of every FAQs topic page. FAQs added include
+      "How can I add my FAQ to this document" and "How can I suggest
+      improvements to existing FAQs".
+    (DS)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Added five additional <a href="../faq/index.html">FAQ categories</a> and pages.
+      Pulled useful FAQ content from various locations within existing docs and sitemap files.
+      Provided "gateway links" to additional site documentation.
+    (DS)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Added new <a href="../faq/index.html">FAQ categories</a>.
+      Restructured FAQ content to facilitate user contributions via patches.
+    (DS)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Reviewed the <a href="linkalarm-readme.txt">LinkAlarm report</a>
+      and fixed some broken links.
+    (DC)</li>
+<li>
+<img class="icon" alt="update" src="images/update.jpg">
+      Added many entries to the new To Do List.
+    (DS)</li>
+</ul>
+  
+<h1>Version 2.0.2 (March 26 2002)</h1>
+<ul>
+<li>
+<img class="icon" alt="add" src="images/add.jpg">
+      Commenced discussion and planning for a Documentation Project.
+    (DS)</li>
+</ul>
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/meta.xml
new file mode 100644
index 0000000..1b0bca6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-changes/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/changes-doc.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/content_en.html
new file mode 100644
index 0000000..24de36b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/content_en.html
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+  <head>
+    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>CInclude Transformer</title>
+    <link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+    <meta content="Carsten Ziegeler" name="DC.Creator">
+    <meta content="This document describes the CInclude Transformer." name="DC.Description">
+  </head>
+  <body>
+
+    <font color="red"><b>SEE 2.1 DOCS FOR UP-TO-DATE VERSION</b></font>
+
+    <h1>CInclude Transformer</h1>
+
+    <p>This transformer includes XML in the current stream and acts therefore
+      as a kind of (dynamic) content aggregation. Two forms are supported by
+      the transformer: one verbose and flexible approach, and a simple approach.
+      We will first discuss the simple approach and
+      the more flexible is mentioned in the next chapter. In addition
+      the cinclude transformer provides a caching mechanism (for the
+      simple include form).</p>
+
+    <p>This transformer triggers for the element <span class="codefrag">include</span> in the
+    namespace "http://apache.org/cocoon/include/1.0".
+    The <span class="codefrag">src</span> attribute contains the url which points to
+    an xml resource which is included instead of the element.
+    With the attributes <span class="codefrag">element</span>, <span class="codefrag">ns</span> and
+    <span class="codefrag">prefix</span> it is possible to specify an element
+    which surrounds the included content.
+    </p>
+
+<ul>
+<li>Name : cinclude</li>
+<li>Class: org.apache.cocoon.transformation.CIncludeTransformer</li>
+<li>Cacheable: no.</li>
+</ul>
+
+   <p>
+    A simple example might help to use the CIncludeTransfomer effectively:
+   </p>
+
+   <p>
+    Add the CIncludeTransformer to the components in your sitemap.xmap
+   </p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:transformers default="xslt"&gt;
+  ...
+    &lt;map:transformer name="cinclude"
+      src="org.apache.cocoon.transformation.CIncludeTransformer"/&gt;
+  ...
+</pre>
+
+   <p>
+     Next define in your pipeline to use the CIncludeTransformer
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="cinc/simple-cinc"&gt;
+  &lt;map:generate src="cinc/simple-cinc.xml"/&gt;
+  &lt;map:transform type="cinclude"/&gt;
+  &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+   <p>
+    In this example pipeline it assumed that simple-cinc.xml contains
+    the include element. Beside defining the include element
+    it defines the namespace URI "http://apache.org/cocoon/include/1.0".
+    This helps the CIncludeTransformer to find the tag to get replaced by
+    the xml content referenced via the src attribute.
+    The simple-cinc.xml may look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page
+  xmlns:cinclude="http://apache.org/cocoon/include/1.0"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+    &lt;cinclude:include src="include.xml" element="included"/&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+
+   <p>
+    Next you should define the include.xml file which is included.
+    A simple include.xml might look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;p&gt;
+ I am &lt;strong&gt;included&lt;/strong&gt; by CIncludeTransformer.
+ I come from "include.xml".
+&lt;/p&gt;
+</pre>
+
+   <p>
+    Now finally we have everything put together the xml content after the
+    CIncludeTransformer processing will look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page
+  xmlns:cinclude="http://apache.org/cocoon/include/1.0"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+    &lt;included&gt;
+      &lt;p&gt;
+        I am &lt;strong&gt;included&lt;/strong&gt; by CIncludeTransformer.
+        I come from "include.xml".
+      &lt;/p&gt;
+    &lt;/included&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+
+<h1>Including External XML (simple)</h1>
+
+<p>One feature of the cinclude transformer (this is currently not
+         supported by the caching cinclude transformer) is including XML from
+       external sources, e.g. files or from an HTTP server.
+       The <span class="codefrag">cinclude:includexml</span> tag starts including of XML:</p>
+
+<pre class="code">
+&lt;cinclude:includexml&gt;  &lt;!-- Include XML from HTTP server --&gt;
+     &lt;cinclude:src&gt;http://external.news.com/flashnews.xml&lt;/cinclude:src&gt;
+&lt;/cinclude:includexml&gt;
+</pre>
+
+<p> This would be a simple way of "get"ting XML data from an
+       external site. Using this method it is also possible to pass parameters in the
+       url - just as you would in a "get" sent from a browser.</p>
+
+<pre class="code">
+&lt;cinclude:includexml&gt;  &lt;!-- Include XML from HTTP server --&gt;
+    &lt;cinclude:src&gt;http://external.news.com/flashnews.xml?id=1234&amp;myname=matthew&lt;/cinclude:src&gt;
+&lt;/cinclude:includexml&gt;
+</pre>
+
+<p>If the external XML is not valid or not available, the
+       transformer signals an error to the pipeline and the document containing the
+       include command is not available.</p>
+
+<p>For this purpose the <span class="codefrag">ignoreErrors</span> attribute can be
+       used:</p>
+
+<pre class="code">
+&lt;cinclude:includexml ignoreErrors="true"&gt;
+...
+&lt;/cinclude:includexml&gt;</pre>
+
+
+<h1>Including External XML (advanced)</h1>
+
+<p>The above section shows you how to include XML data from an
+       external source such as an HTTP server using the simple "get" method supplied
+       in the HTTP protocol. For more advanced uses you will wish to be able to send
+       "Post" or other HTTP methods to the server. In addition you may want to
+       actually send XML data to the server - just as you would using an HTML form.
+       The format of this resource is slightly more complicated:</p>
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;data xmlns:cinclude="http://apache.org/cocoon/include/1.0"&gt;
+&lt;cinclude:includexml&gt;
+    &lt;cinclude:src&gt;http://itsunshine/tamino/blah&lt;/cinclude:src&gt;
+    &lt;cinclude:configuration&gt;
+  &lt;cinclude:parameter&gt;
+    &lt;cinclude:name&gt;method&lt;/cinclude:name&gt;
+    &lt;cinclude:value&gt;POST&lt;/cinclude:value&gt;
+  &lt;/cinclude:parameter&gt;
+    &lt;/cinclude:configuration&gt;
+    &lt;cinclude:parameters&gt;
+      &lt;cinclude:parameter&gt;
+    &lt;cinclude:name&gt;message&lt;/cinclude:name&gt;
+    &lt;cinclude:value&gt;Hi there&lt;/cinclude:value&gt;
+  &lt;/cinclude:parameter&gt;
+  &lt;cinclude:parameter&gt;
+    &lt;cinclude:name&gt;_Process&lt;/cinclude:name&gt;
+    &lt;cinclude:value&gt;&lt;name&gt;matti&lt;/name&gt;&lt;age&gt;36&lt;/age&gt;&lt;/cinclude:value&gt;
+  &lt;/cinclude:parameter&gt;
+    &lt;/cinclude:parameters&gt;
+&lt;/cinclude:includexml&gt;
+&lt;/data&gt;
+    </pre>
+
+<p>Lets look at the tags. The tag <span class="codefrag">cinclude:src</span> defines the address of the
+       resource we want to access and then comes a list of (optional)
+       connection-specific parameters (enclosed in the <span class="codefrag">cinclude:configuration</span> tag).
+       In this example the HTTP-method ("POST") is passed into the connection. The
+       format of these parameters is discussed next.</p>
+
+<p>Then comes the list of parameters we wish to pass into the
+       function. Each parameter defined has a name and a value. The value can either
+       be text or XML.</p>
+
+<p>The format of the parameters is the same as for the connection
+       configuration.</p>
+
+
+<h1>Caching</h1>
+
+<p>This transformer includes XML in the current stream and acts therefore
+      as a kind of (dynamic) content aggregation. However, the included content
+      might be very big or either it might take a lot of time to fetch
+      the content. If, in those cases, your content does not change too
+      frequently, you can turn on caching for these contents.</p>
+
+<p>
+    To turn on caching, this transformer triggers for the element <span class="codefrag">cached-include</span>
+    in the namespace "http://apache.org/cocoon/include/1.0/caching".
+    The <span class="codefrag">src</span> attribute contains the url which points to
+    an xml resource that is included instead of the element.
+    It is possible to mix the <span class="codefrag">cached-include</span> and the <span class="codefrag">include</span>
+    element, so only parts are cached and others are not.
+   </p>
+
+<p>
+    A simple example might help to use the caching effectively:
+   </p>
+
+<p>
+     First define your pipeline to use the CIncludeTransformer with
+     caching turned on; you turn on caching by setting the <span class="codefrag">expires</span>
+     parameter to a value greater than 0. The exact meaning of this
+     parameter is explained below.
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="cinc/simple-cinc"&gt;
+  &lt;map:generate src="cinc/simple-cinc.xml"/&gt;
+  &lt;map:transform type="cinclude"&gt;
+      &lt;map:parameter name="expires" value="600"/&gt;
+  &lt;/map:transform&gt;
+  &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+
+<p>
+    In this example-pipeline it is assumed that simple-cinc.xml contains
+    the <span class="codefrag">cached-include</span> element. Beside defining the element
+    it uses the namespace URI "http://apache.org/cocoon/include/1.0".
+    This helps the transformer to find the tag to get replaced by
+    the xml content referenced via the src attribute.
+    The simple-cinc.xml may look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page
+  xmlns:cinclude="http://apache.org/cocoon/include/1.0"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+    &lt;cinclude:cached-include src="http://server/document1.xml"/&gt;
+    &lt;cinclude:cached-include src="http://server/document2.xml"/&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+
+
+<p>
+    Now finally we have everything put together the xml content after the
+    CIncludeTransformer processing will look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page
+  xmlns:cinclude="http://apache.org/cocoon/include/1.0"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+    &lt;document1&gt;
+        CONTENT OF document 1
+    &lt;/document1&gt;
+    &lt;document2&gt;
+        CONTENT OF document 2
+    &lt;/document2&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+
+<p>So, of course even with caching turned on, this transformer acts like the
+  usual cinclude transformer. But as you can see from the example above, you
+  can define an expires value. The fetched content is cached for the duration of
+  this value; in the example above the content is cached for 10 minutes. So, if
+  during the next 10 minutes after the first time this pipeline was processed,
+  someone else requests this pipeline, the content is not fetched again from a
+  distant server (or whereever the content is stored). It is directly delivered
+  from the cache. When the 10 minutes have expired, the next time the pipeline
+  is requested, the content is fetched again and stored in the cache for the
+  next 10 minutes.</p>
+
+<p>You can fine tune the behaviour of the transformer with several parameters.</p>
+
+<p>The <span class="codefrag">expires</span> parameter defines the expiration date of the
+    content in seconds from the time the pipeline is requested.</p>
+
+<p>Usually the content is cached in the common store, but you
+   can also define a writeable/modifiable source with the "source" parameter,
+ e.g. "file:/c:/temp". Then the cached content is written into this
+ directory.</p>
+
+<p>With the optional <span class="codefrag">purge</span> set to <span class="codefrag">true</span>
+  the cache is purged which means the cached content is regarded as
+  invalid nevertheless if it has expired or not.</p>
+
+<p>With the optional parameter <span class="codefrag">parallel</span> the various
+  included contents are processed (included) in parallel rather than
+  in a series.</p>
+
+<p>With the optional parameter <span class="codefrag">preemptive</span> set to <span class="codefrag">true</span>
+  a pre-emptive caching is activated. When a resource is requested with
+  pre-emptive caching, this transformer always attempts to get the
+  content from the cache. If the content is not in the cache, it is
+  of course retrieved from the original source and cached.
+  If the cached resource has expired, it is still provided. The cache
+  is updated by a background task. This task has to be started
+  beforehand.</p>
+
+<p>
+     Complete Example:
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="cinc/simple-cinc"&gt;
+  &lt;map:generate src="cinc/simple-cinc.xml"/&gt;
+  &lt;map:transform type="cinclude"&gt;
+      &lt;map:parameter name="expires" value="600"/&gt;
+      &lt;map:parameter name="purge" value="false"/&gt;
+      &lt;map:parameter name="parallel" value="true"/&gt;
+      &lt;map:parameter name="preemptive" value="false"/&gt;
+      &lt;map:parameter name="source" value="file:/c:/temp"/&gt;
+  &lt;/map:transform&gt;
+  &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+
+<h1>Configuration</h1>
+
+<p>Besides the usual transformer configuration, this transformer requires some components.
+You have to add the following lines to the cocoon.xconf:</p>
+
+<pre class="code">
+ &lt;component class="org.apache.cocoon.transformation.helpers.DefaultIncludeCacheManager"
+            role="org.apache.cocoon.transformation.helpers.IncludeCacheManager"
+            logger="test"&gt;
+    &lt;!-- Specify this only if you use preemptive-caching --&gt;
+    &lt;parameter name="preemptive-loader-url" value="http://localhost:8080/cocoon/loader"/&gt;
+ &lt;/component&gt;
+</pre>
+
+<p>If you want to use preemptive caching, you have to specify a URI inside Cocoon that contains
+     the preemptive-loader action. This pipeline is automatically called, when
+     preemptive loading is actived and requried. It loads the content in the background.</p>
+
+<p>First you have to define the action:</p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:actions&gt;
+  ...
+      &lt;map:action name="preemptive"
+                  src="org.apache.cocoon.transformation.helpers.PreemptiveLoaderAction"/&gt;
+  ...
+</pre>
+
+<p>Then you must define a pipeline containing the action. This is the pipeline that
+   has to be configured in the cocoon.xconf:</p>
+
+<pre class="code">
+   &lt;map:match pattern="loader"&gt;
+       &lt;map:act type="preemptive"&gt;&lt;/map:act&gt;
+   &lt;/map:match&gt;
+</pre>
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/meta.xml
new file mode 100644
index 0000000..2a355d8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cinclude-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/cinclude-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/content_en.html
new file mode 100644
index 0000000..333821a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/content_en.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Offline Page Generation with the Command Line Interface</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document explains how to use the Cocoon Command Line Interface for offline page and site generation." name="DC.Description">
+</head>
+<body>
+    
+<h1>Overview</h1>
+      
+<p>The Command Line Interface provides access to Cocoon's offline generation capabilities.</p>
+      
+<p>This page gives details of how configure and use the CLI. Details of the concepts behind
+         offline page generation are given on the offline generation 
+         <a href="index.html">overview</a> page.</p>
+    
+    
+<h1>Invoking the CLI</h1>
+      
+<p>The CLI can be invoked from the command line. Change to the root directory of your 
+         Cocoon distribution, and then, on Unix use: <span class="codefrag">./cocoon.sh cli &lt;parameters&gt;</span> 
+         and on Windows use <span class="codefrag">cocoon.bat cli &lt;parameters&gt;</span>
+</p>
+      
+<p>The relevant parameters are detailed in the following sections.</p>
+    
+    
+<h1>Configuring the CLI</h1>
+      
+<p>The CLI has two methods of configuration, with an <span class="codefrag">xconf</span> file, and using 
+         command line parameters.</p>
+      
+<p>The <span class="codefrag">xconf</span> method is the newer, and gives access to a wider range of 
+         features, and is thus explained first.</p>
+      
+<div class="note">Whilst the xconf method provides access to more features, the command line 
+            parameter method is more stable, as there are currently plans to improve
+            the xconf format to allow greater flexibility. If you require a stable and
+            consistent method for accessing the CLI, it is recommended that you use the 
+            command line parameter method.</div>
+
+<p>Copy <code>$COCOON/lib/optional/servlet-2_3.jar</code> to your lib directory
+  (for example, WEB-INF/lib).</p>
+      
+<h2>Using an Xconf file</h2>
+<p>To start the CLI using an xconf file, on Unix do <span class="codefrag">./cocoon.sh cli -x &lt;xconf file&gt;</span>
+           or on Windows: <span class="codefrag">cocoon cli -x &lt;xconf file&gt;</span>.</p>
+<p>For a sample xconf file, with comments describing each option, see the 
+           <a href="configuration.html">configuration</a> page.</p>
+      
+<h2>Command Line Parameters</h2>
+<p>You can get a listing of the available parameters on unix with 
+        <span class="codefrag">./cocoon.sh cli -h</span> or on Windows with <span class="codefrag">cocoon cli -h</span>.
+        This should give a listing something like:</p>
+<pre class="code">
+-------------------- Executing -----------------
+Main Class: org.apache.cocoon.Main
+usage: cocoon cli [options] [targets]
+------------------------------------------------------------------------
+cocoon 2.1
+Copyright (c) 1999-2003 Apache Software Foundation. All rights reserved.
+------------------------------------------------------------------------
+ -a,--userAgent            use given string for user-agent header
+ -e,--confirmExtensions    confirm that file extensions match mime-type of
+                           pages and amend filename accordingly (default is true)
+ -C,--configFile           specify alternate location of the configuration
+                           file (default is ${contextDir}/cocoon.xconf)
+ -D,--defaultFilename      specify a filename to be appended to a URI when
+                           the URI refers to a directory
+ -L,--loadClass            specify a class to be loaded at startup
+                           (specifically for use with JDBC). Can be used multiple times
+ -P,--precompileOnly       generate java code for xsp and xmap files
+ -V,--verbose              enable verbose messages to System.out
+ -b,--brokenLinkFile       send a list of broken links to a file (one URI
+                           per line)
+ -c,--contextDir           use given dir as context
+ -d,--destDir              use given dir as destination
+ -f,--uriFile              use a text file with uris to process (one URI
+                           per line)
+ -h,--help                 print this message and exit
+ -k,--logKitconfig         use given file for LogKit Management
+                           configuration
+ -l,--Logger               use given logger category as default logger for
+                           the Cocoon engine
+ -p,--accept               use given string for accept header
+ -r,--followLinks          process pages linked from starting page or not
+                           (boolean argument is expected, default is true)
+ -u,--logLevel             choose the minimum log level for logging
+                           (DEBUG, INFO, WARN, ERROR, FATAL_ERROR) for startup logging
+ -v,--version              print the version information and exit
+ -w,--workDir              use given dir as working directory
+ -x,--xconf                specify a file containing XML configuration
+                           details for the command line interface
+Note: the context directory defaults to './webapp'
+        </pre>
+<p>For details of the meaning of each specific parameter, see the <a href="index.html">overview</a>
+           page.</p>
+<h3>Specifying Targets</h3>
+<p>The command line parameter method does not have access to all of Cocoon's URI handling features. However,
+             it is possible to specify multiple URIs to be crawled, all of which will be written to the same destination,
+             and that destination (specified by the <span class="codefrag">-d</span> or <span class="codefrag">--destDir</span> option, may be a file URI
+             or any other protocol for which a ModifiableSource exists (e.g. FTP).</p>
+<h3>URI Files</h3>
+<p>A URI file offers a simple way to specify multiple URIs. The file is treated as one URI per line.</p>
+<h3>Broken Link Handling</h3>
+<p>If a broken link file is specified, all broken links will be written to this file, in text format,
+             one URI per line.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/meta.xml
new file mode 100644
index 0000000..3625870
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cli/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/offline/cli.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/content_en.html
new file mode 100644
index 0000000..1bada56
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/content_en.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Offline Page Generation with Apache Ant</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document explains how to use Cocoon to generate offline pages and sites with Apache Ant." name="DC.Description">
+</head>
+<body>
+   
+<h1>Overview</h1>
+    
+<p>Apache Ant can be used to start Cocoon in its Offline mode. A specific Ant 
+       task is available, allowing the user to embed the Cocoon configuration 
+       information into Ant's build script.
+            </p>
+   
+   
+<h1>Configuring the Ant task</h1>
+     
+<p>The main configuration for the task is to specify a <span class="codefrag">cocoon.context</span> property which points to the
+        Cocoon webapp from which the pages or site are to be generated.</p>
+     
+<p>From this property, a classpath can be created. By default, this should point to <span class="codefrag">WEB-INF/classes</span> 
+        and all jar files in <span class="codefrag">WEB-INF/lib</span>. Futher classpaths can be added if they are needed.</p>
+     
+<p>The taskdef requires this classpath in order to invoke the Ant task, and the task itself needs the classpath in
+        order to invoke Cocoon.</p>
+     
+<p>Beyond these configurations, the rest are the same as is used by the <a href="cli.html">Command Line interface</a>,
+        and is detailed on the <a href="configuration.html">configuration</a> page.</p>
+   
+   
+<h1>Sample Ant Task</h1>
+       
+<p>A sample ant build file is shown below. This sample shows only that which is required to configure the
+          Ant task. For further details of configuring Cocoon, see the <a href="configuration.html">configuration</a>
+          page.</p>
+       
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+&lt;project default="cocoon" basedir="."&gt;
+
+    &lt;property name="cocoon.context" value="../cocoon/build/webapp"/&gt;
+    &lt;path id="cocoon.classpath"&gt;
+      &lt;dirset dir="${cocoon.context}/WEB-INF/classes"/&gt;
+      &lt;fileset dir="${cocoon.context}/WEB-INF/lib" includes="*.jar"/&gt;
+    &lt;/path&gt;
+ 
+    &lt;taskdef name="cocoon" classname="org.apache.cocoon.CocoonTask" classpathref="cocoon.classpath"/&gt;
+    
+    &lt;target name="cocoon"&gt;
+
+        &lt;cocoon verbose="true"  
+                classpathref="cocoon.classpath"
+                follow-links="true" 
+                precompile-only="false" 
+                confirm-extensions="false"
+                context-dir="${cocoon.context}"
+                config-file="WEB-INF/cocoon.xconf"
+                work-dir="build/work"
+                dest-dir="build/dest"
+                default-filename="index.html"
+                accept="*/*"&gt;
+        
+           &lt;broken-links type="xml" 
+                         file="brokenlinks.xml"
+                         generate="false"
+                         extension=".error"/&gt;
+           
+           &lt;logging log-kit="${cocoon.context}/WEB-INF/logkit.xconf" logger="cli" level="DEBUG" /&gt;
+    
+           &lt;uris name="site" follow-links="true"&gt;
+               &lt;uri type="append" 
+                    src-prefix="" 
+                    src="index.html"
+                    dest="${cocoon.context}/build/dest/"/&gt;
+           &lt;/uris&gt;        
+        &lt;/cocoon&gt;
+    &lt;/target&gt;
+&lt;/project&gt;
+    </pre>
+     
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/meta.xml
new file mode 100644
index 0000000..0222fc0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-ant-task/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/offline/ant.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/content_en.html
new file mode 100644
index 0000000..0d94073
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/content_en.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The Cocoon Bean</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document details the basics of using the Cocoon bean." name="DC.Description">
+</head>
+<body>
+   
+<h1>Overview</h1>
+    
+<p>The Cocoon Bean provides a Java programmatic interface for embedding Cocoon into other
+       applications.
+    </p>
+   
+   
+<h1>Details</h1>
+       
+<p>At present, the bean is mainly used for offline page generation. However, there is no 
+          reason why it should only be used in offline applications.</p>
+       
+<p>An example of an application that uses the bean is the Cocoon Command Line Interface (CLI). 
+          To find more about using the bean, look at the code for the CLI, which can be found 
+          in the Cocoon codebase in <span class="codefrag">src/java</span>, in the class 
+          <span class="codefrag">org.apache.cocoon.Main</span>.</p>
+       
+<div class="note">Whilst the Cocoon Bean works, it is still under development, and therefore its API
+             must be considered unstable. Return to this page in future versions to see what has 
+             changed.</div>
+     
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/meta.xml
new file mode 100644
index 0000000..f7f55e4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-cocoon-bean/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/offline/bean.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/content_en.html
new file mode 100644
index 0000000..f833cf8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/content_en.html
@@ -0,0 +1,727 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Understanding Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Pankaj Kumar" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+</head>
+<body>
+   
+<h1>Overview</h1>
+     
+<p>
+     This document is intended for both Users and Developers 
+     and presents an overall picture of @Name@.
+     </p>
+
+     
+<ul>
+       
+<li>
+         
+<a href="#pre-requisites">
+           Prerequisites
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#a-little-history">
+           A Little History
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#what-problems">
+           What problem does Cocoon solve?
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#basic-mechanisms">
+           Basic Mechanisms.
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#c2-architecture">
+           Architecture.
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#c2-abstractions">
+           Abstraction.
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#cocoon-configuration">
+           @Name@ Configuration.
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#work-area">
+           @Name@ Work Area.
+         </a>
+       
+</li>
+       
+<li>
+         
+<a href="#use-with-tomcat">
+           Use with Tomcat
+         </a>
+       
+</li>
+     
+</ul>
+  
+
+  
+<a name="pre-requisites"></a>
+  
+<h1>Prerequisites</h1>
+    
+<p>What You Should know:</p> 
+    
+<ul> 
+         
+<li>XML, XML Namespaces</li>
+         
+<li>Basics of XPath, XSLT</li>
+         
+<li>Java language</li>
+         
+<li>Servlets, HTTP</li>
+    
+</ul> 
+    
+<p>What You need not know:</p> 
+    
+<ul> 
+         
+<li>Cocoon 1</li>
+    
+</ul> 
+  
+  
+<a name="a-little-history"></a>
+  
+<h1>A Little History</h1>
+    
+<h2>Cocoon 1</h2>
+<ul> 
+            
+<li>Cocoon project was founded in Jan. 1999 by Stefano Mazzocchi as an open source project under Apache Software Foundation.</li>
+            
+<li>Started as a simple servlet for XSL styling of XML content.</li>
+            
+<li>Was based on DOM level 1 API. This choice turned out to be quite limiting for speed/memory efficiency.</li>
+            
+<li>Used reactor pattern to connect components. This allowed the reaction instructions to be placed inside the documents.  Though appealing, it caused difficulties in managing highly dynamic web-sites.</li>
+            
+<li>Allowed context overlap to happen by having processing instructions in documents/stylesheets.</li>
+      
+</ul>
+    
+<h2>Apache Cocoon</h2>
+<ul> 
+            
+<li>A separate codebase to incorporate Cocoon 1 learnings.</li>
+            
+<li>Designed for execution speed/memory efficiency and scalability to process very large documents by switching processing model from DOM to SAX.</li>
+            
+<li>Centralizes the management functions by allowing processing pipeline specification in a sitemap (an XML file), replacing the embedded processing instruction model.</li>
+            
+<li>Better support for pre-compilation, pre-generation and caching for better performance.</li>
+      
+</ul>
+  
+  
+<a name="what-problems"></a>
+  
+<h1>What problem does Cocoon solve?</h1>
+    
+<p>Basic problem to be solved:</p>
+    
+<h2>Separation of content, style, logic and management functions in an XML content based web site (and web services).</h2>
+<div align="center">
+<img class="figure" alt="The @Name@ Pyramid Model of Contracts" src="images/pyramid-model.gif" height="159" width="313"></div>
+    
+<h2>Data Mapping</h2>
+<div align="center">
+<img class="figure" alt="The @Name@ Data Mapping" src="images/data-mapping.gif" height="174" width="339"></div>
+  
+  
+<a name="basic-mechanisms"></a>
+  
+<h1>Basic Mechanisms.</h1>
+    
+<p>Basic mechanisms for processing XML documents:</p>
+    
+<ul>
+      
+<li>Dispatching based on Matchers.</li>
+      
+<li>Generation of XML documents (from content, logic, Relation DB, objects or any combination) through Generators</li>
+      
+<li>Transformation (to another XML, objects or any combination) of XML documents through Transformers</li>
+      
+<li>Aggregation of XML documents through Aggregators</li>
+      
+<li>Rendering XML through Serializers</li>
+    
+</ul>
+    
+<div align="center">
+<img class="figure" alt="Basic Mechanisms" src="images/basic-mechanism.gif" height="386" width="288"></div>
+    
+<h2>Pipeline Processing</h2>
+<p>Sequence of Interactions</p>
+<div align="center">
+<img class="figure" alt="Interaction Sequence" src="images/interaction-sequence.gif" height="347" width="613"></div>
+<p>Pipeline</p>
+<div align="center">
+<img class="figure" alt="Pipeline" src="images/pipeline.gif" height="223" width="713"></div>
+  
+  
+<a name="c2-architecture"></a>
+  
+<h1>Architecture.</h1>
+    
+<div align="center">
+<img class="figure" alt="Architecture" src="images/architecture.gif" height="349" width="430"></div>
+    
+<h2>Core Cocoon</h2>
+<ul>
+        
+<li>Avalon framework for logging, configuration, threading, context etc.</li>
+        
+<li>Caching mechanism</li>
+        
+<li>Pipeline handling</li>
+        
+<li>Program generation, compilation, loading and execution.</li>
+        
+<li>Base classes for generation, transformation, serialization, components.</li>
+        
+<li>...</li>
+      
+</ul>
+    
+<h2>Cocoon Components</h2>
+<ul>
+        
+<li>Specific generators</li>
+        
+<li>Specific transformers</li>
+        
+<li>Specific matchers</li>
+        
+<li>Specific serializers</li>
+        
+<li>...</li>
+      
+</ul>
+    
+<h2>Built-in Logicsheets</h2>
+<ul>
+        
+<li>sitemap.xsl</li>
+        
+<li>xsp.xsl</li>
+        
+<li>esql.xsl</li>
+        
+<li>request.xsl</li>
+        
+<li>response.xsl</li>
+        
+<li>...</li>
+      
+</ul>
+    
+<h2>Site specific configuration, components, logicsheets and content</h2>
+<ul>
+        
+<li>...</li>
+      
+</ul>
+  
+  
+<a name="c2-abstractions"></a>
+  
+<h1>Abstraction.</h1>
+    
+<h2>eXtensible Server Pages (XSPs)</h2>
+<p>An XSP page is an XML page with following requirements:</p>
+<ul>
+          
+<li>The document root must be <span class="codefrag">&lt;xsp:page&gt;</span>
+</li>
+          
+<li>It must have language declaration as an attribute in the <span class="codefrag">&lt;xsp:page&gt;</span> element.</li>
+          
+<li>It must have namespace declaration for xsp as an attribute in the <span class="codefrag">&lt;xsp:page&gt;</span> element.</li>
+          
+<li>For an XSP to be useful, it must also require at least an <span class="codefrag">&lt;xsp:logic&gt;</span> and an <span class="codefrag">&lt;xsp:expr&gt;</span> element.</li>
+        
+</ul>
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+
+&lt;xsp:page language="java" xmlns:xsp="http://apache.org/xsp"&gt;
+
+  &lt;xsp:logic&gt;
+  static private int counter = 0;
+  private synchronized int count()
+  {
+    return counter++;
+  }
+  &lt;/xsp:logic&gt;
+
+  &lt;page&gt;
+  &lt;p&gt;I have been requested &lt;xsp:expr&gt;count()&lt;/xsp:expr&gt; times.&lt;/p&gt;
+  &lt;/page&gt;
+
+&lt;/xsp:page&gt;
+</pre>
+<p>An XSP page is used by a generator to generate XML document.</p>
+    
+<h2>XSP Processing (Code Generation)</h2>
+<pre class="code">
+package org.apache.cocoon.www.docs.samples.xsp;
+
+import java.io.File;
+// A bunch of other imports 
+
+public class counter_xsp extends XSPGenerator {
+   // .. Bookkeeping stuff commented out.
+  /* User Class Declarations */
+  static private int counter = 0;
+  private synchronized int count() {
+    return counter++;
+  }
+  /* Generate XML data. */
+  public void generate() throws SAXException {
+    this.contentHandler.startDocument();
+    AttributesImpl xspAttr = new AttributesImpl();
+    this.contentHandler.startPrefixMapping("xsp", "http://apache.org/xsp");
+    this.contentHandler.startElement("", "page", "page", xspAttr);
+    // Statements to build the XML document (Omitted)
+    this.contentHandler.endElement("", "page", "page");
+    this.contentHandler.endPrefixMapping("xsp");
+    this.contentHandler.endDocument();
+  }
+</pre>
+    
+<h2>Ways of Creating XSPs</h2>
+<h3>Embedded Logic</h3>
+<ul>
+        
+<li>Code is embedded in the XML page</li>
+        
+<li>No separation of content and logic</li>
+        
+<li>Okay for small examples but terrible for large systems.</li>
+      
+</ul>
+<div align="center">
+<img class="figure" alt="ways of creating xsp's" src="images/xsp-way.gif" height="384" width="323"></div>
+<h3>Included Logicsheet</h3>
+<ul>
+        
+<li>Code is in a separate logicsheet (an XSL file)</li>
+        
+<li>Effective separation of content and logic</li>
+        
+<li>Preferred way to create XSPs</li>
+      
+</ul>
+<div align="center">
+<img class="figure" alt="ways of creating xsp's" src="images/xsp-way2.gif" height="403" width="318"></div>
+<h3>Logicsheet as tag library</h3>
+<ul>
+        
+<li>The logicsheet is packaged as a reusable tag library and registered with Cocoon in cocoon.xconf file.</li>
+        
+<li>Tag library has a namespace declaration, declared in the original logicsheet and matched in <span class="codefrag">&lt;xsp:page&gt;</span> xmlns:... attribute.</li>
+        
+<li>Effective separation of content, logic and management</li>
+      
+</ul>
+<div align="center">
+<img class="figure" alt="ways of creating xsp's" src="images/xsp-way3.gif" height="409" width="344"></div>
+    
+<h2>Sitemap</h2>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+
+&lt;map:components&gt;
+...
+&lt;/map:components&gt;
+
+&lt;map:views&gt;
+...
+&lt;/map:views&gt;
+&lt;map:pipelines&gt;
+&lt;map:pipeline&gt;
+&lt;map:match&gt; 
+...
+&lt;/map:match&gt;
+...
+&lt;/map:pipeline&gt;
+...
+&lt;/map:pipelines&gt;
+...
+&lt;/map:sitemap&gt;
+</pre>
+<p>Sitemap contains configuration information for a Cocoon engine:</p>
+<ul>
+           
+<li>list of matchers</li>
+           
+<li>list of generators</li>
+           
+<li>list of transformers</li>
+           
+<li>list of readers</li>
+           
+<li>list of serializers</li>
+           
+<li>list of selectors</li>
+           
+<li>list of processing pipelines with match patterns</li>
+           
+<li>...</li>
+        
+</ul>
+<p>Sitemap is an XML file corresponding to a sitemap DTD.</p>
+<p>Sitemap can be edited to add new elements.</p>
+<p>Sitemap is generated into a program and is compiled into an executable unit.</p>
+    
+<h2>Matchers</h2>
+<p>A Matcher attempts to match an URI with a specified pattern for dispatching the request to a specific processing pipeline.</p>
+<p>Different types of matchers:</p>
+<ul>
+           
+<li>wildcard matcher</li>
+           
+<li>regexp matcher</li>
+        
+</ul>
+<p>More matchers can be added without modifying Cocoon.</p>
+<p>Matchers help in specifying a specific pipeline processing for a group of URIs.</p>
+<p>Sitemap entries for different types of matchers</p>
+<pre class="code">
+&lt;map:matchers default="wildcard"&gt;
+ &lt;map:matcher name="wildcard" factory="org.apache.cocoon.matching.WildcardURIMatcher"/&gt;
+ &lt;map:matcher name="regexp" factory="org.apache.cocoon.matching.RegexpURIMatcher"/&gt;
+&lt;/map:matchers&gt;
+</pre>
+<p>Pipeline entries in sitemap file</p>
+<pre class="code">
+&lt;map:match pattern="jsp/*"&gt;
+  &lt;map:generate type="jsp" src="/docs/samples/jsp/{1}.jsp"/&gt;
+  ...
+  &lt;/map:match&gt;
+&lt;map:match pattern="hello.pdf"&gt;
+&lt;/map:match
+</pre>
+    
+<h2>Generators</h2>
+<p>A Generator is used to create an XML structure from an input source (file, directory, stream ...)</p>
+<div align="center">
+<img class="figure" alt="ways of creating xsp's" src="images/xsp-way3.gif" height="409" width="344"></div>
+<p>Different types of generators:</p>
+<ul>
+           
+<li>file generator</li>
+           
+<li>directory generator</li>
+           
+<li>XSP generator</li>
+           
+<li>JSP generator</li>
+           
+<li>Request generator</li>
+           
+<li>...</li>
+        
+</ul>
+<p>More generators can be added without modifying Cocoon.</p>
+<p>Sitemap entries for different types of generators</p>
+<pre class="code">
+&lt;map:generators default="file"&gt;
+ &lt;map:generator name="file"
+                src="org.apache.cocoon.generation.FileGenerator"
+                label="content"/&gt;
+ &lt;map:generator name="directory"
+                src="org.apache.cocoon.generation.DirectoryGenerator"
+                label="content"/&gt;
+ &lt;map:generator name="serverpages"
+                src="org.apache.cocoon.generation.ServerPagesGenerator"
+                label="content"/&gt;
+ &lt;map:generator name="request"
+                src="org.apache.cocoon.generation.RequestGenerator"/&gt;
+ ...
+&lt;/map:generators&gt;
+</pre>
+<p>A sample generator entries in a pipeline</p>
+<pre class="code">
+&lt;map:match pattern="hello.html"&gt;
+    &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+    &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+    &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>A Generator turns an XML document, after applying appropriate transformations, into a compiled program whose output is an XML document.</p>
+<p>An XSP generator applies all the logicsheets specified in the source XML file before generating the program.</p>
+<p>Generators cache the compiled programs for better runtime efficiency.</p>
+    
+<h2>Transformers</h2>
+<p>A Transformer is used to map an input XML structure into another XML structure.</p>
+<p>Different types of transformers:</p>
+<ul>
+           
+<li>XSLT Transformer</li>
+           
+<li>Log Transformer</li>
+           
+<li>SQL Transformer</li>
+           
+<li>I18N Transformer</li>
+           
+<li>...</li>
+        
+</ul>
+<p>Log Transformer is a good debugging tool.</p>
+<p>More transformers can be added without modifying Cocoon.</p>
+<p>Sitemap entries for different types of transformers</p>
+<pre class="code">
+&lt;map:transformers default="xslt"&gt;
+   &lt;map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"&gt;
+    &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+    &lt;use-browser-capabilities-db&gt;false&lt;/use-browser-capabilities-db&gt;
+   &lt;/map:transformer&gt;
+   &lt;map:transformer name="log" src="org.apache.cocoon.transformation.LogTransformer"/&gt;
+...
+
+&lt;/map:transformers&gt;
+</pre>
+<p>A sample transformer entry in a pipeline</p>
+<pre class="code">
+&lt;map:match pattern="hello.html"&gt;
+ &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+ &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+ &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+</pre>
+    
+<h2>Serializers</h2>
+<p>A Serializer is used to render an input XML structure into some other format (not necessarily XML)</p>
+<p>Different types of serializers:</p>
+<ul>
+           
+<li>HTML Serializer</li>
+           
+<li>FOP Serializer</li>
+           
+<li>Text Serializer</li>
+           
+<li>XML Serializer</li>
+           
+<li>...</li>
+        
+</ul>
+<p>More serializers can be added without modifying Cocoon.</p>
+<p>Sitemap entries for different types of serializers</p>
+<pre class="code">
+&lt;map:serializers default="html"&gt;
+ &lt;map:serializer name="xml"
+                 mime-type="text/xml"
+                 src="org.apache.cocoon.serialization.XMLSerializer"/&gt;
+ &lt;map:serializer name="html"
+                 mime-type="text/html"
+                 src="org.apache.cocoon.serialization.HTMLSerializer"/&gt;
+ &lt;map:serializer name="fo2pdf"
+                 mime-type="application/pdf"
+                 src="org.apache.cocoon.serialization.FOPSerializer"/&gt;
+ &lt;map:serializer name="vrml"
+                 mime-type="model/vrml"
+                 src="org.apache.cocoon.serialization.TextSerializer"/&gt;
+ ...
+&lt;/map:serializers&gt;
+</pre>
+<p>A sample serializer entry in a pipeline</p>
+<pre class="code">
+ &lt;map:match pattern="hello.html"&gt;
+    &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+    &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+    &lt;map:serialize type="html"/&gt;
+   &lt;/map:match&gt;
+</pre>
+    
+<h2>Pipeline Processing</h2>
+<p>The sitemap configuration allows dynamic setup of processing pipelines consisting of a generator, multiple transformers and a serializer.</p>
+<p>Requests are dispatched to a pipeline based on request URI and the pipeline matching pattern (either with wildcards or as a regexp)</p>
+<p>The pipeline is setup in the generated file <span class="codefrag">sitemap_xmap.java</span> (This file gets generated [possibly asynchronously] everytime the <span class="codefrag">sitemap.xmap</span> is modified.</p>
+<div align="center">
+<img class="figure" alt="Pipeline Entry" src="images/pipeline2.gif" height="341" width="379"></div>
+    
+<h2>Logicsheets</h2>
+<p>Logicsheets are XSL files with an associated namespace.</p>
+<p>Primary mechanism to add program logic (code) to XSPs.</p>
+<p>These need to be registered in configuration file cocoon.xconf.</p>
+<p>Logicsheets are used by the generator to transform XML structure before generating program.</p>
+<p>Cocoon comes with a no. of built-in logic sheets:</p>
+<ul>
+           
+<li>request.xsl</li>
+           
+<li>response.xsl</li>
+           
+<li>session.xsl</li>
+           
+<li>cookie.xsl</li>
+           
+<li>esql.xsl</li>
+           
+<li>log.xsl</li>
+           
+<li>...</li>
+        
+</ul>
+<p>Log.xsl structure</p>
+<pre class="code">
+&lt;xsl:stylesheet  version="1.0"
+                 xmlns:xsp="http://apache.org/xsp"
+                 xmlns:log="http://apache.org/xsp/log"
+                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
+
+&lt;xsl:template match="log:logger"&gt;
+... variable and xsp:logic statements ...
+&lt;/xsl:template&gt;
+
+&lt;xsl:template match="log:debug"&gt;
+  &lt;xsp:logic&gt;
+   if(getLogger() != null)
+     getLogger().debug("&lt;xsl:value-of select="."/&gt;");    
+  &lt;/xsp:logic&gt;  
+&lt;/xsl:template&gt;
+&lt;xsl:template match="log:error"&gt;
+...  
+&lt;/xsl:template&gt;
+&lt;/xsl:stylesheet&gt;
+</pre>
+<p>A sample use</p>
+<pre class="code">
+&lt;xsp:page language="java"
+          xmlns:xsp="http://apache.org/xsp"
+          xmlns:log="http://apache.org/xsp/log"&gt;
+
+  &lt;page&gt;
+  &lt;log:logger name="test" filename="test.log"/&gt;
+  &lt;log:debug&gt;Test Message&lt;/log:debug&gt;
+  &lt;/page&gt;
+&lt;/xsp:page&gt;
+</pre>
+  
+  
+<a name="cocoon-configuration"></a>
+  
+<h1>@Name@ Configuration.</h1>
+    
+<p>Cocoon is highly configurable. Main configuration files, assuming Cocoon deployment as a servlet in a servlet container, are (directory locations assume Tomcat servlet container):</p>
+    
+<ul>
+       
+<li>
+<span class="codefrag">sitemap.xmap</span>: the sitemap file. By default, located in <span class="codefrag">$TOMCAT_HOME/webapps/cocoon</span> directory.</li>
+       
+<li>
+<span class="codefrag">cocoon.xconf</span>: configuration file having logicsheet registrations. Specifies, sitemap.xmap location and other such parameters. By default, located in <span class="codefrag">$TOMCAT_HOME/webapps/cocoon</span> directory.</li>
+       
+<li>
+<span class="codefrag">web.xml</span>: servlet deployment descriptor. Specifies location of cocoon.xconf, log file location and other such parameters. Located in <span class="codefrag">$TOMCAT_HOME/webapps/cocoon/WEB-INF</span> directory.</li>
+       
+<li>
+<span class="codefrag">cocoon.roles</span>: mapping file for Core Cocoon components name and implementation classes. For example, if you want to use a parser other than the default one, you need to modify this file.</li>
+    
+</ul>
+  
+  
+<a name="work-area"></a>
+  
+<h1>@Name@ Work Area</h1>
+    
+<p>Cocoon produces execution log entries for debugging/auditing.</p>
+    
+<ul>
+       
+<li>The amount of data to be logged can be controlled by
+       log-level parameter in web.xml file. The default is DEBUG
+       (maximum data).</li>
+       
+<li>By default, the log file is:
+       <span class="codefrag">$TOMCAT_HOME/webapps/cocoon/WEB-INF/logs/cocoon.log</span>.</li>
+    
+</ul>
+
+    
+<p>Cocoon keeps the generated .java files in a directory tree
+    starting at (by default):<br>
+    
+<span class="codefrag">$TOMCAT_HOME/webapps/work/localhost_8080%2Fcocoon/org/apache/cocoon/www</span>.</p>
+
+
+<p>You can find sitemap_xmap.java here.</p>
+
+    
+<p>Files created by LogTransformer are kept (by default) in <span class="codefrag">$TOMCAT_HOME</span> directory.</p>
+  
+  
+<a name="use-with-tomcat"></a>
+  
+<h1>Use with Tomcat</h1>
+    
+<p>Download Tomcat from Apache site.</p>
+    
+<p>Download Cocoon sources from Apache CVS. [Command assume UNIX Bourne shell]</p>
+
+<pre class="code">
+export CVSROOT=:pserver:anoncvs@cvs.apache.org:/home/cvspublic 
+cvs login 
+Password: anoncvs 
+cvs checkout cocoon-2.1
+</pre>
+    
+<p>Build sources as per instruction in Install file.</p>
+    
+<p>Move the <span class="codefrag">cocoon.war</span> file to <span class="codefrag">$TOMCAT_HOME/webapps</span> directory.</p>
+    
+<p>Start the servlet engine. Type-in the URL <span class="codefrag">http://localhost:8080/cocoon</span> in your browser. You should see the Cocoon welcome message.</p>
+    
+<p>Consult Install file if you face problems.</p>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/meta.xml
new file mode 100644
index 0000000..411d633
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-concepts/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/content_en.html
new file mode 100644
index 0000000..b9836e0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/content_en.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Database Access</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Introduction</h1>
+    
+<p>
+    Publishing dynamic content or creating web-applications 
+    eventually involves database access. Apache Cocoon
+    offers a number of different approaches to access
+    (object) relational and XML databases. This document provides
+    an overview of the different ways to access (object)
+    relational databases.
+    </p>
+    
+<p>
+    This document will not explain how to set up database
+    connectivity with Apache Cocoon. For this, see <a href="../../developing/datasources.html">here.</a>
+    
+</p>
+    
+<p>
+    Basically, there are three different approaches available:
+    <a href="actions.html">Actions,</a> <a href="../xsp/logicsheet-concepts.html">logicsheets,</a>
+    and <a href="sitemap.html">transformers.</a> Each approach has
+    its pros and cons. 
+    </p>
+  
+
+  
+<h1>Actions Approach</h1>
+    
+<p>
+    
+<a href="actions.html">Actions</a> are code to be executed
+    during pipeline setup. The outcome of an action can change how a pipeline is
+    assembled. For example, a pipeline may produce an alternative
+    page to display upon failure of a particular database operation.
+    </p>
+    
+<p>
+    Actions are especially great for inserting, changing, or deleting data. 
+    Employing the pipeline-switching features of actions will simplify your 
+    pages. Such actions are concerned with only one view: either the success
+    or failure of an operation.
+    </p>
+    
+<p>
+    Actions can be useful, even when data is not provided by users.
+    For example, you could store tracking information in a database in
+    a central location without the need to modify every page.
+    </p>
+    
+<p>
+    Database actions can read and return data from a database. This is
+    useful when the pipeline assembly depends upon such data. It's also
+    useful when setting up an environment for XSP processing.
+    </p>
+    
+<p>
+    Once the database meta data is captured in an XML descriptor file, 
+    making use of these actions is simply a matter of placing them in a pipeline. 
+    This is a major advantage of the action approach. No programming is
+    required, not even SQL query writing.
+    </p>
+    
+<p>
+    For more detailed information, read:  <a href="../actions/database-actions.html">Database Actions</a>.
+    </p>
+  
+
+  
+<h1>ESQL Logicsheet Approach</h1>
+    
+<p>
+    The use of logicsheets is limited to XSPs. ESQL is currently available
+    for Java-based XSPs. Its interface is modeled largely on
+    JDBC. Thus, it is advantageous to be familiar with JDBC.
+    </p>
+    
+<p>
+    ESQL is great when reading data from a database. However, it is less attractive
+    to use when it has to react to operation failures. This is due to the fact
+    that it adds a layer of complexity to an XSP file, making it
+    more difficult to understand and maintain.
+    </p>
+    
+<p>
+    Complex layouts of the data are easy to achieve. ESQL allows
+    the arbitrary nesting of queries and connections. It also provides support for
+    stored procedures and complex data types. ESQL provides a means to 
+    create a structured representation of the database data with a single tag. 
+    This is useful when generating reports to use
+    with other XML-aware software or to be formated with XSL or CSS2.
+    XML data can be retrieved from the
+    database and included in the output. With some supported database
+    management systems, ESQL supports skipping part of the
+    resultset as well as limiting the result. 
+    Given the full power of Java available within XSP,
+    any processing of the data is possible. 
+    </p>
+    
+<p>
+    For more detailed information, read:  <a href="../xsp/esql.html">ESQL Taglib</a>.
+    </p>
+  
+
+  
+<h1>SQL Transformer Approach</h1>
+    
+<p>
+    An approach using the SQL transformer can be combined with any kind
+    of page. This will result in slightly cleaner pages as you don't need
+    some of the setup that an ESQL approach requires.
+    </p>
+    
+<p>
+    On the other hand, it is more or less impossible to react to operation
+    failures. This is due to the fact that the pipeline is already assembled 
+    and the necessary logic to handle such failures is not
+    available inside the SQL transformer, unless of course, you are willing
+    to write a custom transformer.
+    Thus, the transformer approach is best for retrieving data. Creating
+    an XML representation of the query result is even simpler than when
+    using the ESQL logicsheet. The transformer also supports stored procedures.
+    No programming is required, apart from writing SQL.
+    </p>
+    
+<p>
+    For more detailed information, read: <a href="../transformers/sql-transformer.html">SQL Transformer</a>.
+    </p>
+  
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/meta.xml
new file mode 100644
index 0000000..150f0ea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-databases/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/databases.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/content_en.html
new file mode 100644
index 0000000..8596a34
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/content_en.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>DateSelector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the DateSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>DateSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">date</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">DateSelector</span> component is used to 
+            select appropriate sitemap processing depending on the current date, and time.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Scratchpad</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.DateSelector</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">DateSelector</span> tests the current date, and time
+        against the test attribute of the selectors when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">DateSelector</span> allows to define date, and time specific sitemap
+        processing. This way Cocoon can do date, and time specific sitemap processing.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:select type="daytime"&gt;
+  &lt;map:when test="night"&gt;
+    &lt;!-- do something for night publishing --&gt;
+    &lt;map:read src="resources/{2}-night.css" mime-type="text/css&gt;
+  &lt;/map:when&gt;
+  &lt;map:when test="morning"&gt;
+    &lt;!-- do something for morning publishing --&gt;
+    &lt;map:read src="resources/{2}-morning.css" mime-type="text/css&gt;
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+    &lt;!-- define for completness, and if selecting fails due to errors --&gt;
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+</pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The following snippet defines a DateSelector named daytime. 
+          A day is partioned into four daytime areas: night, morning, afternoon, and evening.
+          These daytime names are used to define daytime specific pipeline processing for each
+          daytime area.
+        </p>
+<pre class="code">
+&lt;map:selectors default="browser"&gt;
+  ...
+  &lt;map:selector type="daytime" src="org.apache.cocoon.selection.DateSelector"&gt;
+    &lt;before name="night" date="06:00:00" dateformat="HH:mm:ss"/&gt;
+    &lt;before name="morning" date="12:00:00" dateformat="HH:mm:ss"/&gt;
+    &lt;before name="afternoon" date="18:00:00" dateformat="HH:mm:ss"/&gt;
+    &lt;before name="evening" date="23:59:59" dateformat="HH:mm:ss"/&gt;
+  &lt;/map:selector&gt;
+...
+&lt;/map:selectors&gt;
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          Explain the sitemap selector configuration, options when declaring date selector
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          Explain the sitemap selector setup, ie options when using date selector
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+        
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        Describe limitation, bugs of DateSelector 
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        11-28-03: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/meta.xml
new file mode 100644
index 0000000..97fb53e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-date-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/date-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/content_en.html
new file mode 100644
index 0000000..7b5d158
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/content_en.html
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Avalon for Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tom Klaasen" name="DC.Creator">
+<meta content="Berin Loritsch" name="DC.Creator">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document tries to give the basic knowledge of Avalon that is
+      necessary to understand Apache Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+      
+<p>This document tries to provide you with the basic knowledge of Avalon
+        that is necessary to understand Cocoon.</p>
+      
+<p>People trying to understand Avalon in depth, will probably not be much
+        helped by this document. But, if you want to understand Cocoon, you have
+        to have a basic grasp of Avalon.</p>
+      
+<p>The document also outlines the basic steps for configuring Avalon
+        components within Cocoon.</p>
+      
+<p>Much of this document is copied and pasted from original Avalon
+        documentation. However, I hope that by putting all things relevant to
+        Cocoon together in one place I can help you to understand Cocoon more
+        quickly.</p>
+      
+<p>For people wishing to learn Avalon in-depth,
+        <a class="external" href="http://avalon.apache.org/developing/index.html">this
+        is your starting point</a>.</p>
+    
+    
+<h1>Overview</h1>
+      
+<p>For a mission statement of Apache Avalon, please read
+        <a class="external" href="http://avalon.apache.org/index.html">the Avalon
+        homepage</a>.</p>
+      
+<p>In short, Avalon tries to take design efforts away from server-side
+        programmers by providing a framework that </p>
+      
+<ul>
+        
+<li>provides basic working classes;</li>
+        
+<li>provides interfaces to allow different efforts to be integrated
+          more easily.</li>
+      
+</ul>
+    
+    
+<h1>The classes and interfaces</h1>
+      
+<p>These classes and interfaces are extensively used by Cocoon:</p>
+      
+<h2>ServiceManager</h2>
+<p>
+          
+<span class="codefrag">org.apache.avalon.framework.service.ServiceManager</span>
+        
+</p>
+<p>A <span class="codefrag">ServiceManager</span> selects <span class="codefrag">Component</span>s based
+          on a role. The contract is that all the <span class="codefrag">Component</span>s
+          implement the differing roles and there is one <span class="codefrag">Component</span>
+          per role. If you need to select one of many <span class="codefrag">Component</span>s
+          that implement the same role, then you need to use a
+          <span class="codefrag">ServiceSelector</span>. Roles are the full interface name.</p>
+<p>To understand roles better let's use the the analogy of a play. There
+          are many different roles in a script. Any actor or actress can play
+          any given part and you get broadly the same results (same phrases
+          spoken, same movements made, etc.), but with each actor the exact
+          nuances of the performance are different.</p>
+      
+<h2>Serviceable</h2>
+<p>
+          
+<span class="codefrag">org.apache.avalon.framework.service.Serviceable</span>
+        
+</p>
+<p>A <span class="codefrag">Serviceable</span> is a class that needs to connect to
+          software components using a "role" abstraction, thus not depending on
+          particular implementations but on behavioral interfaces. This means,
+          if you need to use other components in your implementation, you
+          have to implement <span class="codefrag">Serviceable</span> to be able to get other
+          components.</p>
+      
+<h2>Configuration</h2>
+<p>
+          
+<span class="codefrag">org.apache.avalon.framework.configuration.Configuration</span>
+        
+</p>
+<p>
+          
+<span class="codefrag">Configuration</span> is an interface encapsulating a
+          configuration node used to retrieve configuration values. This is a
+          "read only" interface preventing applications from modifying their own
+          configurations. The contract surrounding the
+          <span class="codefrag">Configuration</span> is that once it is created, information
+          never changes. The <span class="codefrag">Configuration</span> is built by the
+          <span class="codefrag">ConfigurationBuilder</span>.
+        </p>
+      
+<h2>Configurable</h2>
+<p>
+          
+<span class="codefrag">org.apache.avalon.framework.configuration.Configurable</span>
+        
+</p>
+<p>
+          
+<span class="codefrag">Configurable</span> is an interface describing a component which
+          can be configured. This component gets a <span class="codefrag">Configuration</span>
+          object as input.</p>
+      
+<h2>ConfigurationBuilder</h2>
+<p>
+          
+<span class="codefrag">org.apache.avalon.ConfigurationBuilder</span>
+        
+</p>
+<p>A <span class="codefrag">ConfigurationBuilder</span> builds
+          <span class="codefrag">Configuration</span>s.</p>
+    
+    
+<h1>Configuration</h1>
+      
+<p>Most available Avalon components are configured in the cocoon.xconf.</p>
+      
+<h2>Pooling configuration</h2>
+<p>Avalon now incorporates a couple of modifiers for a Component
+          definition that allows you to control the number of Components in a
+          pool.  This is especially helpful in Cocoon
+          where the defaults don't always work well.</p>
+<p>The magic attribute is "pool-max".
+          The defaults are:</p>
+<ol>
+          
+<li>pool-max: 8</li>
+        
+</ol>
+<p>What this means is that the pool for the default component initially
+          contains zero instances. If demand exceeds this then the pool will
+          increase, one component at a time, up to 8 instances. Beyond that the
+          pool turns into a factory.  That is, new <span class="codefrag">Component</span>
+          instances are created, but destroyed when they are returned. This is a
+          performance issue - but it does manage the number of instances
+          available at one time.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/meta.xml
new file mode 100644
index 0000000..98e8773
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-avalon/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/avalon.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/content_en.html
new file mode 100644
index 0000000..6347a71
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/content_en.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Using Databases in Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Berin Loritsch" name="DC.Creator">
+</head>
+<body> 
+   
+<h1>How do I choose my database?</h1> 
+    
+<p>
+     Apache Cocoon is flexible in the way it allows you to make connections to
+     a database.  There are basically two ways: by redefining all the connection
+     parameters in each page you use a database, or using a pooled connection.
+     The first method is slow and doesn't scale well.  The second method is more
+     scalable, and depending on your database will realize true improvements.
+    </p>
+    
+<h2>Installing the Driver</h2>
+<p>
+       Independent of how you choose to get and maintain your JDBC connections,
+       you have to load the driver so Cocoon can use it (unless you are using
+       a J2EE container--more on that later).  This is an init parameter in
+       your web.xml file.  The following snippet will show you how:
+     </p>
+<pre class="code">
+      
+&lt;init-param&gt;
+  &lt;param-name&gt;load-class&lt;/param-name&gt;
+  &lt;param-value&gt;
+    &lt;!-- For PostgeSQL Database: --&gt;
+    postgresql.Driver
+
+    &lt;!-- For Oracle Database: --&gt;
+    oracle.jdbc.driver.OracleDriver
+  &lt;/param-value&gt;
+&lt;/init-param&gt;
+      
+     </pre>
+<p>
+      You can place as many Driver classes in this parameter you want.  They
+      are separated by white space or commas.
+     </p>
+    
+<h2>Defining a Data Source</h2>
+<p>
+      Cocoon allows you to specify a pooled data source that you can use
+      for throughout the Cocoon system.  There are two different types of
+      data sources: JDBC and J2EE.  The difference is in who controls the
+      connection.  The JDBC data source lets Cocoon handle all the pooling
+      logic.  The J2EE data source tells Cocoon how to pull the DataSource
+      object from a J2EE container (thats Java 2 Enterprise Edition)--the
+      major caveat is that Cocoon must be installed as part of a Enterprise
+      Application.
+     </p>
+<p>
+      The following snippet of cocoon.xconf shows the section where the
+      DataSourceComponent is specified.  You can have more than one in
+      this location.  The code will have one connection for the JDBC data
+      source, and one connection for the J2EE data source.
+     </p>
+<pre class="code">
+      
+  &lt;datasources&gt;
+    &lt;jdbc name="MyConnectionName"&gt;
+
+      &lt;pool-controller min="5" max="10"/&gt;
+      &lt;dburl&gt;jdbc:oracle:thin:@localhost:1521:mydatabase&lt;/dburl&gt;
+      &lt;user&gt;mylogin&lt;/user&gt;
+      &lt;password&gt;myPassword&lt;/password&gt;
+    &lt;/jdbc&gt;
+    &lt;j2ee name="MyJ2eeConnection"&gt;
+      &lt;dbname&gt;cocoonDB&lt;/dbname&gt;
+    &lt;/j2ee&gt;
+  &lt;/datasources&gt;
+      
+     </pre>
+<h3>The JDBC Connection Properties</h3>
+<p>
+       The JDBC connection has up to five different properties--but only one
+       is absolutely required.
+      </p>
+<ul>
+       
+<li>
+         dburl: This is absolutely required.  Without it JDBC can't connect
+	 to the database.
+       </li>
+       
+<li>
+         user: This is only required if the database admin requires you to
+	 log in to the database.
+       </li>
+       
+<li>
+         password: This is only required if the database admin requires a
+	 password to connect to the database.
+       </li>
+       
+<li>
+         pool-controller: This has two parameters with defaults.  If it is
+	 not specified, the defaults are used.
+	 <ul>
+	   
+<li>
+	     min: The minimum number of connections the pool will keep
+	     available at one time.  Defaults to zero (0).
+	   </li>
+	   
+<li>
+	     max: The maximum number of connections the pool will have
+	     created at the same time.  Defaults to three (3).
+	   </li>
+         
+<li>
+           oradb: If you have an Oracle database, you should add the attribute
+                  "oradb" and set it to true.
+         </li>
+	 
+</ul>
+       
+</li>
+       
+<li>
+        auto-commit: If you need to ensure an autocommit is set to true or
+                     false, then create the "auto-commit" element.
+       </li>
+      
+</ul>
+<h3>The J2EE Connection Property</h3>
+<p>
+        The J2EE connection has only one property and it is absolutely
+	required.  Cocoon uses JNDI to look up the DataSource with the
+	name you specified in "dbname".
+      </p>
+    
+<h2>Using the Data Source Component</h2>
+<p>
+       No matter how you defined your DataSourceComponent, you access
+       it the same way.  Because The DataSourceComponent is a Component,
+       your class needs to implement the Avalon Serviceable interface.  The
+       Avalon Framework will give your class a ServiceManager.  At that
+       point, it is up to you how and when you pull the DataSourceComponent
+       out of the ServiceManager.
+      </p>
+<pre class="code">
+       
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.Roles;
+import org.apache.avalon.excalibur.datasource.DataSourceComponent;
+
+import java.sql.Connection;
+
+// .... Skip a lot of lines until we are in the method you use
+//      to initialize the DataSourceComponent ....
+
+private DataSourceComponent datasource;
+
+public void service(ServiceManager manager) {
+    ServiceSelector selector =
+        (ServiceSelector) manager.lookup(Roles.DB_CONNECTION);
+    this.datasource = (DataSourceComponent) selector.select("MyConnectionName");
+}
+
+// .... Skip more lines until we actually need to use the datasource
+
+private void meMethod() {
+    Connection myConnection = this.datasource.getConnection();
+
+    // .... perform SQL code here
+
+    myConnection.close();
+}
+       
+      </pre>
+<p>
+       Notice that once you obtained your connection, you did nothing out of the
+       ordinary to return the connection to the pool?  This is by design, and a
+       result of the JDBC specification.  Basically the JDBC specification states
+       that if a driver implements pooled connections, then it should not alter
+       the way those connections are used.  This maintains the portability of
+       your code.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/meta.xml
new file mode 100644
index 0000000..a16259d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing-with-datasources/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/datasources.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/content_en.html
new file mode 100644
index 0000000..73fc8c6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/content_en.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Developer Documentation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="cocoon-dev" name="DC.Creator">
+</head>
+<body>
+    
+<h1>The usual Cocoon Developer profile</h1>
+      
+<p>As a Cocoon developer (someone who develops components for Cocoon), you
+         need of course everything you have to know as a Cocoon user. In addition
+         you should have a basic understanding of the following technologies.
+         Again, this knowledge is not specific to Cocoon; it can be used for
+         building web applications with different frameworks as well.
+      </p>
+      
+<ul>
+        
+<li>The Java Language and Application Frameworks</li>
+        
+<li>Java Servlets</li>
+        
+<li>
+<a href="avalon.html">Avalon Component Framework</a>
+</li>
+      
+</ul>
+
+    
+ 
+<h1>Overview</h1>
+
+  
+<p>Here will soon appear an overview of the developer perspective.
+  </p>
+  
+<p>If you are interested in developing real-world web-applications requiring
+    form handling, authentication or even developing your own portal, have a 
+    look at the <a href="webapps/index.html">web application documentation</a>.</p>
+  
+<p>The actual developer documentation is available from the side-panel.
+  </p>
+
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/meta.xml
new file mode 100644
index 0000000..f78486d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-developing/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/content_en.html
new file mode 100644
index 0000000..689fdb4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/content_en.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Directory Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Frank Ridderbusch" name="DC.Creator">
+<meta content="John Morrison" name="DC.Creator">
+<meta content="J&ouml;rg Heinicke" name="DC.Creator">
+<meta content="This document describes the Directory Generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Directory Generator</h1>
+      
+<p>The root node of the generated document will normally be a <span class="codefrag">directory</span> node. A
+          directory node can contain zero or more <span class="codefrag">file</span> or <span class="codefrag">directory</span> nodes.
+          A file node has no children. All generated elements have the namespace
+          <span class="codefrag">http://apache.org/cocoon/directory/2.0</span>.
+      </p>
+      
+<p>Each node will contain the following attributes:</p>
+      
+<ul>
+        
+<li>
+<span class="codefrag">name</span>: the name of the file or directory.</li>
+        
+<li>
+<span class="codefrag">lastModified</span>: the time the file was last modified, measured as the number
+            of milliseconds since the epoch (as in <span class="codefrag">java.io.File.lastModified</span>).</li>
+        
+<li>
+<span class="codefrag">date</span> (optional): the time the file was last modified in human-readable form.</li>
+        
+<li>
+<span class="codefrag">size</span>: the file size (or 0 for directories).</li>
+      
+</ul>
+      
+<p>Additionally the node for the requested directory has the attributes:</p>
+      
+<ul>
+        
+<li>
+<span class="codefrag">requested</span>: with the value set to <span class="codefrag">true</span>.</li>
+        
+<li>
+<span class="codefrag">sort</span>: the sort order of the <span class="codefrag">file</span> and <span class="codefrag">directory</span>
+                               nodes.</li>
+        
+<li>
+<span class="codefrag">reverse</span>: determines whether reverse sort was chosen.</li>
+      
+</ul>
+      
+<p>This node needs not to be the root node as you will see later.</p>
+    
+    
+<h1>Configuration</h1>
+      
+<pre class="code">
+  &lt;map:generate type="directory" src="the/requested/directory"&gt;
+    &lt;map:parameter name="depth" value="2"/&gt;
+  &lt;/map:generate&gt;
+      </pre>
+      
+<p>The <span class="codefrag">src</span> attribute on the <span class="codefrag">&lt;map:generate/&gt;</span> must be set to the
+          directory the XML listing should be created of. This is the <em>requested</em> directory.
+      </p>
+      
+<p>The following parameter are all optional and can be specified in the pipeline for the
+          generate command (as seen in the example above for the parameter <span class="codefrag">depth</span>):
+      </p>
+      
+<ul>
+        
+<li>depth: Sets how deep the generator should delve into the directory structure. If
+            set to 1 (the default), only the starting directory's immediate contents will be
+            returned.</li>
+        
+<li>dateFormat: Sets the format for the date attribute of each node as described in
+            <span class="codefrag">java.text.SimpleDateFormat</span>. If unset, the default format for the current
+            locale will be used.</li>
+        
+<li>refreshDelay: Sets the delay (in seconds, default is 1) between checks for updates on
+            the file system. So this option influences the caching of the directory listing.</li>
+        
+<li>sort: Sets the sort order in which the <span class="codefrag">file</span> and <span class="codefrag">directory</span>
+            nodes are returned. Possible values are <span class="codefrag">name</span>, <span class="codefrag">size</span>,
+            <span class="codefrag">lastmodified</span> and <span class="codefrag">directory</span> (where <span class="codefrag">directory</span> is the same
+            as <span class="codefrag">name</span>, except that directory entries are listed first). The default sort
+            order is <span class="codefrag">name</span>.</li>
+        
+<li>reverse: Reverses the sort order, defaults to <span class="codefrag">false</span>.</li>
+        
+<li>root: The root pattern. From the requested director upwards a directory is searched
+            using this pattern, that is added as root node to the document. The path from this root
+            node down to the requested directory will also be in the output. If no root pattern is
+            specified or no ancestor of the requested directory matches this pattern, the requested
+            directory will be the root in the output document.<br>
+            The pattern is a regular expression as described in the API docs of the
+            <a class="external" href="http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html">
+            Apache RegExp project</a>.</li>
+        
+<li>include: The include pattern. Specifies the directories and files that should be
+            included. Also a regular expression.</li>
+        
+<li>exclude: The exclude pattern. Specifies the directories and files that should be
+            excluded. Also a regular expression.</li>
+      
+</ul>
+    
+    
+<h1>DTD</h1>
+      
+<p>XML generated by Directory Generator uses namespace
+          <span class="codefrag">http://apache.org/cocoon/status/2.0</span>. The DTD of XML generated by Directory
+          Generator:
+      </p>
+      
+<pre class="code">
+  &lt;!ELEMENT directory (directory|file)*&gt;
+  &lt;!ATTLIST directory
+    name         CDATA #REQUIRED
+    lastModified CDATA #REQUIRED
+    date         CDATA #REQUIRED
+    size         CDATA #REQUIRED
+    requested    CDATA #IMPLIED
+    sort         CDATA #IMPLIED
+    reverse      CDATA #IMPLIED&gt;
+
+  &lt;!ELEMENT file #EMPTY&gt;
+  &lt;!ATTLIST file
+    name         CDATA #REQUIRED
+    lastModified CDATA #REQUIRED
+    date         CDATA #REQUIRED
+    size         CDATA #REQUIRED&gt;
+      </pre>
+    
+    
+<h1>Example</h1>
+      
+<p>The current Directory Generator may generate following xml:</p>
+      
+<pre class="code">
+&lt;dir:directory xmlns:dir="http://apache.org/cocoon/directory/2.0"
+    name="stylesheets" lastModified="1056668768203" date="27.06.03 01:06" size="0"
+    requested="true" sort="name" reverse="false"&gt;
+  &lt;dir:directory name="sites" lastModified="1056668768203" date="27.06.03 01:06" size="0"/&gt;
+  &lt;dir:file name="dynamic-page2html.xsl" lastModified="1056668768203" date="27.06.03 01:06" size="4321"/&gt;
+  &lt;dir:file name="simple-xml2html.xslt" lastModified="1056668768203" date="27.06.03 01:06" size="1234"/&gt;
+&lt;/dir:directory&gt;
+      </pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/meta.xml
new file mode 100644
index 0000000..f3c1b43
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directory-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/directory-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/content_en.html
new file mode 100644
index 0000000..58dd51d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/content_en.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>DirectoryZipArchiver</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the DirectoryZipArchiver reader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>DirectoryZipArchiver</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">resource</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">DirectoryZipArchiver</span> 
+            The <span class="codefrag">DirectoryZipArchiver</span> component creates a compressed zip
+            archive of directory files on the fly.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Scratchpad</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.DirectoryZipArchiver</td>
+        
+</tr>
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">no</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+      
+</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+      
+<h2>Configuration</h2>
+<p>
+        
+</p>
+      
+<h2>Setup</h2>
+<p></p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p></p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p></p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        MM-DD-YY: comment
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages -->
+      
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/meta.xml
new file mode 100644
index 0000000..9d5cc1b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-directoryziparchiver-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/directoryziparchiver-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/content_en.html
new file mode 100644
index 0000000..5475020
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/content_en.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>About the Cocoon Documentation Effort</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="David Crossley" name="DC.Creator">
+<meta content="Diana Shannon" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+
+  
+<p>
+There is a concerted effort underway at this time to improve Cocoon's documentation. This effort is based on the belief that open source documents can be as first-rate as the software on which they are based. However, such an endeavor is entirely dependent upon vital and timely forms of contributions from developers and users alike. Make no mistake about it; everyone is needed and invited to participate in this effort!
+  </p>
+  
+<p>
+While we have a lot to do, there are evolving structures in place to facilitate and enhance your efforts. We have numerous guidelines for authoring documents, a document-specific email list, and a complementary documentation architectural project at <a class="external" href="http://xml.apache.org/forrest/">Forrest</a>. If you choose to become involved, you will discover many like-minded developers and users who care about Cocoon documentation and will support your effort. Here are a few ideas to help you get started. 
+  </p>
+  
+  
+<h2>Cocoon Docs List</h2>
+<p>
+Find out what documentation efforts are already in process among other users
+and committers. Consider joining the
+cocoon-docs <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">mailing list</a>. 
+</p>
+
+  
+<h2>Forms of Document Contributions</h2>
+<p>
+Check out Cocoon's How-To guidelines to learn about the variety of ways to contribute or improve Cocoon documents.
+  </p>
+<ul>
+
+<li>
+<a href="../howto/howto-author-faq.html">How to Author an FAQ</a>
+</li>
+
+<li>
+<a href="../howto/howto-author-howto.html">How to Author a How-To</a>
+</li>
+
+<li>
+<a href="../howto/howto-author-snippet.html">How to Author a Code Snippet</a>
+</li>
+
+<li>
+<a href="../howto/howto-author-core-docs.html">How to Author Core Documentation</a>
+</li>
+	
+</ul>
+
+  
+<h2>Cocoon Wikis</h2>
+<p>
+Cocoon has two promising and complementary wiki efforts underway.
+</p>
+<ul>
+  
+<li>
+
+<a class="external" href="http://wiki.apache.org/cocoon/">Cocoon Wiki</a> focuses on content development for the Cocoon project. It is designed to facilitate document development and collaboration from all levels of Cocoon users. Documents include FAQs, snippets, how-tos, tutorials, RTs (random thoughts), dreams, surveys, and more. The preliminary focus of this the wiki is to serve as a documentation "breeding ground," where docs can "grow" until mature enough to become official cvs docs. However, it already represents a lively and valid document resource in its own right.
+  </li>
+  
+<li>
+
+<a class="external" href="http://www.anyware-tech.com/wikiland/">Wikiland</a> is an ongoing development effort to build a Cocoon-based wiki architecture. Wikiland features a Cocoon dictionary as the pretext to use, test and develop the wiki. The project is seeking Cocoon-oriented developers to further its development. For more information, see the <a class="external" href="http://rossel.free.fr/">Wikiland home page.</a>
+  
+</li>
+  
+</ul>
+  
+    
+<h2>Other Information</h2>
+<p>
+If you're interested in reviewing recent documentation additions or substantive modifications, see the documentation <a href="changes-doc.html"> History of Changes</a>. You may also want to check out the documentation-specific <a href="todo-doc.html">To-Do List</a>. You can also take an advance look at a proposed <a href="proposed-toc.html">table of contents</a> for a revised Cocoon guide. You may also be interested in reviewing some <a href="issues-doc.html">general and specific issues</a> related to Cocoon documentation. Your comments and feedback on any of the above are welcome on the cocoon-docs list.
+  </p>
+
+ 
+
+
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/meta.xml
new file mode 100644
index 0000000..c3335fe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-doc-plan/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/doc.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/content_en.html
new file mode 100644
index 0000000..c1c2b43
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/content_en.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>EncodeURL Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in @doctitle@" name="DC.Subject">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the EncodeURL transformer." name="DC.Description">
+</head>
+<body>
+  
+<h1>EncodeURL Transformer</h1>
+   
+<p>
+    The encodeURL transformer emits encoded URLs.
+    This transformer applies encodeURL method to URLs.
+    You may want to use this transform to avoid doing the manually
+    encodeURL() call.
+   </p>
+   
+<p>
+    Usually this transformer is appended as last transformer before
+    the serialization process. In this case it is possible to encode
+    URLs introduced in the generator, and xslt transformer phase.
+   </p>
+   
+<p>
+    You can specify which attributes hold URL values in order to restrict
+    URL rewriting to specific attributes and values only. In the current implementation
+    you specify include, and exclude patterns as regular expressions, concatting
+    element-name-regexp + "/@" + attribute-name-regexp [ + "=" + attribute-value-regexp ] 
+    whereas the part in brackets [] are optional.
+   </p>
+   
+<p>
+    The EncodeURLTransformer has several configuration options. These options
+    may be specified in the sitemap, or by each request.
+   </p>
+   
+<dl>
+     
+<dt>include-name</dt>
+     
+<dd>RE pattern for including attributes for encode URL rewriting, 
+       The attribute values are encoded, if an 
+       expressions of the form 
+       <span class="codefrag">element-name-regexp/@attribute-name-regexp[=attribute-value-regexp]</span>
+       matches.
+       <br>
+       By default <span class="codefrag">include-name</span> is defined as
+       <span class="codefrag">.*/@href|.*/@action|frame/@src</span>.
+     </dd>
+     
+<dt>exclude-name</dt>
+     
+<dd>RE pattern for excluding attributes from encode URL rewriting,
+       The attribute values are not encoded, if an 
+       expressions of the form 
+       <span class="codefrag">element-name-regexp/@attribute-name-regexp[=attribute-value-regexp]</span>
+       matches.
+       <br>
+       By default <span class="codefrag">exclude-name</span> is defined as
+       <span class="codefrag">img/@src</span>.
+     </dd>
+   
+</dl>
+   
+<ul>
+    
+<li>Name : encodeURL</li>
+    
+<li>Class: org.apache.cocoon.transformation.EncodeURLTransformer</li>
+    
+<li>Cacheable: yes.</li>
+   
+</ul>
+   
+<p>
+    A simple example might help to use the EncodeURLTransformer effectivly:
+   </p>
+   
+<p>
+    Add the EncodeURLTransformer to the components in your sitemap.xmap
+   </p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:transformers default="xslt"&gt;
+  ...
+    &lt;map:transformer name="encodeURL"
+      src="org.apache.cocoon.transformation.EncodeURLTransformer"&gt;
+      &lt;!-- default configuration, explicitly defined --&gt;
+      &lt;include-name&gt;.*/@href|.*/@action|frame/@src&lt;/include-name&gt;
+      &lt;exclude-name&gt;img/@src|(a/@href|iframe/@src)=.*adserver&lt;/exclude-name&gt;
+    &lt;/map:transformer&gt;
+  ...
+</pre>
+   
+<p>
+     Next define in your pipeline to use the EncodeURLTransformer
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="*.xsp"&gt;
+  &lt;map:generate type="serverpages" name="docs/samples/xsp/{1}.xsp"/&gt;
+  &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+  
+  &lt;map:transform type="encodeURL"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+   
+<p>
+    In this example pipeline it is assumed that the attribute
+    <span class="codefrag">href</span> of element <span class="codefrag">a</span> contains an URL which should get 
+    encoded.
+    Moreover the attribute <span class="codefrag">action</span> of any element contains an URL
+    which should get encoded, too.
+    Finally the attribute <span class="codefrag">src</span> of element 
+    <span class="codefrag">frame</span> should get encoded, too.
+   </p>
+   
+<p>
+    The attribute <span class="codefrag">src</span> of element <span class="codefrag">img</span> is excluded from
+    encoding.
+   </p>
+   
+<p>
+     In other words, images are served regardless of the current session, in contrast
+     anchor links, form actions, and frame src are served depending on the current session.
+   </p>
+   
+<p>
+    The encoding itself applies the servlet method <span class="codefrag">response.encodeURL()</span>
+    upon the URL.
+   </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/meta.xml
new file mode 100644
index 0000000..39481ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-encodeurl-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/encodeurl-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/content_en.html
new file mode 100644
index 0000000..2745361
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/content_en.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Notifying Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the Notifying Generator of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Notifying Generator</h1>
+   
+<p>
+    The notifying generator creates XML content describing an error condition.
+    When an error occurs in a pipeline with a defined an error handler, the
+    sitemap manager activates the error generator, feeding it the cause of
+    the error. 
+   </p>
+   
+<ul>
+    
+<li>Name : &lt;notifier&gt;</li>
+    
+<li>Class: org.apache.cocoon.sitemap.NotifyingGenerator</li>
+    
+<li>Cacheable: No.</li>
+    
+<li>Mode: Sitemap internal</li>
+   
+</ul>
+  
+  
+<h1>DTD</h1>
+   
+<p>
+    XML generated by notifying generator uses the 
+    namespace <span class="codefrag">http://apache.org/cocoon/error/2.0</span> and
+    the <span class="codefrag">error</span> prefix.
+   </p>
+   
+<p>
+    Usually the error condition is described by a throwable object.
+    The information of this throwable object is used by the
+    error generator to produce the xml content.
+    The various elements of the xml content include the following.
+   </p>
+   
+<ul>
+    
+<li>
+     The element <span class="codefrag">notify</span> is the root element, having
+     attributes <span class="codefrag">type</span> and <span class="codefrag">sender</span>.
+     The attribute <span class="codefrag">type</span> has fixed value <span class="codefrag">error</span>.
+     The attribute <span class="codefrag">sender</span> describes the sender of the
+     error notification object. In the current implementation, it has 
+     fixed value <span class="codefrag">org.apache.cocoon.sitemap.ErrorNotifier</span>.
+    </li>
+    
+<li>
+     The element <span class="codefrag">title</span> stores the title of the eror notification.
+     In the current implementation, it has fixed value <span class="codefrag">Cocoon error</span>.
+    </li>
+    
+<li>
+     The <span class="codefrag">source</span> element stores the class name of the throwable object
+     of the error notification.
+    </li>
+    
+<li>
+     The <span class="codefrag">message</span> element stores the <span class="codefrag">getMessage()</span> result 
+     of the throwable object of the error notification, and may be empty.
+    </li>
+    
+<li>
+     The <span class="codefrag">description</span> element stores the <span class="codefrag">toString()</span> result 
+     of the throwable object of the error notification.
+    </li>
+    
+<li>
+     Optional <span class="codefrag">extra</span> elements stores nested exceptions
+     of the throwable object of the error notification.
+    </li>
+   
+</ul>
+   
+<pre class="code">
+&lt;!ELEMENT notify (title, source, message, description, extra*)&gt;
+&lt;!ATTLIST notiy 
+  type CDATA #REQUIRED
+  sender CDATA #REQUIRED
+&gt;
+&lt;!ELEMENT title #PCDATA&gt;
+&lt;!ELEMENT source #PCDATA&gt;
+&lt;!ELEMENT message #PCDATA&gt;
+&lt;!ELEMENT description #PCDATA&gt;
+&lt;!ELEMENT extra #PCDATA&gt;
+&lt;!ATTLIST extra description #CDATA&gt;
+&lt;!ELEMENT statusinfo (group|value)*&gt;
+</pre>
+  
+  
+<h1>Example</h1>
+   
+<p>
+    The following example outputs the xml content of 
+    an error generator:
+   </p>
+   
+<pre class="code">
+&lt;?xml version="1.0"
+ encoding="UTF-8"?&gt;
+ 
+&lt;error:notify
+ error:type="error" 
+ error:sender="org.apache.cocoon.sitemap.ErrorNotifier"
+ xmlns:error="http://apache.org/cocoon/error/2.0"&gt;
+ 
+ &lt;error:title&gt;Cocoon error&lt;/error:title&gt;
+ &lt;error:source&gt;java.lang.NullPointerException&lt;/error:source&gt;
+ &lt;error:message&gt;&lt;/error:message&gt;
+ &lt;error:description&gt;&lt;/error:description&gt;
+ &lt;error:extra description=""&gt;&lt;/error:extra&gt;
+&lt;/error:notify&gt;
+</pre>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/meta.xml
new file mode 100644
index 0000000..e0a2ae3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/error-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/content_en.html
new file mode 100644
index 0000000..be07953
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/content_en.html
@@ -0,0 +1,282 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Error Handling</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bj&ouml;rn L&uuml;tkemeier" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Error Handling</h1>
+      
+<p>
+        During the execution of a Cocoon pipeline exceptions may occur within the involved components like generators, transformers etc. There are two possibilities to deal with them: The one would be not to handle them explicitly in the sitemap, which causes them to be logged and a default Cocoon error page to be displayed in the browser. The second is to define an error handling by using the sitemap tag &lt;map:handle-errors&gt;. Therein you are able to define any pipeline, that is executed in case of an exception occurred and displays an appropriate page.
+      </p>
+      
+<h2>ExceptionSelector</h2>
+<p>
+          The ExceptionSelector allows to realize conditional error handling within &lt;map:handle-errors&gt;-tags depending on the type of the occurred exception. Each exception is configured centrally at the selector in the sitemap by associating a symbolic name to its class.
+        </p>
+<p>
+          Furthermore it is possible to define, what exceptions are to be "unrolled". This means, that if an exception has been rethrown embedded in another exception, this original exception can be considered for choosing the correct error handling.
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+&lt;map:selector name="exception" src="org.apache.cocoon.selection.ExceptionSelector"&gt;
+  &lt;exception name="processing" class="ProcessingException" unroll="true"/&gt;
+  &lt;exception name="sax" class="SAXException"/&gt;
+  &lt;exception name="application" class="ApplicationException"/&gt;
+&lt;/map:selector&gt;
+...
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="resource"&gt;
+    ...
+  &lt;/map:match&gt;
+  &lt;map:handle-errors&gt;
+    &lt;map:select type="exception"&gt;
+      &lt;map:when test="processing"&gt;...&lt;/map:when&gt;
+      &lt;map:when test="sax"&gt;...&lt;/map:when&gt;
+      &lt;map:when test="application"&gt;...&lt;/map:when&gt;
+    &lt;/map:select&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipeline&gt;
+          
+        </pre>
+<p>
+          Let's consider the following nested exceptions to occur:
+        </p>
+<ol>
+          
+<li>
+            ProcessingException ( ApplicationException ): The ProcessingException is unrolled, so the error pipeline for "application" will be executed.
+          </li>
+          
+<li>
+            ProcessingException ( ValidationException ): Since ValidationException is not configured at all and therefore unknown, the ProcessingException is not unrolled even if unrolling is enabled. Therefore the pipeline for "processing" will be executed.
+          </li>
+          
+<li>
+            SAXException ( ApplicationException ): The unrolling is not enabled for SAXException, so the pipeline for "sax" will be executed.
+          </li>
+        
+</ol>
+<p>
+          Please notice that the selector configuration is processed from top to bottom and stops at the first matching exception. Therefore the most specific classes must be configured first. This behaviour is the same as with Java catch statements.
+        </p>
+      
+<h2>XPathExceptionSelector</h2>
+<p>
+          The XPathExceptionSelector is an extension to the standard selector described above. It adds the possibility to configure additional conditions for each exception type by using JXPath expressions, that operate on the exception object. This configuration is also done centrally at the selector in the sitemap, where symbolic names are defined for all specific error situations.
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+&lt;map:selector name="exception" src="org.apache.cocoon.selection.XPathExceptionSelector"&gt;
+  &lt;exception name="Denied" class="AuthenticationFailure"&gt;
+    &lt;xpath name="PasswordWrong" test="authCode=10"/&gt;
+    &lt;xpath name="PasswordExpired" test="errorCode=11"/&gt;
+    &lt;xpath name="AccessForbidden" test="errorCode&amp;gt;11"/&gt;
+  &lt;/exception&gt;
+&lt;/map:selector&gt;
+...
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="login"&gt;
+    ...
+  &lt;/map:match&gt;
+  &lt;map:handle-errors&gt;
+    &lt;map:select type="exception"&gt;
+      &lt;map:when test="PasswordWrong"&gt;...&lt;/map:when&gt;
+      &lt;map:when test="PasswordExpired"&gt;...&lt;/map:when&gt;
+      &lt;map:when test="AccessForbidden"&gt;...&lt;/map:when&gt;
+      &lt;map:when test="Denied"&gt;...&lt;/map:when&gt;
+      &lt;map:otherwise&gt;...&lt;/map:otherwise&gt;
+    &lt;/map:select&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipeline&gt;
+          
+        </pre>
+<p>
+          In this example the exception AuthenticationFailure is configured under name "Denied". Additionally three further conditions "PasswordWrong", "PasswordExpired" and "AccessForbidden" are defined by using JXPath expressions. Therefore instances of AuthenticationFailure are expected to have methods getAuthCode() and getErrorCode(). Now the error handler defined for resource "login" has five branches: If situation "PasswordWrong" occurs, which means that an AuthenticationFailure exception with auth code 10 has been thrown, the first error pipeline is executed. If the error code equals to 11 the second pipeline is executed, if it is greater that 11 the third one and all other AuthenticationFailure errors are handled by the fourth one. In any other error situation the fifth branch would be chosen.
+        </p>
+<p>
+          Please notice that the selector stops when it finds the first JXPath expression in the configuration that matches:
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+  &lt;map:selector name="exception" src="org.apache.cocoon.selection.XPathExceptionSelector"&gt;
+    &lt;exception name="application" class="ApplicationException"&gt;
+      &lt;xpath name="error3" test="errorCode&amp;gt;3"/&gt;
+      &lt;xpath name="error6" test="errorCode&amp;gt;6"/&gt;
+    &lt;/exception&gt;
+  &lt;/map:selector&gt;
+  ...
+  &lt;map:pipeline&gt;
+    &lt;map:match pattern="processForm"&gt;
+      ...
+    &lt;/map:match&gt;
+    &lt;map:handle-errors&gt;
+      &lt;map:select type="exception"&gt;
+        &lt;map:when test="error6"&gt;...&lt;/map:when&gt; &lt;!-- handler 1 --&gt;
+        &lt;map:when test="error3"&gt;...&lt;/map:when&gt; &lt;!-- handler 2 --&gt;
+      &lt;/map:select&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+          
+        </pre>
+<p>
+          If an ApplicationException with error code 9 occurs, handler 2 is executed since error situation "error3" is configured before "error6" at the selector even if the expression for "error6" also evaluates to "true".
+        </p>
+      
+<h2>Error Handler Hierarchy</h2>
+<p>
+          The tag &lt;map:handle-errors&gt; may be attached to any &lt;map:pipeline&gt; or the &lt;map:pipelines&gt; tag of the root sitemap or a subsitemap. Therefore it is possible to define two kinds of error handlers: A default handler may be defined within &lt;map:pipelines&gt; for applying to all resources of a sitemap. Alternatively individual handlers may be configured for sets of resources within &lt;map:pipeline&gt;.
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+&lt;map:pipelines&gt;
+  &lt;map:pipeline name="pipe1"&gt;
+    &lt;map:match pattern="res1"&gt;
+      ...
+    &lt;/map:match&gt;
+    &lt;map:handle-errors&gt;
+      &lt;!-- this is an individual handler for pipe1 --&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+  &lt;map:pipeline name="pipe2"&gt;
+    &lt;map:match pattern="res2"&gt;
+      ...
+    &lt;/map:match&gt;
+  &lt;/map:pipeline&gt;
+  &lt;map:pipeline name="pipe3"&gt;
+    &lt;map:match pattern="res3"&gt;
+      ...
+    &lt;/map:match&gt;
+  &lt;/map:pipeline&gt;
+  &lt;map:handle-errors&gt;
+    &lt;!-- this is the default handler for the whole sitemap --&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipelines&gt;
+          
+        </pre>
+<p>
+          In conjunction with the ExceptionSelector resp. the XPathExceptionSelector it is possible to define a hierarchy of error handlers for an application. The behaviour then is the following: If an error occurs within a pipeline, Cocoon at first checks if an individual handler for this pipeline is defined. If so and it is able to handle the error due to its selection the processing terminates. Otherwise Cocoon looks for a default handler of the current sitemap. If one is found it is called. Now there is the same behaviour as above: If it can handle the exception the processing terminates otherwise the searching proceeds within the pipeline where the subsitemap is mounted. This goes on until the default handler of the root sitemap has been considered. If an error could not be handled at all, it is processed by the Cocoon engine in the end.
+        </p>
+<p>
+          Please notice that a &lt;map:otherwise&gt; breaks the hierarchy since all errors will be handled on this level. Therefore all levels above will be called never.
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+Root sitemap:
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    &lt;map:mount uri-prefix="sub" src="sub/"/&gt;
+    &lt;map:handle-errors&gt;
+      &lt;map:select type="exception"&gt;
+        &lt;map:when test="resourceNotFound"&gt;...&lt;/map:when&gt;
+      &lt;/map:select&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+  &lt;map:handle-errors&gt;
+    &lt;map:generate src="generalerror.htm"/&gt;
+    &lt;map:serialize/&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipelines&gt;
+
+Subsitemap:
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    &lt;map:match pattern="processForm"&gt;
+      ...
+    &lt;/map:match&gt;
+    &lt;map:handle-errors&gt;
+      &lt;map:select type="exception"&gt;
+        &lt;map:when test="validation"&gt;...&lt;/map:when&gt;
+      &lt;/map:select&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+  &lt;map:handle-errors&gt;
+    &lt;map:select type="exception"&gt;
+      &lt;map:when test="application"&gt;...&lt;/map:when&gt;
+    &lt;/map:select&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipelines&gt;
+          
+        </pre>
+<p>
+          Let's consider four situations concerning the above example:
+        </p>
+<ol>
+          
+<li>
+            A ValidationException occurs, because for instance the user entered an invalid value: The defined pipeline's handler is called. Since it has a matching &lt;map:when&gt;-section it is able to handle such an exception and therefore the processing is finished.
+          </li>
+          
+<li>
+            An ApplicationException occurs, because for instance a database connection has failed: The pipeline's handler is not able to handle the exception, so next the subsitemap's default handler is called. It has a matching &lt;map:when&gt;-section and is therefore able to handle the exception.
+          </li>
+          
+<li>
+            A ResourceNotFoundException occurs, because for instance some file is missing. Both the pipeline's and the subsitemaps' handlers are not able to handle it. Now Cocoon proceeds after the mount point of the subsitemap and finds its pipeline's handler next. It is able to handle a ResourceNotFoundException and therefore produces the output in this case.
+          </li>
+          
+<li>
+            A NullPointerException occurs, because something went completely wrong in the application: All handlers are not configured for such an exception and so the root sitemaps default handler will apply to it showing a general error page.
+          </li>
+        
+</ol>
+<p>
+          When handling exceptions in error handlers one has to take care about recursion when working with redirects. Consider the following sitemap:
+        </p>
+<p>
+          Example:
+        </p>
+<pre class="code">
+          
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    &lt;map:match pattern="resource"&gt;
+      ...
+      &lt;map:transformer type="foo"/&gt;
+      ...
+    &lt;/map:match&gt;
+    &lt;map:match pattern="error"&gt;
+      ...
+      &lt;map:transformer type="foo"/&gt;
+      ...
+    &lt;/map:match&gt;
+    &lt;map:handle-errors&gt;
+      &lt;map:select type="exception"&gt;
+        &lt;map:when test="connection"&gt;
+          &lt;map:act type="redirect" src="cocoon:/error"/&gt;
+        &lt;/map:when&gt;
+      &lt;/map:select&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+&lt;/map:pipelines&gt;
+          
+        </pre>
+<p>
+          This configuration may lead to an infinite loop: Imagine to call "resource" where the FooTransformer throws a ConnectionException, because the connection to a backend system has broken. The defined error handler will handle it and the used action internally redirects to resource "error". This resource itself uses the FooTransformer to get some data from the backend, which of cause also causes a ConnectionException. This is handled by the error handler, which redirects to resource "error" and so on. Such an infinite loop may also occur when using several "nested" redirects, i.e. the error handler redirects to a resource, which redirects to another resource, which might produce the original exception.
+        </p>
+<p>
+          When defining error handlers for an application such situation must be avoided. An easy rule would be: An error handling routine must never redirect to a resource for which the routine itself is responsible and which might produce the same error as just handled.
+        </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/meta.xml
new file mode 100644
index 0000000..0ff2b75
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-error-handling/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/errorhandling.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/content_en.html
new file mode 100644
index 0000000..2b9150f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/content_en.html
@@ -0,0 +1,273 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Extending Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tom Klaasen" name="DC.Creator">
+</head>
+<body>
+		
+<h1>Introduction</h1>
+			
+<p>If you want to extend the functionality of Apache Cocoon, it may be unclear
+		  how to achieve your goal. This page tries to indicate when to write what, and
+		  to give an overview of what already exists (so you don't duplicate other's
+		  efforts).</p>
+		
+		
+<h1>When to write a Generator</h1>
+			
+<p>From the sitemap documentation: "A <span class="codefrag">Generator</span> generates
+		  XML content as SAX events and initializes the pipeline processing. "</p>
+			
+<p>Thus a <span class="codefrag">Generator</span> is the starting point of a pipeline: it
+		  produces the first SAX events on which all other components of the pipeline are
+		  triggered.</p>
+			
+<p>You may want to write a <span class="codefrag">Generator</span> if you want some other
+		  basis for your SAX events (maybe you want a SAX event every time the
+		  temperature of your CPU changes?) However, before writing a
+		  <span class="codefrag">Generator</span> from scratch, it may be worthwhile to have a look at
+		  <a href="#xsp">XSP</a>, which can create a <span class="codefrag">Generator</span> for
+		you.</p>
+			
+<p>Existing <span class="codefrag">Generator</span>s are: </p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">DirectoryGenerator</span> - Generates an XML directory
+			 listing.</li>
+				
+<li>
+					
+<span class="codefrag">FileGenerator</span> - Does the job of an XML parser: read an
+			 XML file and outputs SAX events.</li>
+				
+<li>
+					
+<span class="codefrag">HTMLGenerator</span> - Takes an HTML URL, makes an XHTML of
+			 it, and outputs the SAX events caused by this XHTML.</li>
+				
+<li>
+					
+<span class="codefrag">ImageDirectoryGenerator</span> - An extension of
+			 DirectoryGenerators that adds extra attributes for image files. </li>
+				
+<li>
+					
+<span class="codefrag">PhpGenerator</span> - Allows PHP to be used as a generator.
+			 Builds upon the PHP servlet functionality. Overrides the output method in
+			 order to pipe the results into SAX events.</li>
+				
+<li>
+					
+<span class="codefrag">RequestGenerator</span> - [FIXME: This looks like just
+			 outputing the request headers, the request parameters and the configuration
+			 parameters. But I don't see any use of it (besides debugging and
+			 demonstration). Are there other situations in which you might want to use
+			 this?]</li>
+				
+<li>
+					
+<span class="codefrag">ServerPagesGenerator</span> - Makes a <span class="codefrag">Generator</span>
+			 at compile time, based on the <span class="codefrag">src</span> file you define in the sitemap.
+			 This one is responsible for making your XSP pages work.</li>
+				
+<li>
+					
+<span class="codefrag">StatusGenerator</span> - Generates an XML representation of
+			 the current status of Cocoon. This can be considered "for administration use",
+			 i.e. your application probably won't deal with this one.</li>
+			
+</ul>
+			
+<p>All these classes are in the <span class="codefrag">org.apache.cocoon.generation</span>
+		  package. In the same package, you find following helper classes and
+		  interfaces:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">Generator</span> - The interface you have to implement if you
+			 want to write a <span class="codefrag">Generator</span>.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractGenerator</span> - Extend this one for easier
+			 building of your own <span class="codefrag">Generator</span>.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractServerPage</span> - [FIXME: This seems to be intended
+			 as basis for the <span class="codefrag">ServerPagesGenerator</span>, but it seems to be obsolete
+			 now?]</li>
+				
+<li>
+					
+<span class="codefrag">ServiceableGenerator</span> - Can be used as base class if you
+			 want your <span class="codefrag">Generator</span> to be an <a href="avalon.html">Avalon
+		Serviceable</a>.</li>
+				
+<li>
+					
+<span class="codefrag">ServletGenerator</span> - If you want to generate servlets.
+		  This is the base class for the <span class="codefrag">ServerPagesGenerator</span>.</li>
+			
+</ul>
+		
+		
+<h1>When to write a Transformer</h1>
+			
+<p>Let's start again from the sitemap documentation: "A
+		  <span class="codefrag">Transformer</span> transforms SAX events in SAX events." In other words,
+		  a <span class="codefrag">Transformer</span> outputs SAX events based on SAX events it
+		  receives.</p>
+			
+<p>You can imagine a <span class="codefrag">Transformer</span> doing many things, from
+		  XSLT processing over database querying to sending mail (and much further, of
+		  course).</p>
+			
+<p>These <span class="codefrag">Transformer</span>s are standard available:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">LogTransformer</span> - This is a class that can be plugged
+			 into a pipeline to print the SAX events which passes through this
+			 <span class="codefrag">Transformer</span> in a readable form to a file. This
+			 <span class="codefrag">Transformer</span>'s main purpose is debugging.</li>
+				
+<li>
+					
+<span class="codefrag">SQLTransformer</span> - Can be used for querying a SQL
+			 database.</li>
+				
+<li>
+					
+<span class="codefrag">XalanTransformer</span> - Probably the most intuitive
+			 <span class="codefrag">Transformer</span>: it applies an XSL sheet to the SAX events it
+			 receives. It uses Xalan in the process.</li>
+				
+<li>
+					
+<span class="codefrag">XIncludeTransformer</span> - To include other XML documents
+			 in your "XML document" (which at transformation time exists in SAX
+			 events).</li>
+				
+<li>
+					
+<span class="codefrag">XTTransformer</span> - The same as
+			 <span class="codefrag">XalanTransformer</span>, but this one uses XT.</li>
+			
+</ul>
+			
+<p>All these classes can be found in
+		  <span class="codefrag">org.apache.cocoon.transformation</span>, along with these helper classes
+		  and interfaces:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">Transformer</span> - The interface each Transformer has to
+			 implement.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractTransformer</span> - A helper base class for
+			 implementing a <span class="codefrag">Transformer</span>.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractDOMTransformer</span> - An Abstract DOM Transformer
+			 (helper base class), for use when a transformer needs a DOM-based view of the
+			 document.</li>
+			
+</ul>
+		
+		
+<h1>When to write a Serializer</h1>
+			
+<p>No need for re-inventing the wheel, so let's start again with the
+		  sitemap documentation: "A <span class="codefrag">Serializer</span> transforms SAX events in
+		  binary or char streams for final client consumption." A <span class="codefrag">Serializer</span>
+		  is always the last step in a pipeline, and gives the client its final result:
+		  an HTML page, a nice PNG picture, a sound stream, or maybe just an XML
+		  document.</p>
+			
+<p>You should write a <span class="codefrag">Serializer</span> if you want to serve a  client with some format that hasn't been provided yet.</p>
+			
+<p>Existing <span class="codefrag">Serializer</span>s:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">FOPSerializer</span>- Make PDF files.</li>
+				
+<li>
+					
+<span class="codefrag">HTMLSerializer</span> - Generate an HTML document.</li>
+				
+<li>
+					
+<span class="codefrag">LinkSerializer</span>- Show the targets of the links in the document.</li>
+				
+<li>
+					
+<span class="codefrag">SVGSerializer</span>- To construct an SVG.</li>
+				
+<li>
+					
+<span class="codefrag">TextSerializer</span> - Generate a text document.</li>
+				
+<li>
+					
+<span class="codefrag">XMLSerializer</span> - Generate an XML document.</li>
+			
+</ul>
+			
+<p>Again, these can be found in the package <span class="codefrag">org.apache.cocoon.serialization</span>. And this package also includes following interfaces and helper classes:</p>
+			
+<ul>
+				
+<li>
+					
+<span class="codefrag">Serializer</span> - The interface every <span class="codefrag">Serializer</span> has to implement.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractTextSerializer</span> - Use this as base for your <span class="codefrag">Serializer</span> if you want to output a character stream.</li>
+				
+<li>
+					
+<span class="codefrag">AbstractSerializer</span> - A more general base class.</li>
+			
+</ul>
+		
+		
+<h1>About Action</h1>
+			
+<p>[FIXME: We have to wait until we can see what is going to happen here. Also, I wonder if this belongs here or should deserve a separate page.]</p>
+			
+<p>The Action part will be used for making Cocoon able to react on form input. This will make Cocoon no longer a simple basis for web publishing, but will make it apt for web interaction as well.</p>
+			
+<p>See <a href="../userdocs/concepts/actions.html">Actions</a>.</p>
+		
+		
+<h1>About XSP</h1>
+			
+<a name="xsp"></a>
+			
+<p>XSP stands for "eXtensible Server Pages". It is the idea to program <span class="codefrag">Generator</span>s by means of XML. The basic idea is to put XML tags like <span class="codefrag">&lt;xsp:logic&gt;</span> in your XML file, with in those tags Java code.</p>
+			
+<div class="note">This is not the proper way to use XSP's. I just mentioned them here so you wouldn't forget their existence. Look to the <a href="../userdocs/xsp/xsp.html">XSP page</a> for more information.</div>
+		
+	
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/meta.xml
new file mode 100644
index 0000000..da9c5d5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-extending-cocoon/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/extending.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/content_en.html
new file mode 100644
index 0000000..0fcfd31
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/content_en.html
@@ -0,0 +1,528 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Features</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Cocoon community" name="DC.Creator">
+</head>
+<body>
+    
+<h1>General information</h1>
+      
+<ul>
+        
+<li>
+          Apache Cocoon is a web development framework built around the concepts 
+          of component-based web development and separation of concerns, ensuring 
+          that people can interact and collaborate on a project without stepping 
+          on each other toes.
+        </li>
+        
+<li>
+          Cocoon implements these concepts around the notion of <strong>component pipelines</strong>, 
+          each component on the pipeline specializing in a particular operation 
+          (usual pipeline uses a Generator, Transformers and a Serializer). This 
+          makes it possible to use a Lego(tm)-like approach in building web solutions, 
+          hooking together components into pipelines without requiring programming.
+        </li>
+        
+<li>
+          
+<strong>Advanced Control Flow</strong>: continuation-based page flow hides 
+          the complexity of request/response processing and is cleanly separated from 
+          the view and data components.
+        </li>
+        
+<li>
+          Cocoon is open source software (based on the 
+          <a href="license.html">Apache Software License</a>).
+        </li>
+        
+<li>
+          Cocoon does not duplicate efforts but tightly integrates many technologies.
+        </li>
+        
+<li>
+          Cocoon is in use at many live sites and on many company networks.
+        </li>
+        
+<li>
+          Cocoon has a strong community, with many active developers and more 
+          than <a href="who.html">15 active committers</a>!
+        </li>
+        
+<li>
+          There is free support from the thousands of people on our
+          <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">mailing lists</a> 
+          and commercial support is available from various companies and consultants.
+        </li>
+        
+<li>
+          There are many Cocoon sessions at different conferences:
+          <ul>
+            
+<li>
+              
+<a class="external" href="http://www.orixo.com/events/gt2003/">Cocoon GetTogether</a>
+            
+</li>
+            
+<li>
+              
+<a class="external" href="http://apachecon.com/">ApacheCon</a>
+            
+</li>
+            
+<li>
+              
+<a class="external" href="http://cocoon.ifs.tuwien.ac.at/">Austrian Cocoon Day</a>  
+            
+</li>
+            
+<li>
+              
+<a class="external" href="http://www.wjax.de/">WJAX</a>
+            
+</li>
+            
+<li>
+              
+<a class="external" href="http://www.jax2003.de/">JAX</a>
+            
+</li>
+          
+</ul>
+        
+</li>
+        
+<li>
+          To get started see the <a href="tracks/first-steps-track.html">"first steps" 
+          documentation track</a>. 
+          Basically you only need to <a class="external" href="http://cocoon.apache.org/mirror.cgi">download</a> 
+          Cocoon, unpack it and follow the simple INSTALL.txt instructions. 
+          A minimal version of the Jetty servlet container is included with Cocoon.
+        </li>
+      
+</ul>
+    
+    
+<h1>Usage scenarios</h1>
+      
+<p>
+      As you would expect, all of these scenarios can be combined.
+    </p>
+      
+<ul>
+        
+<li>
+          Dynamic multi-channel web publishing (see below for the possible 
+          datasources and output formats)
+        </li>
+        
+<li>
+          Create static content (automatically) by separating data from view</li>
+        
+<li>
+          Offline generation modes with Cocoon's own
+          <a href="userdocs/offline/">offline facilities</a>:
+          command-line interface (CLI), ant task, bean. Also with
+          <a class="external" href="http://forrest.apache.org/">Apache Forrest</a>
+          which utilises Cocoon.
+        </li>
+        
+<li>
+          Dynamic document preparation with
+          <a class="external" href="http://forrest.apache.org/">Apache Forrest</a>,
+          the '<span class="codefrag">forrest run</span>' mode. Use many different data input
+          formats, see the transformed result immediately in the browser.
+        </li>
+        
+<li>
+          Advanced web applications with J2EE integration
+          (with separation of your data, the view and the 
+          <a href="userdocs/flow/index.html">flow logic</a> --&gt; this really means you 
+          can change one of the parts without touching another)
+        </li>
+        
+<li>
+          Develop your company portal using the Cocoon Portal framework
+        </li>
+        
+<li>
+          Support multiple clients, layouts and languages (i18n) without code duplication
+        </li>
+        
+<li>
+          Integrate Cocoon with your existing web applications or use it to put 
+          a better face on them (page scraping)
+        </li>
+        
+<li>
+          Add full-text search to any datasource that can be converted to XML (see below)
+        </li>
+        
+<li>
+          Use Cocoon as the base for Enterprise Application Integration (EAI)
+        </li>
+        
+<li>
+          Use Cocoon as the base for your Content Management System (CMS) 
+          (see <a class="external" href="http://cocoon.apache.org/lenya/">Apache Lenya</a>
+          for a Cocoon based CMS)
+        </li>
+        
+<li>
+          Use Cocoon for producing mobile content (mobile phones, pdas)
+        </li>
+        
+<li>
+          Datawarehouse reporting across multiple formats (see xReporter) 
+        </li>
+      
+</ul>
+    
+    
+<h1>Connect your datasources</h1>
+      
+<p>
+       Out of the box, the following data can be converted to XML to be processed 
+       by Cocoon pipelines.
+    </p>
+      
+<ul>
+        
+<li>
+          XML Files
+        </li>
+        
+<li>
+          XML based (Web) services
+        </li>
+        
+<li>
+          RDBMS (via <a class="external" href="http://java.sun.com/products/jdbc/">JDBC</a>, including connection pooling)
+        </li>
+        
+<li>
+          XML databases
+        </li>
+        
+<li>
+          SAP (r) Systems by adding the SAP JavaConnector see 
+          <a class="external" href="http://service.sap.com/connectors/">http://service.sap.com/connectors/</a>
+          (accessible for all SAP (r) customers)
+        </li>
+        
+<li>
+          
+<a class="external" href="http://www.webdav.org/">WebDAV</a>
+        
+</li>
+        
+<li>
+          CVS (supported by the external project <a class="external" href="http://cocoondev.org/projects/cvssource.html">CVSSource</a>)
+        </li>
+        
+<li>
+          Text-based file formats, either using the integrated <a class="external" href="http://chaperon.sourceforge.net/">Chaperon </a>
+          parser for a yacc-like approach to parsing, or the "slop" 
+          component (Simple Line Oriented Parser).
+        </li>
+        
+<li>
+          
+<a class="external" href="http://jakarta.apache.org/velocity/">Velocity templates</a>
+        
+</li>
+        
+<li>
+          
+<a target="_blank" href="userdocs/flow/jxtemplate.html">JXPath/Jexl templates</a>
+        
+</li>
+        
+<li>
+          
+<a target="_blank" href="userdocs/xsp/index.html">eXtensible Server Pages (XSP)</a> with wide range of 
+          logicsheets (database, mailing, ...)
+        </li>
+        
+<li>
+          
+<a class="external" href="http://www.jython.org/">Python (Jython</a>) and generic <a class="external" href="http://jakarta.apache.org/bsf/">BSF support</a>
+        
+</li>
+        
+<li>
+          
+<a class="external" href="http://java.sun.com/products/jsp/">JSP</a>
+        
+</li>
+        
+<li>
+          Filesystem (traversing directory hierarchies)
+        </li>
+        
+<li>
+          Any information provided by environment (request, session)
+        </li>
+        
+<li>
+          
+<a class="external" href="http://www.macromedia.com/">Flash</a>
+        
+</li>
+        
+<li>
+          
+<a class="external" href="http://www.palserv.com/XMidi/">XMidi</a>
+        
+</li>
+        
+<li>
+          
+<a class="external" href="http://www.ietf.org/rfc/rfc1777.txt?number=1777">LDAP - Lightweight Directory Access Protocol</a>
+        
+</li>
+        
+<li>
+          Easily aggregate different datasources
+      </li>
+      
+</ul>
+    
+    
+<h1>Transform your XML based on standards</h1>
+      
+<ul>
+        
+<li>
+          
+<a class="external" href="http://www.w3.org/TR/xslt">XSLT</a> (The default XSLT-Engine is Apache Xalan, XSLTC is included in the 
+          Cocoon distribution, other XSLT-Engines like Saxon can be easily 
+          integrated)        
+        </li>
+        
+<li>
+          
+<a class="external" href="http://stx.sourceforge.net/documents/spec-stx-20030505.html">STX (Streaming Transformations for XML)</a>
+        
+</li>
+        
+<li>
+          
+<a class="external" href="http://www.w3.org/TR/xinclude/">XInclude</a> with 
+          <a class="external" href="http://www.w3.org/TR/xptr/">XPointer</a> framework support  
+      </li>
+      
+</ul>
+    
+    
+<h1>Serialize your XML to various output formats</h1>
+      
+<ul>
+        
+<li>
+         
+<a class="external" href="http://www.w3.org/XML/">XML</a>
+       
+</li>
+        
+<li>
+         
+<a class="external" href="http://www.w3.org/MarkUp/">HTML</a>
+       
+</li>
+       
+<li>
+         
+<a class="external" href="http://www.w3.org/XHTML/">XHTML</a>
+       
+</li>
+        
+<li>
+         
+<a class="external" href="http://www.adobe.com/products/acrobat/adobepdf.html">PDF</a>
+       
+</li>
+        
+<li>
+         
+<a class="external" href="http://www.openoffice.org/">OpenOffice.org/StarOffice</a>
+       
+</li>
+        
+<li>
+         MS Excel
+       </li>
+        
+<li>
+         
+<a class="external" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnrtfspec/html/rtfspec.asp">RTF</a>
+       
+</li>
+        
+<li>
+         Postscript
+       </li>
+        
+<li>
+         Charts (see external project 
+         <a class="external" href="http://www.cocoondev.org/projects/fins.html">Fins</a>)
+       </li>
+        
+<li>
+         
+<a class="external" href="http://www.macromedia.com/">Flash</a>
+       
+</li>
+        
+<li>
+         Plain text
+       </li>
+        
+<li>
+         
+<a class="external" href="http://www.w3.org/TR/SVG/">Scalable Vector Graphics (SVG)</a>
+       
+</li>
+        
+<li>
+         MIDI
+       </li>
+        
+<li>
+         ZIP archives
+       </li>
+      
+</ul>
+    
+    
+<h1>What else we can do for you</h1>
+      
+<ul>
+        
+<li>
+          Coexist and interoperate side-by-side with your existing J2EE solutions 
+          (<a class="external" href="http://java.sun.com/products/ejb/">EJB</a>, 
+           <a class="external" href="http://java.sun.com/products/jms/">JMS</a>, 
+           ...)
+        </li>
+        
+<li>
+          Build your <a href="developing/portal/index.html">Portals</a> based on Cocoon (expect support for JSR168 soon)
+        </li>
+        
+<li>
+          Scheduler - Run background tasks for maintenance, etc.
+        </li>
+        
+<li>
+          Caching on many levels
+        </li>
+        
+<li>
+          Integrated search engine (using
+          <a class="external" href="http://jakarta.apache.org/lucene/">Lucene</a>)
+        </li>
+        
+<li>
+          
+<a href="developing/deli.html">DELI</a> (detect client configuration)
+        </li>
+        
+<li>
+          Catalog Entity Resolver to map to local copies of DTDs and other resources
+        </li>
+        
+<li>
+          Publish your own WebServices
+          (<a class="external" href="http://xml.apache.org/axis/">Apache Axis</a> is integrated)
+        </li>
+        
+<li>
+          
+<a class="external" href="http://java.sun.com/products/javamail/">Java Mail</a> support
+        </li>
+        
+<li>
+          Easy integration of object-relational frameworks
+          (<a class="external" href="http://db.apache.org/ojb/">OJB</a>,
+          <a class="external" href="http://www.hibernate.org/">Hibernate</a>, ...)
+        </li>
+        
+<li>
+          I18n support (translation support)
+        </li>
+        
+<li>
+          Easily extensible by clear interfaces (write your own components 
+          following <a class="external" href="http://avalon.apache.org/">Avalon</a> patterns)
+        </li>
+        
+<li>
+          Many, many examples and samples
+        </li>
+        
+<li>
+          Configurable build mechanism based on
+          <a class="external" href="http://ant.apache.org/">Ant</a>
+          (you decide which parts of Cocoon you need)
+        </li>
+        
+<li>
+          Integration of Java data binding frameworks
+          (<a class="external" href="http://www.castor.org/">Castor</a>, 
+          <a class="external" href="http://jakarta.apache.org/commons/betwixt/">Betwixt</a>)
+      </li>
+      
+</ul>
+    
+    
+<h1>Form handling frameworks</h1>
+      
+<ul>
+        
+<li>
+           Enhanced form handling with strong validation through 
+           <a href="userdocs/forms/index.html">Cocoon Forms</a>
+        
+</li>
+        
+<li>
+           Easy integration of (future) <a class="external" href="http://www.w3.org/TR/xforms/">XForms</a> clients
+        </li>
+      
+</ul>
+    
+    
+<h1>Cocoon deployment and integration</h1>
+      
+<ul>
+        
+<li>
+           Cocoon can be run in every servlet container or J2EE application server that
+           supports Java Servlets 2.3 and above, e.g. 
+           <a class="external" href="http://jakarta.apache.org/tomcat/">Tomcat</a>, 
+           <a class="external" href="http://jetty.mortbay.org/jetty/">Jetty</a>, 
+           <a class="external" href="http://www.jboss.org/">JBoss</a>
+           <a class="external" href="http://www.macromedia.com/software/jrun/">JRun</a>, 
+           <a class="external" href="http://www.caucho.com/">Resin</a>,
+           <a class="external" href="http://www.ibm.com/software/webservers/">Websphere</a>,
+           <a class="external" href="http://www.bea.com/">Weblogic</a>, ...
+        </li>
+        
+<li>
+           Command line execution, without requiring a servlet container
+        </li>
+        
+<li>
+           Embeddable in any Java application
+        </li>
+       
+</ul>
+        
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/meta.xml
new file mode 100644
index 0000000..fe54653
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-features/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>features.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/content_en.html
new file mode 100644
index 0000000..35d3000
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/content_en.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>File Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the file generator of Cocoon." name="DC.Description">
+</head>
+<body>
+     
+<h1>File Generator</h1>
+      
+<p>The file generator reads an xml document from the local file system or from any url.
+                 While url generator may appear to be a more suitable name, it's known as the file generator for historical reasons.</p>
+              
+<p>The file generator is the default generator.</p>
+      
+<p>The location of the source xml document is specified in
+                     the pipeline by the src attribute.</p>
+
+<pre class="code">
+     
+  &lt;map:generate src="document.xml" type="file"/&gt;
+  &lt;!-- The type attribute can be omitted as it is the default generator. --&gt;
+     
+</pre>
+   
+<p>
+    You can also use an absolute filesystem pathname. See the explanation of
+    <a href="../concepts/sitemap.html#file-url">file: URLs</a>
+   
+</p>
+   
+<p>
+     Be careful to only request xml or xhtml documents, and not html documents.
+     You would get surprising results, including network trips for HTML DTDs
+     that are not provided by Cocoon, and xml parsing errors.
+     Use the "HTMLGenerator instead.
+   </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/meta.xml
new file mode 100644
index 0000000..77d918e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-file-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/file-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/content_en.html
new file mode 100644
index 0000000..96a1581
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/content_en.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Filter Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Sven Beauprez" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+<meta content="This document describes the Filter transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Filter Transformer</h1>
+      
+<p>The filter transformer can be used to let only an amount of elements 
+                     through in a given block.</p>
+      
+<ul>
+        
+<li>Name : filter</li>
+        
+<li>Class: org.apache.cocoon.transformation.FilterTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<p>
+When you for example query a database and it returns too many rows too process at once, you 
+might want to take a block of elements, process this block and ignore the rest 
+for now. You can best compare it to a search on Google: they only return 10 
+results in one time, for more results you have to click on another block (page). 
+It wouldn't be wise to process more than 10 elements in the pipeline if you only 
+need to display 10 elements.
+</p>
+
+<p>
+Assume that a query returns 56 row elements (by using the SQLTransformer) and 
+that you only want to display the first 10 elements:
+</p>
+
+<p>
+Output XML from the SQLTransformer:
+</p>
+
+    
+<pre class="code">
+     
+      &lt;rowset nrofrows="56" name="test" 
+xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+        &lt;row&gt;
+          &lt;!-- db record --&gt;
+        &lt;/row&gt;
+        &lt;row&gt;
+          &lt;!-- db record --&gt;
+        &lt;/row&gt;
+        &lt;row&gt;
+          &lt;!-- db record --&gt;
+        &lt;/row&gt;
+
+        ...
+
+        &lt;row&gt;
+          &lt;!-- db record --&gt;
+        &lt;/row&gt;
+      &lt;/rowset&gt;
+     
+    </pre>
+
+
+<p>
+By adding following lines to the sitemap, just under the SQLTransformer, you 
+restrict the results to 10 elements in the first block:
+</p>
+
+    
+<pre class="code">
+     
+      &lt;map:transform type="filter"&gt;
+        &lt;map:parameter name="element-name" value="row"/&gt;
+        &lt;map:parameter name="count" value="10"/&gt;
+        &lt;map:parameter name="blocknr" value="1"/&gt;
+      &lt;/map:transform&gt;
+     
+    </pre>
+
+
+<p>
+output XML:
+</p>
+
+    
+<pre class="code">
+     
+      &lt;rowset nrofrows="56" name="test" 
+xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+        &lt;block id="1"&gt;
+          &lt;row&gt;
+            &lt;!-- db record --&gt;
+          &lt;/row&gt;
+
+          &lt;!-- total of 10 rows --&gt;
+
+          &lt;row&gt;
+            &lt;!-- db record --&gt;
+          &lt;/row&gt;
+        &lt;/block&gt;
+        &lt;block id="2"/&gt;
+        &lt;block id="3"/&gt;
+        &lt;block id="4"/&gt;
+        &lt;block id="5"/&gt;
+        &lt;block id="6"/&gt;
+      &lt;/rowset&gt;
+     
+    </pre>
+
+
+<p>
+To make it more dynamically, put something like {reqCount} and {reqBlock} in the 
+values for count and blocknr respectively. These can be parameters from the 
+request and they can be passed to the sitemap with an action.
+</p>
+
+<p>
+The FilterTransformer is a standalone component, you don't need to use it in 
+combination with the SQLTransformer.
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/meta.xml
new file mode 100644
index 0000000..710eadd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-filter-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/filter-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/content_en.html
new file mode 100644
index 0000000..722e702
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/content_en.html
@@ -0,0 +1,905 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+<meta content="Christopher Oliver" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Flowscript</h1>
+    
+<p>Cocoon Flowscript is a JavaScript API to manage control flow based on an
+        <a class="external" href="http://cvs.cocoondev.org/cgi-bin/viewcvs.cgi/?cvsroot=rhino">extended</a>
+        version of the <a class="external" href="http://www.mozilla.org/rhino">Mozilla Rhino</a> JavaScript interpreter that supports continuations.</p>
+    
+    
+<a name="FOM"></a>
+<h1>Flow Object Model</h1>
+      
+<p>Cocoon provides a set of system objects for use by Flowscripts. We call this set of objects the <em>Flow Object Model</em> (FOM).
+      The Flow Object Model consists of the following objects:</p>
+    
+<ul>
+      
+<li>
+<a href="#cocoon">Cocoon</a>
+</li>
+      
+<li>
+<a href="#request">Request</a>
+</li>
+      
+<li>
+<a href="#response">Response</a>
+</li>
+      
+<li>
+<a href="#session">Session</a>
+</li>
+      
+<li>
+<a href="#context">Context</a>
+</li>
+      
+<li>
+<a href="#cookie">Cookie</a>
+</li>
+      
+<li>
+<a href="#log">Log</a>
+</li>
+      
+<li>
+<a href="#WebContinuation">WebContinuation</a>
+</li>
+    
+</ul>
+    
+<h2>Cocoon Object</h2>
+<a name="cocoon"></a>
+<p>The <span class="codefrag">Cocoon</span> object represents the current Cocoon Sitemap. This is the entry point into the FOM. There is one instance of <span class="codefrag">Cocoon</span> which you may access in your scripts as the global variable <span class="codefrag">cocoon</span>, for example like this:</p>
+<pre class="code">
+         var value = cocoon.request.getAttribute("blah");
+    </pre>
+<p>
+     The <span class="codefrag">Cocoon</span> object supports the following properties and functions:
+    </p>
+<h3>request</h3>
+<p>The current Cocoon request:</p>
+<p>
+    
+<em>Property</em> [<a href="#request">Request</a>] <span class="codefrag">request</span>
+    
+</p>
+<h3>response</h3>
+<p>The current Cocoon response:</p>
+<p>
+    
+<em>Property</em> [<a href="#response">Response</a>] <span class="codefrag">response</span>
+    
+</p>
+<h3>session</h3>
+<p>The current Cocoon session:</p>
+<p>
+    
+<em>Property</em> [<a href="#session">Session</a>] <span class="codefrag">session</span>
+    
+</p>
+<h3>context</h3>
+<p>The current Cocoon application context:</p>
+<p>
+    
+<em>Property</em> [<a href="#context">Context</a>] <span class="codefrag">context</span>
+    
+</p>
+<h3>log</h3>
+<p>A reference to the current logger:</p>
+<p>
+    
+<em>Property</em> [<a href="#log">Log</a>] <span class="codefrag">log</span>
+    
+</p>
+<h3>parameters</h3>
+<p>Any parameters passed to the script by the Cocoon Sitemap</p>
+<p>
+    
+<em>Property</em> <span class="codefrag">[Object] parameters</span>
+    
+</p>
+<h3>sendPage</h3>
+<a name="sendPage"></a>
+<p>
+      
+<em>Function</em> <span class="codefrag">sendPage([String] uri, [Object] bean)</span>
+      
+</p>
+<p>
+      Passes control to the Cocoon sitemap to generate the output page.
+      </p>
+<p>
+        
+<span class="codefrag">uri</span> is the sitemap URI of the page to be sent back to the client. If the URI starts with a slash, it is resolved starting at the root sitemap, otherwise it is resolved relative to the current sitemap. The URI should not contain a scheme (such as cocoon:).
+      </p>
+<p>
+       
+<span class="codefrag">bean</span> is a context object which can be accessed inside this page to extract
+       various values and place them in the generated page.
+      </p>
+<h3>sendPageAndWait</h3>
+<a name="sendPageAndWait"></a>
+<p>
+    
+<em>Function</em> <span class="codefrag">[WebContinuation] sendPageAndWait([String] uri, [Object] bean, [Function] postPipelineCode, [Number] timeToLive)</span>
+    
+</p>
+<p>
+     Passes control to the Cocoon sitemap to generate the output page.
+     </p>
+<p>The flow script is suspended after the page is generated and the whole execution stack
+        saved in the WebContinuation object returned from this function. </p>
+<p>
+<span class="codefrag">uri</span> is the relative URL of the page to be sent back to the client. If the URI starts with a slash, it is resolved starting at the root sitemap, otherwise it is resolved relative to the current sitemap. The URI should not contain a scheme (such as cocoon:).</p>
+<p>
+        
+<span class="codefrag">bean</span> is a context object which can be accessed inside this page to extract
+        various values and place them in the generated page.</p>
+<p>If provided, the <span class="codefrag">postPipelineCode</span> function will be executed after pipeline processing is complete but before the script is suspended. You can use this to release resources that are needed during the pipeline processing but should not become part of the continuation. For example:</p>
+<pre class="code">
+
+function processPage() {
+   var id = ...
+   var bizData = ...
+   var uri = ...
+   var comp = cocoon.getComponent(id);
+   // use comp
+   ...
+   cocoon.sendPageAndWait(uri, bizData, function() {
+      cocoon.releaseComponent(comp);
+      comp = null;
+   });
+}
+</pre>
+<p>
+<span class="codefrag">timeToLive</span> is the time to live in milliseconds for the continuation created.</p>
+<p>The return value is the <a href="#WebContinuation">continuation</a> object.</p>
+<h3>sendStatus</h3>
+<a name="sendStatus"></a>
+<p>
+    
+<em>Function</em> <span class="codefrag">sendStatus([Number] sc)</span>
+    
+</p>
+<p>
+     Sends an empty response with the provided HTTP status code.
+     </p>
+<h3>createPageLocal</h3>
+<a name="createPageLocal"></a>
+<p>
+      
+<em>Function</em> <span class="codefrag">[Object] createPageLocal()</span>
+      
+</p>
+<p>
+      Creates a <em>Page Local</em> object. The returned object behaves like a normal JavaScript object, but restores the property values it had when <a href="#sendPageAndWait">sendPageAndWait</a> was originally called, each time a page is resubmitted (e.g. after hitting the back button). Such objects can be used to associate state with one particular page sent to the browser.
+      </p>
+<h3>processPipelineTo</h3>
+<p>
+    
+<em>Function</em> <span class="codefrag">processPipelineTo([String] uri, [Object] bizData, [java.io.OutputStream] stream)</span>
+</p>
+<p>
+     Call the Cocoon sitemap for the given URI, sending the output of the
+     eventually matched pipeline to the specified <span class="codefrag">OutputStream</span>.</p>
+<p>
+<span class="codefrag">uri</span> is the URI for which the request should be generated. If the URI starts with a slash, it is resolved starting at the root sitemap, otherwise it is resolved relative to the current sitemap. The URI should not contain a scheme (such as cocoon:).</p>
+<p>
+<span class="codefrag">bizData</span> is the business data object
+     to be made available to the forwarded pipeline</p>
+<p>
+<span class="codefrag">stream</span> is an <span class="codefrag">OutputStream</span> where the output should be written to.</p>
+<h3>redirectTo</h3>
+<p>
+    
+<em>Function</em> <span class="codefrag">redirectTo([String] uri)</span>
+</p>
+<p>
+      Send a client-side redirect to the browser. The <span class="codefrag">uri</span> argument is the URI to which the browser should be redirected.
+    </p>
+<h3>createWebContinuation</h3>
+<a name="createWebContinuation"></a>
+<p>
+      
+<em>Function</em> <span class="codefrag">[WebContinuation] createWebContinuation()</span>
+      
+</p>
+<p>
+Creates a new "bookmark" <a href="#WebContinuation">WebContinuation</a> object. When invoked it will cause the script to resume right after the call. By calling this function prior to sendPageAndWait() you can be create a "bookmark" which will cause the page to be redisplayed in the browser. Note: the WebContinuation associated with sendPageAndWait() doesn't do this. Rather it resumes execution after the the page is submitted.
+</p>
+<p>For example:</p>
+<pre class="code">
+
+function processPage() {
+
+  var bkm = cocoon.createWebContinuation();
+  var biz = getBizData();
+  cocoon.sendPageAndWait("uri", 
+                         {bookmark: bkm, biz: biz}, 
+                         function() { releaseData(biz); });
+}
+</pre>
+<p></p>
+<h3>load</h3>
+<p>
+<em>Function</em> <span class="codefrag">load([String] uri)</span>
+</p>
+<p>
+      Load the JavaScript script specified by <span class="codefrag">uri</span>. The Cocoon
+     source resolver is used to resolve <span class="codefrag">uri</span>. 
+    </p>
+<h3>getComponent</h3>
+<p>
+<em>Function</em> <span class="codefrag">Object getComponent([String] id)</span>
+</p>
+<p>
+      Access an Avalon component. 
+    </p>
+<h3>releaseComponent</h3>
+<p>
+<em>Function</em> <span class="codefrag">releaseComponent([Object] component)</span>
+</p>
+<p>
+      Release a pooled Avalon component. 
+    </p>
+<h3>createObject</h3>
+<p>
+<em>Function</em> <span class="codefrag">createObject([JavaClass] componentClass)</span>
+</p>
+<p>
+     Create and setup an object so that it can access the information provided to regular components. This is done by calling the various Avalon lifecycle interfaces implemented by the object.
+    </p>
+<h3>disposeObject</h3>
+<p>
+<em>Function</em> <span class="codefrag">disposeObject([Object] object)</span>
+</p>
+<p>
+     Dispose an object that has been created using <span class="codefrag">createObject</span>.
+    </p>
+    
+<h2>Request Object</h2>
+<a name="request"></a>
+<p>The <span class="codefrag">Request</span> object represents the current Cocoon request. It provides the following functions and properties:</p>
+<h3>get</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] get([String] name)</span>
+</p>
+<p>
+      Get the request parameter or attribute with the specified <span class="codefrag">name</span>. 
+    </p>
+<h3>getAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getAttribute([String] name)</span>
+</p>
+<p>
+      Get the request attribute with the specified <span class="codefrag">name</span>. 
+    </p>
+<h3>getAttributeNames</h3>
+<p>
+<em>Function</em> <span class="codefrag">[java.util.Enumeration] getAttributeNames()</span>
+</p>
+<p>
+      Get an enumeration of request attribute names. 
+    </p>
+<h3>setAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">setAttribute([String] name, [Object] value)</span>
+</p>
+<p>
+      Set the value of a request attribute. 
+    </p>
+<h3>removeAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">removeAttribute([String] name)</span>
+</p>
+<p>
+      Remove the attribute with the name <span class="codefrag">name</span> from this request. 
+    </p>
+<h3>getCharacterEncoding</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String]getCharacterEncoding()</span>
+</p>
+<p>
+      Return the character encoding used by this request.
+    </p>
+<h3>setCharacterEncoding</h3>
+<p>
+<em>Function</em> <span class="codefrag">setCharacterEncoding([String] value)</span>
+</p>
+<p>
+      Set the character encoding used by this request.
+    </p>
+<h3>getContentLength</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Number] getContentLength()</span>
+</p>
+<p>
+      Get the content-length of this request
+    </p>
+<h3>getContentType</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getContentType()</span>
+</p>
+<p>
+      Get the content-type of this request
+    </p>
+<h3>getParameter</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getParameter([String] name)</span>
+</p>
+<p>
+      Get the request parameter with the specified <span class="codefrag">name</span>. 
+    </p>
+<h3>getParameterValues</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Array] getParameterValues([String] name)</span>
+</p>
+<p>
+      Get an array of request parameters with the specified <span class="codefrag">name</span>. 
+    </p>
+<h3>getParameterNames</h3>
+<p>
+<em>Function</em> <span class="codefrag">[java.util.Enumeration] getParameterNames()</span>
+</p>
+<p>
+      Get an enumeration of the parameter names in this request.
+    </p>
+<h3>getAuthType</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getAuthType()</span>
+</p>
+<p>
+      Get the authorization type used in this request.
+    </p>
+<h3>getProtocol</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getProtocol()</span>
+</p>
+<p>
+      Get the protocol used in this request.
+    </p>
+<h3>getScheme</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getScheme()</span>
+</p>
+<p>
+      Get the scheme used in this request.
+    </p>
+<h3>getMethod</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getMethod()</span>
+</p>
+<p>
+      Get the method used in this request.
+    </p>
+<h3>getServerName</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getServerName()</span>
+</p>
+<p>
+      Get the server name of this request.
+    </p>
+<h3>getServerPort</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Number] getServerPort()</span>
+</p>
+<p>
+      Get the server port of this request.
+    </p>
+<h3>getRemoteAddr</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getRemoteAddr()</span>
+</p>
+<p>
+      Get the remote address of this request.
+    </p>
+<h3>isSecure</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] isSecure()</span>
+</p>
+<p>
+      Get the <span class="codefrag">secure</span> property of this request.
+    </p>
+<h3>getLocale</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getLocale()</span>
+</p>
+<p>
+      Get the locale of this request.
+    </p>
+<h3>getLocales</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Array [String]] getLocales()</span>
+</p>
+<p>
+      Get the locales of this request.
+    </p>
+<h3>getCookies</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Array [Cookie]] getCookies()</span>
+</p>
+<p>
+      Get the cookies associated with this request.
+    </p>
+<h3>getHeader</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getHeader([String] name)</span>
+</p>
+<p>
+      Get the header with <span class="codefrag">name</span> from this request.
+    </p>
+<h3>getHeaders</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Array] getHeaders()</span>
+</p>
+<p>
+      Get the headers associated with this request.
+    </p>
+<h3>getHeaderNames</h3>
+<p>
+<em>Function</em> <span class="codefrag">[java.util.Enumeration] getHeaderNames()</span>
+</p>
+<p>
+      Get an enumeration of header names from this request.
+    </p>
+<h3>getRemoteUser</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getRemoteUser()</span>
+</p>
+<p>
+      Get the remote user associated with this request.
+    </p>
+<h3>getUserPrincipal</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getUserPrincipal()</span>
+</p>
+<p>
+      Get the user principal associated with this request.
+    </p>
+<h3>isUserInRole</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] isUserInRole([String] role)</span>
+</p>
+<p>
+      Returns whether the user associated with this request is in the specified <span class="codefrag">role</span>.
+    </p>
+<h3>Properties</h3>
+<p>
+    
+<span class="codefrag">Request</span> properties map to request parameters, i.e. <span class="codefrag">request.blah</span> is equivalent to <span class="codefrag">request.getParameter("blah")</span>.
+    </p>
+    
+<h2>Response Object</h2>
+<a name="response"></a>
+<p>The <span class="codefrag">Response</span> object represents the Cocoon response associated with the current request.</p>
+<p>
+     The response object contains hooks only to the cookies and to the response headers. Everything else will be controlled by the rest of the cocoon pipeline machinery (like output encoding, for example, which should *NOT* be determined by the flow).
+     </p>
+<p>It provides the following functions and properties:</p>
+<h3>createCookie</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Cookie] createCookie([String] name, [String] value)</span>
+</p>
+<p>
+      Creates a new <a href="#cookie">Cookie</a>. 
+    </p>
+<h3>addCookie</h3>
+<p>
+<em>Function</em> <span class="codefrag">addCookie([Cookie] cookie)</span>
+</p>
+<p>
+      Adds <span class="codefrag">cookie</span> to the current response. 
+    </p>
+<h3>containsHeader</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] containsHeader([String] name)</span>
+</p>
+<p>
+      Returns whether the current response contains a header with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>setHeader</h3>
+<p>
+<em>Function</em> <span class="codefrag">setHeader([String] name, [String] value)</span>
+</p>
+<p>
+      Replaces the value of the header with <span class="codefrag">name</span> with <span class="codefrag">value</span>.
+    </p>
+<h3>addHeader</h3>
+<p>
+<em>Function</em> <span class="codefrag">addHeader([String] name, [String] value)</span>
+</p>
+<p>
+      Creates a new header in the current response with the specified <span class="codefrag">name</span> and <span class="codefrag">value</span>.
+    </p>
+<h3>setStatus</h3>
+<p>
+<em>Function</em> <span class="codefrag">setStatus([Number] sc)</span>
+</p>
+<p>
+      Sets the status code for this response.
+    </p>
+    
+<h2>Session Object</h2>
+<a name="session"></a>
+<p>The <span class="codefrag">Session</span> object represents the user session associated with the current Cocoon request.</p>
+<p>It provides the following functions and properties:</p>
+<h3>getAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Object] getAttribute([String] name)</span>
+</p>
+<p>
+      Get the value of the session attribute with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>setAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">setAttribute([String] name, [Object] value)</span>
+</p>
+<p>
+      Set the value of the session attribute with the specified <span class="codefrag">name</span> to <span class="codefrag">value</span>.
+    </p>
+<h3>removeAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">removeAttribute([String] name)</span>
+</p>
+<p>
+      Remove the session attribute with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>invalidate</h3>
+<p>
+<em>Function</em> <span class="codefrag">invalidate()</span>
+</p>
+<p>
+      Invalidate this session, releasing all resources associated with it.
+    </p>
+<h3>isNew</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] isNew()</span>
+</p>
+<p>
+      Returns <span class="codefrag">true</span> if the client does not yet know about the
+      session or if the client chooses not to join the session.  For
+      example, if the server used only cookie-based sessions, and
+      the client had disabled the use of cookies, then a session would
+      be new on each request.
+    </p>
+<h3>getId</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getId()</span>
+</p>
+<p>
+      Returns the unique id associated with this session.
+    </p>
+<h3>getCreationTime</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Number] getCreationTime()</span>
+</p>
+<p>
+      Returns the time when this session was created, measured
+      in milliseconds since midnight January 1, 1970 GMT.
+    </p>
+<h3>getLastAccessedTime</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Number] getLastAccessedTime()</span>
+</p>
+<p>
+      Returns the last time the client sent a request associated with
+      this session, as the number of milliseconds since midnight
+      January 1, 1970 GMT.
+    </p>
+<h3>setMaxInactiveInterval</h3>
+<p>
+<em>Function</em> <span class="codefrag">setMaxInactiveInterval([Number] interval)</span>
+</p>
+<p>
+      Specifies the time, in seconds, between client requests before the
+      contextcontainer will invalidate this session.  A negative time
+      indicates the session should never timeout.
+    </p>
+<h3>getMaxInactiveInterval</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Number] getMaxInactiveInterval()</span>
+</p>
+<p>
+     Returns the maximum time interval, in seconds, that
+     the context container will keep this session open between
+     client accesses. After this interval, the context container
+     will invalidate the session.  The maximum time interval can be set
+     with the <span class="codefrag">setMaxInactiveInterval</span> method.
+     A negative time indicates the session should never timeout.
+    </p>
+<h3>Properties</h3>
+<p>
+      
+<span class="codefrag">Session</span> properties map to session attributes, i.e. <span class="codefrag">session.blah</span> is equivalent to <span class="codefrag">session.getAttribute("blah")</span>.</p>
+    
+<h2>Context Object</h2>
+<a name="context"></a>
+<p>The <span class="codefrag">Context</span> object represents the client context associated with the current Cocoon request.</p>
+<p>It provides the following functions and properties:</p>
+<h3>getAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Object] getAttribute([String] name)</span>
+</p>
+<p>
+      Get the value of the context attribute with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>setAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">setAttribute([String] name, [Object] value)</span>
+</p>
+<p>
+      Set the value of the context attribute with the specified <span class="codefrag">name</span> to <span class="codefrag">value</span>.
+    </p>
+<h3>removeAttribute</h3>
+<p>
+<em>Function</em> <span class="codefrag">removeAttribute([String] name)</span>
+</p>
+<p>
+      Remove the context attribute with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>getInitParameter</h3>
+<p>
+<em>Function</em> <span class="codefrag">getInitParameter([String] name)</span>
+</p>
+<p>
+      Get the value of the context initialization parameter with the specified <span class="codefrag">name</span>.
+    </p>
+<h3>Properties</h3>
+<p>
+      
+<span class="codefrag">Context</span> properties map to context attributes, i.e. <span class="codefrag">context.blah</span> is equivalent to <span class="codefrag">context.getAttribute("blah")</span>. 
+    </p>
+    
+<h2>Cookie Object</h2>
+<a name="cookie"></a>
+<p>
+<span class="codefrag">Cookie</span> provides the following functions and properties:</p>
+<h3>getName</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getName()</span>
+</p>
+<p>
+       Get the name of this cookie.
+    </p>
+<h3>getVersion</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getVersion()</span>
+</p>
+<p>
+       Get the version of this cookie.
+    </p>
+<h3>setVersion</h3>
+<p>
+<em>Function</em> <span class="codefrag">setVersion([String] version)</span>
+</p>
+<p>
+       Set the version of this cookie.
+    </p>
+<h3>getValue</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getValue()</span>
+</p>
+<p>
+       Get the value of this cookie.
+    </p>
+<h3>setValue</h3>
+<p>
+<em>Function</em> <span class="codefrag">setValue([String] value)</span>
+</p>
+<p>
+       Set the value of this cookie.
+    </p>
+<h3>getComment</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getComment()</span>
+</p>
+<p>
+       Get the comment of this cookie.
+    </p>
+<h3>setComment</h3>
+<p>
+<em>Function</em> <span class="codefrag">setComment([String] comment)</span>
+</p>
+<p>
+       Set the comment of this cookie.
+    </p>
+<h3>getDomain</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getDomain()</span>
+</p>
+<p>
+       Get the domain of this cookie.
+    </p>
+<h3>setDomain</h3>
+<p>
+<em>Function</em> <span class="codefrag">setDomain([String] domain)</span>
+</p>
+<p>
+       Set the domain of this cookie.
+    </p>
+<h3>getPath</h3>
+<p>
+<em>Function</em> <span class="codefrag">[String] getPath()</span>
+</p>
+<p>
+       Get the path of this cookie.
+    </p>
+<h3>setPath</h3>
+<p>
+<em>Function</em> <span class="codefrag">setPath([String] path)</span>
+</p>
+<p>
+       Set the path of this cookie.
+    </p>
+<h3>getSecure</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] getSecure()</span>
+</p>
+<p>
+       Get the secure property of this cookie.
+    </p>
+<h3>setSecure</h3>
+<p>
+<em>Function</em> <span class="codefrag">setSecure([Boolean] value)</span>
+</p>
+<p>
+       Set the secure property of this cookie.
+    </p>
+    
+<h2>Log Object</h2>
+<a name="log"></a>
+<p> The <span class="codefrag">Log</span> object provides an interface to the Cocoon logging system.
+    </p>
+<p>
+        It supports the following functions:
+    </p>
+<h3>error</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">error([String] message, [java.lang.Throwable] exception)</span>
+    
+</p>
+<p>
+      Log an error message. If <span class="codefrag">exception</span> is provided its stack trace will also be logged.
+    </p>
+<h3>debug</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">debug([String] message, [java.lang.Throwable] exception)</span>
+    
+</p>
+<p>
+      Log a debug message. If <span class="codefrag">exception</span> is provided its stack trace will also be logged.
+    </p>
+<h3>warn</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">warn([String] message, [java.lang.Throwable] exception)</span>
+    
+</p>
+<p>
+      Log a warning message. If <span class="codefrag">exception</span> is provided its stack trace will also be logged.
+    </p>
+<h3>info</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">info([String] message, [java.lang.Throwable] exception)</span>
+    
+</p>
+<p>
+      Log an information message. If <span class="codefrag">exception</span> is provided its stack trace will also be logged.
+    </p>
+<h3>isErrorEnabled</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[Boolean] isErrorEnabled()</span>
+    
+</p>
+<p>
+      Returns whether error message logging is enabled.
+    </p>
+<h3>isDebugEnabled</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[Boolean] isDebugEnabled()</span>
+    
+</p>
+<p>
+      Returns whether debug message logging is enabled.
+    </p>
+<h3>isWarnEnabled</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[Boolean] isWarnEnabled()</span>
+    
+</p>
+<p>
+      Returns whether warning message logging is enabled.
+    </p>
+<h3>isInfoEnabled</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[Boolean] isInfoEnabled()</span>
+    
+</p>
+<p>
+      Returns whether information message logging is enabled.
+    </p>
+    
+<h2>WebContinuation</h2>
+<a name="WebContinuation"></a>
+<p>A <span class="codefrag">WebContinuation</span> represents a continuation of a Flowscript. Because a user may click on the back button in the browser and restart a saved computation in a continuation, each <span class="codefrag">WebContinuation</span> becomes the parent of a subtree of continuations.
+    </p>
+<p>
+       If there is no parent <span class="codefrag">WebContinuation</span>, the created continuation becomes the root of a tree of <span class="codefrag">WebContinuation</span>s.
+    </p>
+<p>
+       
+<span class="codefrag">WebContinuation</span> objects support the following functions and properties:
+    </p>
+<h3>id</h3>
+<p>
+<em>Property</em> <span class="codefrag">[String] id</span>
+</p>
+<p>Returns the unique string identifier of this Web Continuation.</p>
+<h3>continuation</h3>
+<p>
+<em>Property</em> <span class="codefrag">[Continuation] continuation</span>
+</p>
+<p>Returns the JavaScript continuation associated with this Web Continuation.</p>
+<h3>previousBookmark</h3>
+<p>
+<em>Property</em> <span class="codefrag">[WebContinuation] previousBookmark</span>
+</p>
+<p>Returns a reference to the first bookmark continuation among the pages preceding the one associated with this object, or null if no such bookmark continuation exists. The returned object is the continuation you would invoke to implement a "Back" button.</p>
+<h3>isBookmark</h3>
+<p>
+<em>Function</em> <span class="codefrag">[Boolean] isBookmark()</span>
+</p>
+<p>Returns <span class="codefrag">true</span> if this continuation was <em>not</em> created by <a href="#sendPageAndWait">sendPageAndWait</a>.</p>
+<h3>getParent</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[WebContinuation] getParent()</span>
+    
+</p>
+<p>
+     Get the parent continuation of this continuation.
+    </p>
+<h3>getChildren</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">[Array [WebContinuation]] getChildren()</span>
+    
+</p>
+<p>
+     Get the child continuations of this continuation.
+    </p>
+<h3>invalidate</h3>
+<p>
+        
+<em>Function</em> <span class="codefrag">invalidate()</span>
+    
+</p>
+<p>
+      Invalidates a <span class="codefrag">WebContinuation</span>. This effectively
+      means that the continuation object associated with it will no
+      longer be accessible from Web pages. Invalidating a
+      <span class="codefrag">WebContinuation</span> invalidates all the
+      <span class="codefrag">WebContinuation</span>s which are children of it.    
+    </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/meta.xml
new file mode 100644
index 0000000..7ae0caf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-api/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/api.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/content_en.html
new file mode 100644
index 0000000..086c2a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/content_en.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+    
+<h1>A different approach</h1>
+      
+<p>Web applications are essentially event-driven
+      applications. Such applications have to react to events
+      generated from the client browser, and they respond to these
+      perhaps by changing their internal state and generating a
+      response.</p>
+
+      
+<p>The result is that even a simple application that needs to
+      collect some information from the user using more than one page,
+      has to somehow maintain the input accumulated so far from the
+      user. This input is a characteristic of the application
+      state. Another characteristic of the application state is where
+      the program processing is.</p>
+
+      
+<p>Let's look at an example. Suppose we want to write a very
+      simple calculator, which collects the numbers to be added, as
+      well as the operator, each in a separate page. It would be very
+      nice if we could write something like this:</p>
+
+      
+<pre class="code">
+function calculator()
+{
+  var a, b, operator;
+
+  cocoon.sendPageAndWait("getA.html");
+  a = cocoon.request.get("a");
+
+  cocoon.sendPageAndWait("getB.html");
+  b = cocoon.request.get("b");
+
+  cocoon.sendPageAndWait("getOperator.html");
+  operator = cocoon.request.get("op");
+
+  try {
+    if (operator == "plus")
+      cocoon.sendPage("result.html", {result: a + b});
+    else if (operator == "minus")
+      cocoon.sendPage("result.html", {result: a - b});
+    else if (operator == "multiply")
+      cocoon.sendPage("result.html", {result: a * b});
+    else if (operator == "divide")
+      cocoon.sendPage("result.html", {result: a / b});
+    else
+      cocoon.sendPage("invalidOperator.html", {operator: operator});
+  }
+  catch (exception) {
+    cocoon.sendPage("error.html", {message: "Operation failed: " + exception.toString()});
+  }
+}
+</pre>
+
+      
+<p>In this example, the <span class="codefrag">calculator</span> function is
+      called to start the calculator application. We'd like the
+      <span class="codefrag">sendPageAndWait</span> function to be a special function, that
+      takes as arguments an HTML file to be sent as response, and some
+      optional data that needs to be placed dynamically in it. We
+      would like <span class="codefrag">sendPageAndWait</span> to send the response page and
+      then block the executing thread, until the user clicks on a link
+      in the response page, which sends a request back to the
+      server. This request resumes the processing at the point it was
+      left, right after the call to <span class="codefrag">sendPageAndWait</span>.</p>
+
+      
+<p>This approach looks very powerful, since the flow of pages
+      within the application can be described as a normal
+      program. Using this approach you no longer have to think of your
+      Web application as a finite state machine, which transitions
+      from one state to another, and in the process generates response
+      pages.</p>
+
+      
+<p>A big disadvantage of the approach above is that we need to
+      maintain a thread alive until the user hits the link on the
+      response page. This is clearly very expensive!</p>
+
+      
+<p>It would be very nice if we could capture the state of the
+      application, its stack of function calls, which includes local
+      variables, the global variables and the program counter, and
+      save them into an object. If this object would give us the
+      ability to restart the processing from the point stored in it,
+      this would be what we need!</p>
+
+      
+<h2>What are continuations?</h2>
+<p>A continuation is exactly the type of object that we need.
+  Think of a continuation as an object that, for a given point
+  in your program, contains a snapshot of the stack trace,
+  including all the local variables, and the program
+  counter. You can not only store these things in the
+  continuation object, but also restore the execution of the
+  program from a continuation object. This means that the stack
+  trace and the program counter of the running program become
+  the ones stored in a continuation.</p>
+<p>Continuations are powerful concepts from the world of
+  functional languages, like <a class="external" href="http://www.schemers.org/">Scheme</a>, but they are
+  becoming popular in other languages as well.</p>
+
+  
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/meta.xml
new file mode 100644
index 0000000..460a69d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-continuations/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/continuations.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/content_en.html
new file mode 100644
index 0000000..b52290b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/content_en.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Oliver" name="DC.Creator">
+</head>
+<body>
+    
+<a name="Java"></a>
+<h1>Calling Java</h1>
+    
+<p>
+    You can easily call Java code from your Flowscripts, for example:
+    </p>
+    
+<pre class="code">
+    var map = new java.util.HashMap();
+    map.put("foo", "bar");
+    </pre>
+   
+<h2>Imports</h2>
+<p>Classes in packages under <span class="codefrag">java</span> are accessible directly in your scripts.</p>
+<p>Note that classes under <span class="codefrag">java.lang</span> are not automatically imported, however:</p>
+<pre class="code">var n = new java.lang.Integer(3);</pre>
+<p>All other java packages and classes are accessible under the property <span class="codefrag">Packages</span>:</p>
+<pre class="code">var tree = new Packages.javax.swing.JTree();</pre>
+<p>You can get the effect of Java imports using the <span class="codefrag">importPackage()</span> and <span class="codefrag">importClass()</span> functions:</p>
+<table>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       In Java:
+       </td>
+       <td colspan="1" rowspan="1">
+       In JavaScript:
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       import foo.*;
+       </td>
+       <td colspan="1" rowspan="1">
+       importPackage(Packages.foo);
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       import foo.Bar;
+       </td>
+       <td colspan="1" rowspan="1">
+       importClass(Packages.foo.Bar);
+       </td>
+     
+</tr>
+    
+</table>
+<p>Example:</p>
+<pre class="code">
+    importPackage(java.util);   
+    var set = new TreeSet();</pre>
+<p>
+    
+</p>
+   
+<h2>Bean Properties</h2>
+<p>
+      If your Java classes have getters and setters you can access them as properties in JavaScript:</p>
+<pre class="code">
+    var d = new java.util.Date();
+    d.year = 2003;    // same effect as d.setYear(2003);
+</pre>
+<p></p>
+   
+<h2>Dynamic Compilation</h2>
+<p> 
+    Cocoon includes an embedded Java compiler that can dynamically compile Java source files and load and execute the resulting classes at runtime. During development you can take advantage of this capability to rapidly develop, test, and debug your applications. The Cocoon source resolver is used to locate source files.
+   </p>
+<p>Example:</p>
+<pre class="code">
+
+      // Cause com.xyz.MyClass to be compiled and loaded:
+      importClass(Packages.com.xyz.MyClass); 
+
+      var obj = new MyClass("foo", 123); // call a constructor
+
+      obj.someMethod();              // call a method
+
+</pre>
+<p></p>
+<h3>Configuration</h3>
+<p>You control this behavior by specifying configuration properties in the <span class="codefrag">cocoon.xconf</span> file located in the WEB-INF/ directory of your application. These properties are located in the <span class="codefrag">component-instance</span> element under <span class="codefrag">flow-interpreters</span> whose <span class="codefrag">name</span> attribute has the value <span class="codefrag">"javascript"</span>. The following properties may be set:
+ </p>
+<table>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       Property:
+       </td>
+       <td colspan="1" rowspan="1">
+       Description:
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       reload-scripts
+       </td>
+       <td colspan="1" rowspan="1">
+       Determines whether Cocoon should attempt to detect changes to source files and reload them. This applies to both JavaScript and Java source files
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       check-time
+       </td>
+       <td colspan="1" rowspan="1">
+       Specifies an interval in milliseconds after which Cocoon will check for changes to source files (ignored if reload-scripts is false or unspecified)
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       classpath
+       </td>
+       <td colspan="1" rowspan="1">
+       A semicolon separated list of URL's that will be searched for Java source files
+       </td>
+     
+</tr>
+    
+</table>
+<p>Example:</p>
+<pre class="code">
+  &lt;flow-interpreters default="javascript" logger="flow"&gt;
+    &lt;!-- FOM (Flow Object Model) --&gt;
+    &lt;component-instance 
+class="org.apache.cocoon.components.flow.
+javascript.fom.FOM_JavaScriptInterpreter" name="javascript"&gt;
+      &lt;load-on-startup&gt;resource://org/apache/cocoon/components/
+flow/javascript/fom/fom_system.js&lt;/load-on-startup&gt;
+      &lt;reload-scripts&gt;true&lt;/reload-scripts&gt;
+      &lt;check-time&gt;4000&lt;/check-time&gt;
+      &lt;classpath&gt;file:C:/dev/myPackages;src/java&lt;/classpath&gt;
+      &lt;debugger&gt;enabled&lt;/debugger&gt; 
+    &lt;/component-instance&gt;
+  &lt;/flow-interpreters&gt;
+</pre>
+    
+<p></p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/meta.xml
new file mode 100644
index 0000000..9584149
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-java/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/java.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/content_en.html
new file mode 100644
index 0000000..39c903f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/content_en.html
@@ -0,0 +1,138 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Oliver" name="DC.Creator">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+   
+<h1>JPath Logic Sheet</h1>
+    
+<p>
+     The JPath Logic Sheet is an <a href="../xsp/index.html">XSP</a> logic sheet that allows
+     you to access data from a Cocoon Flowscript in an XSP page and inject it into a Cocoon
+     pipeline. It provides a set of tags (similar to the those defined by
+     <a class="external" href="http://www.w3.org/TR/xslt">XSLT</a>) that allow you to iterate over Java
+     collections (and Java or JavaScript arrays) and to test for the presence of optional or
+     alternate bean properties. It is based on
+     <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache JXPath</a>.
+    </p>
+    
+<p>Samples of this Logic Sheet are avaliable in the XSP implementation of the petstore block</p>
+   
+   
+<h1>Tags</h1>
+    
+<p>The JPath tags are defined in the namespace</p>
+    
+<pre class="code">http://apache.org/xsp/jpath/1.0</pre>
+    
+<h2>if</h2>
+<p>The <span class="codefrag">if</span> tag allows the conditional execution of its body according to value of its <span class="codefrag">test</span> attribute:</p>
+<pre class="code">
+&lt;if test="XPathExpression"&gt;
+  body
+&lt;/if&gt;
+     </pre>
+<p>Example:</p>
+<pre class="code">
+&lt;jpath:if test="cart/numberOfItems = 0"&gt;
+  Your cart is empty
+&lt;/jpath:if&gt;
+     </pre>
+    
+<h2>choose</h2>
+<p>The <span class="codefrag">choose</span> tag performs conditional block execution by its embedded
+        <span class="codefrag">when</span> sub tags. It renders the body of the first <span class="codefrag">when</span> tag whose
+        <span class="codefrag">test</span> condition evaluates to true. If none of the <span class="codefrag">test</span> conditions
+        of its nested <span class="codefrag">when</span> tags evaluate to <span class="codefrag">true</span>, then the body of its
+        <span class="codefrag">otherwise</span> tag is evaluated, if present:</p>
+<pre class="code">
+&lt;choose&gt;
+  &lt;when test="XPathExpression"&gt;
+    body
+  &lt;/when&gt;+
+  &lt;otherwise&gt;
+    body
+  &lt;/otherwise&gt;?
+&lt;/choose&gt;
+     </pre>
+<p>Example:</p>
+<pre class="code">
+&lt;choose&gt;
+  &lt;when test="not(user/loggedIn)"&gt;
+     You're not logged in
+  &lt;/when&gt;
+  &lt;otherwise&gt;
+     You're already logged in
+  &lt;/otherwise&gt;
+&lt;/choose&gt;
+     </pre>
+    
+<h2>value-of</h2>
+<p>The <span class="codefrag">value-of</span> tag evaluates an expression and outputs the result of the evaluation:</p>
+<pre class="code">
+&lt;value-of select="XPathExpression"/&gt;
+     </pre>
+<p>Example:</p>
+<pre class="code">
+&lt;value-of select="cart/numberOfItems"&gt;
+     </pre>
+    
+<h2>for-each</h2>
+<p>The <span class="codefrag">for-each</span> tag allows you to iterate over a collection of objects:</p>
+<pre class="code">
+&lt;for-each select="XPathExpression"&gt;
+  body
+&lt;/for-each&gt;
+     </pre>
+<p>When using XPath expressions within <span class="codefrag">for-each</span> the current element is the
+        context node and can be referenced with XPath dot operator:</p>
+<pre class="code">.</pre>
+<p>Example:</p>
+<pre class="code">
+&lt;for-each select="cart/cartItems[position() &lt;= $count]"&gt;
+   &lt;td&gt;&lt;value-of select="./productId"&gt;&lt;/td&gt;
+&lt;/for-each&gt;
+     </pre>
+    
+<h2>continuation</h2>
+<p>The <span class="codefrag">continuation</span> tag returns the id of the current web continuation of your
+        Flowscript. You can refer to previous continuations by supplying the optional
+        <span class="codefrag">level</span> attribute. Zero is the current level, <span class="codefrag">-1</span> refers to the
+        previous continuation, and so on.</p>
+<pre class="code">
+&lt;continuation [level="Number"]/&gt;
+     </pre>
+<p>Example:</p>
+<pre class="code">
+&lt;xsp:attribute name="action"&gt;&lt;xsp:expr&gt;&lt;jpath:continuation/&gt;+".form"&lt;/xsp:expr&gt;&lt;/xsp:attribute&gt;
+     </pre>
+    
+<h2>set-lenient</h2>
+<div class="note">Since Cocoon 2.1.6</div>
+<p>
+        The <span class="codefrag">set-lenient</span> tag switch the lenient setting of jxpath.
+        By default it is set to false. If set to true, xpaths that don't point to an 
+        object or a set of them will return null (Instead of that annoying exception). 
+        Saves all the checking if you can accept nulls and are sure there are no typos.
+      </p>
+<p>
+        If the tag contains child elements it will scope the setting for the enclosed
+        elements, otherwise it is a global setting. You can't nest &lt;jpath:set-lenient&gt;
+        tags.
+      </p>
+<pre class="code">
+        &lt;jpath:set-lenient lenient="true|false"&gt;
+      </pre>
+<p>Example:</p>
+<pre class="code">
+        &lt;jpath:set-lenient lenient="true"&gt;
+      </pre>
+   
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/meta.xml
new file mode 100644
index 0000000..416bc79
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jpath/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/jpath.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/content_en.html
new file mode 100644
index 0000000..17be6b7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/content_en.html
@@ -0,0 +1,729 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Oliver" name="DC.Creator">
+</head>
+<body>
+  
+<h1>JXTemplate Generator</h1>
+  
+<p>
+The JXTemplate Generator is a page template processor that allows you to inject data from Java and JavaScript objects passed by a Cocoon Flowscript into a Cocoon pipeline. It provides a set of tags (similar to the <a class="external" href="http://java.sun.com/products/jsp/jstl/">JSTL</a> core tags) that allow you to iterate over Java collections (and Java or JavaScript arrays) and to test for the presence of optional or alternate bean properties, as well as embedded expressions to specify conditions and to access the properties of objects. The <em>JX</em>Template Generator gets its name from the embedded expression languages it supports, namely <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache <em>JX</em>Path</a> and <a class="external" href="http://jakarta.apache.org/commons/jexl">Apache <em>J</em>e<em>X</em>l</a>. 
+  </p>
+
+<p>To use the JXTemplate Generator, add a generator entry to your <a href="../concepts/sitemap.html">sitemap</a> with the <span class="codefrag">src</span> attribute set to <span class="codefrag">org.apache.cocoon.generation.JXTemplateGenerator</span>, for example like this:</p>
+
+<pre class="code">
+&lt;map:generators&gt;
+  &lt;map:generator label="content,data" 
+      logger="sitemap.generator.jx" name="jx" 
+         src="org.apache.cocoon.generation.JXTemplateGenerator"/&gt;
+&lt;/map:generators&gt;
+</pre>
+  
+<p></p>
+         
+         
+<h1>Expression Languages</h1>
+  
+<p>
+The JXTemplate Generator supports two embedded expression languages: <a class="external" href="http://jakarta.apache.org/commons/jexl">Jexl</a> and <a class="external" href="http://jakarta.apache.org/commons/jxpath">JXPath</a>. Apache <a class="external" href="http://jakarta.apache.org/commons/jexl">Jexl</a> provides an extended version of the expression language of the <a class="external" href="http://java.sun.com/webservices/docs/1.0/tutorial/doc/JSTL.html">JSTL</a>. Apache <a class="external" href="http://jakarta.apache.org/commons/jxpath">JXPath</a> provides an interpreter of the <a class="external" href="http://www.w3.org/TR/xpath">XPath</a> expression language that can apply XPath expressions to graphs of Java objects of all kinds: JavaBeans, Maps, Servlet contexts, DOM etc, including mixtures thereof.
+ </p>
+  
+<p>
+ Having an embedded expression language allows a page author to access an object using a simple syntax such as
+ </p>
+
+<pre class="code">
+&lt;site signOn="${accountForm.signOn}"&gt;
+ </pre>
+
+<p>Embedded Jexl expressions are contained in <span class="codefrag">${}</span>.</p>
+
+<p>Embedded JXPath expressions are contained in <span class="codefrag">#{}</span>.</p>
+
+<p>The referenced objects may be Java Beans, DOM, or JavaScript objects 
+from a Flowscript. In addition, a special <span class="codefrag">cocoon</span> object providing access to the Cocoon <a href="api.html#FOM">FOM</a> is available as
+both a JXPath and Jexl variable in a template. 
+</p>
+
+<p>The <span class="codefrag">cocoon</span> object contains the following properties:</p>
+
+
+<dl>
+
+<dt>
+<a href="api.html#request">request</a>
+</dt>
+
+<dd>
+<br>The current Cocoon request<br>
+</dd>
+ 
+
+<dt>
+<br>
+<a href="api.html#session">session</a>
+</dt>
+
+<dd>
+<br>The user session associated with the current request<br>
+</dd>
+ 
+
+<dt>
+<br>
+<a href="api.html#context">context</a>
+</dt>
+
+<dd>
+<br>The Cocoon context associated with the current request<br>
+</dd>
+ 
+
+<dt>
+<br>
+<span class="codefrag">parameters</span>
+</dt>
+
+<dd>
+<br>A map containing the parameters passed to the generator in the pipeline<br>
+</dd>
+
+<dt>
+<br>
+<a href="api.html#WebContinuation">continuation</a>
+</dt>
+
+<dd>
+<br>The current Web Continuation from your Flowscript<br>
+</dd>
+
+</dl>
+
+<p>
+Jexl Example:</p>
+
+<pre class="code">
+The content type of the current request is ${cocoon.request.contentType}
+</pre>
+
+<p>
+JXPath Example:</p>
+
+<pre class="code">
+The content type of the current request is #{$cocoon/request/contentType}
+</pre>
+
+<p> 
+You would typically access the <span class="codefrag">id</span> of the Web Continuation:</p>
+
+<pre class="code">
+&lt;form action="${cocoon.continuation.id}"&gt;
+</pre>
+
+<p>You can also reach previous continuations via its <span class="codefrag">parent</span> property:</p>
+
+<pre class="code">
+&lt;form action="${cocoon.continuation.parent.id}" &gt;
+</pre>
+
+<p>or using an XPath expression:</p>
+
+<pre class="code">
+&lt;form action="#{$cocoon/continuation/parent/id}" &gt;
+</pre>
+
+
+<p>Deprecated Variables:</p>
+
+<p>The following variables are deprecated but still supported:</p>
+
+
+<dl>
+
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Request.html">org.apache.cocoon.environment.Request</a> <span class="codefrag">request</span>
+</dt>
+
+<dd>
+<br>The current Cocoon request (deprecated: use <span class="codefrag">cocoon.request</span> instead)<br>
+</dd>
+
+
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Session.html">org.apache.cocoon.environment.Session</a> <span class="codefrag">session</span>
+</dt>
+
+<dd>
+<br>The current user session (deprecated: use <span class="codefrag">cocoon.session</span> instead)<br>
+</dd>
+ 
+
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Context.html">org.apache.cocoon.environment.Context</a> <span class="codefrag">context</span>
+</dt>
+
+<dd>
+<br>The current context (deprecated: use <span class="codefrag">cocoon.context</span> instead)<br>
+</dd>
+
+
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/components/flow/WebContinuation.html">org.apache.cocoon.components.flow.WebContinuation</a> <span class="codefrag">continuation</span>
+</dt>
+
+<dd>
+<br>The current Web Continuation (deprecated: use <span class="codefrag">cocoon.continuation</span> instead)<br>
+</dd>
+
+</dl>
+
+
+
+<h1>Parameters</h1>
+
+<h2>lenient-xpath</h2>
+<p>
+By default XPath evaluation throws an exception if the supplied XPath does not map to an existing property. This constraint can be relaxed by setting the parameter <span class="codefrag">lenient-xpath</span> to <span class="codefrag">true</span>. In the lenient mode evaluation simply returns null if the path maps to nothing.
+</p>
+<p>
+Example:
+</p>
+<pre class="code">
+
+    &lt;map:match pattern="*.jx"&gt;
+      &lt;map:generate type="jx" src="documents/{1}.jx"&gt;
+           &lt;map:parameter name="lenient-xpath" value="true"/&gt;
+      &lt;/map:generate&gt;
+      &lt;map:serialize type="xhtml"/&gt;
+    &lt;/map:match&gt;
+
+</pre>
+
+
+<h1>Tags</h1>
+
+<p>The JXTemplate Generator tags are defined in the namespace</p>
+
+<pre class="code">
+http://apache.org/cocoon/templates/jx/1.0
+</pre>
+
+<h2>template</h2>
+<p>The <span class="codefrag">template</span> tag defines a new template:</p>
+<pre class="code">
+&lt;jx:template xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"&gt;
+   body
+&lt;/jx:template&gt;
+</pre>
+
+<h2>import</h2>
+
+<p>The <span class="codefrag">import</span> tag allows you to include another template within the current template. The content of the imported template is compiled and will be executed in place of the <span class="codefrag">import</span> tag:</p>
+<pre class="code">
+&lt;jx:import uri="URI" [context="Expression"]/&gt;
+</pre>
+<p>The Cocoon source resolver is used to resolve <span class="codefrag">uri</span>. If <span class="codefrag">context</span> is present, then its value is used as the context for evaluating the imported template, otherwise the current context is used.</p>
+
+<h2>set</h2>
+<p>The <span class="codefrag">set</span> tag creates a local alias of an object. The <span class="codefrag">var</span> attribute specifies the name of a variable to assign the object to. The <span class="codefrag">value</span> attribute specifies the object (defaults to <span class="codefrag">body</span> if not present):</p>
+<pre class="code">
+&lt;jx:set var="Name" [value="Value"]&gt;
+   [body]
+&lt;/jx:set&gt;
+</pre>
+<p>If used within a <span class="codefrag">macro</span> definition (see below) variables created by <span class="codefrag">set</span> are only visible within the body of the <span class="codefrag">macro</span>.</p>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:set var="greeting" value="Hello ${user}"/&gt;
+The value of greeting is ${greeting}
+</pre>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:set var="greeting" value="Hello #{user}"/&gt;
+The value of greeting is #{$greeting}
+</pre>
+<p></p>
+
+<h2>if</h2>
+<p>The <span class="codefrag">if</span> tag allows the conditional execution of its body 
+according to value of its <span class="codefrag">test</span> attribute:</p>
+<pre class="code">
+&lt;jx:if test="Expression"&gt;
+  body
+&lt;/jx:if&gt;
+</pre>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:if test="${cart.numberOfItems == 0}"&gt;
+  Your cart is empty
+&lt;/jx:if&gt;
+</pre>
+<p></p>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:if test="#{cart/numberOfItems = 0}"&gt;
+  Your cart is empty
+&lt;/jx:if&gt;
+</pre>
+<p></p>
+
+<h2>choose</h2>
+<p>The <span class="codefrag">choose</span> tag performs conditional block execution by its 
+embedded <span class="codefrag">when</span> sub tags. It renders the body of the first 
+<span class="codefrag">when</span> tag whose <span class="codefrag">test</span> condition evaluates to true. 
+If none of the <span class="codefrag">test</span> conditions of its nested <span class="codefrag">when</span> tags
+evaluate to <span class="codefrag">true</span>, then the body of its <span class="codefrag">otherwise</span> 
+tag is evaluated, if present:</p>
+<pre class="code">
+&lt;jx:choose&gt;
+  &lt;jx:when test="Expression"&gt;
+    body
+  &lt;/jx:when&gt;+
+  &lt;jx:otherwise&gt;
+    body
+  &lt;/jx:otherwise&gt;?
+&lt;/jx:choose&gt;
+</pre>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:choose&gt;
+  &lt;jx:when test="${!user.loggedIn}"&gt;
+    &lt;jx:set var="label" value="Log in"&gt;
+  &lt;/jx:when&gt;
+  &lt;jx:otherwise&gt;
+    &lt;jx:set var="label" value="Log out"&gt;
+  &lt;/jx:otherwise&gt;
+&lt;/jx:choose&gt;
+</pre>
+<p></p>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:choose&gt;
+  &lt;jx:when test="#{not(user/loggedIn)}"&gt;
+    &lt;jx:set var="label" value="Log in"&gt;
+  &lt;/jx:when&gt;
+  &lt;jx:otherwise&gt;
+    &lt;jx:set var="label" value="Log out"&gt;
+  &lt;/jx:otherwise&gt;
+&lt;/jx:choose&gt;
+</pre>
+<p></p>
+
+<h2>out</h2>
+<p>The <span class="codefrag">out</span> tag evaluates an expression and outputs 
+the result of the evaluation:</p>
+<pre class="code">
+&lt;jx:out value="Expression"/&gt;
+</pre>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:out value="${cart.numberOfItems}"&gt;
+</pre>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:out value="#{cart/numberOfItems}"&gt;
+</pre>
+<p></p>
+
+<h2>forEach</h2>
+<p>The <span class="codefrag">forEach</span> tag allows you to iterate over a collection 
+of objects:</p>
+<pre class="code">
+&lt;jx:forEach [var="Name"] [varStatus="Name"] [items="Expression"] 
+               [begin="NumExpr"] [end="NumExpr"] [step="NumExpr"]&gt;
+  body
+&lt;/jx:forEach&gt;
+</pre>
+<p>The <span class="codefrag">items</span> attribute specifies the list of items to iterate over. The <span class="codefrag">var</span> attribute specifies the name of a variable to hold the current item. The <span class="codefrag">begin</span> attribute specifies the element to start with 
+(<span class="codefrag">0</span> = first item, <span class="codefrag">1</span> = second item, ...). 
+If unspecified it defaults to <span class="codefrag">0</span>. The <span class="codefrag">end</span> 
+attribute specifies the item to end with (<span class="codefrag">0</span> = first item, 
+<span class="codefrag">1</span> = second item, ...). If unspecified it defaults to the last item in the list. Every <span class="codefrag">step</span> items are
+processed (defaults to <span class="codefrag">1</span> if <span class="codefrag">step</span> is absent). Either <span class="codefrag">items</span> or both <span class="codefrag">begin</span> and <span class="codefrag">end</span> must be present.</p>
+<p>An alternate form of <span class="codefrag">forEach</span> is supported for convenience when using XPath (since you can specify the selection criteria for the collection using XPath itself):</p>
+<pre class="code">
+&lt;jx:forEach select="XPathExpression"&gt;
+  body
+&lt;/jx:forEach&gt;
+</pre>
+<p>When using XPath expressions within <span class="codefrag">forEach</span> the current element is the context node and can be referenced with: 
+<span class="codefrag">#{.}</span>
+</p>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:forEach var="item" items="${cart.cartItems}" 
+               begin="${start}" end="${count-start}" step="1"&gt;
+   &lt;td&gt;${item.productId}&lt;/td&gt;
+&lt;/jx:forEach&gt;
+</pre>
+<p></p>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:forEach select="#{cart/cartItems[position() &amp;lt;= $count]}}&gt;
+   &lt;td&gt;#{./productId}&lt;/td&gt;
+&lt;/jx:forEach&gt;
+</pre>
+<p>
+If the <span class="codefrag">varStatus</span> attribute is present a variable will be created to hold information about the current loop status. The variable named by the <span class="codefrag">varStatus</span> attribute will hold a reference to an object with the following properties:</p>
+<table>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       Property:
+       </td>
+       <td colspan="1" rowspan="1">
+       Description:
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       current
+       </td>
+       <td colspan="1" rowspan="1">
+       The item from the collection for the current round of iteration
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       index
+       </td>
+       <td colspan="1" rowspan="1">
+       The zero-based index for the current round of iteration
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       count
+       </td>
+       <td colspan="1" rowspan="1">
+       The one-based count for the current round of iteration
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       first
+       </td>
+       <td colspan="1" rowspan="1">
+       True if this is the first round of iteration
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       last
+       </td>
+       <td colspan="1" rowspan="1">
+       True if this is the last round of iteration
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       begin
+       </td>
+       <td colspan="1" rowspan="1">
+       The value of the <span class="codefrag">begin</span> attribute
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       end
+       </td>
+       <td colspan="1" rowspan="1">
+       The value of the <span class="codefrag">end</span> attribute
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       step
+       </td>
+       <td colspan="1" rowspan="1">
+       The value of the <span class="codefrag">step</span> attribute
+       </td>
+     
+</tr>
+    
+</table>
+<p>Jexl Example:</p>
+<pre class="code">
+&lt;jx:forEach items="${items}" varStatus="status"&gt;
+    index=${status.index},
+    count=${status.count},
+    current=${status.current},
+    first=${status.first},
+    last=${status.last},
+    begin=${status.begin},
+    end=${status.end}
+&lt;/jx:forEach&gt;
+</pre>
+<p></p>
+<p>JXPath Example:</p>
+<pre class="code">
+&lt;jx:forEach select="#{items}" varStatus="status"&gt;
+    index=#{$status/index},
+    count=#{$status/count},
+    current=#{$status/current},
+    first=#{$status/first},
+    last=#{$status/last},
+    begin=#{$status/begin},
+    end=#{$status/end}
+&lt;/jx:forEach&gt;
+</pre>
+
+<h2>formatNumber</h2>
+<p>
+The <span class="codefrag">formatNumber</span> tag is used to display numeric data, including currencies and percentages, in a locale-specific manner. It determines from the locale, for example, whether to use a period or a comma for delimiting the integer and decimal portions of a number. Here is its syntax: 
+</p>
+<pre class="code">
+&lt;jx:formatNumber value="Expression"
+    [type="Type"] [pattern="Expression"]
+    [currencyCode="Expression"] [currencySymbol="Expression"]
+    [maxIntegerDigits="Expression"] [minIntegerDigits="Expression"]
+    [maxFractionDigits="Expression"] [minFractionDigits="Expression"]
+    [groupingUsed="Expression"]
+    [var="Name"] [locale="Expression"]&gt;
+</pre>
+<p>
+Only the <span class="codefrag">value</span> attribute is required. It is used to specify the numeric value that is to be formatted.
+</p>
+<p>
+The value of the <span class="codefrag">type</span> attribute should be either "number", "currency", or "percent", and indicates what type of numeric value is being formatted. The default value for this attribute is "number". The <span class="codefrag">pattern</span> attribute takes precedence over the <span class="codefrag">type</span> attribute and allows more precise formatting of numeric values following the pattern conventions of the <span class="codefrag">java.text.DecimalFormat</span> class. 
+</p>
+<p>
+When the <span class="codefrag">type</span> attribute has a value of "currency", the <span class="codefrag">currencyCode</span> attribute can be used to explicitly specify the currency for the numerical value being displayed. As with language and country codes, currency codes are governed by an ISO standard. This code is used to determine the currency symbol to display as part of the formatted value. 
+</p>
+<p>
+Alternatively, you can use the <span class="codefrag">currencySymbol</span> attribute to explicitly specify the currency symbol. Note that as of JDK 1.4 and the associated introduction of the <span class="codefrag">java.util.Currency</span> class, the <span class="codefrag">currencyCode</span> attribute of <span class="codefrag">formatNumber</span> takes precedence over the <span class="codefrag">currencySymbol</span> attribute. For earlier versions of the JDK, however, the <span class="codefrag">currencySymbol</span> attribute takes precedence. 
+</p>
+<p>
+The <span class="codefrag">maxIntegerDigits</span>, <span class="codefrag">minIntegerDigits</span>, <span class="codefrag">maxFractionDigits</span>, and <span class="codefrag">minFractionDigits</span> attributes are used to control the number of significant digits displayed before and after the decimal point. These attributes require integer values. 
+</p>
+<p>
+The <span class="codefrag">groupingUsed</span> attribute takes a <span class="codefrag">Boolean</span> value and controls whether digits before the decimal point are grouped. For example, in English-language locales, large numbers have their digits grouped by threes, with each set of three delimited by a comma. Other locales delimit such groupings with a period or a space. The default value for this attribute is <span class="codefrag">true</span>. 
+</p>
+
+<h2>formatDate</h2>
+<p>The <span class="codefrag">formatDate</span> tag provides facilities to format Date values:</p>
+<pre class="code">
+&lt;jx:formatDate value="Expression" [dateStyle="Style"] 
+  [timeStyle="Style"] [pattern="Expression"] [type="Type"] [var="Name"] 
+  [locale="Expression"]&gt;
+</pre>
+<p>
+Only the value attribute is required. Its value should be an instance of the <span class="codefrag">java.util.Date</span> class, specifying the date and/or time data to be formatted and displayed.</p>
+<p>The optional <span class="codefrag">timeZone</span> attribute indicates the time zone in which the date and/or time are to be displayed. If not present, then the JVM's default time zone is used (that is, the time zone setting specified for the local operating system). </p>
+<p>
+The <span class="codefrag">type</span> attribute indicates which fields of the specified <span class="codefrag">Date</span> instance are to be displayed, and should be either "time", "date", or "both". The default value for this attribute is "date", so if no <span class="codefrag">type</span> attribute is present, the <span class="codefrag">formatDate</span> tag -- true to its name -- will only display the date information associated with the <span class="codefrag">Date</span> instance, specified using the tag's value attribute. 
+</p>
+<p>
+The <span class="codefrag">dateStyle</span> and <span class="codefrag">timeStyle</span> attributes indicate how the date and time information should be formatted, respectively. Valid styles are "default", "short", "medium", "long", and "full". The default value is, naturally, "default", indicating that a locale-specific style should be used. The semantics for the other four style values are as defined by the java.text.DateFormat class. 
+</p>
+<p>
+Rather than relying on the built-in styles, you can use the pattern attribute to specify a custom style. When present, the value of the pattern attribute should be a pattern string following the conventions of the java.text.SimpleDateFormat class. These patterns are based on replacing designated characters within the pattern with corresponding date and time fields. For example, the pattern MM/dd/yyyy indicates that two-digit month and date values and a four-digit year value should be displayed, separated by forward slashes. 
+</p>
+<p>
+If the <span class="codefrag">var</span> attribute is specified, then a String value containing the formatted date is assigned to the named variable. Otherwise, the <span class="codefrag">formatDate</span> tag will write out the formatting results.
+</p>
+
+<h2>macro</h2>
+<p>The <span class="codefrag">macro</span> tag allows you define a new custom tag.</p>
+<pre class="code">
+&lt;jx:macro name="Name" [targetNamespace="Namespace"]&gt;
+  &lt;jx:parameter name="Name" [optional="Boolean"] [default="Value"]/&gt;*
+  body
+&lt;/jx:macro&gt;
+</pre>
+<p> For example:</p>
+<pre class="code">
+&lt;jx:macro name="d"&gt;
+  &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
+&lt;/jx:macro&gt;
+</pre>
+<p>The tag being defined in this example is <span class="codefrag">&lt;d&gt;</span> and it 
+can be used like any other tag:</p>
+<pre class="code">
+&lt;d/&gt;
+</pre>
+<p>However, when this tag is used it will be replaced with a row containing a single empty data cell.</p>
+<p> When such a tag is used, the attributes and content of the tag become available as variables in the body of the <span class="codefrag">macro</span>'s definition, for example:</p>
+<pre class="code">
+&lt;jx:macro name="tablerows"&gt;
+  &lt;jx:parameter name="list"/&gt;
+  &lt;jx:parameter name="color"/&gt;
+  &lt;jx:forEach var="item" items="${list}"&gt;
+    &lt;tr&gt;&lt;td bgcolor="${color}"&gt;${item}&lt;/td&gt;&lt;/tr&gt;
+  &lt;/jx:forEach&gt;
+&lt;/jx:macro&gt;
+</pre>
+<p>The <span class="codefrag">parameter</span> tags in the macro definition define formal parameters, which are replaced with the actual attribute values of the tag when it is used.</p>
+<p>Assuming you had this code in your flowscript:</p>
+<pre class="code">var greatlakes = ["Superior", "Michigan", "Huron", "Erie", "Ontario"];
+   sendPage(uri, {greatlakes: greatlakes});</pre>
+<p>and a template like this:</p>
+<pre class="code">
+&lt;table&gt;
+   &lt;tablerows list="${greatlakes}" color="blue"/&gt;
+&lt;/table&gt;
+</pre>
+<p>When the <span class="codefrag">tablerows</span> tag is used in this situation the following output would be generated:
+</p>
+<pre class="code">
+&lt;table&gt;
+  &lt;tr&gt;&lt;td bgcolor="blue"&gt;Superior&lt;/td&gt;&lt;/tr&gt;
+  &lt;tr&gt;&lt;td bgcolor="blue"&gt;Michigan&lt;/td&gt;&lt;/tr&gt;
+  &lt;tr&gt;&lt;td bgcolor="blue"&gt;Huron&lt;/td&gt;&lt;/tr&gt;
+  &lt;tr&gt;&lt;td bgcolor="blue"&gt;Erie&lt;/td&gt;&lt;/tr&gt;
+  &lt;tr&gt;&lt;td bgcolor="blue"&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
+&lt;/table&gt;
+</pre>
+
+<h2>evalBody</h2>
+<p>Within the body of a macro the <span class="codefrag">evalBody</span> tag treats the content of the macro tag invocation as a <em>JX</em>Template and executes it. For example, the below macro uses this facility to implement the <a class="external" href="http://java.sun.com/products/jsp/jstl/">JSTL</a> <span class="codefrag">forTokens</span> tag:
+</p>
+<pre class="code">
+
+&lt;jx:macro name="forTokens"&gt;
+  &lt;jx:parameter name="var"/&gt;
+  &lt;jx:parameter name="items"/&gt;
+  &lt;jx:parameter name="delims"/&gt;
+  &lt;jx:forEach var="${var}" 
+         items="${java.util.StringTokenizer(items, delims)}"&gt;
+    &lt;jx:evalBody/&gt;
+  &lt;/jx:forEach&gt;
+&lt;/jx:macro&gt;
+ </pre>
+<p>
+The tag produced by this macro can be used like this:
+</p>
+<pre class="code">
+
+&lt;forTokens var="letter" items="a,b,c,d,e,f,g" delims=","&gt;
+  letter = ${letter} &lt;br/&gt;
+&lt;/forTokens&gt;
+ </pre>
+<p>
+which would create the following output:
+</p>
+<pre class="code">
+
+  letter = a  &lt;br/&gt;  
+  letter = b  &lt;br/&gt;  
+  letter = c  &lt;br/&gt;  
+  letter = d  &lt;br/&gt;  
+  letter = e  &lt;br/&gt;  
+  letter = f  &lt;br/&gt;  
+  letter = g  &lt;br/&gt;  
+ </pre>
+
+<h2>eval</h2>
+<p>
+The <span class="codefrag">eval</span> tag permits dynamic evaluation of custom tags. 
+</p>
+<pre class="code">
+&lt;jx:eval select="Expression"/&gt;
+</pre>
+<p>
+Within the body of a macro, information about the current invocation is available via a special variable <span class="codefrag">macro</span>. This variable contains the following properties:
+</p>
+<table>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       Property:
+       </td>
+       <td colspan="1" rowspan="1">
+       Description:
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       arguments
+       </td>
+       <td colspan="1" rowspan="1">
+       A map containing the all of the attributes from the tag invocation
+       </td>
+     
+</tr>
+     
+<tr>
+       
+<td colspan="1" rowspan="1">
+       body
+       </td>
+       <td colspan="1" rowspan="1">
+       A reference to the content of the tag invocation
+       </td>
+     
+</tr>
+   
+</table>
+<p>
+You can store the value of <span class="codefrag">body</span> in another variable and invoke it later using <span class="codefrag">jx:eval</span>. The <span class="codefrag">select</span> attribute of <span class="codefrag">jx:eval</span> specifies an expression that must evaluate to a macro invocation. For example:
+</p>
+<pre class="code">
+
+
+&lt;jx:set var="tags" value="${java.util.HashMap()}"/&gt;
+
+&lt;jx:macro name="dynamic-tag"&gt;
+  &lt;jx:parameter name="id"/&gt;
+  &lt;jx:set var="ignored" value="${tags.put(id, macro.body)}"/&gt;
+&lt;/jx:macro&gt;
+
+&lt;dynamic-tag id="example"&gt;
+  &lt;em&gt;This tag was invoked dynamically&lt;/em&gt;
+&lt;/dynamic-tag&gt;
+
+&lt;p&gt;I'm about to invoke a dynamic tag:&lt;/p&gt;
+&lt;jx:eval select="${tags.example}"/&gt; 
+
+ 
+
+</pre>
+<p>
+The above template produces the following output:
+</p>
+<pre class="code">
+
+&lt;p&gt;I'm about to invoke a dynamic tag:&lt;/p&gt;
+
+  
+&lt;em&gt;This tag was invoked dynamically&lt;/em&gt;
+ 
+</pre>
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/meta.xml
new file mode 100644
index 0000000..4e52de2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-jxtemplate/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/jxtemplate.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/content_en.html
new file mode 100644
index 0000000..194d53a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/content_en.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+<meta content="Christopher Oliver" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Sitemap</h1>
+    
+<p>The Cocoon <a href="../concepts/sitemap.html">Sitemap</a> provides two elements to specify interactions with your Flowscripts: <a href="#flow">flow</a>, and <a href="#call">call</a>.</p>
+     
+<a name="flow"></a> 
+<h2>flow</h2>
+<p>The <span class="codefrag">flow</span> element defines a Flowscript interpreter for a sitemap. The <span class="codefrag">language</span> attribute specifies the target programming language. Currently the only supported language is <span class="codefrag">"javascript"</span>. Its embedded <span class="codefrag">script</span> elements allow you to specify the files that make up the flow for this sitemap. Each <span class="codefrag">script</span> element specifies the URI of a script that will be compiled and executed when this Sitemap is created. The <span class="codefrag">src</span> attribute specifies the URI of the script.</p>
+<pre class="code">
+        &lt;map:flow language="Language"&gt;
+           &lt;map:script src="URI"/&gt;
+        &lt;/map:flow&gt;
+      </pre>
+<p>Example:</p>
+<pre class="code">
+        &lt;map:flow language="javascript"&gt;
+           &lt;map:script src="myApplication.js"/&gt;
+        &lt;/map:flow&gt;
+      </pre>
+      
+<p></p>
+      
+<a name="call"></a>
+<h2>call</h2>
+<p>The <span class="codefrag">call</span> element allows you to call a top-level function in your Flowscript or to invoke an existing continuation.</p>
+<h3>function</h3>
+<a name="callFunction"></a>
+<p>If the <span class="codefrag">function</span> attribute is present, then the Sitemap will invoke a top-level function defined in your Flowscript. The <span class="codefrag">function</span> attribute specifies the name of the function. Zero or more nested <span class="codefrag">parameter</span> elements may be provided to pass arguments to the function.</p>
+<pre class="code">
+        &lt;map:call function="FunctionName"&gt;
+           &lt;map:parameter name="Name" value="Value"/&gt;*
+        &lt;/map:call&gt;
+      </pre>
+<p>Example:</p>
+<pre class="code">
+        &lt;map:flow language="javascript"&gt;
+           &lt;map:script src="myApplication.js"/&gt;
+        &lt;/map:flow&gt;
+        &lt;map:pipelines&gt;
+           &lt;map:pipeline&gt;
+              &lt;map:match pattern="index.html"&gt;
+                 &lt;map:call function="showIndexPage"&gt;
+                   &lt;map:parameter name="paramName" value="Value"/&gt;
+                 &lt;/map:call&gt;
+              &lt;/map:match&gt;
+           &lt;/map:pipeline&gt;
+        &lt;/map:pipelines&gt;
+      </pre>
+<p>Then in <span class="codefrag">myApplication.js</span> you would define a JavaScript function called <span class="codefrag">showIndexPage()</span> such as:</p>
+<pre class="code">
+        function showIndexPage() { 
+            var param = cocoon.parameters.paramName;
+            sendPage("private/index.html", {param: param});
+        }
+      </pre>
+<p></p>
+<h3>continuation</h3>
+<a name="callContinuation"></a>
+<p>If the <span class="codefrag">continuation</span> attribute is present, then the Sitemap will invoke an existing continuation of your Flowscript. The <span class="codefrag">continuation</span> attribute specifies the unique id of the continuation.</p>
+<pre class="code">
+        &lt;map:call continuation="Id"/&gt;
+      </pre>
+<p>Example:</p>
+<pre class="code">
+        &lt;map:match pattern="*.form"&gt;
+          &lt;map:call continuation="{1}"/&gt;
+        &lt;/map:match&gt;
+      </pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/meta.xml
new file mode 100644
index 0000000..f42fda2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-sitemap/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/sitemap.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/content_en.html
new file mode 100644
index 0000000..deac7b5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/content_en.html
@@ -0,0 +1,355 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tony Collen" name="DC.Creator">
+</head>
+<body>
+
+    
+<h1>Tutorial: A Gentle Introduction to Cocoon Control Flow</h1>
+      
+<p>In this tutorial, we will create a simple number guessing game using
+         Cocoon's Control Flow engine.</p>
+      
+<p>After you have Cocoon 2.1 deployed and running, go to where you have
+        Cocoon deployed and create a new subdirectory named <span class="codefrag">game</span>.
+        Cocoon's default main sitemap will automatically mount the sitemap in
+        the subdirectory.</p>
+      
+<p>Create the following <span class="codefrag">sitemap.xmap</span> in the new subdirectory:</p>
+      
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+
+&lt;map:components&gt;
+  &lt;map:generators default="file"&gt;
+    &lt;!-- in this example we use JXTemplateGenerator to insert
+         Flow variables in page content --&gt;
+    &lt;map:generator label="content,data" logger="sitemap.generator.jx"
+                   name="jx" src="org.apache.cocoon.generation.JXTemplateGenerator"/&gt;
+  &lt;/map:generators&gt;
+  &lt;map:transformers default="xslt"/&gt;
+  &lt;map:serializers default="html"/&gt;
+  &lt;map:matchers default="wildcard"/&gt;
+  &lt;map:selectors default="browser"&gt;
+    &lt;map:selector name="exception" src="org.apache.cocoon.selection.XPathExceptionSelector"&gt;
+      &lt;exception name="invalid-continuation"
+                 class="org.apache.cocoon.components.flow.InvalidContinuationException"/&gt;
+      &lt;exception class="java.lang.Throwable" unroll="true"/&gt;
+    &lt;/map:selector&gt;
+  &lt;/map:selectors&gt;
+  &lt;map:actions/&gt;
+  &lt;map:pipes default="caching"/&gt;
+&lt;/map:components&gt;
+
+&lt;map:views/&gt;
+&lt;map:resources/&gt;
+&lt;map:action-sets/&gt;
+
+&lt;map:flow language="javascript"&gt;
+  &lt;!-- Flow will use the javascript functions defined in game.js --&gt;
+  &lt;map:script src="flow/game.js"/&gt;
+&lt;/map:flow&gt;
+
+&lt;map:pipelines&gt;
+  &lt;map:component-configurations&gt;
+    &lt;global-variables/&gt;
+  &lt;/map:component-configurations&gt;
+
+  &lt;map:pipeline&gt;
+    &lt;!-- no filename: call main() in game.js --&gt;
+    &lt;map:match pattern=""&gt;
+      &lt;map:call function="main"/&gt;
+    &lt;/map:match&gt;
+
+    &lt;!-- use JXtemplate to generate page content --&gt;
+    &lt;map:match pattern="*.jx"&gt;
+      &lt;map:generate type="jx" src="documents/{1}.jx"/&gt;
+      &lt;map:serialize type="xhtml"/&gt;
+    &lt;/map:match&gt;
+
+    &lt;!-- .kont URLs are generated by the Flow system for continuations --&gt;
+    &lt;map:match pattern="*.kont"&gt;
+      &lt;map:call continuation="{1}"/&gt;
+    &lt;/map:match&gt;
+
+    &lt;!-- handle invalid continuations --&gt;
+
+    &lt;!-- this style of handling invalidContinuation is now deprecated: --&gt;
+    &lt;!-- this URI will never be called automatically anymore. --&gt;
+    &lt;!-- see handle-errors below --&gt;
+    &lt;map:match pattern="invalidContinuation"&gt;
+      &lt;map:generate src="documents/invalidContinuation.xml"/&gt;
+      &lt;map:serialize type="xml"/&gt;
+    &lt;/map:match&gt;
+
+    &lt;!-- the new non-hardcoded way of handling invalidContinuation --&gt;
+    &lt;map:handle-errors&gt;
+      &lt;map:select type="exception"&gt;
+        &lt;map:when test="invalid-continuation"&gt;
+          &lt;map:generate src="documents/invalidContinuation.html"/&gt;
+          &lt;map:serialize type="xhtml"/&gt;
+        &lt;/map:when&gt;
+      &lt;/map:select&gt;
+    &lt;/map:handle-errors&gt;
+  &lt;/map:pipeline&gt;
+
+&lt;/map:pipelines&gt;
+
+&lt;/map:sitemap&gt;
+</pre>
+      
+<p>Inside the new subdirectory, create two more directories,
+        <span class="codefrag">documents/</span> and <span class="codefrag">flow/</span>.</p>
+      
+<p>Inside <span class="codefrag">documents/</span>, you will store the "views" -- pages to
+        send to the player. Create the file <span class="codefrag">guess.jx</span>, which will
+        be the page the player will enter their guess:</p>
+      
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;html xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"&gt;
+&lt;head&gt;
+  &lt;title&gt;cocoon flow number guessing game&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+  &lt;h1&gt;Guess the Number Between 1 and 10&lt;/h1&gt;
+  &lt;h2&gt;${hint}&lt;/h2&gt;
+  &lt;h3&gt;You've guessed ${guesses} times.&lt;/h3&gt;
+  &lt;form method="post" action="${cocoon.continuation.id}.kont"&gt;
+    &lt;input type="text" name="guess"/&gt;
+    &lt;input type="submit"/&gt;
+  &lt;/form&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+      
+<p>
+        You'll also need a page to display when the person chooses the correct
+        number. Name it <span class="codefrag">success.jx</span> (Again in <span class="codefrag">documents/</span>):
+      </p>
+      
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;html xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"&gt;
+&lt;head&gt;
+  &lt;title&gt;cocoon flow number guessing game&lt;/title&gt;
+&lt;/head&gt;
+&lt;body&gt;
+  &lt;h1&gt;Success!&lt;/h1&gt;
+  &lt;h2&gt;The number was: ${random}&lt;/h2&gt;
+  &lt;h3&gt;It took you ${guesses} tries.&lt;/h3&gt;
+  &lt;p&gt;&lt;a href="./"&gt;Play again&lt;/a&gt;&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+      
+<p>
+        You may notice some strange codes inside the files -- namely things like
+        <span class="codefrag">${random}</span> and <span class="codefrag">${guesses}</span>. They look like
+        variables and they will be replaced with values when the pages are
+        sent to the client. This is where the
+        <a href="jxtemplate.html">JXTemplateGenerator</a> comes in.
+      </p>
+      
+<p>
+        Inside <span class="codefrag">flow/</span> you will store the code that actually controls
+        how this application runs. In the "MVC" pattern the Flow is the
+        "Controller" and it is very powerful.
+      </p>
+      
+<p>
+        Create the following file named <span class="codefrag">game.js</span>:
+      </p>
+      
+<pre class="code">
+function main() {
+
+  var random =  Math.round( Math.random() * 9 ) + 1;
+
+  var hint = "No hint for you!"
+  var guesses = 0;
+
+  while (true) {
+
+    cocoon.sendPageAndWait("guess.jxt", { "random" : random, "hint" : hint,
+                                          "guesses" : guesses} );
+
+    var guess = parseInt( cocoon.request.get("guess") );
+    guesses++;
+
+    if (guess) {
+      if (guess &gt; random) {
+        hint = "Nope, lower!"
+      } else if (guess &lt; random) {
+        hint = "Nope, higher!"
+      } else {
+        break;
+      }
+    }
+  }
+
+  cocoon.sendPage("success.jx", {"random" : random, "guess" : guess,
+                                  "guesses" : guesses} );
+}
+</pre>
+      
+<p>
+        Alright, now let's follow the execution of this Flow and pipeline: The
+        player accesses the URL <span class="codefrag">http://host/cocoon/game/</span> and the
+        &lt;map:match pattern=""&gt; matches, and starts the pipeline.
+      </p>
+      
+<p>
+        The function <span class="codefrag">main()</span> which is referenced in
+        <span class="codefrag">flow/game.js</span> is called and a new Continuation object is
+        created. Without getting into too much detail the state of the Javascript
+        code is saved and can be recalled any number of times.
+      </p>
+      
+<p>We now enter the code in <span class="codefrag">game.js</span>:</p>
+      
+<p>A random number between 1 and 10 is chosen.</p>
+      
+<p>
+        Variables containing a hint for the player and the player's current
+        number of guesses are initialized. The Flow now enters the
+        <span class="codefrag">while(true)</span> loop which basically keeps the game going until
+        the player guesses the correct number.
+      </p>
+      
+<p>We now get to the following line, where things start to get interesting:</p>
+      
+<pre class="code">
+cocoon.sendPageAndWait("guess.jxt", { "random" : random, "hint" : hint, "guesses" : guesses} );
+</pre>
+      
+<p>
+        The Flow layer sends the contents of the URI "guess.jx" which is matched
+        in the sitemap (see above). We also pass an inline Javascript object,
+        containing three key/value pairs, one named "random" which contains the
+        value of the variable random as initialized above, and so on for hint and
+        guesses. The keys are substituted later down the line, when the
+        <span class="codefrag">JXTemplateGenerator</span> comes into play.
+      </p>
+      
+<p>We could also do the following:</p>
+      
+<pre class="code">
+cocoon.sendPageAndWait("guess.jx", { "foo" : random } );
+</pre>
+      
+<p>
+        In this case, the value of random would be able to be substituted in our
+        JXTemplate, but under the name "foo" instead -- we'd just have to make
+        sure we have the correct keyname in our template.
+      </p>
+      
+<p>
+        The Flow Layer also does another interesting thing: it halts the
+        execution of the Javascript! Through the magic of continuations the Flow
+        Layer is able to resume execution of the script at the exact line in
+        which it left off. This creates some very powerful situations with
+        respect to web programming, and forces the reader to think very
+        differently about how web applications are designed.
+      </p>
+      
+<p>
+        Picking back up in the script execution, the client is sent through
+        the pipeline matching "guess.jx". Referring back to the sitemap, we
+        match *.jx, and run the file through the JXTemplateGenerator, which
+        substitutes the keynames for the values sent from the
+        <a href="api.html#sendPageAndWait">cocoon.sendPageAndWait()</a>
+        function.
+      </p>
+      
+<p>
+        One thing to note is in the form which is sent back to Cocoon when the
+        player submits the guess:
+      </p>
+      
+<pre class="code">
+&lt;form method="post" action="${cocoon.continuation.id}.kont"&gt;
+</pre>
+      
+<p>
+        Here, ${cocoon.continuation.id} is resolved to a unique identifier which points
+        to the current continuation. One can think of this somewhat of a session ID.
+      </p>
+      
+<p>
+        When the player submits the form, it is submitted to a unique URL which
+        contains the continuation ID, plus ".kont", which we end up matching in
+        the sitemap:
+      </p>
+      
+<pre class="code">
+&lt;map:match pattern="*.kont"&gt;
+  &lt;map:call continuation="{1}"/&gt;
+&lt;/map:match&gt;
+</pre>
+      
+<p>
+        When Cocoon sees a URL like this, it attempts to restart the continuation
+        with the specified ID and we re-enter the Javascript code where we left
+        off previously.
+      </p>
+      
+<p>
+        We are now back in the Javascript at the line after
+        <a href="api.html#sendPageAndWait">sendPageAndWait()</a>. We create
+        a new variable (an int), which we get from the POST request that was sent
+        by the form. Notice in the form we had
+        <span class="codefrag">&lt;input type="text" name="guess"/&gt;</span> and in the Javascript
+        we get the request parameter by using <span class="codefrag">cocoon.request.get("guess");</span>.
+      </p>
+      
+<p>
+        Now we increment the player's guess count and we test to see if they
+        guessed the correct number. If the guess was too high, we set the hint
+        variable telling them to guess lower, we fall through the bottom of
+        the while loop and we send the guess form back to the player.
+      </p>
+      
+<p>
+        If the guess was too low, we tell them to guess higher, we fall through
+        the loop as well sending the player the form again.
+      </p>
+      
+<p>
+        If the guess was correct, we break out of the main loop and send the
+        player to a different view, this time to "success.jx", and we give the
+        template not only their number and the random number (pointless, yes,
+        because they were the same), but also the number of guesses to tell the
+        player how good or bad at guessing numbers they are.
+      </p>
+      
+<p>
+        The main point of interest in the Flow script at this point is the use of
+        <span class="codefrag">sendPage()</span> instead of <span class="codefrag">sendPageAndWait()</span>.
+        <span class="codefrag">sendPage()</span> works exactly the same, except, yes, you guessed
+        it, we don't halt execution of code and keep processing.
+      </p>
+      
+<p>At this point there's no more code left and the game is over and the Flow stops.</p>
+      
+<p>
+        Another thing to note is the &lt;map:handle-errors&gt; tag in the sitemap.
+        Previously, when a continuation which did not exist was called, the Flow
+        layer would automatically redirect to the URI "invalidContinuation". Now,
+        the Flow layer throws an <span class="codefrag">InvalidContinuationException</span> and
+        you can now handle it as described in the handle-errors tag.
+      </p>
+      
+<p>
+        And that's it! You have now just made your very first application using
+        the Flow layer.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/meta.xml
new file mode 100644
index 0000000..7567949
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-tutorial/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/tutor.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/content_en.html
new file mode 100644
index 0000000..4c89263
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/content_en.html
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Using Cocoon's Control Flow</h1>
+  
+<p>
+    The general flow of actions in an application which uses the control flow
+    is as described below.
+  </p>
+ 
+  
+<p>
+    The request is received by Cocoon and passed to the sitemap for
+    processing. In the sitemap, you can do two things to pass the control to
+    the Control Flow layer:</p>
+  
+<ul>
+    
+<li>
+      You can invoke a JavaScript top-level function to start processing a
+      logically grouped sequences of pages. Each time a response page is
+      being sent back to the client browser from this function, the
+      processing of the JavaScript  code stops at the point the page is
+      sent back, and the HTTP request finishes. Through the magic of
+      continuations, the execution state is saved in a continuation object.
+      Each continuation is given a unique string id, which could be embedded
+      in generated page, so that you can restart the saved computation later
+      on.
+    </li>
+    
+<li>
+      To invoke a top level JavaScript function in the Control Flow, you use
+      the <a href="sitemap.html#callFunction"><span class="codefrag">&lt;map:call&nbsp;function="function-name"/&gt;</span></a>
+      construction.
+    </li>
+    
+<li>
+      To restart the computation of a previously stopped function, you use
+      the <a href="sitemap.html#callContinuation"><span class="codefrag">&lt;map:call&nbsp;continuation="..."/&gt;</span></a> construction.
+      This restarts the computation saved in a continuation object
+      identified by the string value of the <span class="codefrag">continuation</span> attribute.
+      This value could be extracted in the sitemap from the requested URL,
+      from a POST or GET parameter etc. When the computation stored in the
+      continuation object is restarted, it appears as if nothing happened,
+      all the local and global variables have exactly the same values as
+      they had when the computation was stopped.
+    </li>
+  
+</ul>
+ 
+  
+<p>
+    Once the JavaScript function in the control layer is restarted, you're
+    effectively inside the Control Flow. Here you have access to the request
+    parameters, and to the business logic objects. The controller script
+    takes the appropriate actions to invoke the business logic, usually
+    written in Java, creating objects, setting various values on them etc...
+  </p>
+ 
+  
+<p>
+    When the business logic is invoked, you're inside the Model. The business
+    logic takes whatever actions are needed, accessing a database, making a
+    SOAP request to a Web service etc. When this logic finishes, the program
+    control goes back to the Control Flow.
+  </p>
+ 
+  
+<p>
+    Once here, the Control Flow has to decide which page needs to be sent back
+    to the client browser. To do this, the script can invoke one of the
+    <a href="api.html#sendPageAndWait"><span class="codefrag">cocoon.sendPageAndWait()</span></a> or <a href="api.html#sendPage"><span class="codefrag">cocoon.sendPage()</span></a> functions.
+    These functions take two parameters, the relative URL of the page to be
+    sent back to the client, and a context object which can be accessed
+    inside this page to extract various values and place them in the
+    generated page.
+  </p>
+ 
+  
+<p>
+    The second argument to <span class="codefrag">cocoon.sendPageAndWait()</span> and
+    <span class="codefrag">cocoon.sendPage()</span> is a context object, which can be a
+    simple dictionary with values that need to be displayed by the View. More
+    generally any Java or JavaScript object can be passed here, as long as
+    the necessary get methods for the important values are provided.
+  </p>
+ 
+  
+<p>
+    The page specified by the URL is processed by the sitemap, using the
+    normal sitemap rules. The simplest case is a <a href="views.html">generator</a> followed by
+    an XSLT transformation and a serializer. This page generation is part of
+    the View layer. To process a page you can make use of several
+    Cocoon <a href="views.html">generators</a> to retrieve values from the context objects passed by the
+    Control Flow.
+  </p>
+ 
+  
+<p>
+    Going back to the <span class="codefrag">cocoon.sendPageAndWait()</span> and
+    <span class="codefrag">sendPage()</span> functions, there is a big difference
+    between them. The first function will send the response back to the
+    client browser, and will stop the processing of the JavaScript script by
+    saving it into a continuation object. The other function,
+    <span class="codefrag">cocoon.sendPage()</span> will send the response, but it will not
+    stop the computation. This is useful for example when you need to exit a
+    top-level JavaScript function invoked with
+    <span class="codefrag">&lt;map:call&nbsp;function="..."/&gt;</span>.
+  </p>
+ 
+  
+<p>
+    The above explains how MVC could be really achieved in Cocoon with the
+    control flow layer. Note that there is no direct communication between
+    Model and View, everything is directed by the Control Flow by passing to
+    View a context object constructed from Model data.
+  </p>
+ 
+  
+<h2>Basic usage</h2>
+<p>
+    As hinted in the previous section, an application using Cocoon's MVC
+    approach is composed of three layers:</p>
+<ul>
+    
+<li>
+      A JavaScript controller which implements the interaction with the
+      client
+    </li>
+    
+<li>
+     The business logic model which implements your application
+    </li>
+    
+<li>
+      The <a href="views.html">page templates</a>, which describe the content of the pages, and XSLT
+      stylesheets which describe the look of the content.
+    </li>
+  
+</ul>
+<p>
+    In more complex applications, the flow of pages can be thought of smaller
+    sequences of pages which are composed together. The natural analogy is to
+    describe these sequences in separate JavaScript functions, which can then
+    be called either from the sitemap, can call each other freely.
+  </p>
+<p>
+    An example of such an application is the user login and preferences
+    sample 
+  </p>
+<p>
+    This application is composed of four top-level JavaScript functions:</p>
+<ul>
+    
+<li>
+<span class="codefrag">login</span>,</li>
+    
+<li>
+<span class="codefrag">registerUser</span>,</li>
+    
+<li>
+<span class="codefrag">edit</span> and</li>
+    
+<li>
+<span class="codefrag">logout</span>.</li>
+  
+</ul>
+<p>
+    The entry level point in the application can be any of these functions,
+    but in order for a user to use the application, (s)he must login first.
+    Once the user logs in, we want to maintain the Java User object which
+    represents the user between top-level function invocations.
+  </p>
+<p>
+    Even if you don't need complex control flow in your application, you may
+    still choose to use the MVC pattern described above. You can have top-
+    level JavaScript functions which obtain the request parameters, invoke
+    the business logic and then call <span class="codefrag">cocoon.sendPage()</span> to
+    generate a response page and return from the computation. Since there's
+    no continuation object being created by this function, and no global
+    scope being saved, there's no memory resource being eaten. The approach
+    provides a clean way of separating logic and content, and makes things
+    easy to follow, since you have to look at a single script to understand
+    what's going on.
+  </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/meta.xml
new file mode 100644
index 0000000..2de1be2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-using/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/using.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/content_en.html
new file mode 100644
index 0000000..a226893
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/content_en.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christopher Oliver" name="DC.Creator">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Velocity Generator</h1>
+   
+<p>If called from a Flowscript, the Cocoon
+    <a class="external" href="http://jakarta.apache.org/velocity">Velocity</a>
+    <a href="../generators/velocity-generator.html">Generator</a>
+    provides access to the immediate properties of the context object passed to
+    <a href="api.html#sendPage"><span class="codefrag">cocoon.sendPage</span></a> and
+    <a href="api.html#sendPageAndWait"><span class="codefrag">cocoon.sendPageAndWait</span></a>. In addition, the current <a href="api.html#WebContinuation"><span class="codefrag">WebContinuation</span></a>
+    is also available as a variable named <span class="codefrag">$continuation</span>. You would typically access
+    its <span class="codefrag">id</span>:</p>
+   
+<pre class="code">
+  &lt;form action="$continuation.id"&gt;
+   </pre>
+   
+<p>You can also reach previous continuations by using the <span class="codefrag">getParent()</span> function:</p>
+   
+<pre class="code">
+  &lt;form action="$continuation.getParent().id" &gt;
+   </pre>
+   
+<p>In addition the following implicit objects are always available in the Velocity context:</p>
+   
+<dl>
+    
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Request.html">Request</a> <span class="codefrag">$request</span> 
+</dt>
+    
+<dd>The current Cocoon request</dd>
+    
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Response.html">Response</a> <span class="codefrag">$response</span> 
+</dt>
+    
+<dd>The Cocoon response associated with the current request</dd>
+    
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Session.html">Session</a> <span class="codefrag">$session</span> 
+</dt>
+    
+<dd>The Cocoon session associated with the current request</dd>
+    
+<dt>
+<a href="../../../apidocs/org/apache/cocoon/environment/Context.html">Context</a> <span class="codefrag">$context</span> 
+</dt>
+    
+<dd>The Cocoon context associated with the current request</dd>
+    
+<dt>
+<span class="codefrag">org.apache.avalon.framework.parameters.Parameters</span> <span class="codefrag">$parameters</span> 
+</dt>
+    
+<dd>Any parameters passed to the generator in the pipeline</dd>
+   
+</dl>
+   
+<p>
+   Cocoon installs a Velocity introspector that makes it possible for you
+   to access JavaScript objects and arrays in your templates, as well as Java objects. For example, assuming you had a Flowscript like this:</p>
+   
+<pre class="code">
+    sendPage("myTemplate.vm", {colors: ["red", "blue", "yellow"]});
+   </pre>
+   
+<p>
+    You could do this in <span class="codefrag">myTemplate.vm</span>:</p>
+    
+<pre class="code">
+    &lt;select name="colors"&gt;
+    #foreach ($color in $colors) 
+      &lt;option value="$color"&gt;$color&lt;/option&gt;
+    #end
+    &lt;/select&gt;
+    </pre>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/meta.xml
new file mode 100644
index 0000000..1f1c8a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-velocity/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/velocity.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/content_en.html
new file mode 100644
index 0000000..dfea0cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/content_en.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+<meta content="Christopher Oliver" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Flowscript-aware Generators</h1>
+   
+<p>The second argument to <a href="api.html#sendPage"><span class="codefrag">cocoon.sendPage()</span></a> and
+    <a href="api.html#sendPageAndWait"><span class="codefrag">cocoon.sendPageAndWait()</span></a> is a context object,
+    which can be a simple dictionary with values that need to be displayed by the page. More
+    generally any Java or JavaScript object can be passed here, as long as the necessary <em>get</em>
+    methods for the important values are provided.</p>
+   
+<p>The page specified by the URL is processed by the sitemap, using the normal sitemap rules.</p>
+   
+<p>Several Cocoon generators are provided that allow you to access the context object and inject
+    its values into a pipeline. Currently, these are the
+    <a href="jxtemplate.html">JXTemplate Generator</a>,
+    <a href="jpath.html">JPath XSP Logic Sheet</a> and
+    <a href="velocity.html">Velocity Generator</a>.
+   </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/meta.xml
new file mode 100644
index 0000000..7a7955e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-views/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/views.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/content_en.html
new file mode 100644
index 0000000..8f3e88b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/content_en.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Advanced Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Cocoon and continuations</h1>
+  
+<p>With continuations in the language, you can essentially
+  store the continuation of <span class="codefrag">sendPageAndWait()</span> (think of all
+  the stack trace, and the program counter), put it in a global
+  hash table associated with an id. The id is then encoded in
+  the <span class="codefrag">response.xml</span> page as an URL. When the user
+  clicks on that URL, on the server side the associated
+  continuation is resumed. Resuming the processing happens as if
+  nothing was stopped, you get all the stack trace back, and all
+  the local variables.</p>
+
+  
+<p>So instead of using beans to store things in session, you
+  use normal variables in a program. Since each user has its own
+  version of the program, all the local variables in the program
+  are separate between users.</p>
+
+  
+<p>With this approach clicking the <em>Back</em> button in the
+  browser is no longer a hassle to deal with for you as a
+  server-side programmer. They will simply refer to past
+  continuations objects, which have their own state of the local
+  variables.</p>
+
+  
+<p>Since continuations are objects, you can also store them in
+  a database, for really long-lived session, just like you do
+  with session beans.</p>
+  
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/meta.xml
new file mode 100644
index 0000000..3c7045b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow-workings/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/how-does-it-work.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/content_en.html
new file mode 100644
index 0000000..46602de
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/content_en.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apache Cocoon - Control Flow</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Ovidiu Predescu" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Control Flow</h1>
+      
+<p>Cocoon has advanced control flow, the ability to describe the
+      order of Web pages that have to be sent to the client, at any
+      given point in time in an application.</p>
+
+      
+<p>Traditional Web applications try to model the control flow of
+      a Web application by modeling the application as a finite state
+      machine (FSM). In this model, the Web application is composed of
+      multiple states, but the application can be only in one state at
+      a time. Any request received by the application transitions it
+      into a different state. During such a transition, the application
+      may perform various side-effects, such as updating objects
+      either in memory or in a database. Another important side-effect
+      of such a transition is that a Web page is sent back to the
+      client browser.</p>
+
+      
+<p>For simple Web applications, this model works fine. However,
+      as the application grows, the number of states and transitions
+      between them grows as well, and it becomes hard to visualize
+      what's happening in the application.</p>
+
+      
+<p>Moreover, the interactions in some applications are more
+      complex than a simple finite state machine. In such cases it's
+      much easier to think of and implement the application as a program,
+      rather than a FSM.</p>
+
+      
+<p>By using a high level programming concept called
+      <em>continuations</em>, Cocoon tries to solve this problem, and
+      promises to allow the control flow in Web applications to be
+      modeled as a normal program.</p>
+
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/meta.xml
new file mode 100644
index 0000000..6958848
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-flow/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/flow/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/content_en.html
new file mode 100644
index 0000000..4add7c8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/content_en.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Generators in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes all of the available generators of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+     
+<p>This document lists all of the available generators of Apache Cocoon and describes their
+       purpose.</p>
+    
+    
+<h1>Overview</h1>
+      
+<p>A generator is the starting point of an xml pipeline. It generates XML content as SAX
+        events and initializes pipeline processing. Every pipeline match containing a generator
+        must be terminated by a serializer.
+      </p>
+      
+<p>In the sitemap file, each generator has a unique name which is mapped to a Java class. One
+        generator name must be declared as the default generator. Each generator may have additional
+        configuration information specified in child elements.
+      </p>
+      
+<p>On the left you see all generators that are available in Cocoon. The list is separated into
+        the core generators, belonging to the Cocoon core, and optional generators that are part of
+        specific blocks.
+      </p>        
+      
+<p>For conceptual information on generators see the user's guide document
+        <a href="../concepts/sitemap.html">The Sitemap</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/meta.xml
new file mode 100644
index 0000000..707c76a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-generators/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/generators.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/content_en.html
new file mode 100644
index 0000000..f89ed85
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/content_en.html
@@ -0,0 +1,209 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Host-Selector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the HostSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>HostSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">host</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">HostSelector</span> component is used to
+            select appropriate sitemap processing depending on <span class="codefrag">Host</span> header
+            value.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where HostSelector sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.HostSelector</td>
+        
+</tr>
+        <!-- uncomment folling tr if HostSelector is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">HostSelector</span> tests the <span class="codefrag">Host</span> header field from the 
+        request against the test attribute of the selectors when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">HostSelector</span> allows to define host specific sitemap
+        processing. This way Cocoon can do multi-homed sitemap processing.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The snippet below uses a <span class="codefrag">HostSelector</span> named <span class="codefrag">host</span>,
+          and tests against symbolic host-sites which are configured in the
+          <span class="codefrag">host</span> selector section.
+        </p>
+<pre class="code">
+&lt;map:select type="host"&gt;
+  &lt;map:when test="uk-site"&gt;
+  ....
+  &lt;/map:when&gt;
+  &lt;map:when test="de-site"&gt;
+  ...
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+  ...
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The snippet below declares a <span class="codefrag">HostSelector</span>
+          defining symbolic host-site names for some host domains.
+        </p>
+<pre class="code">
+&lt;map:selectors&gt;
+  &lt;map:selector name="host" 
+    src="org.apache.cocoon.selection.HostSelector"
+    logger="sitemap.selector.host" 
+    
+    &lt;host name="uk-site" value="foo.bar.uk"/&gt;
+    ...
+    &lt;host name="de-site" value="foo.bar.de"/&gt;
+    &lt;host name="us-site" value="foo.bar.com"/&gt;
+    
+  &lt;/map:selector&gt;
+  ...
+&lt;/map:selectors&gt;
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          <!-- Explain the sitemap selector configuration, options when declaring host selector -->
+          The configuration section of <span class="codefrag">HostSelector</span> specifies
+          a mapping from host strings to symbolic host-site names.
+        </p>
+<p>
+          Each host element specifies a name attribute holding the symbolic host-site name
+          used in the test attribute expression. The attribute name contains 
+          a matchable substring of some real host header values.
+        </p>
+<p>
+          It is allowed to specify for a host name more than one entry. This way
+          a symbolic host-site name is matched by different host header substrings.
+          The snippet belows will yield true for <span class="codefrag">test="central-europe"</span> if 
+          the host header contains <span class="codefrag">foo.bar.cz</span>, <span class="codefrag">foo.bar.at</span>, or 
+          <span class="codefrag">foo.bar.hu</span>.
+        </p>
+<pre class="code">
+...
+  &lt;host name="central-europe" value="foo.bar.cz"/&gt;
+  &lt;host name="central-europe" value="foo.bar.at"/&gt;
+  &lt;host name="central-europe" value="foo.bar.uk"/&gt;
+...
+        </pre>
+      
+<h2>Setup</h2>
+<p>
+          <!-- Explain the sitemap selector setup, ie options when using host selector -->
+          Setting up a <span class="codefrag">HostSelector</span> includes choosing the 
+          <span class="codefrag">&lt;map:when&gt;</span> test expressions and a 
+          optional <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+        </p>
+<p>
+          The test attribute of the <span class="codefrag">&lt;map:when&gt;</span> clause must match
+          a host attribute name value. The value of the test attribute in a 
+          <span class="codefrag">&lt;map:when&gt;</span> clause must be declared in a 
+          <span class="codefrag">host</span> name attribute.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">HostSelector</span> has no side effects on the object model or 
+          any sitemap parameters. 
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">HostSelector</span> adds the response header attribute
+        <span class="codefrag">Vary</span> having value <span class="codefrag">Host</span> indicating
+        that the response differ for different hosts. This information
+        is particularly meaningful for a http-proxy server.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        28-12-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+      
+<p>
+        For a detailed <span class="codefrag">Host</span> header documentation 
+        see <a class="external" href="http://www.ietf.org/rfc/rfc2068.txt">RFC 2068</a>, especially
+        if Cocoon's run time environment is an http servlet environment. 
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/meta.xml
new file mode 100644
index 0000000..1f60a6d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-host-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/host-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/content_en.html
new file mode 100644
index 0000000..d45b340
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/content_en.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to Author Core Documentation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Diana Shannon" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Overview</h1>
+
+
+<p>
+This How-To describes the steps necessary to author or revise core documentation for Cocoon. Documentation is considered "core" if it is included in any Cocoon guide. Currently there are three guides: CTWIG, user, and developer. Please note that this guide structure may be revised soon. As you probably have discovered by now, many gaps exist in current Cocoon documentation. Authoring new core documents is a valuable way contribute to the Cocoon community.
+</p>
+
+
+  
+<h1>Purpose</h1>
+
+<p>
+Writing about Cocoon is not a trivial exercise. Understanding the Cocoon CVS and document organization takes time. In other words, many potential obstacles stand in your way. These guidelines were written to help you make the most productive use of your "volunteer" time. Following them not only saves your time but also saves the time of committers who will apply your work to the CVS.
+</p>
+
+
+  
+<h1>Intended Audience</h1>
+
+<p>
+Cocoon users who would like to improve Cocoon's documentation. This includes authors, editors, proofreaders, and quality assurance testers.
+</p>
+
+
+  
+<h1>Prerequisites</h1>
+
+<ul>
+
+<li>Spend some time familiarizing yourself with status of existing Cocoon documents.</li>
+
+<li>When evaluating doc-related issues, make sure you are referring to the most recent document versions from the CVS or Cocoon web site. Please note that sometimes the most recent version of any document will be found only in CVS HEAD.</li>
+
+</ul>
+
+
+
+	
+<h1>Steps</h1>
+
+<p>
+Here's how to proceed.
+</p>
+
+	
+<h2>1. Join the cocoon-docs email list</h2>
+<p>
+Find out what documentation efforts are already in process among other users and committers. Join the Cocoon <a href="mailto:docs-subscribe.at.cocoon.apache.org">Docs List</a>.
+</p>
+
+	
+<h2>2. Find a job</h2>
+<p>
+Look through Cocoon's documentation set in order to find content holes to fill or existing documents to improve. You don't have to be an author to contribute: editors, proofreaders, and quality assurance testers provide vital work as well.
+</p>
+
+	
+<h2>3. Announce your effort</h2>
+<p>
+Let others know about your efforts. Announce your plans on the cocoon-docs list. This will help to prevent any duplication of effort. It will also attract the interest of and valuable feedback from other users who have similar interests or expertise in your document's subject area.</p>
+
+	
+<h2>4. Do the work</h2>
+<p>
+Perhaps the easiest way to start a new document is to use an existing document as a template. If you are revising an existing document, make sure you are using the most recent copy of the document from CVS HEAD. If you aren't working with a local CVS repository, you can access all CVS files through <a class="external" href="http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/">ViewCVS</a>.
+</p>
+	
+	
+<h2>5. Ask for help when you need it</h2>
+<p>
+Writing effectively about a "glue" framework like Cocoon, which integrates many diverse technologies, is difficult, no doubt about it. Navigating your way through the CVS, Bugzilla, the patch process, as well as all of the steps of document creation can be overwhelming at first. Many of us have "been there" already and are available to help you. Don't hesitate to ask for assistance on cocoon-docs when you are confronted with a conceptual or technical problem you can't solve on your own. Don't waste your precious "volunteer" time pulling your hair out. Still, if you reach a point in your work where you are hopelessly stuck, you can always leave concise comments in a &lt;fixme&gt; element for others to fill down the road. This is in tune with open source, community-based development. Contribute what you can, when you have an irresistible "itch" to "scratch". Others will pick up where you left off.
+</p>
+	
+	
+<h2>6. Get some feedback</h2>
+<p>
+If you are working on a new or revised document, please post a text version of it to the cocoon-docs list to receive valuable comments from developers and users. Again, if you have technical holes in your content, be sure to add fixme comments to make it clear for others what particular areas you'd like for them to address.
+</p>
+	
+	
+<h2>7. Review your work</h2>
+<p>
+Look over your work for embarrassing spelling or grammatical errors. At least check your document with a spell checker before submitting it. 
+</p>
+
+	
+<h2>8. Validate your document(s)</h2>
+<p>
+Use the appropriate and most recent dtd to validate any new or revised documents. You will find all dtds in the src/documentation/xdocs/dtd directory. While a "docs" target (during Cocoon's build process) is capable of validating your files, it is far more efficient to troubleshoot validation and well-formedness problems with your own tools.
+</p>
+	
+	
+<h2>9. Update any related pages</h2>
+<p>
+If your work impacts the content of other files, for example the menu file (known as book.xml), consider updating these documents as well. You can validate and check link targets within all your documents by performing a docs build. If you have a working copy of the cvs HEAD, run the appropriate build script inside the cocoon-2.1 directory, specifying docs as the build target. Here's an example: 
+</p>
+<pre class="code">
+./build.[sh|bat] docs
+</pre>
+	
+	
+<h2>10. Prepare any related patches</h2>
+<p>
+Any new document file is already a patch, at least as far as Bugzilla is concerned. However, if you also edited any existing documents, you will need to create a patch for them before submitting all files. If you don't know how to create a patch, follow the instructions in <a href="howto-patch.html">How to Prepare a Patch.</a>
+
+</p>
+
+	
+<h2>11. Submit via Bugzilla</h2>
+<p>
+Create an attachment for any documents, and submit it via Bugzilla. If you don't know how to submit via Bugzilla, follow the instructions in <a href="howto-bugzilla.html">How to Contribute a Patch via Bugzilla.</a>
+
+</p>
+
+	
+
+  
+<h1>Summary</h1>
+
+<p>
+The Cocoon documentation effort is based on the belief that open source documents can be as first-rate as the software on which they are based. However, such an endeavor is dependent upon vital forms of contributions from developers and users alike. This How-To gives you the information you need to join like-minded individuals in the effort to improve Cocoon docs. Take a minute to imagine how advanced the Cocoon community would become if more Cocoon users played a role in improving Cocoon docs. Think how much more we would learn. Think how many more innovative Cocoon-based solutions we could develop, based on our extended knowledge. Think about it.
+</p>
+	
+
+	
+  
+<h1>Comments</h1>
+
+<p>
+Care to comment on this How-To? Got another tip? Help keep this How-To relevant by passing along any useful feedback to the author, <a href="mailto:shannon.at.apache.org">Diana Shannon</a>. Even better, join the Cocoon <a href="mailto:docs-subscribe.at.cocoon.apache.org">Docs List</a> and share your feedback and ideas with other people who are committed to producing high quality Cocoon documentation!
+</p>
+	
+	
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/meta.xml
new file mode 100644
index 0000000..a7160a1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-author-docs/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-author-core-docs.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/content_en.html
new file mode 100644
index 0000000..e94d482
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/content_en.html
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to use the Cocoon Flow Debugger</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Marcus Crafter" name="DC.Creator">
+</head>
+<body>
+	
+<h1>Overview</h1>
+	  
+<p>
+		This how-to describes how to enable and start the flow debugger in Cocoon Web Applications that use the JavaScript based flow engine. The flow debugger allows you to visually debug flow scripts using breakpoints, tracing, variable watches, etc, similar to other common visual debugging environments currently available.
+	  </p>
+	  
+<p>
+		For a full description of how to use the debugger itself, please refer to the Mozilla Rhino debugger <a class="external" href="http://www.mozilla.org/rhino/debugger.html">page</a>.
+	  </p>
+
+<div class="note">Since: 2.1 2002-12-07</div>
+	
+	
+<h1>Purpose</h1>
+	  
+<p>
+		The process of writing and debugging flow script can be tedious and repetitive. JavaScript is a language that features typed objects but untyped references, which means at times it can be difficult to locate programming errors until runtime.
+	  </p>
+	  
+<p>
+		The flow debugger intends to ease the development, debugging and maintenance of flow scripts by allowing you to visually inspect and influence your flow script, while it's running, without having to resort to many superfluous print or log statements.
+	  </p>
+	
+	
+<h1>Intended Audience</h1>
+	  
+<p>
+		This document is intended for Cocoon web application developers who are using the JavaScript flow engine inside of their Cocoon application.
+	  </p>
+	
+	
+<h1>Prerequisites</h1>
+	  
+<p>
+		Until Cocoon 2.1 is released, to use the flow debugger you will need a CVS <a class="external" href="http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/">version</a> or development <a class="external" href="http://xml.apache.org/from-cvs/cocoon-2.1/">snapshot</a> of Cocoon, at least as recent as 7th December 2002.
+	  </p>
+	  
+<p>
+		You will also need a JavaScript flow based web application, for example the flow webapp samples that are currently shipped with Cocoon, and you will need to be running Cocoon on a server that has a display attached (either local or remote).
+	  </p>
+	  
+<p>
+		No special files need to be installed to use the debugger, support for the debugger is included in the Rhino jar file which is part of Cocoon.
+	  </p>
+	
+	
+	
+<h1>Steps</h1>
+	  
+<p>
+		The process of enabling and starting the debugger is quite simple. Essentially, all you have to is enable support for the debugger in the JavaScript interpreter's configuration section of the cocoon.xconf file, and start your application. The debugger will be instantiated by the next request that invokes <span class="codefrag">map:call function</span> or <span class="codefrag">continuation</span>.
+	  </p>
+	  
+	  
+<p>
+		Once the debugger is up and running, it should look similar to:
+      </p>
+
+      
+<div align="center">
+<img class="figure" alt="Flow debugger image" src="images/flow-debugger.jpg"></div>
+
+      
+<p>So, let's get started.</p>
+
+	  
+<h2>Configuration</h2>
+<p>
+		  By default, the flow debugger is disabled. To enable it, you will need to modify the cocoon.xconf file to include one element named <strong>debugger</strong>, which contains the value <em>enabled</em>, as follows:
+		</p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;flow-interpreters default="JavaScript" logger="flow"&gt;
+	&lt;component-instance name="JavaScript"
+		class="org.apache.cocoon.components.flow.javascript.JavaScriptInterpreter"&gt;
+		  &lt;load-on-startup&gt;resource://org/apache/cocoon/components/flow/javascript/system.js&lt;/load-on-startup&gt;
+		  &lt;reload-scripts&gt;true&lt;/reload-scripts&gt;
+		  &lt;check-time&gt;4000&lt;/check-time&gt;
+		  <strong>&lt;debugger&gt;enabled&lt;/debugger&gt;</strong>  &lt;!-- JavaScript Debugger support --&gt;
+	&lt;/component-instance&gt;
+&lt;/flow-interpreters&gt;
+		</pre>
+<div class="note">If you are using the debugger with the Cocoon flow samples, you will need to modify the <em>cocoon.xconf</em> file in build/cocoon/webapp/WEB-INF, or the <em>flow.xconf</em> file in src/java/org/apache/cocoon/components/flow/, which is merged into the cocoon.xconf file at build time</div>
+			
+	  
+<h2>Compile and start your environment</h2>
+<p>
+		  Compile and start your application as normal.
+		</p>
+	
+	  
+<h2>Start the flow engine</h2>
+<p>
+		  Once your application is running and awaiting requests, attempt to access a page that calls a flow function. The invocation will take longer than normal, but on your server's display you should see the visual debugger being created and populated with your flow script.
+		</p>
+<div class="note">Portions of Cocoon's flow script management <a class="external" href="http://cvs.apache.org/viewcvs.cgi/cocoon-2.1/src/java/org/apache/cocoon/components/flow/javascript/system.js?rev=HEAD&content-type=text/vnd.viewcvs-markup">code</a> will also be viewable in the debugger.</div>
+<p>
+		  A debugger instance is created per JavaScript interpreter. This means if you make another request to a different sitemap for example, a new debugger instance will be created alongside the previous one. This allows you to debug flow scripts locally to the sitemap they are defined in.
+		</p>
+	  
+<h2>Use the debugger</h2>
+<p>
+		  At this stage, the debugger is in control. By default, all entry points into the debugger result in an automatic breakpoint being set at that entry point (ie. at the beginning of each call function and handle continuation invocation). To continue processing, press any of the <em>step</em> buttons to trace through your code.
+		</p>
+<div class="note">Pressing <em>Exit</em> from the <em>File</em> menu will not actually exit the debugger or JVM, but will make it invisible. It will be automatically made visible again upon entering a new call-function/handle-continuation frame.</div>
+<p>
+		  Using the flow debugger, you will be able to trace through your code at any level of detail your require. Continuations are also supported, when a <span class="codefrag">sendPageAndWait()</span> is invoked, the debugger will become inactive until the interpreter is called upon to continue that suspended flow.
+		</p>
+	
+
+	
+<h1>Improvements</h1>
+	  
+<h2>Remote debugging</h2>
+<p>
+		  Currently to use the flow debugger you really need to be working on the same machine where your Cocoon application is running, either via a remote login or locally on the system. The ability to remotely attach to a running system and debug flow would be nice.
+		</p>
+	  
+<h2>Enable/disable without restart</h2>
+<p>
+		  Currently to enable/disable the debugger one has to modify the cocoon.xconf/flow.xconf files, perhaps it would be good if this was possible dynamically, ie. without a restart of the servlet environment or Cocoon.
+		</p>
+	
+
+	
+<h1>Comments</h1>
+	  
+<p>
+		Do you have an idea about how to improve the Cocoon flow debugger? Please post it to the <a href="mailto:dev.at.cocoon.apache.org?subject=FlowDebugger:">cocoon-dev</a> mailing list. Care to comment on this How-To? Help keep this document relevant by passing along any constructive feedback to the <a href="mailto:docs.at.cocoon.apache.org?subject=FlowDebugger:">cocoon-docs</a> mailing list.
+	  </p>
+	
+
+	
+<h1>Revisions</h1>
+	  
+<p>
+		11-12-2002: Content originally submitted by Marcus Crafter. 
+	  </p>
+	
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/meta.xml
new file mode 100644
index 0000000..7b4c3f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-flow-debugger/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-flow-debugger.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/content_en.html
new file mode 100644
index 0000000..cfb0ecc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/content_en.html
@@ -0,0 +1,455 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to Publish XML Documents in HTML and PDF</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bertrand Delacr&eacute;taz" name="DC.Creator">
+</head>
+<body>
+
+
+<h1>Overview</h1>
+
+<p>
+This How-To shows you how to publish XML documents in HTML and PDF using Cocoon. It requires no 
+prior knowledge of Cocoon, XSLT or XSL-FO.
+</p>
+
+<p>
+It has been updated for Cocoon 2.1, which does not require the use of the <em>mount</em> directory anymore.
+</p>
+
+
+
+<h1>Purpose</h1>
+
+<p>
+You will learn how to build a simple pipeline that converts XML documents on-the-fly to HTML or PDF using simple 
+XSLT transforms. This is similar to the <span class="codefrag">hello.html</span> and <span class="codefrag">hello.pdf</span> samples of the standard Cocoon installation. However, this How-To teaches you how to build these mechanisms yourself. Thus, you will get a better feel of how Cocoon publishing really works.
+</p>
+
+
+
+<h1>Intended Audience</h1>
+
+<p>
+Beginning Cocoon users who want to learn how to publish HTML and/or PDF documents from XML data.
+</p>
+
+
+
+<h1>Prerequisites</h1>
+
+<p>Here's what you need:</p>  
+
+
+<ul>
+
+<li>Cocoon must be running on your system. The steps below have been tested with Cocoon 2.1m3-dev, but they should work with any 2.1 version.</li>
+
+<li>This document assumes a standard installation where Cocoon is started by the <em>cocoon.sh</em> (or cocoon.bat) script and where
+<span class="codefrag">http://localhost:8888/</span> points to the <em>Welcome to Apache Cocoon</em> page.
+<br>
+If your installation runs on a different URL, you will have to adjust
+the URLs provided throughout this How-To as necessary. 
+</li>
+
+<li>You must be able to create and edit XML files in the main directory of the Cocoon installation.
+When started from cocoon.sh, this directory is <span class="codefrag">build/webapp</span> under the directory that contains cocoon.sh.
+</li>
+
+</ul>
+
+<div class="note">You will not need a fancy XML editor for this How-To. Copying and pasting the sample code snippets into any text editor
+will do.</div>
+
+<div class="note">
+Running "build clean" deletes everything under build/webapp, make sure to save your example files if you
+need to do a clean build.
+ </div>
+
+
+
+
+<h1>Steps</h1>
+
+<p>
+Here's how to proceed.
+</p>
+
+
+<h2>1. Create the work directory</h2>
+<p>
+Under <span class="codefrag">build/webapp</span>, create a new directory and name it <span class="codefrag">html-pdf</span>.
+All files used by this How-To will reside in this directory.
+</p>
+<p>
+At this point, <span class="codefrag">http://localhost:8888/html-pdf/</span> should display an error page saying <em>Resource not found</em>,
+indicating that the file <em>build/webapp/html-pdf/sitemap.xmap</em> was not found. This is normal, as the newly
+created directory does not yet contain the required sitemap file.
+</p>
+
+
+<h2>2. Create the XML example documents</h2>
+<p>
+To keep it simple we will use two small XML files as our data sources.
+Later, you will probably use additional data sources like live XML feeds, databases, and others.</p>
+<p>
+In the <span class="codefrag">html-pdf</span> directory, create the following two files, and name them exactly as
+shown.
+</p>
+<p>
+Contents of file <strong>pageOne.xml</strong>:
+</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+&lt;page&gt;
+&lt;title&gt;This is the pageOne.xml example&lt;/title&gt;
+&lt;s1 title="Section one"&gt;
+    &lt;p&gt;This is the text of section one&lt;/p&gt;
+&lt;/s1&gt;
+&lt;/page&gt;
+        </pre>
+<p>
+Contents of file <strong>pageTwo.xml</strong>:
+</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+&lt;page&gt;
+&lt;title&gt;This is the pageTwo.xml example&lt;/title&gt;
+&lt;s1 title="Yes, it works"&gt;
+    &lt;p&gt;Now you're hopefully seeing pageTwo in HTML or PDF&lt;/p&gt;
+&lt;/s1&gt;
+&lt;/page&gt;
+        </pre>
+<div class="note">
+Be careful about the use of lower/uppercase in filenames if you're working on a Unix or Linux system. 
+On such systems, <span class="codefrag">thisFile.xml</span> is not the same as <span class="codefrag">Thisfile.xml</span>.
+</div>
+<div class="note">
+To avoid any errors, use copy/paste when creating XML documents from examples on this page.
+</div>
+<div class="note">
+Do not leave spaces at the start of XML files. The &lt;?xml... processing instruction must
+be the first character in the file.
+</div>
+
+
+<h2>3. Create the XSLT transform for HTML</h2>
+<p>
+The most common way of producing HTML in Cocoon is to use <strong>XSLT transforms</strong> to select and convert 
+the appropriate elements of the input documents.
+</p>
+<p>
+Copy the file shown below to the <span class="codefrag">html-pdf</span> directory alongside your XML documents, naming it
+<strong>doc2html.xsl</strong>
+
+</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
+
+&lt;!-- generate HTML skeleton on root element --&gt;
+&lt;xsl:template match="/"&gt;
+  &lt;html&gt;
+    &lt;head&gt;
+      &lt;title&gt;&lt;xsl:apply-templates select="page/title"/&gt;&lt;/title&gt;
+    &lt;/head&gt;
+    &lt;body&gt;
+        &lt;xsl:apply-templates/&gt;
+    &lt;/body&gt;
+  &lt;/html&gt;
+&lt;/xsl:template&gt;
+
+&lt;!-- story is used later by the Meerkat example --&gt;
+&lt;xsl:template match="p|story"&gt;
+    &lt;p&gt;&lt;xsl:apply-templates/&gt;&lt;/p&gt;
+&lt;/xsl:template&gt;
+
+&lt;!-- convert sections to HTML headings --&gt;
+&lt;xsl:template match="s1"&gt;
+    &lt;h1&gt;&lt;xsl:apply-templates select="@title"/&gt;&lt;/h1&gt;
+    &lt;xsl:apply-templates/&gt;
+&lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;     
+</pre>
+<div class="note">       
+Basically what this does is generate an HTML skeleton and convert the input markup to HTML. We won't go
+into details here. Rather, our goal is to show you how the components of the publishing chain are combined.  
+</div>
+
+
+<h2>4. Create the sitemap</h2>
+<p>
+We now have documents to publish and an XSLT transform to convert them to our HTML output format.
+What's left is to connect them in a <strong>processing pipeline</strong>. Then, the <strong>sitemap</strong> can select the pipeline based on the details of the browser request.
+</p>
+<p>
+To tell Cocoon how to process requests made to <span class="codefrag">html-pdf</span>, 
+copy the following snippet to a file named <strong>sitemap.xmap</strong> in the 
+<span class="codefrag">html-pdf</span> subdirectory.
+</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+
+    &lt;!-- define the Cocoon processing pipelines --&gt;
+    &lt;map:pipelines&gt;
+        &lt;map:pipeline&gt;
+            &lt;!-- respond to *.html requests with
+                 our docs processed by doc2html.xsl --&gt;
+            &lt;map:match pattern="*.html"&gt;
+                &lt;map:generate src="{1}.xml"/&gt;
+                &lt;map:transform src="doc2html.xsl"/&gt;
+                &lt;map:serialize type="html"/&gt;
+            &lt;/map:match&gt;
+
+            &lt;!-- later, respond to *.pdf requests with
+                 our docs processed by doc2pdf.xsl --&gt;
+            &lt;map:match pattern="*.pdf"&gt;
+                &lt;map:generate src="{1}.xml"/&gt;
+                &lt;map:transform src="doc2pdf.xsl"/&gt;
+                &lt;map:serialize type="fo2pdf"/&gt;
+            &lt;/map:match&gt;
+        &lt;/map:pipeline&gt;
+    &lt;/map:pipelines&gt;
+&lt;/map:sitemap&gt;
+        </pre>
+<div class="note">The important thing here is the first <strong>map:match</strong> element, which tells Cocoon how to process
+requests ending in *.html in this directory. Again, we won't go into details here, but that's where it happens.
+</div>
+<div class="note">The above sitemap is already configured for PDF publishing. However, this capability is not fully functional at this time because we haven't created the required XSLT transform yet.</div>
+
+
+<h2>5. Test the HTML publishing</h2>
+<p>
+At this point you should be able to display the results in HTML: 
+</p>
+<ul>
+
+<li>
+
+<span class="codefrag">http://localhost:8888/html-pdf/pageOne.html</span>
+should display the first page with "Section one" in big letters.
+</li>
+
+<li>
+
+<span class="codefrag">http://localhost:8888/html-pdf/pageTwo.html</span>
+should display the second page with "Yes it works" in big letters.
+</li>
+
+</ul>
+<div class="note">If this doesn't work, you might want to double check the above steps first, and then look at the Cocoon
+logs (see the Cocoon wiki for information about the logs).
+</div>
+<div class="note">
+To convince yourself that the HTML data is generated dynamically, you can try to edit the pageXXX.xml source documents
+(keeping them well-formed),
+and refresh the browser to see the effect of your changes.
+</div>
+
+
+
+<h2>6. Create the XSLT transform for PDF</h2>
+<p>
+PDF documents are created via XSL-FO documents which are XML documents that use a specific page-description
+vocabulary. (See <a href="#references">References</a> below for more info). The actual conversion to PDF is done by the 
+<span class="codefrag">PdfSerializer</span> which uses software from <a class="external" href="http://xml.apache.org/fop">FOP</a>, another Apache
+Software Foundation project.   
+</p>
+<p>
+To activate the PDF conversion, copy the code snippet shown below to the <span class="codefrag">html-pdf</span> directory along with your XML documents, and name it
+<strong>doc2pdf.xsl</strong>
+
+</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
+&lt;xsl:stylesheet 
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+    xmlns:fo="http://www.w3.org/1999/XSL/Format"
+&gt;
+    &lt;!-- generate PDF page structure --&gt;
+    &lt;xsl:template match="/"&gt;
+        &lt;fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"&gt;
+            &lt;fo:layout-master-set&gt;
+                &lt;fo:simple-page-master master-name="page"
+                  page-height="29.7cm" 
+                  page-width="21cm"
+                  margin-top="1cm" 
+                  margin-bottom="2cm" 
+                  margin-left="2.5cm" 
+                  margin-right="2.5cm"
+                &gt;
+                    &lt;fo:region-before extent="3cm"/&gt;
+                    &lt;fo:region-body margin-top="3cm"/&gt;
+                    &lt;fo:region-after extent="1.5cm"/&gt;
+                &lt;/fo:simple-page-master&gt;
+
+                &lt;fo:page-sequence-master master-name="all"&gt;
+                    &lt;fo:repeatable-page-master-alternatives&gt;
+                        &lt;fo:conditional-page-master-reference 
+                           master-reference="page" page-position="first"/&gt;
+                    &lt;/fo:repeatable-page-master-alternatives&gt;
+                &lt;/fo:page-sequence-master&gt;
+            &lt;/fo:layout-master-set&gt;
+
+            &lt;fo:page-sequence master-reference="all"&gt;
+                &lt;fo:flow flow-name="xsl-region-body"&gt;
+                    &lt;fo:block&gt;&lt;xsl:apply-templates/&gt;&lt;/fo:block&gt;
+                &lt;/fo:flow&gt;
+            &lt;/fo:page-sequence&gt;
+        &lt;/fo:root&gt;
+    &lt;/xsl:template&gt;
+
+    &lt;!-- process paragraphs --&gt;
+    &lt;xsl:template match="p"&gt;
+        &lt;fo:block&gt;&lt;xsl:apply-templates/&gt;&lt;/fo:block&gt;
+    &lt;/xsl:template&gt;
+
+    &lt;!-- convert sections to XSL-FO headings --&gt;
+    &lt;xsl:template match="s1"&gt;
+        &lt;fo:block font-size="24pt" color="red" font-weight="bold"&gt;
+            &lt;xsl:apply-templates select="@title"/&gt;
+        &lt;/fo:block&gt;
+        &lt;xsl:apply-templates/&gt;
+    &lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+
+       </pre>
+<div class="note">This file is already referenced by the sitemap we created, so no additional configuration is needed.</div>
+
+
+<h2>5. Test the PDF publishing</h2>
+<p>
+At this point you should be able to display the results in PDF in addition to the existing HTML versions: 
+</p>
+<ul>
+
+<li>
+
+<span class="codefrag">http://localhost:8888/html-pdf/pageOne.pdf</span>
+should display the first page with "Section one" in big red letters.
+</li>
+
+<li>
+
+<span class="codefrag">http://localhost:8888/html-pdf/pageTwo.pdf</span>
+should display the second page with "Yes it works" in big red letters.
+</li>
+
+</ul>
+
+
+
+
+<h1>Summary</h1>
+
+<p>
+I hope you're beginning to see that publishing PDF and HTML documents in Cocoon is not too complicated, once you know what goes where. 
+</p>
+
+<p>
+The nice thing is that all of our huge corpus
+of XML documents (actually, only two documents right now, but that's a start... ) is processed by just two XSLT transforms, one
+for each target format.
+</p>
+
+<p>
+If you need to change the appearance of the published documents, you have to change only these two XSLT transforms. There's no need to touch the source documents.
+</p>
+
+
+
+<h1>Tips</h1>
+
+<h2>Tip 1: Dynamic XML data</h2>
+<p>
+Using dynamic XML as the data source is very easy because the Cocoon FileGenerator can read URLs as well. 
+</p>
+<p>
+If you add the map:match element shown in bold below <strong>before</strong> the existing map:match elements in your sitemap.xmap file, requesting
+<span class="codefrag">http://localhost:8888/html-pdf/meerkat.html</span>
+should display real-time news from Meerkat (assuming an Internet connection to Meerkat is available).
+</p>
+<p>
+The news will be displayed in a very rough format. However, this can be improved by writing a 
+specific XSLT transform for this Meerkat data and using it, instead of doc2html.xsl, in the meerkat.html pipeline.  
+</p>
+<pre class="code">
+
+...
+&lt;map:pipeline&gt;
+
+<strong>
+
+&lt;map:match pattern="meerkat.html"&gt;
+    &lt;map:generate src="http://www.oreillynet.com/meerkat/?_fl=xml"/&gt;
+    &lt;map:transform src="doc2html.xsl"/&gt;
+    &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+
+</strong>
+
+&lt;map:match pattern="*.html"&gt;
+etc...
+
+</pre>
+
+
+<h2>Tip 2: Two-step conversion</h2>
+<p>
+When you are generating multiple formats from a single data source, it is often a good idea to generate 
+an intermediate <strong>logical document</strong> that describes the output in a format-neutral way.
+</p>
+<p>
+This is obviously not needed in our simple example. If you're aiming for more complicated 
+publishing tasks, then you might want to read about this "publishing pattern" in Martin Fowler's 
+<a class="external" href="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</a>
+article.
+</p>
+
+
+
+
+<h1>References</h1>
+
+<a name="references"></a>
+
+<p>
+To go further, you will need to learn about the following technologies and tools.
+</p>
+
+<ul>
+
+<li>
+Learning  
+<a class="external" href="http://cocoon.apache.org/2.1/userdocs/concepts/index.html">
+Cocoon concepts</a> will help you understand how the sitemap, generators, transformers, and serializers work.
+</li> 
+
+<li>
+Learning about <a class="external" href="http://www.w3.org/Style/XSL/">XSLT</a> will enable you to write your own transforms to 
+generate HTML, PDF or other formats from XML data. 
+Information about XSL-FO is available at the same address.  
+</li>
+
+</ul>
+
+
+
+<h1>Comments</h1>
+
+<p>
+Care to comment on this How-To? Got another tip? 
+Help keep this How-To relevant by passing along any useful feedback to the author,
+<a href="mailto:bdelacretaz.at.apache.org">Bertrand Delacr&eacute;taz</a>.
+</p>
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/meta.xml
new file mode 100644
index 0000000..123009e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-howto-pdf-publishing/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-html-pdf-publishing.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/content_en.html
new file mode 100644
index 0000000..7670a75
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/content_en.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HTML Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Sylvain Wallez" name="DC.Creator">
+<meta content="Gianugo Rabellino " name="DC.Creator">
+<meta content="This document describes the html generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>HTML Generator</h1>
+      
+<p>The html generator reads an html document from the local file system or from any url.
+                 It acts similar to the file generator with the difference that it reads
+                     html documents and converts them using <a class="external" href="http://sourceforge.net/projects/jtidy">JTidy</a>
+                     to xhtml.</p>
+      
+<p>This generator is optional and requires the jtidy package
+                     in the lib directory when building Cocoon. However,
+                     the distribution includes this package already.</p>
+      
+<ul>
+        
+<li>Name : html</li>
+        
+<li>Class: org.apache.cocoon.generation.HTMLGenerator</li>
+        
+<li>Cacheable: yes - uses the last modification date of the html document for validation.</li>
+      
+</ul>
+      
+<p>The location of the source html document is specified in
+                     the pipeline by the src attribute.</p>
+  
+<pre class="code">
+   
+  &lt;map:generate src="document.html" type="html"/&gt;
+     
+</pre>
+      
+<p>The html generator, however, can operate also on a request
+      attribute or on a XML POST request. This can be done also by the
+      <a href="stream-generator.html">stream generator</a>, with whom
+      it shares the syntax: the added bonus here is that you can
+      "sanitize" a possibly non well-formed XML snippet for further
+      reuse later. In order to use this feature for request attributes, 
+      just omit the "src" attribute and set a parameter like the following 
+      one in the sitemap:</p>
+
+
+<pre class="code">
+
+  &lt;map:parameter name="form-name" value="my-request-attribute"/&gt;
+
+</pre>
+
+    
+    
+<h1>Configuring JTidy</h1>
+      
+<p>Without any configuration, the generator produces an XHTML document, with the proper namespace. However,
+         JTidy offers a full range of options for converting the HTML document to XML.</p>
+      
+<p>These options can be specified in a properties file (key=value pairs) whose location is given in the
+         component configuration :</p>
+      
+<pre class="code">
+        
+  &lt;map:generator name="html" src="org.apache.cocoon.generation.HTMLGenerator"&gt;
+    &lt;jtidy-config&gt;jtidy.properties&lt;/jtidy-config&gt;
+  &lt;/map:generator&gt;
+        
+      </pre>
+      
+<p>The <span class="codefrag">jtidy-config</span> URL can be either relative (to the application context), one of Cocoon's special
+         protocols such as <span class="codefrag">resouce:</span> which searches the file in the classpath.</p>
+      
+<p>For more information on the available configurations, please refer to the
+         <a class="external" href="http://www.w3.org/People/Raggett/tidy/">original Tidy page</a>. Beware that configuration
+         examples shown there use the ':' as a separator when JTidy requires a '=' as it is a standard Java properties file.
+      </p>
+    
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/meta.xml
new file mode 100644
index 0000000..d63b00f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/html-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/content_en.html
new file mode 100644
index 0000000..01c9b25
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/content_en.html
@@ -0,0 +1,246 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>HTML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the html serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>HTML Serializer</h1>
+      
+<p>
+        The HTML serializer serializes xml content to html.
+        It is the default serializer.
+      </p>
+      
+<ul>
+        
+<li>Name : html</li>
+        
+<li>Class: org.apache.cocoon.serialization.HtmlSerializer</li>
+        
+<li>Cacheable: yes.</li>
+      
+</ul>
+      
+<h2>Sitemap Configuration</h2>
+<p>
+          The HTML Serializer is declared in the sitemap serializers section.
+        </p>
+<pre class="code">
+&lt;map:serializers default="html"&gt;
+...
+  &lt;map:serializer name="html"
+    src="org.apache.cocoon.serialization.HTMLSerializer"
+    mime-type="text/html"  
+    logger="sitemap.serializer.html" 
+    pool-max="32"&gt;
+    &lt;!-- serializer configurations --&gt;
+...    
+  &lt;/map:serializer&gt;
+...
+        </pre>
+<p>
+          HTML Serializer can be configured, specifying elements inside of
+          the &lt;map:serializer&gt; body.
+        </p>
+<h3>Configuration Example</h3>
+<p>
+            The following HTML Serializer snippet is setting
+            doctype, and encoding configuration for the HTML Serializer
+          </p>
+<pre class="code">
+&lt;map:serializer name="html"         
+  src="org.apache.cocoon.serialization.HTMLSerializer"
+  mime-type="text/html"&gt;
+  &lt;doctype-public&gt;-//W3C//DTD HTML 4.01 Transitional//EN&lt;/doctype-public&gt;
+  &lt;encoding&gt;ISO-8859-1&lt;/encoding&gt;
+&lt;/map:serializer&gt;
+          </pre>
+<p>
+            This configuration will result in HTML output of the form
+          </p>
+<pre class="code">
+&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;
+&lt;title...
+...
+          </pre>
+<p>
+          The HTML Serializer accepts following configuration parameters.
+          These configurations are not Xalan specific.
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Name</th><th colspan="1" rowspan="1">Xalan Default Value</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">cdata-section-elements</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">cdata-section-elements</span> specifies a whitespace delimited
+               list of the names of elements whose text node children should be output
+               using CDATA sections.
+               See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation.</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">doctype-public</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">doctype-public</span> specifies the public identifier
+              to be used in the document type declaration.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">doctype-system</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">doctype-system</span> specifies the system identifier
+              to be used in the document type declaration.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">encoding</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">encoding</span> specifies the preferred character
+              encoding that the Transformer should use to encode sequences of
+              characters as sequences of bytes. The value of the attribute should be
+              treated case-insensitively. The value must only contain characters in
+              the range #x21 to #x7E (i.e., printable ASCII characters). The value
+              should either be a <span class="codefrag">charset</span> registered with the Internet
+              Assigned Numbers Authority <a href="#IANA">[IANA]</a>,
+              <a href="#RFC2278">[RFC2278]</a> or start with <span class="codefrag">X-</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">indent</td>
+            <td colspan="1" rowspan="1">
+              yes
+            </td>
+            <td colspan="1" rowspan="1">
+              A Flag for toggling indent. This flag toggles only if some elements
+              should trigger a line break.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">media-type</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">media-type</span> specifies the media type (MIME
+              content type) of the data that results from outputting the result
+              tree. The <span class="codefrag">charset</span> parameter should not be specified
+              explicitly; instead, when the top-level media type is
+              <span class="codefrag">text</span>, a <span class="codefrag">charset</span> parameter should be added
+              according to the character encoding actually used by the output
+              method.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">method</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              The method attribute identifies the overall method that
+              should be used for outputting the result tree.  Other non-namespaced
+              values may be used, such as "xhtml", but, if accepted, the handling
+              of such values is implementation defined.  If any of the method values
+              are not accepted and are not namespace qualified,
+              then {@link javax.xml.transform.Transformer#setOutputProperty}
+              or {@link javax.xml.transform.Transformer#setOutputProperties} will
+              throw a {@link java.lang.IllegalArgumentException}.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">omit-xml-declaration</td>
+            <td colspan="1" rowspan="1"></td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">omit-xml-declaration</span> specifies whether the XSLT
+              processor should output an XML declaration; the value must be
+              <span class="codefrag">yes</span> or <span class="codefrag">no</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">standalone</td>
+            <td colspan="1" rowspan="1"></td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">standalone</span> specifies whether the Transformer
+              should output a standalone document declaration; the value must be
+              <span class="codefrag">yes</span> or <span class="codefrag">no</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">version</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">version</span> specifies the version of the output
+              method.
+              When the output method is "xml", the version value specifies the
+              version of XML to be used for outputting the result tree. The default
+              value for the xml output method is 1.0. When the output method is
+              "html", the version value indicates the version of the HTML.
+              The default value for the xml output method is 4.0, which specifies
+              that the result should be output as HTML conforming to the HTML 4.0
+              Recommendation [HTML].  If the output method is "text", the version
+              property is ignored.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+        
+</table>
+<div class="note">
+          Former property <span class="codefrag">buffer-size</span> is deprecated, and is ignored.
+        </div>
+<p>
+          The HTML Serializer sets the <span class="codefrag">method</span> property
+          to <span class="codefrag">html</span>.
+        </p>
+      
+<h2>Pipeline Usage</h2>
+<pre class="code">
+...
+&lt;map:match pattern="*.html"&gt;
+&lt;map:generate...
+...
+&lt;map:serialize type="html"/&gt;
+...
+      </pre>
+      
+<h2>Further Reading</h2>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/meta.xml
new file mode 100644
index 0000000..46094d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-html-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/html-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/content_en.html
new file mode 100644
index 0000000..8bd0e68
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/content_en.html
@@ -0,0 +1,367 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Request Processing</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tom Klaasen" name="DC.Creator">
+<meta content="This document tries to explain Cocoon technically. We do this by
+            describing what happens if somebody types in the URL of a simple Cocoon page." name="DC.Description">
+</head>
+<body>
+	 
+<h1>Introduction</h1>
+		
+<h2>Goal</h2>
+<p>This document tries to explain Apache Cocoon 
+			 technically. We do this by describing what happens if somebody types in the URL
+			 of a simple Cocoon page.</p> 
+		
+<h2>Intended public</h2>
+<p>The reader should have a knowledge of:</p>
+<ul> 
+			 
+<li>the Java 2 platform</li>
+			 
+<li>the javax.servlet extensions</li> 
+			 
+<li>XML</li> 
+			 
+<li>HTTP</li> 
+		  
+</ul> 
+	  
+	 
+<h1>The configuration assumptions</h1> 
+		
+<p>The sequence of events described in this document, depends on some
+		  assumptions with regard to the configuration of Cocoon. That's what's described
+		  here.</p>
+		
+<h2>sitemap.xmap</h2>
+<p>The task of the sitemap is to define the pipelines that Cocoon will
+			 apply to URI's called in one's browser.</p>
+<p>This is the minimal sitemap that is necessary. The lines here are
+			 included in the standard sitemap.xmap that comes with the distribution of
+			 Cocoon.</p>
+<p>The sitemap is defined in <span class="codefrag">${cocoon}/sitemap.xmap</span>.</p>
+<pre class="code"> 
+&lt;?xml version="1.0"?&gt;
+          
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt; 
+          
+  &lt;!--===========================Components================================--&gt;
+  &lt;map:components&gt;
+          
+    &lt;map:generators default="file"&gt;
+    &lt;map:generator name="file" label="content" 
+                   src="org.apache.cocoon.generation.FileGenerator"/&gt; 
+    &lt;/map:generators&gt; 
+
+    &lt;map:transformers default="xslt"&gt;
+      &lt;map:transformer name="xslt"
+                       src="org.apache.cocoon.transformation.XalanTransformer"&gt;
+        &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+      &lt;/map:transformer&gt; 
+    &lt;/map:transformers&gt;
+
+    &lt;map:serializers default="html"&gt;
+      &lt;map:serializer name="html" mime-type="text/html" 
+                      src="org.apache.cocoon.serialization.HTMLSerializer"/&gt; 
+    &lt;/map:serializers&gt;
+
+    &lt;map:selectors default="browser"&gt;
+      &lt;map:selector name="browser" 
+                    factory="org.apache.cocoon.selection.BrowserSelector"&gt;
+        &lt;browser name="explorer" useragent="MSIE"/&gt;
+        &lt;browser name="netscape" useragent="Mozilla"/&gt; 
+      &lt;/map:selector&gt; 
+    &lt;/map:selectors&gt;
+
+    &lt;map:matchers default="uri"&gt;
+      &lt;map:matcher name="uri" 
+                   factory="org.apache.cocoon.matching.WildcardURIMatcher"/&gt;
+    &lt;/map:matchers&gt; 
+
+  &lt;/map:components&gt; 
+          
+  &lt;!--===========================Pipelines=================================--&gt;
+  &lt;map:pipelines&gt; 
+    &lt;map:pipeline&gt; 
+      &lt;map:match pattern="hello.html"&gt;
+        &lt;map:generate src="docs/samples/hello-page.xml"/&gt;
+        &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+        &lt;map:serialize type="html"/&gt; 
+      &lt;/map:match&gt; 
+    &lt;/map:pipeline&gt; 
+  &lt;/map:pipelines&gt;
+          
+&lt;/map:sitemap&gt; 
+</pre> 
+		
+<h2>cocoon.xconf</h2>
+<p>
+<span class="codefrag">cocoon.xconf</span> is the file that defines the
+			 <a href="avalon.html">Avalon</a> Components.</p>
+<p>For our study, we need the standard <span class="codefrag">cocoon.xconf</span> file
+			 of Cocoon.</p>
+<p>It can be found in <span class="codefrag">${cocoon}/WEB-INF/cocoon.xconf</span>.</p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+
+&lt;cocoon version="2.0"&gt;
+
+&lt;!-- ===================== General Components =========================== --&gt;
+
+  &lt;component role="org.apache.cocoon.components.parser.Parser" 
+             class="org.apache.cocoon.components.parser.JaxpParser"/&gt;
+  &lt;component role="org.apache.cocoon.components.store.Store"  
+             class="org.apache.cocoon.components.store.MemoryStore"/&gt;
+
+  &lt;component role="org.apache.cocoon.components.classloader.ClassLoaderManager" 
+      class="org.apache.cocoon.components.classloader.ClassLoaderManagerImpl"/&gt;
+
+  &lt;component
+      role="org.apache.cocoon.components.language.markup.MarkupLanguageSelector"
+      class="org.apache.cocoon.core.container.StandaloneServiceSelector"&gt;
+    &lt;component-instance name="xsp" 
+        class="org.apache.cocoon.components.language.markup.xsp.XSPMarkupLanguage"&gt;
+      &lt;parameter name="prefix" value="xsp"/&gt;
+      &lt;parameter name="uri" value="http://apache.org/xsp"/&gt;
+
+      &lt;target-language name="java"&gt;
+        &lt;parameter name="core-logicsheet" 
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/xsp.xsl"/&gt;
+
+        &lt;builtin-logicsheet&gt;
+          &lt;parameter name="prefix" value="xsp-request"/&gt;
+          &lt;parameter name="uri" value="http://apache.org/xsp/request/2.0"/&gt;
+          &lt;parameter name="href" 
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/request.xsl"/&gt;
+        &lt;/builtin-logicsheet&gt;
+
+        &lt;builtin-logicsheet&gt;
+          &lt;parameter name="prefix" value="xsp-response"/&gt;
+          &lt;parameter name="uri" value="http://apache.org/xsp/response/2.0"/&gt;
+          &lt;parameter name="href" 
+value="resource://org/apache/cocoon/components/language/markup/xsp/java/response.xsl"/&gt;
+        &lt;/builtin-logicsheet&gt;
+      &lt;/target-language&gt;
+    &lt;/component-instance&gt;
+
+    &lt;component-instance name="sitemap" 
+       class="org.apache.cocoon.components.language.markup.sitemap.SitemapMarkupLanguage"&gt;
+      &lt;parameter name="prefix" value="map"/&gt;
+      &lt;parameter name="uri" value="http://apache.org/cocoon/sitemap/1.0"/&gt;
+
+      &lt;target-language name="java"&gt;
+        &lt;parameter name="core-logicsheet" 
+value="resource://org/apache/cocoon/components/language/markup/sitemap/java/sitemap.xsl"/&gt;
+      &lt;/target-language&gt;
+    &lt;/component-instance&gt;
+  &lt;/component&gt;
+
+  &lt;component role="org.apache.cocoon.components.language.generator.ProgramGenerator" 
+             class="org.apache.cocoon.components.language.generator.ProgramGeneratorImpl"&gt;
+    &lt;parameter name="auto-reload" value="true"/&gt;
+  &lt;/component&gt;
+
+  &lt;!-- these components is used as a PoolController for the sitemap component pools  --&gt;
+  &lt;component role="org.apache.avalon.util.pool.PoolController" 
+             class="org.apache.cocoon.util.ComponentPoolController"/&gt;
+
+  &lt;sitemap file="sitemap.xmap"/&gt; 
+&lt;/cocoon&gt;
+</pre> 
+	  
+	 
+<h1>The sequence of things</h1> 
+		
+<h2>Role of Tomcat</h2>
+<p>The role of Tomcat is to initialize the CocoonServlet, and to
+			 receive the HttpRequest and pass it on to the CocoonServlet.</p>
+<h3>Initialize CocoonServlet</h3>
+<p>This is done by calling
+				<span class="codefrag">CocoonServlet.init(ServletConfig)</span>. This is the standard servlet
+				way to initialize a servlet.</p>
+<h3>Pass HttpRequest</h3>
+<p>On reception of a HttpRequest, Tomcat calls
+				<span class="codefrag">CocoonServlet.service(HttpRequest, HttpResponse)</span>. This is also
+				standard.</p> 
+		
+<h2>Initialization</h2>
+<h3>Overview</h3>
+<p>The steps that happen on initialization, are:</p>
+<h4>Find the classpath</h4>
+<p>Cocoon needs to know the classpath for compilation of the files
+				  it generates itself. This is where the classpath is stored.</p>
+<h4>Find the init file</h4>
+<p>The init file (normally <span class="codefrag">cocoon.xconf</span>, as defined in
+				  <span class="codefrag">${cocoon}/WEB-INF/web.xml</span>) contains the necessary information for
+				  Cocoon to decide which classes to use for which roles (refer to
+				  <a href="avalon.html">Avalon</a>).</p>
+<p>This is a feature that is added for increased configurability.
+				  If you were developing a one time solution, the information in this file would
+				  normally be hard coded, but the use of this file increases potential
+				  reusability.</p>
+<h4>Read the init file</h4>
+<p>The init file is an xml file (normally
+				  <span class="codefrag">cocoon.xconf</span>) which describes the classes to use for which
+				  roles.</p>
+<p>"Roles" are a concept of <a href="avalon.html">Avalon</a>.</p>
+<p>The handling of <span class="codefrag">cocoon.xconf</span> goes as follows:</p>
+<ol> 
+				  
+<li>Get the parser: This is something necessary for
+					 bootstrapping: cocoon.xconf contains the parser to be used by Cocoon, but
+					 cocoon.xconf is an xml file that has to be parsed itself. That's why Cocoon
+					 gets a default parser out of the System properties (this refers to the
+					 environment variable <span class="codefrag">$org.apache.cocoon.components.parser.Parser</span>
+					 of the OS). If no parser is defined in the environment, Cocoon will use
+					 <span class="codefrag">org.apache.cocoon.components.parser.JaxpParser</span> (a hard-coded
+					 default).</li> 
+				  
+<li>Get the components: Cocoon uses roles (refer to
+					 <a href="avalon.html">Avalon</a>) as its working classes. Each role is
+				implemented by one or more real classes (components, again an
+				<a href="avalon.html">Avalon</a> concept). This is where they are
+				retrieved.</li> 
+				
+<li>Get the sitemap: Here the location of the sitemap is retrieved.
+				  The actual compilation of the sitemap occurs in the HttpRequest handling.</li> 
+				
+</ol>
+<h3>UML sequence diagram</h3>
+<p>You can find it <a href="images/initialize_Cocoon.png">here</a>.</p> 
+		
+<h2>HttpRequest handling</h2>
+<h3>Overview</h3>
+<p>When the <span class="codefrag">CocoonServlet</span> gets a HttpRequest from the
+				servlet engine, it sets up an <span class="codefrag">Environment</span> (a
+				<span class="codefrag">HttpEnvironment</span> in this case) and passes that to
+				<span class="codefrag">Cocoon</span>. The <span class="codefrag">Environment</span> exists of Request, Response,
+				and some servlet info (such as requested URI and the servlet's path).</p>
+<p>This <span class="codefrag">Cocoon</span> object lets the <span class="codefrag">Environment</span>
+				decide which sitemap to use, and passes the sitemap filename along with the
+				<span class="codefrag">Environment</span> to a <span class="codefrag">Manager</span>. </p>
+<p>This one puts a <span class="codefrag">Handler</span> to work: it checks whether
+				there already exists a <span class="codefrag">Handler</span> with a compiled version of the
+				sitemap. If not, it creates one. This is what happens then:</p>
+<ol> 
+				
+<li>The <span class="codefrag">Handler</span> creates a <span class="codefrag">File</span> object
+				  with the asked URL.</li> 
+				
+<li>The <span class="codefrag">Manager</span> sets the <span class="codefrag">Serviceable</span> and the
+				  <span class="codefrag">Configuration</span> of the <span class="codefrag">Handler</span>. (These are
+				  <a href="avalon.html">Avalon</a> things).</li> 
+			 
+<li>If necessary, the <span class="codefrag">Manager</span> asks the
+				<span class="codefrag">Handler</span> to regenerate its sitemap class. (FIXME: As of today,
+				2000-11-08, I'm not sure if the "if necessary" check is working). Regeneration
+				exists in: 
+				<ol> 
+				  
+<li>The <span class="codefrag">Handler</span> gets the
+					 <span class="codefrag">"program-generator"</span> <span class="codefrag">Component</span> from its
+					 <span class="codefrag">Serviceable</span>.</li> 
+				  
+<li>The <span class="codefrag">load()</span> method of this
+					 <span class="codefrag">ProgramGeneratorImpl</span> is called. </li> 
+				  
+<li>The <span class="codefrag">ProgramGeneratorImpl</span> gets the
+					 <span class="codefrag">"markup-language"</span> (in this case it will get a
+					 <span class="codefrag">SitemapMarkupLanguage</span>) and <span class="codefrag">"programming-language"</span>
+					 (being <span class="codefrag">JavaLanguage</span>) <span class="codefrag">Component</span>s. </li> 
+				  
+<li>The <span class="codefrag">ProgramGeneratorImpl</span> asks the
+					 <span class="codefrag">SitemapMarkupLanguage</span> to generate code.</li> 
+				  
+<li>Then it asks the <span class="codefrag">JavaLanguage</span> to load the code.
+					 The <span class="codefrag">JavaLanguage</span> does this by creating a <span class="codefrag">Javac</span>
+					 object, setting its variables, and asking it to compile. Then it loads the
+					 class.</li> 
+				  
+<li>Then its back to the <span class="codefrag">ProgramGeneratorImpl</span> who
+					 tells the <span class="codefrag">JavaLanguage</span> to instantiate the just loaded class.</li> 
+				
+</ol>
+</li> 
+			 
+<li>At last, the sitemapManager asks the <span class="codefrag">Handler</span> to
+				process the <span class="codefrag">Environment</span>, and the <span class="codefrag">Handler</span> just
+				forwards this request to the generated sitemap class.</li> 
+			 
+</ol>
+<h3>UML sequence diagram</h3>
+<p>You can find it <a href="images/get_hello_html.png">here</a>.</p> 
+	  
+	 
+<h1>Description of classes</h1> 
+		
+<h2>CocoonServlet</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.servlet.CocoonServlet</span>
+</p>
+<p>This is the contact point for the servlet engine. It sets up the
+			 environment and passes all the work to a Cocoon object.</p> 
+		
+<h2>Cocoon</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.Cocoon</span>
+</p>
+<p>While this sounds to be the most important part of the Cocoon
+			 application, it is not. It is merely a Serviceable, meaning that it does some
+			 administrative work and gets other classes to work.</p> 
+		
+<h2>ConfigurationBuilder</h2>
+<p>
+<span class="codefrag">org.apache.avalon.ConfigurationBuilder</span>
+</p>
+<p>This one generates a Configuration out of a xml file.</p> 
+		
+<h2>Parser</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.components.parser.Parser</span>
+</p>
+<p>An interface that takes an xml file and throws SAX events to the
+			 outside.</p> 
+		
+<h2>Configuration</h2>
+<p>
+<span class="codefrag">org.apache.avalon.Configuration</span>
+</p>
+<p>This is an <a href="avalon.html">Avalon</a> interface. It
+		  assigns classes to roles. If an object needs a class for a specific role, it
+		  can ask a Configuration which class it has to use.</p> 
+		
+<h2>ProgramGenerator</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.components.language.programming.ProgrammingLanguage</span>
+</p>
+<p>Generates programs.</p> 
+		
+<h2>SitemapMarkupLanguage</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.components.language.markup.sitemap.SitemapMarkupLanguage</span>
+</p>
+<p>This one knows the markup of the sitemap, and helps writing the
+			 source file of the sitemap class.</p> 
+		
+<h2>JavaLanguage</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.components.language.programming.java.JavaLanguage</span>
+</p>
+<p>This takes care for outputing Java code as source of the sitemap
+			 class.</p> 
+		
+<h2>ResourcePipeline</h2>
+<p>
+<span class="codefrag">org.apache.cocoon.sitemap.ResourcePipeline</span>
+</p>
+<p>Holds the various steps that have to be taken when executing a
+			 pipeline.</p> 
+	  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/meta.xml
new file mode 100644
index 0000000..5027152
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-http-request/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/httprequest.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/content_en.html
new file mode 100644
index 0000000..ab1b9bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/content_en.html
@@ -0,0 +1,306 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ImageReader in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document describes the ImageReader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>ImageReader</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">image</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">ImageReader</span> component is used 
+            to serve binary image data in a sitemap pipeline.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.ImageReader</td>
+        
+</tr>
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">yes</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+    
+<p>
+      The <span class="codefrag">ImageReader</span> component is used to serve binary image data
+      in a sitemap pipeline. 
+    </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+      
+</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The <span class="codefrag">ImageReader</span> is used in a pipline as shown in the
+          pipeline snippet below:
+        </p>
+<pre class="code">
+&lt;map:match pattern="*.jpg"&gt;
+  &lt;map:read type="image" 
+    src="resources/images/{1}.jpg" 
+    mime-type="image/jpeg"&gt;
+    &lt;!-- optional setup parameters --&gt;
+  &lt;/map:read&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+          It is important to specify the <span class="codefrag">mime-type</span> attribute,
+          as it is passed to the browser as the <span class="codefrag">Content-Type</span>
+          in the <span class="codefrag">HTTP</span> response.
+        </p>
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          A <span class="codefrag">ImageReader</span> is declared in the sitemap readers
+          section, as shown in the sitemap readers snippet below:
+        </p>
+<pre class="code">
+&lt;map:readers default="resource"&gt;
+...
+  &lt;map:reader name="image" 
+    src="org.apache.cocoon.reading.ImageReader"
+    logger="sitemap.reader.image" 
+    pool-max="32"/&gt;
+    &lt;!-- optional reader configuration --&gt;
+    ...
+  &lt;/map:readers&gt;
+...
+        </pre>
+      
+<h2>Configuration</h2>
+<p>
+          The <span class="codefrag">ImageReader</span> has no configuration options. 
+        </p>
+      
+<h2>Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">ImageReader</span> accepts following sitemap
+          setup parameters:
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Parameter Name</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">expires</td>
+            <td colspan="1" rowspan="1">Time in milliseconds</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified it determines how long
+              in miliseconds the resources can be cached by any proxy or browser
+              between Cocoon2 and the requesting visitor.
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">width</td>
+            <td colspan="1" rowspan="1">Image width in pixels</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified it determines the
+              width of the binary image.
+              If no height parameter is specified, the aspect ratio
+              of the image is kept.
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">height</td>
+            <td colspan="1" rowspan="1">Image height in pixels</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified it determines the
+              height of the binary image.
+              If no width parameter is specified, the aspect ratio
+              of the image is kept.
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">allow-enlarging</td>
+            <td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. The <span class="codefrag">width</span> and <span class="codefrag">height</span> parameters allow an image 
+              to be resized. By default, if the image is smaller than the specified 
+              width and height, the image will be enlarged. In some circumstances, this
+              behaviour is undesirable, and can be switched off by setting this parameter
+              to "<span class="codefrag">false</span>". With this parameter set to "<span class="codefrag">false</span>", images will 
+              be reduced in size, but not enlarged. The default for this parameter is 
+              "<span class="codefrag">true</span>".
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">fit-uniform</td>
+            <td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional.  When set to
+              "<span class="codefrag">true</span>", it constrains the image size to the
+              dimensions of the specified width and height, while
+              preserving the original aspect ratio.  The value of
+              <span class="codefrag">&lt;allow-enlarging&gt;</span> is honored.  If
+              <span class="codefrag">&lt;allow-enlarging&gt;</span> is
+              "<span class="codefrag">true</span>", then the image will be enlarged as
+              much as possible while still fitting in the "box"; if 
+              <span class="codefrag">&lt;allow-enlarging&gt;</span> is
+              "<span class="codefrag">false</span>," the image may be reduced to fit the
+              box, but never enlarged.  The default
+              setting of <span class="codefrag">&lt;fit-uniform&gt;</span> is
+              "<span class="codefrag">false</span>".
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">grayscale</td>
+            <td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified and set to true it
+              will cause each image pixel to be normalized.
+              The default for this parameter is "<span class="codefrag">false</span>".
+            </td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">scale(Red|Green|Blue)</td>
+            <td colspan="1" rowspan="1">float</td>
+            <td colspan="1" rowspan="1">(Optional) Scale the RGB colour components by a multiplication factor.</td>
+          
+</tr>
+          
+<tr>
+            
+<td colspan="1" rowspan="1">offset(Red|Green|Blue)</td>
+            <td colspan="1" rowspan="1">float</td>
+            <td colspan="1" rowspan="1">(Optional) Offset the RGB colour components by an increment.</td>
+          
+</tr>
+        
+</table>
+<p>
+          The following pipeline snippet
+          uses the <span class="codefrag">ImageReader</span> for serving images
+          having an expiration time of 1 day (ie. 24 * 60 * 60 * 1000 ms = 86400000 ms), 
+          and scaling images to width 300 pixels.
+        </p>
+<pre class="code">
+&lt;map:match pattern="*.jpg"&gt;
+  &lt;map:reader type="image" 
+    &lt;map:parameter name="expires" value="86400000"/&gt;
+    &lt;map:parameter name="width" value="300"/&gt;
+  &lt;/map:reader&gt;
+...
+        </pre>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">ImageReader</span> does not change object model and sitemap parameters.
+          It only access parameter values for reading.
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">ImageReader</span> is able to transform 
+        <em>JPEG</em> images only. 
+        Nevertheless it can serve any image data in a non transforming mode.
+      </p>
+      
+<p>
+        The <span class="codefrag">ImageReader</span> does NOT support HTTP ranges, thus
+        it sets <span class="codefrag">Accept-Ranges</span> to <span class="codefrag">none</span>.
+      </p>
+      
+<p>
+        The java Bug Id 4502892 (which is found in *all* JVM implementations from
+        1.2.x and 1.3.x on all OS!), <span class="codefrag">ImageReader</span> must buffer 
+        the JPEG generation to avoid that connection resetting by the peer 
+        (user pressing the stop button, for example) crashes the entire JVM. 
+        This is evidently fixed in Sun JVM 1.3.1_04 however our workaround
+        remains for JVM less than 1.4
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-25-02: Initial document creation by Bernhard Huber
+        <br>
+        01-06-03: Renamed the expire-time -&gt; expires parameter,
+                  Fixed the statement about the byte range support, Torsten Curdt
+        <br>
+        03-07-03: Added allow-enlarging parameter, Upayavira
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages -->
+      
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/meta.xml
new file mode 100644
index 0000000..7cb3ddc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-image-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/image-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/content_en.html
new file mode 100644
index 0000000..0656aea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/content_en.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Image Directory Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the Image Directory Generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Image Directory Generator</h1>
+      
+<p>The Image Directory provides all the functionality of the
+        <a href="directory-generator.html">Directory Generator</a>. Additionally it
+        ensures that the files are images and adds their dimensions (<span class="codefrag">width</span>
+        and <span class="codefrag">height</span>) to the attributes. It is configured in the same way as the
+        Directory Generator.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/meta.xml
new file mode 100644
index 0000000..546c5d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-imagedirectory-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/imagedirectory-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/content_en.html
new file mode 100644
index 0000000..d245eb5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/content_en.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="XML Web Development Framework" name="DC.Subject">
+<meta content="cocoon-dev" name="DC.Creator">
+</head>
+<body>
+
+    
+<div align="center">
+<img class="figure" alt="Cocoon" src="images/cocoon.gif"></div>
+   
+<h1>News</h1>
+     
+<p>
+       XMLForm and JXForms have been removed from the 2.1.x distribution.
+       Please use the well established Cocoon Forms (former Woody) framework.
+     </p>
+   
+    
+<h1>What is Cocoon?</h1>
+      
+<p>
+        Apache Cocoon is a web development framework built around the concepts of
+        separation of concerns (making sure people can interact and collaborate on a
+        project, without stepping on each other toes) and component-based web
+        development.
+      </p>
+      
+<p>
+        Cocoon implements these concepts around the notion of "component pipelines",
+        each component on the pipeline specializing on a particular operation. This
+        makes it possible to use a "building block" approach for web solutions,
+        hooking together components into pipelines without any required programming.
+      </p>
+      
+<p>
+        Cocoon is "<em>web glue for your web application development needs</em>". It
+        is a glue that keeps concerns separate and allows parallel evolution of the
+        two sides, improving development pace and reducing the chance of conflicts.
+      </p>
+      
+<p>
+        Cocoon has been designed to coexist and interoperate side-by-side with your
+        existing J2EE solutions or to give them new functionality without requiring
+        any change in the existing infrastructure.
+      </p>
+      
+<p>
+        Cocoon interacts with many data sources, including filesystems, RDBMS,
+        LDAP, native XML databases, SAP&reg; systems and network-based data sources.
+        It adapts content delivery to the capabilities of different devices like HTML, WML,
+        PDF, SVG, and RTF, to name just a few. You can run Cocoon as a Servlet as well as
+        through a powerful, commandline interface. The deliberate design of its abstract
+        environment gives you the freedom to extend its functionality to meet your
+        special needs in a highly modular fashion.
+      </p>
+    
+    
+<h1>Cocoon Features</h1>
+      
+<p>
+        You want to get an overview of all available features of Cocoon in 5 minutes?
+        Read the <a href="features.html">features list</a>!
+      </p>
+    
+    
+<h1>Where can I find it?</h1>
+      
+<p>
+   To download the latest release @released.version@ of Apache Cocoon, go to the
+   <a class="external" href="http://cocoon.apache.org/mirror.cgi">download area.</a>
+      
+</p>
+      
+<p>
+   If you are looking for a past generation of Cocoon (no longer supported but still available),
+   go to the <a class="external" href="http://cocoon.apache.org/1.x/">Cocoon 1.x area</a>.
+      </p>
+    
+    
+<h1>Where to start?</h1>
+      
+<p>
+          With a large serving of core components and more than 45 additional "blocks", this has
+          become a big project and it is often hard for newcomers to find their way through the
+          (wonderful) world of Cocoon.
+      </p>
+      
+<p>
+          To make it easier, we have started to create <a href="./tracks/index.html">documentation tracks</a>
+          to help you locate the parts of the documentation that are the most relevant for your needs.
+          There are few tracks at the moment, but we hope to create more of them depending
+          on the feedback and help that we can get.
+      </p>
+    
+    
+<h1>More News about Cocoon</h1>
+      
+<p>
+Check out our <a class="external" href="http://cocoon.apache.org/news/">news page</a> for more up-to-date news about Cocoon.
+      </p>
+    
+    
+<div align="center">
+<img class="figure" alt="Built with Apache Cocoon" src="images/cocoon-built.gif"></div>
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/meta.xml
new file mode 100644
index 0000000..331aaf6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-index/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/content_en.html
new file mode 100644
index 0000000..8eb87b4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/content_en.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Installing Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stefano Mazzocchi" name="DC.Creator">
+<meta content="Giacomo Pati" name="DC.Creator">
+<meta content="Tom Klaasen" name="DC.Creator">
+<meta content="Chris Stevenson" name="DC.Creator">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Vadim Gritsenko" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="Nicola Ken Barozzi" name="DC.Creator">
+<meta content="Sylvain Wallez" name="DC.Creator">
+</head>
+<body>
+    
+<h1>System Requirements</h1>
+      
+<p>
+       Apache Cocoon requires the following systems to be already installed in your system:
+      </p>
+
+      
+<p>
+<strong>Java Virtual Machine</strong>
+       A Java 1.3 or later compatible virtual machine must be present for both
+       command line and servlet type usage of Apache Cocoon. Note that all servlet engines
+       require a JVM to run so if you are already using servlets you already have
+       one installed.
+      </p>
+
+      
+<p>
+<strong>Servlet Engine</strong>
+       A Servlet 2.3 compliant servlet engine must be present in order to support
+       servlet operation and dynamic request handling. Note that this requirement
+       is optional for command line operation.  Note also that Cocoon now ships 
+       with a stripped down version of Jetty suitable for immediately testing 
+       with no further downloads.
+      </p>
+
+      
+<p>When the time comes to run your Cocoon application in a full featured 
+      servlet container, you may want to consider the following Open Source 
+      options:</p> 
+      
+<ol> 
+      	
+<li>The Apache Tomcat project
+      		<a class="external" href="http://jakarta.apache.org/tomcat/">http://jakarta.apache.org/tomcat/</a>
+      	
+</li>
+      	
+<li>The full version of Jetty 
+      		<a class="external" href="http://jetty.mortbay.org/">http://jetty.mortbay.org/</a>
+      	
+</li>
+      
+</ol>
+    
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/meta.xml
new file mode 100644
index 0000000..83a60ac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-install-requirements/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>installing/requirements.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/content_en.html
new file mode 100644
index 0000000..45642da
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/content_en.html
@@ -0,0 +1,1242 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Installing Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Cocoon Developers" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Getting Apache Cocoon</h1>
+      
+<p>
+       You have three choices for getting Cocoon: you can either download
+       a stable release, or you can download development snapshot, or you can
+       get the latest development version directly from the cvs repository.
+      </p>
+      
+<h2>Download a distribution</h2>
+<p>
+        You can simply download the latest official release from the
+        <a class="external" href="http://cocoon.apache.org/mirror.cgi">Cocoon distribution</a>
+        directory.
+       </p>
+      
+<h2>Download a development snapshot</h2>
+<p>
+        You also can download one of the development snapshots from the
+        <a class="external" href="http://cocoon.apache.org/mirror.cgi#nightly">CVS snapshots</a>
+        directory.
+       </p>
+      
+<h2>Step-by-step cvs instructions for Windows</h2>
+<p>See the Cocoon document
+         <a class="external" href="http://cocoon.apache.org/community/contrib.html">Contrib</a>
+         for starting tips.
+        </p>
+<ol>
+          
+<li>Download a recent
+            <a class="external" href="http://sourceforge.net/projects/cvsgui/">WinCVS</a>
+            (1.2 or above);
+          </li>
+          
+<li>Install it;</li>
+          
+<li>Start it;</li>
+          
+<li>Click on admin-&gt;preferences;</li>
+          
+<li>In "Enter the CVSROOT:" enter
+            ":pserver:anoncvs@cvs.apache.org:/home/cvspublic" (without quotes);</li>
+          
+<li>In "Authentication:" choose "'passwd' file on the cvs server";</li>
+          
+<li>Click "Ok";</li>
+          
+<li>Click admin-&gt;login;</li>
+          
+<li>When asked for the password: answer "anoncvs" (without quotes);</li>
+          
+<li>Click "create-&gt;checkout module";</li>
+          
+<li>Module name and path on the server is "cocoon-2.1" (no quotes);</li>
+          
+<li>Choose a dir to put the source code in;</li>
+          
+<li>Go to the "Checkout-options" tab and select "By revision/tag/branch"
+              and enter "HEAD";</li>
+          
+<li>Click "Ok";</li>
+          
+<li>If everything goes well, messages will start to appear in the log
+            window;</li>
+          
+<li>Wait until you see "*****CVS exited normally with code 0*****" in the
+            log window;</li>
+          
+<li>The Cocoon source is now on your harddrive.</li>
+        
+</ol>
+      
+<h2>Step-by-step cvs instructions for Unix</h2>
+<ol>
+          
+<li>Start the shell of your choice.</li>
+          
+<li>Enter "cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login".</li>
+          
+<li>When asked for the password: answer "anoncvs".</li>
+          
+<li>Enter "cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic -z3 checkout
+            -r HEAD cocoon-2.1". This will create a directory called "cocoon-2.1" where the
+            Cocoon2 source will be stored.</li>
+          
+<li>Wait until cvs has finished.</li>
+          
+<li>The Cocoon source is now on your harddrive.</li>
+        
+</ol>
+<p>In case you want to update your Cocoon source tree to the
+          current version, change to the "cocoon-2.1" directory and
+          call "cvs -z3 update -d -P".</p>
+    
+
+    
+<h1>Configuring Environment</h1>
+      
+<h2>Set JAVA_HOME environment variable</h2>
+<p>Set the JAVA_HOME environment variable to point to the root directory of
+          the Java Development Kit installed on your machine. To do this simply type:</p>
+<pre class="code">
+[unix]  JAVA_HOME=/path/to/java/
+[win32] SET JAVA_HOME=c:\path\to\java
+        </pre>
+<p>Your mileage may vary, but you know how to setup environments, right?</p>
+
+      
+<h2>Java 1.4 configuration</h2>
+<p>Cocoon requires more recent versions of the Xerces and Xalan libraries
+          than those shipped with j2se 1.4. To override bundled libraries, follow
+          these steps:
+        </p>
+<ol>
+          
+<li>
+            Create <span class="codefrag">%JAVA_HOME%\jre\lib\endorsed</span> directory. (Tomcat users
+            use <span class="codefrag">%TOMCAT_HOME\common\endorsed</span> instead)
+          </li>
+          
+<li>
+            Copy <span class="codefrag">xercesXXX.jar</span>, <span class="codefrag">xalan-XXX.jar</span>,
+            and the <span class="codefrag">xml-apis.jar</span> from the
+            <span class="codefrag">.\lib\endorsed\</span> to the new directory created above.
+          </li>
+        
+</ol>
+<p>Due to changes in JDBC between JDK 1.3 and JDK 1.4, it is not possible
+           to use Cocoon built on JDK 1.3 with JDK 1.4 when it comes to database
+           connections. Make sure you prepare cocoon with a JDK that matches the
+           one you will deploy on.
+        </p>
+
+      
+<h2>JDK Dependency</h2>
+<p>Cocoon requires a Java compiler for installation and for running some
+        	components like XSP etc. For components, the default configuration of
+        	Cocoon does not use the compiler in JAVA_HOME, but a version shipped
+        	with Cocoon.
+        </p>
+<div class="note">You can configure which compiler Cocoon uses in WEB-INF/lib.
+        </div>
+      
+<div class="fixme">ghoward:
+      Is this still an issue?</div>
+
+      
+<h2>UNIX with X server</h2>
+<p>Cocoon is bundled with the <a class="external" href="http://xml.apache.org/batik/">Batik</a>
+          (SVG rasterization toolkit) to deliver SVG imaging capabilities. Batik uses Java
+          <span class="codefrag">java.awt</span> library, which (at least in Sun JDK before 1.4) requires
+          graphics display. This means that X server must be running and Cocoon should
+          have permission to connect to it.</p>
+<p>Easiest way to avoid X server connection problem (and to have mentioned permission)
+          is to install and run Cocoon and entire servlet engine of your choice under regular
+          user account.</p>
+<p>For security, and many other reasons, X server can be replaced by Xfvb
+          or PJA (alternative awt implementation).</p>
+<div class="note">Sun JDK 1.4 does not require graphics display anymore, but Java has to be
+          started with the argument <span class="codefrag">-Djava.awt.headless=true</span>,
+          and X libraries still must be installed.</div>
+<div class="fixme">ghoward:
+      Is this still an issue?</div>
+
+      
+<h2>Headless UNIX and PJA</h2>
+<p>If you are using unix with the Sun JDK 1.4, it can run in the
+          headless environment (but you still must have X libraries installed!)
+          when following option is provided on Java startup:</p>
+<pre class="code">-Djava.awt.headless=true</pre>
+<div class="note">If you use Tomcat, this can be done by setting environment variable
+          CATALINA_OPTS (Tomcat 4.x), or TOMCAT_OPTS (Tomcat 3.x):</div>
+<pre class="code">export CATALINA_OPTS='-Djava.awt.headless=true'</pre>
+<p>If you are using unix with the Sun JDK 1.3.1 or earlier, it's awt
+          implementation requires you to use X even if you aren't actually
+          displaying anything. One simple solution is to use a different
+          implementation of the awt.</p>
+<ol>
+          
+<li>From www.eteks.com you can get an awt replacement that doesn't need X:
+            <a class="external" href="http://www.eteks.com/pja/en/">http://www.eteks.com/pja/en/</a>.</li>
+          
+<li>Then add the following options to the Java command starting your container:
+          </li>
+        
+</ol>
+<pre class="code">
+-Xbootclasspath/a:/path/to/pja.jar
+-Dawt.toolkit=com.eteks.awt.PJAToolkit
+-Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment
+-Djava.awt.fonts=/usr/local/jdk/jre/lib/fonts/
+        </pre>
+<div class="note">If you use Tomcat, this can be done by setting environment variable
+          CATALINA_OPTS (Tomcat 4.x), or TOMCAT_OPTS (Tomcat 3.x):</div>
+<pre class="code">
+export CATALINA_OPTS='-Xbootclasspath/a:/path/to/pja.jar \
+    -Dawt.toolkit=com.eteks.awt.PJAToolkit \
+    -Djava.awt.graphicsenv=com.eteks.java2d.PJAGraphicsEnvironment \
+    -Djava.awt.fonts=/usr/local/jdk/jre/lib/fonts/'
+        </pre>
+    
+
+    
+<h1>Building Cocoon</h1>
+      
+<h2>Optional functionality</h2>
+<div class="note">This is an area that has changed significantly since 2.0</div>
+<h3>Blocks</h3>
+<p>Additional "components" in Cocoon 2.1 are now implemented using a partial
+            implementation of a concept called "blocks". Full support (planned for the
+            next release) will include hot-deployable services with java-like extension
+            and inheritance. For this release, blocks are implemented as self contained
+            units of code, samples, files and configuration. Most, if not all optional
+            features have been factored out into blocks and can be neatly included or
+            excluded as a unit.
+          </p>
+<p>Most blocks are configured by default to be included in the build, but can
+            be excluded using a <span class="codefrag">local.blocks.properties</span> file.
+          </p>
+<p>
+            Some blocks delivered with Cocoon require additional libraries which can not
+            be redistributed with Cocoon (e.g. the Php block). The documentation for
+            these should provide more information, and you should find a "mocks" directory
+            containing non-functional code provided merely to allow compilation.
+          </p>
+<h3>Optional Jars</h3>
+<p>Some additional libraries could not be factored ou 
+            into a block. For example, the Jakarta Commons HttpClient jar is used by
+            several different optional components, some not in blocks. If you determine
+            that one of these is not necessary for your build, you can eliminate it from
+            your build by removing its entry in lib/jars.xml and removing the jar from
+            lib/optional.
+          </p>
+<h3>Building a minimal Cocoon</h3>
+<p>By creating and editing local.build.properties and local.blocks.properties
+            you can remove any unnecessary features you desire.
+          </p>
+      
+<h2>Running the build</h2>
+<div class="note">This is an area that has changed significantly since 2.0</div>
+<p>Cocoon uses <a class="external" href="http://jakarta.apache.org/ant/">Jakarta Ant</a>
+          for the build and installation, and comes with a build script
+          ([unix]./build.sh, [win32] .\build.bat) that automates the process.
+        </p>
+<div class="note">If you want to use build.xml directly with your copy of Ant, please
+          run the build script at least once after every CVS checkout, to ensure that
+          extra initializations like jar copying are done correctly.
+        </div>
+<div class="note">The build script overrides the existing ANT_HOME variable.</div>
+<p>There are basically two options that can be set as parameters to
+          the script: <strong>targets</strong> and <strong>properties</strong>.
+        </p>
+<div class="note">The use of -D style properties as parameters to the build is deprecated.
+          Use the build and blocks properties files instead.</div>
+<h3>About build targets</h3>
+<p>Targets are the execution units available in
+            <a class="external" href="http://jakarta.apache.org/ant/">Ant</a> build files.</p>
+<p>Targets are specified by appending them to the script invocation:</p>
+<pre class="code">
+[unix]  ./build.sh target1 target2 ...
+[win32] .\build.bat target1 target2 ...
+          </pre>
+<h3>Cocoon build targets</h3>
+<p>The <strong>build.xml</strong> file comes with some basic
+            important targets. If no target is specified, the default one
+            is used (defined in build.xml).</p>
+<p>Cocoon targets place work files and results in a build directory
+            under the cocoon root. The only exception are the distribution targets
+            that build in a directory called dist.</p>
+<p>The key targets you will use most often are noted below. For a listing
+            of all available targets, run:</p>
+<pre class="code">
+[unix]  ./build.sh -projecthelp
+[win32] .\build.bat -projecthelp
+          </pre>
+<h4>build clean</h4>
+<p>Cleans the build directory. It is recommended to clean Cocoon
+              build directory every time you upgrade Cocoon, or add/remove
+              libraries from the <span class="codefrag">./lib/optional/</span>
+              directory, or change JDK version.
+            </p>
+<h4>build webapp [default]</h4>
+<p>Builds a Cocoon web application in build/webapp. This is the default target, so
+              running the build script with no arguments calls this target.
+            </p>
+<div class="note">For quick testing, a stripped down version of Jetty is included in the
+              distribution. After a <span class="codefrag">build webapp</span> Jetty can be launched by
+              <span class="codefrag">cocoon servlet</span> and Cocoon will be available at http://localhost:8888/.
+            </div>
+<h4>build war</h4>
+<p>Builds a Cocoon web application in build/webapp and packages it as a .war file.</p>
+    
+
+    
+<h1>Installing Cocoon</h1>
+      
+<p>In most servlet engines, this is just a matter of copying
+        the war file or webapp directory to a specific directory and the
+        engine will take care of installing it when restarted.</p>
+
+      
+<div class="note">If you are using JDK 1.4, be sure you have read and followed the
+	      "Java 1.4 configuration" information above.</div>
+      
+<p>If those simple instructions do not work as expected, you may find
+	      help in some of the container-specific notes below contributed by
+	      users:
+      </p>
+      
+<h2>Installing on Tomcat 3.3.X</h2>
+<p>This is a very easy installation.</p>
+<ol>
+          
+<li>
+            Build the Cocoon webapp as described above.
+          </li>
+          
+<li>
+            Copy <span class="codefrag">cocoon/build/cocoon/cocoon.war</span>
+            into <span class="codefrag">tomcat/webapps</span> directory.
+          </li>
+          
+<li>
+            Start Tomcat: Go to the <span class="codefrag">tomcat/bin</span> directory,
+            and run the startup script.
+          </li>
+          
+<li>
+            Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:8080/cocoon/</span>
+          
+</li>
+          
+<li>
+            Congratulations! You should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+
+      
+<h2>Installing on Tomcat 3.2.X</h2>
+<div class="note">Cocoon requires Tomcat version 3.2 or greater. It wouldn't work
+        with Tomcat 3.1.X</div>
+<p>Tomcat currently uses a different version of the XML parser
+          than Cocoon. To get Cocoon to work, you need to perform the
+          following steps:</p>
+<ol>
+          
+<li>
+            
+<strong>Stop Tomcat</strong>
+            Go to the tomcat/bin directory, and run the shutdown script.
+          </li>
+          
+<li>
+            
+<strong>Delete tomcat/lib/jaxp.jar</strong>
+            Tomcat's jaxp.jar is 'sealed', and since xerces contains its
+            own implementation of the JAXP standard extension, Java
+            will fail to load xerces and report a 'Package Sealing Violation'
+            if both are in the classpath.
+          </li>
+          
+<li>
+            
+<strong>Rename tomcat/lib/parser.jar to tomcat/lib/zparser.jar</strong>
+            Tomcat's parser.jar contains older versions of some the same
+            XML APIS that Xerces uses, and these will prevent Xerces from
+            functioning properly if they appear before Xerces in the classpath.
+            Since Tomcat's startup scripts automatically load all the jar files
+            in tomcat/lib in name order, changing the name of the file causes it
+            to be loaded last in the classpath.
+          </li>
+          
+<li>
+            
+<strong>Copy the cocoon/lib/core/xerces-XXX.jar and cocoon/lib/core/xml-apis.jar
+            JAR files to tomcat/lib</strong>
+            Cocoon will now be able to see and use the correct XML libraries.
+          </li>
+          
+<li>
+            
+<strong>Copy cocoon/build/cocoon/cocoon.war into tomcat/webapps</strong>
+          
+</li>
+          
+<li>
+            
+<strong>Start Tomcat</strong>
+            Go to the tomcat/bin directory, and run the startup script.
+          </li>
+          
+<li>
+            
+<strong>Start using Cocoon</strong>
+            Access the URI <span class="codefrag">http://localhost:8080/cocoon/</span>
+            with your favorite browser and start to enjoy the world of Cocoon.
+          </li>
+        
+</ol>
+
+      
+<h2>Installing on Tomcat 4.0 - 4.0.1, 4.0.4b1</h2>
+<p>Tomcat 4 is a really straight-forward installation.</p>
+<ol>
+          
+<li>
+            Build the Cocoon webapp as described above.
+          </li>
+          
+<li>
+            Copy <span class="codefrag">cocoon/build/cocoon/cocoon.war</span> into
+            <span class="codefrag">tomcat/webapps</span> directory.
+          </li>
+          
+<li>
+            Start Tomcat: Go to the <span class="codefrag">tomcat/bin</span> directory,
+            and run the startup script.
+          </li>
+          
+<li>
+            Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:8080/cocoon/</span>
+          
+</li>
+          
+<li>
+            Congratulations! You should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+
+      
+<h2>Installing on Tomcat 4.0.3</h2>
+<p>If you have to use Tomcat 4.0.3, you have to replace its
+          XML parser with the one shipped with Cocoon.</p>
+<ol>
+          
+<li>Remove <span class="codefrag">tomcat/common/lib/xerces.jar</span> file.</li>
+          
+<li>Copy following libraries from the <span class="codefrag">cocoon/lib/core</span>
+            directory to the tomcat/common/lib directory:
+            <ul>
+              
+<li>xalan-XXX.jar</li>
+              
+<li>xercesImpl-XXX.jar</li>
+              
+<li>xml-apis.jar</li>
+            
+</ul>
+          
+</li>
+          
+<li>Copy <span class="codefrag">cocoon/lib/optional/batik-all-XXX.jar</span>
+            to the tomcat/common/lib directory.</li>
+          
+<li>Edit <span class="codefrag">extra-classpath</span> parameter in the
+            <span class="codefrag">cocoon/src/webapp/WEB-INF/web.xml</span> file:
+          </li>
+        
+</ol>
+<p>For UNIX:</p>
+<pre class="code">
+&lt;init-param&gt;
+  &lt;param-name&gt;extra-classpath&lt;/param-name&gt;
+  &lt;param-value&gt;/tomcat/common/lib/xalan-XXX.jar:
+/tomcat/common/lib/xercesImpl-XXX.jar:
+/tomcat/common/lib/xml-apis.jar:
+/tomcat/common/lib/batik-all-XXX.jar&lt;/param-value&gt;
+&lt;/init-param&gt;
+</pre>
+<p>For Windows:</p>
+<pre class="code">
+&lt;init-param&gt;
+  &lt;param-name&gt;extra-classpath&lt;/param-name&gt;
+  &lt;param-value&gt;C:\tomcat\common\lib\xalan-XXX.jar;
+C:\tomcat\common\lib\xercesImpl-XXX.jar;
+C:\tomcat\common\lib\xml-apis.jar;
+C:\tomcat\common\lib\batik-all-XXX.jar&lt;/param-value&gt;
+&lt;/init-param&gt;
+</pre>
+<div class="note">param-value should be in one line!
+        Also, replace <span class="codefrag">/tomcat/</span> (UNIX), <span class="codefrag">C:\tomcat\</span>
+        (Windows) with the path to your Tomcat installation home.</div>
+<ol>
+          
+<li>
+            Clean Cocoon build directory: <span class="codefrag">build clean</span>
+          
+</li>
+          
+<li>
+            Build Cocoon webapp: <span class="codefrag">build webapp</span>
+          
+</li>
+          
+<li>
+            Remove xalan-XXX.jar, xercesImpl-XXX.jar, batik-all-XXX.jar,
+            and xml-apis.jar from the cocoon.war archive.
+          </li>
+          
+<li>
+            Copy <span class="codefrag">cocoon/build/cocoon/cocoon.war</span> into
+            <span class="codefrag">tomcat/webapps</span> directory.
+          </li>
+          
+<li>
+            Start Tomcat: Go to the <span class="codefrag">tomcat/bin</span> directory,
+            and run the startup script.
+          </li>
+          
+<li>
+            Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:8080/cocoon/</span>
+          
+</li>
+          
+<li>
+            Congratulations! You should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+
+      
+<h2>Installing on Tomcat 4.0.4b1 LE with JDK 1.4.0</h2>
+<p>This combination is also easy to install.</p>
+<ol>
+          
+<li>
+            Build the Cocoon webapp as described above.
+          </li>
+          
+<li>
+            Copy <span class="codefrag">cocoon-2.1/build/cocoon/cocoon.war</span> into
+            <span class="codefrag">tomcat/webapps</span> directory.
+          </li>
+          
+<li>
+            Set environment variable <span class="codefrag">CATALINA_OPTS=-Djava.awt.headless=true</span>
+          
+</li>
+          
+<li>
+            Start Tomcat: Go to the <span class="codefrag">tomcat/bin</span> directory,
+            and run the startup script.
+          </li>
+          
+<li>
+            Open the Cocoon welcome page: <span class="codefrag">http://localhost:8080/cocoon/</span>
+          
+</li>
+          
+<li>
+            Congratulations! You should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+<div class="note">
+          Make sure that JAVA_HOME enviroment variable points to the JDK1.4.0.
+          If you had JDK1.3.1 or earlier before, <span class="codefrag">build clean</span> before
+          all these steps.
+        </div>
+
+      
+<h2>Installing on BEA Weblogic 6.0sp2</h2>
+<p>This installs Cocoon using the cocoon.war file.
+          This was successfully installed under Windows 2000 and JDK 1.3.1.
+          Unix users will need to adjust appropriately. If you haven't done so already,
+          build a domain and a server. In this discussion, the name of the domain
+          is 'mydomain', the name of the server is 'myserver', and WebLogic installation
+          directory is <span class="codefrag">c:\bea\wlserver6.0sp2\</span>. These are the BEA defaults.
+        </p>
+<ol>
+          
+<li>
+            Build the Cocoon webapp as described above.
+          </li>
+          
+<li>
+            Copy <span class="codefrag">cocoon\build\cocoon\webapp</span> directory into the
+            <span class="codefrag">c:\bea\wlserver6.0sp2\config\mydomain\applications\</span>
+            directory of your WebLogic server.
+          </li>
+          
+<li>
+            Copy the <span class="codefrag">xerces-XXX.jar</span> and <span class="codefrag">xml-apis.jar</span> JAR files from the
+            <span class="codefrag">cocoon\lib\core\</span> to the directory of your choice, say <span class="codefrag">c:\bea\</span>.
+          </li>
+          
+<li>
+            Add to the config.xml of the WebLogic server following snippet:
+          </li>
+        
+</ol>
+<pre class="code">
+&lt;Application Deployed="true" Name="Cocoon"
+    Path="./config/mydomain/applications"&gt;
+  &lt;WebAppComponent Name="cocoon"
+                   Targets="myserver"
+                   URI="cocoon"/&gt;
+&lt;/Application&gt;
+</pre>
+<ol>
+          
+<li>
+            Edit <span class="codefrag">c:\bea\wlserver6.0sp2\config\mydomain\startWebLogic.cmd</span> file,
+            add xerces and xml-apis JAR files to the classpath:
+          </li>
+        
+</ol>
+<pre class="code">
+set CLASSPATH=c:\bea\xerces-XXX.jar;c:\bea\xml-apis.jar
+set CLASSPATH=%CLASSPATH%;.;.\lib\weblogic_sp.jar
+set CLASSPATH=%CLASSPATH%;.\lib\weblogic.jar
+</pre>
+<ol>
+          
+<li>
+            Start WebLogic server using <span class="codefrag">startWebLogic.cmd</span>.
+          </li>
+          
+<li>
+            Using a browser, you might want to check WebLogic configuration using console:
+            <span class="codefrag">http://localhost:7001/console/</span>.
+          </li>
+          
+<li>
+            Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:7001/cocoon/</span>
+            (Don't forget the final '/' in the link.)
+          </li>
+          
+<li>
+            Congratulations! You should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+<div class="note">Because of some issues with this version of WebLogic, you will
+          see lots of exceptions in the WebLogic's console window.
+        </div>
+
+      
+<h2>Installing on ServletExec 3.1 (In Process with IIS)</h2>
+<p>This installs Cocoon in a "war" configuration.  This was successfully
+         installed under Windows NT 4.0 and IIS 4.  I don't believe that SE is
+         available for unix.</p>
+<div class="note">Please note that <em>JDK 1.3</em> is required.</div>
+<ol>
+          
+<li>Install IIS as usual</li>
+          
+<li>Install ServletExec (default paths will be used throughout), but
+            don't start it.</li>
+          
+<li>Build Cocoon's war file (include lib's)</li>
+          
+<li>Copy <em>cocoon.war</em> into
+            <em>C:\Program Files\New Atlanta\ServletExec ISAPI\webapps\default</em>,
+            creating the directory default if required.</li>
+          
+<li>Start IIS.</li>
+          
+<li>Open the Cocoon welcome page (<span class="codefrag">http://localhost/cocoon/</span>)</li>
+          
+<li>
+            Congratulations! (hopefully) you should see the Cocoon welcome page.
+          </li>
+        
+</ol>
+      
+<h2>Installing on JBoss 2.4.4 with Tomcat 4.0.1 (Catalina)</h2>
+<p>
+         This section describes the deployment of the Cocoon sample WAR with
+         the JBoss-2.4.4_Tomcat-4.0.1 package. It assumes that you built Cocoon as
+         described above or downloaded the binary Cocoon distribution. All steps have
+         been tested with a fresh JBoss 2.4.4 installation on Linux and Windows 2000.
+        </p>
+<div class="note">The JBoss/Tomcat bundle is available from the
+          <a class="external" href="http://sourceforge.net/projects/jboss/">JBoss project page</a>
+        
+</div>
+<p>
+          The JBoss/Tomcat package has the following directory structure
+        </p>
+<pre class="code">
+[path]/JBoss-2.4.4_Tomcat-4.0.1/jboss
+[path]/JBoss-2.4.4_Tomcat-4.0.1/catalina
+        </pre>
+<p>
+          Subsequently,
+        </p>
+<ul>
+          
+<li>
+            
+<span class="codefrag">jboss</span> denotes the <span class="codefrag">JBoss-2.4.4_Tomcat-4.0.1/jboss</span> directory
+          </li>
+          
+<li>
+            
+<span class="codefrag">catalina</span> is short for <span class="codefrag">JBoss-2.4.4_Tomcat-4.0.1/catalina</span>
+          
+</li>
+          
+<li>and <span class="codefrag">cocoon</span> is the base directory of your Cocoon distribution or CVS checkout.</li>
+        
+</ul>
+<p>In order to get Cocoon running you have to install Xerces as default XML parser for JBoss.</p>
+<ul>
+          
+<li>Stop JBoss if it is running.</li>
+          
+<li>Remove the following files from the <span class="codefrag">jboss/lib</span> directory
+            <ul>
+              
+<li>crimson.jar</li>
+              
+<li>jaxp.jar</li>
+            
+</ul>
+          
+</li>
+          
+<li>Copy <span class="codefrag">xml-apis.jar</span> from <span class="codefrag">cocoon/lib/core/</span> to <span class="codefrag">jboss/lib</span>
+          
+</li>
+          
+<li>Change <span class="codefrag">jboss/bin/run.sh</span>
+          
+</li>
+        
+</ul>
+<pre class="code">
+[...]
+# Add the XML parser jar and set the JAXP factory names
+# Crimson parser JAXP setup(default)
+<strong># Change it to Xerces for C2</strong>
+JBOSS_CLASSPATH=$JBOSS_CLASSPATH:<strong>../lib/xml-apis.jar</strong>
+          <strong># Remove the following two lines</strong>
+JAXP=-Djavax.xml.parsers.DocumentBuilderFactory=\
+  org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
+JAXP="$JAXP -Djavax.xml.parsers.SAXParserFactory=\
+  org.apache.crimson.jaxp.SAXParserFactoryImpl"
+[...]
+        </pre>
+<div class="note">Windows users have to change <span class="codefrag">run.bat</span> accordingly.</div>
+<ul>
+          
+<li>Start JBoss with <span class="codefrag">run_with_catalina.sh</span> or <span class="codefrag">run_with_catalina.bat</span>
+</li>
+          
+<li>Copy <span class="codefrag">cocoon/build/cocoon/cocoon.war</span> to <span class="codefrag">jboss/deploy</span>
+</li>
+          
+<li>Check the server log to make sure that <span class="codefrag">J2EE application: [...]/cocoon.war is deployed.</span>
+</li>
+          
+<li>Open the Cocoon welcome page (<span class="codefrag">http://localhost:8080/cocoon/</span>)</li>
+          
+<li>You should see the Cocoon welcome page.</li>
+        
+</ul>
+<div class="note">As both JBoss and Cocoon ship with a Hypersonic database installed,
+          these two conflict and you won't be able to use Cocoon database (SQL) samples.
+          Then again, you probably use JBoss for EJB persistence anyway, so this shouldn't
+          bother you too much ;-)
+        </div>
+
+      
+<h2>Installing on JBoss 2.2.2 with Tomcat 3.2.2</h2>
+<p>This section describes the deployment of the Cocoon sample WAR with
+          the JBoss 2.2.2/Tomcat-3.2.2 package. It assumes that you built Cocoon as described above.
+          All steps have been tested with a fresh JBoss 2.2.2 installation on Linux and Windows ME(sic).</p>
+<div class="note">The JBoss/Tomcat bundle is available from the
+          <a class="external" href="http://sourceforge.net/projects/jboss/">JBoss project page</a>
+        
+</div>
+<p>The JBoss/Tomcat package has the following directory structure</p>
+<pre class="code">
+[path]/JBoss-2.2.2_Tomcat-3.2.2/jboss
+[path]/JBoss-2.2.2_Tomcat-3.2.2/tomcat
+        </pre>
+<p>Subsequently,</p>
+<ul>
+          
+<li>
+            
+<span class="codefrag">jboss</span> denotes the <span class="codefrag">JBoss-2.2.2_Tomcat-3.2.2/jboss</span> directory</li>
+          
+<li>
+            
+<span class="codefrag">Tomcat</span> is short for <span class="codefrag">JBoss-2.2.2_Tomcat-3.2.2/tomcat</span>
+          
+</li>
+          
+<li>and <span class="codefrag">cocoon</span> is the base directory of your Cocoon distribution or CVS checkout.</li>
+        
+</ul>
+<p>In order to get Cocoon running you have to install Xerces as default XML parser for JBoss.</p>
+<ul>
+          
+<li>Stop the server if it is running.</li>
+          
+<li>Remove the following files from the <span class="codefrag">jboss/lib</span> directory
+            <ul>
+              
+<li>crimson.jar</li>
+              
+<li>jaxp.jar</li>
+              
+<li>xml.jar</li>
+            
+</ul>
+          
+</li>
+          
+<li>Remove the following files from the <span class="codefrag">tomcat/lib</span>
+           directory
+            <ul>
+              
+<li>jaxp.jar</li>
+              
+<li>parser.jar</li>
+            
+</ul>
+          
+</li>
+          
+<li>Copy <span class="codefrag">xerces-XXX.jar</span> from <span class="codefrag">cocoon/lib/core/</span> to <span class="codefrag">jboss/lib</span>
+          
+</li>
+          
+<li>Change <span class="codefrag">jboss/bin/run.sh</span>
+          
+</li>
+        
+</ul>
+<pre class="code">
+[...]
+# Add the XML parser jars and set the JAXP factory names
+# Crimson parser JAXP setup(default)
+<strong># Change it to Xerces for C2</strong>
+JBOSS_CLASSPATH=$JBOSS_CLASSPATH:<strong>../lib/xerces-XXX.jar</strong>
+          <strong># Remove the following two lines</strong>
+JAXP=-Djavax.xml.parsers.DocumentBuilderFactory=\
+  org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
+JAXP="$JAXP -Djavax.xml.parsers.SAXParserFactory=\
+  org.apache.crimson.jaxp.SAXParserFactoryImpl"
+[...]
+        </pre>
+<div class="note">Windows users have to change <span class="codefrag">run.bat</span> accordingly.</div>
+<ul>
+          
+<li>Start JBoss with <span class="codefrag">run_with_tomcat.sh</span> or <span class="codefrag">run_with_tomcat.bat</span>
+</li>
+          
+<li>Copy <span class="codefrag">cocoon/build/cocoon/cocoon.war</span> to <span class="codefrag">jboss/deploy</span>
+</li>
+          
+<li>Check the server log to make sure that <span class="codefrag">J2EE application: [...]/cocoon.war is deployed.</span>
+</li>
+          
+<li>Open the Cocoon welcome page (<span class="codefrag">http://localhost:8080/cocoon/</span>)</li>
+          
+<li>Congratulations! (hopefully) you should see the Cocoon welcome page.</li>
+        
+</ul>
+<div class="note">As both JBoss and Cocoon ship with a Hypersonic database installed,
+          these two conflict and you won't be able to use Cocoon database (SQL) samples.
+          Then again, you probably use JBoss for EJB persistence anyway,
+          so this shouldn't bother you too much ;-)
+        </div>
+
+      
+<h2>Installing on Resin 2.x</h2>
+<p>
+          This section describes the deployment of the Cocoon sample WAR with Resin 2.x.
+          It assumes that you built Cocoon as described above. All steps have been tested
+          with a fresh Resin 2.0.0, 2.0.4, and 2.1.3 installations (the package is available from
+          <a class="external" href="http://www.caucho.com/download/">Resin's download page</a>)
+        </p>
+<p>After unpacking the Resin package you get the following directory structure</p>
+<pre class="code">
+[path]...
+[path]/resin-2.x/conf
+[path]/resin-2.x/lib
+[path]/resin-2.x/webapps
+[path]...</pre>
+<p>To get Cocoon running do the following:</p>
+<ul>
+          
+<li>Stop the server if it is running.</li>
+          
+<li>
+            
+<strong>For 2.0.3 version and older:</strong>
+            If yours Resin is older then 2.0.4, you have to install Xerces as
+            default XML parser for Resin
+            <ul>
+              
+<li>Remove the following files from the <span class="codefrag">resin-2.0.x/lib</span> directory:
+                <ul>
+                  
+<li>jaxp.jar</li>
+                  
+<li>dom.jar</li>
+                  
+<li>sax.jar</li>
+                
+</ul>
+              
+</li>
+              
+<li>Copy <span class="codefrag">xerces-XXX.jar</span> and <span class="codefrag">xml-apis.jar</span>
+                JAR file from <span class="codefrag">cocoon-2.1/lib/core/</span> to
+                the <span class="codefrag">resin-2.0.x/lib/</span> directory.</li>
+            
+</ul>
+          
+</li>
+          
+<li>
+            
+<strong>For 2.0.4 version and newer:</strong>
+            Edit <span class="codefrag">resin-2.x/conf/resin.conf</span>, change value of the
+            <span class="codefrag">servlet-classloader-hack</span> element to <span class="codefrag">true</span>
+          
+</li>
+          
+<li>Copy the <span class="codefrag">cocoon-2.1/build/cocoon/cocoon.war</span> WAR file
+            to <span class="codefrag">resin-2.x/webapps</span> directory
+          </li>
+          
+<li>Start Resin as usual</li>
+          
+<li>Open the Cocoon welcome page (<span class="codefrag">http://localhost:8080/cocoon/</span>)</li>
+          
+<li>Congratulations! (hopefully) you should see the Cocoon welcome page.</li>
+        
+</ul>
+<div class="note"> If you want to place Cocoon webapp in a directory different than
+          <span class="codefrag">resin-2.x/webapps</span>, you need to edit
+          <span class="codefrag">resin-2.x/conf/resin.conf</span> file and add a line somewhere
+          in <span class="codefrag">&lt;host&gt;</span> tag:
+          <span class="codefrag">&lt;web-app id='/cocoon' app-dir='/path/to/webapp/cocoon.war'/&gt;</span>
+        
+</div>
+
+      
+<h2>Installing on HP-AS 8.X</h2>
+<p>HP-AS is J2EE application server available from the Hewlett-Packard website.
+          <a class="external" href="http://www.hpmiddleware.com/download">Download and install HP-AS 8.X</a>
+        
+</p>
+<div class="note">Cocoon cannot be deployed as a .war file in HP-AS. Use the
+          following steps to deploy cocoon.war:
+        </div>
+<ol>
+          
+<li>Extract the <span class="codefrag">cocoon.war</span> file to some directory, using <span class="codefrag">WinZIP</span>
+           or a similar utility to extract the files.</li>
+          
+<li>To run HP-AS, go to
+            <strong>
+              <span class="codefrag">( Start | Programs | HP Middleware | HP Application Server | System Console).</span>
+            </strong>
+            
+<br>
+            The HP-AS Console appears with a Log browser. As the HP-AS kernel
+            starts and initializes, messages will appear in the status bar of the
+            console. Wait for the message 'Kernel started' to appear in the Log
+            browser. The following message should display:<br>
+            
+<br>
+            
+<span class="codefrag">[10/16/01 16:03:50][localhost_][S]:Kernel "kernel" started.</span>
+            
+<br>
+            
+<br>
+          
+</li>
+          
+<li>To verify that an instance of HP-AS is running,
+            open a web browser and go to <span class="codefrag">http://localhost:9090/helloservlet/hello</span>
+            
+<br>
+            An HTML page should appear containing the following message:
+            <br>
+            
+<br>
+            
+<span class="codefrag">Congratulations!</span>
+            
+<br>
+            
+<span class="codefrag">Congratulations from the HelloWorldServlet</span>
+            
+<br>
+            
+<span class="codefrag">It appears you have the server running</span>
+            
+<br>
+            
+<span class="codefrag">My servlet path is /hello</span>
+            
+<br>
+            
+<br>
+            
+<strong>
+              <span class="codefrag">This test is valid only if you've performed a full install of HP-AS</span>
+            </strong>
+            
+<br>
+            
+<br>
+          
+</li>
+          
+<li>In the HP-AS console, select <strong>View | Deployment Window</strong>.
+            In the <strong>Available Files</strong> pane on the right,
+            browse to the the directory you extracted the <span class="codefrag">cocoon.war</span> file to.
+            <br>
+            Expand this directory, and then drag and drop the
+            <span class="codefrag">cocoon</span> sub-directory node to the <strong>kernel.j2ee-partition</strong> icon
+            in the left pane.
+          </li>
+          
+<li>When prompted, answer <strong>Yes</strong> to the deployment question.<br>
+            This should create an appropriate entry in the HP-AS j2ee partition configuration file.<br>
+            
+<strong>
+              <span class="codefrag">In the current version of the console, there is no
+                indication that the operation succeeded. If you see a parser
+                error in the Log browser, ignore it.
+              </span>
+            </strong>
+          
+</li>
+          
+<li>To test the deployment, open a web browser and go to the following URL:<br>
+            
+<br>
+            
+<span class="codefrag">http://localhost:9090/cocoon/welcome</span>
+            
+<br>
+            
+<br>
+            Congratulations! (hopefully) you should see the Cocoon welcome page.
+            (this request may take some time).
+            <br>
+          
+</li>
+        
+</ol>
+
+      
+<h2>Installing on JRun 3.1</h2>
+<p>
+          This section describes the deployment of the Cocoon sample WAR with JRun 3.1,
+          on its default server. It assumes that you built Cocoon as described above. All
+          steps have been tested under Win2000.
+        </p>
+<p>To get Cocoon running do the following:</p>
+<ul>
+          
+<li>Stop the default and admin servers if they are running.</li>
+          
+<li>Remove <span class="codefrag">jaxp.jar</span> and <span class="codefrag">parser.jar</span>
+            files (Crimson XML parser) from the <span class="codefrag">jrun/lib/ext/</span> directory.
+          </li>
+          
+<li>Install Xerces as default XML parser for JRun by copying
+            <span class="codefrag">xerces-XXX.jar</span> and <span class="codefrag">xml-apis.jar</span> JAR
+            files from the <span class="codefrag">cocoon-2.1/lib/core/</span> to <span class="codefrag">jrun/lib/ext/</span>
+            directory.
+          </li>
+          
+<li>Update Rhino shipped with JRun with newer version from the Cocoon by
+            overwriting <span class="codefrag">jrun/lib/rhino.jar</span> JAR file
+            with the <span class="codefrag">cocoon-2.1/lib/optional/rhino-1.5r3.jar</span> file.
+          </li>
+          
+<li>Start JRun admin server.</li>
+          
+<li>Start JRun default server.</li>
+          
+<li>Open JRun admin page:
+            <span class="codefrag">http://localhost:8000/</span>
+          
+</li>
+          
+<li>Deploy cocoon.war webapp using console. Use same values for
+            application name and URI prefix (e.g., application name "cocoon",
+            URI "/cocoon").</li>
+          
+<li>Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:8100/cocoon/</span>
+          
+</li>
+          
+<li>Congratulations! (hopefully) you should see the Cocoon welcome page.</li>
+        
+</ul>
+<div class="note">Instead of deploying WAR file using console, same could be done by copying
+          <span class="codefrag">cocoon-2.1/build/cocoon/webapp</span> under <span class="codefrag">jrun/servers/default/</span>
+          directory and adding following lines to the <span class="codefrag">jrun/servers/default/local.properties</span>:
+        </div>
+<pre class="code">
+cocoon.rootdir=/absolute/path/to/jrun/servers/default/cocoon
+cocoon.class={webapp.service-class}
+webapp.mapping./cocoon=cocoon
+        </pre>
+
+      
+<h2>Installing on iPlanet Web Server 4.x and other engines without context management</h2>
+<p>
+          iPlanet Web Server 4.x provides the servlet 2.2 API (<span class="codefrag">javax.servlet.*</span> classes),
+          but the servlet engine doesn't handle servlet contexts. This means there is no classloader
+          built with the contents of <span class="codefrag">WEB-INF/classes</span> and <span class="codefrag">WEB-INF/lib</span> and that
+          resolution of context resources (using <span class="codefrag">ServletContext.getResource()</span>) doesn't give
+          the expected results.
+        </p>
+<p>
+          To be able to run on such non-compliant engines, Cocoon provides a bootstrap servlet in
+          <span class="codefrag">org.apache.cocoon.BootstrapServlet</span>that handles all the servlet context related
+          behaviours needed for proper functioning.
+        </p>
+<p>
+          To use this bootstrap servlet, configure your servlet engine as follows (how to do it depends
+          on the actual engine - see below for iPlanet) :
+        </p>
+<ul>
+          
+<li>add cocoon.jar (and only this one) in the engine's classpath,</li>
+          
+<li>declare the <span class="codefrag">org.apache.cocoon.servlet.BootstrapServlet</span> servlet,</li>
+          
+<li>add a "<span class="codefrag">context-directory</span>" parameter, whose value is the absolute path to Cocoon's
+              context (e.g. "<span class="codefrag">/path/webapp/cocoon</span>"),</li>
+          
+<li>add any other cocoon parameters you want to this servlet (see <span class="codefrag">web.xml</span> for a
+              description of available parameters),</li>
+          
+<li>configure a path translation from "/" to the servlet.</li>
+        
+</ul>
+<p>For iPlanet Web Server 4.x, this translates to :</p>
+<ul>
+          
+<li>connect to the administration server of your web server,</li>
+          
+<li>in the "Servlet" tabs, select "Configure servlet attributes", and enter the following :
+            <ul>
+              
+<li>Servlet Name : <span class="codefrag">cocoon</span>
+</li>
+              
+<li>Servlet Code (class name) : <span class="codefrag">org.apache.cocoon.servlet.BootstrapServlet</span>
+</li>
+              
+<li>Servlet Classpath : <span class="codefrag">/path/webapp/cocoon/WEB-INF/lib/cocoon.jar</span>
+</li>
+              
+<li>Servlet Args : <span class="codefrag">context-directory=/path/webapp/cocoon</span>
+                (and any other Cocoon parameters you want)</li>
+            
+</ul>
+          
+</li>
+          
+<li>select "Configure Servlet Virtual Path Translation" and enter the following :
+            <ul>
+              
+<li>Virtual Path : <span class="codefrag">@/.*</span>
+</li>
+              
+<li>Servlet Name : <span class="codefrag">cocoon</span>
+</li>
+            
+</ul>
+          
+</li>
+          
+<li>save and apply your changes, and enjoy the latest Cocoon on an old-fashioned servlet engine!</li>
+        
+</ul>
+
+      
+<h2>Installing on WebSphere 4.0</h2>
+<p>
+          This section describes the deployment of the Cocoon sample WAR with WebSphere 4.0,
+          on its default server. It assumes that you built Cocoon as described above. All
+          steps have been tested under Win2000 and WebSphere AEs 4.0.1 a0136.02.
+        </p>
+<p>To get Cocoon running do the following:</p>
+<ul>
+          
+<li>Start the server using <span class="codefrag">startServer</span> startup script.</li>
+          
+<li>Open admin page:
+            <span class="codefrag">http://localhost:9090/admin/</span>
+          
+</li>
+          
+<li>Deploy cocoon.war webapp using console.</li>
+          
+<li>Save server configuration file.</li>
+          
+<li>Restart the server using <span class="codefrag">stopServer</span> and 
+            <span class="codefrag">startServer</span> scripts.</li>
+          
+<li>Open the Cocoon welcome page:
+            <span class="codefrag">http://localhost:9080/cocoon/</span>
+          
+</li>
+          
+<li>Congratulations! (hopefully) you should see the Cocoon welcome page.</li>
+        
+</ul>
+<div class="note">WebSphere power users might deploy Cocoon by exploding cocoon.war into
+          <span class="codefrag">installedApps</span> directory and editing
+          <span class="codefrag">config/server-cfg.xml</span> file.
+        </div>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/meta.xml
new file mode 100644
index 0000000..ceb7a6a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-installing/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>installing/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/content_en.html
new file mode 100644
index 0000000..6e0d85e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/content_en.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Internal Pipeline Snippet</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Diana Shannon" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Overview</h1>
+
+<p>
+This Snippet shows how to create and use an internal pipeline in the sitemap. An internal pipeline processes a request from another pipeline in a sitemap. It then returns a pipeline fragment to the requesting pipeline for additional processing. The pipeline fragment produced by an internal pipeline cannot be accessed externally, for example, from an explicit browser request. An internal pipeline is distinguished from other pipelines by the value of its internal-only attribute which is set to true.
+</p>
+  
+
+  
+<h1>Version</h1>
+
+<p>
+At the time of this writing, this Snippet was tested against the current release version, 2.0.3, and head version, 2.1, of Cocoon.
+</p>
+  
+
+  
+<h1>Example</h1>
+    
+<pre class="code">
+
+&lt;map:pipeline internal-only="true"&gt;
+
+  &lt;map:match pattern="salad"&gt;
+    &lt;!-- do something --&gt;
+  &lt;/map:match&gt;
+
+  &lt;map:match pattern="soup"&gt;
+    &lt;!-- do something else --&gt;
+  &lt;/map:match&gt;
+
+&lt;/map:pipeline&gt;
+
+
+&lt;map:pipeline&gt;
+   &lt;map:match pattern="meal"&gt;
+      &lt;map:aggregate element="lunch"&gt;
+         &lt;map:part src="cocoon:/salad"/&gt;
+         &lt;map:part src="cocoon:/soup"/&gt;
+      &lt;/map:aggregate&gt;
+     &lt;map:transform src="stylesheets/lunch2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+&lt;/map:pipeline&gt;
+
+    </pre>
+
+  
+  
+  
+<h1>Discussion</h1>
+
+<p>
+In the above snippet example, you'll find two pipelines. The first is an internal pipeline which provides XML content to the second pipeline upon request. The second pipeline makes requests of the first internal pipeline through the <span class="codefrag">cocoon:/ protocol</span>. For example, when a request such <span class="codefrag">http://localhost:8080/meal</span> is received, the second pipeline, whose <span class="codefrag">map:match</span> element contains the value "meal," is matched. This pipeline begins processing by making two internal requests of the internal pipeline: one for <span class="codefrag">cocoon:/salad</span> and another for <span class="codefrag">cocoon:/soup</span>. It then aggregates the fragments returned by the internal pipeline within a lunch element. It continues processing by transforming and serializing the result. 
+</p>
+
+
+
+  
+<h1>Tips</h1>
+
+<p>
+You may need to check the pipeline fragments returned by your internal pipelines by calling them externally, for example, in your browser. If so, change the <span class="codefrag">internal-only</span> attribute of the pipeline to false until your testing is complete. In the above snippet, you could evaluate the pipeline fragment for soup with the following request: <span class="codefrag">http://localhost:8080/soup</span>. Once your testing is complete, make sure to change the value of the <span class="codefrag">internal-only</span> attribute back to true.
+</p>
+
+
+  
+<h1>Comments</h1>
+
+<p>
+Care to comment on this Snippet? Got another tip? Help keep this Snippet relevant by passing along any useful feedback to the author, <a href="mailto:shannon.at.apache.org">Diana Shannon.</a>
+
+</p>
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/meta.xml
new file mode 100644
index 0000000..f81703e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-internal-pipelines/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>snippet/snippet-internal-pipeline.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/content_en.html
new file mode 100644
index 0000000..375dfe3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/content_en.html
@@ -0,0 +1,563 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Introducing Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stefano Mazzocchi" name="DC.Creator">
+</head>
+<body>
+
+    
+<h1>The XML Hype</h1>
+
+
+<p>
+Everybody talks about XML. XML here, XML there. All application servers
+support XML, everybody wants to do B2B using XML, web services using
+XML, even databases using XML.
+</p>
+
+
+<p>
+Should you care about it? Given the amount of hype, you can't afford to
+go around ignoring XML, for that would be like ignoring the World Wide
+Web 10 years ago: a clear mistake. But why is this so for XML? What is
+this "magic" that XML seems to have in solving your problems? Isn't this
+another hype to change once again the IT infrastructure that you spent
+so much time implementing and fixing in the last few years? Isn't
+another way to spill money out of your pockets?
+</p>
+
+
+<p>
+If you ever asked yourself one of the above questions, this paper is for
+you. You won't find singing-and-dancing marketing hype, you won't find
+boring and useless feature lists, you won't find the usual acronym
+bombing or those good looking vaporware schemas that connect your
+databases to your coffee machines via CORBA or stuff like that.
+</p>
+
+
+<p>
+This document will explain you what the Cocoon project is about and what we are
+doing to solve the problems that we encountered in our web engineering
+experiences, but from an executive perspective, yes, because we all had
+the problems of managing a web site, dealing with our colleagues, rushing
+to the graphical guru to have the little GIF with the new title, or
+calling the web administrator at night because the database is returning
+errors without reasons.
+</p>
+
+
+<p>
+It was frustrating to see the best and most clever information
+technology ever invented--the Web--ruined by the lack of engineering
+practices, tortured by those "let's-reinvent-the-wheel-once-again"
+craftsmen who were great at doing their jobs as individuals but
+could not scale within teams, imposing a growth saturation to their projects.
+</p>
+
+
+<p>
+There had to be a better way of doing things.
+</p>
+
+    
+
+
+    
+<h1>Personal Experiences</h1>
+
+
+<p>
+In 1998, Stefano Mazzocchi volunteered to create the documentation infrastructure for
+the java.apache.org project, which is composed of a bunch of different
+codebases, maintained by a bunch of different people, with different
+skills, different geographical locations and different degree of will
+and time to dedicate to the documentation effort.
+</p>
+
+
+<p>
+But pretty soon he realized that no matter how great and well designed the
+system was, HTML was a problem: it was *not* designed for those kinds of
+things. By looking at the main page (<a class="external" href="http://java.apache.org/">http://java.apache.org/</a>) from the
+browser, you can clearly identify the areas of the screen: sidebar,
+topbar, news, status. But if you viewed the underlying HTML, boom: a nightmare of
+table tags and nesting and small little tricks to make the HTML appear
+the same on every browser.
+</p>
+
+
+<p>
+So he looked around for alternative technologies, but *all* of them were
+trying to add more complexity at the GUI level (Microsoft Frontpage,
+Macromedia Dreamweaver, Adobe GoLive, etc...) hoping to "hide" the
+design problems of HTML under a thick layer of WYSIWYG looks.
+</p>
+
+
+<p>
+What you see is what you get.
+</p>
+
+
+<p>
+But what you see is all you've got.
+</p>
+
+
+<p>
+How can you tell your web server to extract the information contained within the
+sidebar? How can you tell it to find the news articles within a complex HTML page?
+</p>
+
+
+<p>
+It's certainly easy for a human reader: just look at the page and you should have
+no problem distinguishing between a sidebar, a banner, a news and a stock
+quote. Why is it so hard for a machine?
+</p>
+
+    
+
+    
+<h1>The HTML Model</h1>
+
+
+<p>
+HTML is a language that tells your browser how to "draw" things on its
+window. An image here, a letter there, a color down here. Nothing more.
+The browser doesn't have the "higher level" notion of "sidebar": it
+lacks the ability to perform "semantic analysis" of the HTML content.
+</p>
+
+
+<p>
+Semantic analysis? Yeah, it's the kind of thing the human brain is
+simply great at doing, while computer programs simply fail at big time.
+</p>
+
+
+<p>
+So, with HTML, we went a step up and created a highly visual and
+appealing web of HTML content, but we went two steps back by removing
+all the higher level semantic information from the content itself.
+</p>
+
+
+<p>
+Ok, let's make an example...  most of you have seen an HTML
+page... if not, here is an example:
+</p>
+
+
+<pre class="code">
+ &lt;html&gt;
+  &lt;body&gt;
+   &lt;p&gt;Hi, I'm an HTML page&lt;/p&gt;
+   &lt;p align="center"&gt;Written by Stefano&lt;/p&gt;
+  &lt;/body&gt;
+ &lt;/html&gt;
+</pre>
+
+
+<p>
+which says to the browser:
+</p>
+
+
+<ul>
+ 
+<li>I'm a HTML page</li>
+ 
+<li>I have a body</li>
+ 
+<li>I have a paragraph</li>
+ 
+<li>I contain the sentence "Hi, I'm an HTML page."</li>
+ 
+<li>I contain the sentence "Written by Stefano"</li>
+
+</ul>
+
+
+<p>
+Suppose you are a Chinese guy that doesn't understand our alphabet, try
+to answer the following question:
+</p>
+
+
+<p>
+Who wrote the page?
+</p>
+
+
+<p>
+You can't perform semantic analysis, you are as blind as a web browser.
+The only thing you can do is draw it on the screen since this is what
+you were programmed to do. In other words, your semantic capacity is
+fixed to the drawing capabilities and a few other things (like linking),
+thus limited.
+</p>
+
+    
+
+    
+<h1>Semantic Markup</h1>
+
+
+<p>
+Suppose you receive this page:
+</p>
+
+
+<pre class="code">
+ &lt;page&gt;
+  &lt;author&gt;sflkjoiuer&lt;/author&gt;
+  &lt;content&gt;
+   &lt;para&gt;sofikdjflksj&lt;/para&gt;
+  &lt;/content&gt;
+ &lt;/page&gt;
+</pre>
+
+
+<p>
+Can you now tell me who wrote the page? Easy, you say, "sflkjoiuer" did. Good, but later
+you receive:
+</p>
+
+
+<pre class="code">
+ &lt;dlkj&gt;
+  &lt;ruijfl&gt;sofikdjflksj&lt;/ruijfl&gt;
+  &lt;wijlkjf&gt;
+    &lt;oamkfkj&gt;sflkjoiuer&lt;/oamkfkj&gt;
+  &lt;/wijlkjf&gt;
+ &lt;/dlkj&gt;
+</pre>
+
+
+<p>
+Now, who wrote the page? You could guess by comparing the structure,
+but how do you know the two structures reflect the same semantic
+information?
+</p>
+
+
+<p>
+The above two pages are both XML documents.
+</p>
+
+
+<p>
+Are they going to help you? Are they doing to simplify your work? Are
+they going to simplify your problems?
+</p>
+
+
+<p>
+At this point, clearly not, rather the opposite.
+</p>
+
+
+<p>
+So, you could be wondering, why did we spend so much effort to 
+write an XML publishing framework? This document was written exactly
+to clear your doubts on this, so let's keep going.
+</p>
+
+
+    
+
+    
+<h1>The XML Language</h1>
+
+
+<p>
+XML is most of the times referred to as the "eXtensible Markup Language"
+specification. A fairly small yet complex specification that indicates
+how to write languages. It's a syntax. To tell you the truth, nothing fancy at all. So
+</p>
+
+
+<pre class="code">
+ &lt;hello&gt;&lt;/hello&gt;
+</pre>
+
+
+<p>
+is correct, while
+</p>
+
+
+<pre class="code">
+ &lt;hello&gt;&lt;/hi&gt;
+</pre>
+
+
+<p>
+is not, but
+</p>
+
+
+<pre class="code">
+ &lt;hello&gt;&lt;hi/&gt;&lt;/hello&gt;
+</pre>
+
+
+<p>
+is correct. That's more than this, but I'll skip the technical details here.
+</p>
+
+
+<p>
+XML is the ASCII for the new millenium, it's a step forward from ASCII
+or UNICODE (the international extension to ASCII that includes all
+characters from all modern languages). It defines a "lingua franca" for
+textual languages.
+</p>
+
+
+<p>
+Ok, great, so now instead of having one uniform language with visual
+semantics (HTML) we have a babel of languages each with its own
+semantics. How this can possibly help you?
+</p>
+
+    
+
+    
+<h1>XML Transformations</h1>
+
+
+<p>
+This was the point where Stefano was more or less two years ago for
+java.apache.org: I could use XML and define my own semantics with
+&lt;sidebar&gt;, &lt;news&gt;, &lt;status&gt; 
+and all that and I'm sure people would have
+found those XML documents much easier to write (since the XML syntax is
+very similar to the HTML one and very user friendly)... but I would have
+moved from "all browsers" to "no browser".
+</p>
+
+
+<p>
+And having documentation that nobody can browse is totally useless.
+</p>
+
+
+<p>
+The turning point was the creation of the XSL specification which
+included a way to "transform" an XML page into something else. (It's
+more complex than this, but, again, I'll skip the technical details).
+</p>
+
+
+<p>
+So now you have:
+</p>
+
+
+<pre class="code">
+ XML page ---(transformation)--&gt; HTML page
+                    ^
+                    |
+          transformation rules
+</pre>
+
+
+<p>
+that allows you to write your pages in XML, create your "graphics" as
+transformation rules and generate HTML pages on the fly directly from your
+web server.
+</p>
+
+
+<p>
+Apache Cocoon 1.0 did exactly this.
+</p>
+
+    
+
+    
+<h1>The Model Evolves</h1>
+
+
+<p>
+If XML is a lingua franca, it means that XML software can work on almost
+anything without caring about what it is. So, if a cell phone requests
+the page, Cocoon just has to change transformation rules and send the
+WAP page to the phone. Or, if you want a nice PDF to printout your
+monthly report, you change the transformation rules and Cocoon creates
+the PDF for you, or the VRML, or the VoiceML, or your own proprietary
+B2B markup.
+</p>
+
+
+<p>
+Anything without changing the basic architecture that is simply based on
+the simple "angle bracket" XML syntax.
+</p>
+
+    
+
+    
+<h1>Separation of Concerns (SoC)</h1>
+
+
+<p>
+Cocoon was not the first product to perform server side XML
+transformations, nor will be the last one (in a few years, these
+solutions will be the rule rather than the exception). So, what is the
+"plus" that the Cocoon project adds?
+</p>
+
+
+<p>
+We believe the single most important Cocoon innovation is SoC-based design.
+</p>
+
+
+<p>
+SoC is something that you've always been aware of: not everybody is
+equal, not everybody performs the same job with the same ability.
+</p>
+
+
+<p>
+It can be observed that separating people with common skills in
+different working groups increases productivity and reduces management
+costs, but only if the groups do not overlap and have clear "contracts"
+that define their operability and their concerns.
+</p>
+
+
+<p>
+For a web publishing system, the Cocoon project uses what we call the
+<em>pyramid of contracts</em> which outlines four major concern areas and five
+contracts between them. Here is the picture:
+</p>
+
+
+<div align="center">
+<img class="figure" alt="The Cocoon Pyramid Model of Contracts" src="images/pyramid-model.gif" height="159" width="313"></div>
+
+
+<p>
+Cocoon is <em>engineered</em> to provide you a way to isolate these four
+concern areas using just those 5 contracts, removing the contract
+between style and logic that has been bugging web site development since
+the beginning of the Web.
+</p>
+
+
+<p>
+Why? because programmers and graphic people have very different skills
+and work habits... so, instead of creating GUIs to hide the things that
+can be harmful (like graphic to programmers or logic to designers),
+Cocoon allows you to separate the things into different files, allowing
+you to "seal" your working groups into separate virtual rooms connected
+with the other rooms only by those "pipes" (the contracts), that you
+give them from the management area.
+</p>
+
+
+<p>
+Let's have an example:
+</p>
+
+
+<pre class="code">
+ &lt;page&gt;
+  &lt;content&gt;
+   &lt;para&gt;Today is &lt;dynamic:today/&gt;&lt;/para&gt;
+  &lt;/content&gt;
+ &lt;/page&gt;
+</pre>
+
+      
+<p>
+	is written by the content writers and you give them the
+	"contract" that states that the tag
+	&lt;dynamic:today/&gt; prints out the time of the day
+	when included in the page. Content writers don't care (nor
+	should) about what language has been used for that, nor they
+	can mess up with the programming logic that generates the
+	content since it's stored in another part of the system they
+	don't have access to.
+      </p>
+
+
+<p>
+So &lt;dynamic:today/&gt; is the "logic - content" contract.
+</p>
+
+
+<p>
+At the same time, the structure of the page is given as a contract to
+the graphic designers who have to come up with the transformation rules
+that transform this structure in a language that the browser can
+understand (HTML, for example).
+</p>
+
+
+<p>
+So, the page structure is the "content - style" contract.
+</p>
+
+
+<p>
+As long as these contracts don't change, the three areas can work in a
+completely parallel way without overwhelming the human resources used to
+manage them: costs decrease because time to market is reduced and
+maintenance costs is decreased because errors do not propagate out of
+the concern areas.
+</p>
+
+
+<p>
+For example, you can tell your designers to come up with a "Xmas look"
+for your web site, without even telling the other people: just switch to
+the Xmas transformation rules on Xmas morning and you're done.... just
+imagine how painful it would be to do this on your web site today.
+</p>
+
+
+<p>
+With the Cocoon architecture all this is a couple of line changes away.
+</p>
+
+    
+
+    
+<h1>Here we go</h1>
+
+
+<p>
+If you've reached this far in my text, you should be able to grasp the
+value of the Cocoon Project as well as distinguish most of the marketing
+hype that surrounds XML and friends.
+</p>
+
+
+<p>
+Just like you shouldn't care if somebody offers you software that is
+"ASCII compliant" or "ASCII based", you shouldn't care about "XML
+compliant" or "XML based": it doesn't mean anything.
+</p>
+
+
+<p>
+Cocoon uses XML as a core piece of its framework, but improves the model
+to give you the tools you need and is designed to be flexible enough to
+follow your current needs as well as paradigm shifts that may happen in the
+future.
+</p>
+
+    
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/meta.xml
new file mode 100644
index 0000000..a8fff68
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-introduction/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>introduction.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/content_en.html
new file mode 100644
index 0000000..a2d5af1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/content_en.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon JARs</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="John Morrison" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Replace</h1>
+  
+<p>This is now an autogenerated document.  If you see this message, then
+  something is wrong with the build!</p>
+ 
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/meta.xml
new file mode 100644
index 0000000..c839590
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jars/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>installing/jars.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/content_en.html
new file mode 100644
index 0000000..160ff94
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/content_en.html
@@ -0,0 +1,318 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Description of the jx generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Cocoon Community" name="DC.Creator">
+</head>
+<body>
+    
+<h1>JX Generator</h1>
+      
+<p>
+        (<em>JX</em> for <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache <em>JX</em>Path</a>
+        and <a class="external" href="http://jakarta.apache.org/commons/jexl">Apache <em>J</em>e<em>x</em>l</a>).
+      </p>
+      
+<p>
+        Uses the namespace <span class="codefrag">http://apache.org/cocoon/templates/jx/1.0</span>.
+      </p>
+      
+<p>
+        Provides a generic page template with embedded JSTL and XPath
+        expression substitution to access data sent by Cocoon Flowscripts.
+      </p>
+      
+<p>
+        The embedded expression language allows a page author to access an
+        object using a simplified syntax such as
+      </p>
+
+<pre class="code">
+   &lt;site signOn="${accountForm.signOn}"&gt;
+</pre>      
+      
+<p>
+        Embedded JSTL expressions are contained in <span class="codefrag">${}</span>.
+      </p>
+      
+<p>
+        Embedded XPath expressions are contained in <span class="codefrag">#{}</span>.
+      </p>
+      
+<p>
+        Note that since this generator uses
+        <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache JXPath</a>
+        and <a class="external" href="http://jakarta.apache.org/commons/jexl">Apache Jexl</a>, the
+        referenced objects may be Java Beans, DOM, JDOM, or JavaScript objects from
+        a Flowscript. In addition the following implicit objects are available as
+        both XPath and JSTL variables:
+      </p>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">request</span> (<span class="codefrag">org.apache.cocoon.environment.Request</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">session</span> (<span class="codefrag">org.apache.cocoon.environment.Session</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon session associated with the current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">context</span> (<span class="codefrag">org.apache.cocoon.environment.Context</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon context associated with the current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">parameters</span> (<span class="codefrag">org.apache.avalon.framework.parameters.Parameters</span>)</td>
+          <td colspan="1" rowspan="1">A map of parameters passed to the generator in the pipeline</td>
+        
+</tr>
+      
+</table>
+      
+<p>
+  The current Web Continuation from the Flowscript
+  is also available as a variable named <span class="codefrag">continuation</span>. You would
+  typically access its <span class="codefrag">id</span>:
+      </p>
+
+<pre class="code">      
+     &lt;form action="${continuation.id}"&gt;
+</pre>      
+
+  
+<p>You can also reach previous continuations by using the
+  <span class="codefrag">getContinuation()</span> function:</p>
+ 
+
+<pre class="code">      
+      &lt;form action="${continuation.getContinuation(1).id}" &gt;
+</pre>      
+ 
+<p>The <span class="codefrag">template</span> tag defines a new template:</p>
+
+<pre class="code">      
+     &lt;template&gt;
+        body
+     &lt;/template&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">import</span> tag allows you to include another template
+  within the current template. The content of the imported template is
+  compiled and will be executed in place of the <span class="codefrag">import</span> tag:</p>
+
+<pre class="code">
+    &lt;import uri="URI" [context="Expression"]/&gt;
+</pre>
+ 
+<p>The Cocoon source resolver is used to resolve <span class="codefrag">uri</span>.
+ If <span class="codefrag">context</span> is present, then its value is used as the context
+ for evaluating the imported template, otherwise the current context is
+ used.</p>
+ 
+<p>The <span class="codefrag">set</span> tag creates a local alias of an object. The
+ <span class="codefrag">var</span> attribute specifies the name of a variable to assign the
+ object to. The <span class="codefrag">value</span> attribute specifies the object (defaults
+ to <span class="codefrag">body</span> if not present):</p>
+
+
+<pre class="code">      
+     &lt;set var="Name" [value="Value"]&gt;
+         [body]
+     &lt;/set&gt;
+</pre>      
+ 
+<p>If used within a <span class="codefrag">macro</span> definition (see below)
+ variables created by <span class="codefrag">set</span> are only visible within the body of
+ the <span class="codefrag">macro</span>.</p>
+ 
+<p>The <span class="codefrag">if</span> tag allows the conditional execution of its body
+ according to value of a <span class="codefrag">test</span> attribute:</p>
+
+
+<pre class="code">      
+    &lt;if test="Expression"&gt;
+        body
+    &lt;/if&gt;
+</pre>      
+ 
+<p>The <span class="codefrag">choose</span> tag performs conditional block execution by the
+  embedded <span class="codefrag">when</span> sub tags. It renders the body of the first
+  <span class="codefrag">when</span> tag whose <span class="codefrag">test</span> condition evaluates to true.
+  If none of the <span class="codefrag">test</span> conditions of nested <span class="codefrag">when</span> tags
+  evaluate to <span class="codefrag">true</span>, then the body of an <span class="codefrag">otherwise</span>
+  tag is evaluated, if present:</p>
+
+<pre class="code">      
+   &lt;choose&gt;
+     &lt;when test="Expression"&gt;
+        body
+     &lt;/when&gt;
+     &lt;otherwise&gt;
+        body
+     &lt;/otherwise&gt;
+   &lt;/choose&gt;
+</pre>      
+  
+<p>The <span class="codefrag">out</span> tag evaluates an expression and outputs
+  the result of the evaluation:</p>
+
+<pre class="code">      
+  &lt;out value="Expression"/&gt;
+</pre>      
+  
+<p>The <span class="codefrag">forEach</span> tag allows you to iterate over a collection
+  of objects:</p>
+
+<pre class="code">      
+    &lt;forEach [var="Name"] [items="Expression"]
+                 [begin="Number"] [end="Number"] [step="Number"]&gt;
+      body
+   &lt;/forEach&gt;
+</pre>      
+  
+<p>The <span class="codefrag">items</span> attribute specifies the list of items to iterate
+  over. The <span class="codefrag">var</span> attribute specifies the name of a variable to
+  hold the current item. The <span class="codefrag">begin</span> attribute specifies the
+  element to start with (<span class="codefrag">0</span> = first item,
+  <span class="codefrag">1</span> = second item, ...).
+  If unspecified it defaults to <span class="codefrag">0</span>. The <span class="codefrag">end</span>
+  attribute specifies the item to end with (<span class="codefrag">0</span> = first item,
+  <span class="codefrag">1</span> = second item, ...). If unspecified it defaults to the last
+  item in the list. Every <span class="codefrag">step</span> items are
+  processed (defaults to <span class="codefrag">1</span> if <span class="codefrag">step</span> is absent).
+  Either <span class="codefrag">items</span> or both <span class="codefrag">begin</span> and <span class="codefrag">end</span>
+  must be present.</p>
+ 
+  
+<p>
+  The <span class="codefrag">formatNumber</span> tag is used to display numeric data, including
+  currencies and percentages, in a locale-specific manner. The
+  <span class="codefrag">formatNumber</span> action determines from the locale, for example,
+  whether to use a period or a comma for delimiting the integer and decimal
+  portions of a number. Here is its syntax:
+  </p>
+
+<pre class="code">      
+  &lt;formatNumber value="Expression"
+      [type="Type"] [pattern="Expression"]
+      [currencyCode="Expression"] [currencySymbol="Expression"]
+      [maxIntegerDigits="Expression"] [minIntegerDigits="Expression"]
+      [maxFractionDigits="Expression"] [minFractionDigits="Expression"]
+      [groupingUsed="Expression"]
+      [var="Name"] [locale="Expression"]&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">formatDate</span> tag provides facilities to format Date values:</p>
+
+<pre class="code">      
+  &lt;formatDate value="Expression" [dateStyle="Style"]
+    [timeStyle="Style"] [pattern="Expression"] [type="Type"] [var="Name"]
+    [locale="Expression"]&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">macro</span> tag allows you define a new custom tag.</p>
+ 
+
+<pre class="code">      
+  &lt;macro name="Name" [targetNamespace="Namespace"]&gt;
+    &lt;parameter name="Name" [optional="Boolean"] [default="Value"]/&gt;
+    body
+  &lt;/macro&gt;
+</pre>      
+ 
+ 
+<p>For example:</p>
+ 
+
+<pre class="code">      
+  &lt;c:macro name="d"&gt;
+    &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
+  &lt;/c:macro&gt;
+</pre>      
+ 
+  
+<p>The tag being defined in this example is <span class="codefrag">&lt;d&gt;</span> and it
+  can be used like any other tag:</p>
+ 
+
+<pre class="code">      
+    &lt;d/&gt;
+</pre>      
+ 
+  
+<p>However, when this tag is used it will be replaced with a row containing
+  a single empty data cell.</p>
+  
+<p> When such a tag is used, the attributes and content of the tag become
+  available as variables in the body of the <span class="codefrag">macro</span>'s definition,
+  for example:</p>
+ 
+
+<pre class="code">      
+  &lt;c:macro name="tablerows"&gt;
+    &lt;c:parameter name="list"/&gt;
+    &lt;c:parameter name="color"/&gt;
+    &lt;c:forEach var="item" items="${list}"&gt;
+      &lt;tr&gt;&lt;td bgcolor="${color}"&gt;${item}&lt;/td&gt;&lt;/tr&gt;
+    &lt;/c:forEach&gt;
+  &lt;/c:macro&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">parameter</span> tags in the macro definition define formal
+  parameters, which are replaced with the actual attribute values of the
+  tag when it is used. The content of the tag is also available as a special
+  variable <span class="codefrag">${content}</span>.</p>
+  
+<p>Assuming you had this code in your
+  flowscript:</p>
+  
+<pre class="code">var greatlakes = ["Superior", "Michigan", "Huron", "Erie", "Ontario"];</pre>
+ 
+<p>
+<span class="codefrag"> sendPage(uri, {greatlakes: greatlakes});</span>
+ 
+</p>
+ 
+<p>and a template like this:</p>
+ 
+
+<pre class="code">      
+     &lt;tablerows list="${greatlakes}" color="blue"/&gt;
+  &lt;/table&gt;
+</pre>      
+ 
+  
+<p>When the <span class="codefrag">tablerows</span> tag is used in this situation the
+  following output would be generated:
+  </p>
+
+<pre class="code">      
+  &lt;table&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Superior&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Michigan&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Huron&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Erie&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
+  &lt;/table&gt;
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/meta.xml
new file mode 100644
index 0000000..3f87b76
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/jx-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/content_en.html
new file mode 100644
index 0000000..1ec51f0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/content_en.html
@@ -0,0 +1,318 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Description of the JX transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Cocoon Community" name="DC.Creator">
+</head>
+<body>
+    
+<h1>JX Transformer</h1>
+      
+<p>
+        (<em>JX</em> for <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache <em>JX</em>Path</a>
+        and <a class="external" href="http://jakarta.apache.org/commons/jexl">Apache <em>J</em>e<em>x</em>l</a>).
+      </p>
+      
+<p>
+        Uses the namespace <span class="codefrag">http://apache.org/cocoon/templates/jx/1.0</span>.
+      </p>
+      
+<p>
+        Provides a generic page template with embedded JSTL and XPath
+        expression substitution to access data sent by Cocoon Flowscripts.
+      </p>
+      
+<p>
+        The embedded expression language allows a page author to access an
+        object using a simplified syntax such as
+      </p>
+
+<pre class="code">
+   &lt;site signOn="${accountForm.signOn}"&gt;
+</pre>      
+      
+<p>
+        Embedded JSTL expressions are contained in <span class="codefrag">${}</span>.
+      </p>
+      
+<p>
+        Embedded XPath expressions are contained in <span class="codefrag">#{}</span>.
+      </p>
+      
+<p>
+        Note that since this transformer uses
+        <a class="external" href="http://jakarta.apache.org/commons/jxpath">Apache JXPath</a>
+        and <a class="external" href="http://jakarta.apache.org/commons/jexl">Apache Jexl</a>, the
+        referenced objects may be Java Beans, DOM, JDOM, or JavaScript objects from
+        a Flowscript. In addition the following implicit objects are available as
+        both XPath and JSTL variables:
+      </p>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">request</span> (<span class="codefrag">org.apache.cocoon.environment.Request</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">session</span> (<span class="codefrag">org.apache.cocoon.environment.Session</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon session associated with the current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">context</span> (<span class="codefrag">org.apache.cocoon.environment.Context</span>)</td>
+          <td colspan="1" rowspan="1">The Cocoon context associated with the current request</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1"><span class="codefrag">parameters</span> (<span class="codefrag">org.apache.avalon.framework.parameters.Parameters</span>)</td>
+          <td colspan="1" rowspan="1">A map of parameters passed to the transformer in the pipeline</td>
+        
+</tr>
+      
+</table>
+      
+<p>
+  The current Web Continuation from the Flowscript
+  is also available as a variable named <span class="codefrag">continuation</span>. You would
+  typically access its <span class="codefrag">id</span>:
+      </p>
+
+<pre class="code">      
+     &lt;form action="${continuation.id}"&gt;
+</pre>      
+
+  
+<p>You can also reach previous continuations by using the
+  <span class="codefrag">getContinuation()</span> function:</p>
+ 
+
+<pre class="code">      
+      &lt;form action="${continuation.getContinuation(1).id}" &gt;
+</pre>      
+ 
+<p>The <span class="codefrag">template</span> tag defines a new template:</p>
+
+<pre class="code">      
+     &lt;template&gt;
+        body
+     &lt;/template&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">import</span> tag allows you to include another template
+  within the current template. The content of the imported template is
+  compiled and will be executed in place of the <span class="codefrag">import</span> tag:</p>
+
+<pre class="code">
+    &lt;import uri="URI" [context="Expression"]/&gt;
+</pre>
+ 
+<p>The Cocoon source resolver is used to resolve <span class="codefrag">uri</span>.
+ If <span class="codefrag">context</span> is present, then its value is used as the context
+ for evaluating the imported template, otherwise the current context is
+ used.</p>
+ 
+<p>The <span class="codefrag">set</span> tag creates a local alias of an object. The
+ <span class="codefrag">var</span> attribute specifies the name of a variable to assign the
+ object to. The <span class="codefrag">value</span> attribute specifies the object (defaults
+ to <span class="codefrag">body</span> if not present):</p>
+
+
+<pre class="code">      
+     &lt;set var="Name" [value="Value"]&gt;
+         [body]
+     &lt;/set&gt;
+</pre>      
+ 
+<p>If used within a <span class="codefrag">macro</span> definition (see below)
+ variables created by <span class="codefrag">set</span> are only visible within the body of
+ the <span class="codefrag">macro</span>.</p>
+ 
+<p>The <span class="codefrag">if</span> tag allows the conditional execution of its body
+ according to value of a <span class="codefrag">test</span> attribute:</p>
+
+
+<pre class="code">      
+    &lt;if test="Expression"&gt;
+        body
+    &lt;/if&gt;
+</pre>      
+ 
+<p>The <span class="codefrag">choose</span> tag performs conditional block execution by the
+  embedded <span class="codefrag">when</span> sub tags. It renders the body of the first
+  <span class="codefrag">when</span> tag whose <span class="codefrag">test</span> condition evaluates to true.
+  If none of the <span class="codefrag">test</span> conditions of nested <span class="codefrag">when</span> tags
+  evaluate to <span class="codefrag">true</span>, then the body of an <span class="codefrag">otherwise</span>
+  tag is evaluated, if present:</p>
+
+<pre class="code">      
+   &lt;choose&gt;
+     &lt;when test="Expression"&gt;
+        body
+     &lt;/when&gt;
+     &lt;otherwise&gt;
+        body
+     &lt;/otherwise&gt;
+   &lt;/choose&gt;
+</pre>      
+  
+<p>The <span class="codefrag">out</span> tag evaluates an expression and outputs
+  the result of the evaluation:</p>
+
+<pre class="code">      
+  &lt;out value="Expression"/&gt;
+</pre>      
+  
+<p>The <span class="codefrag">forEach</span> tag allows you to iterate over a collection
+  of objects:</p>
+
+<pre class="code">      
+    &lt;forEach [var="Name"] [items="Expression"]
+                 [begin="Number"] [end="Number"] [step="Number"]&gt;
+      body
+   &lt;/forEach&gt;
+</pre>      
+  
+<p>The <span class="codefrag">items</span> attribute specifies the list of items to iterate
+  over. The <span class="codefrag">var</span> attribute specifies the name of a variable to
+  hold the current item. The <span class="codefrag">begin</span> attribute specifies the
+  element to start with (<span class="codefrag">0</span> = first item,
+  <span class="codefrag">1</span> = second item, ...).
+  If unspecified it defaults to <span class="codefrag">0</span>. The <span class="codefrag">end</span>
+  attribute specifies the item to end with (<span class="codefrag">0</span> = first item,
+  <span class="codefrag">1</span> = second item, ...). If unspecified it defaults to the last
+  item in the list. Every <span class="codefrag">step</span> items are
+  processed (defaults to <span class="codefrag">1</span> if <span class="codefrag">step</span> is absent).
+  Either <span class="codefrag">items</span> or both <span class="codefrag">begin</span> and <span class="codefrag">end</span>
+  must be present.</p>
+ 
+  
+<p>
+  The <span class="codefrag">formatNumber</span> tag is used to display numeric data, including
+  currencies and percentages, in a locale-specific manner. The
+  <span class="codefrag">formatNumber</span> action determines from the locale, for example,
+  whether to use a period or a comma for delimiting the integer and decimal
+  portions of a number. Here is its syntax:
+  </p>
+
+<pre class="code">      
+  &lt;formatNumber value="Expression"
+      [type="Type"] [pattern="Expression"]
+      [currencyCode="Expression"] [currencySymbol="Expression"]
+      [maxIntegerDigits="Expression"] [minIntegerDigits="Expression"]
+      [maxFractionDigits="Expression"] [minFractionDigits="Expression"]
+      [groupingUsed="Expression"]
+      [var="Name"] [locale="Expression"]&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">formatDate</span> tag provides facilities to format Date values:</p>
+
+<pre class="code">      
+  &lt;formatDate value="Expression" [dateStyle="Style"]
+    [timeStyle="Style"] [pattern="Expression"] [type="Type"] [var="Name"]
+    [locale="Expression"]&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">macro</span> tag allows you define a new custom tag.</p>
+ 
+
+<pre class="code">      
+  &lt;macro name="Name" [targetNamespace="Namespace"]&gt;
+    &lt;parameter name="Name" [optional="Boolean"] [default="Value"]/&gt;
+    body
+  &lt;/macro&gt;
+</pre>      
+ 
+ 
+<p>For example:</p>
+ 
+
+<pre class="code">      
+  &lt;c:macro name="d"&gt;
+    &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
+  &lt;/c:macro&gt;
+</pre>      
+ 
+  
+<p>The tag being defined in this example is <span class="codefrag">&lt;d&gt;</span> and it
+  can be used like any other tag:</p>
+ 
+
+<pre class="code">      
+    &lt;d/&gt;
+</pre>      
+ 
+  
+<p>However, when this tag is used it will be replaced with a row containing
+  a single empty data cell.</p>
+  
+<p> When such a tag is used, the attributes and content of the tag become
+  available as variables in the body of the <span class="codefrag">macro</span>'s definition,
+  for example:</p>
+ 
+
+<pre class="code">      
+  &lt;c:macro name="tablerows"&gt;
+    &lt;c:parameter name="list"/&gt;
+    &lt;c:parameter name="color"/&gt;
+    &lt;c:forEach var="item" items="${list}"&gt;
+      &lt;tr&gt;&lt;td bgcolor="${color}"&gt;${item}&lt;/td&gt;&lt;/tr&gt;
+    &lt;/c:forEach&gt;
+  &lt;/c:macro&gt;
+</pre>      
+ 
+  
+<p>The <span class="codefrag">parameter</span> tags in the macro definition define formal
+  parameters, which are replaced with the actual attribute values of the
+  tag when it is used. The content of the tag is also available as a special
+  variable <span class="codefrag">${content}</span>.</p>
+  
+<p>Assuming you had this code in your
+  flowscript:</p>
+  
+<pre class="code">var greatlakes = ["Superior", "Michigan", "Huron", "Erie", "Ontario"];</pre>
+ 
+<p>
+<span class="codefrag"> sendPage(uri, {greatlakes: greatlakes});</span>
+ 
+</p>
+ 
+<p>and a template like this:</p>
+ 
+
+<pre class="code">      
+     &lt;tablerows list="${greatlakes}" color="blue"/&gt;
+  &lt;/table&gt;
+</pre>      
+ 
+  
+<p>When the <span class="codefrag">tablerows</span> tag is used in this situation the
+  following output would be generated:
+  </p>
+
+<pre class="code">      
+  &lt;table&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Superior&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Michigan&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Huron&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Erie&lt;/td&gt;&lt;/tr&gt;
+    &lt;tr&gt;&lt;td bgcolor="blue"&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
+  &lt;/table&gt;
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/meta.xml
new file mode 100644
index 0000000..14ceaf3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-jxtemplate-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/jx-template-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/content_en.html
new file mode 100644
index 0000000..958d171
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/content_en.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Link Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Torsten Knodt" name="DC.Creator">
+<meta content="This document describes the link serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Link Serializer</h1>
+      
+<p>The link serializer generates a list of links
+                   using <a class="external" href="http://www.w3.org/TR/xlink/">XLink</a>
+                   from the sax events.
+                   Most <a class="external" href="http://www.w3.org/MarkUp/">XHTML</a>
+                   attributes are also supported (href, src, longdesc,
+                   background). The mime-type of the output is 
+                   <span class="codefrag">application/x-cocoon-links</span>. This serializer is
+                   required by the link status generator and the command line
+                   mode to follow links.</p>
+       
+<ul>
+         
+<li>Name: links</li>
+         
+<li>Class: org.apache.cocoon.serialization.LinkSerializer</li>
+               
+<li>Cacheable: no</li>
+       
+</ul>
+    
+                
+<h1>Usage</h1>
+      
+<p>To use the link serializer for the command-line or the
+                    link status generator, you need the following entries in
+                    your sitemap:</p>
+
+<pre class="code">
+&lt;map:components&gt;
+  &lt;map:serializers&gt;
+    &lt;map:serializer logger="sitemap.serializer.links" name="links"
+                    src="org.apache.cocoon.serialization.LinkSerializer" /&gt;
+  &lt;/map:serializers&gt;
+&lt;/map:components&gt;
+
+&lt;map:views&gt;
+  &lt;map:view from-position="last" name="links"&gt;
+    &lt;map:serialize type="links" /&gt;
+  &lt;/map:view&gt;
+&lt;/map:views&gt;
+</pre>
+                
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/meta.xml
new file mode 100644
index 0000000..a4b3e3e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-link-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/link-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/content_en.html
new file mode 100644
index 0000000..262a347
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/content_en.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>LinkStatus Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the LinkStatus generator." name="DC.Description">
+</head>
+<body>
+  
+<h1>LinkStatus Generator</h1>
+   
+<p>
+    The LinkStatus Generator emits a list of links that are reachable. 
+   </p>
+   
+<p>
+    The LinkStatusGenerator has serveral configuration options.
+   </p>
+   
+<dl>
+     
+<dt>include-name</dt>
+     
+<dd>RE pattern for including links
+       <br>
+       By default <span class="codefrag">include-name</span> is empty.
+     </dd>
+     
+<dt>exclude-name</dt>
+     
+<dd>RE pattern for excluding links.
+       <br>
+       By default <span class="codefrag">exclude-name</span> is defined as
+       <span class="codefrag">.*\.gif(\?.*)?$,
+         .*\.png(\?.*)?$,
+         .*\.jpe?g(\?.*)?$,
+         .*\.js(\?.*)?$,
+         .*\.css(\?.*)?$
+       </span>.
+     </dd>
+     
+<dt>link-content-type</dt>
+     
+<dd>expected MIME type of xml document requested on view
+       <em>link-query-view</em>
+       
+<br>
+       By default <span class="codefrag">link-content-type</span> is set to 
+       <span class="codefrag">application/x-cocoon-links</span>.
+     </dd>
+     
+<dt>link-view-query</dt>
+     
+<dd>A query-string appended to the crawling URL
+       <br>
+       By default <span class="codefrag">link-view-query</span> is set to
+       <span class="codefrag">cocoon-view=links</span>.
+     </dd>
+     
+<dt>user-agent</dt>
+     
+<dd>HTTP user-agent for requesting links,
+       By default <span class="codefrag">user-agent</span> is set to
+       value of <span class="codefrag">org.apache.cocoon.Constants.COMPLETE_NAME</span>,
+       ie. <span class="codefrag">Apache Cocoon 2.1-dev</span>
+     
+</dd>
+     
+<dt>accept</dt>
+     
+<dd>Not currently used</dd>
+   
+</dl>
+   
+<p>
+    A simple example might help to use the LinkStatusGenerator effectivly:
+   </p>
+   
+<p>
+    Add the LinkStatusGenerator to the components in your sitemap.xmap
+   </p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:generators default="file"&gt;
+  ...
+    &lt;map:generator name="linkStatus"
+      src="org.apache.cocoon.generation.LinkStatusGenerator"/&gt;
+  &lt;/map:generators&gt;
+  &lt;map:serialize default="html"&gt;
+    &lt;map:serializer name="links"
+      src="org.apache.cocoon.serialization.LinkSerializer"/&gt;
+  &lt;/map:serialize&gt;
+&lt;/map:components&gt;
+&lt;map:views&gt;
+  &lt;map:view&gt;
+    &lt;map:view from-position="last" name="links"&gt;
+      &lt;map:serialize type="links"/&gt;
+    &lt;/map:view&gt;
+    ...
+&lt;/map:view&gt;
+</pre>
+   
+<p>
+     Next define in your pipeline to use the LinkStatusGenerator
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="/linkStatus"&gt;
+  &lt;map:generate type="linkStatus" name="my-root"/&gt;
+  ...
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/meta.xml
new file mode 100644
index 0000000..2bb6d71
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-linkstatus-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/linkstatus-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/content_en.html
new file mode 100644
index 0000000..54b6728
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/content_en.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Log Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the Log transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Log Transformer</h1>
+      
+<p>This transformations main purpose is debugging.
+The <span class="codefrag">LogTransformer</span> is a class that can be plugged into a pipeline
+to print the SAX events which passes through this transformer in a readable form
+to a file.</p>
+
+<p>
+ The file will be specified in a parameter tag in the sitemap pipeline to the
+ transformer as follows:</p>
+
+<pre class="code">
+  &lt;map:transform type="log"&gt;
+  &nbsp;&nbsp;&lt;map:parameter name="logfile" value="logfile.log"/&gt;
+  &nbsp;&nbsp;&lt;map:parameter name="append" value="no"/&gt;
+  &lt;/map:transform&gt;
+</pre>
+
+<p>
+ Because the log file will be hardcoded into the sitemap this LOGTransformer will
+ not be thread save! If you don't specify the logfile the output is send to
+ the standard output of your servlet engine.</p>
+      
+<ul>
+        
+<li>Name : log</li>
+        
+<li>Class: org.apache.cocoon.transformation.LogTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/meta.xml
new file mode 100644
index 0000000..a29c6a9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-log-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/log-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/content_en.html
new file mode 100644
index 0000000..3882977
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/content_en.html
@@ -0,0 +1,336 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Using and Implementing Matchers and Selectors</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Introduction</h1>
+  
+<p>
+  Matchers and selectors are sitemap components. They are used to
+  determine the flow, the other components involved and their ordering
+  of the request processing. One particular matcher you're probably
+  familiar with, is the WildcardURIMatcher. That is the one that
+  determines the (sub-)pipeline in the welcome example. But there are
+  many more matchers supplied with Apache Cocoon, one matches the requested
+  URI on regular expressions, others match the client's hostname,
+  existence of parameters and so on.
+  </p>
+  
+<p>
+  There is also a number of selectors supplied with Cocoon. Selectors
+  test a generally simple boolean expression and allow to select on
+  roughly the same things as matchers would. There is a selector on
+  the client's hostname, on the client's browser etc.
+  </p>
+  
+<p>
+  To make things even more complicated, actions have very similar
+  properties. You can nest other sitemap elements in an action and
+  those are included in the processing only if the action completes
+  successfully.
+  </p>
+  
+
+<h1>So what are the differences?</h1>
+
+<p>
+The basic structure of a selector is that of a case, switch or
+if-elseif-...-elseif-else statement in programming languages while
+matchers and actions compare more to a if statement. In addition
+selectors don't communicate the basis for their decision to the
+embedded elements, just select the next part(s) of the
+pipeline. Matchers and actions, however, add a new map to the
+environment that can be used for the further processing in the
+sub pipeline. 
+</p>
+
+<p>
+You've already come across this feature on the example sitemap: The
+value matched by the WildcardURIMatcher is used to determine the
+filename <span class="codefrag">docs/samples/xsp/{1}.xsp</span>. Here <span class="codefrag">{1}</span>
+represents the value that is stored in the environmental map with the
+key <span class="codefrag">1</span>. The name of the key is arbitrary and set by the
+matcher. If you had supplied a more complex pattern, there would be
+others. For example <span class="codefrag">&lt;map:match pattern="*/*/*/*/report.html"&gt;</span>
+would result in keys <span class="codefrag">1</span>, <span class="codefrag">2</span>, <span class="codefrag">3</span>,
+and <span class="codefrag">4</span> being defined, corresponding to the <span class="codefrag">*</span>s
+in the pattern.
+</p>
+
+<p>
+BTW you cannot access those maps from your XSP. Use parameters to the
+generator to explicitly send them. On your XSP you can access them
+through an object called <span class="codefrag">parameters</span>. Example
+</p>
+
+
+<pre class="code">
+&lt;map:match pattern="*/*/*/*/report.html"&gt;
+   &lt;map:generate type="serverpages" src="docs/getPostcodeData.xsp"&gt;
+      &lt;parameter name="postcode" value="{1}{2} {3}{4}"/&gt;
+   &lt;/map:generate&gt;
+   &lt;map:transform src="stylesheets/html/report.xsl"/&gt;
+   &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+
+</pre>
+
+
+<p>On your XSP do</p>
+
+<pre class="code">
+
+&lt;xsp:expr&gt;parameters.getParameter("postcode")&lt;/xsp:expr&gt;
+
+</pre>
+
+<p>
+Generally, one could say that selectors are better suited if the
+decisions has few easily distinguishable cases, the map feature is not
+needed and the decision occurs later in the pipeline. Their
+implementation should be lightweight and so is their integration in
+the compiled sitemap.
+</p>
+
+<p>
+Matchers are often the very first element in a pipeline. They direct
+the processing based on more complex decision process. They are
+general purpose but more costly than selectors.
+</p>
+
+<p>
+Actions should be used to <em>"do"</em> something, not to chose
+between different sub pipelines. That should be done only, if an error
+occurred and you cannot continue the regular pipeline. Of course this
+is a fuzzy criterion and using an action to choose between exactly two
+sub pipelines is a very common task i.e. for authentication. Also,
+often actions have no nested elements and the further processing is
+not affected by the result of the action.  </p>
+
+
+<h1>Using Matchers</h1>
+
+<p>
+Like every other sitemap component, matchers need to be declared in
+the sitemap:
+</p>
+
+<pre class="code">
+
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+  &lt;map:components&gt;
+   ...
+
+   &lt;map:matchers default="wildcard"&gt;
+     &lt;map:matcher name="wildcard"
+               src="org.apache.cocoon.matching.WildcardURIMatcher"/&gt;
+     ...
+     &lt;map:matcher name="next-page"
+     src="org.apache.cocoon.matching.WildcardRequestParameterMatcher"&gt;
+        &lt;map:parameter name="parameter-name" value="next-state"/&gt;
+     &lt;/map:matcher&gt;
+   &lt;/map:matchers&gt;
+
+  ...
+  &lt;/map:components&gt;
+
+  &lt;map:resources/&gt;
+  &lt;map:pipelines/&gt;
+&lt;/map:sitemap&gt;
+
+</pre>
+
+<p>Matchers are given a short name (e.g, "wildcard") and of course the
+name of the JAVA class that implements the matcher. In addition,
+parameters can be defined as well.
+</p>
+
+<p>
+One matcher may be defined as default matcher, so whenever a matcher
+appears in the sitemap without explicit type specification it will be
+assumed that it is of the default type.
+</p>
+
+<p>
+In a pipeline use the matcher like this
+</p>
+
+<pre class="code">
+
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+  &lt;map:components/&gt;
+  &lt;map:resources/&gt;
+  &lt;map:pipelines&gt;
+     &lt;map:pipeline&gt;
+
+  &lt;map:match pattern="*"&gt;
+    &lt;map:generate type="serverpages" src="test/{1}.xsp"/&gt;
+    &lt;map:transform src="stylesheets/dynamic-page2html.xsl"/&gt;
+    &lt;map:serialize/&gt;
+  &lt;/map:match&gt;
+
+     &lt;/map:pipeline&gt;
+  &lt;/map:pipelines&gt;
+&lt;/map:sitemap&gt;
+
+</pre>
+
+<p>
+Matchers can be nested:
+</p>
+
+<pre class="code">
+
+&lt;map:match type="sessionstate" pattern="edit*"&gt;
+  &lt;!-- here you could insert parameters for the above matcher --&gt;
+  &lt;map:parameter name="attribute-name" value="__sessionstate"/&gt;
+
+  &lt;map:match type="next-page" pattern="ok*"&gt;
+    &lt;!-- do something here, eg. database updates --&gt;
+    &lt;map:call resource="simple-page1"/&gt;
+  &lt;/map:match&gt;
+  &lt;map:match type="next-page" pattern="delete*"&gt;
+    &lt;!-- do something different here, eg. database deletions --&gt;
+    &lt;map:call resource="simple-page1"/&gt;
+  &lt;/map:match&gt;
+&lt;/map:match&gt;
+
+</pre>
+
+
+<h1>Using Selectors</h1>
+
+<p>
+As said above, selectors are very similar to matchers. Again, you need
+to declare selectors in the sitemap.xmap
+</p>
+
+<pre class="code">
+
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+  &lt;map:components&gt;
+   ...
+  &lt;map:selectors default="browser"&gt;
+   &lt;map:selector name="browser"
+     src="org.apache.cocoon.selection.BrowserSelector"&gt;
+    &lt;browser name="explorer" useragent="MSIE"/&gt;
+    &lt;browser name="lynx" useragent="Lynx"/&gt;
+    &lt;browser name="netscape" useragent="Mozilla"/&gt;
+   &lt;/map:selector&gt;
+   &lt;map:selector name="parameter"
+     src="org.apache.cocoon.selection.ParameterSelector"/&gt;
+  &lt;/map:selectors&gt;
+
+  ...
+  &lt;/map:components&gt;
+
+  &lt;map:resources/&gt;
+  &lt;map:pipelines/&gt;
+&lt;/map:sitemap&gt;
+
+</pre>
+
+<p>
+Their use is a bit different to matchers, though:
+</p>
+
+<pre class="code">
+
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+&lt;map:components/&gt;
+&lt;map:resources/&gt;
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+
+    &lt;map:match pattern="*"&gt;
+      &lt;map:generate type="serverpages" src="test/{1}.xsp"/&gt;
+
+      &lt;map:select type="browser"&gt;
+        &lt;!-- you could insert parameters here as well --&gt;
+        &lt;map:when test="explorer"&gt;
+          &lt;map:transform src="stylesheets/w3c-2-msie.xsl"/&gt;
+        &lt;/map:when&gt;
+        &lt;map:when test="lynx"&gt;
+          &lt;map:transform
+            src="stylesheets/dynamic-page2html-text.xsl"/&gt;
+          &lt;map:serialize/&gt;
+        &lt;/map:when&gt;
+        &lt;map:when test="netscape"&gt;
+          &lt;map:transform src="stylesheets/ns4.xsl"/&gt;
+        &lt;/map:when&gt;
+        &lt;map:otherwise&gt;
+          &lt;map:transform src="stylesheets/w3c.xsl"/&gt;
+        &lt;/map:otherwise&gt;
+      &lt;/map:select&gt;
+
+      &lt;map:transform
+        src="stylesheets/dynamic-page2html.xsl"/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:match&gt;
+
+  &lt;/map:pipeline&gt;
+&lt;/map:pipelines&gt;
+&lt;/map:sitemap&gt;
+
+</pre>
+
+<p>
+Obviously, this could have been done with matchers as well. Decide on
+yourself, what appears clearer to you in a specific situation.
+</p>
+
+
+<h1>Write Your Own Matchers and Selectors</h1>
+
+<h2>Matchers</h2>
+<p>
+Since the basic structure and the assumptions are very similar, we
+look first at matchers and point out the differences to selectors
+at the end.
+</p>
+<p>
+Matchers need to implement the org.apache.cocoon.matching.Matcher
+interface. See javadocs for more details, see also example matchers
+included in the distribution.
+</p>
+<p>
+If you would like to do global configuration for your matcher, it has
+to implement the
+<span class="codefrag">org.apache.avalon.framework.configuration.Configurable</span>
+interface.
+</p>
+<p>
+Local configuration parameters are avalon parameters and thus can be
+easily read and used with the generated matcher method.
+</p>
+<p>
+If the matcher returns not null, the match was successful and the
+nested sub pipeline is executed. Components in sub pipeline can access
+the matching result through the returned map.
+</p>
+<p>
+The easiest way to write your own matcher would be to base it upon
+org.apache.cocoon.matching.WildcardURIMatcher and override the
+getMatchString method with your own.
+</p>
+
+<h2>Selectors</h2>
+<p>
+Selectors and selector factories differ from their matcher counter
+parts only in the fact that selectors return boolean values rather
+than maps. Thus when a selector returns <span class="codefrag">true</span> the nested
+elements will be included in the processing, otherwise they are not
+included. Since no map is returned, no additional information may be
+passed to those elements.
+</p>
+<p>
+For selectors, the last argument reads <span class="codefrag">param</span> instead of
+<span class="codefrag">parameters</span>.  </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/meta.xml
new file mode 100644
index 0000000..171c07a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers-selectors/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/matchers_selectors.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/content_en.html
new file mode 100644
index 0000000..24d66f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/content_en.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Matchers</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in Cocoon" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Gianugo Rabellino" name="DC.Creator">
+<meta content="Diana Shannon, ed." name="DC.Creator">
+<meta content="This document describes all of the available matchers of Cocoon." name="DC.Description">
+</head>
+<body>
+     
+<h1>Goal</h1>
+      
+<p>
+      This document lists all of the available matchers of Apache Cocoon and
+      describes their purpose.
+      See also the concepts document
+      <a href="../concepts/matchers_selectors.html">Using and Implementing
+      Matchers and Selectors</a>.
+      </p>
+     
+     
+<h1>Overview</h1>
+      
+<p>
+      A matcher is a core sitemap component of Cocoon. Matchers allow Cocoon 
+      to associate a pure
+      "virtual" URI space with a given set of "instructions"
+      found in a Cocoon sitemap. Sitemap matchers are used to determine the flow and order 
+      of request processing. They typically describe
+      how to generate, transform and present a requested resource(s) to
+      the client. They may also be used to redirect requests to other pipelines
+      or to call other sitemap resources.
+      </p>
+      
+<p>
+      Cocoon is driven by the client request. A request typically
+      contains a URI, some parameters, cookies, and much more. Within 
+      the Cocoon environment, the request is evaluated to determine
+      what sitemap instructions to use for processing. 
+      More specifically, a given request is matched against a pipeline 
+      matcher's pattern attribute. When a match is found,
+      processing of the request begins.
+      </p>
+      
+<p>
+      As an example, consider the following sitemap snippet:
+      </p>
+
+<pre class="code">
+
+&lt;map:match pattern="body-faq.xml"&gt;
+  &lt;map:generate src="xdocs/faq.xml"/&gt;
+  &lt;map:transform src="stylesheets/faq2document.xsl"/&gt;
+  &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+
+&lt;map:match pattern="body-**.xml"&gt;
+  &lt;map:generate src="xdocs/{1}.xml"/&gt;
+  &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+   
+</pre>
+      
+<p>
+      Here the two sitemap entries map request URIs to different virtual URIs using
+      the default wildcard matcher (defined earlier in a matcher component configuration).
+      The first entry uses an exact match, "body-faq.xml". Only request URIs
+      composed of this exact string will match this entry. The
+      second sitemap entry uses a wildcard pattern. URI Requests that begin with
+      "body-" and end with ".xml" will meet this matcher's
+      requirement. For example, a URI request for "body-cocoon.xml" 
+      would match the second entry.
+      </p>
+     
+     
+<h1>Order</h1>
+       
+<p>
+       It's important to understand that Cocoon is based on a "first-match"
+       approach. All requests are matched against the different "map:match"
+       entries in the order in which matchers are specified in the sitemap.
+       As soon
+       as a match is successful, the pipeline processing begins. This means
+       that more specific patterns must appear before more generic ones. 
+       If the order of the two pipelines in the above example were reversed,
+       a request for "body-faq.xml" not match "body-faq.xml"
+       but "body-**.xml" because it appears first. (This is a familiar 
+       concept, especially in router and firewall configurations.) 
+       </p>
+     
+     
+<h1>Tokenization</h1>
+       
+<p>
+       Another important feature of matchers is tokenization. Every "variable"
+       part of a matcher pattern will be kept in memory by Cocoon for 
+       additional reuse. It remains available within a pipeline match
+       as a numbered argument. Using the previous example, consider a request 
+       URI such as "body-index.xml" matched by the second map:match element.
+       The string "index" which matches the "**" wildcard,
+       is available for reuse by other child elements of map:match. It is
+       identified by the key {1}. This key is used as a parameter for the 
+       generator which will first resolve it to the string 
+       "index", and then look for a file named "xdocs/index.html".  
+       </p>
+     
+     
+<h1>Wildcard and regular expressions</h1>
+       
+<p>
+       Most Cocoon matchers are built using two different techniques:
+       regular expressions and wildcards.
+       Regular expressions (or regexps) are a well-known and powerful 
+       system for pattern matching. Learning how to master them is beyond 
+       the scope of this document. However, you will find a lot of documentation 
+       on the web regarding this topic.
+       </p>
+       
+<p>
+       Although powerful, regexps can be overkill for most
+       typical Cocoon use cases where simple matching operations
+       are performed. This is why Cocoon offers a simplified
+       pattern matching system based on a small set of basic rules.
+       </p>
+       
+<ul>
+        
+<li>
+        An asterisk ('*') matches zero or more characters,
+        up to the occurrence of a '/' character (which serves as
+        a path separator). A string, such as "/cocoon/docs/index.html", 
+        would <em>not</em>
+        match successfully against the pattern '/*/*.index.html'. 
+        The first asterisk matches up to the first path
+        separator only, resulting in the "cocoon" string. 
+        A successful matching pattern would be '/*/*/*.html'.
+        </li>
+        
+<li>
+        A string containing two asterisks ('**') matches zero or more 
+        characters. This could include the path separator '/'. 
+        In this case, "/cocoon/docs/index.html" would successfully
+        match the '/**/*.html' pattern. The double asterisk, including the
+        path separator, would match the "cocoon/docs" string.
+        </li>
+        
+<li>
+        As with regexps, the backslash character ('\') is used to indicate an 
+        escape sequence. The string '\*' will match an actual asterisk
+        while a double backslash ('\\') will match the character '\'. A
+        pattern such as "**/a-\*-is-born.html" would match strings
+        such as "documents/movies/a-*-is-born.html" or 
+        "a/very/long/path/a-*-is-born.html". It would <em>not</em> match
+        the string "docs/a-star-is-born.html".
+        </li>
+       
+</ul>
+     
+     
+<h1>Matchers in Cocoon</h1>
+       
+<ul>
+         
+<li>
+<strong>WildCard URI matcher</strong>(The default matcher): matches the URI against a wildcard pattern.</li>
+         
+<li>
+<strong>Regexp URI matcher:</strong> 
+         matches the URI against a full-blown regular expression</li>
+         
+<li>
+<strong>Request parameter 
+         matcher:</strong> matches a request parameters given as a pattern. If
+         the parameter exists, its value is available for later substitution.
+         </li>
+         
+<li>
+<strong>Wildcard request parameter matcher:</strong> matches a wildcard 
+         given as a pattern against the <strong>value</strong> of a configured 
+         parameter.
+         </li>
+         
+<li>
+<strong>Wildcard session parameter matcher</strong>: similar to the 
+         Wildcard request parameter matcher, but it matches a session parameter.</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/meta.xml
new file mode 100644
index 0000000..ebd8c73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-matchers/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/matchers/matchers.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/content_en.html
new file mode 100644
index 0000000..46eb876
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/content_en.html
@@ -0,0 +1,265 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Input Modules Reference</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tony Collen" name="DC.Creator">
+<meta content="A concise reference to Cocoon's InputModules." name="DC.Description">
+</head>
+<body> 
+
+    
+<h1>Introduction</h1>
+        
+        
+<p>This is meant to be a concise reference to Cocoon's InputModules, 
+        what they do, and how to use them.  InputModules are available in 
+        Cocoon 2.0.4 and above.  Many descriptions are taken directly from 
+        the respective modules' source code, or from trial and error 
+        experimentation.</p>
+        
+        
+<div class="note">See also: the 
+        <a class="external" href="http://wiki.apache.org/cocoon/InputModules">InputModules 
+        Wiki Page</a>.</div>
+    
+
+
+    
+<h1>Modules Reference</h1>
+        
+
+        
+<h2>AbstractInputModule</h2>
+<p>AbstractInputModule gives you the infrastructure for easily 
+            deploying more InputModules.</p>
+
+        
+<h2>AbstractJXPathModule</h2>
+<p>JXPathModule allows to access properties of any object in generic way. 
+            JXPath provides APIs for the traversal of graphs of JavaBeans, DOM and other 
+            types of objects using the XPath syntax. JXPathMetaModule is based on this 
+            class and duplicates the code since multiple inheritance is not possible. 
+            Please keep both classes in sync.</p>
+<p>
+<strong>Configuration Example:</strong>
+</p>
+<p>The following imports the class "String" as extension class to the 
+            JXPathContext using the prefix "str". Thus "str:length(xpath)" would apply 
+            the method "length" to the string object obtained from the xpath expression. 
+            Please note that the class needs to be fully qualified.</p>
+<pre class="code">&lt;function name="java.lang.String" prefix="str"/&gt;</pre>
+<p>The following imports all classes in the package "java.util" as extension 
+            classes to the JXPathContext using the prefix "util". Thus "util:Date.new()" 
+            would create a new java.util.Date object.</p>
+<pre class="code">&lt;package name="java.util" prefix="util"/&gt;</pre>
+
+
+        
+<h2>AbstractMetaModule</h2>
+<p>AbstractMetaModule gives you the infrastructure for easily deploying 
+            more "meta" InputModules i.e. InputModules that are composed of other 
+            InputModules. In order to get at the Logger, use getLogger().</p>
+
+        
+<h2>CollectionMetaModule</h2>
+<p>Constructs an array of values suitable for a JDBC collection type from 
+            parameters obtained from another input module. Application is not limited 
+            to JDBC collections but can be used wherever similar named attributes 
+            shall be collected to an array of a given type. Currently, long, int, and 
+            string are known, more to come.</p>
+<p>
+<strong>Global and Local Configuration:</strong>
+</p>
+<div class="fixme">TC:
+      Finish the reference for this Module.</div>
+
+        
+<h2>CookieModule</h2>
+<p>This module returns the value of the named HTTP cookie.</p>
+<p>
+<strong>Example Pipeline Fragment:</strong>
+</p>
+<pre class="code">
+&lt;map:match pattern="foo.html"&gt;
+  &lt;map:generate type="file" src="documents/{cookie:user-language}/foo.xml"/&gt;
+  &lt;map:transform src="stylesheets/foo2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+        
+<h2>DateInputModule</h2>
+<p>This module returns the current date, optionally formated 
+            as string. Format given through attribute "format" of 
+            configuration root node or nested &lt;format/&gt; tag on module 
+            declaration.</p>
+<div class="note">The 'format' attribute doesn't seem to work. Nested 
+            <span class="codefrag">&lt;format/&gt;</span> tags work fine.</div>
+<div class="note">See also: 
+            <a class="external" href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html">Java 
+            Date Format</a>.</div>
+
+        
+<h2>GlobalInputModule</h2>
+<p>This module allows you to access "global" variables which are defined in 
+            a sitemap's pipelines definition.</p>
+<p>
+<strong>cocoon.xconf usage:</strong>
+</p>
+<pre class="code">
+&lt;input-modules&gt;
+  ...
+  &lt;component-instance 
+     class="org.apache.cocoon.components.modules.input.GlobalInputModule" 
+     logger="core.modules.input" 
+     name="global"/&gt;
+  ...
+&lt;/input-modules&gt; 
+</pre>
+<p>
+<strong>Sitemap Usage:</strong>
+</p>
+<pre class="code">
+&lt;map:component-configurations&gt;
+  &lt;global-variables&gt;
+      &lt;doc&gt;doc.xml&lt;/doc&gt;
+  &lt;/global-variables&gt;
+&lt;/map:component-configurations&gt;
+</pre>
+<p>
+<strong>Example Pipeline Fragment:</strong>
+</p>
+<pre class="code">
+&lt;map:match pattern="foo"&gt;
+  &lt;map:generate type="file" src="documents/{global:doc}"/&gt;
+  &lt;map:transform src="stylesheets/foo2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+
+        
+<a name="raw-request-parameter-module"></a>
+
+        
+<h2>RawRequestParameterModule</h2>
+<p>This module allows access to "raw" request parameters and their 
+            values.</p>
+<p>Values returned are "URL Encoded", meaning if a parameter is 
+            submitted as "foo+bar", you will get the string "foo+bar".</p>
+<div class="note">For access to URL-Decoded request parameters, see the <a href="#request-parameter-module">RequestParameterModule</a>.</div>
+<p>
+<strong>cocoon.xconf usage:</strong>
+</p>
+<pre class="code">
+&lt;input-modules&gt;
+  ...
+  &lt;component-instance 
+     class="org.apache.cocoon.components.modules.input.RawRequestParameterModule" 
+     logger="core.modules.input" 
+     name="raw-request-param"/&gt;
+  ...
+&lt;/input-modules&gt; 
+</pre>
+<p>
+<strong>Example Pipeline Fragment:</strong>
+</p>
+<pre class="code">
+&lt;map:match pattern="amazonProxy"&gt;
+  &lt;map:generate type="file" 
+      src="http://localhost:8888/search?qry={raw-request-param:actor}"/&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+                This input module is useful when you are querying a remote service, 
+                and you need to be able to send a search string with spaces or other 
+                special characters intact. If you were to simply use 
+                <span class="codefrag">{request-param:actor}</span>, you would end up sending a space 
+                character to the remote service, which would be an error, since 
+                <a class="external" href="http://www.faqs.org/rfcs/rfc1738.html">RFC 1738</a> 
+                requires spaces and other special characters to be correctly encoded.
+            </p>
+
+        
+<a name="request-parameter-module"></a>
+
+        
+<h2>RequestParameterModule</h2>
+<p>This module allows access to request parameters. Values returned are 
+            "URL Decoded". That is, if a request parameter is submitted as 
+            <span class="codefrag">foo+bar</span>, you will get the string "foo bar".</p>
+<div class="note">For URL-Encoded request parameters, see the 
+            <a href="#raw-request-parameter-module">RawRequestParameterModule</a>.</div>
+<p>
+<strong>cocoon.xconf usage:</strong>
+</p>
+<pre class="code">
+&lt;input-modules&gt;
+  ...
+  &lt;component-instance 
+     class="org.apache.cocoon.components.modules.input.RequestParameterModule" 
+     logger="core.modules.input" 
+     name="request-param"/&gt;
+  ...
+&lt;/input-modules&gt;
+</pre>
+<p>
+<strong>Example Pipeline Fragment:</strong>
+</p>
+<pre class="code">
+&lt;map:match pattern="bar"&gt;
+   &lt;map:generate type="file" src="documents/{request-param:file}"/&gt;
+   &lt;map:transform src="stylesheets/{request-param:stylesheet}"/&gt;
+   &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>This pipeline will match a request for "bar" and pass the request 
+            parameters "file" and "stylesheet" to the generator and transformer, 
+            respectively. (e.g. 
+            http://localhost:8080/cocoon/bar?file=doc.xml&amp;stylesheet=main.xsl).</p>
+<div class="warning">
+                Directly passing request parameters for file access can be 
+                dangerous. Remember to follow basic webapp safety rules when 
+                designing your pipelines, and when passing around request 
+                parameters.
+            </div>
+
+        
+<h2>RequestURIModule</h2>
+<p>Returns the URI of the request.</p>
+<p>If you are familliar with Avalon and Cocoon's component architecture, 
+            the following will explain what is specifically returned:</p>
+<pre class="code">String uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();</pre>
+<p>
+<strong>cocoon.xconf usage:</strong>
+</p>
+<pre class="code">
+&lt;input-modules&gt;
+  ...
+  &lt;component-instance 
+     class="org.apache.cocoon.components.modules.input.RequestURIModule" 
+     logger="core.modules.input" 
+     name="request-uri"/&gt;
+  ...
+&lt;/input-modules&gt;
+</pre>
+<p>
+<strong>Example Sitemap Usage:</strong>
+</p>
+<pre class="code">{request-uri:requestURI}</pre>
+<p>This is how you would use the module most of the time, since the 
+            module only returns one item, the Request URI.</p>
+<div class="note">
+                The same effect can be achieved by passing the parameter name 
+                "sitemapURI" to the request module. Therefore this component is not 
+                declared in cocoon.xconf by default. You must manually add it.
+            </div>
+        
+    
+
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/meta.xml
new file mode 100644
index 0000000..86681d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules-ref/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/modules-ref.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/content_en.html
new file mode 100644
index 0000000..c5eb513
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/content_en.html
@@ -0,0 +1,246 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Modules</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>
+        Many sitemap components serve a purpose regardless how the input is
+        obtained. Still, to provide a wide range of components to quickly get
+        you up to speed, variants for different inputs exist. Modules allow to
+        create generic components and plug-in input or output later.
+      </p>
+      
+<p>
+        This document will explain how modules work and how to make use of
+        them. If you plan on writing your own modules, it is highly recommended
+        to read <a class="external" href="http://jakarta.apache.org/avalon/developing/index.html">
+          Developing With Apache Avalon</a>. It is a very good description
+        of the underlying rationale and principles.
+      </p>
+    
+    
+<h1>Types of Modules</h1>
+      
+<p>
+        Currently, three different types of modules exist: Input modules
+        provide means to enumerate attributes and to retrieve them, output
+        modules allow storing of data and exhibit transaction like semantics,
+        database modules encapsulate different mechanisms for auto increment
+        columns of various database management systems. Please refer to the
+        javadoc documentation of these interfaces.
+      </p>
+      
+<p>
+        Input modules are modelled after request attributes. The main
+        difference is, that every method takes two additional arguments, the
+        request object and a configuration object. The configuration object is
+        used to allow arbitrarily complex instructions for the input module.
+        Apart from that, input modules are more or less a drop-in replacement.
+      </p>
+      
+<p>
+        Output modules are again very similar to using request
+        attributes. Basically, they provide a method to set an attribute to a
+        value. Again, a request and a configuration object is the only change
+        to request attributes. A fundamental difference is, however, that
+        output modules should exhibit transactional behaviour. Thus setting an
+        attributes implicitly starts a transaction that must be ended by
+        calling rollback or commit. Only if the transaction is completed by
+        calling commit, the values set should be visible. This is needed
+        e.g. by the database actions.
+      </p>
+      
+<p>
+        Database modules, actually named AutoIncrementModule, contains
+        configuration information how to retrieve a value for an auto increment
+        column. It is possible to obtain the value before inserting a row,
+        while inserting as part of the SQL or after successful insert. If the
+        value is obtained before inserting, it can be generated
+        externally. Currently, supported database management systems include
+        HSQL, Informix, MySQL, and querying the database for the current max
+        value. 
+      </p>
+    
+    
+<h1>Using modules</h1>
+      
+<p>
+        Using any of these modules requires a two step setup process. Step one
+        has already been done for your for all modules that come with Apache
+        Cocoon. Exception to this rule are the auto increment modules: only the
+        HSQL module is already setup.
+      </p>
+      
+<h2>Step 1: Making a new module known to Apache Cocoon</h2>
+<p>
+          Like other core components of Apache Cocoon, modules are declared in
+          <span class="codefrag">cocoon.xconf</span>. There are already too many to list here.
+        </p>
+<pre class="code">
+
+&lt;input-modules&gt;
+  &lt;component-instance name="request"   
+  class="org.apache.cocoon.components.modules.input.RequestParameterModule"/&gt;
+
+  &lt;component-instance name="attribute" 
+  class="org.apache.cocoon.components.modules.input.RequestAttributeModule"/&gt;
+
+  &lt;component-instance name="URI"       
+  class="org.apache.cocoon.components.modules.input.RequestURIModule"/&gt;
+
+  &lt;component-instance name="context"       
+  class="org.apache.cocoon.components.modules.input.RequestContextPathModule"/&gt;
+
+  &lt;component-instance name="header"    
+  class="org.apache.cocoon.components.modules.input.HeaderAttributeModule"/&gt;
+
+  &lt;component-instance name="session"   
+  class="org.apache.cocoon.components.modules.input.SessionAttributeModule"/&gt;
+
+  &lt;component-instance name="date"      
+  class="org.apache.cocoon.components.modules.input.DateInputModule"/&gt;
+
+  &lt;component-instance name="defaults"  
+  class="org.apache.cocoon.components.modules.input.DefaultsModule"&gt;
+    &lt;input-module name="request"/&gt;
+    &lt;values&gt;
+      &lt;skin&gt;defaultSkin&lt;/skin&gt;
+      &lt;base-url&gt;http://localhost:8080/cocoon&lt;/base-url&gt;
+    &lt;/values&gt;
+  &lt;/component-instance&gt;
+&lt;/input-modules&gt;
+
+&lt;output-modules&gt;
+  &lt;component-instance name="attribute" 
+  class="org.apache.cocoon.components.modules.output.RequestAttributeOutputModule"/&gt;
+
+  &lt;component-instance name="session"   
+  class="org.apache.cocoon.components.modules.output.SessionAttributeOutputModule"/&gt;
+&lt;/output-modules&gt;
+
+&lt;autoincrement-modules&gt;
+  &lt;component-instance name="auto" 
+  class="org.apache.cocoon.components.modules.database.HsqlIdentityAutoIncrementModule"/&gt;
+
+  &lt;!--
+  &lt;component-instance name="auto" 
+  class="org.apache.cocoon.components.modules.database.ManualAutoIncrementModule"/&gt;
+  &lt;component-instance name="auto" 
+  class="org.apache.cocoon.components.modules.database.IfxSerialAutoIncrementModule"/&gt;
+  &lt;component-instance name="auto" 
+  class="org.apache.cocoon.components.modules.database.MysqlAutoIncrementModule"/&gt;
+  --&gt;
+&lt;/autoincrement-modules&gt;
+        </pre>
+<p>
+          The above snippet declares a number of modules. After this, the
+          modules are accessible through the given name. Thus, when an
+          <span class="codefrag">input-module</span> is expected, it is sufficient to give the
+          name of a module, like <span class="codefrag">header</span>.
+        </p>
+<p>
+          For the auto increment modules only one is declared as the name
+          <span class="codefrag">"auto"</span> has special meaning to the modular database
+          actions. If more than one is needed at the same time, the
+          configuration of the database actions needs to explicitly specify
+          which one to use.
+        </p>
+      
+<h2>Step 2: Use it</h2>
+<p>
+          The following alternatives for using modules exist:
+        </p>
+<h3>Step 2a: Use it as sitemap variable</h3>
+<p>
+            Input modules can be used in a sitemap almost like a sitemap
+            variable. If the variable name contains a colon (":"), the
+            preceeding string is used as the name of the module to use and the
+            trailing string is passed to the module. The expression is replaced
+            with the string value returned from the module.
+          </p>
+<pre class="code">
+
+&lt;map:transform src="resources/stylesheets/{../skin}.xsl"/&gt;
+          </pre>
+<p>
+            The above example uses the variable <span class="codefrag">skin</span> declared
+            e.g. by an action for the stylesheet to apply to the page. The
+            example below uses an input module instead. The way this module was
+            declared above allows to override the skin with a request parameter
+            named "skin".
+          </p>
+<pre class="code">
+
+&lt;map:transform src="resources/stylesheets/{default:skin}.xsl"/&gt;
+          </pre>
+<p>
+            Some of the input modules are JXPath-enabled, so you can use
+            XPath expressions to access values (see Input Modules sample for details).
+            The following example demonstrates the use of XPath function 
+            with <span class="codefrag">system-property</span> module.
+          </p>
+<pre class="code">
+
+&lt;map:parameter name="users-home-base"
+  value="{system-property:substring-before(user.home, user.name)}"/&gt;
+    </pre>
+<h3>Step 2b: Use it on an XSP</h3>
+<p>
+            The input logicsheet allows easy use of InputModules from an
+            XSP. Currently, it provides tags for getting one value, an
+            array of values, and an Iterator for a Collection of
+            parameter names.
+          </p>
+<pre class="code">
+
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+
+&lt;xsp:page language="java"
+    xmlns:xsp="http://apache.org/xsp"  
+    xmlns:input="http://apache.org/cocoon/xsp/input/1.0"&gt;
+
+  &lt;page&gt;
+    &lt;title&gt;Testing InputModules&lt;/title&gt;
+
+    &lt;p&gt;
+      Parameter name=&lt;input:get-attribute module="request-param"
+                       as="string" name="module" default="John Doe"/&gt;;
+    &lt;/p&gt;
+    &lt;p&gt;
+      Parameter cars=&lt;input:get-attribute-values module="request-param" 
+                       as="xml" name="car"/&gt;;
+    &lt;/p&gt;
+  &lt;/page&gt;
+&lt;/xsp:page&gt;
+          </pre>
+<h3>Step 2c: Have sitemap components use a module</h3>
+<p>
+            This depends on the component that is to be used. As an example the
+            <span class="codefrag">CachingWildcardMatcher</span> requires to set the
+            <span class="codefrag">input-module</span> on declaration.
+          </p>
+<pre class="code">
+
+&lt;map:matchers default="wildcard"&gt;
+  &lt;map:matcher name="cached-uri" 
+      src="org.apache.cocoon.matching.modular.CachingWildcardMatcher"&gt;
+    &lt;input-module name="URI"/&gt;
+  &lt;/map:matcher&gt;
+&lt;/map:matchers&gt;
+          </pre>
+<p>
+            By replacing the input module name with any of the other declared
+            input modules, this matcher can be used to match e.g. on session
+            attributes, request headers or even dates!
+          </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/meta.xml
new file mode 100644
index 0000000..451f627
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-modules/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/modules.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/content_en.html
new file mode 100644
index 0000000..4999434
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/content_en.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Description of the mp3directory generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="The Cocoon Community" name="DC.Creator">
+</head>
+<body>
+    
+<h1>MP3DirectoryGenerator</h1>
+ 
+<p>
+  Following extra attributes added to valid MP3 files:</p>
+ 
+<ul>
+ 
+<li>
+<em>frequency</em> : the frequency of the MP3 file in KHz (most common: 44.1)</li>
+ 
+<li>
+<em>bitrate</em> : the bitrate of the MP3 file in Kbit, from 8 to 448.</li>
+ 
+<li>
+<em>mode</em> : the mode of the MP3 file, one of the following: Stereo, 
+          Joint stereo, Dual channel, Single channel.</li>
+ 
+<li>
+<em>variable-rate</em> (optional) : value is "yes" if VBR header is detected.</li>
+ 
+<li>
+<em>title, artitst, album, year, comment, track, genre</em> (all optional) : 
+       values obtained from MP3 ID3 tag.</li>
+   
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/meta.xml
new file mode 100644
index 0000000..ef56984
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mp3directory-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/mp3directory-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/content_en.html
new file mode 100644
index 0000000..00525f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/content_en.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>MRUMemoryStore and Swapping under Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gerhard Froehlich" name="DC.Creator">
+<meta content="This document explains how the MRUMemoryStore and Swapping under 
+    Cocoon executes." name="DC.Description">
+</head>
+<body>
+  
+<h1>Goal</h1>
+    
+<p>This document explains how the MRUMemoryStore and Swapping under 
+    Cocoon executes.</p>
+  
+  
+<h1>Overview</h1>
+    
+<p>The MRUMemoryStore was developed to provide a standard algorithm to
+       store data in memory. For web-based applications the MRU (Most Recently Used) algorithm
+       is very suitable, because the object most frequently accessed is always on "top".
+    </p>
+    
+<p>If configured, the objects are also swapped to the filesystem if the
+    MRUMemoryStore reached its configured maximum object limit.
+    </p>
+  
+  
+<h1>Implementation</h1>
+    
+<h2>MRUMemoryStore</h2>
+<p> 
+    The heart of the MRUMemoryStore is a combination of a LinkedList and a HashMap:
+    </p>
+<p>
+    The LinkedList provides the queue mechanism, and the entries in the LinkedList 
+    contain the key to the data in the HashMap. When caching a new entry in to the list,
+    the entry is inserted to the front of the list.
+    If the list is already full, the oldest data entry is removed from the Cache.
+    When requesting a entry, the store returns the object by key and inserts the requested key 
+    on the top of the Cache.
+       
+    This implementation keeps the most recent used objects in the store and provides the best
+    use of the machines memory.
+    </p>
+    
+<h2>Swapping</h2>
+<p>
+    When the MRUMemoryStore is full or the JVM is at the heap size limit the 
+    objects in the MRUMemoryStore are swapped to the Filesystem. The default 
+    directory is "cache-dir" in the work-directory.
+    </p>
+<p>
+    NOTE: The keys under Cocoon are Strings at the moment. Therefore the
+    filenames of the swapped objects can be very long. Especially Windows OS
+    flavours have problems with long filenames. Use the JispFilesystemStore to
+    deal with that (see <a href="persistence.html">Persistent cache</a>).
+    </p>
+  
+  
+<h1>Configuration of the MRUMemoryStore in the cocoon.xconf</h1>
+  
+<pre class="code">
+&lt;store logger="core.store"&gt;
+  &lt;parameter name="maxobjects" value="100"/&gt;
+  &lt;parameter name="use-persistent-cache" value="true"/&gt;
+&lt;/store&gt;
+  </pre> 
+  
+<p>Explanation of the parameters:</p>
+    
+<ol> 
+      
+<li>
+<span class="codefrag">&lt;parameter name="maxobjects" value="100"/&gt;</span>:
+      Indicates how many objects will be held in MRUMemoryStore. When the number 
+      of maxobjects has been reached, the last object in the MRUMemoryStore will be 
+      thrown out.</li>
+      
+<li>
+<span class="codefrag">&lt;parameter name="use-persistent-cache" value="true"/&gt;</span>:
+      If this switch is set on true, objects are swapped out to the filesystem,
+      if the MRUMemoryStore has reached its maximum object limit, or the JVM 
+      memory consumption is over the heap size limit. See StoreJanitor user 
+      docs for more information.</li>
+  
+</ol>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/meta.xml
new file mode 100644
index 0000000..49029d1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-mru-store/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/mrustore.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/content_en.html
new file mode 100644
index 0000000..2bf0322
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/content_en.html
@@ -0,0 +1,269 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configuration of Cocoon for Offline Use</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document explains how to configure Cocoon for offline page and site generation." name="DC.Description">
+</head>
+<body>
+    
+<h1>Overview</h1>
+      
+<p>This page details the <span class="codefrag">xconf</span> configuration format for configuring Cocoon's offline 
+         page and site generation capabilities.</p>
+      
+<p>This page gives details of how configure Cocoon. Details of the concepts behind
+         offline page generation are given on the offline generation 
+         <a href="index.html">overview</a> page.</p>
+    
+    
+<h1>The xconf Configuration Format</h1>
+      
+<p>The {{xconf}} configuration format can be used both within the Cocoon 
+         <a href="cli.html">Command Line Interface</a> and within the 
+         <a href="ant.html">Cocoon Ant Task</a>.</p>
+    
+    
+<h1>Sample xconf File</h1>
+      
+<p>Below is a sample XConf file. The details of the file are detailed as comments within
+         this sample itself.</p>
+
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt;
+
+&lt;!--+
+    |  This is an Apache Cocoon command line configuration file. 
+    |  Here you give the command line interface details of where
+    |  to find various aspects of your Cocoon installation.
+    |
+    |  If you wish, you can also use this file to specify the URIs
+    |  that you wish to generate.
+    |
+    |  The current configuration information in this file is for
+    |  building the Cocoon documentation. Therefore, all links here 
+    |  are relative to the build context dir, which, in the build.xml 
+    |  file, is set to ${build.context} 
+    |
+    |  Options:
+    |    verbose:            increase amount of information presented
+    |                        to standard output (default: false)
+    |    follow-links:       whether linked pages should also be 
+    |                        generated (default: true)
+    |    precompile-only:    precompile sitemaps and XSP pages, but 
+    |                        do not generate any pages (default: false)
+    |    confirm-extensions: check the mime type for the generated page
+    |                        and adjust filename and links extensions
+    |                        to match the mime type 
+    |                        (e.g. text/html-&gt;.html)
+    |    context-dir:        The context directory is usually the webapp 
+    |                        directory containing the sitemap.xmap file.
+    |    config-file:        The config file is the cocoon.xconf file, 
+    |                        usually found within the WEB-INF folder
+    |    work-dir:           The work directory is used by Cocoon to 
+    |                        store temporary files and cache files.
+    |    dest-dir:           The destination directory is where generated 
+    |                        pages will be written (assuming the 'simple' 
+    |                        mapper is used, see below)
+    |
+    +--&gt;
+    
+&lt;cocoon verbose="true"  
+        follow-links="true" 
+        precompile-only="false" 
+        confirm-extensions="true"
+        context-dir="build/webapp/xconf"
+        config-file="WEB-INF/cocoon.xconf"
+        work-dir="build/work"
+        dest-dir="build/dest"&gt;
+
+   &lt;!--+
+       | Broken link reporting options:
+       |   Report into a text file, one link per line:
+       |     &lt;broken-links type="text" report="filename"/&gt;
+       |   Report into an XML file:
+       |     &lt;broken-links type="xml" report="filename"/&gt;
+       |   Ignore broken links (default):
+       |     &lt;broken-links type="none"/&gt;
+       |     
+       |   Two attributes to this node specify whether a page should
+       |   be generated when an error has occured. 'generate' specifies 
+       |   whether a page should be generated (default: true) and
+       |   extension specifies an extension that should be appended
+       |   to the generated page's filename (default: none)
+       |   
+       |   Using this, a quick scan through the destination directory
+       |   will show broken links, by their filename extension.
+       +--&gt;
+   &lt;broken-links type="xml" 
+                 file="brokenlinks.xml"
+                 generate="false"
+                 extension=".error"/&gt;
+   
+   &lt;!--+
+       |  Load classes at startup. This is necessary for generating
+       |  from sites that use SQL databases and JDBC.
+       |  The &lt;load-class&gt; element can be repeated if multiple classes
+       |  are needed.
+       +--&gt;
+   &lt;!--
+   &lt;load-class&gt;org.firebirdsql.jdbc.Driver&lt;/load-class&gt;
+   --&gt;
+
+   &lt;!--+
+       |  Configures logging. 
+       |  The 'log-kit' parameter specifies the location of the log kit 
+       |  configuration file (usually called logkit.xconf. 
+       | 
+       |  Logger specifies the logging category (for all logging prior 
+       |  to other Cocoon logging categories taking over)
+       |
+       |  Available log levels are:
+       |    DEBUG:        prints all level of log messages.
+       |    INFO:         prints all level of log messages except DEBUG 
+       |                  ones.
+       |    WARN:         prints all level of log messages except DEBUG 
+       |                  and INFO ones.
+       |    ERROR:        prints all level of log messages except DEBUG, 
+       |                  INFO and WARN ones.
+       |    FATAL_ERROR:  prints only log messages of this level
+       +--&gt;
+   &lt;logging log-kit="build/webapp/WEB-INF/logkit.xconf" logger="cli" level="DEBUG" /&gt;
+
+   &lt;!--+
+       |  Specifies the filename to be appended to URIs that
+       |  refer to a directory (i.e. end with a forward slash).
+       +--&gt;
+   &lt;default-filename&gt;index.html&lt;/default-filename&gt;
+
+   &lt;!--+
+       |  Specifies a user agent string to the sitemap when
+       |  generating the site.
+       +--&gt;
+   &lt;!--
+   &lt;user-agent&gt;xxx&lt;/user-agent&gt;
+   --&gt;
+
+   &lt;!--+
+       |  Specifies an accept string to the sitemap when generating
+       |  the site.
+       +--&gt;
+   &lt;accept&gt;*/*&lt;/accept&gt;
+   
+   &lt;!--+
+       | Specifies which URIs should be included or excluded, according
+       | to wildcard patterns. 
+       | 
+       | By default, all URIs are included. If both include and exclude
+       | patterns are specified, a URI is first checked against the 
+       | include patterns, and then against the exclude patterns.
+       | 
+       | Multiple patterns can be given, using muliple include or exclude
+       | nodes. 
+       | 
+       | The order of the elements is not significant, as only the first 
+       | successful match of each category is used.
+       | 
+       | Currently, only the complete source URI can be matched (including
+       | any URI prefix). Future plans include destination URI matching 
+       | and regexp matching. If you have requirements for these, contact
+       | dev@cocoon.apache.org.
+       +--&gt;
+   &lt;include pattern="**"/&gt;
+   &lt;exclude pattern="docs/apidocs/**"/&gt;
+   
+&lt;!--   &lt;include-links extension=".html"/&gt;--&gt;
+   
+   &lt;!--+
+       |  &lt;uri&gt; nodes specify the URIs that should be generated, and 
+       |  where required, what should be done with the generated pages.
+       |
+       |  Append: append the generated page's URI to the end of the 
+       |  source URI:
+       |
+       |   &lt;uri type="append" src-prefix="documents/" src="index.html"
+       |   dest="build/dest/"/&gt;
+       |
+       |  Replace: Completely ignore the generated page's URI - just 
+       |  use the destination URI:
+       |
+       |   &lt;uri type="replace" src-prefix="documents/" src="index.html" 
+       |   dest="build/dest/docs.html"/&gt;
+       |
+       |  Insert: Insert generated page's URI into the destination 
+       |  URI at the point marked with a * (example uses fictional 
+       |  zip protocol)
+       |
+       |   &lt;uri type="insert" src-prefix="documents/" src="index.html" 
+       |   dest="zip://*.zip/page.html"/&gt;
+       |
+       |  If in any of these scenarios, the dest attribute is omitted,
+       |  the value provided globally using the &lt;dest-dir&gt; node will 
+       |  be used.
+       +--&gt;
+
+   &lt;uri type="replace" 
+        src-prefix="samples/" 
+        src="hello-world/hello.html"
+        dest="build/dest/hello-world.html"/&gt;
+        
+   &lt;!--+
+       | &lt;uri&gt; nodes can be grouped together in a &lt;uris&gt; node. This 
+       | enables a group of URIs to share properties. The following
+       | properties can be set for a group of URIs:
+       |   * follow-links:       should pages be crawled for links
+       |   * confirm-extensions: should file extensions be checked
+       |                         for the correct mime type
+       |   * src-prefix:         all source URIs should be 
+       |                         pre-pended with this prefix before
+       |                         generation. The prefix is not 
+       |                         included when calculating the 
+       |                         destination URI
+       |   * dest:               the base destination URI to be
+       |                         shared by all pages in this group
+       |   * type:               the method to be used to calculate
+       |                         the destination URI. See above 
+       |                         section on &lt;uri&gt; node for details.
+       | 
+       | Each &lt;uris&gt; node can have a name attribute. When a name
+       | attribute has been specified, the -n switch on the command
+       | line can be used to tell Cocoon to only process the URIs
+       | within this URI group. When no -n switch is given, all 
+       | &lt;uris&gt; nodes are processed. Thus, one xconf file can be 
+       | used to manage multiple sites.
+       +--&gt;
+   &lt;uris name="docs" follow-links="true"&gt;
+     &lt;uri type="append" src-prefix="docs/" src="index.html"
+          dest="build/dest/" /&gt;
+   &lt;/uris&gt;
+   
+   &lt;uris name="samples" follow-links="false"
+         confirm-extensions="true"
+         src-prefix="samples/"
+         dest="build/dest/examples/"
+         type="append"
+         &gt;
+      &lt;uri src=""/&gt;
+      &lt;uri src="hello-world/"/&gt;
+      &lt;uri src="hello-world/hello.html"/&gt;
+      &lt;uri src="hello-world/hello.xml"/&gt;
+   &lt;/uris&gt;
+
+   &lt;!--+
+       |  File containing URIs (plain text, one per
+       |  line).
+       +--&gt;
+   &lt;!--
+   &lt;uri-file&gt;&lt;/uri-file&gt;
+   --&gt;
+   
+&lt;/cocoon&gt;
+
+        </pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/meta.xml
new file mode 100644
index 0000000..4e900dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline-configuration/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/offline/configuration.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/content_en.html
new file mode 100644
index 0000000..a17a59b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/content_en.html
@@ -0,0 +1,249 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Offline Page Generation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+<meta content="This document explains the basic concepts of offline page generation with Apache Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Overview</h1>
+      
+<p>Cocoon can generate static, 'offline' versions of web pages or web sites, as well
+         as sites served dynamically. This document covers the concepts involved in offline
+         page and site generation.
+      </p>
+    
+    
+<h1>Offline Page Generation</h1>
+      
+<p>Cocoon allows static versions of Cocoon web sites to be created.</p>
+      
+<p>At present, this can be done in three ways:</p>
+      
+<ul>
+        
+<li>
+<a href="cli.html">Command Line Interface</a>
+</li>
+        
+<li>
+<a href="ant.html">Using Ant Task</a>
+</li>
+        
+<li>
+<a href="bean.html">Cocoon Bean</a>
+</li>
+      
+</ul>
+      
+<p>This document explains the general concepts that are shared by all of these approaches.
+         The specific details for each method are explained on a separate page.</p>
+      
+<p>Cocoon, when generating pages offline, can follow links in a page (whether that page
+         is HTML, PDF or anything else), and can rewrite URIs to create filenames by checking 
+         the mime type of the generated page. All links to pages who's URIs change are changed
+         too.
+      </p>
+    
+    
+<h1>Configuration</h1>
+      
+<p>To use Cocoon in its offline mode, a servlet container (e.g. Tomcat or Jetty) is not
+         needed. Cocoon can generate an offline site directly using the information available
+         in the Cocoon <span class="codefrag">webapp</span> folder.</p>
+      
+<p>Having said this, many choose to have a servlet container available locally for use
+         whilst debugging, as this can speed up the development process significantly.</p>
+      
+<h2>Directories and Files</h2>
+<p>As all the information Cocoon needs to generate a site is stored in the Cocoon 
+           webapp directory, we need to tell it where to find it, and where to find various 
+           other files and directories. These are:</p>
+<ul>
+          
+<li>Context directory (the Cocoon Webapp directory)</li>
+          
+<li>Configuration File (usually <span class="codefrag">${COCOON_WEBAPP}/WEB-INF/cocoon.xconf</span>)</li>
+          
+<li>Work Directory (used by Cocoon to store temporary files, this can be anywhere of your choosing)</li>
+        
+</ul>   
+      
+<h2>Logging</h2>
+<p>There are three options that need to be specified in relation to logging. These are:</p>
+<ul>
+          
+<li>Log Kit (the logging configuration file, usually <span class="codefrag">${COCOON_WEBAPP}/WEB-INF/logkit.xconf</span>)</li>
+          
+<li>Logger (a category used for logging, as configured in the configuration file)</li>
+          
+<li>Log Level (a logging level, either DEBUG, INFO WARN, ERROR or FATAL_ERROR. Relates specifically to logging
+              at startup, after which log kit configuration takes over)</li>
+        
+</ul>
+      
+<h2>Other Configuration Options</h2>
+<p>In online mode, a User agent string tells Cocoon what browser is being used to access a page. The user agent
+           can be configured manually for offline generation.</p>
+<p>In online mode, an accept string is provided by a browser, telling the browser what types of content it 
+           is capable of accepting. This will be a comma separated list of mime types. In offline mode, an accept
+           string can also be specified.</p>
+<p>As Cocoon based sites can change the content they generate based upon the user agent string and the accepts 
+           string, it can be necessary to specify them in order to have the correct content generated.</p>
+<p>In order to generate sites that make use of databases and database connections, it is necessary to load
+           JDBC classes at startup. Cocoon allows for this.</p>
+<p>When, in offline mode, Cocoon generates a page ending in a <span class="codefrag">/</span>, the resultant file cannot be 
+           written to a filesystem as its name would refer specifically to a directory. Therefore, the user can
+           specify a default filename which will be appended to the page's URI before saving to disc.</p>
+    
+    
+<h1>URIs and Targets</h1>
+      
+<h2>SourceURIs</h2>
+<p>A source URI (which may also have a source prefix prepended) is the part of the URI that is given
+           to Cocoon for processing. So, for example, if you access a page with: 
+           <span class="codefrag">http://localhost:8080/cocoon/site/page.html</span> then the source URI would be 
+           <span class="codefrag">site/page.html</span>
+</p>
+      
+<h2>Destinations and Modifiable Sources</h2>
+<p>Most of the time, when generating pages, the generated pages will be simply written to disk.</p>
+<p>However, this is not the only option. Generated pages can be written anywhere for which a 
+           <span class="codefrag">ModifiableSource</span> exists. So, for example, it is possible to generate a site and 
+           have the pages written directly to a web server using FTP, by making use of the Avalon 
+           <span class="codefrag">FTPSource</span>.</p>
+      
+<h2>Target Types</h2>
+<p>When generating a page, Cocoon needs to know how to decide upon the URI of the generated page. 
+           This process could be described as 'URI arithmetic'.</p>
+<p>Source and destination URIs are made up of the following elements:</p>
+<ul>
+          
+<li>Source Prefix: Part of a source URI used to request a page but excluded from the destination 
+              URI</li>
+          
+<li>Source URI: Part of a source URI that is used when calculating the destination URI</li>
+          
+<li>Destination URI: The base URI for a destination</li>
+          
+<li>Type: The method used for merging the above elements (can be append, replace or 
+              insert</li>
+        
+</ul>
+<div class="note">When combining elements to make a URI, it is the user's responsibility to include directory
+              separators. For example, <span class="codefrag">foo</span> with <span class="codefrag">bar</span> appended will be 
+              <span class="codefrag">foobar</span>, whereas <span class="codefrag">foo/</span> with <span class="codefrag">bar</span> appended will be
+              <span class="codefrag">foo/bar</span>.
+        </div>
+<h3>Appending</h3>
+<p>Here, when calculating the destination URI, the source prefix is ignored, and the destination
+             URI is calculated by appending the source URI to the end of the destination URI. For example,
+             with the following values:</p>
+<p>Source prefix: <span class="codefrag">site/</span>, source URI: <span class="codefrag">page.html</span>, destination URI:
+             <span class="codefrag">pages/</span>
+</p>
+<p>A request will be made to Cocoon for a page at: <span class="codefrag">site/page.html</span>. This will be
+             saved as <span class="codefrag">pages/page.html</span>.</p>
+<h3>Replacing</h3>
+<p>Here, when calculating the destination URI, the source prefix and the source URI are 
+             ignored, and the destination URI is used as is. This is useful when you wish to save the
+             generated page with a filename that bears no relationship to the source URI. For example,
+             with the following values:</p>
+<p>Source prefix: <span class="codefrag">site/</span>, source URI: <span class="codefrag">page.html</span>, destination URI:
+             <span class="codefrag">pages/simple.html</span>
+</p>
+<p>A request will be made to Cocoon for a page at: <span class="codefrag">site/page.html</span>. This will be
+             saved as <span class="codefrag">pages/simple.html</span>.</p>
+<div class="note">Given the nature of this target type, it inherently cannot be used when following links 
+             (otherwise all pages will be written on top of each other).</div>
+<h3>Inserting</h3>
+<p>Here, when calculating the destination URI, the source prefix is ignored, and the source URI
+             is inserted into the destination URI at the point marked by an asterisk (*). This is intended
+             for use with complex protocols where the source URI does not appear at the end of the 
+             destination URI.</p>
+      
+<h2>Mime Type Checking</h2>
+<p>Cocoon can optionally test the mime type for a page, and, if the mime type doesn't match the page's
+           extension, amend the destination URI to include the correct extension. This will ensure that pages
+           will load correctly when served by a static web server.</p>
+<p>When Cocoon amends a destination URI, it also amends URIs for links in those pages, so that links 
+           will still work when a site has been crawled.</p>
+<div class="note">This feature substantially slows down page generation, as each page must be generated three times,
+              (once to find links, once to find its mime-type and once to collect the actual content. This 
+              can be avoided by ensuring that all URIs in the site are correct and do not need amending, in which
+              case it is only necessary to generate a page once.</div>
+    
+    
+<h1>Following Links and Site Crawling</h1>
+      
+<p>Cocoon can be configured to either follow, or ignore, links in pages that it generates. It has two methods
+      of gathering links, 'link view' and 'link gathering'.</p>
+      
+<h2>Link View Crawling</h2>
+<p>With link view crawling, Cocoon gets the links by generating the 'link view' for a page. Using link view
+           gives a significant degree of configurability in terms of which links are gathered, as it is possible to
+           insert a transformer into the view to select out links that should not be followed.</p>
+<p>The disadvantage with link view crawling is that each page must be generated twice, which doubles page 
+           generation time.</p>
+<p>Link view is usually configured in the root sitemap with:</p>
+<pre class="code">
+
+
+  &lt;map:views&gt;
+
+  &lt;map:view from-position="last" name="links"&gt;
+   &lt;map:serialize type="links"/&gt;
+  &lt;/map:view&gt;
+
+ &lt;/map:views&gt;
+
+        </pre>
+<p>If you have this in your root sitemap, you do not need it in your sub-sitemaps. However, you may choose
+           to override it with one that carries our further processing - for example, with an XSLT transformer that
+           removes links that should not be crawled.</p>
+<p>See <a href="../concepts/views.html">views</a> for more on views. </p>
+<p>You can see the link view yourself by appending <span class="codefrag">?cocoon-view=links</span> to the page's URI.</p>
+      
+<h2>Link Gathering Crawling</h2>
+<p>With link gathering crawling, links are gathered from the SAX stream right before the serializer. All 
+           <span class="codefrag">src</span>, <span class="codefrag">href</span> and <span class="codefrag">xlink:href</span> attributes are taken to be links, and are
+           therefore followed.</p>
+<p>The benefit of link gathering crawling is that pages do not need to be generated twice. However, one looses
+           the ability to configure which links should be followed that exists with link view crawling.</p>
+    
+    
+<h1>Broken Links</h1>
+      
+<p>When a page cannot be found at a URI that has either been specified, or has been found as a link in another
+         page, it is considered 'broken'.</p>
+      
+<p>Exactly what is done when a broken link is found depends upon the method used to evoke 
+         Cocoon. See related pages for specific details.</p>
+      
+<h2>Broken Link Handling using xconf Configuration method</h2>
+<p>The xconf method allows for more sophisticated broken link handling. The
+             user can select to have broken links reported to a file, this file being
+             either text or XML.</p>
+<p>When this file is plain text, it will have one link URI per line.</p>
+<p>When this file is in XML, it will detail a message explaining the reason
+           for the broken link, as well as the URI of the link.</p>
+<p>It is also possible to specify whether an error page should be generated 
+           in the place of the broken page (based upon the configured 
+           <span class="codefrag">&lt;map:handle-errors&gt;</span> code in the sitemap). If required,
+           an extension can be appended to the original file's URI to signify that
+           it is an error page (e.g. <span class="codefrag">.error</span>).</p>
+    
+    
+<h1>Precompiling XSPs</h1>
+      
+<p>When used offline, Cocoon can precompile XSP pages. If no URIs are specified, it will scan all directories
+         within the context directory looking for XSP files, each of which will be compiled. If URIs are specified,
+         all links will be followed looking for pages that make use of XSP, compiling those XSP pages as they are
+         found.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/meta.xml
new file mode 100644
index 0000000..4a0358a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-offline/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/offline/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/content_en.html
new file mode 100644
index 0000000..acfb8c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/content_en.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Overview of Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Tom Klaasen" name="DC.Creator">
+</head>
+<body> 
+	 
+<h1>What is Apache Cocoon</h1> 
+		
+<p>Cocoon is an XML publishing framework. It allows you to define XML
+		  documents and transformations to be applied on it, to eventually generate a
+		  presentation format of your choice (HTML, PDF, SVG, ...).</p> 
+		
+<p>Cocoon also gives you the possibility to apply logic to your XML files
+		  (so that the XML pipeline can be dynamic).</p> 
+
+    
+<p>The <a href="userdocs/index.html">User documentation</a>
+     and especially <a href="userdocs/concepts/index.html">Concepts</a>
+     will help to understand Cocoon.
+    </p>
+    
+
+   
+<a name="samples"></a>
+   
+<h1>Examples and demonstration applications</h1> 
+    
+<p>
+     There are a whole suite of sample applications to demonstrate the power
+     of Cocoon. These samples are available from the "welcome" page after
+     you have downloaded, built, and installed the distribution.
+     Each example portrays a different aspect of the vast capabilities of
+     Cocoon ...
+     <span class="codefrag">http://localhost:8080/cocoon/</span>
+    
+</p>
+
+    
+<div class="note">With the 2.1 version,
+     <span class="codefrag">http://localhost:8080/cocoon/</span> goes directly to the
+     documentation, while
+     <span class="codefrag">http://localhost:8080/cocoon/samples/</span> is the Samples.
+    </div>
+
+    
+<p>
+     It will greatly assist your understanding of Cocoon to investigate
+     behind-the-scenes, to find out how each sample is processed. Do this
+     by looking at the actual XML documents provided in the distribution at
+     <span class="codefrag">src/webapp/samples/</span> and by consulting each sitemap to see
+     the processing steps that are defined.
+    </p>
+    
+
+   
+<h1>Overview of XML document processing</h1> 
+    
+<p>This section gives a general overview of how an XML document is
+     handled by Cocoon. See also the document
+     <a href="userdocs/concepts/index.html">Understanding Cocoon</a> for explanation of
+     the separation of content, style, logic and management functions.
+    </p> 
+
+		
+<h2>Pipeline</h2>
+<p>Cocoon relies on the pipeline model: an XML document is pushed
+			 through a pipeline, that exists in several transformation steps of your
+			 document. Every pipeline begins with a generator, continues with zero or more
+			 transformers, and ends with a serializer. This can be compared to the
+			 "servlet-chaining" concept of a servlet engine. We'll explain the components of
+			 the pipeline now in more detail.</p>
+<h3>Generator</h3>
+<p>The Generator is the starting point for the pipeline. It is
+				responsible for delivering SAX events down the pipeline.</p>
+<p>The simplest Generator is the FileGenerator: it takes a local XML
+				document, parses it, and sends the SAX events down the pipeline. </p>
+<p>The Generator is constructed to be independent of the concept
+				"file". If you are able to generate SAX events from another source, you can use
+				that without having to go via a temporary file.</p>
+<h3>Transformer</h3>
+<p>A Transformer can be compared to an XSL: it gets an XML document
+				(or SAX events), and generates another XML document (or SAX events).</p>
+<p>The simplest Transformer is the XalanTransformer: it applies an
+				XSL to the SAX events it receives.</p>
+<h3>Serializer</h3>
+<p>A Serializer is responsible for transforming SAX events to a
+				presentation format. For actors looking at the back of the pipeline, it looks
+				like a static file is delivered. So a browser can receive HTML, and will not be
+				able to tell the difference with a static file on the filesystem of the server.
+				</p>
+<p>We have Serializers for generating HTML, XML, PDF, VRML, WAP, and
+				of course you can create your own.</p>
+<p>The simplest Serializer is the XMLSerializer: it receives the SAX
+				events from up the pipeline, and returns a "human-readable" XML file.</p> 
+	  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/meta.xml
new file mode 100644
index 0000000..9c57b9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-overview/meta.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <source>legacy.21</source>
+  <legacy>
+    <original-filename>overview.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/content_en.html
new file mode 100644
index 0000000..768bc0b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/content_en.html
@@ -0,0 +1,554 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to use the Paginator Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Stefano Mazzocchi" name="DC.Creator">
+</head>
+<body>
+	
+<h1>Overview</h1>
+  
+<p>
+This How-To describes the how to use Cocoon's Paginator Transformer component. You can consider it a 'FilterTransformer' on pagination steroids. The Paginator Transformer filters specific data and counts pages as it transforms SAX events. It implements pagination rules based on easy-to-configure pagesheet documents.
+  </p>
+	
+	
+<h1>Purpose</h1>
+  
+<p>
+XSLT-based approaches to pagination are problematic. First of all, it's somewhat complex to define the necessary declarative logic in XSLT. Additionally, an XSLT solution is rarely reusable across different pagination use cases. These problems spurred the creation of the Paginator Transformer. You can quickly add pagination capabilities to your webapp once you have configured a simple few rules within a single configuration file, the pagesheet.
+  </p>
+  
+<p>
+The Paginator Transformer works quite nicely for use cases involving a few tens of pages and, of course, for static generation of any number of pages. However, the Transformer must process an entire file before it can extract even a single page. Therefore, you are <strong>strongly</strong> advised against using it for books or other large documents on dynamic sites. Nevertheless, its output is cacheable. Thus, if the same page is requested, then the document will be reprocessed by the Transformer only when it has changed.
+  </p>
+	
+	
+<h1>Intended Audience</h1>
+  
+<p>
+Cocoon users who need pagination capabilities for their web documents. This includes frustrated users who are tired of implementing complex, XSLT-based approaches to pagination.
+  </p>
+	
+	
+<h1>Prerequisites</h1>
+  
+<p>
+Make sure you have the version 2.1 or greater of Cocoon. The PaginatorTransformer component source is located in the core area. 
+  </p>
+  
+<p>
+During the build process, the necessary configuration details for the PaginatorTransformer component are automatically copied to cocoon.xconf of cocoon.war. This means that you don't need to manually configure cocoon.xconf. However, if you are adding the paginator samples to Cocoon webapp that was <strong>not</strong> generated by the above build command, add the following snippet to your cocoon.xconf file, located in the WEB-INF directory of your deployed webapp.
+  </p>
+  
+<p>
+Version 2.1:
+  </p>
+    
+<pre class="code">
+  &lt;paginator 
+     class="org.apache.cocoon.transformation.pagination.Paginator" 
+     role="org.apache.cocoon.transformation.pagination.Paginator"
+     logger="core.paginator"/&gt;
+   /&gt;</pre>
+  
+<p>
+Sample files, not directly related to this How-To, are also copied during the build process to Cocoon webapp at webapp/samples/paginator. You can access them in your web browser using the following URI: 
+ </p>
+  
+<pre class="code">
+http://localhost:8888/samples/paginator/
+  </pre>
+	
+	
+	
+<h1>Steps</h1>
+  
+<p>
+Let's start with a simple example.
+  </p>
+		
+<h2>Simple Example</h2>
+<p>
+Suppose you have an XML file, document.xml, as follows. 
+	  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;images&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+    &lt;image /&gt;
+&lt;/images&gt;
+    </pre>
+<p>
+First, you need to write a <strong>pagesheet.</strong> Just as a stylesheet contains instructions for an xslt processor, a pagesheet contains instructions for the paginator filter. Here is the pagesheet dtd.
+  </p>
+<pre class="code">
+&lt;!ELEMENT pagesheet (items?, rules)*&gt;
+&lt;!ATTLIST pagesheet xmlns CDATA #IMPLIED&gt;
+
+&lt;!ELEMENT items (group)&gt;
+
+&lt;!ELEMENT group EMPTY &gt;
+&lt;!ATTLIST group 
+   name CDATA #IMPLIED 
+   element CDATA #IMPLIED &gt;
+
+&lt;!ELEMENT rules (link?, count?)*&gt;
+
+&lt;!ELEMENT link EMPTY &gt;
+&lt;!ATTLIST link 
+   type ( unit | range ) #REQUIRED 
+   num CDATA #REQUIRED 
+ &gt;
+ 
+ &lt;!ELEMENT count EMPTY &gt;
+ &lt;!ATTLIST count 
+   type ( element | char ) #REQUIRED 
+   num CDATA #REQUIRED 
+   name CDATA #IMPLIED 
+   namespace CDATA #IMPLIED 
+ &gt;
+    </pre>
+<p>
+Let's say you want to paginate document.xml content based on a rule of three &lt;image&gt; elements per page. Here's a sample pagesheet, images.xml, which does just that.
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;pagesheet xmlns="http://apache.org/cocoon/paginate/1.0"&gt;
+	&lt;rules&gt;
+		&lt;count type="element" name="image" num="3" /&gt;
+	&lt;/rules&gt;
+&lt;/pagesheet&gt;
+    </pre>
+<p>
+You process a source file through a pagesheet filter in a sitemap snippet like this:
+	  </p>
+<pre class="code">
+&lt;map:match pattern="page(*)"&gt;
+  &lt;map:generate src="document.xml"/&gt;
+  &lt;map:transform src="pagesheets/images.xml" type="paginator"&gt;
+	&lt;map:parameter name="page" value="{1}"/&gt;
+  &lt;/map:transform&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+    </pre>
+<p>
+Accessing the URI for page one, page(1) yields:
+	  </p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8" ?&gt; 
+&lt;images xmlns:page="http://apache.org/cocoon/paginate/1.0"&gt;
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;page:page 
+     current="1" 
+     total="3" 
+     current-uri="/cocoon/samples/paginator/page(1)" 
+     clean-uri="/cocoon/samples/paginator/page" /&gt; 
+&lt;/images&gt;
+
+
+    </pre>
+<p>
+Clearly the above XML could have been transformed into something more meaningful. Note that the transformer must process all pages to obtain the value of <span class="codefrag">total</span>. Currently, there is no way to avoid this.
+	  </p>
+			
+			
+<h2>Adding Navigation</h2>
+<p>
+Given the Paginator's a full-blown pagesheet language, there's even more we can accomplish, most importantly, navigation.
+		  </p>
+<p>
+As an example, consider the following pagesheet, images2.xml.
+		  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;pagesheet xmlns="http://apache.org/cocoon/paginate/1.0"&gt;
+&lt;items&gt;
+  &lt;group name="item" element="images" /&gt;
+ &lt;/items&gt; 
+ &lt;rules&gt;
+    &lt;rules&gt;
+      &lt;count type="element" name="image" num="3"/&gt;
+      &lt;link type="unit" num="1"/&gt;
+    &lt;/rules&gt;
+ &lt;/rules&gt;
+&lt;/pagesheet&gt;
+
+    </pre>
+<p>
+The pagesheet rules demonstrate that the transformer understands how the page was encoded in the given URI request, i.e., that parentheses surround the value of page. They also reveal that the transformer can provide navigation links to available pages, in this case, plus or minus one position.
+  </p>
+<div class="fixme">DS:
+      
+In the above paragraph, you say the transformer understand how the page was encoded. How? I don't see the evidence until the snippet produced below.
+	</div>
+<p>
+In your sitemap.xmap file, if you change the pagesheet source to images2.xml as follows:
+  </p>
+<pre class="code">
+&lt;map:match pattern="page(*)"&gt;
+	&lt;map:generate src="document.xml" /&gt;
+	&lt;map:transform src="pagesheets/images2.xml" type="paginator"&gt;
+		&lt;map:parameter name="page" value="{1}" /&gt;
+	&lt;/map:transform&gt;
+	&lt;map:serialize type="xml" /&gt;
+&lt;/map:match&gt;
+    </pre>
+<p>
+processing the same page(1) request yields the following (pretty-printed for this document):
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;images xmlns:page="http://apache.org/cocoon/paginate/1.0"&gt;
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;page:page 
+    current="1" 
+    total="3" 
+    current-uri="/cocoon/samples/paginator/page(1)" 
+    clean-uri="/cocoon/samples/paginator/page"&gt;
+  &lt;page:link 
+     type="next" 
+     uri="/cocoon/samples/paginator/page(2)" 
+     page="2" /&gt; 
+  &lt;/page:page&gt;
+&lt;/images&gt;
+
+    </pre>
+<p>
+This result demonstrates:
+  </p>
+<ul>
+	
+<li>
+Page 0 does not exist, so no &lt;page:link&gt; is created for a previous page.
+	</li>
+	
+<li>
+Page 2 exists, so &lt;page:link&gt; is created, along with 
+		<ul>
+		  
+<li>
+a value of "next" for its type attribute (useful for visualization), and
+		  </li>
+		  
+<li>
+a value of page(2) for its URI attribute (useful for linking without XSLT-specific logic)
+		  </li>
+		
+</ul>
+		
+</li>
+		
+</ul>
+<p>
+Note that the URI is re-encoded using the same parentheses pattern, page(2).
+  </p>
+<p>
+Now, without changing anything, requesting page(2) yields the following (pretty-printed for this document):
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;images xmlns:page="http://apache.org/cocoon/paginate/1.0"&gt;
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;image /&gt; 
+  &lt;page:page 
+      current="2" 
+      total="3" 
+      current-uri="/cocoon/samples/paginator/page(2)" 
+      clean-uri="/cocoon/samples/paginator/page"&gt;
+    &lt;page:link type="prev" uri="/cocoon/samples/paginator/page(1)" page="1" /&gt; 
+    &lt;page:link type="next" uri="/cocoon/samples/paginator/page(3)" page="3" /&gt; 
+  &lt;/page:page&gt;
+&lt;/images&gt;
+    </pre>
+<p>
+And requesting page(3) yields the following.
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;images xmlns:page="http://apache.org/cocoon/paginate/1.0"&gt;
+  &lt;image /&gt; 
+  &lt;page:page 
+     current="3" 
+     total="3" 
+     current-uri="/cocoon/samples/paginator/page(3)" 
+     clean-uri="/cocoon/samples/paginator/page"&gt;
+  &lt;page:link 
+     type="prev" 
+     uri="/cocoon/samples/paginator/page(2)" 
+     page="2" /&gt; 
+  &lt;/page:page&gt;
+&lt;/images&gt;</pre>
+<p>
+Note only one &lt;image&gt;. The original document, images.xml, only contained seven &lt;image&gt; elements: three for page one, three for page two, but only one for page three. Thus, the result here is the modulo (or remainder) of the division.
+  </p>
+	
+	
+<h2>Real-Life Examples</h2>
+<p>
+Here are a few pagesheets examples which are a bit more complex.
+  </p>
+<h3>DirectoryGenerator Pagination</h3>
+<p>
+Here's an example of paginating the contents of a directory using the DirectoryGenerator.
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;pagesheet xmlns="http://apache.org/cocoon/paginate/1.0"&gt;
+	&lt;rules&gt;
+		&lt;count type="element" name="file" 
+		  namespace="http://apache.org/cocoon/directory/2.0" 
+		  num="16" /&gt;
+		&lt;link type="unit" num="2" /&gt;
+		&lt;link type="range" value="5" /&gt;
+	&lt;/rules&gt;
+&lt;/pagesheet&gt;
+    </pre>
+<p>
+The rules state:
+  </p>
+<ol>
+		
+<li>
+paginate 16 files per page
+		</li>
+		
+<li>
+provide links to +/- 1 and +/- 2 pages (when available)
+		</li>
+		
+<li>
+provide links to +/- 5 (when available)
+		</li>
+	
+</ol>
+<p>
+So, suppose we have a directory with 300 files. If we request page 10, the generated page will be:
+	  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;dir:directory&gt;
+	&lt;dir:file ... /&gt;
+		[other 15 dir:file] 
+	&lt;page:page 
+	     xmlns:page="http://apache.org/cocoon/paginate/1.0" 
+	     current="10" 
+	     total="19" 
+	     current-uri="dir(10)" 
+	     clean-uri="dir" &gt;
+	  &lt;page:range-link page="5" type="prev" uri="page(5)" /&gt;
+	  &lt;page:link page="8" type="prev" uri="page(8)" /&gt;
+	  &lt;page:link page="9" type="prev" uri="page(9)" /&gt;
+	  &lt;page:link page="11" type="next" uri="page(11)" /&gt;
+	  &lt;page:link page="12" type="next" uri="page(12)" /&gt;
+	  &lt;page:range-link page="15" type="next" uri="page(15)" /&gt;
+	&lt;/page:page&gt;
+&lt;/dir:directory&gt;
+    </pre>
+<h3>Asymmetric pagination</h3>
+<p>
+We also have the ability to indicate different rules for each page, for example:
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;pagesheet xmlns="http://apache.org/cocoon/paginate/1.0"&gt;
+	&lt;rules page="1"&gt;
+		&lt;count type="element" name="b" num="5" /&gt;
+		&lt;link type="unit" num="1" /&gt;
+	&lt;/rules&gt;
+	&lt;rules&gt;
+		&lt;count type="element" name="b" num="10" /&gt;
+		&lt;link type="unit" num="2" /&gt;
+	&lt;/rules&gt;
+&lt;/pagesheet&gt;
+    </pre>
+<h3>Count types</h3>
+<p>
+The Paginator Transformer was designed to count. However, it's up to you to define what needs to be counted, either XML elements or characters (not yet implemented). By supplying values to the attributes of &lt;count&gt; in the pagesheet, you can specify exactly what needs to be counted.
+  </p>
+<p>
+The &lt;count&gt; element has two required and two optional attributes. The required attributes are:
+  </p>
+<ul>
+     
+<li>
+
+<strong>type</strong> the method of counting the paginator should perform, either elements or characters. 
+When element is specified, the transformer counts startElement() SAX events. When chars is specified (currently not implemented), the transformer counts the primitive data type char.
+     </li>
+     
+<li>
+
+<strong>num</strong> a number which how many times counted item (element or chars) must be present within the transformed page.
+     </li>
+   
+</ul>
+<p>
+Optional attributes (when type="element" is specified) are:
+  </p>
+<ul>
+      
+<li>
+
+<strong>name</strong> the name of the element, without any namespace prefix
+      </li>
+      
+<li>
+
+<strong>namespace</strong> the URI of the namespace. If not specified, the default namespace is used.
+      </li>
+   
+</ul>
+  
+  
+  
+<h1>Improving the Paginator Transformer</h1>
+
+  
+<p>
+The PaginatorTransformer was developed, initially, to paginate a directory listing. It 
+works great when it paginates by counting elements, particularly elements which contain similar amounts of content to be displayed on pages. With documents, for example, it could paginate by counting sections or subsections. However, bear in mind that this approach does not always guarantee visually-balanced web pages.
+  </p>
+  
+
+<h2>Nested Pagination</h2>
+<p>
+Furthermore, simply counting elements is not always simple. Consider the following:
+  </p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+ &lt;a&gt;
+  &lt;b&gt;
+   &lt;a&gt;
+    &lt;b&gt;
+     &lt;a&gt;
+      &lt;b/&gt;
+     &lt;/a&gt;
+    &lt;/b&gt;
+   &lt;/a&gt;
+  &lt;/b&gt;
+ &lt;/a&gt;
+    </pre>
+<p>
+Let's say you want to paginate using one &lt;b&gt; per page. What should the transformed pages look like? Here's a few possible outcomes. Which one is the best? 
+  </p>
+<h3>Page 1</h3>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+ &lt;a&gt;
+  &lt;b&gt;
+   &lt;a&gt;
+    &lt;a/&gt;
+   &lt;/a&gt;
+  &lt;/b&gt;
+ &lt;/a&gt;
+    </pre>
+<h3>Page 2</h3>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+ &lt;a&gt;
+  &lt;a&gt;
+   &lt;b&gt;
+    &lt;a/&gt;
+   &lt;/b&gt;
+  &lt;/a&gt;
+ &lt;/a&gt;
+    </pre>
+<h3>Page 3</h3>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+ &lt;a&gt;
+  &lt;a&gt;
+   &lt;a&gt;
+    &lt;b/&gt;
+   &lt;/a&gt;
+  &lt;/a&gt;
+ &lt;/a&gt;
+    </pre>
+<p>
+It appears the current code is buggy somewhere. With deep
+nesting as in this example, some SAX events are lost. This 
+creates a non-well-formed SAX stream which chokes subsequent
+transformers, such as XSLT, which may be sensitive to well-formedness.
+  </p>
+<p>
+Does the above might look like a mental exercise to you? Perhaps, but consider 
+the structure of Cocoon Project's Document DTD 1.1. which includes nested &lt;section&gt; elements. Similar problems will emerge when paginating these documents based on this dtd. 
+It's isn't clear whether the solution adopted above is meaningful or not for a real-world  pagination. Suggestions on this are welcome.
+  </p>
+  
+
+<h2>Character-based Pagination</h2>
+<p>
+Given the need to visually balance pages, a counting method for characters was added, even though it isn't implemented yet. Counting by characters is especially difficult when you think about the algorithms that perform chunking. 
+  </p>
+<p>
+Assume you have a document like this:
+  </p>
+<pre class="code">
+ &lt;p&gt;this is some &lt;strong&gt;text&lt;/strong&gt; that happens 
+ to be &lt;em&gt;chuncked&lt;/em&gt;&lt;/p&gt;
+             ^
+    </pre>
+<p>
+Suppose that paginating by counting the chars results in a chunking point
+indicated by the caret above (between the letters u and n). 
+Ending a page at that position results in XML that is not well-formed as well as
+truncated words. Even if you find a way to provide well-formed XML, 
+you still must deal with word-break issues. Therefore, we need a way to 
+produce well-formed XML by continuing until the first 'block-level' element is encountered, for example, 
+&lt;p&gt; in this case. However, this means that the pagesheet must contain a list of
+such 'block-delimiting' elements. Currently, the Pagesheet parser and
+object model does <strong>not</strong> support this notion.
+  </p>
+<p>
+Conclusion? Pagination at the char level is not trivial and will require a
+little bit of additional work on the transformer.
+  </p>
+  
+
+<h2>Other Improvements</h2>
+<p>
+One possible way to improve the concept is to count by XPath results. For example,
+you may want to count &lt;section&gt; elements included in other &lt;section&gt; elements. Another way to improve the design is to allow booleans to be used within counting
+rules. For example, you could count &lt;session&gt; AND &lt;chapter&gt; elements. Most likely, XPath will help here as well.
+  </p>
+  
+  
+  
+<h1>Comments</h1>
+
+<p>
+Got an idea how to improve the Paginator Transformer? Post it to the <a href="mailto:dev.at.cocoon.apache.org?subject=Paginator:">cocoon-dev</a> mailing list. Care to comment on this How-To? Help keep this document relevant by passing along any constructive feedback to the <a href="mailto:docs.at.cocoon.apache.org?subject=Paginator:">cocoon-docs</a> mailing list.
+  </p>
+  
+  
+<h1>Revisions</h1>
+  
+<p>
+06-06-02: Content originally posted to cocoon-dev by Stefano Mazzocchi. 
+  </p>
+  
+<p>
+06-26-02: Edited and structured by Diana Shannon. Scratchpad samples also added.
+  </p>
+  
+<p>
+06-27-02: Scratchpad samples revised by Stefano Mazzocchi.
+  </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/meta.xml
new file mode 100644
index 0000000..cbc6ffa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-paginator-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-paginator-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/content_en.html
new file mode 100644
index 0000000..bd062cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/content_en.html
@@ -0,0 +1,178 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Parameter Selector</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in @doctitle@" name="DC.Subject">
+<meta content="Beth Naquin" name="DC.Creator">
+<meta content="This document describes the Parameter Selector." name="DC.Description">
+</head>
+<body>
+  
+<h1>Parameter Selector</h1>
+   
+   
+<ul>
+    
+<li>Name : ParameterSelector</li>
+    
+<li>Class: org.apache.cocoon.selection.ParameterSelector</li>
+    
+<li>Cacheable: not applicable</li>
+   
+</ul>
+   
+   
+<p>
+    This Selector matches a string, in the Parameters object passed to the 
+    selector, against a specified Cocoon internal parameter.  It performs a 
+    case-sensitive string comparison between the value of the 
+    'parameter-selector-test' parameter and the value of the 'test' 
+    attribute of the <span class="codefrag">&lt;map:when ...&gt;</span> element.
+   </p>
+   
+   
+<p>
+   This internal parameter could be:
+   </p>
+   
+<ul>
+    
+<li>A sitemap parameter from the <span class="codefrag">&lt;map:match ...&gt;</span> portion of the pipeline</li>
+    
+<li>A sitemap parameter set by an action</li>
+   
+</ul>
+   
+   
+   
+   
+<h1>Reasons to use ParameterSelector</h1>
+   
+<p>
+   One purpose of this selector is to choose between different components 
+   of a pipeline based on sitemap parameters set by an action.  This would 
+   allow the action to control the logic required to set one or more parameters, 
+   which can then be used by this selector to control pipeline processing.  
+   Thus, complex decision-making logic can be contained in actions, while the 
+   sitemap simply uses the results of the actions (the parameters) to determine 
+   pipeline processing.
+   </p>
+   
+<p>
+   Parameter Selector can also be used to select on the value of 'keys' 
+   (such as {1} or {../2} ) from the wildcard matcher.  Information in the 
+   URI, such as part of a filename, can then be used to determine pipeline 
+   processing.   
+   </p>
+   
+   
+   
+<h1>Examples</h1>
+   
+<p>
+   Add the component to your sitemap.xmap:
+   </p>
+   
+<pre class="code">
+   &lt;map:components&gt;
+    ...
+    &lt;map:selectors&gt;
+     ...
+     &lt;map:selector
+      name="parameter"
+        logger="sitemap.selector.parameter"
+        src="org.apache.cocoon.selection.ParameterSelector"/&gt;
+     ...</pre>
+   
+   
+<p>
+   Use a parameter set by an action:
+   </p>
+   
+<p>
+    Assume there is an action (named MyAction) that sets a parameter 
+    (named MyRegion) to several possible values.  For more information on actions, 
+    including a simple example of an action that creates a sitemap parameter, see
+    <a href="../concepts/actions.html">Creating and Using Actions</a>.
+   </p>
+   
+<pre class="code">
+   &lt;map:match pattern="*.xml"&gt;
+    &lt;map:act type="MyAction"&gt;
+      &lt;map:generate src="{../1}.xml"/&gt;
+
+      &lt;map:select type="parameter"&gt;
+        &lt;map:parameter name="parameter-selector-test" value="{MyRegion}"/&gt;
+      
+        &lt;!-- executes iff the value of MyRegion equals 
+             "United States" (without quotes) --&gt;
+        &lt;map:when test="United States"&gt;
+          &lt;map:transform src="stylesheets/us.xsl"/&gt;
+        &lt;/map:when&gt;
+      
+        &lt;map:when test="South_America"&gt;
+          &lt;map:transform src="stylesheets/southamerica.xsl"/&gt;
+        &lt;/map:when&gt;
+
+        &lt;map:when test="Europe"&gt;
+          &lt;map:transform src="stylesheets/europe.xsl"/&gt;
+        &lt;/map:when&gt;
+
+        &lt;map:otherwise&gt;
+          &lt;map:transform src="all_others.xsl"
+        &lt;/map:otherwise&gt;
+
+      &lt;/map:select&gt;
+    &lt;/map:act&gt;
+    &lt;map:serialize/&gt;
+  &lt;/map:match&gt;</pre>
+   
+   
+<p>
+   Use values from the URI:
+   </p>
+   
+<pre class="code">
+   &lt;map:pipeline&gt;
+     &lt;!-- {1}/{2}/myfile.xml --&gt;
+     &lt;map:match pattern="**/*/myfile.xml"&gt; 
+   
+       &lt;!-- Use ParameterSelector --&gt;
+       &lt;map:select type="parameter"&gt;
+        &lt;map:parameter name="parameter-selector-test" value="{2}"/&gt;
+
+        &lt;!-- executes iff the value of {2} equals 
+             "basic" (without quotes); the requested URI
+              could be **/basic/myfile.xml --&gt;
+        &lt;map:when test="basic"&gt;
+            &lt;map:generate src="{1}/myfile.xml"/&gt;
+            &lt;map:transform src="stylesheets/basic.xsl"&gt;
+                &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+                &lt;map:parameter name="resource" value="{2}.html"/&gt;
+            &lt;/map:transform&gt;
+            &lt;map:serialize/&gt;
+        &lt;/map:when&gt;
+
+        &lt;map:when test="aggregate"&gt;
+            &lt;map:aggregate element="site"&gt;
+          &lt;map:part src="cocoon:/{1}/sidebar-{1}/{2}.xml"/&gt;
+          &lt;map:part src="cocoon:/body-{1}/{2}.xsp"/&gt;
+            &lt;/map:aggregate&gt;
+            &lt;map:transform src="stylesheets/aggregate2xhtml.xsl"/&gt;
+            &lt;map:serialize/&gt;
+        &lt;/map:when&gt;
+
+        &lt;map:otherwise&gt;
+            &lt;map:redirect-to uri="other_URI"/&gt;
+        &lt;/map:otherwise&gt;
+
+      &lt;/map:select&gt;
+    &lt;/map:match&gt; 
+    ...</pre>
+   
+   
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/meta.xml
new file mode 100644
index 0000000..afef5db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parameter-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/parameter-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/content_en.html
new file mode 100644
index 0000000..6582f1d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/content_en.html
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Parent Service Manager</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Leo Sutic" name="DC.Creator">
+<meta content="This document describes how to use a parent service manager in Cocoon." name="DC.Description">
+</head>
+<body>
+            
+<h1>Parent Service Manager</h1>
+                
+<p>When using Apache Cocoon it is sometimes neccessary to obtain
+                    components from other sources than the <span class="codefrag">user.roles</span> file,
+                    or preferable to have a common component manager for several web applications.</p>
+                
+                
+<p>The pattern chosen for Cocoon is the dynamic loading of a service manager class.
+                    The initialization parameter parent-service-manager in web.xml specifies a class
+                    that will be loaded, instantiated and used as a parent service manager for 
+                    Cocoon's serivce manager.</p>
+                
+                
+<p>The recommended procedure is for the class, when it is initialized, to create a 
+                    delegate in the form of an <span class="codefrag">CocoonServiceManager</span>, configure it
+                    by looking up a <span class="codefrag">Configuration</span> object via JNDI, and delegate any requests to it.</p>
+                
+                
+<p>In order to provide a way to pass parameters to the parent service manager class 
+                    (the class specified in parent-service-manager), Cocoon will instantiate the class
+                    via the constructor that takes a single <span class="codefrag">String</span> argument, passing
+                    anything to the right of the first <span class="codefrag">'/'</span> in the parameter value to the
+                    constructor. Subsequently Cocoon examines whether the class implements 
+                    <span class="codefrag">org.apache.avalon.framework.logger.LogEnabled</span> and/or 
+                    <span class="codefrag">org.apache.avalon.framework.activity.Initializable</span> and calls
+                    <span class="codefrag">setLogger</span> and/or <span class="codefrag">initialize</span>, as appropriate.
+                    The instance is then used as a parent service manager.
+                </p>
+                                
+                
+<p>Since that didn't make much sense in itself, let's look at the sample.</p>
+                
+                
+<p>The goal is to define a component that can give us the time of day and
+                    let it be managed by a parent service manager.</p>
+                
+                
+<p>So, first we need to put a Configuration object into JNDI, and then 
+                    grab that object, use it to configure an CocoonServiceManager,
+                    and pass on any requests to that manager.</p>
+                
+                
+<h2>Step 1: Creating a configuration object</h2>
+<p>We'll do this the quick and dirty way. The static initializer of a class
+                        will create a Configuration instance with a single role and bind it
+                        to <span class="codefrag">org/apache/cocoon/samples/parentcm/ParentCMConfigration</span>.
+                    </p>
+<p>The following code was taken from org/apache/cocoon/samples/parentcm/Configurator.java</p>
+<pre class="code">
+public class Configurator  {
+
+    static {
+        try {
+            //
+            // Create a new role.
+            //
+            DefaultConfiguration config = new DefaultConfiguration("roles", "");
+            DefaultConfiguration timeComponent = new DefaultConfiguration("role", "roles");
+            timeComponent.addAttribute("name", Time.ROLE);
+            timeComponent.addAttribute("default-class", TimeComponent.class.getName());
+            timeComponent.addAttribute("shorthand", "samples-parentcm-time");
+            config.addChild(timeComponent);
+            
+            //
+            // Bind it - get an initial context.
+            //
+            Hashtable environment = new Hashtable();
+            environment.put(Context.INITIAL_CONTEXT_FACTORY, 
+                            MemoryInitialContextFactory.class.getName());
+            initialContext = new InitialContext(environment);
+            
+            //
+            // Create subcontexts and bind the configuration.
+            //
+            Context ctx = initialContext.createSubcontext("org");
+            ctx = ctx.createSubcontext("apache");
+            ctx = ctx.createSubcontext("cocoon");
+            ctx = ctx.createSubcontext("samples");
+            ctx = ctx.createSubcontext("parentcm");
+            ctx.rebind("ParentCMConfiguration", config);
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+    }    
+}</pre>
+<p>To make sure the static initializer runs we make Cocoon force-load the class
+                    by making a change to the web.xml file:</p>
+<pre class="code">
+&lt;init-param&gt;
+  &lt;param-name&gt;load-class&lt;/param-name&gt;
+  &lt;param-value&gt;
+    &lt;!-- For IBM WebSphere: 
+    com.ibm.servlet.classloader.Handler --&gt;
+
+    &lt;!-- For Database Driver: --&gt;
+    @database-driver@
+        
+    &lt;!-- For parent ServiceManager sample:
+            This will cause the static initializer to run,
+            and thus the Configuration object to be created
+            and bound. --&gt;
+    org.apache.cocoon.samples.parentcm.Configurator 
+  &lt;/param-value&gt;
+&lt;/init-param&gt;</pre>
+                
+                
+<h2>Step 2: Write the service manager</h2>
+<p>Now that the configuration object is sitting there waiting for us, let's craft
+                        the component manager. Please see the file org/apache/cocoon/samples/parentcm/ParentServiceManager.java
+                        for an example. It is too much to paste in here.</p>
+                    
+                
+<h2>Step 3: Tell Cocoon to use the service manager</h2>
+<p>Change the web.xml file to:</p>
+<pre class="code">
+&lt;init-param&gt;
+  &lt;param-name&gt;parent-service-manager&lt;/param-name&gt;
+  &lt;param-value&gt;org.apache.cocoon.samples.parentcm.ParentServiceManager/(remove this line break)
+org/apache/cocoon/samples/parentcm/ParentCMConfiguration&lt;/param-value&gt;
+&lt;/init-param&gt;</pre>
+<p>Cocoon will now do the following: First, it will split the parameter value at the first slash,
+                        in this case ending up with the strings <span class="codefrag">"org.apache.cocoon.samples.parentcm.ParentServiceManager"</span>
+                        and <span class="codefrag">"org/apache/cocoon/samples/parentcm/ParentCMConfiguration"</span>. The first string is the 
+                        class to instantiate. The second is the parameter that will be passed to the constructor.</p>
+<p>Next, Cocoon loads the component manager class and uses reflection to find a constructor that
+                        will accept a single <span class="codefrag">String</span> argument. Upon finding one, it instantiates the
+                        class in a manner similar to:</p>
+<pre class="code">
+ServiceManager cm = new 
+    org.apache.cocoon.samples.parentcm.ParentServiceManager(
+        "org/apache/cocoon/samples/parentcm/ParentCMConfiguration");</pre>
+<p>
+                        After this Cocoon checks whether the parent service manager class implements <span class="codefrag">Initializable</span> and/or
+                        <span class="codefrag">LogEnabled</span>. Since the <span class="codefrag">ParentServiceManager</span> class implements both, Cocoon
+                        does the following (with simplification):
+                    </p>
+<pre class="code">
+((LogEnabled) cm).enableLogging(logger);
+((Initializable) cm).initialize();</pre>
+<p>Finally, the instance is used as parent service manager of Cocoon's own service manager.</p>
+                
+                
+<h2>Step 4: Use the component</h2>
+<p>Cocoon components can now use the ServiceManager given to them by Cocoon to look up the
+                        component managed by the parent service manager:</p>
+<p>The following code was taken from org/apache/cocoon/samples/parentcm/Generator.java</p>
+<pre class="code">
+public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+            
+    Time timeGiver = null;
+    try {
+        timeGiver = (Time) manager.lookup(Time.ROLE);
+        this.time = timeGiver.getTime ();
+    } catch (ServiceException ce) {
+        throw new ProcessingException ("Could not obtain current time.", ce);
+    } finally {
+        manager.release(timeGiver);
+    }
+}</pre>
+                
+                
+<p>And that concludes the tour. A parent service manager was initialized with a configuration
+                    obtained via JNDI and its components used by a Cocoon generator.</p>
+            
+        
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/meta.xml
new file mode 100644
index 0000000..6b65518
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-parent-component-manager/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/parent-component-manager.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/content_en.html
new file mode 100644
index 0000000..f37bde3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/content_en.html
@@ -0,0 +1,275 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apache Cocoon Performance Tips</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gerhard Froehlich" name="DC.Creator">
+</head>
+<body>
+ 
+ 
+<h1>Disclaimer</h1>
+   
+<p>The Cocoon Performance Tips in this version is a loose collection of
+   usenet articles regarding how to improve the Apache Cocoon performance.</p>
+   
+<p>As in the real world, it needs some kind of evolution to get better.
+   If you have suggestions how to make it better or new kool tips, then be brave and
+   send it to the <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">
+   Cocoon Mailing Lists</a>!</p>
+   
+<div class="note">Sometimes the tips maybe doubled or contradictory. If you notice something
+   like that, then send a note to the <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">
+   Cocoon Mailing Lists</a>.</div>
+ 
+ 
+ 
+<h1>Common</h1>
+   
+<ul>
+      
+<li>Logging kills performance. Consider disabling logging entirely from
+      Cocoon (leave only the ERROR channel) and let Apache or the servlet
+      container log accesses and stuff.</li>
+      
+      
+<li>Use a transparent proxy in front of your web server! The fastest
+      response is the one that is not even processed. Cocoon is very slow
+      (compared to a proxy server) to read resources such as stylesheets and
+      images. A transparent proxy (SQUID, for example, don't use Apache 1.3
+      mod_proxy because it is not fully compatible with HTTP/1.1 and disables
+      connection keep-alive - Apache 2 mod_proxy is fine).
+      Make sure you tune how long the static resources
+      that Cocoon "read"s from the sitemap are cached (look into the readers
+      code to find out more).</li>
+      
+      
+<li>Consider prerendering or time-based batch-process the static parts
+      of your site. PDF reports, rasterized SVG graphs or things that change
+      regularly.</li>
+      
+      
+<li>For optimum performance with Tomcat 4 and Cocoon 2, 
+      use the HTTP/1.0 connector.</li>
+      
+      
+<li>Move static content out of Cocoon's control. Move your static content out of the 
+      Cocoon servlet context and into its own context (just letting Tomcat serve directly). 
+      An even better approach would be to use a front-end webserver to serve the static, but 
+      installing Apache + Tomcat + our Cocoon app would be a bit much when Tomcat + our Cocoon 
+      app is doing fine.</li>
+
+      
+<li>Disable resource reloading. The disk I/O system could become the
+      bottleneck.</li>
+
+      
+<li>Search for messages such as "decommissioning instance of...". This reveals some 
+      undersized pools which are corrected by tuning cocoon.xconf and sitemap.xmap. 
+      Undersized pools act like an object factory, plus the ServiceManager
+      overhead.</li>
+   
+</ul> 
+ 
+ 
+ 
+<h1>Caching and Pooling</h1>
+   
+<ul>
+     
+<li>Fine-tune the pool sizes for components in the files cocoon.xconf and
+     sitemap.xmap. If the pools are too small for the load this will have a great
+     impact on your performance. The goal is to achieve such a configuration that for 
+     every request there is a free component in the pool. Suppose, you have up 
+     to 100 simultaneous requests and your pipelines have up to 2 xslt 
+     transformers, then you need to set the maximum pool size to 200 xslt 
+     transformers. They will be created when needed and retained to the pool 
+     for future use.
+     </li>
+   
+     
+<li>Fine-tune the Cocoon settings for the store and the other stuff.</li>
+
+     
+<li>Important is the size of the documents that will be cached, because
+     caching appears to be very time consuming process.</li>
+
+     
+<li>Use the Caching Pipelines in your sitemaps where relevant.</li>
+     
+<li>If your cache is set too small to keep the entire XML in memory,
+      then the cache will be of no benefit.</li>
+
+     
+<li>Watch the cachability in the log files, and make sure that things
+      are being fed from the cache.</li>
+     
+<li>Only use dynamic data when it is needed. Dynamic pages can't be
+      cached 100%.</li>
+
+     
+<li>Don't put Cocoon webapp too deep into directory structure. Cache
+     keys contain absolute file names (or hash values of the absolute file
+     names - in 2.0.X series), and the deeper cocoon is located in the
+     filesystem, the longer keys are becoming. Obviously, longer keys will
+     take more time to process them. In worst case scenario, slowdown up to
+     10% could be achieved (unscientific observations, do your own
+     test).</li>
+     
+   
+</ul>
+     
+<p>More information about caching can be found 
+       <a href="userdocs/concepts/caching.html">in the Caching documentation</a>.
+       Especially look at the information about the expires configuration.
+     </p>
+ 
+ 
+ 
+<h1>JVM and OS</h1>
+   
+<ul>
+      
+<li>Consider using a good JVM on a good OS. Scalability is a very
+      different beast than pure speed. An Apple DualG4 866 seems to run faster
+      than a Sun Enterprise 4500 (and costs a fraction), but try hitting them
+      with 2000 concurrent Cocoon requests.</li>
+
+      
+<li>Fine-tune your JVM settings (max heap-size, initial memory, s.o.).
+      Please read the <a class="external" href="http://java.sun.com/docs/hotspot/PerformanceFAQ.html">Java Performance
+      FAQ's</a> and the <a class="external" href="http://java.sun.com/docs/hotspot/gc/index.html">Tuning
+      Garbage Collection</a> Document.</li>
+
+      
+<li>Don't specify the -Xms parameter.</li>
+
+      
+<li>Set the <span class="codefrag">-Xnoclassgc</span> parameter on the Sun JDK 1.3.1!
+      It reduces the frequency of need for garbage collection by permitting the 
+      memory allocated to unused classes to be reused (instead of having to be 
+      collected and/or compacted).  Less fragmentation means less collection
+      means better response times.</li>
+   
+</ul>
+ 
+ 
+ 
+<h1>Perfomance Formulas</h1>
+   
+<ul>
+     
+<li>Consider following formula for Pipeline Processing:<br>
+     
+<span class="codefrag">Number_of_simultaneous_users * depth_of_content_aggregation</span>
+     
+</li>
+
+     
+<li>Consider following formula for Generators/Transformers/Serializers:<br>
+     
+<span class="codefrag">Amount_required_to_process_one_request * Number_of_simultaneous_users</span>
+     
+</li>
+
+     
+<li>Consider following formula for Connectors:<br>
+     
+<span class="codefrag">Count_of_pipeline_components_to_process_one_request * 
+     Number_of_simultaneous_users</span>
+</li>
+
+   
+</ul>
+ 
+ 
+ 
+<h1>Pipelines</h1>
+   
+<ul>
+     
+<li>Keep an eye on the overall complexity of pipelines.</li>
+
+     
+<li>Try to keep the size of the documents going through the pipeline
+     small. To big documents slows down translation.</li>
+
+     
+<li>Use the Caching Pipelines in your sitemaps where relevant.</li>
+     
+     
+<li>Use the <span class="codefrag">expires</span> parameter (see above) as frequently as you can.
+     	It improves the end user experience dramatically. Browsers and intermediate
+     	proxy servers love the HTTP <span class="codefrag">Expires</span> header.</li>
+   
+</ul>
+ 
+ 
+ 
+<h1>XSP</h1>
+   
+<p>Consider turning your XSPs into Generators by hand and call them
+    directly. Of course you don't need to do this for all pages, but it's 
+    recommended to it for those which are heavy loaded.</p>
+   
+<p>You can try it this way:</p>
+   
+<p>Cocoon will compile your XSP's into Java classes 
+    (see tomcat/work/..../org/apache/cocoon/www/my_xsp.class). After that, add
+    the generated Generator to the Sitemap:<br>
+    
+<span class="codefrag">
+     &lt;map:generator type="myXSP" src="org.apache.cocoon.www.my_xsp"/&gt;
+    </span>
+   
+</p>
+   
+<p>And use it:<br>
+    
+<span class="codefrag">
+     &lt;map:generate type="myXSP"/&gt;
+    </span>
+   
+</p>
+ 
+ 
+ 
+<h1>XSLT and XSL</h1>
+   
+<div class="note">For more tips and information about XSL and XSLT grep the Internet and the 
+   <a class="external" href="http://xml.apache.org/xalan-j/index.html">Xalan Homepage</a>
+   
+</div>
+ 
+   
+<ul>
+    
+<li>Try to keep the number of templates in the XSL translation small.</li>
+
+    
+<li>There are several ways of doing the same stuff in XSLT, test the 
+    difference between them.</li>
+
+    
+<li>Consider browser-dependent targetting to perform client-side XSLT.
+    Cocoon is very fast if it doesn't do transformations. IE 5.5 and 6 are
+    pretty compliant and might be something around 30% of your hits
+    (probably more on some popular public web sites like Nasa's). Reducing
+    one/third of the transformations might speed up a LOT.</li>
+
+   
+<li>How complicated are the XSLT stylesheets? If you are not using global 
+   variables or parameters this will speeds things up.</li>
+   
+   
+<li>Consider using XSLTC instead of Xalan. XSLTC compiles XSLT to bytecode (translets)
+   	the first time a stylesheet is used. Consequently it uses the compiled code
+   	which is faster by a magnitude than the interpreted one.</li>
+   	 
+   
+</ul>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/meta.xml
new file mode 100644
index 0000000..d4b76d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-performance-tips/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>performancetips.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/content_en.html
new file mode 100644
index 0000000..43b40b0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/content_en.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The persistent cache under Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gerhard Froehlich" name="DC.Creator">
+<meta content="This document explains how the persistent cache under 
+    Cocoon operates." name="DC.Description">
+</head>
+<body>
+  
+<h1>Goal</h1>
+    
+<p>This document explains how the persistent cache under 
+    Cocoon operates.</p>
+  
+  
+<h1>Normal filesystem persistence:</h1>
+  
+<p>When you configure this opportunity, then the Cocoon objects will be ordinarily
+  serialized to a specified directory. This method is okay for a small number
+  of objects and if your OS can handle long filenames. Some Windows OS
+  have problems when the filenames are very long.</p>
+    
+  
+<h1>Jisp based persistence:</h1>
+  
+<p>The aim of the <a class="external" href="http://www.coyotegulch.com/jisp/index.html">Jisp
+  based</a> persistence is to provide a more scalable persistence. The objects 
+  are stored in an indexed file, which uses a B-Tree alghorithm to store the objects. 
+  This is a more elegant and fast solution, especially when you need to handle many
+  objects.</p>
+  
+  
+<h1>Configuration:</h1>
+  
+<pre class="code">
+ &lt;persistent-store logger="core.store.persistent"&gt;
+    &lt;!-- Configuration goes here --&gt;
+ &lt;/persistent-store&gt;
+  </pre> 
+  
+<p>Please refer to <span class="codefrag">cocoon.xconf</span> file for further configuration
+  explanation.</p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/meta.xml
new file mode 100644
index 0000000..07a8a96
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-persistent-store/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/persistence.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/content_en.html
new file mode 100644
index 0000000..75bbeb7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/content_en.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Refactoring of Cocoon Samples</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Planning Documentation" name="DC.Subject">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+ 
+<p>
+  The Cocoon samples are now under <span class="codefrag">src/webapp/samples/</span> and have
+  been refactored to be self contained, to have their own sitemaps, and to
+  utilise some common resources.
+ </p>
+
+ 
+<p>
+  However, there are still some old samples that have not yet been moved into
+  this new structure. They are at <span class="codefrag">src/webapp/docs/samples/</span> and so
+  are not available from the samples page. Please help to bring them back.
+ </p>
+
+ 
+<p>
+  The main page of the samples is becoming rather cluttered again. The aim
+  is to have various samples pages, rather than just one big page.
+ </p>
+
+ 
+<p>There are some missing groups of samples, e.g.</p>
+
+
+<ul>
+
+<li>Welcome =&gt; Samples =&gt; More Samples =&gt; Static Content</li>
+
+<li>Welcome =&gt; Samples =&gt; More Samples =&gt; Server Pages</li>
+
+<li>Welcome =&gt; Samples =&gt; More Samples =&gt; Sources</li>
+
+<li>Welcome =&gt; Samples =&gt; More Samples =&gt; Web Applications</li>
+
+</ul>
+ 
+
+ 
+<h1>Procedure</h1>
+
+
+<ul>
+
+<li>Choose your favourite missing sample.</li>
+
+<li>Create a new directory under <span class="codefrag">webapp/samples</span>
+</li>
+
+<li>Follow the example of some other samples,
+e.g. <span class="codefrag">poi/</span> or <span class="codefrag">i18n/</span> or <span class="codefrag">misc/</span>
+</li>
+
+<li>
+<span class="codefrag">cp samples/misc/sitemap.xmap samples/yours/sitemap.xmap</span>
+and edit it to suit your own matches.
+</li>
+
+<li>
+<span class="codefrag">cp samples/misc/samples.xml samples/yours/samples.xml</span>
+and edit it to become the front page to your collection of samples.</li>
+
+<li>Move the documents from the old sample at <span class="codefrag">webapp/docs/samples</span>
+</li>
+
+<li>Make links to your new samples from other pages.</li>
+
+<li>Remove the old sample from <span class="codefrag">webapp/docs/samples</span>
+</li>
+
+<li>Ensure that the new sample works as expected.</li>
+
+<li>Send a <a href="../howto/index.html">patch via Bugzilla</a>
+</li>
+
+</ul>
+
+
+<div class="fixme">DC:
+      Explain how to retain CVS history when moving the files.</div>
+ 
+
+ 
+<h1>Other discussion</h1>
+ 
+<p>
+  There has been some discussion on cocoon-dev ...
+ </p>
+
+ 
+<ul>
+  
+<li>
+<a class="external" href="http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102259446212331">Samples Refactoring: Documentation Structure</a>
+</li>
+ 
+</ul>
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/meta.xml
new file mode 100644
index 0000000..7ee1c29
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan-samples/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/samples.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/content_en.html
new file mode 100644
index 0000000..f1866f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/content_en.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Planning Notes</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+
+  
+<p>This is a collection of notes to assist with long-term planning and
+   development.
+  </p>
+
+  
+<p>There is much discussion of issues and Random Thought (RT) threads on
+   the <span class="codefrag">cocoon-dev</span> mailing list (and elsewhere). However, details
+   get lost in the sheer volume. This is the place to document the summary of
+   discussions on some key topics. Some new and complex capabilities will take
+   lots of design and specification before they can be implemented.
+  </p>
+
+  
+<p>Another use for this collection of notes is as a place to quickly store
+   a snippet from an email discussion or even a link to a discussion thread.
+   The concepts can then be fleshed-out over time.
+  </p>
+
+  
+<p>Anyone can participate in this process. Please get involved in discussion
+   on the <a class="external" href="http://cocoon.apache.org/community/mail-lists.html">mailing lists</a> and contribute
+   patches for these summary planning
+   documents via the normal <a class="external" href="http://cocoon.apache.org/community/contrib.html">contribution</a>
+   process.
+  </p>
+
+  
+<p>These planning documents are intended to be concise notes only. They are
+   also ever-evolving, because as issues are addressed these notes will be
+   revised.
+  </p>
+ 
+
+ 
+<h1>Topics and Issues</h1>
+
+  
+<ul>
+   
+<li>
+<a href="release.html">Release Plan</a>
+    - major things to do before the next release</li>
+   
+<li>
+<a href="review-sitemap-docs.html">Review Sitemap Docs</a>
+    - a coordinated review of the generated documentation for sitemap
+     components.
+   </li>
+   
+<li>
+<a class="external" href="http://wiki.apache.org/cocoon/22NewDocuments">New Cocoon 2.2 Documentation</a>
+    - a coordinated review of all documentation, to prepare for the
+    Cocoon-2.2 release.
+   </li>
+  
+</ul>
+
+  
+<ul>
+   
+<li>Not maintained: <a href="doc.html">Documentation</a>
+    - revisions and additions are required</li>
+   
+<li>Not maintained: <a href="changes-doc.html">Documentation History of Changes</a>
+</li>
+   
+<li>Not maintained: <a href="todo-doc.html">Documentation To Do List</a>
+</li>
+   
+<li>Not maintained: <a href="issues-doc.html">Documentation Issues</a>
+</li>
+   
+<li>Not recent: <a href="linkstatus.html">Linkstatus</a>
+    - Tools to assess and mend any broken hyperlinks</li>
+  
+</ul>
+
+  
+<ul>
+   
+<li>
+<a href="samples.html">Refactoring of Cocoon Samples</a>
+    - there are still some old samples that are not yet moved under the
+    new webapp/samples/ structure ... you can help</li>
+   
+<li>
+<a href="proposed-toc.html">Proposed TOC, Cocoon Guide</a>
+</li>
+   
+<li>See the general <a href="../todo.html">To Do</a> list 
+    and the <span class="codefrag">cocoon-dev</span> email archives for other issues</li>
+  
+</ul>
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/meta.xml
new file mode 100644
index 0000000..260bac9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-plan/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/content_en.html
new file mode 100644
index 0000000..ef7f806
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/content_en.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Profiler</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bruno Dumon" name="DC.Creator">
+</head>
+<body> 
+    
+<h1>Profiler Overview</h1> 
+      
+<p>The Cocoon Profiler has a double goal:</p>
+      
+<ul>
+        
+<li>it shows how much time is spent in each step of the SAX pipeline.
+          Because of the nature of SAX, this information is difficult or
+          impossible to obtain using general-purpose Java profilers.
+          Additionally, it shows the time spent in the setup() method of each
+          component of the pipeline (sometimes setup takes more time than the
+          actual processing!).</li>
+        
+<li>it allows to take a look at the XML produced in each step of a
+          pipeline. You can use this to get insight in how pipelines work or to
+          see what a particular transformer actually does. It is much easier
+          and comfortable than fuzzing around with the LogTransformer.</li>
+      
+</ul>
+
+      
+<p>The profiler does not show the time spent in components during
+        pipeline setup. These include selectors and matchers, but most
+        importantly, actions. Since Actions are used to execute all kind of
+        logic such as communication with databases or EJB's, they can take up
+        quite some time. Use a general purpose Java profiling tool to analyze
+        them.</p>
+
+      
+<p>The Cocoon samples include a demonstration of the profiler. It can be
+        found below "Block samples".</p>
+    
+    
+<h1>Usage</h1> 
+      
+<p>To use the profiler, two things need to be done:</p>
+      
+<ul>
+        
+<li>Change the pipeline implementation</li>
+        
+<li>Add pipelines to generate the profiler information</li>
+      
+</ul>
+      
+<h2>Change pipeline implementation</h2>
+<p>First, check that the profiling pipeline implementations (caching and/or
+          noncaching) are declared in the map:components section of the sitemap.
+          Here is an example:</p>
+<pre class="code">&lt;map:pipes default="caching"&gt;
+  [...]
+   
+  &lt;!-- The following two can be used for profiling:--&gt;
+  &lt;map:pipe name="profile-caching"
+    src="org.apache.cocoon.components.profiler.ProfilingCachingProcessingPipeline"/&gt;
+  &lt;map:pipe name="profile-noncaching"
+    src="org.apache.cocoon.components.profiler.ProfilingNonCachingProcessingPipeline"/&gt;
+&lt;/map:pipes&gt;</pre>
+<p>You can now turn on the profiling in two ways:</p>
+<ul>
+          
+<li>Change the default pipeline implementation by changing the value of the default
+            attribute on the map:pipes element.</li>
+          
+<li>Change the pipeline implementation of a specific map:pipeline by
+            adding a type attribute to it with as value "profile-caching" or
+            "profiling-noncaching".</li>
+        
+</ul>
+      
+<h2>Add pipelines to generate the profiler information</h2>
+<div class="note">Instead of following the instructions below, you could also reuse
+          the profiler demonstration from the Cocoon samples as-is, and mount
+          it into your own application.</div>
+<p>The information gathered by the profiler can be retrieved using the
+          ProfilerGenerator. Make sure the profiler generator is declared
+          inside the map:generators element in the sitemap, as follows:</p>
+<pre class="code">&lt;map:generator label="content,data" logger="sitemap.generator.profiler" name="profiler"
+    src="org.apache.cocoon.generation.ProfilerGenerator"/&gt;</pre>
+<p>Now add the following two matchers in an appropriate place in your sitemap:</p>
+<pre class="code">&lt;map:match pattern="profile.html"&gt;
+  &lt;map:generate type="profiler"/&gt;
+  &lt;map:transform src="profile2html.xsl"&gt;
+    &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+  &lt;/map:transform&gt;
+  &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+
+&lt;map:match pattern="profile.xml"&gt;
+  &lt;map:generate type="profiler"/&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;</pre>
+<p>Make sure the profile2html.xsl stylesheet is available, you can
+          find it in te Cocoon distribution.</p>
+<p>You also need the pretty-content view (which is included in the
+          default Cocoon sitemap). It can be added in the map:views section of
+          the sitemap as follows:</p>
+<pre class="code">&lt;map:views&gt;
+  &lt;map:view name="pretty-content" from-label="data"&gt;
+    &lt;map:transform src="simple-xml2html.xslt"/&gt;
+    &lt;map:serialize type="html"/&gt;
+  &lt;/map:view&gt;
+&lt;/map:views&gt;</pre>
+<p>Again, make sure the simple-xml2html.xsl stylesheet is available, it
+          can also be found in the Cocoon distribution.</p>
+<p>Now you are ready to use the profiler. First make a series of requests
+          on the pages you want to profile, then go look at the profiler results
+          by requesting the profile.html page.</p>
+    
+    
+<h1>Notes</h1> 
+      
+<ul>
+        
+<li>the profiler is contained in a seperate Cocoon block. Unless you
+          deactivated it, it is included in the standard build.</li>
+        
+<li>if you are streaming very large documents through the pipeline, the
+          profiler will use a lot of memory since it buffers the data in
+          between pipeline components.</li>
+        
+<li>profiling has a very negative impact on performance and memory
+          usage, since it buffers all data between pipeline components. Only
+          activate it when required, and never activate it on production
+          systems.</li>
+        
+<li>when using the profile-caching pipeline implementation the XML
+          generated by components will only be available on non-cached
+          executions.</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/meta.xml
new file mode 100644
index 0000000..9ed0728
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-profiler/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/profiler.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/content_en.html
new file mode 100644
index 0000000..7de6542
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/content_en.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Read DOM Session Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Sven Beauprez" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+<meta content="This document describes the read dom session transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Read DOM Session Transformer</h1>
+      
+<p>With this transformer, a DOM-object that is stored in the session, can be inserted
+  in the SAX stream at a given position.</p>
+      
+<ul>
+        
+<li>Name : readDOMsession</li>
+        
+<li>Class: org.apache.cocoon.transformation.ReadDOMSessionTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<p>
+Simply transforms a DOM to SAX-events, which can be used further on in the 
+pipeline. Once you stored the result of a query in the session with the 
+WriteDOMSessionTransformer, you can read it again with the 
+ReadDOMSessionTransformer:
+</p>
+
+    
+<pre class="code">
+     
+      &lt;map:transform type="readDOMsession"&gt;
+        &lt;map:parameter name="dom-name" value="DBresult"/&gt;
+        &lt;map:parameter name="trigger-element" value="users"/&gt;
+        &lt;map:parameter name="position" value="after"/&gt;
+      &lt;/map:transform&gt;
+     
+    </pre>
+
+
+<p>
+In this example, the SAX-events that came from the DOM tree that is stored in 
+the session with name DBresult will be added after the users element. This means 
+as soon that the transformer encounters the end-element 'users', it will start 
+to generate SAX-events from the DOM tree. There are three possible positions, 
+'before','in' and 'after':
+</p>
+
+<ol>
+
+<li>'before' means that when the transformer encounters the 'users' element, it 
+will FIRST translate the DOM tree to SAX-events and THEN it will continue to 
+forward the other SAX-events (starting with 'users').
+</li>
+
+<li>'in' means that the transformer will forward the startElement event for 
+'users' and that it IMMEDIATELY starts to generate SAX-events from the DOM-tree. 
+After that, it will continue to forward the child elements of users and then all 
+the other elements.
+</li>
+
+<li>'after' means that the transformer starts to generate SAX-events from the 
+DOM-tree just after it has forwarded the end-element 'users'.
+</li>
+
+</ol>
+
+<p>
+The ReadDOMSessionTransformer is a standalone component, you don't need to use 
+it in combination with the WriteDOMSessionTransformer.
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/meta.xml
new file mode 100644
index 0000000..d584b93
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readdomsession-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/readdomsession-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/content_en.html
new file mode 100644
index 0000000..94d1b0f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/content_en.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Readers in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes all of the available readers of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+    
+<h1>Goal</h1>
+      
+<p>
+        This document lists all of the available readers of Apache Cocoon and
+        describes their purpose.
+      </p>
+    
+    
+<h1>Overview</h1>
+      
+<p>
+        A reader is the starting, and end point of an xml pipeline. 
+        It collapses the features of a generator, transformer, and serializer.
+        Readers are useful for delivering binary content like images; more
+        general readers deliver content as-is.
+      </p>
+      
+<p>
+        In the sitemap file, each reader has a unique name which is mapped 
+        to a java class. 
+        One reader name must be declared as the default reader. 
+        Each reader may have additional configuration information specified in 
+        child elements.
+      </p>
+      
+<p>
+        For conceptual information on readers see the user's guide document 
+        <a href="../concepts/sitemap.html">The Sitemap</a>.
+      </p>
+    
+    
+<h1>The Readers in Apache Cocoon</h1>
+      
+<ul>
+        
+<li>
+<a href="axisrpc-reader.html">AxisRPC Reader</a> (Optional: Axis block)</li>
+        
+<li>
+<a href="database-reader.html">Database Reader</a> (Optional: Database block)</li>
+        
+<li>
+<a href="directoryziparchiver-reader.html">Directory ZIP Archiver</a> (Scratchpad)</li>
+        
+<li>
+<a href="image-reader.html">Image Reader</a>
+</li>
+        
+<li>
+<a href="jsp-reader.html">JSP Reader</a> (Optional: JSP block)</li>
+        
+<li>
+<a href="resource-reader.html">Resource Reader</a> (The default reader)</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/meta.xml
new file mode 100644
index 0000000..1da03a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-readers/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/readers.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/content_en.html
new file mode 100644
index 0000000..5bcfc8d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/content_en.html
@@ -0,0 +1,198 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Redirection</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Upayavira" name="DC.Creator">
+</head>
+<body>
+
+    
+<h1>Introduction</h1>
+      
+<p>
+        A Redirector allows the sitemap to pass a request for one URI on to another,
+        whether that other URI is handled by Cocoon or not.
+      </p>
+      
+<p>
+        To redirect from <span class="codefrag">page1.html</span> to <span class="codefrag">page2.html</span>, you can use
+        the following:
+      </p>
+        
+<pre class="code">
+
+  &lt;map:match pattern="page1.html"&gt;
+    &lt;map:redirect-to uri="page2.html"/&gt;
+  &lt;/map:match&gt;
+
+        </pre>
+
+    
+
+    
+<h1>HTTP redirects and how they work</h1>
+      
+<p>If the URI specified does not use the Cocoon: protocol, then an HTTP redirect
+         will occur. The new URI is sent back to the client, which will then request
+         the page from this new location.
+      </p>
+      
+<p>Therefore, directory handling in redirect URIs works differently from other
+         sitemap components.
+      </p>
+      
+<p>If the new URI is relative, then it will be relative to the directory of the 
+         page that called it, not relative to the URI of the sitemap containing it.
+         Thus, the following is incorrect:
+      </p>
+
+<pre class="code">
+
+  &lt;map:match pattern="folder/page1.html"&gt;
+    &lt;map:redirect-to uri="folder/page2.html"/&gt;
+  &lt;/map:match&gt;
+
+</pre>
+      
+<p>
+         This will in fact redirect the user to folder/folder/page2.html, which is
+         probably not intended. The correct version is:
+      </p>
+
+<pre class="code">
+
+  &lt;map:match pattern="folder/page1.html"&gt;
+    &lt;map:redirect-to uri="page2.html"/&gt;
+  &lt;/map:match&gt;
+    
+</pre>
+    
+    
+<h1>Internal Redirects Using the Cocoon Protocol</h1>
+      
+<p>
+        A redirection URI can make use of the <span class="codefrag">cocoon:</span> protocol to return
+        content from another Cocoon pipeline. In this case, the redirection happens     
+        internally. The content from the redirected URI is returned to the client as 
+        if it came from the original URI.
+      </p>
+      
+<p>
+        Directory handling is the same here as for other sitemap components. So that:
+      </p>
+
+<pre class="code">
+
+  &lt;map:match pattern="folder/page1.html"&gt;
+    &lt;map:redirect-to uri="cocoon:/folder/page2.html"/&gt;
+  &lt;/map:match&gt;
+
+</pre>
+      
+<p>
+        will return the content of <span class="codefrag">page2.html</span> to the client in response
+        to the request for <span class="codefrag">page1.html</span>.
+      </p>
+      
+<p>
+        Note: when the <span class="codefrag">cocoon:</span> protocol is used, an HTTP redirect is not
+        used.
+      </p>
+    
+    
+    
+<h1>Session Management with Redirects</h1>
+      
+<p>
+      By setting the <span class="codefrag">session</span> attribute to <span class="codefrag">yes</span>, the current
+      session will be maintained during the redirect.
+      </p>
+    
+    
+    
+<h1>Temporary and Permanent Redirects</h1>
+      
+<p>
+      By default, an HTTP redirect sends a code of <span class="codefrag">SC_MOVED_TEMPORARILY</span>, 
+      (<span class="codefrag">302</span>). This instructs the user agent to use the new URI, but not to
+      cache the resulting page, as it may well soon revert back to the old URI.
+      </p>
+      
+<p>
+        This can be a problem for pages that have been moved permanently, as the new
+        page will never be cached, placing additional load on both the browser and on
+        the server.
+      </p>
+      
+<p>
+        This can be avoided using a permanent redirect, using a code of 
+        <span class="codefrag">SC_MOVED_PERMANENTLY</span> (<span class="codefrag">301</span>). A permanent redirect 
+        can be specified as:
+      </p>
+       
+<pre class="code">
+
+  &lt;map:match pattern="page1.html"&gt;
+    &lt;map:redirect-to uri="page2.html" permanent="yes"/&gt;
+  &lt;/map:match&gt;
+
+        </pre>   
+      
+<p>
+        This results in the user agent caching the redirected page, and thus saves
+        resources both on the server and for the client's browser.
+      </p>
+    
+    
+    
+<h1>Redirects in Pipelines</h1>
+      
+<p>
+        A redirect must stand alone in a pipeline - it cannot occur after a generator.
+        If a redirect needs to be generated conditionally by a pipeline, then a 
+        <span class="codefrag">&lt;meta&gt;</span> tag redirect should be added into the 
+        <span class="codefrag">&lt;head&gt;</span> of the HTML page. The syntax for this is:
+      </p>
+      
+<pre class="code">
+  
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;meta http-equiv="refresh" content="0;URL=page2.html"/&gt;
+    ...
+  &lt;/head&gt;
+  ...
+&lt;/html&gt;
+
+        </pre>
+    
+    
+    
+<h1>Global Redirects</h1>
+      
+<p>
+        When an aggregator accesses a source that includes a redirection, it will 
+        aggregate the document specified by the redirection URI.
+      </p>
+      
+<p>
+        Alternatively, if a redirection that has the <span class="codefrag">global</span> attribute is set 
+        (to <span class="codefrag">yes</span> or <span class="codefrag">true</span>) occurs within an aggregation, the 
+        aggregation is cancelled and the redirect is sent back to the client.
+      </p>
+    
+    
+    
+<h1>Redirecting to Resources</h1>
+      
+<p>Specifiying a <span class="codefrag">resource</span> attribute allows the redirection to a sitemap
+      resource. This usage has been deprecated. <span class="codefrag">map:call</span> should be used
+      instead.
+      </p>
+    
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/meta.xml
new file mode 100644
index 0000000..45119a3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-redirection/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/redirection.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/content_en.html
new file mode 100644
index 0000000..94fc13c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/content_en.html
@@ -0,0 +1,193 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Regular-Expression-Header-Selector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Colin Adams" name="DC.Creator">
+<meta content="This document describes the RegexpHeaderSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>RegexpHeaderSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">regexp-header</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">RegexpHeaderSelector</span> component is used to
+            select appropriate sitemap processing depending on a particular header value.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where RegexpHeaderSelector sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.RegexpHeaderSelector</td>
+        
+</tr>
+        <!-- uncomment folling tr iff RegexpHeaderSelector is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1.6</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">RegexpheaderSelector</span> tests a header field against
+        the test attribute of the selectors when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">RegexpHeaderSelector</span> allows to define sitemap
+        processing based on the content of a particular header field.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:select type="regexp-header"&gt;
+  &lt;map:when test="xhtml"&gt;
+  ....
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+  ...
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+        
+</p>
+<pre class="code">
+&lt;map:selectors...
+  &lt;map:selector name="regexp-header" 
+    src="org.apache.cocoon.selection.RegexpHeaderSelector"
+    
+    &lt;pattern name="xhtml"&gt;application/xhtml\+xml&lt;/pattern&gt;
+    ...
+    &lt;header-name&gt;accept&lt;/header-name&gt;
+    
+  &lt;/map:selectors&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          <!-- Explain the sitemap selector configuration, options when declaring browser selector -->
+          The configuration section of <span class="codefrag">RegexpHeaderSelector</span> specifies
+          a mapping from header strings to symbolic pattern names.
+        </p>
+<p>
+          Each pattern element specifies a name attribute holding the symbolic pattern name
+          used in the test attribute expression. The contents contains 
+          a regular expression to match against the header value.
+        </p>
+<p>
+          The header concerned is named by the contents of the header-name element.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          <!-- Explain the sitemap selector setup, ie options when using this selector -->
+          Setting up a <span class="codefrag">RegexpHeaderSelector</span> includes choosing the 
+          <span class="codefrag">&lt;map:when&gt;</span> test expressions, and a 
+         optional <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+        </p>
+<p>
+          The test attribute of the <span class="codefrag">&lt;map:when&gt;</span> clause must match
+          a pattern attribute name value. The value of the test attribute in a 
+          <span class="codefrag">&lt;map:when&gt;</span> clause must be declared in a 
+          <span class="codefrag">pattern</span> name attribute.
+        </p>
+<p>The header-name can be overridden by a parameter element.
+  </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">RegexpHeaderSelector</span> has no side effects on the object model, or 
+          any sitemap parameters. 
+        </p>
+    
+    
+<h1>Notes</h1>
+      
+<p>
+      The main motivation for this selector is to do some simple content
+      negotiation to serve XHTML 1.1 pages where the browser indicates it
+      accepts application/xhtml+xml, and HTML pages otherwise.
+      However, this has many more uses, including automatic i18n according
+      to the accept-language header.
+      </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The <span class="codefrag">RegexpHeaderSelector</span> adds the response header attribute
+        <span class="codefrag">Vary</span> having a value of the header name, indicating
+        that the response differ for different user agents. This information
+        especially meaningfull for an http-proxy server.
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        26-07-04: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/meta.xml
new file mode 100644
index 0000000..c98eb8a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-regexpheader-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/regular-expression-header-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/content_en.html
new file mode 100644
index 0000000..06fb9bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/content_en.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Release Plan</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Planning Documentation" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>General tasks for a release</h1>
+  
+<ul>
+   
+<li>We have many open
+    <a class="external" href="http://issues.apache.org/bugzilla/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bugidtype=include&product=Cocoon+2&order=bugs.bug_id">
+    bugs</a> in bugzilla. These must be reviewed
+    and then solved (or declared invalid etc).</li>
+   
+<li>Documentation updates (this area lacks most).
+    Documentation must be happening all the time, and not left
+    until last.</li>
+   
+<li>Checking what to backport. We have components in the
+    latest developer versions, which might find their way into
+    the bugfix version line (2.0.x).</li>
+   
+<li>Ensure that licensing requirements have been met.
+    update jars.xml, ensure proper banner in *.java header,
+    verify the current LICENSE* files, ensure that external
+    components have suitable licensing requirements.</li>
+   
+<li>Everything we forgot...</li>
+  
+</ul>
+ 
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/meta.xml
new file mode 100644
index 0000000..053db28
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-release/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/release.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/content_en.html
new file mode 100644
index 0000000..c3b7080
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/content_en.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Request Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the request generator of Cocoon." name="DC.Description">
+</head>
+<body>
+        
+<h1>Request Generator</h1>
+            
+<p>The request generator uses the current request to produce xml data.
+                     It converts some of the information contained in the request
+                     to structured xml.</p>
+            
+<ul>
+                
+<li>Name : request</li>
+                
+<li>Class: org.apache.cocoon.generation.RequestGenerator</li>
+                
+<li>Cacheable: no.</li>
+            
+</ul>
+
+<pre class="code">
+&lt;map:generate type="request"/&gt;
+&lt;!-- The src attribute is optional --&gt;
+</pre>
+            
+<p>The output has the following schema. All elements have the namespace
+               <span class="codefrag">http://apache.org/cocoon/request/2.0</span>
+</p>
+
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+
+&lt;!-- The root element is request. The target attribute is the 
+     requested uri and the source attribute is the optional 
+     source attribute of the sitemap entry for this pipeline. --&gt;
+&lt;request target="/cocoon/request" source=""
+         xmlns="http://apache.org/cocoon/request/2.0"&gt;
+
+  &lt;!-- First the headers: --&gt;
+  &lt;requestHeaders&gt;
+    &lt;header name="accept-language"&gt;de&lt;/header&gt;
+    &lt;header name="connection"&gt;Keep-Alive&lt;/header&gt;
+    &lt;header name="accept"&gt;image/gif, image/x-xbitmap, image/jpeg,
+      image/pjpeg, */*&lt;/header&gt;
+    &lt;header name="host"&gt;thehost.serving.cocoon&lt;/header&gt;
+    &lt;header name="accept-encoding"&gt;gzip, deflate&lt;/header&gt;
+    &lt;header name="user-agent"&gt;Browser User Agent&lt;/header&gt;
+    &lt;header name="referer"&gt;http://thehost.serving.cocoon/cocoon/welcome
+      &lt;/header&gt;
+  &lt;/requestHeaders&gt;
+
+  &lt;!-- All request parameters: --&gt;
+  &lt;requestParameters&gt;
+    &lt;!-- Create a parameter element for each parameter --&gt;
+    &lt;parameter name="login"&gt;
+      &lt;!-- Create a value element for each value --&gt;
+      &lt;value&gt;test&lt;/value&gt;
+    &lt;/parameter&gt;
+  &lt;/requestParameters&gt;
+
+  &lt;!-- All request attributes; see below the note on generate-attributes parameter. 
+       (This feature is available startign with version 2.1 --&gt;
+  &lt;requestAttributes&gt;
+    &lt;!-- Create an attribute element for each attribute --&gt;
+    &lt;attribute name="errorMessage"&gt;
+      &lt;!-- Create a value element for the attribute value --&gt;
+      &lt;value&gt;I was put here by an earlier action.&lt;/value&gt;
+    &lt;/attribute&gt;
+  &lt;/requestAttributes&gt;
+
+  &lt;!-- All configuration parameters: --&gt;
+  &lt;configurationParameters&gt;
+    &lt;!-- Create a parameter element for each parameter specified 
+         in the pipeline for this generator--&gt;
+    &lt;parameter name="test_sitemap_parameter"&gt;the value&lt;/parameter&gt;
+  &lt;/configurationParameters&gt;
+
+&lt;/request&gt;
+</pre>
+
+
+            
+<div class="note">If you want request attributes to be generated, you must specify <span class="codefrag">generate-attributes</span> parameter at generator definition or invocation in the sitemap.</div>
+
+<pre class="code">
+&lt;!-- This will turn on attribute generation on by default --&gt;
+&lt;map:generator name="request" src="org.apache.cocoon.generation.RequestGenerator"&gt; 
+    &lt;map:parameter name="generate-attributes" value="true"/&gt;
+&lt;/map:generator&gt;
+
+&lt;!-- or --&gt;
+
+    &lt;!-- This will turn on attribute generation for this invocation only. --&gt;
+    &lt;map:match pattern="request"&gt;
+        &lt;map:generate type="request"&gt;
+      &lt;map:parameter name="generate-attributes" value="true"/&gt;
+        &lt;/map:generate&gt;
+    &lt;/map:match&gt;
+
+
+</pre>
+        
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/meta.xml
new file mode 100644
index 0000000..51459ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-request-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/request-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/content_en.html
new file mode 100644
index 0000000..cc19552
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/content_en.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>RequestAttribute-Selector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the RequestAttributeSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>RequestAttributeSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">request-attribute</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">RequestAttributeSelector</span> component is used to
+            select appropriate sitemap processing depending on a request attribute
+            value.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where RequestAttributeSelector sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.RequestAttributeSelector</td>
+        
+</tr>
+        <!-- uncomment folling tr iff RequestAttributeSelector is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">RequestAttributeSelector</span> tests the value of request attribute
+        against the test attribute of the selector's when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">RequestAttributeSelector</span> allows to control the 
+        sitemap processing depending on a request attribute.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The snippet below uses a <span class="codefrag">RequestAttributeSelector</span> named <span class="codefrag">request-attribute</span>.
+          It tests the value of request attribute named <span class="codefrag">command</span> against
+          <span class="codefrag">list</span>, <span class="codefrag">create</span>; finally it has a <span class="codefrag">otherwise</span> clause.
+        </p>
+<pre class="code">
+&lt;map:select type="request-attribute"&gt;
+  &lt;map:parameter name="attribute-name" value="command"/&gt;
+  &lt;map:when test="list"&gt;
+  ....
+  &lt;/map:when&gt;
+  &lt;map:when test="create"&gt;
+  ...
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+  ...
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The snippet below declares a <span class="codefrag">RequestAttributeSelector</span>
+          defining to use the request attribute <span class="codefrag">cmd</span>.
+        </p>
+<pre class="code">
+&lt;map:selectors...
+  &lt;map:selector name="request-attribute" 
+    src="org.apache.cocoon.selection.RequestAttributeSelector"
+    logger="sitemap.selector.requestattribute"&gt;
+    
+    &lt;attribute-name&gt;command&lt;/attribute-name&gt;
+  &lt;/map:selectors&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          <!-- Explain the sitemap selector configuration, options when declaring request-attribute selector -->
+          The configuration section of <span class="codefrag">RequestAttributeSelector</span> specifies
+          the default name of the request attribute, used for testing.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          <!-- Explain the sitemap selector setup, ie options when using request-attribute selector -->
+          Setting up a <span class="codefrag">RequestAttributeSelector</span> includes
+        </p>
+<ul>
+          
+<li>Defining an optional sitemap paramter named <span class="codefrag">request-name</span>, it overrides
+            the attribute-name setting in the configuration section.
+          </li>
+          
+<li>choosing the <span class="codefrag">&lt;map:when&gt;</span> test expressions, and a 
+          optional <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+          </li>
+        
+</ul>
+<p>
+          The test attribute of the <span class="codefrag">&lt;map:when&gt;</span> clause shall match
+          the value of the request attribute.
+          If no test value matches, or the request attribute is not defined at all,
+          the <span class="codefrag">&lt;map:otherwise</span> clause is selected.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">RequestAttributeSelector</span> has no side effects on the object model, or 
+          any sitemap attributes. 
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+      
+</p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        28-12-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/meta.xml
new file mode 100644
index 0000000..38c4e90
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestattribute-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/requestattribute-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/content_en.html
new file mode 100644
index 0000000..dc36586
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/content_en.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>RequestMethodSelector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Cocoon Community" name="DC.Creator">
+<meta content="This document describes the RequestMethodSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>RequestMethodSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">RequestMethod</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">RequestMethodSelector</span> component is used to 
+            select appropriate sitemap processing depending on the request method, 
+            for example, <span class="codefrag">GET</span> or <span class="codefrag">POST</span>.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.RequestMethodSelector</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The RequestMethodSelector allows pipeline creation to be influenced by the method of
+        the request. For example, in a Cocoon Forms environment, a <span class="codefrag">GET</span> request
+        could be forwarded to a new FlowScript function, whilst a <span class="codefrag">POST</span> could be 
+        forwarded to a continuation, for example:
+      </p>
+      
+<pre class="code">
+&lt;map:match pattern="myform"&gt;
+  &lt;map:select type="request-method"&gt;
+    &lt;map:when test="GET"&gt;
+       &lt;map:call function="myform"/&gt;
+    &lt;/map:when&gt;
+    &lt;map:when test="POST"&gt;
+      &lt;map:call continuation="request-param:continuation-id"/&gt;
+    &lt;/map:when&gt;
+  &lt;/map:select&gt;
+&lt;/map:match&gt;
+</pre>
+    
+    
+<h1>Configuration</h1>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:selectors...
+  &lt;map:selector name="request-method" 
+                logger="sitemap.selector.request-method" 
+                src="org.apache.cocoon.selection.RequestMethodSelector"/&gt;
+  ...
+&lt;/map:selectors&gt;
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          The request method selector does not require any specific configuration, other than
+          specifying a name and an implementing class, as in the example above.
+        </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        2004-12-16: Created this document
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        General documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/meta.xml
new file mode 100644
index 0000000..1770a6e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestmethod-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/requestmethod-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/content_en.html
new file mode 100644
index 0000000..e64edae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/content_en.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>RequestParameter-Selector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the RequestParameterSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>RequestParameterSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">request-parameter</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">RequestParameterSelector</span> component is used to
+            select appropriate sitemap processing depending on a request parameter
+            value.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where RequestParameterSelector sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.RequestParameterSelector</td>
+        
+</tr>
+        <!-- uncomment folling tr iff RequestParameterSelector is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">RequestParameterSelector</span> tests the value of request parameter
+        against the test attribute of the selector's when clause.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">RequestParameterSelector</span> allows to control the 
+        sitemap processing depending on a request parameter.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The snippet below uses a <span class="codefrag">RequestParameterSelector</span> named <span class="codefrag">request-parameter</span>.
+          It tests the value of request parameter named <span class="codefrag">command</span> against
+          <span class="codefrag">list</span>, <span class="codefrag">create</span>; finally it has a <span class="codefrag">otherwise</span> clause.
+        </p>
+<pre class="code">
+&lt;map:select type="request-parameter"&gt;
+  &lt;map:parameter name="parameter-name" value="command"/&gt;
+  &lt;map:when test="list"&gt;
+  ....
+  &lt;/map:when&gt;
+  &lt;map:when test="create"&gt;
+  ...
+  &lt;/map:when&gt;
+  ...
+  &lt;map:otherwise&gt;
+  ...
+  &lt;/map:otherwise&gt;
+&lt;/map:select&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The snippet below declares a <span class="codefrag">RequestParameterSelector</span>
+          defining to use the request parameter <span class="codefrag">command</span>.
+        </p>
+<pre class="code">
+&lt;map:selectors...
+  &lt;map:selector name="request-parameter" 
+    src="org.apache.cocoon.selection.RequestParameterSelector"
+    logger="sitemap.selector.requestparameter"&gt;
+    
+    &lt;parameter-name&gt;command&lt;/parameter-name&gt;
+  &lt;/map:selectors&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          <!-- Explain the sitemap selector configuration, options when declaring request-parameter selector -->
+          The configuration section of <span class="codefrag">RequestParameterSelector</span> specifies
+          the default name of the request parameter, used for testing.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          <!-- Explain the sitemap selector setup, ie options when using request-parameter selector -->
+          Setting up a <span class="codefrag">RequestParameterSelector</span> includes
+        </p>
+<ul>
+          
+<li>Defining an optional sitemap parameter named <span class="codefrag">request-name</span>, it overrides
+            the parameter-name setting in the configuration section.
+          </li>
+          
+<li>choosing the <span class="codefrag">&lt;map:when&gt;</span> test expressions, and a 
+          optional <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+          </li>
+        
+</ul>
+<p>
+          The test attribute of the <span class="codefrag">&lt;map:when&gt;</span> clause shall match
+          the value of the request parameter.
+          If no test value matches, or the request parameter is not defined at all,
+          the <span class="codefrag">&lt;map:otherwise</span> clause is selected.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">RequestParameterSelector</span> has no side effects on the object model, or 
+          any sitemap parameters. 
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+      
+</p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        28-12-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/meta.xml
new file mode 100644
index 0000000..5a97d0f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-requestparameter-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/requestparameter-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/content_en.html
new file mode 100644
index 0000000..289248a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/content_en.html
@@ -0,0 +1,280 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ResourceReader in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the ResourceReader of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>ResourceReader</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">resource</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">ResourceReader</span> component is used 
+            to serve binary data in a sitemap pipeline.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Reader, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.reading.ResourceReader</td>
+        
+</tr>
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">yes</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+    
+<p>
+      The <span class="codefrag">ResourceReader</span> component is used to serve binary data
+      in a sitemap pipeline. 
+    </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+      
+</p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The <span class="codefrag">ResourceReader</span> is used in a pipline as shown in the
+          pipeline snippet below:
+        </p>
+<pre class="code">
+&lt;map:match pattern="*.css"&gt;
+  &lt;map:read type="resource" 
+    src="resources/styles/{1}.css" 
+    mime-type="text/css"&gt;
+    &lt;!-- option sitemap parameters --&gt;
+    ...
+  &lt;/map:read&gt;
+&lt;/map:match&gt;
+</pre>
+<p>
+          It is important to specify the <span class="codefrag">mime-type</span> attribute,
+          as it is passed to the browser as the <span class="codefrag">Content-Type</span>
+          in the <span class="codefrag">HTTP</span> response.
+        </p>
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          A <span class="codefrag">ResourceReader</span> is declared in the sitemap readers
+          section, as shown in the sitemap readers snippet below:
+        </p>
+<pre class="code">
+&lt;map:readers default="resource"&gt;
+  &lt;map:reader name="resource" 
+    src="org.apache.cocoon.reading.ResourceReader" 
+    logger="sitemap.reader.resource" 
+    pool-max="32"/&gt;
+    &lt;!-- optional reader configuration --&gt;
+    ...
+  &lt;/map:readers&gt;
+...
+        </pre>
+      
+<h2>Configuration</h2>
+<p>
+          The <span class="codefrag">ResourceReader</span> accepts the following configuration parameters:
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Parametername</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">expires</td><td colspan="1" rowspan="1">Time in milliseconds</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified it determines how long
+              in miliseconds the resources can be cached by any proxy or browser
+              between Cocoon2 and the requesting visitor.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">quick-modified-test</td><td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. This boolean parameter controls the
+              last modified test. If set to true (default is false), only the
+              last modified of the current source is tested, but not if the
+              same source is used as last time.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">byte-ranges</td><td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. This boolean parameter enables or disables
+              support for the byte ranges. 
+              By default this parameter is set to true.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">buffer-size</td><td colspan="1" rowspan="1">integer</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. It specifies the buffer/block size when
+              reading from a resource.
+              By default this parameter is set to 8192.
+            </td>
+          
+</tr>
+        
+</table>
+<p>
+          The following <span class="codefrag">ResourceReader</span> declaration snippet
+          configures the default reader for having an expiration of
+          1 day (ie. 24 * 60 * 60 * 1000 ms = 86400000 ms)
+        </p>
+<pre class="code">
+&lt;map:readers default="resource"&gt;
+  &lt;map:reader name="resource" 
+    src="org.apache.cocoon.reading.ResourceReader" 
+    logger="sitemap.reader.resource" 
+    pool-max="32"/&gt;
+    &lt;!-- optional reader configuration --&gt;
+    &lt;parameter name="expires" value="86400000"/&gt;
+  &lt;/map:readers&gt;
+...
+        </pre>
+      
+<h2>Setup</h2>
+<p>
+          The <span class="codefrag">ResourceReader</span> accepts following sitemap
+          setup parameters that override the configuration settings:
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Parametername</th><th colspan="1" rowspan="1">Type</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">expires</td><td colspan="1" rowspan="1">Time in milliseconds</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. When specified it determines how long
+              in miliseconds the resources can be cached by any proxy or browser
+              between Cocoon2 and the requesting visitor.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">quick-modified-test</td><td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. This boolean parameter controls the
+              last modified test. If set to true (default is false), only the
+              last modified of the current source is tested, but not if the
+              same source is used as last time.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">byte-ranges</td><td colspan="1" rowspan="1">boolean</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. This boolean parameter enables or disables
+              support for the byte ranges. 
+              By default this parameter is set to true.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">buffer-size</td><td colspan="1" rowspan="1">integer</td>
+            <td colspan="1" rowspan="1">
+              This parameter is optional. It specifies the buffer/block size when
+              reading from a resource.
+              By default this parameter is set to 8192.
+            </td>
+          
+</tr>
+        
+</table>
+<p>
+          The following <span class="codefrag">ResourceReader</span> declaration snippet
+          parameterizes the default reader for having an expiration of
+          1 day (ie. 24 * 60 * 60 * 1000 ms = 86400000 ms)
+        </p>
+<pre class="code">
+  &lt;map:read src="images/picture.gif"/&gt;
+    &lt;map:parameter name="expires" value="86400000"/&gt;
+  &lt;/map:read&gt;
+...
+        </pre>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">ResourceReader</span> does not change object model and sitemap parameters.
+          It only access values for reading.
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-25-02: Initial document creation by Bernhard Huber
+        <br>
+        01-06-03: Added new parameters and byte range support, Torsten Curdt
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages -->
+      
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/meta.xml
new file mode 100644
index 0000000..cd679d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resource-reader/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/readers/resource-reader.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/content_en.html
new file mode 100644
index 0000000..cb80cbb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/content_en.html
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>ResourceExistsSelector in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Andrew Savory" name="DC.Creator">
+<meta content="This document describes the ResourceExistsSelector of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>ResourceExistsSelector</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">resource-exists</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">ResourceExistsSelector</span> component is used to 
+            select appropriate sitemap processing depending on the existence of a set of resources.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Selector, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.selection.ResourceExistsSelector</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.1</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">ResourceExistsSelector</span> selects the first of a set of
+        Resources (usually files) that exists in the context.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        Pipelines can be built based on the existence of files, for example
+        building a PDF from XSL-FO or a higher-level XML format.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:match pattern="**.html"&gt; 
+  &lt;map:select type="resource-exists"&gt;
+    &lt;map:when test="content/{1}.xml"&gt;
+      &lt;map:generate src="content/{1}.xml" /&gt;
+      &lt;map:transform src="stylesheets/page2html.xsl" /&gt;
+    &lt;/map:when&gt;
+    &lt;map:otherwise&gt;
+      &lt;map:generate src="resources/html/{1}.html" /&gt;
+    &lt;/map:otherwise&gt;
+  &lt;/map:select&gt;
+  &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:selectors...
+
+  &lt;map:selector name="resource-exists" 
+    src="org.apache.cocoon.selection.ResourceExistsSelector"
+    logger="sitemap.selector.resource-exists"
+  &gt;
+    &lt;map:parameter src="prefix" value="/"/&gt;
+  &lt;/map:selector&gt;
+    ...
+  &lt;/map:selectors&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          The optional <span class="codefrag">prefix</span> parameter is prepended to all test
+          expressions before evaluation. The default prefix is '/', meaning that
+          all expressions are relative to the context root, unless explicitly
+          overridden.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          Setting up a <span class="codefrag">ResourceExistsSelector</span> includes choosing the
+          <span class="codefrag">&lt;map:when&gt;</span> test expressions, and an optional 
+          <span class="codefrag">&lt;map:otherwise&gt;</span> clause.
+        </p>
+<!--      <s2 title="Effect on Object Model and Sitemap Parameters">
+        <p>
+        
+        </p>
+      </s2>-->
+    
+<!--    <s1 title="Bugs/Caveats">
+      <p>
+        Describe limitation, bugs of ResourceExistsSelector 
+      </p>
+    </s1>-->
+    
+<h1>History</h1>
+      
+<p>
+        03-19-03: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about selectors is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/meta.xml
new file mode 100644
index 0000000..4067475
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-resourceexists-selector/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/resourceexists-selector.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/content_en.html
new file mode 100644
index 0000000..35e901c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/content_en.html
@@ -0,0 +1,4102 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Review of sitemap component documentation</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Cocoon Developers" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>
+        This is a coordination table to assist the systematic review of the
+        "sitemap component documentation" which is the set of documentation
+        available at 
+        <a href="../userdocs/">/userdocs/</a>
+        for each sitemap component
+        (actions generators matchers readers selectors serializers transformers).
+      </p>
+      
+<p>
+        This review focusses only on this set of documentation, as part of
+        the overall documentation
+        <a class="external" href="http://wiki.apache.org/cocoon/22NewDocuments">review</a>.
+        This set is a key part, because it
+        addresses the heart of Cocoon - the sitemap components. Having a
+        well-defined "User Guide" will assist both users and developers to
+        be more productive.
+      </p>
+      
+<p>
+        Please assist by sending discussion to the dev mailing list and
+        patches of xdocs and java code via the issue tracker.
+        See the <a href="#To+Do">To Do</a> section at the bottom.
+      </p>
+      
+<p>
+        This documentation is generated as part of the Cocoon 'build docs' process.
+        An anttask (tools/anttasks/SitemapTask) scans the java code looking
+        for javadoc-like tags (e.g. @cocoon.sitemap.component.name) and
+        extracts that information. For each component there is also a default
+        document at src/documentation/xdocs/userdocs/ which contains additional
+        manual content. The two sources are merged to form each final xdoc, with
+        two new sections being added (Description and Info). Then Forrest builds
+        the final set of documents as part of the normal 'build docs' process.
+      </p>
+      
+<p>These are the SitemapTask attributes that are used in the code:</p>
+      
+<ul>
+        
+<li>@cocoon.sitemap.component.documentation - The documentation (optional)</li>
+        
+<li>@cocoon.sitemap.component.name - The name of the component in the sitemap (required)</li>
+        
+<li>@cocoon.sitemap.component.logger - The logger category (optional)</li>
+        
+<li>@cocoon.sitemap.component.label - The label for views (optional)</li>
+        
+<li>@cocoon.sitemap.component.mimetype - The mime type for serializers and readers (optional)</li>
+        
+<li>@cocoon.sitemap.component.hide - If this tag is specified, the component is not added to the sitemap (optional)</li>
+        
+<li>@cocoon.sitemap.component.documentation.disabled - If this tag is specified, no documentation is generated (optional)</li>
+        
+<li>@cocoon.sitemap.component.configuration - Configuration (optional)</li>
+        
+<li>@cocoon.sitemap.component.documentation.caching - Caching info (optional)</li>
+        
+<li>@cocoon.sitemap.component.pooling.min - Pooling min (optional)</li>
+        
+<li>@cocoon.sitemap.component.pooling.max - Pooling max (optional)</li>
+        
+<li>@cocoon.sitemap.component.pooling.grow - Pooling grow (optional)</li>
+      
+</ul>
+    
+
+    
+<h1>Coordination table</h1>
+      
+<p>The table columns are:</p>
+      
+<ul>
+        
+<li>Java source - The name of the Java source file and link to javadoc.</li>
+        
+<li>Document - The name of the generated document and a link to it.
+        This is also the @cocoon.sitemap.component.name</li>
+        
+<li>A - The xdoc is available to supply additional manual content.</li>
+        
+<li>B - The java code is in "core" or as a "block".</li>
+        
+<li>C - The javadoc-like tags (SitemapTask attributes) are available in the code.</li>
+        
+<li>D - The component parameters are properly described.</li>
+        
+<li>E - The code and xdoc are synchronised between Cocoon trunk and 2.1 branch.</li>
+      
+</ul>
+      
+<p>Cell values are:</p>
+      
+<ul>
+        
+<li>blank - Not yet investigated.</li>
+        
+<li>y - Yes.</li>
+        
+<li>n - No.</li>
+        
+<li>- - Not relevant.</li>
+        
+<li>* - Has issues, needs more work.</li>
+      
+</ul>
+      
+<p>There are 314 entries.</p>
+
+    
+<h2>Actions</h2>
+<table>
+<!-- table: actions -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractAction.html">AbstractAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractComplementaryConfigurableAction.html">AbstractComplementaryConfigurableAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractConfigurableAction.html">AbstractConfigurableAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractDatabaseAction.html">AbstractDatabaseAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/forms/acting/AbstractFormsAction.html">AbstractFormsAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">forms</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractMultiAction.html">AbstractMultiAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/AbstractValidatorAction.html">AbstractValidatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/authentication/acting/AuthAction.html">AuthAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">authentication-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/portal/acting/AuthAction.html">AuthAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/BookmarkAction.html">BookmarkAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/CacheEventAction.html">CacheEventAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">eventcache</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ClearCacheAction.html">ClearCacheAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ClearPersistentStoreAction.html">ClearPersistentStoreAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/CommandAction.html">CommandAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ComposerAction.html">ComposerAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ConfigurableComposerAction.html">ConfigurableComposerAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ConfigurableServiceableAction.html">ConfigurableServiceableAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/CookieCreatorAction.html">CookieCreatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/CookieValidatorAction.html">CookieValidatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/CopletSetDataAction.html">CopletSetDataAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/CopySourceAction.html">CopySourceAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseAddAction.html">DatabaseAddAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseAuthenticatorAction.html">DatabaseAuthenticatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseCookieAuthenticatorAction.html">DatabaseCookieAuthenticatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseDeleteAction.html">DatabaseDeleteAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseSelectAction.html">DatabaseSelectAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DatabaseUpdateAction.html">DatabaseUpdateAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/DbXMLAuthenticatorAction.html">DbXMLAuthenticatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xmldb</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/faces/FacesAction.html">FacesAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">faces</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ExpiresPipelineAction.html">ExpiresPipelineAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/acting/FormManagerAction.html">FormManagerAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/FormValidatorAction.html">FormValidatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/forms/acting/HandleFormSubmitAction.html">HandleFormSubmitAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">forms</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/HelloAction.html">HelloAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/HttpCacheAction.html">HttpCacheAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/HttpHeaderAction.html">HttpHeaderAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/InputModuleAction.html">InputModuleAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/JMSPublisherAction.html">JMSPublisherAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">jms</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/LinkTranslatorMapAction.html">LinkTranslatorMapAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/LocaleAction.html">LocaleAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/authentication/acting/LoggedInAction.html">LoggedInAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">authentication-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/authentication/acting/LoginAction.html">LoginAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">authentication-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/LoginAction.html">LoginAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/authentication/acting/LogoutAction.html">LogoutAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">authentication-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/LogoutAction.html">LogoutAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/mail/MailAction.html">MailAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/forms/acting/MakeFormAction.html">MakeFormAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">forms</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseAction.html">modular/DatabaseAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseAddAction.html">modular/DatabaseAddAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseDeleteAction.html">modular/DatabaseDeleteAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseSelectAction.html">modular/DatabaseSelectAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseQueryAction.html">modular/DatabaseQueryAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/DatabaseUpdateAction.html">modular/DatabaseUpdateAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/ObjectModelAction.html">ObjectModelAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/OraAddAction.html">OraAddAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/OraUpdateAction.html">OraUpdateAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/PropagatorAction.html">PropagatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/RequestParamAction.html">RequestParamAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/RequestParameterExistsAction.html">RequestParameterExistsAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ResourceExistsAction.html">ResourceExistsAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/acting/SaveAction.html">SaveAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ScriptAction.html">ScriptAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/actions/script-action.html">script</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">bsf</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SectionCutterAction.html">SectionCutterAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SendmailAction.html">SendmailAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/actions/sendmail-action.html">sendmail</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ServerPagesAction.html">ServerPagesAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/ServiceableAction.html">ServiceableAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/acting/SessionAction.html">SessionAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/actions/session-action.html">session</a></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/acting/SessionFormAction.html">SessionFormAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SessionInvalidatorAction.html">SessionInvalidatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SessionIsValidAction.html">SessionIsValidAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SessionPropagatorAction.html">SessionPropagatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SessionStateAction.html">SessionStateAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SessionValidatorAction.html">SessionValidatorAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/SetCharacterEncodingAction.html">SetCharacterEncodingAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/taglib/test/acting/TagtestAction.html">TagtestAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">taglib</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/acting/modular/TestAction.html">modular/TestAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core/samples</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/samples/castor/TestBeanAction.html">castor/TestBeanAction</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+
+    
+<h2>Generators</h2>
+<table>
+<!-- table: generators -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/generation/AbstractCopletGenerator.html">AbstractCopletGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/AbstractGenerator.html">AbstractGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/ant/AntBuildGenerator.html">AntBuildGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/asciiart/AsciiArtSVGGenerator.html">AsciiArtSVGGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">asciiart</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/coplets/basket/BasketContentGenerator.html">BasketContentGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/coplets/basket/BasketGenerator.html">BasketGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/CalendarGenerator.html">CalendarGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/calendar-generator.html">calendar</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/flow/ws/ClientBindingGenerator.html">ClientBindingGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/flow</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ComposerGenerator.html">ComposerGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/authentication/generation/ConfigurationGenerator.html">ConfigurationGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">authentication-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/portal/generation/ConfigurationGenerator.html">ConfigurationGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/DirectoryGenerator.html">DirectoryGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/directory-generator.html">directory</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/error-generator.html">error</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/EventCacheGenerator.html">EventCacheGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">eventcache</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/samples/errorhandling/ExceptionGenerator.html">ExceptionGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core/samples</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/extractor-generator.html">extractor</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/FileGenerator.html">FileGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/file-generator.html">file</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/forms/generation/FormsGenerator.html">FormsGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/FragmentExtractorGenerator.html">FragmentExtractorGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">batik</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/GarbageGenerator.html">GarbageGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/GenericProxyGenerator.html">GenericProxyGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">proxy</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/HTMLGenerator.html">HTMLGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/html-generator.html">html</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">html</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/HttpProxyGenerator.html">HttpProxyGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">proxy</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ImageDirectoryGenerator.html">ImageDirectoryGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/imagedirectory-generator.html">imagedirectory</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/IMAPGenerator.html">IMAPGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/JellyGenerator.html">JellyGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/markup/xsp/JSGenerator.html">JSGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/JSPGenerator.html">JSPGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/jsp-generator.html">jsp</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">jsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/JXTemplateGenerator.html">JXTemplateGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/jx-generator.html">jx</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/LinkStatusGenerator.html">LinkStatusGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/linkstatus-generator.html">linkstatus</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/markup/LogicsheetCodeGenerator.html">LogicsheetCodeGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/markup/MarkupCodeGenerator.html">MarkupCodeGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/MP3DirectoryGenerator.html">MP3DirectoryGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/mp3directory-generator.html">mp3directory</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/NekoHTMLGenerator.html">NekoHTMLGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">html</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/sitemap/NotifyingGenerator.html">NotifyingGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ParseExceptionGenerator.html">ParseExceptionGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/PauseGenerator.html">PauseGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core/test</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/PhpGenerator.html">PhpGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/php-generator.html">php</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">php</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/generation/PortalGenerator.html">PortalGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/portal/generation/PortalGenerator.html">PortalGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/profile-generator.html">profile</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ProfilerGenerator.html">ProfilerGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">profiler</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/generator/ProgramGenerator.html">ProgramGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/markup/xsp/PythonGenerator.html">xsp/PythonGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">python</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/RequestAttributeGenerator.html">RequestAttributeGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/RequestGenerator.html">RequestGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/request-generator.html">request</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/RequestParameterGenerator.html">RequestParameterGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ScriptGenerator.html">ScriptGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/script-generator.html">script</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">bsf</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/SearchGenerator.html">SearchGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/search-generator.html">search</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">lucene</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ServerPagesGenerator.html">ServerPagesGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/serverpages-generator.html">serverpages</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ServiceableGenerator.html">ServiceableGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/ServletGenerator.html">ServletGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/SessionAttributeGenerator.html">SessionAttributeGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/slop/generation/SlopGenerator.html">SlopGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">slop</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/StatusGenerator.html">StatusGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/status-generator.html">status</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/StreamGenerator.html">StreamGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/stream-generator.html">stream</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/SWFGenerator.html">SWFGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">swf</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/TextGenerator.html">TextGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/TraversableGenerator.html">TraversableGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">repository</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/TraversableSourceDescriptionGenerator.html">TraversableSourceDescriptionGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">repository</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/TraxGenerator.html">TraxGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/VelocityGenerator.html">VelocityGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/velocity-generator.html">velocity</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">velocity</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/wsproxy-generator.html">wsproxy</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/WebServiceProxyGenerator.html">WebServiceProxyGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">proxy</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/XMidiGenerator.html">XMidiGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">midi</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/XMLDBGenerator.html">XMLDBGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/xmldb-generator.html">xmldb</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">xmldb</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/XMLDBCollectionGenerator.html">XMLDBCollectionGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/xmldbcollection-generator.html">xmldbcollection</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">xmldb</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/XPathDirectoryGenerator.html">XPathDirectoryGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/generators/xpathdirectory-generator.html">xpathdirectory</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/generation/XPathTraversableGenerator.html">XPathTraversableGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">repository</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/markup/xsp/XSPGenerator.html">XSPGenerator</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+
+    
+<h2>Matchers</h2>
+<table>
+<!-- table: matchers -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/AbstractPreparableMatcher.html">AbstractPreparableMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/AbstractRegexpMatcher.html">AbstractRegexpMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/AbstractWildcardMatcher.html">AbstractWildcardMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/CookieMatcher.html">CookieMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/HeaderMatcher.html">HeaderMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/LocaleMatcher.html">LocaleMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/modular/CachingRegexpMatcher.html">modular/CachingRegexpMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/modular/CachingWildcardMatcher.html">modular/CachingWildcardMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/modular/WildcardMatcher.html">modular/WildcardMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/MountTableMatcher.html">MountTableMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/ParameterMatcher.html">ParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/PreparableMatcher.html">PreparableMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpHeaderMatcher.html">RegexpHeaderMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpHostMatcher.html">RegexpHostMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpParameterMatcher.html">RegexpParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpRequestAttributeMatcher.html">RegexpRequestAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpRequestParameterMatcher.html">RegexpRequestParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpSessionAttributeMatcher.html">RegexpSessionAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpURIMatcher.html">RegexpURIMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RegexpURIDefaultsMatcher.html">RegexpURIDefaultsMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RequestAttributeMatcher.html">RequestAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/RequestParameterMatcher.html">RequestParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/SessionAttributeMatcher.html">SessionAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardHeaderMatcher.html">WildcardHeaderMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/matchers/wildcardheader-matcher.html">wildcardheader</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardHostMatcher.html">WildcardHostMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardParameterMatcher.html">WildcardParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardRequestAttributeMatcher.html">WildcardRequestAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardRequestParameterMatcher.html">WildcardRequestParameterMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardSessionAttributeMatcher.html">WildcardSessionAttributeMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/matching/WildcardURIMatcher.html">WildcardURIMatcher</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/matchers/wildcarduri-matcher.html">wildcarduri</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+
+    
+<h2>Readers</h2>
+<table>
+<!-- table: readers -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/AbstractReader.html">AbstractReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/AxisRPCReader.html">AxisRPCReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/axisrpc-reader.html">axisrpc</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">axis</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/ComposerReader.html">ComposerReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/DatabaseReader.html">DatabaseReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/database-reader.html">database</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/DirectoryZipArchiver.html">DirectoryZipArchiver</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/directoryziparchiver-reader.html">directoryziparchiver</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/ImageReader.html">ImageReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/image-reader.html">image</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/JSPReader.html">JSPReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/jsp-reader.html">jsp</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">jsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/reading/ProxyReader.html">ProxyReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/ResourceReader.html">ResourceReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/readers/resource-reader.html">resource</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/reading/ServiceableReader.html">ServiceableReader</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+
+    
+<h2>Selectors</h2>
+<table>
+<!-- table: selectors -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/AbstractRegexpSelector.html">AbstractRegexpSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/AbstractSwitchSelector.html">AbstractSwitchSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/BrowserSelector.html">BrowserSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/browser-selector.html">browser</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/CookieSelector.html">CookieSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.html">ComponentsSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/DateSelector.html">DateSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/date-selector.html">date</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/ExceptionSelector.html">ExceptionSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/language/generator/GeneratorSelector.html">GeneratorSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xsp</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/HeaderSelector.html">HeaderSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/HostSelector.html">HostSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/host-selector.html">host</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/mail/MailCommandSelector.html">MailCommandSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/selection/MediaSelector.html">MediaSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/NamedPatternsSelector.html">NamedPatternsSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/pipeline/OutputComponentSelector.html">OutputComponentSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/ParameterSelector.html">ParameterSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/parameter-selector.html">parameter</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/RegexpHeaderSelector.html">RegexpHeaderSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/regular-expression-header-selector.html">regular-expression-header</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/RegexpRequestParameterSelector.html">RegexpRequestParameterSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/RequestAttributeSelector.html">RequestAttributeSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/requestattribute-selector.html">requestattribute</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/RequestMethodSelector.html">RequestMethodSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/requestmethod-selector.html">requestmethod</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/RequestParameterSelector.html">RequestParameterSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/selectors/requestparameter-selector.html">requestparameter</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/ResourceExistsSelector.html">ResourceExistsSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/SessionAttributeSelector.html">SessionAttributeSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/SimpleSelector.html">SimpleSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/sitemap/SitemapComponentSelector.html">SitemapComponentSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/SwitchSelector.html">SwitchSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/selection/XPathExceptionSelector.html">XPathExceptionSelector</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+
+    
+<h2>Serializers</h2>
+<table>
+<!-- table: serializers -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/AbstractSerializer.html">AbstractSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/AbstractSerializer.html">AbstractSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/AbstractTextSerializer.html">AbstractTextSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/ElementProcessorSerializer.html">ElementProcessorSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">poi</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/serializers/EncodingSerializer.html">EncodingSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">serializers</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/EncodingSerializer.html">EncodingSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/FOPSerializer.html">FOPSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">fop</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/HSSFSerializer.html">HSSFSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">poi</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/HTMLSerializer.html">HTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/html-serializer.html">html</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/serializers/HTMLSerializer.html">HTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">serializers</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/HTMLSerializer.html">HTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/serialization/IncludingHTMLSerializer.html">IncludingHTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/iTextSerializer.html">iTextSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">itext</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/LinkSerializer.html">LinkSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/link-serializer.html">link</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/pcl-serializer.html">pcl</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/pdf-serializer.html">pdf</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/POIFSSerializer.html">POIFSSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">poi</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/ps-serializer.html">ps</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/RTFSerializer.html">RTFSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">jfor</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/Serializer.html">Serializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/SVGSerializer.html">SVGSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/svg-serializer.html">svg</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">batik</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/svgjpeg-serializer.html">svgjpeg</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/svgpng-serializer.html">svgpng</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/svgtiff-serializer.html">svgtiff</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/svgxml-serializer.html">svgxml</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/SWFSerializer.html">SWFSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">swf</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/TextSerializer.html">TextSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/text-serializer.html">text</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/vrml-serializer.html">vrml</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/wap-serializer.html">wap</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/xhtml-serializer.html">xhtml</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/serializers/XHTMLSerializer.html">XHTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">serializers</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/XHTMLSerializer.html">XHTMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/xls-serializer.html">xls</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/XMidiSerializer.html">XMidiSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">midi</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/XMLSerializer.html">XMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/xml-serializer.html">xml</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/sax/XMLSerializer.html">sax/XMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">serializers</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/components/serializers/XMLSerializer.html">XMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">serializers</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/garbage/serializer/XMLSerializer.html">XMLSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad/garbage</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/serialization/ZipArchiveSerializer.html">ZipArchiveSerializer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/serializers/ziparchive-serializer.html">ziparchive</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+</table>
+
+    
+<h2>Transformers</h2>
+<table>
+<!-- table: transformers -->
+
+<tr>
+  
+<th colspan="1" rowspan="1">Java source</th>
+  <th colspan="1" rowspan="1">Document</th>
+  <th colspan="1" rowspan="1">A</th>
+  <th colspan="1" rowspan="1">B</th>
+  <th colspan="1" rowspan="1">C</th>
+  <th colspan="1" rowspan="1">D</th>
+  <th colspan="1" rowspan="1">E</th>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/constrained/AbstractConstrainedTransformer.html">AbstractConstrainedTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/AbstractCopletTransformer.html">AbstractCopletTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/AbstractDOMTransformer.html">AbstractDOMTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/AbstractExtractionTransformer.html">AbstractExtractionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/AbstractSAXTransformer.html">AbstractSAXTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/transformation/AbstractSessionTransformer.html">AbstractSessionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/AbstractTransformer.html">AbstractTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/AugmentTransformer.html">AugmentTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/augment-transformer.html">augment</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/coplets/basket/BasketTransformer.html">BasketTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/BetwixtTransformer.html">BetwixtTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/CastorTransformer.html">CastorTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/CIncludeTransformer.html">CIncludeTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/cinclude-transformer.html">cinclude</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/CopletTransformer.html">CopletTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/DASLTransformer.html">DASLTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">webdav</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/DeliTransformer.html">DeliTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">deli</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/EncodeURLTransformer.html">EncodeURLTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/encodeurl-transformer.html">encodeurl</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/ErrorAwareTraxTransformer.html">ErrorAwareTraxTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/EventLinkTransformer.html">EventLinkTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/ExtendedParserTransformer.html">ExtendedParserTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/extractor-transformer.html">extractor</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1"></td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/FragmentExtractorTransformer.html">FragmentExtractorTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">batik</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/FilterTransformer.html">FilterTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/filter-transformer.html">filter</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/forms/transformation/FormsTemplateTransformer.html">FormsTemplateTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">forms</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/HTMLEventLinkTransformer.html">HTMLEventLinkTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/HTMLRootTransformer.html">HTMLRootTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/HTMLTransformer.html">HTMLTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">html</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/I18nTransformer.html">I18nTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/i18n-transformer.html">i18n</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/IncludeTransformer.html">IncludeTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/include-transformer.html">include</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">scratchpad</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/JPathTransformer.html">JPathTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/JXTemplateTransformer.html">JXTemplateTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/jx-template-transformer.html">jx-template</a></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/LDAPTransformer.html">LDAPTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/ldap-transformer.html">ldap</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">naming</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/LuceneIndexTransformer.html">LuceneIndexTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">lucene</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/LexicalTransformer.html">LexicalTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/lexer-transformer.html">lexer</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/LinkTransformer.html">LinkTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/LinkRewriterTransformer.html">LinkRewriterTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">linkrewriter</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/LogTransformer.html">LogTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/log-transformer.html">log</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/NewEventLinkTransformer.html">NewEventLinkTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/ParserTransformer.html">ParserTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/parser-transformer.html">parser</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/PatternTransformer.html">PatternTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/pattern-transformer.html">pattern</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">chaperon</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/ProxyTransformer.html">ProxyTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/ReadDOMSessionTransformer.html">ReadDOMSessionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/readdomsession-transformer.html">readdomsession</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/RoleFilterTransformer.html">RoleFilterTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/portal/transformation/RSSTransformer.html">RSSTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">portal</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/mail/transformation/SendMailTransformer.html">SendMailTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">mail</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/ServiceableTransformer.html">ServiceableTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/transformation/SessionTransformer.html">SessionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/transformation/SessionPostTransformer.html">SessionPostTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/webapps/session/transformation/SessionPreTransformer.html">SessionPreTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">session-fw</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/SimpleFormInstanceExtractionTransformer.html">SimpleFormInstanceExtractionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/SimpleFormTransformer.html">SimpleFormTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/SourcePropsWritingTransformer.html">SourcePropsWritingTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">repository</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/SourceWritingTransformer.html">SourceWritingTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/sourcewriting-transformer.html">sourcewriting</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/SQLTransformer.html">SQLTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/sql-transformer.html">sql</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">databases</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/TagTransformer.html">TagTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">taglib</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/Transformer.html">TraxTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/VariableRewriterTransformer.html">VariableRewriterTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">linkrewriter</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/Web3RfcTransformer.html">Web3RfcTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">web3</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/WriteDOMSessionTransformer.html">WriteDOMSessionTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/writedomsession-transformer.html">writedomsession</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/XIncludeTransformer.html">XIncludeTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/xinclude-transformer.html">xinclude</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/XMLDBTransformer.html">XMLDBTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"></td>
+  <!-- A --><td colspan="1" rowspan="1">n</td>
+  <!-- B --><td colspan="1" rowspan="1">xmldb</td>
+  <!-- C --><td colspan="1" rowspan="1">n</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+
+<tr>
+  <!-- 1 -->
+<td colspan="1" rowspan="1"><a href="../apidocs/org/apache/cocoon/transformation/TraxTransformer.html">TraxTransformer</a></td>
+  <!-- 2 --><td colspan="1" rowspan="1"><a href="../userdocs/transformers/xslt-transformer.html">xslt</a></td>
+  <!-- A --><td colspan="1" rowspan="1">y</td>
+  <!-- B --><td colspan="1" rowspan="1">core</td>
+  <!-- C --><td colspan="1" rowspan="1">y</td>
+  <!-- D --><td colspan="1" rowspan="1"></td>
+  <!-- E --><td colspan="1" rowspan="1"></td>
+
+</tr>
+      
+</table>
+    
+
+    
+<h1>To Do</h1>
+      
+<p>Not a list of everything to be done, just a few notes ...</p>
+      
+<ul>
+        
+<li>
+          Ask everyone to check the current table to see if any components
+          were missed. Before we do anything, we need to be sure that the
+          table is complete.
+        </li>
+        
+<li>
+           Perhaps there are some superfluous entries.
+        </li>
+        
+<li>
+          Create some complete entries to serve as examples and time estimates.
+        </li>
+        
+<li>
+          Review the
+          <a class="external" href="http://reports.linkalarm.com/855893764719/">LinkAlarm report</a> and fix broken links.
+        </li>
+        
+<li>
+          Document the procedure for reviewing a document/code and for
+          amending this table.
+        </li>
+        
+<li>
+          Enhance the SitemapTask.java
+        </li>
+        
+<li>
+          Add basic SitemapTask attributes to the java code for each compoent.
+          This could be
+          automated. Check if the SitemapTask.java copes with empty default
+          values. Add to column C.
+        </li>
+        
+<li>
+          Does SitemapTask scan the src/blocks/*.java ?
+        </li>
+        
+<li>
+          Some trouble with names (e.g. EncodeURLTransformer) needs doc name
+          lowercase (encodeurl-transformer). Perhaps need extra SitemapTask attribute or do toLower().
+        </li>
+        
+<li>
+          Investigate docs in blocks. The "mail" block has some.
+        </li>
+        
+<li>
+          Reduce the length of labels in the left-hand-panel of the documents,
+          e.g. "Transformer" =&gt; "Tr" or delete the word entirely.
+          In the generated */book.xml files.
+        </li>
+        
+<li>
+          Develop tools to analyse the table and ensure that it remains
+          synchronised. See the script in the repository at:
+          tools/review-sitemap-docs/correlate-table.sh
+        </li>
+        
+<li>
+          Monitor the email discussion on the cocoon-dev mailing list:
+          <a class="external" href="http://thread.gmane.org/gmane.text.xml.cocoon.devel/44203">review of sitemap component documentation</a>
+        
+</li>
+<!--
+        <li>
+        </li>
+-->
+      
+</ul>
+      
+<p>Other notes...</p>
+      
+<p>The "@cocoon.sitemap.component.documentation.caching" tag cannot be
+       the last element or it will suck the rest of the javadoc description
+       in with it.</p>
+      
+<p>Be careful with "@cocoon.sitemap.component.name" - it is also used
+      for another purpose.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/meta.xml
new file mode 100644
index 0000000..f7a1e44
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-review-sitemap-docs/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/review-sitemap-docs.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/content_en.html
new file mode 100644
index 0000000..5210aab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/content_en.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Release Plan</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Planning Documentation" name="DC.Subject">
+<meta content="The Cocoon Community" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Timeframe</h1>
+  
+<p>This is the current time frame for the next releases:</p>
+  
+<ul>
+   
+<li>Not schedulded yet: 2.1.7 (maintenance release)</li>
+   
+<li>Not schedulded yet: 2.2M1 (Milestone 1)</li>
+  
+</ul>
+ 
+
+ 
+<h1>Roadmap</h1>
+   
+<p>
+     In general, the next Cocoon version 2.2 can be seen as the 
+     "consolidation version". In the past a lot of new features, blocks
+     and components were added which resulted in the fact that 
+     in some places concurring solutions were developed that could be 
+     combined a little bit.
+   </p>
+   
+<p>
+     One good example is form handling where we now are concentrating 
+     on CForms. We will try this in other areas as well. Of course this 
+     does not mean that we won't add new features to 2.2, but we try to 
+     consolidate what we currently have as well.
+   </p>   
+   
+<p>
+     The follow is a list of items that are planned for the next minor release
+     of Cocoon (2.2). This is a dynamic list that might change over time :)
+   </p>
+   
+<p>
+     We have come to the conclusion that real blocks might take a little bit 
+     longer than we have expected. So we agreed on not affecting the current 
+     development of Cocoon by the real blocks development. Which means we have 
+     to develop the blocks system separately from Cocoon until the block 
+     system is stable enough to be "merged" into Cocoon. This allows us to 
+     release new versions of Cocoon (like 2.2) without waiting for blocks to 
+     be working/finished.
+   </p>
+   
+<ul>
+     
+<li>Official Versioning Guide (will be published soon).</li>
+     
+<li>Virtual Sitemap Components.</li>
+     
+<li>First finished version of CForms.</li>
+     
+<li>Deprecate (not remove!) XSP (and provide a viable alternative).</li>
+     
+<li>Cleaning up the caching/store mess.</li>
+     
+<li>Deprecate blocks that haven't been maintained in a long while 
+        or don't serve any evident purpose. Web3, Apples, Python,
+        Asciiart might be some candidates. We will decide this on a 
+        case-by-case basis.
+     </li>
+     
+<li>Differentiate between blocks that provide a service to other 
+        blocks and blocks that contain just samples or small applications 
+        built upon cocoon (petstore, tour, linotpye). Maybe "samples-only" 
+        blocks should be a separate download. Perhaps remove deprecated blocks etc.
+     </li>
+     
+<li>
+       Review the implications and the implementation of pooling.
+     </li>
+     
+<li>
+       Reduce unneeded dependencies on Avalon, where possible.
+     </li>
+     
+<li>
+       Review the logging framework. Log4j is the de-facto standard and 
+       we have blocks that complain if Log4j is not properly configured, 
+       so let's accept it and stop reinventing the wheel.
+     </li>
+     
+<li>
+       Write more tests (you knew this one was coming ;-) ).
+     </li>
+   
+</ul>
+   
+<p>
+     The <a href="updating.html">updating to 2.2</a> document contains 
+     more information on how to prepare your application for the next minor
+     release.
+   </p>
+  
+
+  
+<h1>The Future</h1>
+    
+<p>
+      We already have plans for further versions of Cocoon that might be 
+      long in the future...
+    </p>
+    
+<ul>
+      
+<li>Design and implement blocks.</li>
+      
+<li>Integrate Kernel into the Cocoon core.</li>
+    
+</ul>
+  
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/meta.xml
new file mode 100644
index 0000000..be92bd6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-roadmap/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/roadmap.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/content_en.html
new file mode 100644
index 0000000..6cb9c57
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/content_en.html
@@ -0,0 +1,167 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>How to run and explore the Cocoon samples</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bertrand Delacr&eacute;taz" name="DC.Creator">
+</head>
+<body>
+
+        
+<h1>Overview</h1>
+            
+<p>
+                This How-To shows you how to run and explore the Cocoon samples. It requires no
+                prior knowledge of Cocoon.
+            </p>
+        
+
+        
+<h1>Purpose</h1>
+            
+<p>
+                You will learn how install and run Cocoon in the simplest way, in order to run the Cocoon samples, and
+                also how to study the samples from the inside to see how their are built.
+            </p>
+        
+
+        
+<h1>Intended Audience</h1>
+            
+<p>
+                Beginning Cocoon users or people evaluating Cocoon for the first time.
+            </p>
+        
+
+        
+<h1>Prerequisites</h1>
+            
+<p>You only need a JDK (1.3 or later) installed on your computer, and an Internet connection
+                to download Cocoon.</p>
+
+        
+
+        
+<h1>Steps</h1>
+            
+<p>
+                Here's how to proceed.
+            </p>
+
+            
+<h2>1. Get Cocoon</h2>
+<p>
+                    Download Cocoon from the location listed on the
+                    <a class="external" href="http://cocoon.apache.org">cocoon.apache.org</a>
+                    web site.
+                </p>
+<div class="note">
+                    If you want the latest bleeding edge version, you can get it from CVS, this is described on
+                    the site as well, but more complicated if you're not familiar with CVS.
+                </div>
+
+            
+<h2>2. Build and start Cocoon</h2>
+<p>
+                    Unpack the Cocoon distribution and follow the instructions found in the
+                    <em>INSTALL.txt</em> file to build
+                    Cocoon.
+                </p>
+<div class="note">
+                    If you have done this previously, make sure to remove any local.* configuration files that you
+                    might have created. You usually want to activate all Cocoon components to look at the samples,
+                    and local.* files might disable some components or even disable the samples.
+                </div>
+<div class="note">
+                    Also, if you have already built Cocoon with a different configuration before, you might need to
+                    do a "build clean" first, to prevent any conflicts between different configurations.
+
+                </div>
+<p>
+                    The INSTALL.txt file also contains instructions for starting Cocoon with the <em>cocoon.sh</em> or
+                    <em>cocoon.bat</em> script, which is the simplest way and is sufficient to explore the samples.
+                </p>
+
+            
+<h2>3. Access the samples</h2>
+<p>
+                    Once Cocoon starts (and assuming you have kept the standard configuration), point your browser
+                    at http://localhost:8888, this should show the "Welcome to Apache Cocoon" page. On this page,
+                    click the
+                    <em>samples</em> link.
+                </p>
+<p>
+                    You should now see a page with links to many samples (
+                    <em>Hello World!</em>, etc.), which show you what Cocoon is about.
+                    Note that there are several categories of samples: do not forget to look at the
+                    <em>blocks
+                        with samples</em> page, which contains samples based on components which are not part of the Cocoon core.
+                </p>
+<p>
+                    Another category is the
+                    <em>scratchpad</em> samples , these are based on experimental
+                    components that might or might not be included later in the Cocoon core or in a Cocoon block.
+                </p>
+
+            
+<h2>4. Study the samples</h2>
+<p>
+                    Now comes the interesting part: looking at the samples innards to find out how they are built.
+                </p>
+<p>
+                    This is fairly simple as the directory structure of the samples is similar to the URLs
+                    used to access the samples. These simple rules should help you find out much more about
+                    the samples:
+                </p>
+<ul>
+                        
+<li>If using the standard build configuration, samples are found under the
+                            <em>build/webapp/samples</em> directory. That's where you want to look
+                            to find out how a particular sample works.
+                        </li>
+                        
+<li>Under this directory, the pathnames are the same than after the
+                            <em>http://localhost:8888/samples</em> base URL. The
+                            midi block samples, for example, are accessed from
+                            <em>http://localhost:8888/samples/midi</em>
+                            and the corresponding files are found under
+                            <em>build/webapp/samples/midi</em>.
+                        </li>
+                        
+<li>
+                            When studying how a sample is built, it is recommended to first study its <em>sitemap.xmap</em>
+                            files, which map incoming requests to pipelines.
+                        </li>
+                    
+</ul>
+        
+
+        
+<h1>Conclusion</h1>
+            
+<p>
+                We hope that this How-To will help you explore the samples yourself, as this
+                is probably the best way of learning about Cocoon.
+            </p>
+            
+<p>
+                Do not forget to look at the reference documentation though, once you have found
+                out which Cocoon components you need for your application.
+            </p>
+        
+
+        
+<h1>Comments</h1>
+          
+<p>
+              Care to comment on this How-To?
+              Help keep this document relevant by passing along any constructive feedback to the
+              <a href="mailto:docs.at.cocoon.apache.org?subject=howto-explore-samples:">cocoon-docs</a>
+              mailing list.
+          </p>
+        
+
+    
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/meta.xml
new file mode 100644
index 0000000..1fe5e27
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-samples/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>howto/howto-explore-samples.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/content_en.html
new file mode 100644
index 0000000..61f16ca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/content_en.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Selectors</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Gianugo Rabellino" name="DC.Creator">
+<meta content="Diana Shannon, ed." name="DC.Creator">
+<meta content="This document describes all of the available selectors of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+      
+<p>
+      This document lists all of the available selectors of Apache Cocoon and
+      describes their purpose.
+      You may also wish to read  
+      <a href="../concepts/matchers_selectors.html">Using and Implementing
+      Matchers and Selectors</a>.
+      </p>
+     
+     
+<h1>Overview</h1>
+      
+<p>
+      Selectors in Apache Cocoon have a role similar to matchers 
+      with additional flexibility. If you haven't learned about
+      matchers yet, read about them <a href="../matchers/matchers.html">here</a>
+      before continuing. Selectors are designed to evaluate a 
+      generally simple boolean expression regarding some
+      part of the environment (request URI, headers, or cookies, for example). 
+      The result of this evaluation determines which pipeline fragments 
+      should be combined within a given pipeline. Unlike matchers, 
+      selectors can be active decision-driving components.
+      For example, a matcher makes only simple 
+      "yes/no" decisions. If a match is successful, a 
+      pipeline is executed. If not, it is ignored. 
+      Selectors go further by allowing more complex, multiple-choice
+      use cases. In short, consider matchers to be simple "if" 
+      statements. By extension, consider selectors to have all
+      the power of an "if-else if-else" or "switch-case" constructs.
+      The selector syntax should be familiar to anyone who
+      uses XSLT's <span class="codefrag">&lt;xsl:choose&gt;</span> statement.
+      </p>
+      
+<p>
+      As an example, consider the typical scenario in which a page should
+      be rendered differently based on the client browser. 
+      Given the large number and diversity of available browsers, 
+      it would be awkward and counterintuitive to address this need
+      with a set of matchers. The BrowserSelector tests a given parameter
+      against the user-agent request header. Using this single selector, 
+      we can deploy a consistent and readable setup.
+      </p>
+
+<pre class="code">
+
+&lt;map:match pattern="docs/*.html"&gt;
+  &lt;map:generate src="xdocs/{1}.xml"/&gt;
+ 
+  &lt;map:select type="browser"&gt;
+    &lt;map:when test="netscape"&gt;
+      &lt;map:transform src="stylesheets/netscape.xsl" /&gt;
+    &lt;/map:when&gt;
+    &lt;map:when test="explorer"&gt;
+      &lt;map:transform src="stylesheets/ie.xsl" /&gt;
+    &lt;/map:when&gt;
+    &lt;map:when test="lynx"&gt;
+      &lt;map:transform src="stylesheets/text-based.xsl" /&gt;
+    &lt;/map:when&gt;
+    &lt;map:otherwise&gt;
+      &lt;map:transform src="stylesheets/html.xsl" /&gt;
+    &lt;/map:otherwise&gt;
+  &lt;/map:select&gt;
+
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+
+</pre>
+      
+     
+     
+<h1>The Selectors in Cocoon</h1>
+      
+<p>
+      Available Selectors in Cocoon include the following:
+      </p>
+      
+<ul>
+        
+<li>
+<strong>BrowserSelector</strong>: matches the value of the "test"
+        parameter against the HTTP User-Agent header, allowing it to 
+        recognize the browser issuing the request;</li>
+        
+        
+<li>
+<strong>CodeSelector</strong>: matches a snippet of Java code
+        given as the "test" parameter against the environment;</li>
+
+        
+<li>
+<strong>HostSelector</strong>: matches the "test" parameter value
+        against the Host request header</li>
+
+        
+<li>
+<a href="parameter-selector.html">ParameterSelector</a>: matches the string specified
+        in the "test" parameter against a specified Cocoon internal
+        (e.g. sitemap) parameter;</li>
+
+        
+<li>
+<strong>HeaderSelector</strong>: same as the Parameter selector,
+        but matches against the request headers;</li>
+
+        
+<li>
+<a href="regular-expression-header-selector.html">RegexpHeaderSelector</a>: same as the Header selector,
+        but uses a regular expression for matching;</li>
+
+        
+<li>
+<strong>RequestSelector</strong>: again, same as the Parameter selector,
+        but matches against the Request parameters;</li>
+
+        
+<li>
+<strong>SessionSelector</strong>: finally, this selector is used as
+        the Parameter selector to match against an arbitrary session
+        attribute;</li>
+
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/meta.xml
new file mode 100644
index 0000000..9722b5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-selectors/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/selectors/selectors.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/content_en.html
new file mode 100644
index 0000000..cb0b155
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/content_en.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Serializers</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes all of the available serializers of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+      
+<p>
+        This document lists all of the available serializers of Apache Cocoon and
+        describes their purpose.
+      </p>
+    
+    
+<h1>Overview</h1>
+      
+<p>
+        A serializer is the end point of an xml pipeline. 
+        It transforms SAX events into binary or char streams for 
+        final client consumption. 
+        Every pipeline match containing a generator must be terminated 
+        by a serializer. 
+      </p>
+      
+<p>
+        In the sitemap file, each serializer has a unique name which 
+        is mapped to a java class. 
+        One serializer name must be declared as the default serialzer. 
+        Each serializer may have additional configuration information 
+        specified in child elements.
+      </p>
+      
+<p>
+        For more conceptual information about serializers 
+        see <a href="../concepts/sitemap.html">the sitemap</a>.
+      </p>
+    
+    
+<h1>The Serializers in Apache Cocoon</h1>
+      
+<ul>
+        
+<li>
+<a href="html-serializer.html">HTML Serializer</a> (The default serializer)</li>
+        
+<li>
+<a href="xhtml-serializer.html">XHTML Serializer</a>
+</li>
+        
+<li>
+<a href="xml-serializer.html">XML Serializer</a>
+</li>
+        
+<li>
+<a href="text-serializer.html">Text Serializer</a>
+</li>
+        
+<li>
+<a href="xls-serializer.html">HSSF (XLS) Serializer</a> (optional)</li>
+        
+<li>
+<a href="pdf-serializer.html">PDF Serializer</a> (optional)</li>
+        
+<li>
+<a href="ps-serializer.html">PS Serializer</a> (optional)</li>
+        
+<li>
+<a href="pcl-serializer.html">PCL Serializer</a> (optional)</li>
+        
+<li>
+<a href="wap-serializer.html">WAP/WML Serializer</a>
+</li>
+        
+<li>
+<a href="svg-serializer.html">SVG Serializer</a>
+</li>
+        
+<li>
+<a href="svgxml-serializer.html">SVG/XML Serializer</a>
+</li>
+        
+<li>
+<a href="svgjpeg-serializer.html">SVG/JPEG Serializer</a>
+</li>
+        
+<li>
+<a href="svgpng-serializer.html">SVG/PNG Serializer</a>
+</li>
+        
+<li>
+<a href="svgtiff-serializer.html">SVG/TIFF Serializer</a>
+</li>
+        
+<li>
+<a href="vrml-serializer.html">VRML Serializer</a>
+</li>
+        
+<li>
+<a href="link-serializer.html">Link Serializer</a>
+</li>
+        
+<li>
+<a href="ziparchive-serializer.html">Zip archive Serializer</a>
+</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/meta.xml
new file mode 100644
index 0000000..597388f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-serializers/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/serializers.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/content_en.html
new file mode 100644
index 0000000..a4472b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/content_en.html
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Example sitemap snippets</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Explanations of some sitemaps" name="DC.Subject">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview</h1>
+  
+<p>
+   The following explanations describe how some sections of the sitemaps
+   operate. For overview, see the general
+   <a href="sitemap.html">Sitemap</a> document and the specific
+   userdocs.
+  </p>
+ 
+
+ 
+<h1>C2 documentation</h1>
+  
+<p>
+   The Cocoon documentation XML files are located at 
+   <span class="codefrag">documentation/xdocs/*.xml</span> and sub-directories.
+   The sitemap at <span class="codefrag">documentation/sitemap.xmap</span> does most of the
+   work. It is used by <span class="codefrag">build docs</span> and it also mounted by the
+   main sitemap to handle requests for documentation as a servlet.
+  </p>
+
+  
+<p>
+   Each match is presented and described in turn.
+  </p>
+
+
+<pre class="code">
+Match #1 ...
+   &lt;!-- ================  C2 documentation  ================= --&gt;
+   &lt;map:match pattern=""&gt;
+    &lt;map:redirect-to uri="index.html"/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   Just a convenience for redirecting the null pattern to the home page.
+  </p>
+
+
+<pre class="code">
+Match #2 ...
+   &lt;map:match pattern="*.html"&gt;
+    &lt;map:aggregate element="site"&gt;
+     &lt;map:part src="cocoon:/book-{1}.xml"/&gt;
+     &lt;map:part src="cocoon:/body-{1}.xml"/&gt;
+    &lt;/map:aggregate&gt;
+    &lt;map:transform src="stylesheets/site2xhtml.xsl"&gt;
+     &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+     &lt;map:parameter name="header" value="graphics/{1}-header.jpg"/&gt;
+    &lt;/map:transform&gt;
+    &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   Generates the response for a top-level page (e.g. index.html).
+   Note that lower-level pages (e.g. userdocs/index.html) do not match
+   here and are processed in a similar way by Match #3.
+  </p>
+
+  
+<p>
+   Each document is composed of two separate parts: the side-panel menu and
+   the actual page content. Each part is build separately and then aggregated.
+   Consider the example of the home page (index.html). 
+   The side-panel content comes from <span class="codefrag">documentation/xdocs/book.xml</span>
+   (and is handled by the pipeline <span class="codefrag">book-index.xml</span>).
+   The actual page content comes from <span class="codefrag">documentation/xdocs/index.xml</span>
+   (and is handled by the pipeline <span class="codefrag">body-index.xml</span>).
+  </p>
+
+  
+<p>
+   So Match #2 generates an intermediate XML file by aggregating the XML output
+   from the two pipelines and wrapping it with a <span class="codefrag">&lt;site&gt;</span>
+   element. (The <span class="codefrag">cocoon:/</span> protocol means "Use the relevant
+   pipeline from the current sitemap".)
+   The output stream is then transformed to XHTML and serialized.
+  </p>
+
+
+<pre class="code">
+Match #3 ...
+   &lt;map:match pattern="**/*.html"&gt;
+    &lt;map:aggregate element="site"&gt;
+     &lt;map:part src="cocoon:/{1}/book-{1}/{2}.xml"/&gt;
+     &lt;map:part src="cocoon:/body-{1}/{2}.xml"/&gt;
+    &lt;/map:aggregate&gt;
+    &lt;map:transform src="stylesheets/site2xhtml.xsl"&gt;
+       &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+       &lt;map:parameter name="header" value="graphics/{2}-header.jpg"/&gt;
+     &lt;/map:transform&gt;
+    &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   This is similar to Match #2, except that it deals with documents in
+   sub-directories. For the side-panel, this uses the <span class="codefrag">book.xml</span>
+   found in each relevant directory.
+  </p>
+
+
+<pre class="code">
+Match #4 ...
+   &lt;map:match pattern="**book-**.xml"&gt;
+     &lt;map:generate src="xdocs/{1}book.xml"/&gt;
+       &lt;map:transform src="stylesheets/book2menu.xsl"&gt;
+         &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+         &lt;map:parameter name="resource" value="{2}.html"/&gt;
+       &lt;/map:transform&gt;
+     &lt;map:serialize type="xml"/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   This produces the additional structured content for the relevant
+   side-panel menu. Note that this is the only match that serializes to
+   XML (the others have the default HTML).
+  </p>
+
+  
+<p>
+   In essence, this Match #4 is called from Match #2 via the
+   <span class="codefrag">cocoon:/</span> protocol and is aggregated with the output of Match #6
+  </p>
+
+
+<pre class="code">
+Match #5 ...
+   &lt;map:match pattern="body-todo.xml"&gt;
+     &lt;map:generate src="xdocs/todo.xml"/&gt;
+     &lt;map:transform src="stylesheets/todo2document.xsl"/&gt;
+     &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+
+   &lt;map:match pattern="body-changes.xml"&gt;
+     &lt;map:generate src="xdocs/changes.xml"/&gt;
+     &lt;map:transform src="stylesheets/changes2document.xsl"/&gt;
+     &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+
+   &lt;map:match pattern="body-faq.xml"&gt;
+     &lt;map:generate src="xdocs/faq.xml"/&gt;
+     &lt;map:transform src="stylesheets/faq2document.xsl"/&gt;
+     &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   These matches are for special cases. Note that they are defined before
+   the general body-*.xml match. Remember that the sitemap reads from top to
+   bottom and the first encountered match is used.
+  </p>
+
+  
+<p>
+   These special-cases need to transform the content into XML files that
+   conform to document-v10.dtd first.
+  </p>
+
+
+<pre class="code">
+Match #6 ...
+   &lt;map:match pattern="body-**.xml"&gt;
+     &lt;map:generate src="xdocs/{1}.xml"/&gt;
+     &lt;map:transform src="stylesheets/document2html.xsl"/&gt;
+     &lt;map:serialize/&gt;
+   &lt;/map:match&gt;
+</pre>
+
+  
+<p>
+   This match handles the bodies of all other the other documents
+   (which are natively conforming to document-v10.dtd).
+  </p>
+
+  
+<p>
+   In essence, this Match #6 is called from Match #2 via the
+   <span class="codefrag">cocoon:/</span> protocol and is aggregated with the output of Match #4
+  </p>
+
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/meta.xml
new file mode 100644
index 0000000..23afd89
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap-examples/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/sitemap-examples.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/content_en.html
new file mode 100644
index 0000000..a99ffae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/content_en.html
@@ -0,0 +1,1270 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The Sitemap</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Giacomo Pati" name="DC.Creator">
+<meta content="Stefano Mazzocchi" name="DC.Creator">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>The Sitemap</h1>
+   
+<h2>Introduction</h2>
+<p>
+     This document describes the Cocoon sitemap concept in full details, why
+     it's there, what it does, how it works and how you can use it.
+    </p>
+<div class="note">
+     See the <a href="../index.html">User documentation</a>
+     for details about configuration of each sitemap component.
+     See the <a href="sitemap-examples.html">Example sitemap snippets</a>.
+     Explore each <span class="codefrag">sitemap.xmap</span> in the distribution, to see
+     how the various situations are handled.
+    </div>
+
+   
+<h2>Goals</h2>
+<p>
+     The goal of the sitemap is to allow non-programmers to create web sites
+     and web applications built from logic components and XML documents.
+    </p>
+<p>
+     It finds inspiration from both Apache's httpd.conf/.htaccess files as well
+     as from Servlet API 2.2 WAR archives. It uses concepts such as Cascading
+     from W3C CSS, as well as declarative approaches integrated into the W3C 
+     XSLT language. It also uses some element/attribute equivalence patterns 
+     used in W3C RDF.
+    </p>
+<p>
+     The following goals were identified as engineering constraints:
+    </p>
+<ol>
+     
+<li>minimal verbosity is of maximum importance.</li>
+     
+<li>the schema should be sufficiently expressive to allow learning by
+      examples.</li>
+     
+<li>sitemap authoring should not require assistive tools, but be
+      sufficiently future-compatible to allow them.</li>
+     
+<li>sitemaps must scale along with the site and should not impose growth
+      limitation to the site as a whole nor limit its administration with size
+      increase.</li>
+     
+<li>sitemaps should contain all the information required to Cocoon to
+      generate all the requests it receives.</li>
+     
+<li>sitemaps should contain information for both dynamic operation as
+      well as offline generation.</li>
+     
+<li>uri mapping should be powerful enough to allow every possible mapping
+      need.</li>
+     
+<li>basic web-serving functionalities (redirection, error pages,
+      resource authorisation) should be provided.</li>
+     
+<li>sitemaps should not limit Cocoon's intrinsic modular extensibility.</li>
+     
+<li>resources must be matched with all possible state variables, not
+      only with URI (http parameters, environment variables, server
+      parameters, time, etc...).</li>
+     
+<li>sitemaps should embed the notion of "semantic resources" to be
+      future-compatible with semantic crawling and indexing.</li>
+     
+<li>sitemaps should be flexible enough to allow a complete web site to
+      be built with Cocoon.</li>
+    
+</ol>
+
+   
+<h2>The Structure</h2>
+<p>
+     The Sitemap has the following general structure:
+    </p>
+<pre class="code">&lt;?xml version="1.0"?&gt;
+  &lt;map:sitemap 
+      xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+    &lt;map:components/&gt;
+    &lt;map:views/&gt;
+    &lt;map:resources/&gt;
+    &lt;map:action-sets/&gt;
+    &lt;map:pipelines/&gt;
+  &lt;/map:sitemap&gt; </pre>
+
+   
+<h2>The &lt;map:sitemap&gt;</h2>
+<pre class="code">&lt;map:sitemap 
+    xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt; </pre>
+<p>
+     The default namespaces are used mainly for versioning, instead of using 
+     attributes such as version="1.0" which could create confusion. People are 
+     used to writing URIs with no spelling mistakes, while versioning could be 
+     used for their own sitemap versions and this might break operation.
+    </p>
+<p>  
+     The versioning schema will be "major.minor" where major will be increased
+     by one each time a new release breaks backwards compatibility, while minor
+     is increased each time a change has been made that doesn't create
+     backwards compatibility problems.
+    </p>
+
+   
+<h2>The &lt;map:components&gt;</h2>
+<pre class="code">
+  &lt;map:components&gt;
+    &lt;map:generators/&gt;
+    &lt;map:transformers/&gt;
+    &lt;map:serializers/&gt;
+    &lt;map:readers/&gt;
+    &lt;map:selectors/&gt;
+    &lt;map:matchers/&gt;
+    &lt;map:actions/&gt;
+    &lt;map:pipes/&gt;
+  &lt;/map:components&gt; </pre>
+<h3>Common Attributes of Components</h3>
+<p>
+      All components have some common attributes. The list below will show and explain them:
+     </p>
+<dl>
+      
+<dt>name</dt>
+      
+<dd>Gives the component an identifying name by which it may be referenced in the pipeline section.</dd>
+      
+<dt>src</dt>
+      
+<dd>Specifies the class implementing this component.</dd>
+     
+</dl>
+<h3>Component Parameters</h3>
+<p>
+      All components are configured with parameters specified in their child elements at component instantiation time.
+      The following example shows how to specify a <span class="codefrag">&lt;use-request-parameter&gt;</span> parameter for an XSLT
+      transformation component: </p>
+<pre class="code">
+
+&lt;map:components&gt;
+  &lt;map:transformer name="xslt"
+     src="org.apache.cocoon.transformation.TraxTransformer"&gt;
+     &lt;!-- This is a parameter to the transformer component --&gt;
+     &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+  &lt;/map:transformer&gt;
+&lt;/map:components&gt; </pre>
+<p>
+       The name and meaning of the parameters are dependent on the component.
+     </p>
+<h3>Generators</h3>
+<p>
+      A <a href="#interface-generator"><span class="codefrag">Generator</span></a> generates XML content as SAX events and initializes the pipeline processing. 
+     </p>
+<pre class="code">
+
+&lt;map:generators default="file"&gt;
+  &lt;map:generator name="file"
+    src="org.apache.cocoon.generation.FileGenerator"/&gt;
+  &lt;map:generator name="dir"
+    src="MyDirGenerator"/&gt;
+  &lt;map:generator name="serverpages"
+    src="org.apache.cocoon.generation.ServerPagesGenerator"&gt;
+   ...
+  &lt;/map:generator&gt;
+&lt;/map:generators&gt; </pre>
+<p>
+      The <span class="codefrag">default</span> attribute on <span class="codefrag">&lt;map:generators&gt;</span> specifies the type 
+      of generator to use if none is specified in a pipeline.
+     </p>
+<h3>Transformers</h3>
+<p>
+      A <a href="#interface-transformer"><span class="codefrag">Transformer</span></a> transforms SAX events into other SAX events.
+     </p>
+<pre class="code">
+
+&lt;map:transformers default="xslt"&gt;
+  &lt;map:transformer name="xslt" 
+      src="org.apache.cocoon.transformation.TraxTransformer"&gt;
+    &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+    &lt;use-browser-capabilities-db&gt;false
+        &lt;/use-browser-capabilities-db&gt;
+  &lt;/map:transformer&gt;
+  &lt;map:transformer name="xinclude" 
+  src="org.apache.cocoon.transformation.XIncludeTransformer"/&gt;
+&lt;/map:transformers&gt; </pre>
+<p>
+      The <span class="codefrag">default</span> attribute on <span class="codefrag">&lt;map:transformers&gt;</span> specifies the type 
+      of transformer to use if none is specified in a pipeline.
+     </p>
+<h3>Serializers</h3>
+<p>
+      A <a href="#interface-serializer"><span class="codefrag">Serializer</span></a> transforms SAX events 
+      in binary or char streams for final client consumption.
+     </p>
+<pre class="code">
+
+&lt;map:serializers default="html"&gt;
+  &lt;map:serializer name="html" mime-type="text/html" 
+         src="org.apache.cocoon.serialization.HTMLSerializer"&gt;
+    &lt;doctype-public&gt;-//W3C//DTD HTML 4.0 Transitional//EN
+      &lt;/doctype-public&gt;
+    &lt;doctype-system&gt;http://www.w3.org/TR/REC-html40/loose.dtd
+      &lt;/doctype-system&gt;
+    &lt;omit-xml-declaration&gt;true&lt;/omit-xml-declaration&gt;
+    &lt;encoding&gt;UTF-8&lt;/encoding&gt;
+    &lt;indent&gt;1&lt;/indent&gt;
+  &lt;/map:serializer&gt;
+
+  &lt;map:serializer name="wap" mime-type="text/vnd.wap.wml" 
+         src="org.apache.cocoon.serialization.XMLSerializer"&gt;
+    &lt;doctype-public&gt;-//WAPFORUM//DTD WML 1.1//EN
+      &lt;/doctype-public&gt;
+    &lt;doctype-system&gt;http://www.wapforum.org/DTD/wml_1.1.xml
+      &lt;/doctype-system&gt;
+    &lt;encoding&gt;UTF-8&lt;/encoding&gt;
+  &lt;/map:serializer&gt;
+
+  &lt;map:serializer name="svg2jpeg" mime-type="image/jpeg" 
+         src="org.apache.cocoon.serialization.SVGSerializer"&gt;
+    &lt;parameter name="background_color" 
+               type="color" value="#00FF00"/&gt;
+  &lt;/map:serializer&gt;
+
+  &lt;map:serializer name="svg2png" mime-type="image/png" 
+          src="org.apache.cocoon.serialization.SVGSerializer"&gt;
+  &lt;/map:serializer&gt;
+&lt;/map:serializers&gt; </pre>
+<p>
+      The <span class="codefrag">default</span> attribute on <span class="codefrag">&lt;map:serializers&gt;</span> specifies the type 
+      of serializer to use if none is specified in a pipeline.
+     </p>
+<h3>Selectors</h3>
+<p>
+       A <a href="#interface-selector"><span class="codefrag">Selector</span></a> is used to implement basic
+       conditional logic (<span class="codefrag">if-then-else</span> or <span class="codefrag">switch</span>) inside the sitemap.
+       As can be seen in the <a href="#interface-selector"><span class="codefrag">Selector</span></a>
+       interface, this functionality decomposes into the ability to evaluate a boolean
+       condition.</p>
+<pre class="code">
+
+&lt;map:selectors default="browser"&gt;
+  &lt;map:selector name="load"
+      src="org.apache.cocoon.selection.MachineLoadSelector"&gt;
+   ...
+  &lt;/map:selector&gt;
+
+  &lt;map:selector name="user"
+    src="org.apache.cocoon.selection.AuthenticationSelector"&gt;
+   ...
+  &lt;/map:selector&gt;
+
+  &lt;map:selector name="browser" 
+           src="org.apache.cocoon.selection.BrowserSelector"&gt;
+    &lt;browser name="explorer" useragent="MSIE"/&gt;
+    &lt;browser name="lynx" useragent="Lynx"/&gt;
+    &lt;browser name="mozilla5" useragent="Mozilla/5"/&gt;
+    &lt;browser name="mozilla5" useragent="Netscape6/"/&gt;
+    &lt;browser name="netscape" useragent="Mozilla"/&gt;
+   ...
+  &lt;/map:selection&gt;
+&lt;/map:selection&gt; </pre>
+<p>
+      The <span class="codefrag">default</span> attribute on <span class="codefrag">&lt;map:selectors&gt;</span> specifies the type 
+      of selector to use if none is specified in a pipeline.
+     </p>
+<h3>Matchers</h3>
+<p>
+      A <a href="#interface-matcher"><span class="codefrag">Matcher</span></a> maps a pattern to a resource.
+     </p>
+<pre class="code">
+
+&lt;map:matchers default="wildcard"&gt;
+  &lt;map:matcher name="wildcard" 
+          src="org.apache.cocoon.matching.WildcardURIMatcher"&gt;
+   ...
+  &lt;/map:matcher&gt;
+
+  &lt;map:matcher name="regexp" 
+          src="org.apache.cocoon.matching.RegexpURIMatcher"&gt;
+   ...
+  &lt;/map:matcher&gt;
+&lt;/map:matchers&gt; </pre>
+<p>
+      The <span class="codefrag">default</span> attribute on <span class="codefrag">&lt;map:matchers&gt;</span> specifies the type 
+      of matcher to use if none is specified in a pipeline.
+     </p>
+<h3>Actions</h3>
+<p>
+      An <a href="#interface-action"><span class="codefrag">Action</span></a> is a sitemap component
+      that manipulates runtime parameters based on request and application state.
+      An Action's result is available in the sitemap as map of name/value pairs.
+      Detailed information on actions may be found in <a href="actions.html">the Actions
+      section</a>.
+     </p>
+<pre class="code">
+
+&lt;map:actions&gt;
+  &lt;map:action name="add-employee"
+          src="org.apache.cocoon.acting.DatabaseAddAction"/&gt;
+  &lt;map:action name="locale"
+          src="org.apache.cocoon.acting.LocaleAction"/&gt;
+  &lt;map:action name="request"
+          src="org.apache.cocoon.acting.RequestParamAction"/&gt;
+  &lt;map:action name="form-validator"
+          src="org.apache.cocoon.acting.FormValidatorAction"/&gt;
+&lt;/map:actions&gt; </pre>
+
+   
+<h2>The &lt;map:views&gt;</h2>
+<p>
+     The <span class="codefrag">&lt;map:view&gt;</span> element defines different view
+     of the site. Views are defined independent of pipelines and might
+     be used with any pipeline defined in the sitemap. For more on views 
+     read <a href="views.html">the Views section</a>.
+    </p>
+<pre class="code">
+
+&lt;map:views&gt;
+  &lt;map:view name="content" from-label="content"&gt;
+    &lt;map:serialize type="xml"/&gt;
+  &lt;/map:view&gt;
+
+  &lt;map:view name="links" from-position="last"&gt;
+    &lt;map:serialize type="links"/&gt;
+  &lt;/map:view&gt;
+&lt;/map:views&gt; </pre>
+
+   
+<h2>The &lt;map:resources&gt;</h2>
+<p>
+     The <span class="codefrag">&lt;map:resource&gt;</span> element is used as a placeholder for pipelines
+     that are used several times inside the document.
+    </p>
+<pre class="code">
+
+&lt;map:resources&gt;
+  &lt;map:resource name="Access refused"&gt;
+    &lt;map:generate src="./error-pages/restricted.xml"/&gt;
+    &lt;map:transform src="./stylesheets/general-browser.xsl"/&gt;
+    &lt;map:serialize status-code="401"/&gt;
+  &lt;/map:resource&gt;
+&lt;/map:resources&gt; </pre>
+
+   
+<h2>The &lt;map:action-sets&gt;</h2>
+<p>
+     The <span class="codefrag">&lt;map:action-set&gt;</span> element is used to arrange actions in
+     groups (See <a href="actions.html">the Actions section</a> for details).
+    </p>
+<pre class="code">
+
+&lt;map:action-sets&gt;
+  &lt;map:action-set name="employee"&gt;
+   &lt;map:act type="add-employee" action="Add"/&gt;
+   &lt;map:act type="del-employee" action="Delete"/&gt;
+   &lt;map:act type="upd-employee" action="Update"/&gt;
+   &lt;map:act type="sel-employee" action="Select"/&gt;
+  &lt;/map:action-set&gt;
+&lt;/map:action-sets&gt; </pre>
+  
+ 
+  
+<h1>Pipelines</h1>
+   
+<h2>Introduction</h2>
+<p>
+     Cocoon relies on the pipeline model: an XML document is pushed through a pipeline, 
+     that exists in several transformation steps of your document. 
+     Every pipeline begins with a generator, continues with zero or more transformers, 
+     and ends with a serializer. Beside this normal processing each pipeline 
+     may define its own error handling, too.
+    </p>
+<p>
+      Beside using the various components, you can use matchers, and selectors to choose a 
+      specific pipeline processing. Aggregation allows you to build a hierarchy of pipelines.
+    </p>
+<p>
+      Using views allows you to define exit points in a pipeline.
+    </p>
+   
+<h2>Define a Pipeline</h2>
+<p>
+       Defining a pipeline is simple. 
+       Just write a <span class="codefrag">map:pipeline</span> element inside the
+       <span class="codefrag">map:pipelines</span> element.
+     </p>
+<div class="fixme">Bernhard Huber:
+      
+         Explain optional attribute <span class="codefrag">internal-only</span>
+       
+</div>
+   
+<h2>Pipeline Elements</h2>
+<p>
+       Having defined a pipeline you can use following sitemap elements:
+     </p>
+<table>
+      
+<tr>
+<th colspan="1" rowspan="1">Element</th><th colspan="1" rowspan="1">Description</th>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:match</td><td colspan="1" rowspan="1">Selects pipeline processing depending on matching</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:select, map:when, map:otherwise</td><td colspan="1" rowspan="1">Selects pipeline processing depending on selecting</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:mount</td><td colspan="1" rowspan="1">Mounts a sub sitemap</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:redirect-to</td><td colspan="1" rowspan="1">Redirects to a another URI</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:call</td><td colspan="1" rowspan="1">Goto another pipeline fragment</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:parameter</td><td colspan="1" rowspan="1">Defines additional parameters for the sitemap components</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:act</td><td colspan="1" rowspan="1">Peform action processing</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:generate</td><td colspan="1" rowspan="1">Defines the generation step</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:aggregate, map:part</td><td colspan="1" rowspan="1">Defines an alternate generation step by mergine pipelines</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:transform</td><td colspan="1" rowspan="1">Defines zero or more transformation steps</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:serialize</td><td colspan="1" rowspan="1">Defines the final serialization step</td>
+</tr>
+      
+<tr>
+<td colspan="1" rowspan="1">map:handle-errors</td><td colspan="1" rowspan="1">Handles processing errors</td>
+</tr>
+     
+</table>
+<p>
+      The usage of these sitemap elements is explained in the following sections in more detail.
+     </p>
+   
+   
+<h2>Matching</h2>
+<p>
+     These powerful sitemap components allow Cocoon to associate a pure "virtual" URI space
+     to a given set of instructions that describe how to generate, 
+     transform and present the requested resource(s) to the client. 
+    </p>
+<p>See also 
+      <a href="matchers_selectors.html">Implementing Matchers And Selectors</a>
+    
+</p>
+   
+   
+<h2>Selecting And Testing</h2>
+<p>
+     Selectors in Apache Cocoon have a role similar to matchers while being more flexible. 
+     Like matchers they are designed to test something against a part of the 
+     environment (the request URI, headers, cookies and so on), but unlike matchers they 
+     can be active decision driving components. 
+     A matcher allows only for simple "yes/no" decisions: the match can be succesful or not, 
+     if it is the pipeline is executed, if not it's simply ignored. 
+     Selectors go a step further allowing for more complex use cases, 
+     where there is need for a decision to be made according to a multiple chance scenario.
+     In short you can think of matchers as an "if" statement, while selectors have 
+     all the power of an "if-else if-else" or "switch-case" construct. 
+     The selector syntax is similar will be familiar to people 
+     using the XSLT <span class="codefrag">&lt;xsl:test&gt; statement</span>.
+    </p>
+<p>See also 
+      <a href="matchers_selectors.html">Implementing Matchers And Selectors</a>
+    
+</p>
+   
+   
+<h2>Acting</h2>
+<p>
+      Apache Cocoon has a rich set of tools for publishing web documents, 
+      and while XSP and Generators provide alot of functionality, they still mix content
+      and logic to a certain degree. The Action was created to fill that gap.
+      Because the Cocoon Sitemap provides a mechanism to select the pipeline at run time, 
+      we surmised that sometimes we need to adjust the pipeline based on runtime parameters,
+      or even the contents of the Request parameter. 
+      Without the use of Actions this would make the sitemap almost incomprehensible.
+    </p>
+<p>See also 
+      <a href="actions.html">Creating And Using Actions</a>
+    
+</p>
+   
+<h2>Generating</h2>
+<p>
+      A generator is the starting point of an xml pipeline. 
+      It generates XML content as SAX events and initialize the pipeline processing. 
+    </p>
+<p>
+     See also 
+      <a href="../generators/generators.html">
+        Generators in Cocoon.
+      </a>
+    
+</p>
+   
+<h2>Aggregating</h2>
+<p>
+An aggregator produces XML content. It is composed of one or more parts, each of which defined by an XML source. During pipeline processing, all parts of an aggregator are merged.
+The name of the parent element which contains the merged XML content from each part is defined by the value of the map:aggregate's attribute called element.
+    </p>
+<p>
+     You can define an aggregator in places where you define a generator. Defining an aggregator
+     is simple. The example belows defines an aggregate, the merged in parts will become children
+     of element <span class="codefrag">the-aggregated-content</span>.
+    </p>
+<pre class="code">
+&lt;map:aggregate element="the-aggregated-content"&gt;
+  &lt;!-- define your map:parts here --&gt;
+&lt;/map:aggregate&gt; </pre>
+<p>
+     Defining an aggregator implicits defining the parts building up the content of
+     an aggregate.
+    </p>
+<p>
+     Define parts inside of an aggregate. You can define as source of a part a URL.
+     The following list of examples summarizes some useful part sources:
+    </p>
+<ul>
+     
+<li>
+      Use <span class="codefrag">http://foo/bar</span> to merge in xml content via http protocol, 
+      received from machine foo.
+     </li>
+     
+<li>
+      Use <span class="codefrag">context://servlet-context-path/foo/bar</span> to merge in xml content
+      from the servlet context.
+     </li>
+     
+<li>
+      Use <span class="codefrag">cocoon:/current-sitmap-pipeline/foo/bar</span> to merge in xml content
+      from the current sitemap. 
+      The appropriate pipeline is selected matching <span class="codefrag">current-sitemap-pipeline</span>.
+     </li>
+     
+<li>
+      Use <span class="codefrag">cocoon://root-sitmap-pipeline/foo/bar</span> to merge in xml content
+      from the root sitemap. 
+      The appropriate pipeline is selected matching <span class="codefrag">root-sitemap-pipeline</span>.
+     </li>
+     
+<li>
+      Use <span class="codefrag">resource://class-path-context/foo/bar</span> to merge in xml content
+      from the classpath.
+     </li>
+     
+<li>
+      Use <span class="codefrag">jar:http://www.foo.com/bar/jar.jar!/foo/bar</span> to merge in xml content
+      coming from a jar via http connection. 
+     </li>
+     
+<li>
+      Use <span class="codefrag">file:///foo/bar</span> to merge in xml content from the filesystem.
+     </li>
+     
+<li>
+      Use <span class="codefrag">xmldb:&lt;your driver here&gt;://your.xmldb.host/db/foo/bar</span> to merge in xml content from a XML:DB compliant database.
+     </li>
+     
+<li>
+      Depending on your setup you may use 
+      <span class="codefrag">nfs:</span>, <span class="codefrag">jndi:</span> protocols, too.
+     </li>
+    
+</ul>
+<p>
+     Defining a part element of an aggregate is simple.
+     A part element specifies by its src attribute the source of the xml content.
+    </p>
+<p>
+     The following example is taken from the documentation sitemap. 
+     The xml content of pipelines matching <span class="codefrag">book-*.xml</span>, and <span class="codefrag">body-*.xml</span>
+     is aggregated having root element site.
+    </p>
+<pre class="code">
+&lt;map:match pattern="*.html"&gt;
+ &lt;map:aggregate element="site"&gt;
+  &lt;map:part src="cocoon:/book-{1}.xml"/&gt;
+  &lt;map:part src="cocoon:/body-{1}.xml"/&gt;
+ &lt;/map:aggregate&gt;
+ ... </pre>
+<p>
+     The aggregated xml content may look like this:
+    </p>
+<pre class="code">
+&lt;site&gt;
+ &lt;menu&gt;
+  &lt;!-- content of book xml --&gt; 
+  ...
+ &lt;/menu&gt;
+ &lt;document&gt;
+  &lt;!-- content of body xml --&gt;
+  ...
+ &lt;/document&gt;
+&lt;/site&gt; </pre>
+   
+<h2>Transforming</h2>
+<p>
+     A transformer is the central point in the pipeline. 
+     It transform SAX events in SAX events. 
+    </p>
+<p>
+     See also 
+      <a href="../transformers/transformers.html">
+        Transformers in Cocoon.
+      </a>
+    
+</p>
+   
+<h2>Serializing</h2>
+<p>
+     A serializer is the end point of an xml pipeline. 
+     It transform SAX events in binary or char streams for final client consumption. 
+    </p>
+<p>
+     See also 
+      <a href="../serializers/serializers.html">
+        Serializers in Cocoon.
+      </a>
+    
+</p>
+   
+<h2>Handling Errors</h2>
+<p>
+     Each pipeline may define its error handling. 
+     A error handler is specialized pipeline having a pre-configures generator.
+     Each error handler uses the generator named <span class="codefrag">!error-notifier!</span>.
+     Thus you do not define a generator inside the error handler.
+     Beside this issue you configure the error handler like a pipeline.
+     Thus you can choose your transformer, and serializer, and 
+     all other features of pipeline processing.
+    </p>
+<p>
+     You may define the error handler as last element of a pipeline.
+     A error handler may have a type attribute describing which error
+     is handled. By default an error handler handles status code 500.
+    </p>
+<p>
+     The following example defines an error handler, transforming the content
+     of the error content by the xslt, and i18n transformer, 
+     and finally serializing html.
+    </p>
+<pre class="code">
+&lt;map:pipeline&gt;
+...
+ &lt;map:error-handler type="500"&gt;
+  &lt;map:transform type="xslt" src="error2html"/&gt;
+  &lt;map:transform type="i18n"/&gt;
+  &lt;map:serialize/&gt;
+ &lt;/map:error-handler&gt;
+&lt;/map:pipeline&gt; </pre>
+
+   
+<h2>Viewing</h2>
+<p>
+     Basically, views let you specify exit points of your pipelines 
+     that are taken whenever a particular view is requested. 
+     The processing continues with the definitions in the requested view. 
+     The advantage over selectors that could achieve the same is, that these 
+     exit points are not necessarily declared for each pipeline individually, 
+     but once per sitemap.
+    </p>
+   
+<h2>Redirecting</h2>
+<p>
+     Redirecting forwards the the request. You may externally send an
+     redirect response to the client. The behaviour is controlled by
+     using the approriate attributes of the element <span class="codefrag">redirect-to</span>.
+    </p>
+<p>
+     The attribute <span class="codefrag">uri</span> defines the target of redirect.
+     The target is sent as redirect response to the client.
+     The optional attribute <span class="codefrag">session</span> specifies, if the redirect 
+     should happen inside of a session or not. Setting <span class="codefrag">session</span> to
+     <span class="codefrag">yes</span>, or <span class="codefrag">true</span> will persist a session across
+     the redirect response. Use enable the session option if you use http session
+     within your web application.
+    </p>
+<p>
+     The following example redirects to a welcome page:
+    </p>
+<pre class="code">
+&lt;map:pipeline&gt;
+ &lt;map:match pattern=""&gt;
+  &lt;map:redirect-to uri="welcome"/&gt;
+ &lt;/map:match&gt;
+ &lt;map:match pattern="welcome"&gt;
+ ...
+&lt;/map:pipeline&gt; </pre>
+   
+<h2>Calling resources</h2>
+<p>Calling resources is dissimilar to redirects as the client does
+    not notice this.</p>
+<p> When calling a resource, arbitrary parameters can be
+    specified. They will be available to the processing later on, just
+    like the parameters set by e.g. matchers or actions. Calling a
+    resource always creates a new map of parameters. </p>
+<div class="note">The behaviour of resources has slightly changed due to the 
+    introduction of the TreeProcessor in Cocoon. Since 2.1 the sitemap 
+    interpreter strategy allows for the Resources to be templating any composed
+    portion of a pipeline. (Prior to 2.1 Resources were 'ending' pipelines
+    and as such a call of resource was said 'not to return')</div>
+<p>
+     The following example shows how to define and call sitemap resources:
+    </p>
+<pre class="code">
+&lt;map:resources&gt;
+  &lt;map:resource name="generate-data" &gt;
+    &lt;map:generate type="my-specific-parser" src="{input-src}" /&gt;
+  &lt;/map:resource&gt;
+
+  &lt;map:resource name="transform-data2svg" &gt;
+    &lt;map:transform src="xsl/data2svg.xsl" /&gt;      
+  &lt;/map:resource&gt;
+
+  &lt;map:resource name="transform-data2html" &gt;
+    &lt;map:transform src="xsl/data2html.xsl" /&gt;      
+  &lt;/map:resource&gt;
+  
+  &lt;map:resource name="pipe-data-raw"&gt;
+    &lt;map:read mime-type="text/plain" src="{input-src}" /&gt;
+  &lt;/map:resource&gt;
+&lt;/map:resources&gt;
+
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="styled-data/*/*"&gt;
+    &lt;map:call resource="generate-data"&gt;
+      &lt;map:parameter name="input-src" value="{2}"/&gt;
+    &lt;/map:call&gt;
+    &lt;map:call resource="transform-data2{1}" /&gt;
+    &lt;map:serialize /&gt;
+  &lt;/map:match&gt;
+  
+  &lt;map:match pattern="raw-data/*" &gt;
+    &lt;map:call resource="pipe-data-raw"&gt;
+      &lt;map:parameter name="input-src" value="{1}"/&gt;
+    &lt;/map:call&gt;
+  &lt;/map:match&gt;
+  
+&lt;/map:pipeline&gt; 
+ </pre>
+    
+<h2>Mounting sitemaps</h2>
+<p>
+       Mount points allow sitemaps to be cascaded and site management
+       workload to be parallelized. This creates a tree of sitemaps with
+       the main sitemap at the root and possibly several sub-sitemaps
+       as nodes and leaves.
+     </p>
+<p>The sub-sitemaps serve two important goals: scalability and
+      simplification of maintenance. The different sub-sitemaps are independent
+      and don't affect each other.
+    </p>
+<pre class="code">
+
+&lt;map:match pattern="faq/*"&gt; 
+  &lt;map:mount uri-prefix="faq" check-reload="no"
+             src="faq/sitemap.xmap"/&gt;
+&lt;/map:match&gt; </pre>
+<p>
+     The src attribute is where the sub-sitemap is located. If it ends in a slash
+     "sitemap.xmap" is appended to find the sitemap, otherwise the src
+     value is used. A check-reload attribute can be used to determine if the
+     modification date of the sub-sitemap file should be checked. 
+     The uri-prefix is the part that should be removed from the request URI.
+     The engine will correctly check for a trailing slash (which you may
+     write, of course).
+     If in the example above "faq/cocoon" is requested, "faq/" is removed from
+     the URI and "cocoon" is passed to the sub-sitemap which is loaded
+     from "faq/sitemap.xmap".
+     </p>
+<p>
+     Sitemap components (generators, transformers, etc.) in a sitemap are accessible 
+     from a sub-sitemap by their names. This is due to the fact that each sitemap has its 
+     own Sitemap service manager and they are arranged in the same hierarchical 
+     structure as the sitemaps are and thus knows which are their parent 
+     sitemap service manager and can ask it for a SitemapComponent it doesn't know about.
+     </p>
+<h3>Use Cases</h3>
+<p>
+     Usually you use the same SitemapComponents over and over again in your sub-sitemaps. 
+     And because you have a contract between the parent and sub sitemaps (the uri-prefix) you 
+     can deliver common SitemapComponents from the parent sitemap to your sub-sitemaps as well.
+     If you break a sitemap all its sub-sitemaps are broken as well (because of the hierarchical arrangement).
+     </p>
+<p>
+     However you can create independent sub-sitemaps, which meet the following goals:
+     </p>
+<ol>
+      
+<li>Simplify site construction</li>
+      
+<li>Reduce risk of "bad' sitemap entries killing whole site</li>
+      
+<li>Ease deployment of pre-built applications</li>
+      
+<li>Keep sitemap files an understandable and manageable size</li>
+     
+</ol>
+<p>
+     Just build a main sitemap with the minimum needs: A matcher and a selector. 
+     These two components allow to select and direct to mount two other sitemaps.
+     These sub-sitemaps load the components they need (which includes generators
+     and transformers etc...) and have the map elements for that site/application.
+     The benefit is that each sitemap is completely independent of each other and
+     any error in that sitemap does not kill any other sitemap. 
+     </p>
+<p>
+     Here is an example of a main sitemap. You will notice that it is using a selector that
+     matches on host name of the request, but any matcher or selector would work
+     at this point. Both sub-sitemaps are mounted at the root level.
+     </p>
+<pre class="code">
+
+&lt;?xml version="1.0"?&gt; 
+
+&lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+  &lt;!-- Components =============================== --&gt;
+  &lt;map:components&gt;
+    &lt;map:matchers default="wildcard"&gt;
+      &lt;map:matcher
+          name="wildcard"
+          src="org.apache.cocoon.matching.WildcardURIMatcher"/&gt;
+    &lt;/map:matchers&gt;
+
+    &lt;map:selectors default="host"&gt;
+      &lt;map:selector
+          name="host"
+          src="org.apache.cocoon.selection.HostSelector"&gt;
+        &lt;host name="fee" value="www.foo.com"/&gt;
+      &lt;/map:selector&gt;
+    &lt;/map:selectors&gt;
+
+  &lt;/map:components&gt;
+  &lt;!-- Pipelines ================================ --&gt;
+  &lt;map:pipelines&gt;
+    &lt;map:pipeline&gt;
+
+      &lt;map:select type="host"&gt;
+        &lt;map:when test="fee"&gt;
+          &lt;map:mount uri-prefix="" src="fee.xmap"/&gt;
+        &lt;/map:when&gt;
+        &lt;map:otherwise&gt;
+          &lt;map:mount uri-prefix="" src="foo.xmap"/&gt;
+        &lt;/map:otherwise&gt;
+      &lt;/map:select&gt;
+
+    &lt;/map:pipeline&gt;
+  &lt;/map:pipelines&gt;
+&lt;/map:sitemap&gt; </pre>
+<h3>Reloading</h3>
+<p>The reloading of the sub-sitemaps can be configured by two attributes,
+       "check-reload" and "reload-method".</p>
+<pre class="code">
+
+&lt;map:match pattern="faq/*"&gt; 
+  &lt;map:mount uri-prefix="faq/" check-reload="no" 
+     src="faq/sitemap.xmap" reload-method="asynchron"/&gt; 
+&lt;/map:match&gt; </pre>
+<p>
+      The "check-reload" attribute specifies whether the sitemap should be reloaded (regenerated) if
+      it's source XML (sitemap.xmap) is modified.  If "check-reload" is set to "no", the sitemap is
+      only generated on the first request for this sitemap.  If "check-reload" is set to "yes" (the
+      default), the "reload-method" attribute determines how the sitemap is
+      regenerated if it had changed.
+    </p>
+<p>
+      If "reload-method" is set to "asynchron" (the default), then the next request for the changed
+      sitemap causes it to be regenerated in the background, and the request is served with the old
+      one. All subsequent requests are served with the old sitemap until the regeneration in the
+      background has finished. If the reload-method is set to "synchron", the sitemap is first
+      regenerated and then the request is processed.
+     </p>
+  
+
+  
+<a name="file-url"></a>
+  
+<h1>File: URLs</h1>
+   
+<p>
+    In your sitemaps you may need to refer to some resource that is outside
+    the webapp context (e.g. UNIX /foo/bar/this.xsl
+    e.g. Windows C:\foo\bar\this.xsl). You need to use the file: convention
+    with the following syntax for absolute filesystem pathnames.
+   </p>
+
+   
+<ul>
+    
+<li>UNIX ... <span class="codefrag">file:///foo/bar/this.xsl</span>
+</li>
+    
+<li>Windows ... <span class="codefrag">file:///C:/foo/bar/this.xsl</span>
+</li>
+   
+</ul>
+
+   
+<p>
+    Everything starting with a URI scheme identifer like "file:"
+    or "http:" is an absolute URI. An absolute file URL is
+    <span class="codefrag">file://some.host/some/path/to/file.ext</span>
+    ... the host can be omitted, defaulting to localhost, so you can write
+    <span class="codefrag">file:///some/path/to/file.ext</span>
+   
+</p>
+
+   
+<p>
+    Further information is at RFC2396:
+    <a class="external" href="http://www.rfc-editor.org/rfc/rfc2396.txt">Uniform Resource Identifiers (URI): Generic Syntax</a>
+   
+</p>
+  
+
+  
+<h1>Protocols</h1>
+   
+<p>In the sitemap, you can use all protocols nearly everywhere
+    (except for in <span class="codefrag">map:redirect</span>).
+   </p>
+
+   
+<p>Inside your components, you can also use these protocols whenever you
+    have a <span class="codefrag">SourceResolver</span> handy.
+   </p>
+
+   
+<ul>
+    
+<li>
+<span class="codefrag">context://</span>
+     - get a resource using the servlet context
+    </li>
+    
+<li>
+<span class="codefrag">cocoon:/</span>
+     - get a pipeline from the current sitemap
+    </li>
+    
+<li>
+<span class="codefrag">cocoon://</span>
+     - get a pipeline using the root sitemap
+    </li>
+    
+<li>
+<span class="codefrag">resource://</span>
+     - get a resource from the context classloader
+    </li>
+   
+</ul>
+  
+
+  
+<h1>Interface specifications</h1>
+   
+<a name="interface-XMLProducer"></a>
+   
+<h2>XMLProducer</h2>
+<p>
+     This interfaces identifies classes that produce XML data, sending SAX
+     events to the configured <span class="codefrag">XMLConsumer</span>.<br>
+     It is beyond the scope of this interface to specify a way in which the XML
+     data production is started.
+    </p>
+<pre class="code">
+
+public interface XMLProducer {
+
+    /**
+     * Set the &lt;code&gt;XMLConsumer&lt;/code&gt; that will 
+     * receive XML data.
+     */
+    public void setConsumer(XMLConsumer consumer);
+
+} </pre>
+
+   
+<a name="interface-XMLConsumer"></a>
+   
+<h2>XMLConsumer</h2>
+<p>
+     This interfaces identifies classes that consume XML data, receiving 
+     notification of SAX events.<br>
+     This interface unites the idea of SAX <span class="codefrag">ContentHandler</span> and
+     <span class="codefrag">LexicalHandler</span>.
+    </p>
+<pre class="code">
+
+public interface XMLConsumer extends ContentHandler,
+                                     LexicalHandler {
+
+} </pre>
+
+   
+<a name="interface-XMLPipe"></a>
+   
+<h2>XMLPipe</h2>
+<p>
+     This interfaces identifies classes that consume XML data, receiving 
+     notification of SAX events, and also that produce XML data, sending SAX
+     events to the configured <span class="codefrag">XMLConsumer</span>.<br>
+     This interface unites the idea of <span class="codefrag">XMLProducer</span> and
+     <span class="codefrag">XMLConsumer</span>.
+    </p>
+<pre class="code">
+
+public interface XMLPipe extends XMLConsumer , XMLProducer {
+
+} </pre>
+
+   
+<a name="interface-sitemap-model-component"></a>
+   
+<h2>SitemapModelComponent</h2>
+<p>
+     All sitemap components producing XML must implement this interface:
+    </p>
+<pre class="code">
+
+public interface SitemapModelComponent extends Component {
+
+    /**
+     * Set the &lt;code&gt;SourceResolver&lt;/code&gt;, objectModel 
+     * &lt;code&gt;Map&lt;/code&gt;, the source and sitemap 
+     * &lt;code&gt;Parameters&lt;/code&gt; used to process the request.
+     */
+    void setup(SourceResolver resolver, Map objectModel,
+               String src, Parameters par)
+    throws ProcessingException, SAXException, IOException;
+} </pre>
+
+   
+<a name="interface-sitemap-output-component"></a>
+   
+<h2>SitemapOutputComponent</h2>
+<p>
+     All sitemap components creating the output must implement this interface:
+    </p>
+<pre class="code">
+
+public interface SitemapOutputComponent extends Component {
+
+    /**
+     * Set the &lt;code&gt;OutputStream&lt;/code&gt; where the requested 
+     * resource should be serialized.
+     */
+    void setOutputStream(OutputStream out) throws IOException;
+
+    /**
+     * Get the mime-type of the output of this 
+     * &lt;code&gt;Component&lt;/code&gt;.
+     */
+    String getMimeType();
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    boolean shouldSetContentLength();
+} </pre>
+   
+<a name="interface-generator"></a>
+   
+<h2>Generator</h2>
+<p>
+     A <span class="codefrag">Generator</span> must implement at least the following interface:
+    </p>
+<pre class="code">
+
+public interface Generator extends XMLProducer, 
+                                   SitemapModelComponent {
+
+    String ROLE = "org.apache.cocoon.generation.Generator";
+
+    public void generate()
+    throws IOException, SAXException, ProcessingException;
+
+} </pre>
+
+   
+<a name="interface-transformer"></a>
+   
+<h2>Transformer</h2>
+<p>
+     A <span class="codefrag">Transformer</span> must implement at least the following interface:
+    </p>
+<pre class="code">
+
+public interface Transformer 
+extends   XMLPipe, SitemapModelComponent {
+
+    String ROLE = "org.apache.cocoon.transformation.Transformer";
+
+} </pre>
+
+   
+<a name="interface-serializer"></a>
+   
+<h2>Serializer</h2>
+<p>
+     A <span class="codefrag">Serializer</span> gets the <span class="codefrag">OutputStream</span> where the XML should 
+     be serialized with the following interface:
+    </p>
+<pre class="code">
+
+public interface Serializer extends XMLConsumer, SitemapOutputComponent {
+
+    String ROLE = "org.apache.cocoon.serialization.Serializer";
+
+} </pre>
+
+   
+<a name="interface-selector"></a>
+   
+<h2>Selector</h2>
+<p>
+     A <span class="codefrag">Selector</span> gets an expression to evaluate and signals the evaluation with a 
+     boolean value.
+    </p>
+<pre class="code">
+
+public interface Selector extends Component {
+
+    String ROLE = "org.apache.cocoon.selection.Selector";
+
+    /**
+     * Selectors test pattern against some objects in a &lt;code&gt;Map&lt;/code&gt;
+     * model and signals success with the returned boolean value
+     * @param expression  The expression to test.
+     * @param objectModel The &lt;code&gt;Map&lt;/code&gt; containing object of the
+     *                    calling environment which may be used
+     *                    to select values to test the expression.
+     * @param parameters  The sitemap parameters, as specified by
+     *                    &amp;lt;parameter/&amp;gt; tags.
+     * @return boolean    Signals successfull test.
+     */
+    boolean select (String expression, Map objectModel,
+                    Parameters parameters);
+} </pre>
+
+   
+<a name="interface-matcher"></a>
+   
+<h2>Matcher</h2>
+<p>
+     A <span class="codefrag">Matcher</span> matches a pattern against any value:
+    </p>
+<pre class="code">
+
+public interface Matcher extends Component {
+
+    String ROLE = "org.apache.cocoon.matching.Matcher";
+
+    /**
+     * Matches the pattern against some &lt;code&gt;Request&lt;/code&gt; values
+     * and returns a &lt;code&gt;Map&lt;/code&gt; object with replacements
+     * for wildcards contained in the pattern.
+     * @param pattern     The pattern to match against. Depending on
+     *                    the implementation the pattern can contain
+     *                    wildcards or regular expressions.
+     * @param objectModel The &lt;code&gt;Map&lt;/code&gt; with object of the
+     *                    calling environment which can be used
+     *                    to select values this matchers matches against.
+     * @return Map        The returned &lt;code&gt;Map&lt;/code&gt; object with
+     *                    replacements for wildcards/regular-expressions
+     *                    contained in the pattern.
+     *                    If the return value is null there was no match.
+     */
+    Map match (String pattern, Map objectModel, Parameters parameters);      
+} </pre>
+
+   
+<a name="interface-action"></a>
+   
+<h2>Action</h2>
+<p>
+     An <span class="codefrag">Action</span> processes input <span class="codefrag">objectModel</span> and returns results
+     in a <span class="codefrag">Map</span>:
+    </p>
+<pre class="code">
+
+public interface Action extends Component, ThreadSafe {
+
+    String ROLE = "org.apache.cocoon.acting.Action";
+
+    /**
+     * Controls the processing against some values of the
+     * &lt;code&gt;Dictionary&lt;/code&gt; objectModel and returns a
+     * &lt;code&gt;Map&lt;/code&gt; object with values used in subsequent
+     * sitemap substitution patterns.
+     *
+     * NOTE: It is important that &lt;code&gt;Action&lt;code&gt; classes are
+     * written in a thread safe manner.
+     *
+     * @param resolver    The &lt;code&gt;SourceResolver&lt;/code&gt; in charge
+     * @param objectModel The &lt;code&gt;Map&lt;/code&gt; with object of the
+     *                    calling environment which can be used
+     *                    to select values this controller may need
+     *                    (ie Request, Response).
+     * @param source      A source &lt;code&gt;String&lt;/code&gt; to the Action
+     * @param parameters  The &lt;code&gt;Parameters&lt;/code&gt; for this invocation
+     * @return Map        The returned &lt;code&gt;Map&lt;/code&gt; object with
+     *                    sitemap substitution values which can be used
+     *                    in subsequent elements attributes like src=
+     *                    using a xpath like expression: 
+     *                    src="mydir/{myval}/foo"
+     *                    If the return value is null the processing
+     *                    inside the &lt;map:act&gt; element of the sitemap
+     *                    will be skipped.
+     * @exception Exception Indicates something is totally wrong
+     */
+    Map act(Redirector redirector, SourceResolver resolver,
+            Map objectModel, String source, Parameters par)
+    throws Exception;
+} </pre>
+  
+
+  
+<h1>Additional resources</h1>
+  
+<p>
+Learn more about advanced Sitemap features by downloading the free chapter, <a class="external" href="http://www.newriders.com/books/product.asp?product_id={C3C05052-BE3B-4E06-A60A-13FB40AF58F6}">A User's Look at the Cocoon architecture,</a> from Langham and Ziegeler's <em>Cocoon: Building XML Applications</em> available at the New Riders web site.
+  </p>
+  
+<p>
+     Check out a draft XML Schema <a class="external" href="http://cvs.apache.org/viewcvs.cgi/*checkout*/cocoon-2.1/src/documentation/xdocs/drafts/sitemap-2.1-draft.xsd?rev=HEAD&content-type=text/plain">grammar for the Cocoon sitemap</a>, and some <a class="external" href="http://outerthought.net/sitemap/">external documentation</a>
+     generated from this Schema. A poster diagram of
+     the sitemap structure is also available.
+   </p>
+  
+ 
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/meta.xml
new file mode 100644
index 0000000..bb07531
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sitemap/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/sitemap.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/content_en.html
new file mode 100644
index 0000000..5b1f9ec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/content_en.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Source Resolving</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+</head>
+<body>
+
+<h1>Differences between Cocoon and Avalon Excalibur Source Resolving</h1>
+
+
+<p>
+This story tries to list the changes between the two source resolving approaches. 
+Originally, the source resolving was developed in the Cocoon community. As the 
+community recognized that it had a more common value, the source resolving was 
+donated to the Avalon Excalibur project and there it was refined and redesigned.
+Now the way back takes place by reintegrating the Avalon Excalibur Source Resolving 
+into Cocoon and deprecating the now obsolete Cocoon Source Resolving.</p>
+
+<h2>The Interfaces</h2>
+<p>
+Besides the package names the main difference is that the Cocoon Source object is 
+XMLizable, that means it can directly send SAX events.
+The AE Source object is not XMLizable, which is more correct as a protocol only 
+describes the way of transport but not the format of the data which is transfered. 
+Therefore it provides a getMimeType() method.</p>
+
+<h2>Caching</h2>
+<p>
+The Cocoon Source object returns a last modified time stamp which is very limiting. 
+For example a source could have an expires date or something like that.
+The AE Source returns a validity object which is capable of all these validity 
+checkings. So the information used for validity checking is provided by the source 
+object and not maintained by the client of the source as it is currently in Cocoon.</p>
+
+<h2>XMLizable</h2>
+<p>
+As we in Cocoonland are dealing a lot with XML, a Source implementation can still implement 
+the XMLizable Interface (from AE and not from Cocoon!) to directly provide SAX events. 
+The Cocoon SourceUtil class has a method toSAX() which gets a Source object and tests if 
+it implements the XMLizable interface. If not the new AE XMLizer is used which is a 
+component that can convert an input stream with a given mime-type to SAX events. 
+This component is configurable and extensible.</p>
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/meta.xml
new file mode 100644
index 0000000..4fcb4d5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sources/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/source.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/content_en.html
new file mode 100644
index 0000000..2613b0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/content_en.html
@@ -0,0 +1,340 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Source Writing Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Jeremy Quinn" name="DC.Creator">
+<meta content="This document describes the Source Writing transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Source Writing Transformer</h1>
+      
+<p>Diverts xml from a pipeline, writing it to a Source (or
+      deleting it).</p>
+      
+<p>Thankfully, <span class="codefrag">FileSource</span> is no longer the only <span class="codefrag">Source</span> that currently implements <span class="codefrag">WritableSource</span>; there are implementations of WebDAV and Apache Slide WritableSources in the scratchpad. Hopefully further <span class="codefrag">ModifiableSource</span> implementations (XMLDB, CVS, Email, SQL, etc.) will be appear in the future.</p>
+      
+<p>See the transformer in action with the Cocoon Samples for webdav block,
+      and Wiki about it at
+      <a class="external" href="http://wiki.apache.org/cocoon/WebDAVCMS">WebDAVCMS</a>.
+      </p>
+      
+<ul>
+        
+<li>Name : write-source</li>
+        
+<li>Class: org.apache.cocoon.transformation.SourceWritingTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+    
+    
+<h1>The Tags</h1>
+        
+<pre class="code">
+          
+    &lt;source:write&gt;
+      [&lt;source:path/&gt;]
+      &lt;source:source/&gt;
+      &lt;source:fragment/&gt;
+    &lt;/source:write&gt;
+    
+    &lt;source:insert/&gt;
+      &lt;source:path/&gt;
+      &lt;source:source/&gt;
+      &lt;source:fragment/&gt;
+      [&lt;source:replace/&gt;]
+      [&lt;source:reinsert/&gt;]
+    &lt;/source:insert&gt;
+
+    &lt;source:delete/&gt;
+      &lt;source:source/&gt;
+      [&lt;source:path/&gt;] - Ignored
+      [&lt;source:fragment/&gt;] - Ignored
+      [&lt;source:replace/&gt;] - Ignored
+      [&lt;source:reinsert/&gt;] - Ignored
+    &lt;/source:insert&gt;
+          
+        </pre>
+      
+<p>In the namespace <span class="codefrag">xmlns:source="http://apache.org/cocoon/source/1.0"</span>.</p>
+      
+<p>The contents of the <span class="codefrag">&lt;source:fragment/&gt;</span>
+      tag are written to the specified ModifiableSource when the
+      document containing it is transformed by SourceWritingTransformer
+      (or deleted if you are using the <span class="codefrag">delete </span>instruction).</p>
+    
+    
+<h1>Definition</h1>
+        
+<pre class="code">
+          
+ &lt;map:transformer name="write-source" 
+    src="org.apache.cocoon.transformation.SourceWritingTransformer"&gt;
+    &lt;map:parameter name="serializer" value="xml"/&gt;  
+ &lt;/map:transformer/&gt;
+          
+        </pre>
+      
+<p>The SourceWritingTransformer is predefined for you in the main SiteMap.</p>
+    
+    
+<h1>Invocation</h1>
+      
+<p>This invokes the SourceWritingTransformer on your pipeline.</p>
+        
+<pre class="code">
+          
+ &lt;map:transform type="write-source"/&gt;
+          
+        </pre>
+      
+<p>Or you can over-ride the default serializer here.</p>
+        
+<pre class="code">
+          
+ &lt;map:transform type="write-source"&gt;
+   &lt;map:parameter name="serializer" value="my-special-serializer"/&gt;   
+ &lt;/map:transform&gt;
+          
+        </pre>
+    
+
+    
+<h1>The Tags in detail</h1>
+      
+<h2>source:write</h2>
+<p>The source:write tag can take optional attributes, <span class="codefrag">create</span> (defaults to 'true') and <span class="codefrag">serializer</span> (defaults to the serializer set up in the definition or invocation of the transformer).</p>
+<p>Replaces the entire content of a <span class="codefrag">Source</span> (specified by the <span class="codefrag">&lt;source:source/&gt;</span> tag) with the contents of the <span class="codefrag">&lt;source:fragment/&gt;</span> tag, if @create is 'true', a new asset will be created if one does not already exist.</p>
+<p>The <span class="codefrag">&lt;source:source/&gt;</span> and <span class="codefrag">&lt;source:fragment/&gt;</span> tags are required, a <span class="codefrag">&lt;source:path/&gt;</span> tag is optional, if specified, the value is used as an XPath to generate xml in your <span class="codefrag">Source</span>, in which to wrap your content.</p>
+<h3>source:source</h3>
+<p>The System ID of the <span class="codefrag">Source</span> to be written to.</p>
+<p>e.g. <span class="codefrag">&lt;source:source&gt;docs/blah.xml&lt;/source:source&gt;</span> or <span class="codefrag">&lt;source:source&gt;context:/blah.xml&lt;/source:source&gt;</span> etc.</p>
+<h3>source:fragment</h3>
+<p>The XML Fragment to be written.</p>
+<p>For example:</p>
+<pre class="code">
+              
+  &lt;source:fragment&gt;&lt;foo&gt;
+      &lt;bar id="dogcow"/&gt;
+    &lt;/foo&gt;&lt;/source:fragment&gt;
+              
+            </pre>
+<p>or</p>
+<pre class="code">
+              
+  &lt;source:fragment&gt;
+    &lt;foo/&gt;
+    &lt;bar&gt;
+      &lt;dogcow/&gt;
+    &lt;bar/&gt;
+  &lt;/source:fragment&gt;
+              
+            </pre>
+<p>etc.</p>
+<div class="note">The second example type, can only be used when the <span class="codefrag">&lt;source:path/&gt;</span> tag has been specified.</div>
+<h3>source:path</h3>
+<p>[Optional] XPath to specify how your content is wrapped</p>
+<p>e.g. <span class="codefrag">&lt;source:path&gt;doc&lt;/source:path&gt;</span> - your content is placed inside a <span class="codefrag">&lt;doc/&gt;</span> root tag.</p>
+<div class="note">If this parameter is omitted, your content MUST have only ONE top-level node.</div>
+
+      
+<h2>source:insert</h2>
+<p>The source:insert tag can take optional attributes, <span class="codefrag">create</span> (defaults to 'true') and <span class="codefrag">serializer</span> (defaults to the serializer set up in the definition or invocation of the transformer).</p>
+<p>Inserts into a <span class="codefrag">Source</span> (specified by the <span class="codefrag">&lt;source:source/&gt;</span> tag) the contents of the tag <span class="codefrag">&lt;source:fragment/&gt;</span> at the XPath location specified in the <span class="codefrag">&lt;source:path/&gt;</span> tag, if @create is 'true', a new <span class="codefrag">Source</span> will be created if one does not already exist.</p>
+<p>The <span class="codefrag">&lt;source:source/&gt;</span>, <span class="codefrag">&lt;source:path/&gt;</span> and <span class="codefrag">&lt;source:fragment/&gt;</span> tags are all required, the <span class="codefrag">&lt;source:replace/&gt;</span> and <span class="codefrag">&lt;source:reinsert/&gt;</span> tags are optional.</p>
+<h3>source:source</h3>
+<p>The System ID of the <span class="codefrag">Source</span> to be inserted into.</p>
+<p>e.g. <span class="codefrag">&lt;source:source&gt;docs/blah.xml&lt;/source:source&gt;</span> or <span class="codefrag">&lt;source:source&gt;context:/blah.xml&lt;/source:source&gt;</span> etc.</p>
+<h3>source:fragment</h3>
+<p>The XML Fragment to be written.</p>
+<p>e.g.</p>
+<pre class="code">
+              
+  &lt;source:fragment&gt;
+    &lt;foo&gt;
+      &lt;bar id="dogcow"/&gt;
+    &lt;/foo&gt;
+  &lt;/source:fragment&gt;
+              
+            </pre>
+<p>or</p>
+<pre class="code">
+              
+  &lt;source:fragment&gt;
+    &lt;foo/&gt;
+    &lt;bar&gt;
+      &lt;dogcow/&gt;
+    &lt;bar/&gt;
+  &lt;/source:fragment&gt;
+              
+            </pre>
+<p>etc.</p>
+<h3>source:path</h3>
+<p></p>
+<h3>source:replace</h3>
+<p>[Optional] XPath (from <span class="codefrag">&lt;source:path/&gt;</span>) to select the node that is replaced by your new content</p>
+<p>e.g. <span class="codefrag">&lt;source:replace&gt;foo/bar/dogcow/@status='cut'&lt;/source:replace&gt;</span> (is equivalent to this in XSLT: <span class="codefrag">select="foo[bar/dogcow/@status='cut']"</span>), what gets replaced is the <span class="codefrag">&lt;foo/&gt;</span> which has a <span class="codefrag">&lt;bar/&gt;</span> with a <span class="codefrag">&lt;dogcow status="cut"/&gt;</span> in it.</p>
+<p>The <span class="codefrag">overwrite</span> attribute of the parent <span class="codefrag">&lt;source:insert/&gt;</span> is used to check if replacing is allowed. If <span class="codefrag">overwrite</span> is 'true' (the default) the node is replaced. If <span class="codefrag">overwrite</span> is 'false' the node is only inserted if the replace node is found.</p>
+<h3>source:reinsert</h3>
+<p>[Optional] The XPath (relative to <span class="codefrag">&lt;source:replace/&gt;</span>) to backup the contents of the overwritten node to.</p>
+<p>e.g. <span class="codefrag">&lt;source:reinsert&gt;foo/versions&lt;/source:reinsert&gt;</span> or <span class="codefrag">&lt;source:reinsert&gt;/doc/versions/foo&lt;/source:reinsert&gt;</span>.</p>
+<p>If specified and a node is replaced, all children of this replaced node will be reinserted at the given path.</p>
+      
+<h2>Notes</h2>
+<ul>
+            
+<li>if 'replace' is not specified, your 'fragment' is appended as a child of 'path'.</li>
+            
+<li>if 'replace' is specified and it exists and 'overwrite' is true, your 'fragment' is inserted in 'path', before 'replace' and then 'replace' is deleted.</li>
+            
+<li>if 'replace' is specified and it exists and 'overwrite' is false, no action occurs.</li>
+            
+<li>if 'replace' is specified and it does not exist and 'overwrite' is true, your 'fragment' is appended as a child of 'path'.</li>
+            
+<li>if 'replace' is specified and it does not exist and 'overwrite' is false, your 'fragment' is appended as a child of 'path'.</li>
+            
+<li>if 'reinsert' is specified and it does not exist, no action occurs.</li>
+          
+</ul>
+      
+<h2>source:delete</h2>
+<p>This instruction takes only a <span class="codefrag">&lt;source:source/&gt;</span>
+         parameter (as a child tag) and deletes the corresponding
+         source. All other <span class="codefrag">source:*</span> tags are ignored, if
+         present: this allows for easy source-write instructions to be
+         generated on the fly (e.g. by a stylesheet). Just change 
+         <span class="codefrag">source:write</span> to <span class="codefrag">source:delete</span> and
+         you're set.
+         </p>
+    
+    
+    
+<h1>Examples</h1>
+      
+<h2>Simple Write</h2>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;source:write xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;      
+     &lt;source:fragment&gt;&lt;page&gt;
+       &lt;title&gt;Hello World&lt;/title&gt;
+       &lt;content&gt;
+         &lt;p&gt;This is my first paragraph.&lt;/p&gt;
+       &lt;/content&gt;
+     &lt;/page&gt;&lt;/source:fragment&gt;
+   &lt;/source:write&gt;
+   ...
+ &lt;/page&gt;
+            
+          </pre>
+      
+<h2>Insert at end</h2>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;source:insert xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;      
+     &lt;source:path&gt;page/content&lt;/source:path&gt;      
+     &lt;source:fragment&gt;
+       &lt;p&gt;This paragraph gets &lt;emp&gt;inserted&lt;/emp&gt;.&lt;/p&gt;
+       &lt;p&gt;With this one, at the end of the content.&lt;/p&gt;
+     &lt;/source:fragment&gt;
+   &lt;/source:insert&gt;
+   ...
+ &lt;/page&gt;
+            
+          </pre>
+      
+<h2>Replace</h2>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;source:insert xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+     &lt;source:source&gt;context://doc/editable/my.xml"&lt;/source:source&gt;      
+     &lt;source:path&gt;page/content&lt;/source:path&gt;      
+     &lt;source:replace&gt;p[1]&lt;/source:replace&gt;      
+     &lt;source:fragment&gt;
+       &lt;p&gt;This paragraph &lt;emp&gt;replaces&lt;/emp&gt; the first paragraph.&lt;/p&gt;
+     &lt;/source:fragment&gt;
+   &lt;/source:insert&gt;
+   ...
+ &lt;/page&gt;
+            
+          </pre>
+      
+<h2>Insert at the beginning</h2>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;source:insert&gt;
+     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;
+     &lt;source:path&gt;page&lt;/source:path&gt;
+     &lt;source:replace&gt;content&lt;/source:replace&gt;
+     &lt;source:reinsert&gt;content&lt;/source:reinsert&gt;
+     &lt;source:fragment&gt;
+       &lt;content&gt;
+         &lt;p&gt;This new paragraph gets inserted &lt;emp&gt;before&lt;/emp&gt; the other ones.&lt;/p&gt;
+       &lt;/content&gt;
+     &lt;/source:fragment&gt;
+    &lt;source:insert&gt;
+   ...
+ &lt;/page&gt;
+            
+          </pre>
+<p>This sample does not currently work, see the tests in the scratchpad at <span class="codefrag">http://localhost:8080/cocoon/mount/editor/tests</span>.</p>
+<div class="note">You must have built Cocoon with the scratchpad included for this link to work.</div>
+      
+<h2>Delete a source</h2>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;source:delete&gt;
+     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;
+   &lt;source:delete&gt;
+   ...
+ &lt;/page&gt;
+            
+            </pre>
+      
+<h2>Sample of the output of these tags</h2>
+<p>This is the kind of information that the <span class="codefrag">SourceWritingTransformer</span> outputs to the pipeline, replacing the original <span class="codefrag">source:write</span> and <span class="codefrag">source:insert</span> tags</p>
+<pre class="code">
+            
+ &lt;page&gt;
+   ...
+   &lt;sourceResult&gt;
+     &lt;action&gt;new|overwritten|none&lt;/action&gt;
+     &lt;behaviour&gt;write|insert&lt;behaviour&gt;
+     &lt;execution&gt;success|failure&lt;/execution&gt;
+     &lt;serializer&gt;xml&lt;/serializer&gt;
+     &lt;source&gt;source:specific/path/to/context/doc/editable/my.xml&lt;/source&gt;
+     &lt;message&gt;a message about what happened&lt;/message&gt;
+   &lt;/sourceResult&gt;
+   ...
+ &lt;/page&gt;
+            
+          </pre>
+    
+    
+<h1>Known Problems</h1>
+      
+<p>I cannot get the 'insert before' example working, which uses the <span class="codefrag">&lt;source:reinsert/&gt;</span> tag.</p>
+    
+    
+<h1>Warning</h1>
+      
+<p>It is not known how robust this transformer is under even moderate load, especially when it comes to more than one person modifying the same file at the same time.</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/meta.xml
new file mode 100644
index 0000000..3812595
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sourcewriting-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/sourcewriting-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/content_en.html
new file mode 100644
index 0000000..33e326d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/content_en.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Specifying Different XSLT Processor Options</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Vadim Gritsenko" name="DC.Creator">
+<meta content="Diana Shannon" name="DC.Creator">
+</head>
+<body>
+
+  
+<h1>Overview</h1>
+
+<p>
+This Snippet shows how to specify different options of the same XSLT processor when processing different pipeline requests. The following example is based on the need to turn incremental processing both off and on. This is useful in situations when processing requests for both PDF and HTML output. For example, you may want to turn incremental processing "off" for PDF requests but leave it "on" for HTML requests. In addition, you can follow the <strong>same</strong> approach in order to utilize two <strong>different</strong> XSLT processors when processing requests.
+</p>
+  
+
+  
+<h1>Version</h1>
+
+<p>
+At the time of this writing, this Snippet was tested against the Cocoon version 2.0.3. Please note that this approach does not work with Cocoon 2.1. Stay tuned for an upcoming Snippet which illustrates a different approach for version 2.1.
+</p>
+  
+  
+  
+<h1>cocoon.xconf</h1>
+
+<p>
+Here is a snippet from cocoon.xconf which declares a default XSLT processor. It assumes the use of Xalan. You can see that the default XSLT processor is configured to allow the incremental processing of SAX events. Check your cocoon.xconf file, as the value for incremental-processing may be different from what is shown here.
+</p>
+
+
+<pre class="code">
+&lt;xslt-processor class="org.apache.cocoon.components.xslt.XSLTProcessorImpl"
+   logger="core.xslt-processor"&gt;
+ &lt;parameter name="use-store" value="true"/&gt;
+ &lt;parameter name="incremental-processing" value="true"/&gt;
+&lt;/xslt-processor&gt;
+</pre>
+  
+
+<p>
+As discussed above, we need the ability to turn incremental processing of our XSLT processor both on and off. Even though we are using the same XSLT processor implementation, we need to declare an additional component in our cocoon.xconf file in order to use the XSLT processor differently. So, in the next snippet, we add a new component (as a child element of the root cocoon element) to cocoon.xconf. Don't be concerned if you don't see any other component declarations like this in the particular cocoon.xconf file you happen to be using.
+</p>
+  
+   
+<pre class="code">
+&lt;component 
+    role="org.apache.cocoon.components.xslt.XSLTProcessor/NotIncremental"
+    class="org.apache.cocoon.components.xslt.XSLTProcessorImpl"&gt;
+  &lt;parameter name="use-store" value="true"/&gt;
+  &lt;parameter name="incremental-processing" value="false"/&gt; 
+&lt;/component&gt;
+</pre>
+
+    
+<p>
+In the snippet above, the component is identified by the role it plays. Note the value for the role attribute: "org.apache.cocoon.components.xslt.XSLTProcessor/NotIncremental". We will use this value in additional snippets below. Note also that the incremental-processing parameter and its value of "false" is also specified in this particular snippet. 
+  </p>
+
+
+
+  
+<h1>sitemap.xmap</h1>
+
+<p>Next, we need to add one more XSLT transformer component to the components declaration section of our sitemap.xmap file.</p>
+
+   
+<pre class="code">
+&lt;map:components&gt;
+
+  &lt;!-- other map:components here --&gt;
+  
+&lt;map:transformers&gt;
+
+  &lt;!-- other map:transformers here --&gt;
+  
+  &lt;map:transformer 
+    name="xslt-notinc"
+    src="org.apache.cocoon.transformation.TraxTransformer"
+    logger="sitemap.transformer.xslt"
+    pool-max="32"&gt;
+    &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+    &lt;use-browser-capabilities-db&gt;false&lt;/use-browser-capabilities-db&gt;
+    &lt;use-deli&gt;false&lt;/use-deli&gt;
+    &lt;xslt-processor-role&gt;
+org.apache.cocoon.components.xslt.XSLTProcessor/NotIncremental
+    &lt;/xslt-processor-role&gt;
+  &lt;/map:transformer&gt;
+  
+  &lt;!-- other map:transformers here --&gt;
+
+&lt;/map:transformers&gt;
+
+&lt;!-- other map:components here --&gt;
+
+&lt;/map:components&gt;
+</pre>
+
+    
+<p>
+In the snippet above, we are using the value for the role attribute, specified earlier in the cocoon.xconf snippet, for the value of xslt-processor-role element. Note also that we are giving this transformer the name "xslt-notinc". Please note that the text node for xslt-processor-role was manually broken across several lines for page viewing purposes only. Do not do this in your sitemap.xmap file.
+  </p>
+
+
+<p>Finally, in the relevant map:match elements in our sitemap.xmap, we can specify exactly which xslt transformer component to use by supplying its name as map:transformer's type attribute. Remember that the default xslt transformer, as declared in cocoon.xconf, has incremental processing turned on. Because it's the <em>default</em> transformer, you don't need to specify its name in map:transform's type attribute. In fact, you don't have to supply a type attribute at all when you use default components.</p>
+
+
+<pre class="code">
+&lt;map:pipeline&gt;
+
+   &lt;!-- incremental processing = false --&gt;
+   &lt;map:match pattern="*.pdf"&gt;
+    &lt;map:generate src="docs/{1}.xml"/&gt;
+    &lt;map:transform type="xslt-notinc" src="stylesheets/page2fo.xsl"/&gt;
+    &lt;map:serialize type="fo2pdf"/&gt;
+   &lt;/map:match&gt;
+   
+   &lt;!-- incremental processing = true --&gt;
+   &lt;map:match pattern="*.html"&gt;
+    &lt;map:generate src="docs/{1}.xml"/&gt;
+    &lt;map:transform src="stylesheets/page2html.xsl"/&gt;
+    &lt;map:serialize type="html"/&gt;
+   &lt;/map:match&gt;
+   
+&lt;/map:pipeline&gt;
+</pre>
+
+
+
+  
+<h1>Comments</h1>
+
+<p>
+Care to comment on this Snippet? Got another tip? Help keep this Snippet relevant by passing along any useful feedback to the <a href="mailto:users.at.cocoon.apache.org">cocoon users list.</a>
+
+</p>
+
+
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/meta.xml
new file mode 100644
index 0000000..44c71f1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-specifying-xslt-options/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>snippet/snippet-xslt-options.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/content_en.html
new file mode 100644
index 0000000..2b4adad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/content_en.html
@@ -0,0 +1,570 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SQL Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Sven Beauprez" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+</head>
+<body>
+    
+<h1>Introduction</h1>
+      
+<p>
+        The purpose of the SQLTransformer is to query a database and translate
+        the result to XML. To retrieve the information from the database, you
+        are not restricted to use simple SQL statements (e.g. select, insert,
+        update), it is also possible to use stored procedures. In combination
+        with other transformers (e.g. FilterTransformer), this one can be very
+        powerful.
+      </p>
+      
+<ul>
+        
+<li>Name: sql</li>
+        
+<li>Class: org.apache.cocoon.transformation.SQLTransformer</li>
+        
+<li>Cacheable: no</li>
+      
+</ul>
+    
+    
+<h1>Basic functionality</h1>
+      
+<p>
+        To be able to query a database, we need XML that describes exactly what
+        we want to do. The general structure of this input XML is as follows:
+      </p>
+      
+<pre class="code">
+      
+  &lt;page&gt;
+    &lt;execute-query xmlns="http://apache.org/cocoon/SQL/2.0"&gt; 
+      &lt;query&gt;
+      &lt;!-- here comes the SQL statement or stored procedure --&gt;
+      &lt;/query&gt;
+    &lt;/execute-query&gt;
+  &lt;/page&gt;
+   </pre>
+      
+<p>
+        Nothing prevents you from putting other XML around the
+        <span class="codefrag">execute-query</span> element. Any element not in the SQL namespace
+        will stay untouched. The format of the SQL statement or the stored
+        procedure is exactly the same as if you would call it directly from java
+        with a prepared statement or a callable statement.
+      </p>
+      
+<p>The query element has the following optional attributes:</p>
+      
+<ol>
+        
+<li>
+          
+<strong>name</strong>:
+          Naming a query implicates naming the corresponding rowset (see below).
+          When you have a sequence of queries you want to execute, it can be
+          handy give them a name. To process the retrieved data of a certain
+          query, you can use another transformer to check the name of the rowset
+          and to execute the necessary business logic on it.
+          <br>
+          usage: <span class="codefrag">&lt;query name="myName"&gt;</span>
+        
+</li>
+        
+<li>
+          
+<strong>isstoredprocedure</strong>:
+          When you want to use stored procedures, you have to explicitly add
+          this attribute to the query element. By default, the transformer
+          assumes that you want to execute a SQL statement.
+          <br>
+          usage: <span class="codefrag">&lt;query isstoredprocedure="true"&gt;</span>
+        
+</li>
+      
+</ol>
+      
+<p>Here is an example of how the input XML might look like:</p>
+      
+<pre class="code">
+      
+  &lt;page&gt;
+   &lt;title&gt;Hello&lt;/title&gt;
+   &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page filled with sql data!&lt;/para&gt;
+    &lt;execute-query xmlns="http://apache.org/cocoon/SQL/2.0"&gt; 
+     &lt;query name="department"&gt;
+          select id,name from department_table 
+     &lt;/query&gt;
+    &lt;/execute-query&gt;
+   &lt;/content&gt;
+  &lt;/page&gt;
+   </pre>
+      
+<p>
+        You can use the file generator to retrieve the XML from the filesystem.
+        To invoke the SQLTransformer you have to add following to the sitemap:
+      </p>
+      
+<pre class="code">
+      
+  &lt;map:transform type="sql"&gt;
+    &lt;map:parameter name="use-connection" value="personnel"/&gt;
+    &lt;map:parameter name="show-nr-of-rows" value="true"/&gt; 
+    &lt;map:parameter name="clob-encoding" value="UTF-8"/&gt; 
+  &lt;/map:transform&gt;
+   </pre>
+      
+<p>
+        The <span class="codefrag">use-connection</span> parameter defines which connection,
+        defined under the datasources element in <span class="codefrag">cocoon.xconf</span>, the
+        SQLTransformer has to use to retrieve the data.
+      </p>
+      
+<p>
+        The <span class="codefrag">show-nr-of-rows</span> instructs the transformer to count the
+        number of rows in the resultset explicitly and to set the result as
+        attribute to the rowset element. This attribute is only useful in
+        combination with a sql statement, not with stored procedures. If a
+        stored procedure returns a resultset and you want to know how many rows
+        it contains, you have to count the number of rows in another transformer
+        or your stored procedure has to return it also (last solution is the
+        best one).
+      </p>
+      
+<p>
+        The <span class="codefrag">clob-encoding</span> parameter defines what encoding should be
+        used in getting content from CLOB columns.
+      </p>
+      
+<p>The output XML will look as follows:</p>
+      
+<pre class="code">
+      
+  &lt;page&gt;
+   &lt;title&gt;Hello&lt;/title&gt;
+   &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page filled with sql data!&lt;/para&gt;
+    &lt;rowset nrofrows="2" name="department" 
+            xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+      &lt;row&gt;
+        &lt;id&gt;1&lt;/id&gt;
+        &lt;name&gt;Programmers&lt;/name&gt;
+      &lt;/row&gt;
+      &lt;row&gt;
+        &lt;id&gt;2&lt;/id&gt;
+        &lt;name&gt;Loungers&lt;/name&gt;
+      &lt;/row&gt;
+    &lt;/rowset&gt;
+   &lt;/content&gt;
+  &lt;/page&gt;
+   </pre>
+      
+<p>
+        If you use this in combination with the <span class="codefrag">simple-sql2html.xsl</span>
+        stylesheet,
+      </p>
+      
+<pre class="code">
+      
+  &lt;map:transform src="stylesheets/simple-sql2html.xsl"/&gt;
+   </pre>
+      
+<p>you will get a more visually attractive page.</p>
+      
+<p>See below for a more in depth example with stored procedures.</p>
+      
+<p>
+        By now you should be able to use the SQLTransformer, but there are some
+        more options you might find useful...
+      </p>
+    
+    
+<h1>Advanced functionality</h1>
+      
+<h2>Substitution</h2>
+<p>
+          Sometimes you need more information before you can execute a query,
+          e.g. the name of the user that is currently logged on your site. This
+          information is only available at runtime and hence can only be
+          substituted in the query when available.
+        </p>
+<p>
+          To pass this information to the SQL statement, the input XML has to
+          look like this:
+        </p>
+<pre class="code">
+        
+  &lt;page xmlns:sql="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;execute-query xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+      &lt;query&gt;
+       select id,name from employee_table where name =
+                '&lt;sql:substitute-value sql:name="username"/&gt;'
+      &lt;/query&gt;
+    &lt;/execute-query&gt;
+  &lt;/page&gt;
+     </pre>
+<p>
+          The substitution is done by the SQLTransformer before it executes the
+          query (before it calls the method <span class="codefrag">prepareStatement</span>!). For
+          this, the transformer has to be given the necessary values via the
+          sitemap (as parameter):
+        </p>
+<pre class="code">
+        
+  &lt;map:transform type="sql"&gt;
+    &lt;map:parameter name="use-connection" value="personnel"/&gt;
+    &lt;map:parameter name="show-nr-of-rows" value="true"/&gt; 
+    &lt;map:parameter name="username" value="Stefano Mazzocchi"/&gt;
+  &lt;/map:transform&gt;
+     </pre>
+<p>
+          Whenever the transformer encounters a <span class="codefrag">substitute-value</span>
+          element for which the attribute <span class="codefrag">name</span> contains the value
+          <span class="codefrag">username</span>, it will replace this element with the value
+          <span class="codefrag">Stefano Mazzocchi</span>.
+        </p>
+<p>The output XML will be as follow:</p>
+<pre class="code">
+        
+  &lt;page xmlns:sql="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;rowset nrofrows="1" xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+      &lt;row&gt;
+        &lt;id&gt;2&lt;/id&gt;
+        &lt;name&gt;Stefano Mazzocchi&lt;/name&gt;
+      &lt;/row&gt;
+    &lt;/rowset&gt;
+  &lt;/page&gt;
+     </pre>
+<p>
+          It is also possible to use substitution in combination with stored
+          procedures.
+        </p>
+      
+<h2>Ancestors</h2>
+<p>This functionality is best described by a simple example.</p>
+<p>Take following input XML:</p>
+<pre class="code">
+        
+  &lt;page xmlns:sql="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;execute-query xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+     &lt;query name="department"&gt;
+          select id,name from department_table
+     &lt;/query&gt;
+     &lt;execute-query&gt;
+      &lt;query name="employee"&gt;
+       select id,name from employee_table where department_id =
+                  &lt;ancestor-value sql:name="id" sql:level="1"/&gt;
+      &lt;/query&gt;
+     &lt;/execute-query&gt;
+    &lt;/execute-query&gt;
+  &lt;/page&gt;
+     </pre>
+<p>
+          The first query will retrieve all <span class="codefrag">id</span>'s and
+          <span class="codefrag">name</span>'s from the <span class="codefrag">department_table</span> table. For
+          each <span class="codefrag">id</span> that comes from the
+          <span class="codefrag">department_table</span>, the second query, in which the
+          <span class="codefrag">ancestor-value</span> element will be replaced by the
+          <span class="codefrag">id</span>, will be executed. The above example will be
+          transformed to the following XML:
+        </p>
+<pre class="code">
+        
+  &lt;page xmlns:sql="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;rowset nrofrows="2" name="department" 
+            xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+      &lt;row&gt;
+        &lt;id&gt;1&lt;/id&gt;
+        &lt;name&gt;Programmers&lt;/name&gt;
+        &lt;rowset nrofrows="2" name="employee"&gt;
+          &lt;row&gt;
+            &lt;id&gt;1&lt;/id&gt;
+            &lt;name&gt;Donald Ball&lt;/name&gt;
+          &lt;/row&gt;
+          &lt;row&gt;
+            &lt;id&gt;2&lt;/id&gt;
+            &lt;name&gt;Stefano Mazzocchi&lt;/name&gt;
+          &lt;/row&gt;
+        &lt;/rowset&gt;
+      &lt;/row&gt;
+      &lt;row&gt;
+        &lt;id&gt;2&lt;/id&gt;
+        &lt;name&gt;Loungers&lt;/name&gt;
+        &lt;rowset nrofrows="1" name="employee"&gt;
+          &lt;row&gt;
+            &lt;id&gt;3&lt;/id&gt;
+            &lt;name&gt;Pierpaolo Fumagalli&lt;/name&gt;
+          &lt;/row&gt;
+        &lt;/rowset&gt;
+      &lt;/row&gt;
+    &lt;/rowset&gt;
+  &lt;/page&gt;
+     </pre>
+      
+<h2>in- and out-parameters</h2>
+<p>
+          Stored procedures can return data as a parameter. To make use of this
+          functionality in java, you have to register these parameters as
+          <em>out parameters</em>. Since this information is application
+          specific, the SQLTransformer uses reflection to retrieve the data in
+          the right format. For this, an extra element is needed in the input
+          XML:
+        </p>
+<pre class="code">
+        
+  &lt;out-parameter sql:nr="1" sql:name="code"
+                 sql:type="java.sql.Types.INTEGER"/&gt;
+     </pre>
+<p>where:</p>
+<ol>
+          
+<li>
+            
+<strong>nr</strong>:
+            The targeted parameter number that will return data of a certain
+            type.
+          </li>
+          
+<li>
+            
+<strong>type</strong>:
+            The type of data that will be returned (defined in
+            <span class="codefrag">java.sql.Types</span> or in database specific drivers, e.g.
+            <span class="codefrag">oracle.jdbc.driver.OracleTypes</span>). Once the stored
+            procedure returns data in the parameters, the stored procedure tries
+            to process them. If the returned parameter is an instance of
+            <span class="codefrag">ResultSet</span>, it will be translated to XML as we saw
+            before. In all the other situations the SQLTransformer will convert
+            the parameter to a string.
+          </li>
+        
+</ol>
+<p>
+          This is an example of how to call an oracle stored procedure and
+          process it with the SQLTransformer:
+        </p>
+<pre class="code">
+        
+  &lt;page xmlns:sql="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;execute-query xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+      &lt;query isstoredprocedure="true" name="namesearch"&gt;
+          begin QUICK_SEARCH.FIND_NAME('&lt;sql:substitute-value
+                          sql:name="username"/&gt;',?,?,?); end;
+      &lt;/query&gt;
+      &lt;out-parameter sql:nr="1" sql:name="code"
+                     sql:type="java.sql.Types.INTEGER"/&gt;
+      &lt;out-parameter sql:nr="2" sql:name="nrofrows"
+                     sql:type="java.sql.Types.INTEGER"/&gt;
+      &lt;out-parameter sql:nr="3" sql:name="resultset"
+                     sql:type="oracle.jdbc.driver.OracleTypes.CURSOR"/&gt;
+    &lt;/execute-query&gt;
+  &lt;/page&gt;
+     </pre>
+<p>
+          The SQLTransformer will create 3 elements, respectively
+          <span class="codefrag">code</span>, <span class="codefrag">nrofrows</span> and <span class="codefrag">resultset</span>
+          under the element <span class="codefrag">namesearch</span>. Since the type
+          <span class="codefrag">oracle.jdbc.driver.OracleTypes.CURSOR</span> corresponds to a
+          <span class="codefrag">ResultSet</span>, a <span class="codefrag">rowset</span> element will be created,
+          containing all the data of the resultset. It is also possible to use
+          an <em>in-parameter</em> element, e.g.
+          <span class="codefrag">&lt;in-parameter sql:nr="1" sql:value="1"/&gt;</span>. This
+          functionality is only provided to be complete, because it is available
+          in Java itself. You can also use the <em>in-parameter</em> in
+          combination with a SQL statement. Used in combination with an
+          <em>out-parameter</em>, a <em>?-parameter</em> can be an
+          <em>in-parameter</em> and an <em>out-parameter</em> at the same time.
+        </p>
+    
+    
+<h1>Combined with other transformers</h1>
+      
+<h2>Filtertransformer</h2>
+<p>
+          When you query a database and it returns too many rows to process at
+          once, you might want to take a block of elements, process this block
+          and ignore the rest for now. You can best compare it to a search on
+          Google: they only return 10 results in one time, for more results you
+          have to click on another block (page). It wouldn't be wise to process
+          more than 10 elements in the pipeline if you only need to display 10
+          elements.
+        </p>
+<p>
+          Assume that a query returns 56 row elements (by using the
+          SQLTransformer) and that you only want to display the first 10
+          elements:
+        </p>
+<p>Output XML from the SQLTransformer:</p>
+<pre class="code">
+        
+  &lt;rowset nrofrows="56" name="test"
+          xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;row&gt;
+      &lt;!-- db record --&gt;
+    &lt;/row&gt;
+    &lt;row&gt;
+      &lt;!-- db record --&gt;
+    &lt;/row&gt;
+
+    ...
+
+    &lt;row&gt;
+      &lt;!-- db record --&gt;
+    &lt;/row&gt;
+  &lt;/rowset&gt;
+     </pre>
+<p>
+          By adding following lines to the sitemap, just under the
+          SQLTransformer, you restrict the results to 10 elements in the first
+          block:
+        </p>
+<pre class="code">
+        
+  &lt;map:transform type="filter"&gt;
+    &lt;map:parameter name="element-name" value="row"/&gt;
+    &lt;map:parameter name="count" value="10"/&gt;
+    &lt;map:parameter name="blocknr" value="1"/&gt;
+  &lt;/map:transform&gt;
+     </pre>
+<p>output XML:</p>
+<pre class="code">
+        
+  &lt;rowset nrofrows="56" name="test"
+          xmlns="http://apache.org/cocoon/SQL/2.0"&gt;
+    &lt;block id="1"&gt;
+      &lt;row&gt;
+        &lt;!-- db record --&gt;
+      &lt;/row&gt;
+
+      &lt;!-- total of 10 rows --&gt;
+
+      &lt;row&gt;
+        &lt;!-- db record --&gt;
+      &lt;/row&gt;
+    &lt;/block&gt;
+    &lt;block id="2"/&gt;
+    &lt;block id="3"/&gt;
+    &lt;block id="4"/&gt;
+    &lt;block id="5"/&gt;
+    &lt;block id="6"/&gt;
+  &lt;/rowset&gt;
+     </pre>
+<p>
+          To make it more dynamically, put something like
+          <span class="codefrag">{reqCount}</span> and <span class="codefrag">{reqBlock}</span> in the values for
+          <em>count</em> and <em>blocknr</em> respectively. These can be
+          parameters from the request and they can be passed to the sitemap with
+          an action.
+        </p>
+<p>
+          The FilterTransformer is a standalone component; you don't need to use
+          it in combination with the SQLTransformer.
+        </p>
+      
+<h2>WriteDOMSessionTransformer</h2>
+<p>
+          If you only use the FilterTransformer in combination with the
+          SQLTransformer, you have to query the database each time the user
+          wants to see another part of the result. You can better store the
+          result in the session after the first request and retrieve the result
+          from the session for the subsequent requests. This can be done by
+          using a selector, which checks if the data is available in the session
+          or not.
+        </p>
+<p>
+          WriteDOMSessionTransformer can build a DOM starting from a given
+          element (which will be the root of the DOM tree) and store it in the
+          session. If you want to store the result of a query, you have to add
+          following to the sitemap:
+        </p>
+<pre class="code">
+        
+  &lt;map:transform type="writeDOMsession"&gt;
+    &lt;map:parameter name="dom-name" value="DBresult"/&gt;
+    &lt;map:parameter name="dom-root-element" value="rowset"/&gt;
+  &lt;/map:transform&gt;
+     </pre>
+<p>
+          The transformer will build a DOM tree with <span class="codefrag">rowset</span> as root
+          element and will store it in the session with the name
+          <span class="codefrag">DBresult</span>.
+        </p>
+<div class="note">
+          Most of the times, it is not smart to keep the output XML of the
+          SQLTransformer in the session. Check if it is better to do the
+          necessary transformations first, so that you get a smaller DOM, and
+          then put the result in the session. You probably will be able to use
+          the FilterTransformer on the transformed XML also.
+        </div>
+<p>
+          The WriteDOMSessionTransformer is a standalone component, you don't
+          need to use it in combination with the SQLTransformer.
+        </p>
+      
+<h2>ReadDOMSessionTransformer</h2>
+<p>
+          Simply transforms a DOM to SAX events, which can be used further on in
+          the pipeline. Once you stored the result of a query in the session
+          with the WriteDOMSessionTransformer, you can read it again with the
+          ReadDOMSessionTransformer:
+        </p>
+<pre class="code">
+        
+  &lt;map:transform type="readDOMsession"&gt;
+    &lt;map:parameter name="dom-name" value="DBresult"/&gt;
+    &lt;map:parameter name="trigger-element" value="users"/&gt;
+    &lt;map:parameter name="position" value="after"/&gt;
+  &lt;/map:transform&gt;
+     </pre>
+<p>
+          In this example the SAX events, that come from the DOM tree stored in
+          the session with name <span class="codefrag">DBresult</span>, will be added after the
+          <span class="codefrag">users</span> element. This means as soon that the transformer
+          encounters the end element <span class="codefrag">users</span>, it will start to
+          generate SAX events from the DOM tree. There are three possible
+          positions, <span class="codefrag">before</span>, <span class="codefrag">in</span> and
+          <span class="codefrag">after</span>:
+        </p>
+<ol>
+          
+<li>
+            
+<strong><span class="codefrag">before</span></strong> means that when the transformer
+            encounters the <span class="codefrag">users</span> element, it will FIRST translate
+            the DOM tree to SAX events and THEN it will continue to forward the
+            other SAX events (starting with <span class="codefrag">users</span>).
+          </li>
+          
+<li>
+            
+<strong><span class="codefrag">in</span></strong> means that the transformer will
+            forward the start element event for <span class="codefrag">users</span> and that it
+            IMMEDIATELY starts to generate SAX events from the DOM tree. After
+            that, it will continue to forward the child elements of users and
+            then all the other elements.
+          </li>
+          
+<li>
+            
+<strong><span class="codefrag">after</span></strong> means that the transformer
+            starts to generate SAX events from the DOM tree just after it has
+            forwarded the end element <span class="codefrag">users</span>.
+          </li>
+        
+</ol>
+<p>
+          The ReadDOMSessionTransformer is a standalone component, you don't
+          need to use it in combination with the WriteDOMSessionTransformer.
+        </p>
+      
+<p>That's it,</p>
+      
+<p>Sven Beauprez</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/meta.xml
new file mode 100644
index 0000000..fc709d1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-sql-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/sql-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/content_en.html
new file mode 100644
index 0000000..771cc9c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/content_en.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Status Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the status generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Status Generator</h1>
+      
+<p>The status generator creates xml from the current status of cocoon.</p>
+      
+<p>The information is surrounded by the root element <span class="codefrag">statusinfo</span>
+                     and grouped with the elements <span class="codefrag">group</span> and <span class="codefrag">value</span>.</p>
+      
+<p>The <span class="codefrag">statusinfo</span> element has the attributes <span class="codefrag">host</span>
+                     and <span class="codefrag">date</span>.</p>
+                  
+<p>A group collects several informations about one topic. The topic
+                     is set by the attribute <span class="codefrag">name</span> of the group. A group
+                     can have subgroups (element <span class="codefrag">group</span>) or values.</p>
+                  
+<p>Each value has a name specified by the attribute <span class="codefrag">name</span> and can
+                     consist of one or several <span class="codefrag">line</span>.</p>
+      
+<p>All elements have the namespace <span class="codefrag">http://apache.org/cocoon/status/2.0</span>.</p>
+      
+<ul>
+        
+<li>Name : status</li>
+        
+<li>Class: org.apache.cocoon.generation.StatusGenerator</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<pre class="code">
+     
+  &lt;map:generate type="status"/&gt;
+     
+</pre>
+    
+                
+<h1>DTD</h1>
+                
+<p>XML generated by status generator uses namespace 
+                  <span class="codefrag">http://apache.org/cocoon/status/2.0</span>. The DTD of XML
+                  generated by status generator:
+                </p>
+
+<pre class="code">
+&lt;!ELEMENT statusinfo (group|value)*&gt;
+
+&lt;!ATTLIST statusinfo
+   date CDATA #IMPLIED
+   host CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT group (group|value)*&gt;
+&lt;!ATTLIST group
+   name CDATA #IMPLIED
+&gt;
+
+&lt;!ELEMENT value (line)+&gt;
+&lt;!ATTLIST value
+   name CDATA #REQUIRED
+
+&lt;!ELEMENT line (#PCDATA)+&gt;
+</pre>
+                
+    
+<h1>Example</h1>
+    
+<p>The current status generator outputs information about the jvm:</p>
+
+<pre class="code">
+     
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;statusinfo date="16.07.2001 16:46:20" host="myhost" 
+            xmlns="http://apache.org/cocoon/status/2.0" 
+            xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
+  &lt;group name="vm"&gt;
+    &lt;group name="memory"&gt;
+      &lt;value name="total"&gt;&lt;line&gt;11788288&lt;/line&gt;&lt;/value&gt;
+      &lt;value name="free"&gt;&lt;line&gt;2778208&lt;/line&gt;&lt;/value&gt;
+    &lt;/group&gt;
+    &lt;group name="jre"&gt;
+      &lt;value name="version"&gt;&lt;line&gt;1.3.0&lt;/line&gt;&lt;/value&gt;
+      &lt;value type="simple" href="http://java.sun.com/" name="java-vendor"&gt;
+        &lt;line&gt;Sun Microsystems Inc.&lt;/line&gt;
+      &lt;/value&gt;
+    &lt;/group&gt;
+    &lt;group name="operating-system"&gt;
+      &lt;value name="name"&gt;&lt;line&gt;Windows 2000&lt;/line&gt;&lt;/value&gt;
+      &lt;value name="architecture"&gt;&lt;line&gt;x86&lt;/line&gt;&lt;/value&gt;
+      &lt;value name="version"&gt;&lt;line&gt;5.0&lt;/line&gt;&lt;/value&gt;
+    &lt;/group&gt;
+    &lt;value name="classpath"&gt;
+      &lt;line&gt;classes&lt;/line&gt;
+      &lt;line&gt;lib\ant.jar&lt;/line&gt;
+      &lt;line&gt;lib\jasper.jar&lt;/line&gt;
+    &lt;/value&gt;
+  &lt;/group&gt;
+&lt;/statusinfo&gt;     
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/meta.xml
new file mode 100644
index 0000000..846ca59
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-status-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/status-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/content_en.html
new file mode 100644
index 0000000..de49054
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/content_en.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>StoreJanitor in Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Gerhard Froehlich" name="DC.Creator">
+<meta content="This document describes the usage of the StoreJanitor under Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Goal</h1>
+<p>This document describes the usage of the StoreJanitor under 
+  Apache Cocoon.</p>
+  
+<h1>Description</h1>
+  
+<p>The implementation is quite simple! Every implementation of a Store can register in the 
+  StoreJanitor. It checks at a configurable interval if memory is running low. If low, 
+  it greps via Round Robin a victim (Store) and frees xx% of all elements in this Store. 
+  After that the StoreJanitor sleeps and waits for the next iteration.</p>
+  
+  
+<h1>Configuration</h1>
+  
+<pre class="code">
+&lt;store-janitor logger="root.store"&gt;
+  &lt;parameter name="freememory" value="1000000"/&gt;
+  &lt;parameter name="heapsize" value="60000000"/&gt;
+  &lt;parameter name="cleanupthreadinterval" value="10"/&gt;
+  &lt;parameter name="threadpriority" value="5"/&gt;
+  &lt;parameter name="percent_to_free" value="10"/&gt;
+&lt;/store-janitor&gt;
+  </pre> 
+  
+<p>The right configuration is very important, because wrong settings can cause a high system load.</p>
+  
+<h2>Example configuration</h2>
+<ul>
+<li>Tomcat settings in tomcat.sh or tomcat.bat:</li>
+</ul>
+<pre class="code">
+%_RUNJAVA% %TOMCAT_OPTS% -Dtomcat.home="%TOMCAT_HOME%" \
+  -Xmx200000000 org.apache.tomcat.startup.Tomcat %2 %3 %4 %5 %6 %7 %8 %9
+    </pre>
+<ul>
+<li>StoreJanitor settings:</li>
+</ul>
+<p>The freememory and heapsize parameters always depend on the Xmx 
+    parameter.</p>
+<pre class="code">
+&lt;store-janitor logger="root.store"&gt;
+  &lt;parameter name="freememory" value="50000000"/&gt;
+  &lt;parameter name="heapsize" value="150000000"/&gt;
+  &lt;parameter name="cleanupthreadinterval" value="10"/&gt;
+  &lt;parameter name="threadpriority" value="5"/&gt;
+  &lt;parameter name="percent_to_free" value="10"/&gt;
+&lt;/store-janitor&gt;
+    </pre>
+<p>It is recommended to have <span class="codefrag">heapsize</span> equal to -Xmx, especially
+    on Sun's JVM which is unable to shrink its heap once it grows above the minimum. 
+    The <span class="codefrag">freememory</span> parameter should be greater than the amount
+    of memory necessary for normal application operation.
+    </p>
+<p> The <span class="codefrag">cleanupthreadinterval</span> defines the interval
+    (in seconds)of the background 
+    thread which checks memory. Also this parameter should configured wisely. 
+    A too short interval can also cause a high system load. The 
+    <span class="codefrag">threadpriority</span> defines the priority of the background thread
+    (1 is the lowest level and 10 the highest).</p>
+<p>
+    The <span class="codefrag">percent_to_free</span> parameter describes what percentage of the 
+    elements of each registered Store shall be removed when low on memory.
+    </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/meta.xml
new file mode 100644
index 0000000..5e9d1b1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-store-janitor/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/storejanitor.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/content_en.html
new file mode 100644
index 0000000..bbf4c5c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/content_en.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Source Resolving</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Sylvain Wallez" name="DC.Creator">
+</head>
+<body>
+  
+<h1>The Store Components in Cocoon</h1>
+    
+    
+<p>
+      To keep cached data, Cocoon uses components implementing the
+      <em>org.apache.excalibur.Store</em> interface. Cocoon uses two
+      implementations of this interface, the "transient store" and the "store",
+      and optionally a third one, the "persistent store".
+    </p>
+
+    
+<h2>The Transient store</h2>
+<p>
+        The transient store (role <em>Store.TRANSIENT_STORE</em> is used for objects
+        that are not serializable, or whose storage doesn't make sense across server
+        restart. The transient store lives on its own and has no relation with other
+        stores. This is a mandatory component within Cocoon (i.e. used by Cocoon's code).
+        Transient store can drop stored components if system is running low on memory.
+      </p>
+<p>
+        Cocoon uses the transient store to cache XSLT style sheets, XSP logicsheets, etc.
+      </p>
+    
+<h2>The Store (aka "main Store")</h2>
+<p>
+        The store (role <em>Store.ROLE</em>) can hold not serializable objects also.
+        It is a mandatory component, as the transient store. If memory is scarce, the
+        store can drop non serializable objects, and swaps serializable objects to disk.
+        For efficiency reasons, implementations of the store should swap out (or drop)
+        least often used objects. On shutdown, store can write out all objects residing
+        in memory to the disk.
+      </p>
+<p>
+        Cocoon uses the main store to cache pipeline output.
+      </p>
+    
+<h2>Persistent store (optional)</h2>
+<p>
+        Some store (<em>Store.ROLE</em>) implementations (but not all)
+        may actually be just an in-memory cache that swap objects by calling
+        the persistent store (<em>Store.PERSISTENT_STORE</em>) when needed. So
+        the persistent store is an <em>optional</em> component which is used only
+        by MRUMemoryStore, and nowhere else in the code.
+      </p>
+<p>
+        Two examples to illustrate this:
+      </p>
+<ul>
+        
+<li>when using JISP, we had this mechanism : the store was a MRUMemoryStore
+            swapping to the persistent store which was a JISPStore.</li>
+        
+<li>JCS has its own in-memory front end to its own persistent storage.
+            In this configuration Store.ROLE will be a JCSStore and
+            Store.PERSISTENT_STORE will have no implementation, because we don't
+            need it.
+        </li>
+      
+</ul>
+  
+  
+<h1>Summary</h1>
+    
+    
+<ul>
+      
+<li>Store.TRANSIENT_STORE : used by Cocoon to store non-serializable objects</li>
+      
+<li>Store.ROLE : used by Cocoon to store serializable objects</li>
+      
+<li>Store.PERSISTENT_STORE : optional component that may be used by in-memory
+          implementations of Store.ROLE to delegate persistent storage.</li>
+    
+</ul>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/meta.xml
new file mode 100644
index 0000000..6e11ea3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stores/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>developing/stores.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/content_en.html
new file mode 100644
index 0000000..ac7d2be
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/content_en.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Stream Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Kinga Dziembowska" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+<meta content="This document describes the stream generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Stream Generator</h1>
+              
+<p>
+              The StreamGenerator is a class that reads XML from an HttpRequest 
+              InputStream and generates SAX Events. StreamGenerator expects 
+              XML data coming as HTTP request message. 
+              </p>
+      
+<ul>
+        
+<li>Name : stream</li>
+        
+<li>Class: org.apache.cocoon.generation.StreamGenerator</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+               
+<p>
+             For POST requests with mimetype of application/x-www-form-urlencoded, 
+          the xml data expects to be associated with the name specified 
+              in the sitemap parameter.
+              </p>
+
+              
+<p>
+              For HTTP requests with mimetypes: text/plain, text/xml, application/xml 
+              the xml data is in the body of the HTTP request and its length is 
+              specified by the value returned by getContentLength() method.
+              </p>
+      
+<h2>PostInputStream</h2>
+<p>
+              The StreamGenerator uses helper class org.apache.cocoon.util.PostInputStream 
+              for InputStream reading operations. At the time that Parser reads the data 
+              out of InputStream - Parser has no knowledge about the length of data to be
+              read. The only way to signal to the Parser that all data was read from the 
+              InputStream is to control reading   operation - PostInputStream- and to 
+              return to the requestor -1 when the number of bytes read is equal to the 
+              getContentLength() value.
+              </p>
+
+      
+<h2>See it in Action</h2>
+<p>
+              The Generator is a generic object, i.e. it can process any stream out of the 
+              HTTP message. There are two ways to see StreamGenerator in action:
+              </p>
+<ul>
+                  
+<li>To invoke URL http://localhost:8080/cocoon/Order</li>
+                  
+<li>To use telnet program to generate POST request</li>
+              
+</ul>
+<p>  
+              The first option is not a "pure" stream invocation, but it is quick way to 
+              observe desired effects. The result of this invocation is a form containing 
+              the XML document embedded in the textarea of the form. Submission of this 
+              form will invoke StreamGenerator. The testarea name/value par is specified 
+              as a parameter in the sitemap definition for the StreamGenerator. The expected 
+              result is the submitted xml document send back to the browser.
+              </p>
+<p>
+              The second or "pure" option of testing StreamGenerator "in action," requires the 
+              use of Telnet program or any other process able to generate correct HTTP message. 
+              The procedure is:
+              </p>
+<ul>
+                  
+<li>To invoke telnet, connect to localhost 8080 and to use content of 
+                      <a href="telnet.txt">telnet.txt</a> file as a post message. 
+                  </li>
+                  
+<li>Here, the Copy-Paste method should be used.</li>
+                  
+<li>Remember to hit the enter button twice enter after the contents of the post are set in telnet.</li>
+              
+</ul>
+<p>
+              It is important because Content-len is calculated assuming two "enter" in the end of http message. 
+              Once again, the performed task results in the mirror of the original document being sent back to the requestor. 
+              </p>
+<p>
+              The "pure" stream generation can be observed using the telnet utility where you can invoke a 
+              message targeting my processing. Any other method is good (URL object connection) as 
+              long the message is well formed.
+              </p>
+<pre class="code">
+     
+  &lt;map:generate type="stream"/&gt;
+     
+</pre>
+<p>
+              If you want to process XML streams sent by clients that don't set the Content-Type HTTP header
+              just use the defaultContentType parameter.
+                 
+            </p>
+<pre class="code">
+     
+  &lt;map:generate type="stream"&gt;
+    &lt;map:parameter name="defaultContentType" value="text/xml"/&gt;
+  &lt;/map:generate&gt;
+     
+</pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/meta.xml
new file mode 100644
index 0000000..67896cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-stream-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/stream-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/content_en.html
new file mode 100644
index 0000000..6457921
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/content_en.html
@@ -0,0 +1,156 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Template-Matcher in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Your Name" name="DC.Creator">
+<meta content="This document describes the TemplateMatcher of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>TemplateMatcher</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">template</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">TemplateMatcher</span> component is used 
+            to serve data in a sitemap pipeline.
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Matcher, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where TemplateMatcher sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core/Block-Name/Scratchpad</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.matching.TemplateMatcher</td>
+        
+</tr>
+        <!-- uncomment folling tr iff TemplateMatcher is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon X.Y</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        A general description of TemplateMatcher
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        A usage scenario of TemplateMatcher
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p></p>
+<pre class="code">
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    &lt;map:match pattern="page-*.html"&gt;
+      &lt;map:generator 
+        src="{1}"
+      &gt;
+        &lt;!-- option sitemap parameters --&gt;
+      &lt;/map:generator&gt;
+    &lt;/map:match&gt;
+  &lt;/map:pipeline&gt;
+  ...
+        </pre>
+      
+      
+<h2>Sitemap component configuration example</h2>
+<p></p>
+<pre class="code">
+&lt;map:matchers...
+  &lt;map:matcher name="template" 
+    src="org.apache.cocoon.matching.TemplateMatcher"
+    logger="sitemap.matcher.template" 
+  /&gt;
+    &lt;!-- optional matcher configuration --&gt;
+    ...
+  &lt;/map:matcher&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          Explain the sitemap matcher configuration, options when declaring template matcher
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          Explain the sitemap matcher setup, ie options when using template matcher
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+        
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        <!-- Describe limitation, bugs of TemplateMatcher --> 
+      
+</p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        MM-DD-YY: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        <!-- Links to related components pages. -->
+        A general documentation about matchers is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/meta.xml
new file mode 100644
index 0000000..cb52a84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-template-matcher/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/matchers/template-matcher.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/content_en.html
new file mode 100644
index 0000000..1a03f83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/content_en.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Testing your Apache Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="Stephan Michels" name="DC.Creator">
+<meta content="David Crossley" name="DC.Creator">
+</head>
+<body>
+ 
+<h1>Overview of testing procedures</h1>
+  
+<p>
+   There are some initial procedures available for you to ensure that
+   Apache Cocoon can run properly on your particular computing platform
+   and that the components do function properly.
+  </p>
+  
+<p>
+   You can build upon this infrastructure to add your own tests, and to
+   ensure that development work proceeds smoothly. The tests are located
+   in the <span class="codefrag">src/test/</span> directory.
+  </p>
+ 
+
+ 
+<h1>JUnit tests</h1>
+  
+<p>
+   Run "<span class="codefrag">build test</span>" to conduct an initial set of
+   automated JUnit test cases,
+   e.g. Test various transformers;
+   Test the methods for getting platform-dependent filesystem pathnames; etc.
+  </p>
+
+  
+<h2>How to add more tests</h2>
+<p>
+    As there is already a nice junit framework available, it is not that
+    difficult to add junit tests for any transformer. In short:
+   </p>
+<ul>
+    
+<li>Create XYTransformerTestCase.java</li>
+    
+<li>Create XYTransformerTestCase.xconf</li>
+    
+<li>Edit the transformers section in XYTransformerTestCase.xtest
+     for XYTransformerTestCase</li>
+    
+<li>Add testABC() methods to XYTransformerTestCase.java</li>
+   
+</ul>
+ 
+
+ 
+<h1>Other tests</h1>
+  
+<ul>
+    
+<li>
+      Some Anteater Functional Tests at <span class="codefrag">src/test/anteater</span>
+    
+</li>
+    
+<li>
+      
+<a href="../catalog-test.html">Testing: Catalog Entity Resolver</a>
+      which conducts some additional tests for resolving external entities.
+    </li>
+  
+</ul>
+ 
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/meta.xml
new file mode 100644
index 0000000..9e9a33e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tests/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>installing/tests.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/content_en.html
new file mode 100644
index 0000000..fe5a571
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/content_en.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Text Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the text serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>Text Serializer</h1>
+    
+<p>
+      The Text serializer serializes xml into plain text..
+    </p>
+    
+<ul>
+      
+<li>Name : text</li>
+      
+<li>Class: org.apache.cocoon.serialization.TextSerializer</li>
+      
+<li>Cacheable: yes.</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        The text Serializer is declared in the sitemap serializers section.
+      </p>
+<pre class="code">
+&lt;map:serializers...
+...
+ &lt;map:serializer name="text" 
+   src="org.apache.cocoon.serialization.TextSerializer"
+   mime-type="text/plain" 
+   logger="sitemap.serializer.text" 
+ /&gt;
+...
+      </pre>
+<p>
+          The text Serializer sets the <span class="codefrag">method</span> property
+          of the XML serializer to the value <span class="codefrag">text</span>.
+        </p>
+    
+<h2>Pipeline Usage</h2>
+<p>
+        Using the text Serializer in a pipeline is just setting the 
+        serializer type to text. 
+        The following code snippet uses the text Serializer:
+      </p>
+<pre class="code">
+...
+&lt;map:match pattern="announcement.txt"&gt;
+&lt;map:generate...
+...
+&lt;map:serialize type="text"/&gt;
+...
+      </pre>
+<p>
+        The pipeline snippet above serializes the SAX events of the
+        announcment document resource to plain text. 
+      </p>
+<p>
+        Input document of the text serializer must be valid XML document. It
+        should have at least one element, root element, which will contain
+        all the text of the document. Root element will be ignored by text
+        serializer and will not go into the output stream.
+      </p>
+    
+<h2>Further Reading</h2>
+<p>
+        As text Serializer uses the XML serializer internally, you might 
+        want to read the complete list of valid XML configuration parameters.
+        It is available at <a href="xml-serializer.html">XML serializer</a>
+        user documentation.
+      </p>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/meta.xml
new file mode 100644
index 0000000..764ac43
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-text-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/text-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/content_en.html
new file mode 100644
index 0000000..9e62262
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/content_en.html
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Todo List</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+</head>
+<body>
+
+ 
+<devs>
+  <!-- in strict alphabetical order -->
+  
+<person email="crossley@apache.org">
+<a name="DC"></a>
+</person>
+  
+<person email="shannon@apache.org">
+<a name="DS"></a>
+</person>
+  
+<person email="cocoon-dev@apache.org">
+<a name="open"></a>
+</person>
+ 
+</devs>
+
+ 
+<h1>high</h1>
+<ul>
+<li>
+<strong>[docs]</strong> 
+   Decide priorities for initial documentation project efforts.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Decide how draft documentation will be managed in CVS.
+   Probably under the main xdocs to start with.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Decide how to simplify proposed content submission and review process.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Explore options for building "depends" hooks into 
+   documentation to couple document content more tightly to code evolution.
+   In other words, create internal document flags to help identify content
+   to update when a particular component/option changes.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Clarify any copyright issues related to contributed documentation.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Javadocs need simple package.html for description of each class.
+   See email discussion cocoon-dev
+   <a class="external" href="http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102056702426129">Javadocs: need basic package information</a>
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop how-to author Tutorial and Recipe documents.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop how-to author a case studies/success story document.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop how-to author business case document.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop tips on writing effectively document for contributors.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop basic editing conventions for project.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop status page of in-process documents and topics.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Review all existing documentation. Update 
+   <a actuate="user" href="doc.html" show="replace" type="simple">Documentation Revisions</a> as appropriate. 
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Review the titles of all existing documents. At one stage they were
+   deliberately kept short because of show-off banner images. Now there is no
+   need and titles can be properly descriptive. Also set guidelines for new
+   document titles. See cocoon-dev discussion
+   <a class="external" href="http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=101982197707050"> Re: tracks/titles</a>.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Harvest FAQ content from user list. Expand FAQ content. Revise faq-v10.dtd.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop and post survey to user list to assess documentation needs. 
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop comprehensive how-to "wish list" cover all critical development issues. 
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Provide technical review of draft tutorial: "Developing Your Own Generator." 
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Expand documentation infrastructure (XSLT, indexing, etc.) to provide efficient user
+   access to multiple FAQs, How-Tos, Snippets, Tutorials, etc.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Revise web site navigation/hierarchy to make all documentation more accessible.
+   &rarr; </li>
+</ul>
+
+ 
+<h1>medium</h1>
+<ul>
+<li>
+<strong>[code]</strong> 
+   Build upon Ken's excellent Patch Queue notifier to send a reminder/prompt
+   to relevant mail list about outstanding DOC patches in Bugzilla.
+   &rarr; </li>
+<li>
+<strong>[code]</strong> 
+   Explore CMS-related options with Forrest project.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Recruit users for authoring and QA testing.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Explore other QA options, such as off-site wikis and contentEnabled 
+   browser capabilities.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Decide how Cocoon project web site can be updated more frequently.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Edit content of existing documents, based on 
+   <a actuate="user" href="doc.html" show="replace" type="simple">Documentation Revisions</a>.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Restructure existing documents, if necessary, based on 
+   <a actuate="user" href="doc.html" show="replace" type="simple">Documentation Revisions</a>.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop more informative introductory pages for refactored samples.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Figure out how to consistently link between the Samples and the relevant
+   documentation and vice versa. Then create more links.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop learner's roadmaps.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Develop an expanded version of <a actuate="user" href="doc.html" show="replace" type="simple">Documentation Revisions</a>
+   to facilitate contributor and coordination efforts.
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Review all existing scratchpad documentation. Update 
+   <a actuate="user" href="doc.html" show="replace" type="simple">Documentation Revisions</a> as appropriate. 
+   &rarr; </li>
+<li>
+<strong>[docs]</strong> 
+   Decide what to do about the cTwIG (Cocoon Two Idiots Guide). After the
+   re-organisation of the menus, it is no longer linked in.
+   Perhaps some of it should move into the new How-to docs.
+   There is also an old patch waiting in Bugzilla ...
+   <a class="external" href="http://issues.apache.org/bugzilla/show_bug.cgi?id=6435">Bug 6435</a>
+   which contains neglected contributions.
+   &rarr; </li>
+</ul>
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/meta.xml
new file mode 100644
index 0000000..c3c4883
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/todo-doc.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/content_en.html
new file mode 100644
index 0000000..7ffda3f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/content_en.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Todo List</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+</head>
+<body>
+    
+<h1>high</h1>
+<ul>
+<li>
+<strong>[docs]</strong> 
+        Customize this template project with your project's details.  This
+        TODO list is generated from 'status.xml'.
+       &rarr; JB</li>
+<li>
+<strong>[docs]</strong> 
+        Add lots of content.  XML content goes in
+        <span class="codefrag">src/documentation/content/xdocs</span>, or wherever the
+        <span class="codefrag">${project.xdocs-dir}</span> property (set in
+        <span class="codefrag">forrest.properties</span>) points.
+       &rarr; JB</li>
+<li>
+<strong>[feedback]</strong> 
+        Mail <a href="mailto:forrest-dev.at.xml.apache.org">forrest-dev@xml.apache.org</a>
+        with feedback.
+       &rarr; JB</li>
+</ul>
+    <!-- Add todo items. @context is an arbitrary string. Eg:
+    <actions priority="high">
+      <action context="code" dev="SN">
+      </action>
+    </actions>
+    <actions priority="medium">
+      <action context="docs" dev="open">
+      </action>
+    </actions>
+    -->
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/meta.xml
new file mode 100644
index 0000000..1590f3a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-todo2/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>todo.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/content_en.html
new file mode 100644
index 0000000..da9b6c9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/content_en.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Transformers</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes all of the available transformers of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Goal</h1>
+      
+<p>This document lists all of the available transformers of Apache Cocoon and
+                     describes their purpose.</p>
+     
+     
+<h1>Overview</h1>
+  
+<p>
+A transformer is the central point in a sitemap pipeline. Within a pipeline match, transformers consume SAX events and emit SAX events. Transformers are placed inside a pipeline match between a generator and a serializer. You can include several transformers within a pipeline match. Any pipeline match containing a generator and transformer must end with a serializer.
+  </p>
+  
+<p>
+In the sitemap file, each transformer has a unique name which is mapped to a java class. One transformer name must be declared as the default transformer. Each transformer may have additional configuration information specified in child elements.
+  </p>
+  
+<p>
+ For more conceptual information about transformers see <a href="../concepts/sitemap.html">the sitemap</a>.
+  </p>
+
+
+<h1>The Transformers in Apache Cocoon</h1>
+  
+<ul>
+    
+<li>
+<a href="xslt-transformer.html">XSLT Transformer</a> (The default transformer)</li>
+  
+<li>
+<a href="extractor-transformer.html">Fragment Extractor Transformer</a>
+</li>
+  
+<li>
+<a href="i18n-transformer.html">I18n Transformer</a>
+</li>
+  
+<li>
+<a href="log-transformer.html">Log Transformer</a>
+</li>
+  
+<li>
+<a href="sql-transformer.html">SQL Transformer</a>
+</li>
+  
+<li>
+<a href="filter-transformer.html">Filter Transformer</a>
+</li>
+  
+<li>
+<a href="readdomsession-transformer.html">Read DOM Session Transformer</a>
+</li>
+  
+<li>
+<a href="writedomsession-transformer.html">Write DOM Session Transformer</a>
+</li>
+  
+<li>
+<a href="xinclude-transformer.html">XInclude Transformer</a>
+</li>
+  
+<li>
+<a href="cinclude-transformer.html">CInclude Transformer</a>
+</li>
+  
+<li>
+<a href="encodeurl-transformer.html">EncodeURL Transformer</a>
+</li>
+  
+<li>
+<a href="sourcewriting-transformer.html">SourceWriting Transformer</a>
+</li>
+    
+<li>
+<a href="augment-transformer.html">Augment Transformer</a>
+</li>
+    
+<li>
+<a href="jx-template-transformer.html">JX Template Transformer</a>
+</li>
+  
+<li>
+<a href="ldap-transformer.html">LDAP Transformer</a> (optional)</li>
+    
+<li>
+<a href="lexer-transformer.html">Lexical Transformer</a> (optional)</li>
+    
+<li>
+<a href="parser-transformer.html">Parser Transformer</a> (optional)</li>
+    
+<li>
+<a href="pattern-transformer.html">Pattern Transformer</a> (optional)</li>
+    
+<li>
+<a href="../../developing/webapps/contexts.html">Session Transformer</a> (optional)</li>
+  
+</ul>
+
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/meta.xml
new file mode 100644
index 0000000..93bfae4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-transformers/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/transformers.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/content_en.html
new file mode 100644
index 0000000..b6de535
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/content_en.html
@@ -0,0 +1,751 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Write a Custom Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Geoff Howard" name="DC.Creator">
+</head>
+<body>
+      
+<h1>Introduction</h1>
+         
+<p>This Tutorial describes the steps necessary to write a basic Cocoon
+          generator. Starting with a quick "Hello World" example and
+          progressing to slightly more involved examples should give a good
+          start to those whose applications call for extending Cocoon with a
+          custom generator.</p>
+
+         
+<p>The intention is to provide:</p>
+
+         
+<ul>
+            
+<li>the basics of creating SAX events in a C2 generator</li>
+
+            
+<li>a little understanding of the Avalon container contract as it
+             relates to C2 generators</li>
+
+            
+<li>a little understanding of the factors that would influence
+             the decision about which xxxGenerator to extend</li>
+         
+</ul>
+
+         
+<h2>Purpose</h2>
+<p>The flexibility to extend the basic "Out of the box"
+            functionality of Cocoon will be an important feature for Cocoon's
+            viability as a broadly used application framework. Though the
+            documentation on 
+            <a href="../developing/extending.html">"Extending Cocoon"</a>
+            (at least at this writing) seems to have a hard time imagining
+            applications for custom generators outside of the bizarre, I
+            imagine several scenarios which could call for it:</p>
+<ul>
+              
+<li>A datasource as yet undeveloped in Cocoon (e.g. event
+               logs)</li>
+
+              
+<li>Database driven applications for which XSP is either too
+               awkward or holds too many performance questions. The need for
+               high scalability will drive some (such as myself) to seek
+               optimization in custom generators that just do not seem
+               reasonable to expect out of the auto-generated code that XSPs
+               produce. The current 
+               <a href="../performancetips.html">Performance Tips</a>
+               documentation seems to lead in this direction.</li>
+
+               
+<li>Customized control over the caching behaviour if not
+                provided for by other means.</li>
+            
+</ul>
+
+         
+<h2>Important</h2>
+<p>There are other options that should be considered before
+            settling on a new generator. One notable consideration is the
+            option of writing a Source that would fit your needs. See 
+            <a class="external" href="http://marc.theaimsgroup.com/?t=102571404500001&r=1&w=2">this discussion</a>
+
+            from the mailing list for an introduction to the idea. Of course,
+            XSP should be considered - I have not seen any performance
+            comparisons that quantify the benefit that can be had from a
+            custom generator. Finally, be sure you understand the purpose and
+            capabilities of all current standard Generators, as well as those
+            in the scratchpad (for instance, there is a
+            <span class="codefrag">TextParserGenerator</span> in the scratchpad at the moment
+            which may be configurable enough to process the event log need
+            mentioned above). Cocoon is a rapidly developing technology that
+            may have anticipated your need. Because the documentation lags
+            behind development, you may find more by examining the source
+            directory and searching the 
+            <a class="external" href="http://cocoon.apache.org/community/mail-archives.html">mail archives</a>
+            for applicable projects.</p>
+
+         
+<h2>Intended Audience</h2>
+<p>This Tutorial is aimed at users who have developed an
+            understanding of the basics of Cocoon and have a need to begin
+            extending it for their own purposes, or desire a deeper
+            understanding of what goes on under the hood.</p>
+
+         
+<h2>Prerequisites</h2>
+<p>Generator developers should have:</p>
+<ul>
+              
+<li>Read 
+              <a href="../userdocs/concepts/index.html">Cocoon Concepts</a>
+               , as well as 
+               <a href="../developing/extending.html">Extending Cocoon</a>
+
+               , and the broad overview of 
+               <a href="../developing/avalon.html">Avalon</a>
+
+               , the framework upon which Cocoon is built.</li>
+
+               
+<li>An installed version of Cocoon if you want to follow the
+                examples yourself (obviously).</li>
+
+               
+<li>A good understanding of Java.</li>
+               
+<li>Java SDK (1.2 or later) "installed".</li>
+            
+</ul>
+      
+
+      
+<h1>Diving In</h1>
+         
+<p>Let us start with a simple "Hello World" example:</p>
+
+         
+<h2>Simple Example</h2>
+<p>Our goal will be to build the following document (or, more to
+            the point, the SAX events that would correspond to this document).
+           </p>
+<pre class="code">
+&lt;example&gt;Hello World!&lt;/example&gt;
+</pre>
+<p>An example of code that will send the correct SAX events down
+            the pipeline:</p>
+<pre class="code">
+
+import org.apache.cocoon.generation.AbstractGenerator;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.SAXException;
+
+public class HelloWorldGenerator extends AbstractGenerator 
+{
+
+    AttributesImpl emptyAttr = new AttributesImpl();
+
+    /**
+     * Override the generate() method from AbstractGenerator.
+     * It simply generates SAX events using SAX methods.  
+     * I haven't done the comparison myself, but this 
+     * has to be faster than parsing them from a string.
+     */
+
+    public void generate() throws SAXException
+    
+    {
+       
+      // the org.xml.sax.ContentHandler is inherited 
+      // through org.apache.cocoon.xml.AbstractXMLProducer 
+
+      contentHandler.startDocument();
+      
+      contentHandler.startElement("", "example", "example", emptyAttr);
+      
+      contentHandler.characters("Hello World!".toCharArray(),0,
+                                  "Hello World!".length());
+
+      contentHandler.endElement("","example", "example");
+
+      contentHandler.endDocument();
+
+    }
+}
+</pre>
+<p>So, the basic points are that we extend
+           <span class="codefrag">AbstractGenerator</span>, override its generate() method,
+           call the relevant SAX methods on the contentHandler (inherited
+           from <span class="codefrag">AbstractGenerator</span>) to start, fill and end the
+           document. For information on the SAX api, see 
+            <a class="external" href="http://www.saxproject.org/">www.saxproject.org</a>
+            
+</p>
+<div class="note">A performance tip might be to keep an empty instance of
+             <span class="codefrag">AttributesImpl</span> around to reuse for each element
+             with no attributes. Also, the characters(char[] chars, int start,
+             int end) begs to be overloaded with a version like 
+            <span class="codefrag">characters(String justPutTheWholeThingIn)</span>
+
+            that handles the conversion to a character array and assumes you
+            want from beginning to end, as is done in
+            <span class="codefrag">org.apache.cocoon.generation.AbstractServerPage</span>.
+            If you are not using namespaces, it is easy to imagine overloaded
+            convenience implementations of the other SAX methods as well.
+            You will probably want to set up a convenient BaseGenerator with
+            helpers like this and extend it for your real Generators.</div>
+<h3>What to Extend?</h3>
+<p>How did we choose to extend <span class="codefrag">AbstractGenerator</span>?
+               Generators are defined by the
+               <span class="codefrag">org.apache.cocoon.generation.Generator</span> interface.
+               The only direct implementation of this of interest to us is
+               <span class="codefrag">AbstractGenerator</span>, which gives a basic level of
+               functionality. Another option would have been
+               <span class="codefrag">ServiceableGenerator</span>, which would give us the added
+               functionality of implenting the Avalon interface 
+               <span class="codefrag">Serviceable</span>
+               , which would signal the container that handles all the
+               components including our generator to give us a handle back to
+               the <span class="codefrag">ServiceManager</span>
+               during the startup of the container. If we needed to lookup a
+               pooled database connection, or some other standard or custom
+               Cocoon component, this is what we would do. Most of the out
+               of the box Generators extend <span class="codefrag">ServiceableGenerator</span>.
+               Other abstract Generators you may choose to extend include the
+               poorly named (IMHO) <span class="codefrag">ServletGenerator</span>
+
+               , and <span class="codefrag">AbstractServerPage</span>
+               . While these both introduce functionality specific to their
+               eventual purpose - the JSP and XSP generators, they do make a
+               convenient starting place for many other Generators.</p>
+<h3>Running The Sample</h3>
+<p>In order to run this sample, you will need to compile the code,
+               deploy it into the cocoon webapp, and modify the sitemap to
+               declare our generator and allow access to it via a pipeline.</p>
+<h4>Compile</h4>
+<p>Save this source as <span class="codefrag">HelloWorldGenerator.java</span>
+                 and compile it using</p>
+<pre class="code">javac -classpath %PATH_TO_JARS%\cocoon.jar;%PATH_TO_JARS%\xml-apis.jar
+   HelloWorldGenerator.java</pre>
+<p>Unfortunately for me, the exact name of your cocoon and
+                   xml-apis jars may vary with exactly which distribution,
+                   or CVS version you are using, since the community has taken
+                   to appending dates or versions at the end of the jar name
+                   to avoid confusion. Be sure to find the correct name on
+                   your system and substitute it in the classpath. Also, you
+                   have several options on where to find jars. If you have a
+                   source version that you built yourself, you may want to
+                   point to <span class="codefrag">lib\core\</span> for them. If you have only
+                   the binary version, you can find them in
+                   <span class="codefrag">WEB-INF\lib\</span>
+</p>
+<h4>Deploy</h4>
+<p>Simply copy the class file into the
+                  <span class="codefrag">%TOMCAT_HOME%\webapps\cocoon\WEB-INF\classes</span>
+                  directory</p>
+<div class="note">If memory serves me, there have been occasional
+                   classloading problems in the past that may affect
+                   classloading. If your compiled classes are not recognized
+                   in the classes directory, try 
+                  <span class="codefrag">jar</span>-ing them up and place them in
+                  <span class="codefrag">WEB-INF\lib\</span> instead. That is probably where
+                  your real generators would go anyway - with a whole package
+                  of all your custom classes in one jar.</div>
+<h4>Sitemap Modifications</h4>
+<p>You need to do two things: in the 
+                  <span class="codefrag">map:generators</span>
+
+                  section, add an element for your class:</p>
+<pre class="code">&lt;map:generator name="helloWorld" src="HelloWorldGenerator"/&gt;</pre>
+<p>Then add a pipeline to sitemap.xmap which uses it:</p>
+<pre class="code">
+...
+   &lt;map:match pattern="heyThere.xml"&gt;
+      &lt;map:generate type="helloWorld"/&gt;
+      &lt;map:serialize type="xml"/&gt;
+   &lt;/map:match&gt;
+...
+</pre>
+<p>And finally, our creation should be available at 
+                  <span class="codefrag">http://localhost:8080/cocoon/heyThere.xml</span>
+                  
+</p>
+<p>Depending on your exact setup, you may need to restart
+                   Tomcat (or whatever your servlet container is) to get
+                   there.</p>
+<div class="note">Notice that the 
+                  <span class="codefrag">
+                     &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+                  </span>
+
+                  declaration was added for us by the xml serializer at the
+                  beginning. If you need to modify this, the generator is not
+                  the appropriate place. The default encoding of UTF-8 could
+                  be overridden with iso-8859-1 for example by specifying an 
+                  <span class="codefrag">
+                     &lt;encoding&gt;iso-8859-1&lt;/encoding&gt;
+                  </span>
+
+                  child parameter inside the declaration for the xml
+                  serializer in your sitemap.</div>
+
+         
+<h2>A Less Trivial Example</h2>
+<p>Moving on to a less trivial example, we will take some
+             information out of the Request, and construct a slightly more
+             involved document. This time, our goal will be the following
+             document:</p>
+<pre class="code">
+&lt;doc&gt;
+&lt;uri&gt;...&lt;/uri&gt;
+&lt;params&gt;
+    &lt;param value="..."&gt;...&lt;/param&gt;
+    ...
+&lt;/params&gt;
+&lt;date&gt;..&lt;/date&gt;
+&lt;/doc&gt;
+</pre>
+<p>The values of course will be filled in from the request, and
+             will depend on choices we make later.</p>
+<pre class="code">import org.apache.cocoon.generation.AbstractGenerator;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.SAXException;
+
+// for the setup() method
+import org.apache.cocoon.environment.SourceResolver;
+import java.util.Map;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import java.io.IOException;
+
+// used to deal with the request parameters.
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import java.util.Enumeration;
+
+import java.util.Date;
+
+
+public class RequestExampleGenerator extends AbstractGenerator 
+{
+
+    // Will be initialized in the setup() method and used in generate()
+    Request request = null;
+    Enumeration paramNames = null;
+    String uri = null;
+
+    // We will use attributes this time.
+    AttributesImpl myAttr = new AttributesImpl();
+    AttributesImpl emptyAttr = new AttributesImpl();
+    
+   
+    public void setup(SourceResolver resolver, Map objectModel, 
+             String src, Parameters par)  
+         throws ProcessingException, SAXException, IOException 
+    {
+       super.setup(resolver, objectModel, src, par);
+       request = ObjectModelHelper.getRequest(objectModel);
+       paramNames = request.getParameterNames();
+       uri = request.getRequestURI();
+    } 
+
+    /**
+     * Implement the generate() method from AbstractGenerator.
+     */
+
+    public void generate() throws SAXException
+    {
+
+      contentHandler.startDocument();
+      
+      contentHandler.startElement("", "doc", "doc", emptyAttr);
+
+      // &lt;uri&gt; and all following elements will be nested inside the doc element
+      contentHandler.startElement("", "uri", "uri", emptyAttr);
+
+      contentHandler.characters(uri.toCharArray(),0,uri.length());
+
+      contentHandler.endElement("", "uri", "uri");
+      
+      contentHandler.startElement("", "params", "params", emptyAttr);
+         
+      while (paramNames.hasMoreElements())
+      {
+          // Get the name of this request parameter.
+          String param = (String)paramNames.nextElement();
+          String paramValue = request.getParameter(param);
+      
+          // Since we've chosen to reuse one AttributesImpl instance, 
+          // we need to call its clear() method before each use.  We 
+          // use the request.getParameter() method to look up the value 
+          // associated with the current request parameter.
+          myAttr.clear();
+          myAttr.addAttribute("","value","value","",paramValue);
+
+          // Each &lt;param&gt; will be nested inside the containing &lt;params&gt; element.
+          contentHandler.startElement("", "param", "param", myAttr);
+          contentHandler.characters(param.toCharArray(),0,param.length());
+          contentHandler.endElement("","param", "param");
+      }
+            
+      contentHandler.endElement("","params", "params");
+
+      contentHandler.startElement("", "date", "date", emptyAttr);
+
+      String dateString = (new Date()).toString();
+      contentHandler.characters(dateString.toCharArray(),0,dateString.length());
+
+      contentHandler.endElement("", "date", "date");
+      contentHandler.endElement("","doc", "doc");
+      contentHandler.endDocument();
+   }
+
+   public void recycle() {
+      super.recycle();
+      this.request = null;
+      this.paramNames = null;
+      this.parNames = null;
+      this.uri = null;
+   }
+}</pre>
+<h3>Compile and Test</h3>
+<p>Save this code as
+                         <span class="codefrag">RequestExampleGenerator.java</span>
+                         and compile as before.  You will need to add both
+                         <span class="codefrag">avalon-framework.jar</span> and
+                         <span class="codefrag">avalon-excalibur.jar</span> to your classpath
+                        this time.  Besides finding the exact name of the jar
+                        as described above, you may now also have to ensure
+                        that you have the version of excalibur targeted to your
+			jvm version - there is currently a version for JDK 1.4
+                        and one for 1.2/1.3</p>
+<p>For your sitemap, you will need to add a definition
+                        for this generator like 
+<span class="codefrag">&lt;map:generator name="requestExample" src="RequestExampleGenerator"/&gt;</span>
+                        and you will need a sitemap pipeline like:</p>
+<pre class="code">&lt;map:match pattern="howYouDoin.xml"&gt;
+    &lt;map:generate type="requestExample"/&gt;
+    &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+</pre>
+<p>At this point, you should be able to access the
+                         example at
+<span class="codefrag">http://localhost:8080/cocoon/howYouDoin.xml?anyParam=OK&amp;more=better</span>
+</p>
+<h3>New Concepts</h3>
+<h4>Lifecycle</h4>
+<p>First, notice that we now override the
+                <span class="codefrag">setup(...)</span> and <span class="codefrag">recycle()</span> methods
+                defined in <span class="codefrag">AbstractGenerator</span>.
+                The <span class="codefrag">ServiceManager</span> that handles the lifecycle of
+                all <span class="codefrag">service</span>s in Cocoon, calls
+                <span class="codefrag">setup(..)</span> before each new call to
+                <span class="codefrag">generate()</span> to give the Generator information
+                about the current request and its environment, and calls
+                recycle() when it is done to enable it to clean up resources
+                as appropriate. Our example uses only the
+                <span class="codefrag">objectModel</span> which abstracts the Request,
+                Response, and Context. We get a reference to the Request
+                wrapper, and obtain an <span class="codefrag">Enumeration</span> of all the
+                GET/POST parameters available.</p>
+<p>The <span class="codefrag">src</span> and <span class="codefrag">SourceResolver</span> are
+                provided to enable us to look up and use whatever source is
+                specified in the pipeline setup. Had we specified 
+<span class="codefrag">&lt;map:generate type="helloWorld" src="someSourceString"/&gt;</span>
+                we would have used the <span class="codefrag">SourceResolver</span> to work
+                with "someSourceString", whether it be a file, or url, etc.</p>
+<p>We are also given a 
+               <span class="codefrag">Parameters</span> reference which we would use to obtain
+                any parameter names and values which are children elements of
+                our <span class="codefrag">map:generate</span> element in the pipeline.</p>
+<div class="note">It may be good practice to abstract the source of your parameters so
+that they do not have to come from the Request object. For instance, the
+following code would allow us to abstract the origin of two parameters, param1
+and param2:</div>
+<pre class="code">In RequestExampleGenerator.java, 
+...
+String param1 = null;
+String param2 = null;
+...
+   public void setup(SourceResolver resolver, Map objectModel, 
+   			String src, Parameters par)  
+   		throws ProcessingException, SAXException, IOException 
+   {
+        ... 
+        param1 = par.getParameter("param1");
+        param2 = par.getParameter("param2");
+   } 
+
+and in sitemap.xmap, 
+
+...
+&lt;map:match pattern="abstractedParameters.xml"/&gt;
+	&lt;map:act type="request"&gt;
+	  &lt;map:parameter name="parameters" value="true"/&gt;
+	  &lt;map:generate type="requestExample"&gt;
+		&lt;parameter name="param1" value="{visibleName1}"/&gt;
+		&lt;parameter name="param2" value="{visibleName2}"/&gt;
+	  &lt;/map:generate&gt;
+	&lt;/map:act&gt;
+&lt;/map:match&gt;
+...</pre>
+<p>As you can see, we have also hidden the internal
+                    name from the outside world who will use
+                    <span class="codefrag">?visibleName1=foo&amp;visibleName2=bar</span>
+                    
+</p>
+<h4>Nested Elements</h4>
+<p>In this example, nested elements are created simply
+            by nesting complete
+            <span class="codefrag">startElement()</span>/<span class="codefrag">endElement</span> 
+            pairs within each other. If we had a logic failure in our code and 
+            sent non-wellformed xml events down the pipeline, nothing in our 
+            process would complain (try it!). Of course, any transformers later 
+            in the pipeline would behave in an unpredictable manner.</p>
+<h4>Attributes</h4>
+<p>Finally, we've introduced the use of attributes.
+            We chose to 
+            employ one <span class="codefrag">attributesImpl</span>, clearing it before each 
+            element.  Multiple attributes for an element would simply be added 
+            by repeated calls to <span class="codefrag">addAttribute</span>.</p>
+<h3>A Lesson</h3>
+<p>Before moving on, it is worth noting that
+             after all this work, there is already a generator provided with 
+             Cocoon which does much of what we have accomplished here
+             - <span class="codefrag">org.apache.cocoon.generation.RequestGenerator</span>
+             which in the default configuration is probably available at
+             <span class="codefrag">http://localhost:8080/cocoon/request</span>
+</p>
+
+         
+<h2>Moving On</h2>
+<p>From here, we will move on to cover handling ugly pseudo-xml
+          (like real world html) with CDATA blocks, employing some of the
+          Avalon lifecycle method callbacks (Serviceable/Disposable), Database
+          access, and Caching.</p>
+<h3>The Employee SQL Example Reworked</h3>
+<p>In the samples included with Cocoon, there is an example of a SQL
+           query using XSP and ESQL.  We will recreate part of that example
+           below using the same HSQL database, which should be automatically
+           configured and populated with data in the default build. If you
+           find that you do not have that database set up, see the ESQL XSP
+           sample for instructions on setting the datasource up.  Do note that
+           this specific task is handled in the ESQL XSP example in just a few
+           lines of code.  If your task is really this simple, there may be no
+           need to create your own generator.</p>
+<pre class="code">import org.apache.cocoon.generation.ServiceableGenerator;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.excalibur.datasource.DataSourceComponent;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.caching.Cacheable;
+import org.apache.cocoon.caching.CacheValidity;
+import org.apache.cocoon.ProcessingException;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+ 
+import java.sql.*;
+import java.util.Map;
+import java.util.Date;
+import org.apache.avalon.framework.activity.Disposable;
+
+public class EmployeeGeneratorExample extends ServiceableGenerator
+   implements Cacheable, Disposable
+{
+
+	public void dispose() {
+	    super.dispose();
+	    manager.release(datasource);
+	    datasource = null;
+	}
+
+	public void recycle() {
+	    myAttr.clear();
+	    super.recycle();
+	}
+
+	public void setup(SourceResolver resolver, Map objectModel,
+                          String src, Parameters par) {
+	    // Not neeed for this example, but you would get request
+            // and/or sitemap parameters here.
+	}
+
+	
+	public void service(ServiceManager manager) 
+	throws ServiceException{
+	  super.service(manager);
+	  ServiceSelector selector = (ServiceSelector)
+            manager.lookup(DataSourceComponent.ROLE + "Selector");
+	  this.datasource = (DataSourceComponent) selector.select("personnel");
+	}
+
+	public void generate() 
+	throws SAXException, ProcessingException {
+		try {
+
+			Connection conn = this.datasource.getConnection();
+			Statement stmt = conn.createStatement(); 
+			
+			ResultSet res = stmt.executeQuery(EMPLOYEE_QUERY);
+			
+                        //open the SAX event stream
+			contentHandler.startDocument();
+			myAttr.addAttribute("","date","date","",
+                            (new Date()).toString());
+                        //open root element
+			contentHandler.startElement("","content",
+                            "content",myAttr);
+
+			
+			String currentDept = "";
+			boolean isFirstRow = true;
+			boolean moreRowsExist = res.next() ? true : false;
+			
+			while (moreRowsExist) {
+			    String thisDept = attrFromDB(res, "name");
+			    if (!thisDept.equals(currentDept)) {
+				newDept(res,thisDept,isFirstRow);
+				currentDept = thisDept;
+			    }
+			    addEmployee(res,attrFromDB(res,"id"),
+                              attrFromDB(res,"empName"));
+			    isFirstRow = false;
+			    
+			    if (!res.next()) {
+				endDept();
+				moreRowsExist = false;
+			    }
+			}
+			
+                        //close root element
+			contentHandler.endElement("","content","content");
+                        //close the SAX event stream
+			contentHandler.endDocument();
+			
+			res.close();
+			stmt.close();
+			conn.close();
+	  	} catch (SQLException e) { 
+  			throw new ProcessingException(e); 
+  		} 
+	}
+
+	public long generateKey()
+	{
+		// Default non-caching behaviour. We will implement this later.
+		return 0;
+	}
+
+	public CacheValidity generateValidity()
+	{
+		// Default non-caching behaviour. We will implement this later.
+		return null;
+	}
+
+
+  private DataSourceComponent datasource;
+  private AttributesImpl myAttr = new AttributesImpl();
+  
+  private String EMPLOYEE_QUERY = 
+  "SELECT department.name, employee.id, employee.name as empName " +
+  "FROM department, employee " + 
+  "WHERE department.id = employee.department_id  ORDER BY department.name";
+  
+  private void endDept() throws SAXException {
+      contentHandler.endElement("","dept","dept");
+  }
+  
+  private void newDept(ResultSet res, String dept, boolean isFirstRow)
+      throws SAXException {
+    if (!isFirstRow) {
+	endDept();
+    }
+    myAttr.clear();
+    myAttr.addAttribute("","name","name","",dept);
+    contentHandler.startElement("","dept","dept",myAttr);
+  }    
+  
+  private void addEmployee(ResultSet res, String id, String name)
+      throws SAXException {
+      myAttr.clear();
+      myAttr.addAttribute("","id","id","",id);
+      contentHandler.startElement("","employee","employee",myAttr);
+      contentHandler.characters(name.toCharArray(),0,name.length());
+      contentHandler.endElement("","employee","employee");
+  }
+  
+  private String attrFromDB(ResultSet res, String column)
+      throws SQLException {
+  		String value = res.getString(column);
+		return (res.wasNull())?"":value;
+  }
+
+}</pre>
+<h3>Compile and Test</h3>
+<p>To compile this, you will now need the following on your classpath:
+         <span class="codefrag">avalon-excalibur.jar, avalon-framework.jar, cocoon.jar,
+         xml-apis.jar</span> (using whatever names they have in your
+         distribution).  When you compile this, you may receive some
+         deprecation warnings.  Do not worry about them - we will discuss 
+         that later.</p>
+<p>To test it, copy it over to your <span class="codefrag">WEB-INF\classes\</span>
+         directory as before and add something like the following to your
+         <span class="codefrag">sitemap.xmap</span> ...</p>
+<pre class="code">...
+&lt;map:generator name="employee" src="EmployeeGeneratorExample"/&gt;
+...
+&lt;map:match pattern="employee.xml"&gt;
+    &lt;map:generate type="employee"/&gt;
+    &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+...</pre>
+<h3>New Concepts</h3>
+<h4>Serviceable and Disposable</h4>
+<p>We've implemented the Avalon lifecycle interfaces Serviceable and 
+    Disposable.  When Cocoon starts up (which happens when the servlet 
+    container starts up) the <span class="codefrag">ServiceManager</span> will call 
+    <span class="codefrag">service(ServiceManager m)</span> for our component as it works 
+    its way through all the components declared in the sitemap.  The handle 
+    to <span class="codefrag">ServiceManager</span> is used to look up any other Avalon 
+    components that we need.  Lookups happen in an abstracted way using a 
+    ROLE which enables us to change out implementations of each component 
+    without affecting previously written code.  Our generator's ROLE by the 
+    way was defined in the <span class="codefrag">Generator</span> interface.  </p>
+<p>Similarly, when this instance of our generator is disposed of by the 
+    container, it will call the <span class="codefrag">dispose()</span> method to allow us to 
+    clean up any resources we held on to between invocations.  Note that 
+    components can be pooled by the container.  If we thought that our employee 
+    generator was going to see a lot of traffic, we might change its definition 
+    at the top of sitemap.xmap to include attributes like <span class="codefrag">pool-max="16"</span> so that multiple overlapping requests 
+    could be serviced without a log jam.</p>
+<h4>Datasource</h4>
+<p>We look up our HSQL database here by its name given in cocoon.xconf. 
+    If we had multiple datasources (say a backup development database and 
+    a live one), we could determine which one to use based on a simple 
+    configuration parameter in sitemap.xmap.  We could get at configuration 
+    parameters using the Avalon interface <span class="codefrag">Configurable</span>.</p>
+<div class="note">Notice that we wait until generate() to request our connection 
+    from the pool - as we should.  The problem is that we lose the benefit 
+    of using prepared statements since they would be destroyed when we 
+    returned the instance to the pool.  At present, the implementation of 
+    org.apache.avalon.excalibur.datasource.DataSourceComponent does not 
+    support the pooling of statements.</div>
+<h4>Caching</h4>
+<div class="fixme">open:
+      Need more content here, or links to other docs.</div>
+<div class="note">FIXME: This is still coming.</div>
+<p>Introduce new code to implement Caching, discuss basic logic, and
+    deprecation/move to Avalon. I could use some help here from Carsten,
+    or someone who can quickly give an overview of the changes and plan.
+    </p>
+      
+   
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/meta.xml
new file mode 100644
index 0000000..ed82bc4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-custom-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>tutorial/tutorial-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/content_en.html
new file mode 100644
index 0000000..4ee91c4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/content_en.html
@@ -0,0 +1,1301 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Writing a Cocoon 2 generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Erwin Hermans" name="DC.Creator">
+</head>
+<body>
+		
+<h1>Preface</h1>
+			
+<p>This document is written in context of the thesis of Carolien Coenen and Erwin Hermans at the department of Computer Science at the Katholieke Universiteit Leuven (<a class="external" href="http://www.cs.kuleuven.ac.be/cwis-cs/frames/index-E.shtml">Department of Computer Science</a>).
+			</p>
+			
+			
+<p>At some point in our thesis the need for extending the functionality of Cocoon 2 became imminent. At that moment, we worked with an application that generated XML documents from Java source files (a sort of JavaDoc tool). We wrote some XSL stylesheets for transforming these documents into HTML, so they could easily be served by Cocoon 2. But <strong>every time</strong> the documentation comments changed in the Java source files, these XML documents <strong>required (re)generation</strong>. The ultimate goal of this project was to be able to do all the intermediate steps of the document generation in memory. This way the HTML documents would change whenever the Java source files were modified, <strong>without the need to regenerate the XML documents</strong>.
+		</p>
+		
+		
+<p>To reach this goal, we made some modifications in our program. Our output documents were built in memory using the JDOM API (<a class="external" href="http://www.jdom.org">JDOM.org</a>). At the time of writing this API supported 3 output methods, which are <strong>DOM</strong> (<a class="external" href="http://www.w3.org/TR/REC-DOM-Level-1/">Document Object Model (DOM) Level 1 Specification, Version 1.0, W3C Recommendation 1 October 1998</a>), <strong>SAX</strong> (<a class="external" href="http://www.saxproject.org/">The official SAX website</a>) and <strong>XML</strong> (<a class="external" href="http://www.w3.org/TR/REC-xml">Extensible Markup Language (XML) 1.0 (Second Edition), W3C Recommendation 6 October 2000</a>). The DOM output method outputs a DOM tree from an existing JDOM tree. The XML output method outputs an XML file to an OutputStream or a Writer. But the most interesting of these three outputmethods is SAX. The generators that come with Cocoon 2 don't supply a method (or at least we haven't found any) to take the SAX output of an arbitrary Java program and feed it into the transformers (in our case). That's why we wanted to write a generator that would be able to supply SAX events that were outputted by our (or an arbitrary) Java program and to feed this SAX events into the transformer pipeline. This generator would be responsible for starting the Java program and delegating the received SAX events to the Cocoon 2 transformation pipeline in some way.
+		</p>
+		
+		
+<p>
+To accomplish this task we decided to write our own generator and this documentation in parallel, as there was no documentation available, except for the following phrase on Apache's Cocoon 2 website (<a href="../index.html">Cocoon2 van The Apache XML project</a>): "A Generator generates XML content as SAX events and initializes the pipeline processing."	
+Apache's Cocoon 2 website also enumerates the available Generators, which package contains them, which interfaces and helper classes there are in that package and which of those should be implemented/extended. But at that point, the documentation stopped. So the only way to actually be able to write a generator ourselves, was by studying the Cocoon 2 code (more specific the Generators) and figure out for ourselves how to write a generator. Because we want to make a contribution to the Cocoon 2 community, we have written this document. We think our experiences may come in handy for developers who are also thinking about extending Cocoon 2 with their own generators, .
+		</p>
+		
+		
+<p>The writing of this generator and all the testing of our code were performed with the following configuration:</p>
+			
+<ul>
+				
+<li>Compaq/Digital Personal Workstation 500a (Alpha 500MHz processor)</li>
+				
+<li>Redhat Linux 7.1</li>
+				
+<li>Compaq JDK 1.3.1-1 (Classic VM (build 1.3.1-1, native threads, jit))</li>
+				
+<li>Jakarta Tomcat 3.2.3</li>
+				
+<li>Cocoon 2.0.2-dev</li>
+			
+</ul>		
+		
+	
+	
+<h1>Planning</h1>
+		
+<p>Here you'll find a list of consequent steps that we expect will be necessary to write our own Generator. It is of course possible that in this first draft of our planning we have forgotten a few steps or that some steps actually form one step.</p>
+		
+<ul>
+			
+<li>Find out which classes should be extended and which interfaces implemented.</li>
+			
+<li>Examine these superclasses and interfaces and find which methods should be actually implemented and what is excepted from these methods.</li>
+			
+<li>Write a first Generator as a <strong>proof of concept</strong> to see if our conlusions in relation to the methods are correct, and let this Generator generate some SAX events (hard coded in the Generator) to 'feed' to Cocoon2.</li>
+			
+<li>Find out how to feed the SAXOutput of a JDOM document (hardcoded in the Generator) to Cocoon2.</li>
+			
+<li>Modify our program so it can generate SAXOutput when this is requested.</li>
+			
+<li>Feed the SAXOutput from our program to the Generator (we think it shall require running our program from the Generator). This SAXOutput shall then be passed to Cocoon 2. Again, every call to our program and the parameters will be hardcoded in our Generator.</li>
+			
+<li>Find out how we can use the sitemap to pass parameter values to our Generator (= examing how the sitemap is transformed into Java code and how we can read the parameter values from this code). This will no longer be hardcoded then.</li>
+			
+<li>Examine how we can define in the most general way the syntax from the sitemap, so that it is possible to define which class should be called to generate SAXOutput and with which values and methods this class should be called. This also implies that we must study if this is possible in Java.</li>
+			
+<li>This will be tested with our program and our Generator (hopefully we'll get this far) will become heavily parameterized.</li>
+			
+<li>Modify our program once again, so that it satisfies our final needs.</li>
+			
+<li>Submit our generator, and this document to the Cocoon 2 project.</li>
+		
+</ul>
+		
+	
+	
+	
+<h1>Our planning, step by step</h1>
+		
+<h2>Classes and interfaces to be extended/implemented</h2>
+<p>In this section, we'll discuss which classes should/can be extended to implement our own Generator. Also, we'll take a closer look at these classes to see which functionality they provide and (try to) discuss their functionality. Let it be clear that it is <strong>not required</strong> to extend one of the existing (abstract) generator classes. But by doing so, it'll make your work a great deal easier.
+			</p>
+<p>The second part of this section will discuss the interface(s) that have to be implemented to write our own generator. We'll look at what the methods that are defined in the interface should do. There is one interface that has to be implemented if you write your own generator: the <strong>org.apache.cocoon.generation.Generator</strong> interface. 
+			</p>
+<h3>Classes</h3>
+<p>According to the Cocoon 2 website at the time of writing (21st november 2001) there are four helper classes in the org.apache.cocoon.generation package that can be extended. These four are (they will be discussed later):</p>
+<ul>
+						
+<li>AbstractGenerator</li>
+						
+<li>AbstractServerPage</li>
+						
+<li>ServiceableGenerator</li>
+						
+<li>ServletGenerator</li>
+					
+</ul>
+<p>					
+Java only supports single inheritance, so you'll have to choose one of these for your Generator. We want to use the AbstractGenerator (in our first attempt), but to help the reader of this document in making a well motivated choice, we'll discuss each of these options briefly as to what specific functionality they provide.
+				</p>
+<p>There is a hierarchy between these classes, namely:</p>
+<ul>
+						
+<li>AbstractGenerator</li>
+						
+<li>ServiceableGenerator extends AbstractGenerator</li>
+						
+<li>ServletGenerator extends ServiceableGenerator</li>
+						
+<li>AbstractServerPage extends ServletGenerator</li>
+					
+</ul>
+<p>So the choice of which class to extend will depends mostly on which is the level of abstraction required by your generator.
+				</p>
+<h4>AbstractGenerator</h4>
+<p>
+<strong>Extend this one for easier building of your own Generator</strong>
+<br>
+					
+</p>
+<p>This <strong>abstract class</strong> extends the class <strong>org.apache.cocoon.xml.AbstractXMLProducer</strong> and implements the interface <strong>org.apache.cocoon.generation.Generator</strong>.
+					</p>
+<p>The <strong>Generator</strong> interface extends the interfaces <strong>org.apache.cocoon.xml.XMLProducer</strong> and <strong>org.apache.cocoon.sitemap.SitemapModelComponent</strong>.
+					</p>
+<p>The interface <strong>XMLProducer</strong> is a top-level interface.
+					</p>
+<p>The interface <strong>SitemapModelComponent</strong> extends the interface <strong>org.apache.avalon.framework.component.Component</strong>, which in turn is a top-level interface.
+					</p>
+<p>The abstract class <strong>AbstractXMLProducer</strong> extends the abstract class <strong>org.apache.avalon.framework.logger.AbstractLoggable</strong> and implements the interfaces <strong>org.apache.cocoon.xml.XMLProducer</strong> and <strong>org.apache.avalon.excalibur.pool.Recyclable</strong>.
+					</p>
+<p>
+<strong>AbstractLoggable</strong> is a top-level abstract class to provide logging capabilities. This is deprecated and <strong>AbstractLogEnabled</strong> should be used instead. AbstractLoggable implements the interface <strong>org.apache.avalon.framework.logger.Loggable</strong>, but as mentioned in the API docs <strong>org.apache.avalon.framework.logger.LogEnabled</strong> should be used instead.
+					</p>
+<p>The interface <strong>Recyclable</strong> extends the interface <strong>org.apache.avalon.excalibur.pool.Poolable</strong>, which is a top-level interface.
+					</p>
+<p>The following methods are defined for <strong>AbstractGenerator</strong>, some of which already have an implementation:</p>
+<ul>
+	
+<li>From <strong>org.apache.avalon.excalibur.pool.Poolable</strong>:
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+		This interface is implemented bij components if it is reasonable to Pool the object. It marks the component Poolable.
+	</li>
+	
+	
+<li>From <strong>org.apache.avalon.excalibur.pool.Recyclable</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">public void recycle()</span>: this method should be implemented to remove all costly resources in the object. These resources can be object references, database connections, threads, etc. What is categorised as "costly" resources is determined on a case by case analysis.
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.logger.Loggable</strong> (Deprecated):
+		<ul>
+			
+<li>
+<span class="codefrag">public void setLogger	(org.apache.log.Logger logger)</span>: provide component with a logger.
+			</li>
+		
+</ul>
+		Interface can be implemented by Components that need to log.
+	</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.logger.AbstractLoggable</strong> (Deprecated):
+		<ul>
+			
+<li>
+<span class="codefrag">protected org.apache.log.Logger getLogger()</span>: Helper method to allow sub-classes to acquire logger (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected void setupLogger(java.lang.Object component)</span>: Helper method to setup other components with the same logger (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected void setupLogger(java.lang.Object component, org.apache.log.Logger logger)</span>: Helper method to setup other components with logger (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected void setupLogger(java.lang.Object component, java.lang.String subCategory)</span>: Helper method to setup other components with logger (implemented).
+			</li>
+		
+</ul>
+		This is a utility class to allow the construction of easy components that will perform logging.
+	</li>
+	
+	
+<li>From <strong>org.apache.cocoon.xml.XMLProducer</strong>
+		
+<ul>
+			
+<li>
+<span class="codefrag">void setConsumer(XMLConsumer xmlconsumer)</span>: set the XMLConsumer that will receive XML data. The XMLConsumer interface extends <strong>org.xml.sax.ContentHandler</strong> and <strong>org.xml.sax.ext.LexicalHandler</strong>.
+			</li>
+		
+</ul>
+		This interface identifies classes that produce XML data, sending SAX events to the configured XMLConsumer.
+	</li>
+	
+	
+<li>From <strong>org.apache.cocoon.xml.AbstractXMLProducer</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">void setConsumer(XMLConsumer xmlconsumer)</span>: set the XMLConsumer that will receive XML data (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">public void setContentHandler(ContentHandler consumer)</span>: Set the ContentHandler that will receive XML data (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">public void setLexicalHandler(LexicalHandler handler)</span>: Set the LexicalHandler that will receive XML data (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">public void recycle()</span>: Recycle the producer by removing references (implemented).
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.generation.Generator</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">void generate()</span>: generate the SAX events to initialize a pipeline.
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.sitemap.SitemapModelComponent</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">void setup(SourceResolver resolver, Map objectmodel, String src, Parameters par)</span>: set the SourceResolver, objectmodel Map, the source and sitemap Parameters used to process the request.
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>AbstractGenerator</strong> itself:
+		<ul>
+			
+<li>
+<span class="codefrag">void setup(SourceResolver resolver, Map objectmodel, String src, Parameters par)</span>: set the SourceResolver, objectmodel Map, the source and sitemap Parameters used to process the request (implemented).
+			</li>
+			
+			
+<li>
+<span class="codefrag">public void recycle()</span>: Recycle the generator by removing references (override implementation).
+			</li>
+		
+</ul>
+	
+</li>
+
+</ul>
+<p>
+If we carefully analyse this list, we see that the only method left unimplemented is the <strong>generate()</strong> method. So if we extend the <strong>AbstractGenerator</strong> class to make our own generator, the only method we'll have to implement is the <strong>generate()</strong> method.
+					</p>
+<p>The following variables are defined in the different interfaces and classes:</p>
+<ul>
+	
+<li>From <strong>org.apache.avalon.excalibur.pool.Poolable</strong>:
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.excalibur.pool.Recyclable</strong>:
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.logger.AbstractLoggable</strong> (Deprecated):
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.logger.AbstractLoggable</strong> (Deprecated):
+		<ul>
+			
+<li>
+<span class="codefrag">private org.apache.log.Logger m_logger</span>: the base logger instance. Provides component with a logger. The <strong>getLogger()</strong> method should be used to aquire the logger.
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.xml.XMLProducer</strong>
+		
+<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.xml.AbstractXMLProducer</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">protected XMLConsumer xmlConsumer</span>: The XMLConsumer receiving SAX events. Can be accessed via <strong>super.xmlConsumer</strong>.
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected ContentHandler contentHandler</span>: The ContentHandler receiving SAX events. Can be accessed via <strong>super.ContentHandler</strong>. 
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected LexicalHandler lexicalHandler</span>: The LexicalHandler receiving SAX events. Can be accessed via <strong>super.LexicalHandler</strong>. 
+			</li>
+		
+</ul>
+		We here access these variables via the <strong>super.</strong> qualifier, this is only done for clarity. They can be equally well accessed via using the <strong>this.</strong> qualifier (or omitting this). For reasons of clarity, if we access such a variable in our code, we will use the <strong>super.</strong> qualifier, although when summing up all the variables we will use <strong>this.</strong>.
+	</li>
+	
+	
+<li>From <strong>org.apache.cocoon.generation.Generator</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">String ROLE = "org.apache.cocoon.generation.Generator"</span>
+			
+</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.sitemap.SitemapModelComponent</strong>:
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.component.Component</strong>:
+		<ul>
+			
+<li>None</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>AbstractGenerator</strong> itself:
+		<ul>
+			
+<li>
+<span class="codefrag">protected SourceResolver resolver = null</span>: The current SourceResolver. Can be accessed via <strong>this.resolver</strong>.
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected Map objectModel = null</span>: The current Map objectModel. Can be accessed via <strong>this.objectModel</strong>.
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected Parameters parameters = null</span>: The current Parameters. Can be accessed via <strong>this.parameters</strong>.
+			</li>
+			
+			
+<li>
+<span class="codefrag">protected String source = null</span>: The source URI associated with the request or <strong>null</strong>. Can be accessed via <strong>this.source</strong>.
+			</li>
+		
+</ul>
+	
+</li>
+
+</ul>
+<p>
+This gives us a list of variables that we can use throughout our own generator.
+</p>
+<h4>ServiceableGenerator</h4>
+<p>
+<strong>Can be used as base class if you want your Generator to be an Avalon Serviceable</strong>
+<br>
+					
+</p>
+<p>This <strong>abstract class</strong> extends <strong>org.apache.cocoon.generation.AbstractGenerator</strong> and extends the interfaces <strong>org.apache.avalon.framework.service.Serviceable</strong> and <strong>org.apache.avalon.framework.activity.Disposable</strong>.</p>
+<p>In addition to all the methods introduced in the <strong>AbstractGenerator</strong> class, these two interfaces introduce som new methods:</p>
+<ul>
+	
+<li>From <strong>org.apache.avalon.framework.service.Serviceable</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">public void service(ServiceManager serviceManager)</span>: Pass the ServiceManager to the Serviceable. The Serviceable implementation should use the specified ServiceManager to acquire the components it needs for execution.				      
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.avalon.framework.activity.Disposable</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">public void dispose()</span>: The dispose operation is called at the end of a components lifecycle. Components use this method to release and destroy any resources that the Component owns.
+			</li>
+		
+</ul>
+		The Disposable interface is used when components need to deallocate and dispose resources prior to their destruction.
+	</li>
+	
+	
+<li>From <strong>ServiceableGenerator</strong> itself:
+		<ul>
+			
+<li>
+<span class="codefrag">public void service(ServiceManager serviceManager)</span>: Pass the ServiceManager to the Serviceable. The Serviceable implementation should use the specified ServiceManager to acquire the components it needs for execution. (implemented)
+			</li>
+			
+			
+<li>
+<span class="codefrag">public void dispose()</span>: The dispose operation is called at the end of a components lifecycle. Components use this method to release and destroy any resources that the Component owns. (implemented - implementation sets the ServiceManager to null)
+			</li>
+		
+</ul>
+	
+</li>
+
+</ul>
+<p>We see that this class provides a default implementation of the methods introduced by the two new interfaces. The only method that needs to be implemented remains the <strong>generate()</strong> method, if we are satisfied with the default implementations.</p>
+<p>Besides these methods, also a new variable is introduced:</p>
+<ul>
+	
+<li>From <strong>ServiceableGenerator</strong> itself:
+		<ul>
+			
+<li>
+<span class="codefrag">protected ServiceManager manager = null</span>: the service manager instance, can be accessed via <strong>this.manager</strong>.
+			</li>
+		
+</ul>
+	
+</li>
+
+</ul>
+<h4>ServletGenerator</h4>
+<p>
+<strong>If you want to generate servlets. This is the base class for the ServerPagesGenerator</strong>
+<br>
+					
+</p>
+<p>The <strong>ServletGenerator</strong> extends <strong>ServiceableGenerator</strong>. 
+					</p>
+<p>We are not giving a more elaborate description of this component at this time. We have not experimented with this component and we would not like to risk making any wrong assumptions.
+					</p>
+<h4>AbstractServerPage</h4>
+<p>
+<strong>[FIXME: This seems to be intended as basis for the ServerPagesGenerator, but it seems to be obsolete now?]</strong>
+<br>
+					
+</p>
+<p>The <strong>AbstractServerPage</strong> extends <strong>ServletGenerator</strong> and implements the <strong>org.apache.cocoon.caching.Cacheable</strong> and <strong>org.apache.cocoon.components.language.generator.CompiledComponent</strong> interfaces.
+					</p>
+<p>We are not giving a more elaborate description of this component at this time. We have not experimented with this component and we would not like to risk making any wrong assumptions.
+					</p>
+<h3>Interface(s)</h3>
+<p>Following the somewhat little pointers on develop-part of the Cocoon-website <a href="../developing/extending.html">Extending Apache Cocoon van The Apache XML Project</a>), we find that the only interface that should be implemented is the Generator interface in the <strong>org.apache.cocoon.generation</strong> package, so we will try to give an overview as complete as possible for now.
+				</p>
+<h4>Generator</h4>
+<p>As mentioned earlier this public interface is situated in the <strong>org.apache.cocoon.generation</strong> package. This interface in its turn extends the <strong>org.apache.cocoon.xml.XMLProducer</strong> and the <strong>org.apache.cocoon.sitemap.SitemapModelComponent</strong> interfaces.
+					</p>
+<p>The interface <strong>XMLProducer</strong> is a top-level interface.
+					</p>
+<p>The interface <strong>SitemapModelComponent</strong> extends the interface <strong>org.apache.avalon.framework.component.Component</strong>, which in turn is a top-level interface.
+					</p>
+<p>Analyzing these interfaces tells us that the following methods should be implemented when implementing the <strong>Generator</strong> interface:</p>
+<ul>
+	
+<li>From <strong>org.apache.cocoon.xml.XMLProducer</strong>
+		
+<ul>
+			
+<li>
+<span class="codefrag">void setConsumer(XMLConsumer xmlconsumer)</span>: set the XMLConsumer that will receive XML data. The XMLConsumer interface extends <strong>org.xml.sax.ContentHandler</strong> and <strong>org.xml.sax.ext.LexicalHandler</strong>.
+			</li>
+		
+</ul>
+		This interface identifies classes that produce XML data, sending SAX events to the configured XMLConsumer.
+	</li>
+	
+	
+<li>From <strong>org.apache.cocoon.sitemap.SitemapModelComponent</strong>:
+		<ul>
+			
+<li>
+<span class="codefrag">void setup(SourceResolver resolver, Map objectmodel, String src, Parameters par)</span>: set the SourceResolver, objectmodel Map, the source and sitemap Parameters used to process the request.
+			</li>
+		
+</ul>
+	
+</li>
+	
+	
+<li>From <strong>org.apache.cocoon.generation.Generator</strong> itself:
+		<ul>
+			
+<li>
+<span class="codefrag">void generate()</span>: generate the SAX events to initialize a pipeline.
+			</li>
+		
+</ul>
+	
+</li>
+
+</ul>
+<p>We decided that the easiest way of writing a custom generator was to extend the <strong>AbstractGenerator</strong> class. The only method required to implement was the <strong>generate</strong> method, for now, we would settle with the provided default implementations of the other methods.
+			</p>
+		
+		
+<h2>Writing a test generator</h2>
+<p>After making these decisions, and looking at the implementations of the classes, we could begin the implementation keeping in mind the following:</p>
+<ul>
+					
+<li>We have to provide SAX events to the XMLConsumer, that is set via the <strong>setConsumer</strong> method.</li>
+					
+<li>We can access the XMLConsumer via <strong>super.xmlConsumer</strong> (analysis of code of <strong>FileGenerator</strong> and definition of the <strong>xmlConsumer</strong> variable as <strong>protected</strong> in the <strong>AbstractXMLProducer</strong> class). The <strong>super.</strong> modifier is only used for clarity, since it can also be accessed via <strong>this.xmlConsumer.</strong>
+</li>
+					
+<li>We will extend the <strong>org.apache.cocoon.generation.AbstractGenerator</strong> class.</li>
+<li>We have to implement the <strong>generate</strong> method which purpose is to produce SAX events and feed them to the XMLConsumer.</li>
+				
+</ul>
+<h3>The code of our first generator</h3>
+<p>As a first test we decided to parse a string containing the following XML content and feed the SAX events to the XMLConsumer:</p>
+<pre class="code">
+&lt;doc&gt;My first Cocoon 2 generator!&lt;/doc&gt;
+	
+</pre>
+<p>First, we will give our code and then we will explain what it does and why we made these choices.</p>
+<pre class="code">
+package test;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReaderFactory;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.generation.AbstractGenerator;
+
+public class MyGenerator extends AbstractGenerator {
+  public void generate () throws IOException, SAXException,
+    ProcessingException {
+      String message = "&lt;doc&gt;My first Cocoon 2 generator!&lt;/doc&gt;";
+      
+      XMLReader xmlreader = XMLReaderFactory.createXMLReader();
+      xmlreader.setContentHandler(super.xmlConsumer);
+      InputSource source = new InputSource(new StringReader(message));
+      xmlreader.parse(source);
+  }
+}
+
+
+</pre>
+<p>First of all, in our working directory (may be any directory) we made a directory "test" and in that directory we created the Java source file <strong>MyGenerator.java</strong>. We also decided to put this class in a package and named that package <strong>test</strong>. This can be easily changed afterwards.
+				</p>
+<p>The obvious <strong>import</strong> statements are those to import the <strong>AbstractGenerator</strong> class and those to import the exceptions thrown by the <strong>generate</strong> method. The other import statements serve to parsing our string and generating SAX events.
+				</p>
+<p>The code itself is pretty straightforward. We have our class definition containing one method definition. First of all, in the <strong>generate</strong> method, we define the variable <strong>message</strong> containing the XML content we want to generate SAX events for.
+				</p>
+<pre class="code">
+XMLReader xmlreader = XMLReaderFactory.createXMLReader();
+
+</pre>
+<p>
+Here we make a new <strong>XMLReader</strong> via the <strong>XMLReaderFactory</strong>. Since XMLReader is an interface, the XMLReaderFactory has to provide us with a class that implements the XMLReader interface, commonly known as a <strong>SAXParser</strong>. Therefore the XMLReaderFactory uses the system variable <strong>org.xml.sax.driver</strong> to determine which class to instantiate to provide us with an XMLReader. An example of how this is done is provided after we have discussed the rest of the code.
+				</p>
+<pre class="code">
+xmlreader.setContentHandler(super.xmlConsumer);
+
+</pre>
+<p>
+With this line of code, we tell the XMLReader which object will receive the SAX events that will be generated when parsing. You can see that we use <strong>super.xmlConsumer</strong> to receive the SAX events.
+				</p>
+<pre class="code">
+InputSource source = new InputSource(new StringReader(message));
+xmlreader.parse(source);
+
+</pre>
+<p>
+With the second line we tell the XMLReader to start parsing the source, provided as argument of the <strong>parse</strong> method. This parse method can only be supplied with an <strong>org.xml.sax.InputSource</strong> argument or a <strong>String</strong> that represents a system identifier or URI. To parse our string we must encapsulate it in an InputSource object. Since the InputSource class can not be passed an XML document that is contained in a string, we first must encapsulate our string into another object, which we then pass to an InputSource object. In this example we have chosen for a <strong>StringReader</strong>. A StringReader can be given as argument when constructing an InputSource object and a StringReader can be given a String object as argument for its construction. This way we succeed in parsing our string.
+				</p>
+<p>The next step is compiling our newly written class. We give here an overview of the our work environment and show how we compiled this Java-file. All the commands from this example were carried out on a PC running Linux, but with respect to a few minor modifications, these commands will also work on a PC running Windows. The commands were carried out in the directory "/home/erwin/cocoon2/generator/". This directory has three subdirectories:</p>
+<ul>
+		
+<li>"test/": directory containing the source files
+			<ul>
+				
+<li>
+<strong>MyGenerator.java</strong>: source file for our generator
+				</li>
+			
+</ul>
+		
+</li>
+		
+		
+<li>"jar/": directory containing the necessary jar (Java Archive) files
+			<ul>
+				
+<li>
+<strong>xerces.jar</strong>: Xerces has an implementation for the XMLReader interface which we use</li>
+				
+<li>
+<strong>cocoon.jar</strong>: contains the classes from Cocoon 2.0.2-dev, needed to extend AbstractGenerator. This is in fact a symbolic link to $TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/cocoon-2.0.2.jar. Under Windows you will have to copy this file or point directly to this file.</li>
+			
+</ul>
+		
+</li>
+		
+		
+<li>"compiled/": outputdirectory for javac. The compiled files will end up in this directory
+			<ul>
+				
+<li>
+<strong>test/MyGenerator.class</strong>: after compiling, we will have this file here</li>
+			
+</ul>
+		
+</li>
+	
+</ul>
+<pre class="code">
+javac -classpath .:jar/cocoon.jar:jar/xerces.jar \
+-d compiled test/MyGenerator.java
+
+</pre>
+<p>
+Now we have our compiled class, we can make the big step of putting it to work. To make sure there were no errors in our code, we tested our code by using another class as the ContentHandler of our generator. After these tests were completed (without errors), we tried to deploy our generator from within Cocoon 2. 
+				</p>
+<h3>Deploying MyGenerator</h3>
+<p>The next step is deploying our custom written generator. First of all we stopped the Tomcat engine (and thus Cocoon 2). We also emptied the <strong>work</strong> directory, located at "$TOMCAT_HOME/work/". Experience learned that this is something you have to do every time you want to try something like this with Cocoon 2.
+				</p>
+<p>For the next step, we changed the main sitemap to be able to use or generator in the following way:</p>
+<p>Under the <strong>map:generators</strong> element, we added the following:</p>
+<pre class="code">						
+&lt;map:generator name="mygenerator" src="test.MyGenerator"/&gt;
+	
+</pre>
+<p>Under the <strong>map:pipelines</strong> element, we added the following:</p>
+<pre class="code">
+&lt;map:pipeline&gt;
+  &lt;map:match pattern="mygenerator.xml"&gt;
+    &lt;map:generate type="mygenerator"/&gt;
+    &lt;map:serialize type="xml"/&gt;
+  &lt;/map:match&gt;
+  &lt;map:handle-errors&gt;
+    &lt;map:transform src="stylesheets/system/error2html.xsl"/&gt;
+    &lt;map:serialize status-code="500"/&gt;
+  &lt;/map:handle-errors&gt;
+&lt;/map:pipeline&gt;
+
+</pre>
+<p>If the page <strong>mygenerator.xml</strong> is requested, we tell Cocoon 2 to use our generator, which we have named <strong>mygenerator</strong>. We do not define the <strong>src</strong> attribuut, since we do not use it in our generator. Once we get the content, we serialize it as xml, so we can check if the input matches the output. In the event that an error occurs, we use one of the stylesheets of Cocoon 2 or another pipeline to signal the error to the user.</p>
+<p>After the changes to the sitemap, we added the directory "/home/erwin/cocoon2/generator/" to the classpath. After these changes, we restarted Tomcat and tried to access the page "http://localhost:8080/cocoon/mygenerator.xml". After waiting a while, we received a fatal error. Inspection of the log-files (which is something you should always do when receiving an error that is not so clear) showed that the following exception was the cause of that fatal error:</p>
+<pre class="code">
+ERROR   (2002-03-27) 23:21.40:190   [sitemap] (/cocoon/)
+Thread-23/Handler: Error compiling sitemap
+java.lang.NoClassDefFoundError:
+org/apache/cocoon/generation/AbstractGenerator
+        at java.lang.ClassLoader.defineClass0(Native Method)
+        at java.lang.ClassLoader.defineClass
+(ClassLoader.java, Compiled Code)
+        at java.security.SecureClassLoader.defineClass
+(SecureClassLoader.java, Compiled Code)
+        at java.net.URLClassLoader.defineClass
+(URLClassLoader.java, Compiled Code)
+        at java.net.URLClassLoader.access$100
+(URLClassLoader.java, Compiled Code)
+        at java.net.URLClassLoader$1.run
+(URLClassLoader.java, Compiled Code)
+        at java.security.AccessController.doPrivileged
+(Native Method)
+        at java.net.URLClassLoader.findClass
+(URLClassLoader.java, Compiled Code)
+        at java.lang.ClassLoader.loadClass
+(ClassLoader.java, Compiled Code)
+        at sun.misc.Launcher$AppClassLoader.loadClass
+(Launcher.java, Compiled Code)
+        at java.lang.ClassLoader.loadClass
+(ClassLoader.java, Compiled Code)
+        at org.apache.tomcat.loader.AdaptiveClassLoader.loadClass
+
+(AdaptiveClassLoader.java, Compiled Code)
+        at java.lang.ClassLoader.loadClass
+(ClassLoader.java, Compiled Code)
+        at java.lang.ClassLoader.loadClass
+(ClassLoader.java, Compiled Code)
+        at org.apache.cocoon.util.ClassUtils.loadClass
+
+(ClassUtils.java, Compiled Code)
+        at org.apache.cocoon.sitemap.AbstractSitemap.load_component
+
+(AbstractSitemap.java, Compiled Code)
+        at org.apache.cocoon.www.sitemap_xmap
+$Configurer.configGenerators(sitemap_xmap.java, Compiled Code)
+        at org.apache.cocoon.www.sitemap_xmap.configure
+(sitemap_xmap.java, Compiled Code)
+        at org.apache.avalon.excalibur.component.
+DefaultComponentFactory.newInstance
+(DefaultComponentFactory.java, Compiled Code)
+        at org.apache.avalon.excalibur.component.
+ThreadSafeComponentHandler.initialize
+(ThreadSafeComponentHandler.java, Compiled Code)
+	at org.apache.cocoon.components.language.generator.
+GeneratorSelector.addGenerator
+(GeneratorSelector.java, Compiled Code)
+        at org.apache.cocoon.components.language.generator.
+ProgramGeneratorImpl.addCompiledComponent
+(ProgramGeneratorImpl.java, Compiled Code)
+        at org.apache.cocoon.components.language.generator.
+ProgramGeneratorImpl.generateResource
+(ProgramGeneratorImpl.java, Compiled Code)
+        at org.apache.cocoon.components.language.generator.
+ProgramGeneratorImpl.createResource
+(ProgramGeneratorImpl.java, Compiled Code)
+        at org.apache.cocoon.components.language.generator.
+ProgramGeneratorImpl.load
+(ProgramGeneratorImpl.java, Compiled Code)
+        at org.apache.cocoon.sitemap.Handler.run
+(Handler.java, Compiled Code)
+        at java.lang.Thread.run(Thread.java:484)
+
+</pre>
+<p>Puzzled by this error, we mailed to the cocoon-users mailinglist (users@cocoon.apache.org) and explained our situation. The answer we received was to put our generator in the "$TOMCAT_HOME/webapps/cocoon/WEB-INF/classes/". We stopped Tomcat, emptied the work-directory, removed the directory "/home/erwin/cocoon2/generator/" from the classpath and made a directory "test/" under the "$TOMCAT_HOME/webapps/cocoon/WEB-INF/classes/" and placed <strong>MyGenerator.class</strong> in that directory. We then restarted Tomcat and once again tried to access "http://localhost:8080/cocoon/mygenerator.xml". But after making that request in our browser, we got a message from the browser saying that the server could not be reached. Looking at the xterm from which we started Tomcat, we saw the following error:</p>
+<pre class="code">
+IGSEGV   11*  segmentation violation
+si_signo [11]: SIGSEGV   11*  segmentation violation
+si_errno [0]: Success
+si_code [128]: unknown siginfo
+sc_pc: 0x20010164f08, r26: 0x200001e19e0
+		 
+thread pid: 26157
+stackpointer=0x3fffc5f69b8
+			   
+Full thread dump Classic VM (1.3.1-1, native threads):
+...
+...
+
+</pre>
+<p>
+Removing our class (and commenting out our changes in the sitemap for safety) would resolve the problem, but then we can't use our generator.
+				</p>
+<p>Somewhere on the Web we had read a mail from someone who was also having <strong>NoClassDefFoundError</strong>s that he was able to solve by unzipping all the jar-files (a jar is basically a zip file containing the compiled classes) from "$TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/" into the "$TOMCAT_HOME/webapps/cocoon/WEB-INF/classes/" directory. We stopped Tomcat, emptied the work-directory and started Tomcat again.
+				</p>
+<p>After restarting Tomcat we had our hopes up that this time it would work. We also started our browser and tried to access "http://localhost:8080/cocoon/mygenerator.xml", again. After waiting a while (Cocoon 2 had to recompile its sitemap and some other components) we got the see our XML file. Cocoon 2 produced the following XML document:</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;doc&gt;My first Cocoon 2 generator!&lt;/doc&gt;
+
+</pre>
+<p>
+So, after a bit of struggling, we finally succeeded in deploying our own generator.
+				</p>
+<h3>Considerations afterwards</h3>
+<p>After seeing our example and having some experience with Cocoon 2 one might ask why we reinvented the wheel by instantiating a parser and not using the one provided by Cocoon 2. It is evident that a start of a pipeline is a generator that fires SAX events, there must be a SAXParser available throughout Cocoon 2 that can be easily accessed. This is in fact the case. There are a number of reasons why we had not chosen that approach the first time around:</p>
+<ul>
+						
+<li>Limited knowledge of the whole underlying architecture, not really enhanced by the documentation.</li>
+						
+<li>We wanted to keep the time-to-test as short as possible, so we didn't spend time finding this information in the source in the first phase.</li>
+						
+<li>We didn't see any other possibility of testing our code before we tried to integrate it with the Cocoon 2 project.</li>
+					
+</ul>
+<p>We would still like to point the reader to an alternative solution, i.e. the solution that is used throughout Cocoon 2. We will give the code fragments here and we will then explain what it does.</p>
+<pre class="code">
+...
+import org.apache.excalibur.xml.sax.SAXParser;
+...
+SAXParser parser = null;
+
+  try {
+    parser = (SAXParser)this.manager.lookup(SAXParser.ROLE);
+    parser.parse(this.getInputSource(),handler);
+  } catch (SAXException e) {
+    // Preserve original exception
+    throw e;
+  } catch (Exception e) {
+    throw new ProcessingException("Exception during processing of " +
+    this.getSystemId(),e);
+  } finally {
+    if (parser != null) {
+      this.manager.release(parser);
+    }
+  }
+...
+
+</pre>
+<p>An extra <strong>import</strong> statement is added. The <strong>SAXParser</strong> interface of the Avalon/Excalibur project (<a class="external" href="http://jakarta.apache.org/avalon/excalibur/index.html">Avalon/Excalibur van The Jakarta Project</a>) defines the following method:</p>
+<ul>
+						
+<li>
+<span class="codefrag">void parse(InputSource in, ContentHandler consumer)</span>: the implementation of this method should parse the <strong>InputSource</strong> and send the SAX events to the <strong>consumer</strong>. The consumer can be an <strong>XMLConsumer</strong> or an object that implements <strong>LexicalHandler</strong> as well.
+						</li>
+					
+</ul>
+<p>This interface defines a variable <strong>ROLE</strong> of the type String that is given the value <strong>org.apache.excalibur.xml.sax.SAXParser</strong>. This variable is used to ask the <strong>ServiceManager</strong>, which is accessed by <strong>this.manager</strong>, to <strong>lookup</strong> a <strong>Component</strong> that has that role. The returned Component is then casted to a <strong>SAXParser</strong> type. We can then apply the parse method to any <strong>org.xml.sax.InputSource</strong> object and to an object that implements the <strong>ContentHandler</strong> interface. Finally, we have to tell the ServiceManager that we are finished using the parser. This allows the ServiceManager to handle the End-Of-Life Lifecycle events associated with this Component.
+				</p>
+<p>
+<strong>NOTE:</strong> if you want to use this method to obtain a parser, it would be better to extend the <strong>ServiceableGenerator</strong> class, instead of the <strong>AbstractGenerator</strong> class. The ServiceableGenerator is defined to make use of a <strong>ServiceManager</strong>, while this is not the case for the <strong>AbstractGenerator</strong> class. You should envisage the given code as part of a class that extends the <strong>ServiceableGenerator</strong> class or one of its children.
+				</p>
+		
+		
+<h2>Going the distance</h2>
+<p>We have succeeded in implementing a first test to find out how everything works, but a generator that only sends a fixed string to Cocoon 2 is not that interesting. Since we have written an application that can serve XML documents contained in a String object (using JDOM (<a class="external" href="http://www.jdom.org">JDOM.org</a>)), we want to be able to retrieve these documents through our browser, which sends this request to Cocoon 2. Cocoon 2 then fires up our generator to retrieve the requested XML document and can start the pipeline for processing that document.
+			</p>
+<p>Since we had experimented with Java RMI in one of our courses, we decided to try a setup where our generator was a client for the document server and the communication would happen via RMI. For this section, we will first look at setting up the server, next we will look at accessing the server from within MyGenerator and finally we will put it all together. If we get this to work, we then can ponder about looking up parameters defined in the sitemap to use in MyGenerator. We used (<a class="external" href="http://java.sun.com/products/jdk/1.2/docs/guide/rmi/getstart.doc.html">Getting Started Using RMI</a>) as a basis for getting started with RMI. If you have never used RMI, we recommend that you read this document to develop a basic understanding of working with RMI.
+			</p>
+<h3>Setting up a RMI server</h3>
+<p>After reading the document (<a class="external" href="http://java.sun.com/products/jdk/1.2/docs/guide/rmi/getstart.doc.html">Getting Started Using RMI</a>) and having deployed the example, we started writing our own interface, called <strong>Serverfunctions</strong> that defines the methods that should be implemented by a program that wishes to serve as a server for <strong>MyGenerator</strong>. This interface looks like this:</p>
+<pre class="code">
+package test;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface ServerFunctions extends Remote {
+  /**
+    This method returns a String, containing 
+    a well-formed XML fragment/document. This String 
+    contains information about the application implementing 
+    this interface. Choosing what information is put 
+    into this String is left to the application designer.
+  */
+  String sayHello () throws RemoteException;
+
+  /**
+    This method returns a String, containing a well-formed XML
+    fragment/document. To determine the information that should be
+    returned, a systemId is passed to this method.
+  */
+  String getResource (String systemId) throws RemoteException;
+}
+
+
+</pre>
+<p>
+This interface defines two methods that should be implemented. Since these methods can be invoked via RMI we must declare that these methods can throw a RemoteException. These methods should return well-formed XML, as specified.
+				</p>
+<p>With interfaces alone we cannot build an application. We also must have a class that implements this interface. The following example demonstrates how this can be implemented. We used JDOM (<a class="external" href="http://www.jdom.org">JDOM.org</a>) for reading in a XML document and converting it to a String.</p>
+<pre class="code">
+package test;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.RMISecurityManager;
+import java.rmi.server.UnicastRemoteObject;
+
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+import test.ServerFunctions;
+
+public class Server extends UnicastRemoteObject implements
+  ServerFunctions {
+
+  
+  public Server () throws RemoteException {
+    super();
+  }
+
+  public String sayHello () {
+    return "&lt;doc&gt;My First RMI Server!&lt;/doc&gt;";
+  }
+
+  public String getResource (String systemId) {
+    try {
+      SAXBuilder sb = new SAXBuilder();
+      Document newdoc = sb.build(systemId);
+      return (new XMLOutputter()).outputString(newdoc);
+    } catch (JDOMException jde) {
+      System.out.println("JDOM error: " + jde.getMessage());
+      jde.printStackTrace();
+      // Rethrow the exception so the other
+      // side knows something is wrong
+      throw new RemoteException("JDOMException while processing " +
+        systemId,jde);
+    }
+  }
+
+  public void main (String args[]) {
+    // Create and install a security manager
+    // For testing purposes only, set this to null
+    System.setSecurityManager(null);
+    
+    try {
+      Server obj = new Server();
+      // Bind this object instance to the name "MyServer"
+      Naming.rebind("MyServer",obj);
+      System.out.println("MyServer bound in registry");
+    } catch (Exception e) {
+      System.out.println("Server error: " + e.getMessage());
+      e.printStackTrace();
+  }
+}
+}
+
+
+
+
+</pre>
+<p>We first have the necessary import-statements. This class implements the <strong>ServerFunctions</strong> interface we defined before. We also extend the <strong>UnicastRemoteObject</strong>. The Java API docs ((<a class="external" href="http://java.sun.com/j2se/1.3/docs/api/index.html">Java 2 Platform, SE v1.3 API documentation</a>)) tell us the following about UnicastRemoteObject: "The UnicastRemoteObject class defines a non-replicated remote object whose references are valid only while the server process is alive. Objects that require remote behavior should extend RemoteObject, typically via UnicastRemoteObject." This allows us, by calling the constructor of this superclass, to use the behavior of the UnicastRemoteObject for our RMIServer. This is typically done by calling the <strong>super()</strong> constructor in the constructor of our class.
+				</p>
+<p>Next, we have the implementation of the two methods defined in our interface. The <strong>sayHello</strong> method just returns a string representing the following XML fragment:</p>
+<pre class="code">
+&lt;doc&gt;My First RMI Server!
+	
+</pre>
+<p>We then also implement the <strong>getResource</strong> method. In the body of the try-block we first build a JDOM Document using the given systemId. This means that an XML file, at the given location, is read and a JDOM Document object is created. Next, we use the method <strong>outputString(Document doc)</strong> of the <strong>XMLOutputter</strong> class to convert the JDOM Document to a string. It is this string that is returned to the client. In the event that there may be an error building the document, a <strong>JDOMException</strong> is thrown. If this is the case, we print the info to stdout and rethrow the exception, encapsulated in a RemoteException.
+				</p>
+<p>We then only need a <strong>main</strong> method to have a Java application at hand. The first thing we do is disabling the <strong>SecurityManager</strong>. For security reasons, this should only be done only for testing purposes on an isolated system and in production environments. We did this so we could bind this server in the rmiregistry without rewriting any Java policy files. Next, we make a new <strong>Server</strong> object and bind this in the rmiregistry, where it is associated with the name <strong>MyServer</strong>. We end with printing out a line that we have bound this object in the rmiregistry.
+				</p>
+<h3>Setting up a RMI client</h3>
+<p>The next step in the process is to implement a Java application that can connect to our RMI server and invoke its methods. Once again, we will first give our code and then explain what it does.</p>
+<pre class="code">
+package test;
+
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+
+import test.ServerFunctions;
+
+public class Client {
+
+  public void main (String args[]) {
+    String message = "blank";
+
+    
+    try {
+      // "obj" is the identifier that we'll use to refer
+      // to the remote object that implements the
+      // "ServerFunctions" interface
+      ServerFunctions obj = 
+      (ServerFunctions)Naming.lookup("//myhost.com/MyServer");
+      
+      message = obj.sayHello();
+      System.out.println(message);
+      
+      message = obj.getResource("index.xml");
+      System.out.println(message);
+    } catch (Exception e) {
+      System.out.println("Server exception: " + e.getMessage());
+      e.printStackTrace();
+    }
+  }
+}
+
+
+</pre>
+<p>Our client only defines a <strong>main</strong> method. We first initialize the variable, to which we will assign the return value of the <strong>sayHello</strong> method. Next, we try to <strong>lookup</strong> an object that is bound to "//myhost.com/MyServer" (note that myhost.com is a random chosen example). The lookup method returns an object, that is casted to the <strong>ServerFunctions</strong> type. We then invoke the sayHello method on the object and we print this message out. We also invoke the <strong>getResource</strong> method and print the result out. If this succeeds, we know everything works correctly. If an exception occurs, we print out the message from this exception plus its stack trace.
+				</p>
+<h3>Testing the RMI components</h3>
+<p>We will first test if the RMI communication works. If it doesn't work there is no point in trying to integrate RMI communication in MyGenerator.Located in the directory "/home/erwin/cocoon2/generator/", which has the subdirectory "test/" containing our files, we execute the following commands:</p>
+<pre class="code">
+javac -classpath .:jar/jdom.jar:jar/xerces.jar -d compiled/ test/*.java
+rmic -classpath .:jar/jdom.jar:jar/xerces.jar -d compiled/ test.Server
+rmiregistry &amp;amp;
+java -classpath compiled/:jar/jdom.jar:jar/xerces.jar \
+-Djava.rmi.server.codebase=http://myhost.com/~erwin/cocoon2/generator/compiled/ \
+test.Server
+MyServer bound in registry
+
+</pre>
+<p>
+If you forget to define the <strong>java.rmi.server.codebase</strong> system property or give it a wrong value, you are most likely to get the following exception:</p>
+<pre class="code">
+HelloImpl err: RemoteException occurred in server thread; nested exception is:
+        java.rmi.UnmarshalException: error unmarshalling arguments; 
+nested exception is:
+        java.lang.ClassNotFoundException: test.Server_Stub
+java.rmi.ServerException: RemoteException occurred in server thread; 
+nested exception is:
+        java.rmi.UnmarshalException: error unmarshalling arguments; 
+nested exception is:
+        java.lang.ClassNotFoundException: test.Server_Stub
+java.rmi.UnmarshalException: error unmarshalling arguments; 
+nested exception is:
+        java.lang.ClassNotFoundException: test.Server_Stub
+java.lang.ClassNotFoundException: test.Server_Stub
+        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer
+(StreamRemoteCall.java, Compiled Code)
+        at sun.rmi.transport.StreamRemoteCall.executeCall
+(StreamRemoteCall.java, Compiled Code)
+        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java, Compiled Code)
+        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
+        at java.rmi.Naming.rebind(Naming.java, Compiled Code)
+        at test.Server.main(Server.java, Compiled Code)
+
+</pre>
+<p>
+We now can start the client to test if everything works. Notice that the resource requested in the code is in fact a relative URI. It is relative to the path from where we started the server application. The file index.xml contains the following information:</p>
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;document&gt;
+  &lt;title&gt;This is a document&lt;/title&gt;
+  &lt;para&gt;This is the first paragraph.&lt;/para&gt;
+&lt;/document&gt;
+
+</pre>
+<p>
+The client is started with the following command:
+</p>
+<pre class="code">
+[erwin generator]$ java -classpath compiled/ test.Client
+
+</pre>
+<p>This resulted in the following output:</p>
+<pre class="code">
+&lt;doc&gt;My First RMI Server!&lt;/doc&gt;
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;document&gt;
+  &lt;title&gt;This is a document&lt;/title&gt;
+  &lt;para&gt;This is the first paragraph.&lt;/para&gt;
+&lt;/document&gt;
+
+</pre>
+<p>
+This is exactly the output we expected, except for the encoding attribute. But this is something that is added by JDOM.
+				</p>
+<p>
+<strong>NOTE:</strong> we would like to conclude this section with a final note about the RMI server application. If you wish to deploy an RMI server application in the real world, you may wish to delete the code that disables the SecurityManager. If no other settings are changed, you may get the following error when starting your server application (depending on the configuration in your <strong>java.policy</strong> file):</p>
+<pre class="code">
+HelloImpl err: access denied 
+(java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
+java.security.AccessControlException: access denied 
+(java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
+        at java.security.AccessControlContext.checkPermission
+(AccessControlContext.java, Compiled Code)
+	...
+        at test.Server.main(Server.java, Compiled Code)	
+
+</pre>
+<p>
+The most likely reason is that the default policy does not permit your server to bind its name in the rmiregistry. You have to change the security policy specified in the "$JAVA_HOME/jre/lib/security/java.policy" file. Since we are no experts in security we cannot give you any advice in this matter, but a general advice in security related matters is that you are better safe then sorry.
+				</p>
+<h3>Putting the pieces together</h3>
+<p>We now have been able to setup a generator and use RMI communication, now it is time to integrate these two pieces so we have a fully blown RMIGenerator for Cocoon 2. But before we do that, we will look how we can access the parameters and source that are passed from the sitemap to MyGenerator.
+				</p>
+<p>We have seen that the method <strong>setup</strong> is implemented in the <strong>AbstractGenerator</strong> class. One of the arguments of this method is String src. The value of the <strong>src</strong> attribute in the sitemap is passed via this argument and the variable <strong>source</strong> will be assigned this value. If for instance the following is a small part of the sitemap:</p>
+<pre class="code">
+&lt;map:match pattern="mygenerator.xml"&gt;
+  &lt;map:generate type="mygenerator" src="example.xml"/&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+
+
+</pre>
+<p>
+If we request "$FULL_URL_PATH/mygenerator.xml", the value of the <strong>src</strong> attribute will be passed to <strong>MyGenerator</strong> using the setup method. This value, <strong>example.xml</strong> can then be accessed via the <strong>this.source</strong> variable in our code.
+				</p>
+<p>As for now, we still have hardcoded in MyGenerator to which RMI server our generator should connect and also which bindname should be looked up. This is not desirable, we wish to have a configurable generator. "Compile once, run many" is maybe the way you could describe this. We wish to pass these values as parameters to the generator. Clearly, these values should be specified in the sitemap. Amongst the elements allowed in the sitemap there is a <strong>parameter</strong> element. If we want to use this element to pass parameters to our generator this element has to appear as a child of the <strong>generate</strong> element. Our sitemap fragment will then look like this:</p>
+<pre class="code">
+&lt;map:match pattern="mygenerator.xml"&gt;
+  &lt;map:generate type="mygenerator" src="example.xml"&gt;
+    &lt;map:parameter name="host" value="myhost.com"/&gt;
+    &lt;map:parameter name="port" value="1099"/&gt;
+    &lt;map:parameter name="bindname" value="MyServer"/&gt;
+  &lt;/map:generate&gt;
+  &lt;map:serialize type="xml"/&gt;
+&lt;/map:match&gt;
+
+
+</pre>
+<p>
+We define three parameters:</p>
+<ul>
+	
+<li>
+<strong>host</strong>: tells the generator at which host the RMI server application is running. <strong>REQUIRED</strong>.</li>
+	
+<li>
+<strong>port</strong>: tells the generator at which port at the remote host the rmiregistry process is running. If no value is specified Java uses the default port (1099). <strong>OPTIONAL</strong>.</li>
+	
+<li>
+<strong>bindname</strong>: tells the generator which name should be looked up in the remote registry to obtain access to the RMI server object. <strong>REQUIRED</strong>.</li>
+
+</ul>
+<p>
+We only need these three parameters to define the remote server object. We do not need to specify which methods should be invoked since we demand that a remote server implements the <strong>ServerFunctions</strong> interface. This is something that may be considered in the future.
+				</p>
+<p>We now have defined the host, port and bindname parameters, but how can we access the value of these parameters in our code? The setup method has an argument Parameters par. It is via this argument that the parameters defined in the sitemap will be passed to the generator. This argument will be assigned to the <strong>parameters</strong> variable defined in AbstractGenerator. To obtain the value of each parameter we can invoke the following method on the parameters variable: <span class="codefrag">public java.lang.String getParameter(java.lang.String name)</span>. This method returns the value of the specified parameter, or throws an exception if there is no such parameter.
+				</p>
+<p>With all this in mind, we can finally build our configurable RMIGenerator. Also, this time we are going to extend the <strong>ServiceableGenerator</strong> instead of the <strong>AbstractGenerator</strong> class. This way, we can make use of the <strong>ServiceManager</strong> to obtain a SAXParser. 
+				</p>
+<p>At this moment we decide that if there is no value given to the src attribute in the sitemap (<strong>source is null</strong>), we will invoke the <strong>sayHello</strong> method and otherwise the getResource with the appropriate parameter. When the value of the src attribute is the <strong>empty string</strong>, the <strong>getResource</strong> method is invoked, so this should be <strong>handled by the RMI server application</strong>.
+After a little bit of thinking about how to code all this, we eventually wrote the following generator:</p>
+<pre class="code">
+package test;
+
+// import the necessary classes from the java.io package
+import java.io.IOException;
+import java.io.StringReader;
+
+// import the necessary classes from the java.rmi package
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.rmi.NotBoundException;
+
+// import the necessary SAX classes
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+// import of the classes used from Cocoon
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.generation.ServiceableGenerator;
+
+// Avalon Framework
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.parameters.ParameterException;
+
+// needed for obtaining parser in Cocoon
+import org.apache.excalibur.xml.sax.SAXParser;
+
+import test.ServerFunctions;
+
+public class MyGenerator extends ServiceableGenerator {
+  public void generate () throws IOException, SAXException,
+    ProcessingException {
+      String host;
+
+      // lookup parameter 'host'
+      try {
+        host = parameters.getParameter("host");
+        // test if host is not the empty string
+        if (host == "") {
+          throw new ParameterException(
+          "The parameter 'host' may not be the empty string");
+        }
+      } catch (ParameterException pe) {
+        // rethrow as a ProcessingException
+        throw new ProcessingException(
+        "Parameter 'host' not specified",pe);
+      }
+
+      String bindname;
+      
+      // lookup parameter 'bindname'
+      try {
+        bindname = parameters.getParameter("bindname");
+        // test if bindname is not the empty string
+        if (bindname == "") {
+          throw new ParameterException(
+          "The parameter 'bindname' may not be the empty string");
+        }
+      } catch (ParameterException pe) {
+        // rethrow as a ProcessingException
+        throw new ProcessingException(
+        "Parameter 'bindname' not specified",pe);
+      }
+
+      String port = "";
+      
+      // lookup parameter 'port'
+      try {
+        port = parameters.getParameter("port");
+        port = ":" + port;
+      } catch (ParameterException pe) {
+        // reset port to the empty string
+        // port is not required
+        port = "";
+      }
+
+      try {
+        ServerFunctions obj = 
+        (ServerFunctions)Naming.lookup("//" +
+          host + port + "/" + bindname);
+        String message = "";
+	
+        // determine the method to invoke
+        // depending on value of source
+	if (this.source == null) {
+	  message = obj.sayHello();
+	} else {
+	  message = obj.getResource(source);
+	}
+
+	SAXParser parser = null;
+	parser = (SAXParser)this.manager.lookup(SAXParser.ROLE);
+	
+	InputSource inputSource = new InputSource(
+	new StringReader(message));
+	parser.parse(inputSource,super.xmlConsumer);
+	
+      } catch (NotBoundException nbe) {
+	throw new ProcessingException("
+	Error looking up the RMI server application",nbe);
+      } catch (ServiceException ce) {
+        throw new ProcessingException("
+        Error obtaining a SAXParser",ce);
+      }
+    }
+}
+      
+
+</pre>
+<p>Since we have already explained every step that happens in this generator, we are confident that everyone will understand the code. We are now ready to deploy this generator.
+				</p>
+<h3>The final step: deployment</h3>
+<p>We can now compile our classes and put the generator, along with the ServerFunctions interface, in the right place. For compiling, we used the following command:</p>
+<pre class="code">
+javac -classpath .:jar/xerces.jar:jar/cocoon.jar:jar/framework.jar: \
+jar/excalibur.jar:jar/exc-scratchpad.jar \
+-d compiled/ test/ServerFunctions.java test/MyGenerator.java
+
+</pre>
+<p>
+where xerces.jar is a symbolic link to "$TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/xercesImpl-2.0.0.jar", framework.jar to "$TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/avalon-framework-4.1.2.jar", excalibur.jar to "$TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/avalon-excalibur-4.1.jar" and exc-scratchpad.jar to "$TOMCAT_HOME/webapps/cocoon/WEB-INF/lib/avalon-excalibur-scratchpad-20020212.jar". This is valid for Cocoon 2.0.2-dev. If you use another version of Cocoon 2, you might have to change some of these names.
+If your platform does not allow the use of symbolic links, you should use the complete path to the corresponding jar-files.
+				</p>
+<p>Now that these classes are compiled we can place them in the $TOMCAT_HOME/webapps/cocoon/WEB-INF/classes/" directory as before. Now all that is left is shutting down Tomcat/Cocoon, emptying the work directory, modifying the sitemap, setting up a RMI server application and starting Tomcat/Cocoon.
+				</p>
+	
+	
+	
+<h1>Future plans</h1>
+		
+<p>The first version of this generator was written as a proof-of-concept. The latest version (as given here, extending the ServiceableGenerator) only foresees in the <strong>generate</strong> method. There are a number of plans we still have to extend the functionality and thus usability of this generator:</p>
+			
+<ul>
+				
+<li>allow passing of a (J)DOM document instance as a resource to our generator. JDOM does require an additional entry in the classpath.</li>
+				
+<li>supply a possibility for caching documents</li>
+				
+<li>if the RMI server application can generate SAX events, try to pass the xmlConsumer to the server application as the ContentHandler</li>
+			
+</ul>
+		
+		
+<p>These are some of the extensions we have in mind for this generator. Our goal is to complete these steps within a few weeks (it will probably be a bit longer since the deadline of our thesis is only three weeks a way at the time of writing).
+		</p>
+	
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/meta.xml
new file mode 100644
index 0000000..4686637
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorial-rmi-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>tutorial/tutorial-rmi-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/content_en.html
new file mode 100644
index 0000000..c800d68
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/content_en.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cocoon Tutorials</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Overview" name="DC.Subject">
+<meta content="Diana Shannon" name="DC.Creator">
+</head>
+<body>
+ 
+ 
+<h1>Overview</h1>
+
+
+<p>
+This is a collection of tutorials. The Cocooon project is actively seeking additional tutorial contributors to expand this collection. 
+
+<!-- For information on how to write your own HOWTO, please see <link href="author-tutorial-howto.html">How to write your own HOWTO.</link> -->
+</p>
+
+
+ 
+<h2>Tutorials</h2>
+<ul>
+
+<li>
+<a href="tutorial-develop-webapp.html">How to develop Web Applications</a>
+</li>
+
+<li>
+<a href="tutorial-generator.html">Write a Custom Generator</a>
+</li>
+
+<li>
+<a href="tutorial-rmi-generator.html">Building a RMI Server Generator</a> - Draft</li>
+	
+</ul>
+ 
+  
+<h2>Third-Party Tutorials</h2>
+<ul>
+
+<li>
+<a class="external" href="http://cocooncenter.org/">cocooncenter.org has a few tutorials and articles</a>
+</li>
+
+<li>
+<a class="external" href="http://www.galatea.com/flashguides/index.html">Galatea FlashGuides(TM)</a>
+</li>
+
+<li>
+<a class="external" href="http://durdo.miesto.sk/Cocoon2HowTo/index.html">Cocoon 2 How-To Pages</a>
+</li>
+
+<li>Leigh Dodds's <a class="external" href="http://www-105.ibm.com/developerworks/education.nsf/xml-onlinecourse-bytitle/83F66813F7FFD61486256B74006EB648?open&l=472,t=gr">Introduction to Cocoon 2</a> at the IBM developerWorks web site. Covers how to install and configure Cocoon,
+introduces the principles of the Cocoon 2 architecture and its key
+components, and provides example pipeline configurations which demonstrate how to
+construct a dynamic Web site using Cocoon and XSLT.</li>
+
+<li>Leigh Dodds's <a class="external" href="http://www-105.ibm.com/developerworks/education.nsf/xml-onlinecourse-bytitle/14DFAEE91D8BB1EF86256BA300662FAF?open&l=472,t=gr">Working with XML Server Pages in Apache Cocoon 2</a> at the IBM developerWorks web site. Introduces XML Server Pages (XSP), the Cocoon technology for generating dynamic XML content.</li>
+
+<li>Leigh Dodds's <a class="external" href="http://www-105.ibm.com/developerworks/education.nsf/xml-onlinecourse-bytitle/AC994D2B8F0B85D086256BC1006B53AC?open&l=472,t=gr">Cocoon 2: Build database-driven sites</a> at the IBM developerWorks web site. Introduces basic concepts of the Cocoon 2 architecture and XML Server Pages (XSP) as a means for creating and publishing dynamic XML content.</li>
+	
+</ul>
+
+ 
+
+
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/meta.xml
new file mode 100644
index 0000000..8d77f48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-tutorials/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>tutorial/index.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/content_en.html
new file mode 100644
index 0000000..e64af66
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/content_en.html
@@ -0,0 +1,476 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Updating Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="J&ouml;rg Heinicke" name="DC.Creator">
+<meta content="Bertrand Delacr&eacute;taz" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Updating Cocoon</h1>
+   
+<p>
+    Please take your time to read this document completely before trying to upgrade from
+    a Cocoon 2.1.x installation to 2.2 (or above). You can also read it if you want to
+    know what was going on in the development of Cocoon. If you want to upgrade from
+    an 2.0.x installation, please read the instructions 
+    <a href="../installing/updating.html">here</a>, first.
+   </p>
+   
+<div class="note">THIS DOCUMENTATION IS ALPHA AS WELL AS THE CURRENT DEVELOPMENT FOR 2.2,
+     so use this information with great care. It might be that we don't have added
+     everything and (more important) it might be that we revert some changes
+     detailed here.</div>
+   
+<p>
+    The Cocoon team took great care in making this new version as compatible as
+    possible. However, in order to achieve even more flexibility, usability and
+    performance, the internal architecure of Cocoon has been improved. Due to these
+    improvements it has not been possible to be compatible in every little detail.
+    If you follow the instructions of this document closely, however,
+    you should be able to quickly upgrade your Cocoon 2.1.x installation.
+   </p>
+   
+<p>
+    In general, a good advice is that you avoid any calls to private or deprecated
+    API. If you are calling deprecated API, look up for an alternative. In most 
+    case this is documented in the java docs. If not or if you are calling private
+    API please ask on the mailing lists for the "right way".
+   </p>
+  
+  
+<h1>Updating Your Application</h1>
+    
+<p>Currently, updating your application from an older version to the latest
+     version of Cocoon has to be done manually (but we are working on a better
+     solution!).</p>
+    
+<p>We suggest you, that you start from a clean Cocoon installation and 
+    incorporate your changes into the cocoon.xconf, the sitemap etc. This
+    is in most cases much easier than starting with your old application
+    and adapting it for Cocoon 2.2.x.</p>
+  
+  
+<h1>Sitemap Changes</h1>
+    
+<h2>Mime-Types and Readers</h2>
+<p>The way, a reader sets the mime-type has changed. Now the following algorithm is used:</p>
+<ol>
+       
+<li>If the reader instance has a mime-type definition, it is used.</li>
+       
+<li>If the used reader has a mime-type definition, it is used.</li>
+       
+<li>If both are not set, the reader itself has to provide the mime-type.</li>
+      
+</ol>
+<p>You can find further information in <a class="external" href="http://issues.apache.org/bugzilla/show_bug.cgi?id=10277">bug entry 10277</a>.</p>
+  
+  
+<h1>Recompilation</h1>
+    
+<p>
+      As detailed below some deprecated classes and methods have been removed,
+      therefore the easiest way to detect if you are affected is to recompile
+      your code. If during compilation an error occurs have a look in the
+      sections below on what to change.
+    </p>
+  
+  
+<h1>Internal Processing</h1>
+    
+<p>
+      The internal processing of Cocoon has been improved, therefore some
+      deprecated methods have been removed to clean up the code.
+    </p>
+    
+<h2>Environment Interface</h2>
+<p>The deprecated <em>getOutputStream</em> method of the <em>Environment</em> 
+      interface has been removed. Use the <em>getOutputStream(int)</em> method
+      instead.</p>
+<p>
+        In addition some methods of the Environment interface have been changed,
+        removed and added. The environment is now free from any dependencies
+        to the Cocoon core and it is easier to create own environments.
+      </p>
+    
+<h2>Cocoon Source Resolver Interface</h2>
+<p>The deprecated <em>resolve</em> method of the 
+        <em>org.apache.cocoon.environment.SourceResolver</em> 
+        interface has been removed. Use the <em>resolveURI</em> and
+        the <em>release</em> method instead.</p>
+<p>In addition the following interfaces and implementations have been 
+        removed in favour of their new versions:</p>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.environment.Source</em> : Use the 
+          <em>org.apache.excalibur.source.Source</em> interface instead.</li>
+        
+<li>
+<em>org.apache.cocoon.environment.ModifiableSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.environment.URLFactorySourceResolver</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.environment.WriteableSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.AbstractSAXSource</em> - Not needed anymore&gt;</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.AbstractStreamSource</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.AbstractStreamWriteableSource</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.CocoonSourceFactory</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.DelayedRefreshSourceWrapper</em> - org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.FileSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.FileSourceFactory</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.ModifiableTraversableSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.SitemapSource</em> - org.apache.cocoon.components.source.impl.SitemapSource</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.SourceFactory</em> - org.apache.cocoon.components.source.impl.SitemapSourceFactory</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.SourceHandler</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.SourceHandlerImpl</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.TraversableSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.URLSource</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.impl.AvalonToCocoonSource</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.impl.AvalonToCocoonSourceInvocationHandler</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.impl.CocoonToAvalonSource</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.impl.SourceFactoryWrapper</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.source.impl.URLFactoryWrapper</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.url.ContextURLFactory</em> - org.apache.cocoon.components.source.impl.ContextSourceFactory</li>
+        
+<li>
+<em>org.apache.cocoon.components.url.ResourceURLFactory</em> - Excalibur SourceResolver</li>
+        
+<li>
+<em>org.apache.cocoon.components.url.URLFactory</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.components.url.URLFactoryImpl</em> - Not needed anymore</li>
+        
+<li>
+<em>org.apache.cocoon.xml.XMLizable</em> - Excalibur SourceResolver</li>
+      
+</ul>
+    
+<h2>XML Parsing</h2>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.components.parser.JaxpParser</em> - Excalibur XMLUtils</li>
+        
+<li>
+<em>org.apache.cocoon.components.parser.Parser</em> - Excalibur XMLUtils</li>
+        
+<li>
+<em>org.apache.cocoon.components.parser.PooledJaxpParser</em> - Excalibur XMLUtils</li>
+        
+<li>
+<em>org.apache.cocoon.components.parser.XercesParser</em> - Excalibur XMLUtils</li>
+      
+</ul>
+    
+<h2>XML Entity Resolver</h2>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.components.resolver.Resolver</em> - Excalibur XMLUtils</li>
+        
+<li>
+<em>org.apache.cocoon.components.resolver.ResolverImpl</em> - Excalibur XMLUtils</li>
+      
+</ul>
+    
+<h2>Stores</h2>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.components.store.FilesystemStore</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.JispFilesystemStore</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.JispStringKey</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.MemoryStore</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.MRUMemoryStore</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.Store</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.StoreJanitor</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.StoreJanitorImpl</em> - Excalibur Store</li>
+        
+<li>
+<em>org.apache.cocoon.components.store.impl.DefaultPersistentStore</em> - JCS Store</li>
+      
+</ul>
+    
+<h2>XSLT Processor</h2>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.components.xslt.XSLTProcessor</em> - Excalibur XMLUtils</li>
+        
+<li>
+<em>org.apache.cocoon.components.xslt.XSLTProcessorImpl</em> - Excalibur XMLUtils</li>
+      
+</ul>
+    
+<h2>Sitemap Components</h2>
+<ul>
+        
+<li>
+<em>org.apache.cocoon.components.treeprocessor.MapStackResolver</em> - org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory</li>
+        
+<li>
+<em>org.apache.cocoon.matching.RegexpTargetHostMatcher</em> - org.apache.cocoon.matching.RegexpHostMatcher</li>
+        
+<li>
+<em>org.apache.cocoon.matching.RequestParamMatcher</em> - org.apache.cocoon.matching.RequestParameterMatcher</li>
+        
+<li>
+<em>org.apache.cocoon.matching.WildcardParameterValueMatcher</em> - org.apache.cocoon.matching.WildcardRequestParameterMatcher</li>
+        
+<li>
+<em>org.apache.cocoon.matching.helpers.WildcardURIMatcher</em> - org.apache.cocoon.matching.helpers.WildcardHelper</li>
+        
+<li>
+<em>org.apache.cocoon.selection.RequestSelector</em> - org.apache.cocoon.selection.RequestParameterSelector</li>
+        
+<li>
+<em>org.apache.cocoon.selection.SessionStateSelector</em> - org.apache.cocoon.selection.SessionAttributeSelector</li>
+        
+<li>
+<em>org.apache.cocoon.sitemap.SitemapRedirector</em> - Removed</li>
+        
+<li>
+<em>org.apache.cocoon.sitemap.XSLTFactoryLoader</em> - Removed</li>
+        
+<li>
+<em>org.apache.cocoon.transformation.CachingCIncludeTransformer</em> - org.apache.cocoon.transformation.CIncludeTransformer</li>
+        
+<li>
+<em>org.apache.cocoon.transformation.helpers.MirrorRecorder</em> - Different alternatives, e.g. ParamSaxBuffer</li>
+      
+</ul>
+    
+<h2>Request Lifecycle Components</h2>
+<p>
+        The deprecated class <em>org.apache.cocoon.components.RequestLifecycleComponent</em>
+        and the deprecated class <em>org.apache.cocoon.components.GlobalRequestLifecycleComponent</em>
+        have been removed. Use the <em>org.apache.cocoon.components.persistence.RequestDataStore</em>
+        component instead.
+      </p>
+  
+  
+<h1>Caching</h1>
+    
+<p>Although the basic caching mechanism is still the same (each sitemap component
+       in the pipeline is queried), the interfaces for a component have been
+       improved as well.</p>
+    
+<p>The following deprecated interfaces and classes have been removed from
+     the <em>org.apache.cocoon.caching</em> package:</p>
+     
+<ul>
+     
+<li>
+<em>Cacheable</em> : Use the <em>CacheableProcessingComponent</em> interface that is very similar.</li>
+     
+<li>
+<em>CacheValidity</em> : Is replaced by <em>SourceValidity</em>.</li>
+     
+<li>
+<em>AggregatedCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>CompositeCacheValidity</em> - Excalibur SourceResolver</li> 
+     
+<li>
+<em>DeltaTimeCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>IncludeCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>NOPCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>ParametersCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>TimeStampCacheValidity</em> - Excalibur SourceResolver</li>
+     
+<li>
+<em>CacheValidityToSourceValidity</em>
+</li>
+     
+<li>
+<em>SourceCacheValidity</em>
+</li>
+     
+<li>
+<em>CachedEventObject</em> : Is replaced by <em>CachedResponse</em>.</li>
+     
+<li>
+<em>CachedStreamObject</em> : Is replaced by <em>CachedResponse</em>.</li>
+     
+</ul>
+    
+<p>Some other interfaces and implementations, like the validity of the cached 
+      information have moved to the source packacke in Avalon Excalibur.</p>
+  
+
+<!--
+  <s1 title="Components">
+   <p>
+    The Cocoon architecture has changed significantly. However, great care has been
+    taken to preserve backwards compatibility.
+   </p>
+   <s2 title="Cocoon Configuration (cocoon.xconf)">
+    <p>In order to reflect the new version, the version information in the <em>cocoon.xconf</em>
+       has changed from <em>2.0</em> to <em>2.1</em>.
+    </p>
+    <p>To update <em>cocoon.xconf</em>, we recommend that you start with the new cocoon.xconf from V2.1 and
+       incorporate your changes in it, instead of trying to migrate your old configuration file.</p>
+     <p>The SAXConnectors have been removed, so if you upgrade manually you have to remove
+        the <em>sax-connectors</em> configuration from <em>cocoon.xconf</em>.</p>
+   </s2>
+   <s2 title="XSLT Processor">
+    <p>There are some issues related to JDK 1.4.</p>
+     <s3 title="XML/XSLT with JDK 1.4">
+      <p>Another serious issue is the presence of the Xalan and Xerces
+       package in the JDK 1.4. For general information on this please read the
+       <link href="http://xml.apache.org/xalan-j/faq.html#jdk14">Xalan FAQ</link> and our own
+       <link href="http://wiki.apache.org/cocoon/EndorsedLibsProblem">EndorsedLibsProblem</link>
+       wiki page.
+      </p>
+      <p>
+       Basically, you have to update your libraries in the endorsed dirs of the JDK
+       or the servlet containers with every new version of Xalan and Xerces delivered with Cocoon.
+       Strange errors can occur if you have different versions of these packages in the
+       classpath (independent of those in the JDK).
+      </p>
+     </s3>
+   </s2>
+   <s2 title="XML Parser">
+    <p>The XML parser component has been moved to Excalibur.
+     In cocoon.xconf, the hint name has therefore changed from <em>parser</em> to
+     <em>xml-parser</em>. The configuration has not changed, so changing the hint
+     names is sufficent.</p>
+    <p>Java code should not use
+      <em>org.apache.cocoon.components.parser.Parser.ROLE</em> anymore; use
+      <em>org.apache.excalibur.xml.sax.SAXParser.ROLE</em> instead.
+    </p>
+   </s2>
+   <s2 title="XML Entity Resolver">
+    <p>Similarly, the XML entity resolver component has been moved to Excalibur.
+     In cocoon.xconf the hint name has therefore changed from <em>resolver</em> to
+     <em>entity-resolver</em>. The configuration has not changed, so changing the hint
+     names is sufficent.</p>
+    <p>Java code should not use
+      <em>org.apache.cocoon.components.resolver.Resolver.ROLE</em> anymore; use
+      <em>org.apache.excalibur.xml.EntityResolver.ROLE</em> instead.
+    </p>
+    <p>The default entities (DTDs, entity sets, etc.) have moved to the
+     WEB-INF/ directory.
+    </p>
+   </s2>
+   <s2 title="Stores">
+    <p>The Store and StoreJanitor components and implementations have been moved to
+       Avalon Excalibur.</p>
+    <p>To make upgrading easier, the class attributes of the store janitor 
+       component have been removed in <em>cocoon.xconf</em> as the class names have changed.
+       The <em>cache-transient</em> and <em>cache-persistent</em> components do
+       not exist anymore, so any reference to them must be removed from cocoon.xconf.
+       Use the <em>persistent-store</em> and <em>transient-store</em> components instead.
+    </p>
+    <p>In general the package names changed from <em>org.apache.cocoon.components.store</em>
+       to <em>org.apache.excalibur.store</em> (and <em>org.apache.excalibur.store.impl</em>). So
+       if you have custom java code using these components, you have to change
+       your imports.</p>
+    <p>The roles <em>PERSISTENT_CACHE</em> and <em>TRANSIENT_CACHE</em> have been renamed to
+       <em>PERSISTENT_STORE</em> and <em>TRANSIENT_STORE</em>. The hold() method has been removed
+       from the Store interface.</p>
+   </s2>
+   <s2 title="SAXConnectors, Stream and Event Pipeline">
+    <p>This is the only real incompatible change (But don't panic, this will
+       not affect you, or maybe just a little bit..).
+    </p>
+    <p>
+       The internal architecture of Cocoon
+       has changed: previously, the processing pipeline - consisting of
+       a generator, the transformers and a serializer - was represented by two components,
+       called <em>stream</em> and <em>event pipeline</em>.</p>
+    <p>For a simpler architecture, enhanced functionality and improved performance,
+       these components have been combined into one: the <em>processing pipeline</em>.
+       The <em>SAXConnectors</em>, which were rarely used, have been removed
+       to avoid overcomponentization.</p>
+   </s2>
+   <s2 title="File Upload">
+     <p>The class name for file upload has changed from <em>org.apache.cocoon.components.request.multipart.FilePart</em> to
+        <em>org.apache.cocoon.servlet.multipart.Part</em>, and the <em>getFilePath()</em> has been renamed
+        <em>Part.getUploadName()</em>.
+     </p>
+   </s2>
+   <s2 title="RequestLifeCycleComponent">
+    <p>If you are using the marker interface <em>RequestLifeCycleComponent</em> for your
+    own components, you have to make sure that your implementations still implement
+    the <em>Component</em> interface. The <em>RequestLifeCycleComponent</em> does no
+    longer extend the <em>Component</em> interface, so you have to declare it in your
+    own components together with <em>RequestLifeCycleComponent</em>. Otherwise you
+    will get a <em>ClassCastException</em> as soon as you access your component.</p>
+   </s2>
+  </s1>
+  -->
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/meta.xml
new file mode 100644
index 0000000..3697dc6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating-to-2.2/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>plan/updating.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/content_en.html
new file mode 100644
index 0000000..2bdd559
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/content_en.html
@@ -0,0 +1,361 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Updating Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="J&ouml;rg Heinicke" name="DC.Creator">
+<meta content="Bertrand Delacr&eacute;taz" name="DC.Creator">
+</head>
+<body>
+  
+<h1>Known Issues for 2.1.5</h1>
+   
+<p>
+     This is a list of known issues for Cocoon 2.1.5.
+   </p>
+   
+<h2>Store</h2>
+<p>
+      Cocoon 2.1.5 uses different implementation of the store based on the
+      <a class="external" href="http://jakarta.apache.org/turbine/jcs">JCS</a>.
+      This new implementation currently does not allow storing of not serializable objects,
+      and it does not write out memory cache to the disk on shutdown. If you depend on
+      this functionality, you can keep 2.1.4 store configuration.
+     </p>
+<p>
+      Cocoon 2.1.4 used MRUMemoryStore as store implementation and JISPStore as persistent
+      store implementation. JISPStore is known to corrupt storage file under some
+      conditions.
+     </p>
+   
+<h2>Logging Configuration</h2>
+<p>
+      Cocoon 2.1.5 uses a newer version of the Avalon Excalibur logging package
+      than version 2.1.4. Unfortunately this logging package has an imcompatibility
+      to the version used in Cocoon 2.1.4.
+     </p>
+<p>
+      If you update your application from 2.1.4 to 2.1.5 make sure that you have
+      a log definition for the empty category in your logkit.xconf. Add the following
+      lines to your category definition:
+     </p>
+<pre class="code">
+    &lt;category name="" log-level="@loglevel@"&gt;
+      &lt;log-target id-ref="core"/&gt;
+      &lt;log-target id-ref="error"/&gt;
+    &lt;/category&gt;
+     </pre>
+  
+
+  
+<h1>Updating Cocoon</h1>
+   
+<p>
+    Please take your time to read this document completely before trying to upgrade from
+    a Cocoon 2.0.x installation to 2.1 (or above). You can also read it if you want to
+    know what was going on in the development of Cocoon.
+   </p>
+   
+<p>
+    The Cocoon team took great care in making this new version as compatible as
+    possible. However, in order to achieve even more flexibility, usability and
+    performance, the internal architecure of Cocoon has been improved. Due to these
+    improvements it has not been possible to be compatible in every little detail.
+    If you follow the instructions of document closely, however,
+    you should be able to quickly upgrade your Cocoon 2.0.x installation.
+   </p>
+   
+<p>
+    The Cocoon team has developed many Avalon components that are not specific to Cocoon
+    and therefore have been donated to the Avalon Excalibur project and moved out
+    of Cocoon. This has led to some configuration changes which are also described
+    in this document.
+   </p>
+  
+  
+<h1>Sitemap</h1>
+   
+<div class="note">There are some changes in the sitemap and in the configuration of some
+    components in the sitemap. In general we recommend you to start with a new
+    sitemap from 2.1 and to adapt it to your needs. But for manual migration we
+    will list as many changes as possible.</div>
+   
+<h2>Pipelines configuration in the sitemap</h2>
+<p>
+      The configuration of the pipelines has moved from cocoon.xconf to the sitemap.
+      To update your installation, you have to remove the "event-pipeline" and "stream-pipeline"
+      section from your cocoon.xconf (see also the cocoon.xconf section) and add the
+      <span class="codefrag">map:pipes</span> section to the <span class="codefrag">map:components</span> section
+      of your sitemap. You can find the pipelines components definition in the sample
+      main sitemap of Cocoon. Here is an example:
+     </p>
+<pre class="code">
+&lt;map:sitemap&gt;
+ &lt;map:components&gt;
+      ...
+  &lt;map:pipes default="caching"&gt;
+   &lt;map:pipe name="caching"
+    src="org.apache.cocoon.components.pipeline.impl.CachingProcessingPipeline"/&gt;
+   &lt;map:pipe name="noncaching"
+    src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline"/&gt;
+  &lt;/map:pipes&gt;
+ &lt;/map:components&gt;
+   ...
+&lt;/map:sitemap&gt;
+     </pre>
+<p>You can choose these different pipeline implementations
+       in the <span class="codefrag">map:pipeline</span> section by specifying their <span class="codefrag">type</span> attribute:
+     </p>
+<pre class="code">
+&lt;map:sitemap&gt;
+  ...
+ &lt;map:pipelines&gt;
+  &lt;map:pipeline type="noncaching"&gt;
+   &lt;map:match pattern="welcome"&gt;
+                  ...
+   &lt;/map:match&gt;
+            ..
+  &lt;/map:pipeline&gt;
+ &lt;/map:pipelines&gt;
+&lt;/map:sitemap&gt;
+     </pre>
+<p>This is similar to choosing the type of a generator or any other sitemap component.
+       If the type attribute is omitted, the default configuration from the
+       <span class="codefrag">map:components</span> section is used.
+     </p>
+   
+<h2>FOP Serializer</h2>
+<p>Relative paths in FOP serializer's <span class="codefrag">&lt;user-config&gt;</span> are now resolved
+      relatively to the directory that contains the sitemap.</p>
+<p>All Cocoon URIs are supported too.</p>
+   
+<h2>Sitemap components</h2>
+<p>Some of the sitemap components have been removed from Cocoon sources, others were renamed.
+      If you have the old declaration in your sitemap, you will get
+      <span class="codefrag">ClassNotFoundException</span>s. Trial and error will probably be the fastest way for
+      removing them and getting a clean and working sitemap. Hopefully you are not using one of the
+      removed components. The following components are known to be removed or renamed:</p>
+<ul>
+     
+<li>
+      
+<span class="codefrag">o.a.c.XTTransformer</span> - use the TraxTransformer instead.
+     </li>
+     
+<li>
+      
+<span class="codefrag">o.a.c.webapps.authentication.selection.MediaSelector</span> - the full qualified class
+      name has changed to <span class="codefrag">o.a.c.webapps.session.selection.MediaSelector</span>.
+     </li>
+    
+</ul>
+   
+<h2>Error handling</h2>
+<p>The <span class="codefrag">map:handle-errors</span> section must now be a complete pipeline. This means the
+       old form</p>
+<pre class="code">
+    &lt;map:handle-errors&gt;
+      &lt;map:transform src="stylesheets/system/error2html.xsl"/&gt;
+      &lt;map:serialize status-code="404"/&gt;
+    &lt;/map:handle-errors&gt;
+  </pre>
+<p>is no longer valid, because the generator is missing. Therefore you can now describe
+     explicitely the error handling. The replacement of the above looks like the following:</p>
+<pre class="code">
+    &lt;map:handle-errors&gt;
+      &lt;map:generate type="notifying"/&gt;
+      &lt;map:transform src="stylesheets/system/error2html.xsl"/&gt;
+      &lt;map:serialize status-code="404"/&gt;
+    &lt;/map:handle-errors&gt;
+  </pre>
+<p>For a more detailed example have a look into the default sitemap delivered with Cocoon
+       sources or read the
+       <a href="../userdocs/concepts/errorhandling.html">documentation on error handling</a>.
+     </p>
+  
+  
+<h1>Namespace changes</h1>
+    
+<p>
+      In order to have consistent namespaces, some transformers and generators
+      (listed below) use new namespaces. If you use any of these components, you
+      will need to use the new namespaces.
+    </p>
+    
+<h2>Request Generator</h2>
+<p>RequestGenerator changed its namespace from
+      <span class="codefrag">http://xml.apache.org/cocoon/requestgenerator/2.0</span> to
+      <span class="codefrag">http://apache.org/cocoon/request/2.0</span>.
+    </p>
+    
+<h2>I18nTransformer</h2>
+<p>The I18nTransformer supports both
+         <span class="codefrag">http://apache.org/cocoon/i18n/2.0</span> and
+         <span class="codefrag">http://apache.org/cocoon/i18n/2.1</span> namespace.</p>
+  
+  
+<h1>Changes in logging interfaces require recompilation</h1>
+    
+<p>
+       Due to some interface changes in the Cocoon logging components, custom java
+       components (generators, transformers or actions for example) compiled for Cocoon
+       2.0.x will not run under Cocoon 2.1 unless recompiled.</p>
+       
+<p>It's also advisable to change your implementations from using <em>Loggable</em>
+         to <em>LogEnabled</em> when it comes to logging in your components.
+       </p>
+  
+  
+<h1>Components</h1>
+   
+<p>
+    The Cocoon architecture has changed significantly. However, great care has been
+    taken to preserve backwards compatibility.
+   </p>
+   
+<h2>Cocoon Configuration (cocoon.xconf)</h2>
+<p>In order to reflect the new version, the version information in the <em>cocoon.xconf</em>
+       has changed from <em>2.0</em> to <em>2.1</em>.
+    </p>
+<p>To update <em>cocoon.xconf</em>, we recommend that you start with the new cocoon.xconf from V2.1 and
+       incorporate your changes in it, instead of trying to migrate your old configuration file.</p>
+<p>The SAXConnectors have been removed, so if you upgrade manually you have to remove
+        the <em>sax-connectors</em> configuration from <em>cocoon.xconf</em>.</p>
+   
+<h2>Source Resolver</h2>
+<p>
+      Every sitemap component gets a SourceResolver from the sitemap processor.
+      For all other components that need access to a SourceResolver, the SourceResolver 
+      is now an Avalon component that can be accessed using <em>cocoon.manager.lookup(SourceResolver.ROLE).</em>.
+      The package name of the component is <em>org.apache.excalibur.source</em>.
+    </p>
+   
+<h2>XSLT Processor</h2>
+<p>There are some issues related to JDK 1.4.</p>
+<h3>XML/XSLT with JDK 1.4</h3>
+<p>Another serious issue is the presence of the Xalan and Xerces
+       package in the JDK 1.4. For general information on this please read the
+       <a class="external" href="http://xml.apache.org/xalan-j/faq.html#jdk14">Xalan FAQ</a> and our own
+       <a class="external" href="http://wiki.apache.org/cocoon/EndorsedLibsProblem">EndorsedLibsProblem</a>
+       wiki page.
+      </p>
+<p>
+       Basically, you have to update your libraries in the endorsed dirs of the JDK
+       or the servlet containers with every new version of Xalan and Xerces delivered with Cocoon.
+       Strange errors can occur if you have different versions of these packages in the
+       classpath (independent of those in the JDK).
+      </p>
+   
+<h2>XML Parser</h2>
+<p>The XML parser component has been moved to Excalibur.
+     In cocoon.xconf, the hint name has therefore changed from <em>parser</em> to
+     <em>xml-parser</em>. The configuration has not changed, so changing the hint
+     names is sufficent.</p>
+<p>Java code should not use
+      <em>org.apache.cocoon.components.parser.Parser.ROLE</em> anymore; use
+      <em>org.apache.excalibur.xml.sax.SAXParser.ROLE</em> instead.
+    </p>
+   
+<h2>XML Entity Resolver</h2>
+<p>Similarly, the XML entity resolver component has been moved to Excalibur.
+     In cocoon.xconf the hint name has therefore changed from <em>resolver</em> to
+     <em>entity-resolver</em>. The configuration has not changed, so changing the hint
+     names is sufficent.</p>
+<p>Java code should not use
+      <em>org.apache.cocoon.components.resolver.Resolver.ROLE</em> anymore; use
+      <em>org.apache.excalibur.xml.EntityResolver.ROLE</em> instead.
+    </p>
+<p>The default entities (DTDs, entity sets, etc.) have moved to the
+     WEB-INF/ directory.
+    </p>
+   
+<h2>Caching</h2>
+<p>Although the basic caching mechanism is still the same (each sitemap component
+       in the pipeline is queried), the interface for a component have been
+       improved as well.</p>
+<p>The old interface <em>Cacheable</em> is deprecated in favour of the new
+      <em>CacheableProcessingComponent</em> interface. The basic behaviour of this
+      interface has been preserved, however the method names and the signatures
+      have changed a little bit.
+      </p>
+<p>Some other interfaces, like the validity of the cached information has
+      moved to the source packacke in Avalon Excalibur.</p>
+<p>The old interfaces are still support but deprecated, so it's advisable to
+      update your components. However, you can support both interfaces at the
+      same time, making your component runable in old and new Cocoon installations
+      at the same time.</p>
+   
+<h2>Stores</h2>
+<p>The Store and StoreJanitor components and implementations have been moved to
+       Avalon Excalibur.</p>
+<p>To make upgrading easier, the class attributes of the store janitor
+       component have been removed in <em>cocoon.xconf</em> as the class names have changed.
+       The <em>cache-transient</em> and <em>cache-persistent</em> components do
+       not exist anymore, so any reference to them must be removed from cocoon.xconf.
+       Use the <em>persistent-store</em> and <em>transient-store</em> components instead.
+    </p>
+<p>In general the package names changed from <em>org.apache.cocoon.components.store</em>
+       to <em>org.apache.excalibur.store</em> (and <em>org.apache.excalibur.store.impl</em>). So
+       if you have custom java code using these components, you have to change
+       your imports.</p>
+<p>The roles <em>PERSISTENT_CACHE</em> and <em>TRANSIENT_CACHE</em> have been renamed to
+       <em>PERSISTENT_STORE</em> and <em>TRANSIENT_STORE</em>. The hold() method has been removed
+       from the Store interface.</p>
+   
+<h2>SAXConnectors, Stream and Event Pipeline</h2>
+<p>This is the only real incompatible change (But don't panic, this will
+       not affect you, or maybe just a little bit..).
+    </p>
+<p>
+       The internal architecture of Cocoon
+       has changed: previously, the processing pipeline - consisting of
+       a generator, the transformers and a serializer - was represented by two components,
+       called <em>stream</em> and <em>event pipeline</em>.</p>
+<p>For a simpler architecture, enhanced functionality and improved performance,
+       these components have been combined into one: the <em>processing pipeline</em>.
+       The <em>SAXConnectors</em>, which were rarely used, have been removed
+       to avoid overcomponentization.</p>
+   
+<h2>File Upload</h2>
+<p>The class name for file upload has changed from <em>org.apache.cocoon.components.request.multipart.FilePart</em> to
+        <em>org.apache.cocoon.servlet.multipart.Part</em>, and the <em>getFilePath()</em> has been renamed
+        <em>Part.getUploadName()</em>.
+     </p>
+   
+<h2>RequestLifeCycleComponent</h2>
+<p>If you are using the marker interface <em>RequestLifeCycleComponent</em> for your
+    own components, you have to make sure that your implementations still implement
+    the <em>Component</em> interface. The <em>RequestLifeCycleComponent</em> does no
+    longer extend the <em>Component</em> interface, so you have to declare it in your
+    own components together with <em>RequestLifeCycleComponent</em>. Otherwise you
+    will get a <em>ClassCastException</em> as soon as you access your component.</p>
+  
+  
+<h1>Components from the scratchpad</h1>
+    
+<p>Cocoon 2.0.x had some components in the scratchpad area that have now moved into
+       the main trunk as blocks. With this move some things have changed.
+    </p>
+    
+<h2>Session, Authentication and Portal</h2>
+<p>The session framework (sunShine), the authentication framework (sunRise)
+         and the portal framework (sunSpot) are now blocks (session-fw, authentication-fw
+         and portal-fw).
+      </p>
+<p>The <em>sunShine transformer</em> has been renamed to <em>session transformer</em>.
+        All sitemap components starting with <em>sunrise-</em> have been changed to
+        start now with <em>auth-</em>. The <em>sunrise-auth</em> action has been
+        renamed to <em>auth-protect</em>.
+      </p>
+<p>
+      The transformer namespace has changed from <em>http://cocoon.apache.org/sunshine/1.0</em>
+      to <em>http://apache.org/cocoon/session/1.0</em> and the context names have changed
+      from <em>sunshine</em> to <em>session</em> and from <em>sunrise</em> to
+      <em>authentication</em>.
+      </p>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/meta.xml
new file mode 100644
index 0000000..0801205
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-updating/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>installing/updating.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/content_en.html
new file mode 100644
index 0000000..6ac98ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/content_en.html
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Views</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Christian Haul" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+</head>
+<body>
+  
+<h1>The Views</h1>
+   
+<p>
+    Apache Cocoon provides "views" to a resource.
+    Defining a pipeline in a sitemap specifies the different stages
+    of processing a resource. 
+    A view defines an exit point in the pipeline processing.
+   </p>
+   
+<p>
+    Views are yet another sitemap component. 
+    Unlike the rest, they are not inherited by sub-sitemaps and
+    they are orthogonal to the resource and pipeline definitions. 
+    In the following we will not distinguish between resources and pipelines
+    because their differences are not relevant here. So, when we talk
+    about pipelines the said is valid for resources as well.
+   </p>
+   
+<p>
+    Basically, views let you specify exit points of your pipelines
+    that are taken whenever a particular view is requested. The
+    processing continues with the definitions in the requested view. The
+    advantage over selectors that could achieve the same is, that these
+    exit points are not necessarily declared for each pipeline
+    individually, but once per sitemap.
+   </p>
+
+   
+<h2>Motivation</h2>
+<p>
+     Implementing a semantic search feature is the main motivation
+     to offer views in Apache Cocoon.
+    </p>
+<p>
+     A sitemap defines the URI space of a Cocoon application.
+     Apache Cocoon offers a fairly sophisticated URI space mapping mechanism.
+     Defining pipelines in a sitemap you define this mapping.
+     It's generally a mistake to map a file system 
+     (or a directory server, or a database repository) one-to-one
+     with the URI space, since it leads to easily broken links and potential
+     security issues. 
+    </p>
+<p>
+     Browsers requests resources of this URI space. 
+     The response of a browser request is normally intended for presenting
+     to a human being. It may be augmented with navigation controls, and advertisements.
+     An indexer of a search engines requests resources of this URI space, too.
+     In contrast to a browser an indexer is interested in the
+     bare content of a resource.
+    </p>
+<p>
+     Views can access the original content of a resource.
+     
+     For example, you can now index a document resource, 
+     requesting the "content" view of the resource lacking the aggregation 
+     with navigation controls, and advertisements.
+     
+     You can now index the text inside a logo, if you are given the SVG content 
+     that generated the raster image. 
+     You can index the PDF content without having to implement a PDF parser since you
+     request the "content" view of the resource obtaining an easily
+     parsable XML file.
+    </p>
+
+   
+<h2>Defining A View</h2>
+<p>
+     You declare a view in the sitemap. The definition of a view
+     may define further processing steps. You are not allowed to
+     define a generator step for a view, as the content of a view
+     is the xml content from a view's exit point.
+     The most simple view just serializes the xml content to xml.
+    </p>
+<p>
+     A view element is identified by its name, and its label. You
+     specify the name of a view by the attribute name, and its label either
+     by the attribute from-label, or by the attribute from-position.
+     The following list explains the attributes in more detail.
+    </p>
+<ul>
+     
+<li>
+      The attribute name specifies the name of view. Each view must have a unique name.
+      If you request a view you have to specify the view name.
+     </li>
+     
+<li>
+       The attribute from-label defines a label name of a pipeline exit point. 
+       You can choose any name you like, as a label name, except "first", and "last".
+     </li>
+     
+<li>
+       The attribute from-position may have only following values "first", and "last".
+       The special label "first" is the pipeline exit point after the generator
+       processing stage. 
+       The special label "last" is the pipeline exit point
+       right before the serializer processing stage.
+       The labels "first", and "last" are set by the sitemanager automatically.
+      </li>
+    
+</ul>
+<p>
+     The following example is a simple resource view, just serializing
+     the xml content of the view's exit point.
+    </p>
+<pre class="code">
+&lt;map:views&gt;
+ &lt;map:view name="content" from-label="content"&gt;
+ &lt;map:serialize type="xml"/&gt;
+&lt;/map:view&gt;</pre>
+<p>
+     The next example performs an xslt transformation
+     before serializing to xml.
+    </p>
+<pre class="code">
+&lt;map:views&gt;
+ &lt;map:view name="dublin-core" from-label="dublin-core"&gt;
+ &lt;map:transform src="stylesheets/document2dublin-core.xsl"/&gt;
+ &lt;map:serialize type="xml"/&gt;
+&lt;/map:view&gt;</pre>
+<p>
+     The last example defines a view specifying the position-from attribute "last",
+     and serializing to pdf, for a pdf-aware only indexer, or archiver.
+    </p>
+<pre class="code">
+&lt;map:views&gt;
+ &lt;map:view name="full-document-content" from-position="last"&gt;
+ &lt;map:transform src="stylesheets/document2fo.xsl"/&gt;
+ &lt;map:serialize type="fo2pdf"/&gt;
+&lt;/map:view&gt;</pre>
+   
+<h2>Placing Labels</h2>
+<p>
+     You place labels to define a pipeline exit point.
+     A pipeline exit point may be shared by more than a single view.
+    </p>
+<p>
+     Defining a pipeline exit point you have to add an attribute 
+     "label" to a sitemap element. The following sitemap elements are label aware:
+    </p>
+<table>
+     
+<tr>
+<th colspan="1" rowspan="1">Sitemap Element</th><th colspan="1" rowspan="1">Description</th>
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:generator</td>
+      <td colspan="1" rowspan="1">
+       A generator element is allowed to have a label, 
+       eg. <span class="codefrag">&lt;map:generator name="foo" src="bar" label="content"/&gt;</span>.
+       The xml content produced by the generator is passed to the requested view.
+       Moreover requesting a "first" view has the same effect as labelling the first
+       generator of pipeline.
+      </td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:generate</td>
+      <td colspan="1" rowspan="1">
+       A generate element is allowed to have a label attribute, 
+       eg. <span class="codefrag">&lt;map:generate type="foo" label="content"/&gt;</span>.
+       The xml content produced by the generator is passed to the requested view.
+       Moreover requesting a "first" view has the same effect as labelling the first
+       generator of pipeline.
+      </td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:transformer</td>
+      <td colspan="1" rowspan="1">
+       A transformer element is allowed to have a label attribute,
+       eg. <span class="codefrag">&lt;map:transformer name="foo" src="bar" label="augmented-content"/&gt;</span>.
+       The xml content produced by the transformer is passed to the requested view.
+      </td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:transform</td>
+      <td colspan="1" rowspan="1">
+       A transform element is allowed to have a label attribute,
+       eg. <span class="codefrag">&lt;map:transform type="foo" label="augmented-content"/&gt;</span>.
+       The xml content produced by the transformer is passed to the requested view.
+      </td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:aggregate</td>
+      <td colspan="1" rowspan="1">
+       An aggregte element is allowed to have a label attribute,
+       eg. <span class="codefrag">&lt;map:aggregate element="foo" label="all-news"/&gt;</span>.
+       The xml content produced by the aggregate is passed to the requested view.
+      </td>
+     
+</tr>
+     
+<tr>
+      
+<td colspan="1" rowspan="1">map:part</td>
+      <td colspan="1" rowspan="1">
+       A part element of an aggregate element is allowed to have a label attribute.
+       eg. <span class="codefrag">&lt;map:part src="foo" label="news-only"/&gt;</span>.
+       The xml content produced by the part only is passed to the requested view.
+      </td>
+     
+</tr>
+    
+</table>
+<p>
+     A label attribute may hold 1 or more label names, separated by comma or blank,
+     eg. <span class="codefrag">&lt;map:generate src="foo" label="label1, label2"/&gt;</span>.
+    </p>
+   
+   
+<h2>Placing Labels Summary</h2>
+<p>
+     As described above you have a wide range of choice for placing labels.
+     You may even place labels to part elements, and to pipelines 
+     being the source of a labelled part element. The following paragraphs 
+     summarize some of the hot features.
+    </p>
+<p>
+     You can use more that one label-value (label="content,link rdf")
+     separated by comma or blank.
+    </p>
+<p>
+     The aggregate element can have a label attribute which acts
+     as on a generator, or transformer (all part elements are collected).
+    </p>
+<p>
+     Part elements can have a label attribute. In this case only
+     those parts are collected which corresponds to the requested view.
+    </p>
+<p>
+     If you refer to sources via the cocoon:/ protocol the requested view
+     will be propagated.
+    </p>
+<div class="note">
+     The element label is deprecated, and being not supported anymore.
+     Thus you have to rewrite your sitemap if you are using 
+     <span class="codefrag">&lt;map:label name="foobar"/&gt;</span>.
+    </div>
+<p>
+     Rewrite your sitemap if you were using label elements, moving the label name
+     up to the previous xml producer.
+     For example rewrite your sitemap:
+    </p>
+<pre class="code">
+...
+&lt;map:generate src="foo"/&gt;
+&lt;map:transform type="bar"/&gt;
+&lt;map:label name="mylabel"/&gt;
+&lt;map:serialize/&gt;
+...</pre>
+<p>
+     ...to this sitemap:
+    </p>
+<pre class="code">
+...
+&lt;map:generate src="foo"/&gt;
+&lt;map:transform type="bar" label="mylabel"/&gt;
+&lt;map:serialize/&gt;
+...</pre>
+   
+<h2>View Processing</h2>
+<p>
+     The samples sitemap contains two view definitions. One of them
+     looks like the excerpt below.
+    </p>
+<pre class="code">
+&lt;map:views&gt;
+ &lt;map:view name="content" from-label="content"&gt;
+ &lt;map:serialize type="xml"/&gt;
+&lt;/map:view&gt;</pre>
+<p>
+     It only defines what processing steps should be taken, after some
+     exit point labelled "content" is reached. In all this case just a 
+     serializer is used to further process the document.
+    </p>
+   
+   
+<h2>Exit Points</h2>
+<p>
+     A look at the pipelines reveals no label "content". But a closer
+     look at the defined components show this:
+    </p>
+<pre class="code">
+&lt;map:components&gt;
+
+ &lt;map:generators default="file"&gt;
+  &lt;map:generator name="file"        
+                 src="org.apache.cocoon.generation.FileGenerator"
+                 label="content"/&gt;
+  &lt;map:generator name="directory"   
+                 src="org.apache.cocoon.generation.DirectoryGenerator"
+                 label="content"/&gt;
+  &lt;map:generator name="serverpages" 
+                 src="org.apache.cocoon.generation.ServerPagesGenerator"
+                 label="content"/&gt;
+  ...</pre>
+<p>
+     Here a number of generators are declared, each one has a label
+     attribute. Now, everytime one of these generators is used in a
+     pipeline, an exit point "content" is generated, just after the
+     generator has been executed.
+    </p>
+<p>
+     This is not limited to generators - every sitemap component can
+     be augmented with a view label.
+    </p>
+<p>
+     Two special labels exist: "first" and "last". These are
+     automatically declared for every pipeline, after the first component
+     and after the last respectively. This is used by the second view in
+     the samples sitemap.
+    </p>
+<pre class="code">
+&lt;map:view name="links" from-position="last"&gt;
+ &lt;map:serialize type="links"/&gt;
+&lt;/map:view&gt;</pre>
+  
+   
+<h2>Requesting A View</h2>
+<p>
+     The current way for Cocoon to access views is fixed as a special URI
+     query parameter <span class="codefrag">cocoon-view</span>.
+    </p>
+<p>
+     For example querying the view <span class="codefrag">content</span> of the page:
+    </p>
+<pre class="code">http://localhost:8080/cocoon/documents/index.html</pre>
+<p>
+     You use following URL:
+    </p>
+<pre class="code">http://localhost:8080/cocoon/documents/index.html?cocoon-view=content</pre>
+<p>
+     Suggestions for further accessing views are:
+    </p>
+<ul>
+     
+<li>
+      React on a "variant" HTTP header (nothing cocoon specific since the
+      concept could be impelemented later on by other publishing frameworks).
+     </li>
+     
+<li>
+      React on URI extension: for example <span class="codefrag">http://host/path/file.view</span>,
+      that is something that can be done by configuring the sitemaps manually.
+      (where <span class="codefrag">http://host/path/index</span> is the default resource,
+      and <span class="codefrag">index.content</span> is the XML view of the content).
+     </li>
+    
+</ul>
+   
+<div class="note">
+    Since views are orthogonal to pipelines, keep in mind to
+    remove any unwanted view from a deployed application.
+   </div>
+  
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/meta.xml
new file mode 100644
index 0000000..2619cc9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-views/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/concepts/views.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/content_en.html
new file mode 100644
index 0000000..09f88fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/content_en.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>VRML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the vrml serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>VRML Serializer</h1>
+      
+<p>????.</p>
+      
+<ul>
+        
+<li>Name : vrml</li>
+        
+<li>Class: org.apache.cocoon.serialization.TextSerializer</li>
+        
+<li>Cacheable: yes.</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/meta.xml
new file mode 100644
index 0000000..07431cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-vrml-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/vrml-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/content_en.html
new file mode 100644
index 0000000..1d03b68
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/content_en.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>WML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the WML serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>WML Serializer</h1>
+    
+<p>
+      The WML serializer serializes sax events to WML.
+      The output of the WML serializer is a WML document.
+    </p>
+    
+<ul>
+      
+<li>Name : wml</li>
+      
+<li>Class: org.apache.cocoon.serialization.XMLSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        The WML serializer is declared in the sitemap serializers section.
+      </p>
+<pre class="code">
+&lt;map:serializers ...
+...
+   &lt;map:serializer name="wml" 
+     src="org.apache.cocoon.serialization.XMLSerializer"
+     mime-type="text/vnd.wap.wml" 
+     logger="sitemap.serializer.wml"&gt;
+    &lt;doctype-public&gt;-//WAPFORUM//DTD WML 1.1//EN&lt;/doctype-public&gt;
+    &lt;doctype-system&gt;http://www.wapforum.org/DTD/wml_1.1.xml&lt;/doctype-system&gt;
+   &lt;/map:serializer&gt;
+...
+      </pre>
+<p>
+        The declaration of the WML serializer shall use following 
+        XML serializer configuration parameters
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Name</th><th colspan="1" rowspan="1">Value</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-public</td><td colspan="1" rowspan="1">-//WAPFORUM//DTD WML 1.1//EN</td>
+          <td colspan="1" rowspan="1">specifies the WML public document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-system</td><td colspan="1" rowspan="1">http://www.wapforum.org/DTD/wml_1.1.xml</td>
+          <td colspan="1" rowspan="1">specifies the WML system document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">mime-type</td><td colspan="1" rowspan="1">text/vnd.wap.wml</td>
+          <td colspan="1" rowspan="1">specifies mime-type of the serialized WML document.
+          </td>
+        
+</tr>
+      
+</table>
+    
+<h2>Pipeline Usage</h2>
+<p>
+        Using the WML Serializer in a pipeline is just setting the 
+        serializer type to wml. 
+        The following code snippet uses the WML Serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="*.wml"&gt;
+...
+  &lt;map:serialize type="wml"/&gt;
+&lt;/map:match&gt;
+...
+      </pre>
+    
+<h2>Further Reading</h2>
+<p>
+        As WML serializer uses the XML serializer internally, you might 
+        want to read the complete list of valid XML configuration parameters.
+        It is available at <a href="xml-serializer.html">XML serializer</a>
+        user docuementation.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/meta.xml
new file mode 100644
index 0000000..fe0df25
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wap-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/wap-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/content_en.html
new file mode 100644
index 0000000..695f0b7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/content_en.html
@@ -0,0 +1,197 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Who we are</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Davanum Srinivas" name="DC.Creator">
+</head>
+<body>
+
+ 
+<h1>Who we are</h1>
+  
+<p>
+    The Apache Cocoon Project operates on a meritocracy: the more you do, the more 
+    responsibility you will obtain. This page lists all of the people who have 
+    gone the extra mile and are Committers. If you would like to get involved, 
+    the first step is to join the mailing lists. 
+  </p>
+
+  
+<p>
+    We ask that you please do not send us emails privately asking for support. 
+    We are non-paid volunteers who help out with the project and we do not 
+    necessarily have the time or energy to help people on an individual basis. 
+    Instead, we have setup mailing lists which often contain hundreds of 
+    individuals who will help answer detailed requests for help. The benefit of 
+    using mailing lists over private communication is that it is a shared 
+    resource where others can also learn from common mistakes and as a 
+    community we all grow together. 
+  </p>
+
+  
+<h2>Active Committers</h2>
+<p>
+    This list contains all currently active committers
+    in strict alphabetical order.
+    </p>
+<ul>
+      
+<li>Nicola Ken Barozzi (nicolaken.at.apache.org) [blocks]</li>
+
+<li>Arj&eacute; Cahn (arje.at.apache.org)</li>
+
+<li>Guido Casper (gcasper.at.apache.org)</li>
+      
+<li>Ugo Cei (ugo.at.apache.org)</li>
+      
+<li>Tony Collen (tony.at.apache.org)</li>
+      
+<li>Marcus Crafter (crafterm.at.apache.org)</li>
+      
+<li>David Crossley (crossley.at.apache.org)</li>
+      
+<li>Torsten Curdt (tcurdt.at.apache.org)</li>
+      
+<li>Bertrand Delacr&eacute;taz (bdelacretaz.at.apache.org)</li>
+      
+<li>Bruno Dumon (bruno.at.apache.org)</li>
+      
+<li>Daniel Fagerstr&ouml;m (danielf.at.apache.org)</li>
+      
+<li>Pier Fumagalli (pier.at.apache.org)</li>
+      
+<li>Antonio Gallardo (antonio.at.apache.org)</li>
+      
+<li>Leszek Gawron (lgawron.at.apache.org)</li>
+      
+<li>Ralph Goers (rgoers.at.apache.org)</li>
+      
+<li>Vadim Gritsenko (vgritsenko.at.apache.org)</li>
+      
+<li>Christian Haul (haul.at.apache.org)</li>
+      
+<li>J&ouml;rg Heinicke (joerg.at.apache.org)</li>
+      
+<li>Unico Hommes (unico.at.apache.org)</li>
+      
+<li>Geoff Howard (ghoward.at.apache.org)</li>
+      
+<li>Bernhard Huber (huber.at.apache.org)</li>
+      
+<li>Ivelin Ivanov (ivelin.at.apache.org)</li>
+      
+<li>Matthew Langham (mlangham.at.apache.org)</li>
+      
+<li>Tim Larson (tim.at.apache.org)</li>
+
+<li>Helma van der Linden (hepabolu.at.apache.org)</li>
+      
+<li>Stefano Mazzocchi (stefano.at.apache.org)</li>
+      
+<li>Michael Melhem (michaelm.at.apache.org)</li>
+      
+<li>Stephan Michels (stephan.at.apache.org)</li>
+      
+<li>John Morrison (morrijr.at.apache.org)</li>
+
+<li>Alfred Nathaniel (anathaniel.at.apache.org)</li>
+      
+<li>Steven Noels (stevenn.at.apache.org)</li>
+      
+<li>Christopher Oliver (coliver.at.apache.org)</li>
+      
+<li>Giacomo Pati (giacomo.at.apache.org)</li>
+      
+<li>Konstantin Piroumian (kpiroumian.at.apache.org)</li>
+      
+<li>Reinhard P&ouml;tz(reinhard.at.apache.org)</li>      
+      
+<li>Marc Portier (mpo.at.apache.org)</li>      
+      
+<li>Ovidiu Predescu (ovidiu.at.apache.org)</li>
+      
+<li>Jeremy Quinn (jeremy.at.apache.org)</li>
+      
+<li>Gianugo Rabellino (gianugo.at.apache.org)</li>
+      
+<li>Peter Royal (proyal.at.apache.org)</li>
+      
+<li>Andrew Savory (asavory.at.apache.org)</li>
+      
+<li>Diana Shannon (shannon.at.apache.org)</li>
+      
+<li>Jeff Turner (jefft.at.apache.org)</li>
+      
+<li>Upayavira (upayavira.at.apache.org)</li>
+      
+<li>Sylvain Wallez (sylvain.at.apache.org)</li>
+      
+<li>Carsten Ziegeler (cziegeler.at.apache.org)</li>
+    
+</ul>
+
+  
+<h2>Inactive Committers</h2>
+<p>
+    This list contains all inactive committers in strict alphabetical order.
+    They do not consider themselves active currently, but are still 
+    somewhat involved in Cocoon and hope to return active again soon.
+    </p>
+<ul>
+      
+<li>Gerhard Froehlich (froehlich.at.apache.org)</li>
+      
+<li>Martin Man (mman.at.apache.org)</li>
+      
+<li>Davanum Srinivas (dims.at.apache.org)</li>
+    
+</ul>
+
+  
+<h2>Emeritus Committers</h2>
+<p>
+    This list contains all emeritus committers in strict alphabetical order.
+    They have not committed anything for some time, and consider 
+    themselves retired from active duty. 
+    We wish them well and hope to see them return.
+    </p>
+<ul>
+      
+<li>Zvi Avraham (zvia.at.apache.org)</li>
+      
+<li>Donald Ball (balld.at.apache.org)</li>
+      
+<li>Brian Behlendorf (brian.at.apache.org)</li>
+      
+<li>Ross Burton (rossb.at.apache.org)</li>
+      
+<li>Mark Butler (mark-h.butler.at.hp.com)</li>
+      
+<li>Steven Coffman (gears.at.apache.org)</li>
+      
+<li>Peter Donald (donaldp.at.apache.org)</li>
+      
+<li>Robin Green (greenrd.at.apache.org)</li>
+      
+<li>Ben Laurie (ben.at.apache.org)</li>
+      
+<li>Berin Loritsch (bloritsch.at.apache.org)</li>
+      
+<li>Brett McLaughlin (bmclaugh.at.apache.org)</li>
+      
+<li>Ricardo Rocha (ricardo.at.apache.org)</li>
+      
+<li>Sam Ruby (rubys.at.apache.org)</li>
+      
+<li>Paul Russell (prussell.at.apache.org)</li>
+      
+<li>Sebastien Sahuc (ssahuc.at.apache.org)</li>
+     
+</ul>
+ 
+
+
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/meta.xml
new file mode 100644
index 0000000..dca4d96
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-who/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>who.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/content_en.html
new file mode 100644
index 0000000..e2453d1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/content_en.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>WildcardHeader-Matcher in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the WildcardHeaderMatcher of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>WildcardHeaderMatcher</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">header-match, referer-match</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">WildcardHeaderMatcher</span> matches a header value
+            against a wildcard expression..
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Matcher, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where WildcardHeaderMatcher sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.matching.WildcardHeaderMatcher</td>
+        
+</tr>
+        <!-- uncomment folling tr iff WildcardHeaderMatcher is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">WildcardHeaderMatcher</span> matches a wildcard pattern against a 
+        header value of the request.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">WildcardHeaderMatcher</span> is used to apply the same sitemap processing
+        to a group of requested URIs. A requested URI belongs to this group iff
+        the header value is matched by the specified pattern.  
+      </p>
+      
+<p>
+        The snippet below applies to all requested URIs having a header referer value matching
+        the wildcard pattern <span class="codefrag">http://foo.bar:8080/documentation/*.html</span> the specified pipeline processing.
+      </p>
+      
+<p>
+        The generator retrieves the xml document having extension <span class="codefrag">.xml</span>,
+        its basename is the request URI path, stripped off the prefix <span class="codefrag">page-</span>.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The snippet below uses the <span class="codefrag">WildcardHeaderMatcher</span> for matching
+          the referer header value.
+        </p>
+<pre class="code">
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    ....
+    &lt;map:match type="referer-match" pattern=http://foo.bar:8080/documentation/*.html"&gt;
+      &lt;!-- pipeline processing generator, transformer, serializing
+      &lt;map:generator src="xdocs/{../1}.xml"/&gt;
+      &lt;map:transformer src="stylesheet/document2html"/&gt;
+        &lt;map:parameter name="prev" value="{1}.html"/&gt;
+      &lt;map:transformer/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:match&gt;
+    ...
+  &lt;/map:pipeline&gt;
+  ...
+        </pre>
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The <span class="codefrag">WildcardHeaderMatcher</span> sitemap configuration consists of
+          choosing a name, and specifying the src attribute of the fully qualified name of the 
+          WildcardHeaderMatcher class.
+        </p>
+<p>
+          Moreover sub element name <span class="codefrag">header-name</span> specifies the name of the
+          header. Its value is matched against the specified pattern.
+        </p>
+<pre class="code">
+&lt;map:matchers...
+  &lt;map:matcher name="referer-match" 
+    src="org.apache.cocoon.matching.WildcardHeaderMatcher"
+    logger="sitemap.matcher.referer-match" 
+  /&gt;
+    &lt;header-name&gt;referer&lt;/header-name&gt;
+    ...
+  &lt;/map:matcher&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          The <span class="codefrag">WildcardHeaderMatcher</span> is configured by the 
+          subelement <span class="codefrag">header-name</span>, specifying the name of the header attribute
+          name.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          The <span class="codefrag">WildcardHeaderMatcher</span> gets the wildcard pattern from
+          its pattern attribute.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          See a detailed discussion in
+          <a href="wildcarduri-matcher.html">WildcardURIMatcher</a>
+        
+</p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        The use of <span class="codefrag">parameter-name</span> instead of <span class="codefrag">header-name</span> is deprecated. 
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-28-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        A general documentation about matchers is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+      
+<p>
+        For a reference of available header names
+        see <a class="external" href="http://www.ietf.org/rfc/rfc2068.txt">RFC 2068</a>, especially
+        if Cocoon's run time environment is an http servlet environment. 
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/meta.xml
new file mode 100644
index 0000000..ff7cace
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcardheader-matcher/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/matchers/wildcardheader-matcher.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/content_en.html
new file mode 100644
index 0000000..247fee3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/content_en.html
@@ -0,0 +1,212 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>WildcardURI-Matcher in Cocoon</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the WildcardURIMatcher of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>WildcardURIMatcher</h1>
+      
+<table>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">NAME</td><td colspan="1" rowspan="1">wildcard</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">WHAT</td><td colspan="1" rowspan="1">The <span class="codefrag">WildcardURIMatcher</span> matches the request URI
+            against a wildcard expression..
+          </td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">TYPE</td><td colspan="1" rowspan="1">Matcher, Sitemap Component</td>
+        
+</tr>
+        
+<tr>
+          <!-- choose Core, the block name, or Scratchpad 
+            depending on where WildcardURIMatcher sources live
+          -->
+          
+<td colspan="1" rowspan="1">BLOCK</td><td colspan="1" rowspan="1">Core</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CLASS</td><td colspan="1" rowspan="1">org.apache.cocoon.matching.WildcardURIMatcher</td>
+        
+</tr>
+        <!-- uncomment folling tr iff WildcardURIMatcher is deprecated -->
+        <!--tr>
+          <td>DEPRECATED</td><td>Cocoon 2.0, 2.1</td>
+        </tr-->
+        
+<tr>
+          
+<td colspan="1" rowspan="1">SINCE</td><td colspan="1" rowspan="1">Cocoon 2.0</td>
+        
+</tr>
+        
+<tr>
+          
+<td colspan="1" rowspan="1">CACHEABLE</td><td colspan="1" rowspan="1">not applicable</td>
+        
+</tr>
+      
+</table>
+    
+    
+<h1>Description</h1>
+      
+<p>
+        The <span class="codefrag">WildcardURIMatcher</span> matches a wildcard pattern against
+        the requested URI.
+      </p>
+    
+    
+<h1>Usage</h1>
+      
+<p>
+        The <span class="codefrag">WildcardURIMatcher</span> is used to apply the same sitemap processing
+        to a group of requested URIs.  A requested URI belongs to this group iff
+        the requested URI is matched by the specified pattern.
+      </p>
+      
+<p>
+        The snippet below applies to all requested URIs matching
+        the wildcard pattern <span class="codefrag">page-*.html</span> the same specified pipeline processing.
+        The generator retrieves the xml document having extension <span class="codefrag">.xml</span>, and
+        its basename evaluated from the requested URI path, stripped off the prefix <span class="codefrag">page-</span>.
+      </p>
+      
+<h2>Sitemap pipeline examples</h2>
+<p>
+          The snippet below uses the <span class="codefrag">WildcardURIMatcher</span> for matching
+          requested URIs of the form <span class="codefrag">page-*.html</span>.
+        </p>
+<pre class="code">
+&lt;map:pipelines&gt;
+  &lt;map:pipeline&gt;
+    &lt;map:match pattern="page-*.html"&gt;
+      &lt;!-- pipeline processing generator, transformer, serializing
+      &lt;map:generator src="xdocs/{1}.xml"/&gt;
+      &lt;map:transformer src="stylesheet/document2html"/&gt;
+      &lt;map:serialize/&gt;
+    &lt;/map:match&gt;
+  &lt;/map:pipeline&gt;
+  ...
+        </pre>
+      
+<h2>Sitemap component configuration example</h2>
+<p>
+          The <span class="codefrag">WildcardURIMatcher</span> sitemap configuration consists of
+          choosing a name, and specifying the src attribute of the fully qualified name of the 
+          WildcardURIMatcher class.
+        </p>
+<pre class="code">
+&lt;map:matchers...
+  &lt;map:matcher name="template" 
+    src="org.apache.cocoon.matching.WildcardURIMatcher"
+    logger="sitemap.matcher.template" 
+    pool-max="32"/&gt;
+  &lt;/map:matcher&gt;
+...
+</pre>
+      
+<h2>Configuration</h2>
+<p>
+          The <span class="codefrag">WildcardURIMatcher</span> has no extra configuration as already
+          mentioned above.
+        </p>
+      
+<h2>Setup</h2>
+<p>
+          The <span class="codefrag">WildcardURIMatcher</span> gets its wildcard pattern from
+          the pattern attribute.
+        </p>
+      
+<h2>Effect on Object Model and Sitemap Parameters</h2>
+<p>
+          The <span class="codefrag">WildcardURIMatcher</span> accepts wildcard patterns. 
+          Wildcard patterns uses following matching algorithm
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Pattern Token</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">**</td><td colspan="1" rowspan="1">Matches zero or more characters including the slash ('/') character</td>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">*</td><td colspan="1" rowspan="1">Matches zero or more characters excluding the slash ('/') character</td>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">\ character </td><td colspan="1" rowspan="1">The backslash character is used as escape sequence.
+            Thus \* matches the character asterisk ('*'), and \\ matched the character backslash ('\').</td>
+          
+</tr>
+        
+</table>
+<p>
+          The pattern '**' has higher precedence that two consecutive '*' patterns.
+        </p>
+<p>
+          If matching succeeds <span class="codefrag">WildcardURIMatcher</span> returns a <span class="codefrag">Map</span>
+          object. The entries of the map are the matched wildcard variable parts of the pattern.
+          Accessing these matched values is accomplished by using sitemap parameter
+          name of <em>{N}</em>. The N is ordinal number of matched variable part, starting
+          with 0. The expression <span class="codefrag">{0}</span> represents the complete request URI, the
+          expression <span class="codefrag">{1}</span> represents the first matched wildcard value, the expression
+          <span class="codefrag">{2}</span> represents the second, etc.
+        </p>
+<p>
+          In case of nested matchers, or actions the parent <span class="codefrag">Map</span> entries
+          are referencable by using <span class="codefrag">../</span> prefix. Thus referencing the 
+          first wildcard matched value of a parent matcher in a child matcher it
+          is expressed as <span class="codefrag">{../1}</span>.
+        </p>
+<p>
+          In the snippet above <span class="codefrag">xdocs/{1}.xml</span> is expanded to <span class="codefrag">xdocs/index.xml</span>,
+          if the requested URI was <span class="codefrag">page-index.html</span>.
+        </p>
+    
+    
+<h1>Bugs/Caveats</h1>
+      
+<p>
+        If a request URI starts with slash ('/'), the slash character is stripped off. 
+      </p>
+    
+    
+<h1>History</h1>
+      
+<p>
+        12-28-02: initial creation
+      </p>
+    
+    
+<h1>See also</h1>
+      
+<p>
+        A general documentation about matchers is available at
+        <a href="../concepts/matchers_selectors.html">Matchers and Selectors</a>.
+      </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/meta.xml
new file mode 100644
index 0000000..1140aef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-wildcarduri-matcher/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/matchers/wildcarduri-matcher.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/content_en.html
new file mode 100644
index 0000000..f0e0ca4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/content_en.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Write DOM Session Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Sven Beauprez" name="DC.Creator">
+<meta content="Davanum Srinivas" name="DC.Creator">
+<meta content="This document describes the write dom session transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Write DOM Session Transformer</h1>
+      
+<p>Make a DOM object from SAX events and write it to the session.</p>
+      
+<ul>
+        
+<li>Name : writeDOMsession</li>
+        
+<li>Class: org.apache.cocoon.transformation.WriteDOMSessionTransformer</li>
+        
+<li>Cacheable: no.</li>
+      
+</ul>
+
+<p>
+If you only use the FilterTransformer in combination with the SQLTransformer, 
+you have to query the database each time the user wants to see another part of 
+the result. You can better store the result in the session after the first 
+request and retrieve the result from the session for the subsequent requests. 
+This can be done by using a selector, which checks if the data is available in 
+the session or not.
+</p>
+
+<p>
+WriteDOMSessionTransformer can build a DOM starting from a given element (which 
+will be the root of the DOM tree) and store it in the session. If you want to 
+store the result of a query, you have to add following to the sitemap:
+</p>
+    
+<pre class="code">
+     
+      &lt;map:transform type="writeDOMsession"&gt;
+        &lt;map:parameter name="dom-name" value="DBresult"/&gt;
+        &lt;map:parameter name="dom-root-element" value="rowset"/&gt;
+      &lt;/map:transform&gt;
+     
+    </pre>
+
+<p>
+The transformer will build a DOM tree with rowset as root element and will store 
+it in the session with the name "DBresult".
+</p>
+
+<p>
+Note: most of the times, it is not smart to keep the output XML of the 
+SQLTransformer in the session. Check if it is better to do the necessary 
+transformations first, so that you get a smaller DOM, and then put the result in 
+the session. You probably will be able to use the FilterTransformer on the 
+transformed XML also.
+</p>
+
+<p>
+The WriteDOMSessionTransformer is a standalone component, you don't need to use 
+it in combination with the SQLTransformer.
+</p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/meta.xml
new file mode 100644
index 0000000..f9c75be
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-writedomsession-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/writedomsession-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/content_en.html
new file mode 100644
index 0000000..6fe21b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/content_en.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XHTML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the XHTML serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+  
+<h1>XHTML Serializer</h1>
+    
+<p>
+      The XHTML serializer serializes sax events to XHTML.
+      The output of the XHTML serializer is XHTML.
+    </p>
+    
+<ul>
+      
+<li>Name : xhtml</li>
+      
+<li>Class: org.apache.cocoon.serialization.XMLSerializer</li>
+      
+<li>Cacheable: yes</li>
+    
+</ul>
+    
+<h2>Sitemap Configuration</h2>
+<p>
+        The XHTML serializer is declared in the sitemap serializers section.
+      </p>
+<pre class="code">
+&lt;map:serializers ...
+...
+   &lt;map:serializer name="xhtml"
+     src="org.apache.cocoon.serialization.XMLSerializer"
+     mime-type="text/html" 
+     logger="sitemap.serializer.xhtml"
+     pool-max="64"
+     &gt;
+     &lt;doctype-public&gt;-//W3C//DTD XHTML 1.0 Strict//EN&lt;/doctype-public&gt;
+     &lt;doctype-system&gt;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&lt;/doctype-system&gt;
+     &lt;encoding&gt;UTF-8&lt;/encoding&gt;
+   &lt;/map:serializer&gt;
+...
+      </pre>
+<p>
+        The declaration of the XHTML serializer shall use following 
+        XML serializer configuration parameters
+      </p>
+<table>
+        
+<tr>
+<th colspan="1" rowspan="1">Name</th><th colspan="1" rowspan="1">Value</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-public</td><td colspan="1" rowspan="1">-//W3C//DTD XHTML 1.0 Strict//EN</td>
+          <td colspan="1" rowspan="1">specifies the XHTML public document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">doctype-system</td><td colspan="1" rowspan="1">http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd</td>
+          <td colspan="1" rowspan="1">specifies the XHTML system document type</td>
+        
+</tr>
+        
+<tr>
+<td colspan="1" rowspan="1">mime-type</td><td colspan="1" rowspan="1">text/html</td>
+          <td colspan="1" rowspan="1">specifies mime-type of the serialized XHTML document.
+          </td>
+        
+</tr>
+      
+</table>
+    
+<h2>Pipeline Usage</h2>
+<p>
+        Using the XHTML Serializer in a pipeline is just setting the 
+        serializer type to xhtml. 
+        The following code snippet uses the XHTML Serializer:
+      </p>
+<pre class="code">
+&lt;map:match pattern="*.html"&gt;
+...
+  &lt;map:serialize type="xhtml"/&gt;
+&lt;/map:match&gt;
+...
+      </pre>
+    
+<h2>Further Reading</h2>
+<p>
+        As XHTML serializer uses the XML serializer internally, you might 
+        want to read the complete list of valid XML configuration parameters.
+        It is available at <a href="xml-serializer.html">XML serializer</a>
+        user docuementation.
+      </p>
+  
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/meta.xml
new file mode 100644
index 0000000..87a0838
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xhtml-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/xhtml-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/content_en.html
new file mode 100644
index 0000000..de3cf3d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/content_en.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XInclude Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="in @doctitle@" name="DC.Subject">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="This document describes the XInclude transformer." name="DC.Description">
+</head>
+<body>
+  
+<h1>XInclude Transformer</h1>
+   
+<p>
+    This transformer works according to the XInclude specification.
+   </p>
+   
+<p>
+    For more information refer to the
+    <a class="external" href="http://www.w3.org/TR/xinclude">XInclude specification</a>.
+   </p>
+   
+<ul>
+    
+<li>Name : xinclude</li>
+    
+<li>Class: org.apache.cocoon.transformation.XIncludeTransformer</li>
+    
+<li>Cacheable: no.</li>
+   
+</ul>
+   
+<p>
+    You can include either simple text, or xml content. 
+    Including xml content -- which is the default --
+    gives you the option to define an xpointer in the href attribute. Some
+    quick xinclude examples should reveal the possibilities of xinclude. 
+   </p>
+   
+<ul>
+    
+<li>
+     Include an xml content as-is: 
+     <span class="codefrag">&lt;xi:include href="include.xml"/&gt;</span>
+    
+</li>
+    
+<li>
+     Include an xml content but pick the strong element only:
+     <span class="codefrag">&lt;xi:include href="include.xml#xpointer(/p/strong)"/&gt;</span>
+    
+</li>
+    
+<li>
+     Include text content:
+     <span class="codefrag">&lt;xi:include parse="text" href="include.txt"/&gt;</span>
+    
+</li>
+   
+</ul>
+
+   
+<p>
+    A simple example using xinclude might help to use this transfomer
+    effectively:
+   </p>
+   
+<p>
+    Add the XIncludetransfomer to the components in your sitemap.xmap
+   </p>
+
+<pre class="code">
+...
+&lt;map:components&gt;
+...
+  &lt;map:transformers default="xslt"&gt;
+  ...
+    &lt;map:transformer name="xinclude"
+      src="org.apache.cocoon.transformation.XIncludeTransformer"/&gt;
+  ...
+</pre>
+
+   
+<p>
+    Next define in your pipeline to use the XIncludeTransformer
+   </p>
+
+<pre class="code">
+&lt;map:match pattern="xinc/simple-xinc"&gt;
+  &lt;map:generate src="xinc/simple-xinc.xml"/&gt;
+  &lt;map:transform type="xinclude"/&gt;
+  &lt;map:transform src="stylesheets/page/simple-page2html.xsl"/&gt;
+  &lt;map:serialize/&gt;
+&lt;/map:match&gt;
+</pre>
+
+   
+<p>
+    In this example pipeline it assumed that simple-xinc.xml contains
+    the include element. As well as defining the include element,
+    it defines the namespace URI "http://www.w3.org/2001/XInclude".
+    This helps the XIncludeTransformer to find the include element to 
+    get replaced by the included content.
+    The simple-xinc.xml may look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page 
+  xmlns:xi="http://www.w3.org/2001/XInclude"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+    &lt;xi:include href="include.xml"/&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+
+   
+<p>
+    Next you should define the include.xml file which is included.
+    A simple include.xml might look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0"?&gt;
+&lt;p&gt;
+  I am &lt;strong&gt;included&lt;/strong&gt; by XIncludeTransformer.
+  I come from "include.xml".
+&lt;/p&gt;
+</pre>
+
+   
+<p>
+    Now finally we have everything put together the xml content after the 
+    XIncludeTransformer processing will look like this:
+   </p>
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;page 
+  xmlns:xi="http://www.w3.org/2001/XInclude"&gt;
+  &lt;title&gt;Hello&lt;/title&gt;
+  &lt;content&gt;
+    &lt;para&gt;This is my first Cocoon page!&lt;/para&gt;
+      &lt;p&gt;
+       I am &lt;strong&gt;included&lt;/strong&gt; by XIncludeTransformer.
+       I come from "include.xml".
+      &lt;/p&gt;
+  &lt;/content&gt;
+&lt;/page&gt;
+</pre>
+  
+ 
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/meta.xml
new file mode 100644
index 0000000..9f2c463
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xinclude-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/xinclude-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/content_en.html
new file mode 100644
index 0000000..76f5f48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/content_en.html
@@ -0,0 +1,274 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XML Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Bernhard Huber" name="DC.Creator">
+<meta content="This document describes the xml serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>XML Serializer</h1>
+      
+<p>
+        The xml serializer is the simplest possible serializer. 
+        It generates an xml document from the sax events.
+        This serializer is used for serializing to any XML document
+        format, ie. SVG, WML, VRML, et. al.
+      </p>
+      
+<ul>
+        
+<li>Name : xml</li>
+        
+<li>Class: org.apache.cocoon.serialization.XMLSerializer</li>
+        
+<li>Cacheable: yes.</li>
+      
+</ul>
+      
+<h2>Sitemap Configuration</h2>
+<p>
+          The XML Serializer is declared in the sitemap serializers section.
+        </p>
+<pre class="code">
+&lt;map:serializers ...
+...
+  &lt;map:serializer name="xml"
+    src="org.apache.cocoon.serialization.XMLSerializer"
+    mime-type="text/xml"  
+    logger="sitemap.serializer.xml" 
+    pool-max="32"&gt;
+    &lt;!-- serializer configurations --&gt;
+...    
+  &lt;/map:serializer&gt;
+...
+        </pre>
+<p>
+          XML Serializer can be configured, specifying elements inside of
+          the &lt;map:serializer&gt; body.
+        </p>
+<h3>Configuration Example</h3>
+<p>
+            The following XML Serializer snippet is setting
+            encoding configuration for the XML Serializer
+          </p>
+<pre class="code">
+&lt;map:serializer name="xml"         
+  src="org.apache.cocoon.serialization.XMLSerializer"
+  mime-type="text/xml"&gt;
+  &lt;encoding&gt;ISO-8859-1&lt;/encoding&gt;
+&lt;/map:serializer&gt;
+          </pre>
+<p>
+            This configuration will result in xml output of the form
+          </p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+...
+          </pre>
+<p>
+          The XML Serializer accepts following configuration parameters.
+          These configurations are not Xalan specific.
+        </p>
+<table>
+          
+<tr>
+<th colspan="1" rowspan="1">Name</th><th colspan="1" rowspan="1">Xalan Default Value</th><th colspan="1" rowspan="1">Comment</th>
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">cdata-section-elements</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">cdata-section-elements</span> specifies a whitespace delimited
+               list of the names of elements whose text node children should be output
+               using CDATA sections.
+               See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation.</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">doctype-public</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">doctype-public</span> specifies the public identifier
+              to be used in the document type declaration.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">doctype-system</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">doctype-system</span> specifies the system identifier
+              to be used in the document type declaration.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">encoding</td>
+            <td colspan="1" rowspan="1">none</td>
+            <td colspan="1" rowspan="1"><span class="codefrag">encoding</span> specifies the preferred character
+              encoding that the Transformer should use to encode sequences of
+              characters as sequences of bytes. The value of the attribute should be
+              treated case-insensitively. The value must only contain characters in
+              the range #x21 to #x7E (i.e., printable ASCII characters). The value
+              should either be a <span class="codefrag">charset</span> registered with the Internet
+              Assigned Numbers Authority <a href="#IANA">[IANA]</a>,
+              <a href="#RFC2278">[RFC2278]</a> or start with <span class="codefrag">X-</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">indent</td>
+            <td colspan="1" rowspan="1">
+              yes
+            </td>
+            <td colspan="1" rowspan="1">
+              A Flag for toggling indent. This flag toggles only if some elements
+              should trigger a line break.
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">media-type</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">media-type</span> specifies the media type (MIME
+              content type) of the data that results from outputting the result
+              tree. The <span class="codefrag">charset</span> parameter should not be specified
+              explicitly; instead, when the top-level media type is
+              <span class="codefrag">text</span>, a <span class="codefrag">charset</span> parameter should be added
+              according to the character encoding actually used by the output
+              method.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">method</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              The method attribute identifies the overall method that
+              should be used for outputting the result tree.  Other non-namespaced
+              values may be used, such as "xhtml", but, if accepted, the handling
+              of such values is implementation defined.  If any of the method values
+              are not accepted and are not namespace qualified,
+              then {@link javax.xml.transform.Transformer#setOutputProperty}
+              or {@link javax.xml.transform.Transformer#setOutputProperties} will
+              throw a {@link java.lang.IllegalArgumentException}.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">omit-xml-declaration</td>
+            <td colspan="1" rowspan="1"></td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">omit-xml-declaration</span> specifies whether the XSLT
+              processor should output an XML declaration; the value must be
+              <span class="codefrag">yes</span> or <span class="codefrag">no</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">standalone</td>
+            <td colspan="1" rowspan="1"></td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">standalone</span> specifies whether the Transformer
+              should output a standalone document declaration; the value must be
+              <span class="codefrag">yes</span> or <span class="codefrag">no</span>.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+          
+<tr>
+<td colspan="1" rowspan="1">version</td>
+            <td colspan="1" rowspan="1">
+            </td>
+            <td colspan="1" rowspan="1">
+              <span class="codefrag">version</span> specifies the version of the output
+              method.
+              When the output method is "xml", the version value specifies the
+              version of XML to be used for outputting the result tree. The default
+              value for the xml output method is 1.0. When the output method is
+              "html", the version value indicates the version of the HTML.
+              The default value for the xml output method is 4.0, which specifies
+              that the result should be output as HTML conforming to the HTML 4.0
+              Recommendation [HTML].  If the output method is "text", the version
+              property is ignored.
+              See <a class="external" href="http://www.w3.org/TR/xslt#output">section 16 of the XSL Transformations (XSLT) W3C Recommendation</a>
+            </td>
+          
+</tr>
+        
+</table>
+<div class="note">
+          Former property <span class="codefrag">buffer-size</span> is deprecated, and is ignored.
+        </div>
+<p>
+          The XML Serializer sets the <span class="codefrag">method</span> property
+          to <span class="codefrag">xml</span>.
+        </p>
+      
+<h2>Pipeline Usage</h2>
+<p>
+        Using the XML Serializer in a pipeline is just setting the 
+        serializer type to xml. 
+        The following code snippet uses the XML Serializer:
+      </p>
+<pre class="code">
+...
+&lt;map:match pattern="*.xml"&gt;
+&lt;map:generate...
+...
+&lt;map:serialize type="xml"/&gt;
+...
+      </pre>
+      
+<h2>Further Reading</h2>
+<p>
+          The XML serializer is usable for serializing any SAX events
+          to a plain xml output. The various xml documents 
+          requires in most cases a proper configuration of following
+          parameters
+        </p>
+<ul>
+          
+<li>doctype-public</li>
+          
+<li>doctype-system</li>
+        
+</ul>
+<p>
+          Moreover the mime-type, and name attribute of the serializer definition
+          shall be set propertly.
+        </p>
+<p>
+          Read the XML serializer configuration user documentation
+          for
+          <a href="svgxml-serializer.html">SVG/XML</a>,
+          and
+          <a href="wap-serializer.html">WML</a> in order
+          to understand using the XML serialiazer for 
+          serializing to some specific XML content type.
+        </p>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/meta.xml
new file mode 100644
index 0000000..fa148c1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xml-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/xml-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/content_en.html
new file mode 100644
index 0000000..1228579
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/content_en.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XPath Directory Generator</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="J&ouml;rg Heinicke" name="DC.Creator">
+<meta content="This document describes the XPath Directory Generator of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>XPath Directory Generator</h1>
+      
+<p>Generates an XML directory listing performing XPath queries on XML files.</p>
+      
+<ul>
+        
+<li>Name: xpathdirectory</li>
+        
+<li>Class: org.apache.cocoon.generation.XPathDirectoryGenerator</li>
+        
+<li>Cacheable: yes</li>
+      
+</ul>
+      
+<p>The XPath Directory Generator provides all the functionality of the
+        <a href="directory-generator.html">Directory Generator</a>. Additionaly it is possible
+        to get XML snippets out of the XML files the Directory Generator finds.</p>
+    
+    
+<h1>Additional Configuration</h1>
+      
+<pre class="code">
+  &lt;map:generate type="xpathdirectory" src="the/requested/directory"&gt;
+    &lt;map:parameter name="xpath" value="/article/title|/article/abstract"/&gt;
+    &lt;map:parameter name="xmlFiles" value="\.x.*$"/&gt;
+  &lt;/map:generate&gt;
+      </pre>
+      
+<p>The XPath Directory Generator has two additional parameters, both are optional.</p>
+      
+<ul>
+        
+<li>xpath: Sets the XPath the XPath Directory Generator should use for queries on XML files.
+            If you don't set this parameter it will behave like the Directory Generator.</li>
+        
+<li>xmlFiles: The xml files pattern. Specifies the files that should be handled as XML
+            files. XPath queries will only be tried on files matching this pattern. The XPath
+            Directory Generator does not fail on non-XML files or files that are not
+            well-formed or not valid. All Exceptions on parsing the files will be caught and
+            ignored. But of course, useless parsing, throwing and catching exceptions is very
+            time consuming, so the <span class="codefrag">xmlFiles</span> pattern should not be too generic.<br>
+            If you specify an empty pattern all files will be handled as XML files. The default
+            pattern when not specifying this parameter is <span class="codefrag">\.xml$</span>, so that all files
+            ending <span class="codefrag">.xml</span> are handled as XML files.<br>
+            The pattern is a regular expression as described in the API docs of the
+            <a class="external" href="http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html">
+            Apache RegExp project</a>.</li>
+      
+</ul>
+    
+    
+<h1>Extended DTD</h1>
+      
+<pre class="code">
+  &lt;!ELEMENT directory (directory|file)*&gt;
+  &lt;!ATTLIST directory
+    name         CDATA #REQUIRED
+    lastModified CDATA #REQUIRED
+    date         CDATA #REQUIRED
+    size         CDATA #REQUIRED
+    requested    CDATA #IMPLIED
+    sort         CDATA #IMPLIED
+    reverse      CDATA #IMPLIED&gt;
+
+  &lt;!ELEMENT file (xpath?)&gt;
+  &lt;!ATTLIST file
+    name         CDATA #REQUIRED
+    lastModified CDATA #REQUIRED
+    date         CDATA #REQUIRED
+    size         CDATA #REQUIRED&gt;
+
+  &lt;!ELEMENT xpath #ALL&gt;
+  &lt;!ATTLIST xpath
+    query        CDATA #REQUIRED&gt;
+      </pre>
+    
+    
+<h1>Example</h1>
+      
+<p>The current XPath Directory Generator may generate following xml:</p>
+      
+<pre class="code">
+&lt;dir:directory xmlns:dir="http://apache.org/cocoon/directory/2.0"
+    name="articles" lastModified="1057183738609" date="03.07.03 00:08" size="0"
+    requested="true" sort="name" reverse="false"&gt;
+  &lt;dir:directory name="images" lastModified="1057183738609" date="03.07.03 00:08" size="0"/&gt;
+  &lt;dir:file name="article1.xml" lastModified="1057183738609" date="03.07.03 00:08" size="123"&gt;
+    &lt;dir:xpath query="/article/title"&gt;
+      &lt;title&gt;My first article!&lt;/title&gt;
+    &lt;/dir:xpath&gt;
+  &lt;/dir:file&gt;
+  &lt;dir:file name="article2.html" lastModified="1057183738609" date="03.07.03 00:08" size="345"/&gt;
+  &lt;dir:file name="article2.xml" lastModified="1057183738609" date="03.07.03 00:08" size="234"&gt;
+    &lt;dir:xpath query="/article/title"&gt;
+      &lt;title&gt;My second article!&lt;/title&gt;
+    &lt;/dir:xpath&gt;
+  &lt;/dir:file&gt;
+&lt;/dir:directory&gt;
+      </pre>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/meta.xml
new file mode 100644
index 0000000..57af522
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xpathdirectory-generator/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/generators/xpathdirectory-generator.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/content_en.html
new file mode 100644
index 0000000..8bcd3d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/content_en.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>XSLT Transformer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Carsten Ziegeler" name="DC.Creator">
+<meta content="Sylvain Wallez" name="DC.Creator">
+<meta content="This document describes the xslt transformer of Cocoon." name="DC.Description">
+</head>
+<body>
+     
+<h1>Trax/XSLT Transformer</h1>
+      
+<p>The xslt transformer reads an xsl document from the local file system or from any url.
+                 It transforms the sax stream using this stylesheet.</p>
+              
+<p>The xslt transformer is the default transformer .</p>
+      
+<ul>
+        
+<li>Name : xslt</li>
+        
+<li>Class: org.apache.cocoon.transformation.TraxTransformer</li>
+        
+<li>Cacheable: yes - uses the last modification date of the xsl document for validation.</li>
+      
+</ul>
+      
+<p>The xslt transformer is configurable. You can specify one or more of 
+                     the following configuration information:</p>
+      
+<ul>
+        
+<li>use-request-parameters: true|false - Setting this to true makes all
+                        request parameters available in the XSLT stylesheet. Note that this might 
+                        have issues concerning cachability of the generated output of this transformer,
+                        the caching algorithm not only checks the last modification date but also
+                        all values of the request parameters.
+                        This property is false by default. If set to true the values of a request
+                        parameter is available using a variable in the xslt with the name of the parameter.</li>
+        
+<li>use-browser-capabilities-db: true|false - This configuration forces the transformer to make all
+                        properties from the browser capability database available in the XSLT stylesheet as.
+                        Note that this might have issues concerning cachability of the generated output of this
+                        transformer as the caching algorithm adds this values to the validation phase.
+                        The default for this property is false.</li>
+        
+<li>use-cookies: true|false - This configuration forces the transformer to make all
+                cookies from the request available in the XSLT stylesheetas.
+                Note that this might have issues concerning cachability of the generated output of this
+                transformer. This property is false by default.</li>
+        
+<li>xslt-processor-role: [role name] - This configuration allows to specify the XSLT processor (see below)
+           that will be used by its role name. This allows to have several XSLT processors in the configuration
+          (e.g. Xalan and Saxon) and choose one or the other depending on the needs of stylesheet
+          specificities. This property defaults to "org.apache.cocoon.components.xslt.XSLTProcessor"
+          which is the standard role name for an XSLTProcessor.</li>
+      
+</ul>
+      
+<p>The "use-request-parameters" and "use-browser-capabilities-db" configuration
+                     of a transformer can be changed for one single pipeline by specifying
+                     parameters with the same name:</p>
+
+<pre class="code">
+     
+  &lt;map:transform src="stylesheet.xsl" type="xslt"/&gt;
+  &lt;!-- The type attribute can be omitted as it is the default transformer. --&gt;
+     
+</pre>
+      
+<p>The "use-request-parameters" and "use-browser-capabilities-db" configuration
+                     of a transformer can be changed for one single pipeline by specifying
+                     parameters with the same name:</p>
+
+<pre class="code">
+     
+  &lt;map:transform src="stylesheet.xsl"&gt;
+  &lt;map:parameter name="use-request-parameters" value="true"/&gt;
+  &lt;/map:transform&gt;
+     
+</pre>
+      
+<p>In addition all other parameters to the transformer are
+                  available in the stylesheet as &lt;xsl:param/&gt;s (These values
+                  are also used in the caching algorithm.)</p>
+    
+            
+<h1>The XSLT Processor</h1>
+      
+<p>The XSLT Transformer uses a component called XSLTProcessor. This component is
+                     configured in the cocoon.xconf. You can configure it as follows:</p>
+      
+<ul>
+        
+<li>use-store: true|false -  If set to true it forces the xslt processor 
+                        to put the generated templates from the XSLT stylesheet into the
+         system store. This property is true by default.</li>
+        
+<li>transformer-factory: [class name] - tells the transformer to use a particular
+          implementation of javax.xml.transform.TransformerFactory. This allows to force the use of
+          a given TRAX implementation (e.g. xalan or saxon) if several are available in the classpath.
+          If this property is not set, the transformer uses the standard TRAX mechanism
+          (TransformerFactory.newInstance()).</li>
+      
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/meta.xml
new file mode 100644
index 0000000..5373267
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-xslt-transformer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/transformers/xslt-transformer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/comments_en.xml
new file mode 100644
index 0000000..37566d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/comments_en.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<comments>
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/content_en.html
new file mode 100644
index 0000000..9e8cb4e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/content_en.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Zip archive Serializer</title>
+<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
+<meta content="Sylvain Wallez" name="DC.Creator">
+<meta content="This document describes the Zip archive serializer of Cocoon." name="DC.Description">
+</head>
+<body>
+    
+<h1>Zip archive Serializer</h1>
+      
+<p>The Zip archive serializer generates a zip archive by aggregating several sources.</p>
+    
+ 
+<p>The input document should describe entries of the archive by means of
+ their name (which can be a path) and their content either as URLs or
+ inline data :</p>
+ 
+<ul>
+   
+<li>URLs, given by the "src" attribute, are Cocoon sources and as such
+       can use any of the protocols handled by Cocoon, including "cocoon:" to
+       include dynamically generated content in the archive.</li>
+   
+<li>inline data is represented by an XML document that is serialized to the
+       zip entry using the serializer identified by the "serializer" attribute.</li>
+   
+</ul>
+ 
+<p>
+   Example :
+ </p>
+
+<pre class="code">
+&lt;zip:archive xmlns:zip="http://apache.org/cocoon/zip-archive/1.0"&gt;
+  &lt;zip:entry name="foo.html" src="cocoon://dynFoo.html"/&gt;
+  &lt;zip:entry name="images/bar.jpeg" src="bar.jpeg"/&gt;
+  &lt;zip:entry name="index.html" serializer="html"&gt;
+    &lt;html&gt;
+      &lt;head&gt;
+        &lt;title&gt;Index page&lt;/title&gt;
+      &lt;/head&gt;
+      &lt;body&gt;
+        Please go &lt;a href="foo.html"&gt;there&lt;/a&gt;
+      &lt;/body&gt;
+    &lt;/html&gt;
+  &lt;/zip:entry&gt;
+&lt;/zip:archive&gt;
+</pre>
+
+       
+<ul>
+         
+<li>Name: zip</li>
+         
+<li>Class: org.apache.cocoon.serialization.ZipArchiveSerializer</li>
+               
+<li>Cacheable: no</li>
+       
+</ul>
+    
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/meta.xml
new file mode 100644
index 0000000..3194b6f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21-ziparchive-serializer/meta.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://cocoon.apache.org">Cocoon Community</author>
+  </authors>
+  <legacy>
+    <original-filename>userdocs/serializers/ziparchive-serializer.html</original-filename>
+  </legacy>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/content_en.xdoc b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/content_en.xdoc
new file mode 100644
index 0000000..fafb126
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/content_en.xdoc
@@ -0,0 +1,563 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
+
+<document> 
+ <header>
+  <title>Understanding Apache Cocoon</title>
+  <authors>
+   <person name="Pankaj Kumar" email="pankaj_kumar@hp.com"/>
+   <person name="Davanum Srinivas" email="dims@yahoo.com"/>
+  </authors>
+ </header>
+
+ <body>
+   <s1 title="Overview">
+     <p>
+     This document is intended for both Users and Developers 
+     and presents an overall picture of @Name@.
+     </p>
+
+     <ul>
+       <li>
+         <link href="#pre-requisites">
+           Prerequisites
+         </link>
+       </li>
+       <li>
+         <link href="#a-little-history">
+           A Little History
+         </link>
+       </li>
+       <li>
+         <link href="#what-problems">
+           What problem does Cocoon solve?
+         </link>
+       </li>
+       <li>
+         <link href="#basic-mechanisms">
+           Basic Mechanisms.
+         </link>
+       </li>
+       <li>
+         <link href="#c2-architecture">
+           Architecture.
+         </link>
+       </li>
+       <li>
+         <link href="#c2-abstractions">
+           Abstraction.
+         </link>
+       </li>
+       <li>
+         <link href="#cocoon-configuration">
+           @Name@ Configuration.
+         </link>
+       </li>
+       <li>
+         <link href="#work-area">
+           @Name@ Work Area.
+         </link>
+       </li>
+       <li>
+         <link href="#use-with-tomcat">
+           Use with Tomcat
+         </link>
+       </li>
+     </ul>
+  </s1>
+
+  <anchor id="pre-requisites"/>
+  <s1 title="Prerequisites">
+    <p>What You Should know:</p> 
+    <ul> 
+         <li>XML, XML Namespaces</li>
+         <li>Basics of XPath, XSLT</li>
+         <li>Java language</li>
+         <li>Servlets, HTTP</li>
+    </ul> 
+    <p>What You need not know:</p> 
+    <ul> 
+         <li>Cocoon 1</li>
+    </ul> 
+  </s1>
+  <anchor id="a-little-history"/>
+  <s1 title="A Little History">
+    <s2 title="Cocoon 1">
+      <ul> 
+            <li>Cocoon project was founded in Jan. 1999 by Stefano Mazzocchi as an open source project under Apache Software Foundation.</li>
+            <li>Started as a simple servlet for XSL styling of XML content.</li>
+            <li>Was based on DOM level 1 API. This choice turned out to be quite limiting for speed/memory efficiency.</li>
+            <li>Used reactor pattern to connect components. This allowed the reaction instructions to be placed inside the documents.  Though appealing, it caused difficulties in managing highly dynamic web-sites.</li>
+            <li>Allowed context overlap to happen by having processing instructions in documents/stylesheets.</li>
+      </ul> 
+    </s2>
+    <s2 title="Apache Cocoon">
+      <ul> 
+            <li>A separate codebase to incorporate Cocoon 1 learnings.</li>
+            <li>Designed for execution speed/memory efficiency and scalability to process very large documents by switching processing model from DOM to SAX.</li>
+            <li>Centralizes the management functions by allowing processing pipeline specification in a sitemap (an XML file), replacing the embedded processing instruction model.</li>
+            <li>Better support for pre-compilation, pre-generation and caching for better performance.</li>
+      </ul>
+    </s2>
+  </s1>
+  <anchor id="what-problems"/>
+  <s1 title="What problem does Cocoon solve?">
+    <p>Basic problem to be solved:</p>
+    <s2 title="Separation of content, style, logic and management functions in an XML content based web site (and web services).">
+      <figure src="images/pyramid-model.gif"
+              alt="The @Name@ Pyramid Model of Contracts"
+              width="313" height="159"/>
+    </s2>
+    <s2 title="Data Mapping">
+      <figure src="images/data-mapping.gif" alt="The @Name@ Data Mapping"
+              width="339" height="174"/>
+    </s2>
+  </s1>
+  <anchor id="basic-mechanisms"/>
+  <s1 title="Basic Mechanisms.">
+    <p>Basic mechanisms for processing XML documents:</p>
+    <ul>
+      <li>Dispatching based on Matchers.</li>
+      <li>Generation of XML documents (from content, logic, Relation DB, objects or any combination) through Generators</li>
+      <li>Transformation (to another XML, objects or any combination) of XML documents through Transformers</li>
+      <li>Aggregation of XML documents through Aggregators</li>
+      <li>Rendering XML through Serializers</li>
+    </ul>
+    <figure src="images/basic-mechanism.gif" alt="Basic Mechanisms"
+            width="288" height="386"/>
+    <s2 title="Pipeline Processing">
+        <p>Sequence of Interactions</p>
+        <figure src="images/interaction-sequence.gif"
+                alt="Interaction Sequence"
+                width="613" height="347"/>
+        <p>Pipeline</p>
+        <figure src="images/pipeline.gif" alt="Pipeline"
+                width="713" height="223"/>
+    </s2>
+  </s1>
+  <anchor id="c2-architecture"/>
+  <s1 title="Architecture.">
+    <figure src="images/architecture.gif" alt="Architecture"
+            width="430" height="349"/>
+    <s2 title="Core Cocoon">
+      <ul>
+        <li>Avalon framework for logging, configuration, threading, context etc.</li>
+        <li>Caching mechanism</li>
+        <li>Pipeline handling</li>
+        <li>Program generation, compilation, loading and execution.</li>
+        <li>Base classes for generation, transformation, serialization, components.</li>
+        <li>...</li>
+      </ul>
+    </s2>
+    <s2 title="Cocoon Components">
+      <ul>
+        <li>Specific generators</li>
+        <li>Specific transformers</li>
+        <li>Specific matchers</li>
+        <li>Specific serializers</li>
+        <li>...</li>
+      </ul>
+    </s2>
+    <s2 title="Built-in Logicsheets">
+      <ul>
+        <li>sitemap.xsl</li>
+        <li>xsp.xsl</li>
+        <li>esql.xsl</li>
+        <li>request.xsl</li>
+        <li>response.xsl</li>
+        <li>...</li>
+      </ul>
+    </s2>
+    <s2 title="Site specific configuration, components, logicsheets and content">
+      <ul>
+        <li>...</li>
+      </ul>
+    </s2>
+  </s1>
+  <anchor id="c2-abstractions"/>
+  <s1 title="Abstraction.">
+    <s2 title="eXtensible Server Pages (XSPs)">
+      <p>An XSP page is an XML page with following requirements:</p>
+        <ul>
+          <li>The document root must be <code>&lt;xsp:page&gt;</code></li>
+          <li>It must have language declaration as an attribute in the <code>&lt;xsp:page&gt;</code> element.</li>
+          <li>It must have namespace declaration for xsp as an attribute in the <code>&lt;xsp:page&gt;</code> element.</li>
+          <li>For an XSP to be useful, it must also require at least an <code>&lt;xsp:logic&gt;</code> and an <code>&lt;xsp:expr&gt;</code> element.</li>
+        </ul>
+<source><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xsp:page language="java" xmlns:xsp="http://apache.org/xsp">
+
+  <xsp:logic>
+  static private int counter = 0;
+  private synchronized int count()
+  {
+    return counter++;
+  }
+  </xsp:logic>
+
+  <page>
+  <p>I have been requested <xsp:expr>count()</xsp:expr> times.</p>
+  </page>
+
+</xsp:page>
+]]></source>
+
+      <p>An XSP page is used by a generator to generate XML document.</p>
+    </s2>
+    <s2 title="XSP Processing (Code Generation)">
+<source><![CDATA[
+package org.apache.cocoon.www.docs.samples.xsp;
+
+import java.io.File;
+// A bunch of other imports 
+
+public class counter_xsp extends XSPGenerator {
+   // .. Bookkeeping stuff commented out.
+  /* User Class Declarations */
+  static private int counter = 0;
+  private synchronized int count() {
+    return counter++;
+  }
+  /* Generate XML data. */
+  public void generate() throws SAXException {
+    this.contentHandler.startDocument();
+    AttributesImpl xspAttr = new AttributesImpl();
+    this.contentHandler.startPrefixMapping("xsp", "http://apache.org/xsp");
+    this.contentHandler.startElement("", "page", "page", xspAttr);
+    // Statements to build the XML document (Omitted)
+    this.contentHandler.endElement("", "page", "page");
+    this.contentHandler.endPrefixMapping("xsp");
+    this.contentHandler.endDocument();
+  }
+]]></source>
+    </s2>
+    <s2 title="Ways of Creating XSPs">
+      <s3 title="Embedded Logic">
+      <ul>
+        <li>Code is embedded in the XML page</li>
+        <li>No separation of content and logic</li>
+        <li>Okay for small examples but terrible for large systems.</li>
+      </ul>
+      <figure src="images/xsp-way.gif" alt="ways of creating xsp's"
+              width="323" height="384"/>
+      </s3>
+      <s3 title="Included Logicsheet">
+      <ul>
+        <li>Code is in a separate logicsheet (an XSL file)</li>
+        <li>Effective separation of content and logic</li>
+        <li>Preferred way to create XSPs</li>
+      </ul>
+      <figure src="images/xsp-way2.gif" alt="ways of creating xsp's"
+              width="318" height="403"/>
+      </s3>
+      <s3 title="Logicsheet as tag library">
+      <ul>
+        <li>The logicsheet is packaged as a reusable tag library and registered with Cocoon in cocoon.xconf file.</li>
+        <li>Tag library has a namespace declaration, declared in the original logicsheet and matched in <code>&lt;xsp:page&gt;</code> xmlns:... attribute.</li>
+        <li>Effective separation of content, logic and management</li>
+      </ul>
+      <figure src="images/xsp-way3.gif" alt="ways of creating xsp's"
+              width="344" height="409"/>
+      </s3>
+    </s2>
+    <s2 title="Sitemap">
+<source><![CDATA[
+<?xml version="1.0"?>
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+<map:components>
+...
+</map:components>
+
+<map:views>
+...
+</map:views>
+<map:pipelines>
+<map:pipeline>
+<map:match> 
+...
+</map:match>
+...
+</map:pipeline>
+...
+</map:pipelines>
+...
+</map:sitemap>
+]]></source>
+      <p>Sitemap contains configuration information for a Cocoon engine:</p>
+        <ul>
+           <li>list of matchers</li>
+           <li>list of generators</li>
+           <li>list of transformers</li>
+           <li>list of readers</li>
+           <li>list of serializers</li>
+           <li>list of selectors</li>
+           <li>list of processing pipelines with match patterns</li>
+           <li>...</li>
+        </ul>
+      <p>Sitemap is an XML file corresponding to a sitemap DTD.</p>
+      <p>Sitemap can be edited to add new elements.</p>
+      <p>Sitemap is generated into a program and is compiled into an executable unit.</p>
+    </s2>
+    <s2 title="Matchers">
+      <p>A Matcher attempts to match an URI with a specified pattern for dispatching the request to a specific processing pipeline.</p>
+      <p>Different types of matchers:</p>
+        <ul>
+           <li>wildcard matcher</li>
+           <li>regexp matcher</li>
+        </ul>
+      <p>More matchers can be added without modifying Cocoon.</p>
+      <p>Matchers help in specifying a specific pipeline processing for a group of URIs.</p>
+      <p>Sitemap entries for different types of matchers</p>
+<source><![CDATA[
+<map:matchers default="wildcard">
+ <map:matcher name="wildcard" factory="org.apache.cocoon.matching.WildcardURIMatcher"/>
+ <map:matcher name="regexp" factory="org.apache.cocoon.matching.RegexpURIMatcher"/>
+</map:matchers>
+]]></source>
+      <p>Pipeline entries in sitemap file</p>
+<source><![CDATA[
+<map:match pattern="jsp/*">
+  <map:generate type="jsp" src="/docs/samples/jsp/{1}.jsp"/>
+  ...
+  </map:match>
+<map:match pattern="hello.pdf">
+</map:match
+]]></source>
+    </s2>
+    <s2 title="Generators">
+      <p>A Generator is used to create an XML structure from an input source (file, directory, stream ...)</p>
+      <figure src="images/xsp-way3.gif" alt="ways of creating xsp's"
+              width="344" height="409"/>
+      <p>Different types of generators:</p>
+        <ul>
+           <li>file generator</li>
+           <li>directory generator</li>
+           <li>XSP generator</li>
+           <li>JSP generator</li>
+           <li>Request generator</li>
+           <li>...</li>
+        </ul>
+      <p>More generators can be added without modifying Cocoon.</p>
+      <p>Sitemap entries for different types of generators</p>
+<source><![CDATA[
+<map:generators default="file">
+ <map:generator name="file"
+                src="org.apache.cocoon.generation.FileGenerator"
+                label="content"/>
+ <map:generator name="directory"
+                src="org.apache.cocoon.generation.DirectoryGenerator"
+                label="content"/>
+ <map:generator name="serverpages"
+                src="org.apache.cocoon.generation.ServerPagesGenerator"
+                label="content"/>
+ <map:generator name="request"
+                src="org.apache.cocoon.generation.RequestGenerator"/>
+ ...
+</map:generators>
+]]></source>
+      <p>A sample generator entries in a pipeline</p>
+<source><![CDATA[
+<map:match pattern="hello.html">
+    <map:generate src="docs/samples/hello-page.xml"/>
+    <map:transform src="stylesheets/page/simple-page2html.xsl"/>
+    <map:serialize type="html"/>
+</map:match>
+]]></source>
+
+      <p>A Generator turns an XML document, after applying appropriate transformations, into a compiled program whose output is an XML document.</p>
+      <p>An XSP generator applies all the logicsheets specified in the source XML file before generating the program.</p>
+      <p>Generators cache the compiled programs for better runtime efficiency.</p>
+    </s2>
+    <s2 title="Transformers">
+      <p>A Transformer is used to map an input XML structure into another XML structure.</p>
+      <p>Different types of transformers:</p>
+        <ul>
+           <li>XSLT Transformer</li>
+           <li>Log Transformer</li>
+           <li>SQL Transformer</li>
+           <li>I18N Transformer</li>
+           <li>...</li>
+        </ul>
+      <p>Log Transformer is a good debugging tool.</p>
+      <p>More transformers can be added without modifying Cocoon.</p>
+      <p>Sitemap entries for different types of transformers</p>
+<source><![CDATA[
+<map:transformers default="xslt">
+   <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer">
+    <use-request-parameters>false</use-request-parameters>
+    <use-browser-capabilities-db>false</use-browser-capabilities-db>
+   </map:transformer>
+   <map:transformer name="log" src="org.apache.cocoon.transformation.LogTransformer"/>
+...
+
+</map:transformers>
+]]></source>
+      <p>A sample transformer entry in a pipeline</p>
+<source><![CDATA[
+<map:match pattern="hello.html">
+ <map:generate src="docs/samples/hello-page.xml"/>
+ <map:transform src="stylesheets/page/simple-page2html.xsl"/>
+ <map:serialize type="html"/>
+</map:match>
+]]></source>
+    </s2>
+    <s2 title="Serializers">
+      <p>A Serializer is used to render an input XML structure into some other format (not necessarily XML)</p>
+      <p>Different types of serializers:</p>
+        <ul>
+           <li>HTML Serializer</li>
+           <li>FOP Serializer</li>
+           <li>Text Serializer</li>
+           <li>XML Serializer</li>
+           <li>...</li>
+        </ul>
+      <p>More serializers can be added without modifying Cocoon.</p>
+      <p>Sitemap entries for different types of serializers</p>
+<source><![CDATA[
+<map:serializers default="html">
+ <map:serializer name="xml"
+                 mime-type="text/xml"
+                 src="org.apache.cocoon.serialization.XMLSerializer"/>
+ <map:serializer name="html"
+                 mime-type="text/html"
+                 src="org.apache.cocoon.serialization.HTMLSerializer"/>
+ <map:serializer name="fo2pdf"
+                 mime-type="application/pdf"
+                 src="org.apache.cocoon.serialization.FOPSerializer"/>
+ <map:serializer name="vrml"
+                 mime-type="model/vrml"
+                 src="org.apache.cocoon.serialization.TextSerializer"/>
+ ...
+</map:serializers>
+]]></source>
+      <p>A sample serializer entry in a pipeline</p>
+<source><![CDATA[
+ <map:match pattern="hello.html">
+    <map:generate src="docs/samples/hello-page.xml"/>
+    <map:transform src="stylesheets/page/simple-page2html.xsl"/>
+    <map:serialize type="html"/>
+   </map:match>
+]]></source>
+    </s2>
+    <s2 title="Pipeline Processing">
+      <p>The sitemap configuration allows dynamic setup of processing pipelines consisting of a generator, multiple transformers and a serializer.</p>
+      <p>Requests are dispatched to a pipeline based on request URI and the pipeline matching pattern (either with wildcards or as a regexp)</p>
+      <p>The pipeline is setup in the generated file <code>sitemap_xmap.java</code> (This file gets generated [possibly asynchronously] everytime the <code>sitemap.xmap</code> is modified.</p>
+      <figure src="images/pipeline2.gif" alt="Pipeline Entry"
+              width="379" height="341"/>
+    </s2>
+    <s2 title="Logicsheets">
+      <p>Logicsheets are XSL files with an associated namespace.</p>
+      <p>Primary mechanism to add program logic (code) to XSPs.</p>
+      <p>These need to be registered in configuration file cocoon.xconf.</p>
+      <p>Logicsheets are used by the generator to transform XML structure before generating program.</p>
+      <p>Cocoon comes with a no. of built-in logic sheets:</p>
+        <ul>
+           <li>request.xsl</li>
+           <li>response.xsl</li>
+           <li>session.xsl</li>
+           <li>cookie.xsl</li>
+           <li>esql.xsl</li>
+           <li>log.xsl</li>
+           <li>...</li>
+        </ul>
+      <p>Log.xsl structure</p>
+<source><![CDATA[
+<xsl:stylesheet  version="1.0"
+                 xmlns:xsp="http://apache.org/xsp"
+                 xmlns:log="http://apache.org/xsp/log"
+                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="log:logger">
+... variable and xsp:logic statements ...
+</xsl:template>
+
+<xsl:template match="log:debug">
+  <xsp:logic>
+   if(getLogger() != null)
+     getLogger().debug("<xsl:value-of select="."/>");    
+  </xsp:logic>  
+</xsl:template>
+<xsl:template match="log:error">
+...  
+</xsl:template>
+</xsl:stylesheet>
+]]></source>
+      <p>A sample use</p>
+<source><![CDATA[
+<xsp:page language="java"
+          xmlns:xsp="http://apache.org/xsp"
+          xmlns:log="http://apache.org/xsp/log">
+
+  <page>
+  <log:logger name="test" filename="test.log"/>
+  <log:debug>Test Message</log:debug>
+  </page>
+</xsp:page>
+]]></source>
+    </s2>
+  </s1>
+  <anchor id="cocoon-configuration"/>
+  <s1 title="@Name@ Configuration.">
+    <p>Cocoon is highly configurable. Main configuration files, assuming Cocoon deployment as a servlet in a servlet container, are (directory locations assume Tomcat servlet container):</p>
+    <ul>
+       <li><code>sitemap.xmap</code>: the sitemap file. By default, located in <code>$TOMCAT_HOME/webapps/cocoon</code> directory.</li>
+       <li><code>cocoon.xconf</code>: configuration file having logicsheet registrations. Specifies, sitemap.xmap location and other such parameters. By default, located in <code>$TOMCAT_HOME/webapps/cocoon</code> directory.</li>
+       <li><code>web.xml</code>: servlet deployment descriptor. Specifies location of cocoon.xconf, log file location and other such parameters. Located in <code>$TOMCAT_HOME/webapps/cocoon/WEB-INF</code> directory.</li>
+       <li><code>cocoon.roles</code>: mapping file for Core Cocoon components name and implementation classes. For example, if you want to use a parser other than the default one, you need to modify this file.</li>
+    </ul>
+  </s1>
+  <anchor id="work-area"/>
+  <s1 title="@Name@ Work Area">
+    <p>Cocoon produces execution log entries for debugging/auditing.</p>
+    <ul>
+       <li>The amount of data to be logged can be controlled by
+       log-level parameter in web.xml file. The default is DEBUG
+       (maximum data).</li>
+       <li>By default, the log file is:
+       <code>$TOMCAT_HOME/webapps/cocoon/WEB-INF/logs/cocoon.log</code>.</li>
+    </ul>
+
+    <p>Cocoon keeps the generated .java files in a directory tree
+    starting at (by default):<br/>
+    <code>$TOMCAT_HOME/webapps/work/localhost_8080%2Fcocoon/org/apache/cocoon/www</code>.</p>
+
+<p>You can find sitemap_xmap.java here.</p>
+
+    <p>Files created by LogTransformer are kept (by default) in <code>$TOMCAT_HOME</code> directory.</p>
+  </s1>
+  <anchor id="use-with-tomcat"/>
+  <s1 title="Use with Tomcat">
+    <p>Download Tomcat from Apache site.</p>
+    <p>Download Cocoon sources from Apache CVS. [Command assume UNIX Bourne shell]</p>
+<source><![CDATA[
+export CVSROOT=:pserver:anoncvs@cvs.apache.org:/home/cvspublic 
+cvs login 
+Password: anoncvs 
+cvs checkout cocoon-2.1
+]]></source>
+    <p>Build sources as per instruction in Install file.</p>
+    <p>Move the <code>cocoon.war</code> file to <code>$TOMCAT_HOME/webapps</code> directory.</p>
+    <p>Start the servlet engine. Type-in the URL <code>http://localhost:8080/cocoon</code> in your browser. You should see the Cocoon welcome message.</p>
+    <p>Consult Install file if you face problems.</p>
+  </s1>
+</body>
+</document>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/meta.xml
new file mode 100644
index 0000000..ad6f58c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_concepts_index/meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="dev@cocoon.apache.org">The Cocoon community</author>
+  </authors>
+  <source>legacy.21</source>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/content_en.xdoc b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/content_en.xdoc
new file mode 100644
index 0000000..0b6254d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/content_en.xdoc
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
+
+<document> 
+ <header>
+  <title>2.1 legacy documentation</title>
+  <authors/>
+ </header>
+
+ <body>
+   <section>
+     <p>
+      These documents have been copied here from the Cocoon 2.1
+       source tree, but have not been reviewed yet.
+     </p>
+    <fixme author="BD">
+      Add more info about how to handle them, how to indicate
+      sections that have move to new docs, etc.
+    </fixme>
+   </section>
+
+</body>
+</document>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/meta.xml
new file mode 100644
index 0000000..ffa06d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_index/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="dev@cocoon.apache.org">The Cocoon community</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/content_en.xdoc b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/content_en.xdoc
new file mode 100644
index 0000000..e7fa39d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/content_en.xdoc
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
+
+<document>
+
+  <header>
+    <title>Introducing Cocoon</title>
+    <authors>
+      <person name="Stefano Mazzocchi" email="stefano@apache.org"/>
+    </authors>
+  </header>
+
+  <body>
+
+    <s1 title="The XML Hype">
+
+<p>
+Everybody talks about XML. XML here, XML there. All application servers
+support XML, everybody wants to do B2B using XML, web services using
+XML, even databases using XML.
+</p>
+
+<p>
+Should you care about it? Given the amount of hype, you can't afford to
+go around ignoring XML, for that would be like ignoring the World Wide
+Web 10 years ago: a clear mistake. But why is this so for XML? What is
+this "magic" that XML seems to have in solving your problems? Isn't this
+another hype to change once again the IT infrastructure that you spent
+so much time implementing and fixing in the last few years? Isn't
+another way to spill money out of your pockets?
+</p>
+
+<p>
+If you ever asked yourself one of the above questions, this paper is for
+you. You won't find singing-and-dancing marketing hype, you won't find
+boring and useless feature lists, you won't find the usual acronym
+bombing or those good looking vaporware schemas that connect your
+databases to your coffee machines via CORBA or stuff like that.
+</p>
+
+<p>
+This document will explain you what the Cocoon project is about and what we are
+doing to solve the problems that we encountered in our web engineering
+experiences, but from an executive perspective, yes, because we all had
+the problems of managing a web site, dealing with our colleagues, rushing
+to the graphical guru to have the little GIF with the new title, or
+calling the web administrator at night because the database is returning
+errors without reasons.
+</p>
+
+<p>
+It was frustrating to see the best and most clever information
+technology ever invented--the Web--ruined by the lack of engineering
+practices, tortured by those "let's-reinvent-the-wheel-once-again"
+craftsmen who were great at doing their jobs as individuals but
+could not scale within teams, imposing a growth saturation to their projects.
+</p>
+
+<p>
+There had to be a better way of doing things.
+</p>
+
+    </s1>
+
+
+    <s1 title="Personal Experiences">
+
+<p>
+In 1998, Stefano Mazzocchi volunteered to create the documentation infrastructure for
+the java.apache.org project, which is composed of a bunch of different
+codebases, maintained by a bunch of different people, with different
+skills, different geographical locations and different degree of will
+and time to dedicate to the documentation effort.
+</p>
+
+<p>
+But pretty soon he realized that no matter how great and well designed the
+system was, HTML was a problem: it was *not* designed for those kinds of
+things. By looking at the main page (<link href="http://java.apache.org/">http://java.apache.org/</link>) from the
+browser, you can clearly identify the areas of the screen: sidebar,
+topbar, news, status. But if you viewed the underlying HTML, boom: a nightmare of
+table tags and nesting and small little tricks to make the HTML appear
+the same on every browser.
+</p>
+
+<p>
+So he looked around for alternative technologies, but *all* of them were
+trying to add more complexity at the GUI level (Microsoft Frontpage,
+Macromedia Dreamweaver, Adobe GoLive, etc...) hoping to "hide" the
+design problems of HTML under a thick layer of WYSIWYG looks.
+</p>
+
+<p>
+What you see is what you get.
+</p>
+
+<p>
+But what you see is all you've got.
+</p>
+
+<p>
+How can you tell your web server to extract the information contained within the
+sidebar? How can you tell it to find the news articles within a complex HTML page?
+</p>
+
+<p>
+It's certainly easy for a human reader: just look at the page and you should have
+no problem distinguishing between a sidebar, a banner, a news and a stock
+quote. Why is it so hard for a machine?
+</p>
+
+    </s1>
+
+    <s1 title="The HTML Model">
+
+<p>
+HTML is a language that tells your browser how to "draw" things on its
+window. An image here, a letter there, a color down here. Nothing more.
+The browser doesn't have the "higher level" notion of "sidebar": it
+lacks the ability to perform "semantic analysis" of the HTML content.
+</p>
+
+<p>
+Semantic analysis? Yeah, it's the kind of thing the human brain is
+simply great at doing, while computer programs simply fail at big time.
+</p>
+
+<p>
+So, with HTML, we went a step up and created a highly visual and
+appealing web of HTML content, but we went two steps back by removing
+all the higher level semantic information from the content itself.
+</p>
+
+<p>
+Ok, let's make an example...  most of you have seen an HTML
+page... if not, here is an example:
+</p>
+
+<source><![CDATA[
+ <html>
+  <body>
+   <p>Hi, I'm an HTML page</p>
+   <p align="center">Written by Stefano</p>
+  </body>
+ </html>
+]]></source>
+
+<p>
+which says to the browser:
+</p>
+
+<ul>
+ <li>I'm a HTML page</li>
+ <li>I have a body</li>
+ <li>I have a paragraph</li>
+ <li>I contain the sentence "Hi, I'm an HTML page."</li>
+ <li>I contain the sentence "Written by Stefano"</li>
+</ul>
+
+<p>
+Suppose you are a Chinese guy that doesn't understand our alphabet, try
+to answer the following question:
+</p>
+
+<p>
+Who wrote the page?
+</p>
+
+<p>
+You can't perform semantic analysis, you are as blind as a web browser.
+The only thing you can do is draw it on the screen since this is what
+you were programmed to do. In other words, your semantic capacity is
+fixed to the drawing capabilities and a few other things (like linking),
+thus limited.
+</p>
+
+    </s1>
+
+    <s1 title="Semantic Markup">
+    <moved author="BD" href="site:concepts.html">
+      This section has moved to the "concepts" document - if the
+      linking works, there should be a link to the new location
+      at the beginning of his note.
+    </moved>
+    </s1>
+
+    <s1 title="The XML Language">
+
+<p>
+XML is most of the times referred to as the "eXtensible Markup Language"
+specification. A fairly small yet complex specification that indicates
+how to write languages. It's a syntax. To tell you the truth, nothing fancy at all. So
+</p>
+
+<source><![CDATA[
+ <hello></hello>
+]]></source>
+
+<p>
+is correct, while
+</p>
+
+<source><![CDATA[
+ <hello></hi>
+]]></source>
+
+<p>
+is not, but
+</p>
+
+<source><![CDATA[
+ <hello><hi/></hello>
+]]></source>
+
+<p>
+is correct. That's more than this, but I'll skip the technical details here.
+</p>
+
+<p>
+XML is the ASCII for the new millenium, it's a step forward from ASCII
+or UNICODE (the international extension to ASCII that includes all
+characters from all modern languages). It defines a "lingua franca" for
+textual languages.
+</p>
+
+<p>
+Ok, great, so now instead of having one uniform language with visual
+semantics (HTML) we have a babel of languages each with its own
+semantics. How this can possibly help you?
+</p>
+
+    </s1>
+
+    <s1 title="XML Transformations">
+
+<p>
+This was the point where Stefano was more or less two years ago for
+java.apache.org: I could use XML and define my own semantics with
+<![CDATA[<sidebar>]]>, <![CDATA[<news>]]>, <![CDATA[<status>]]> 
+and all that and I'm sure people would have
+found those XML documents much easier to write (since the XML syntax is
+very similar to the HTML one and very user friendly)... but I would have
+moved from "all browsers" to "no browser".
+</p>
+
+<p>
+And having documentation that nobody can browse is totally useless.
+</p>
+
+<p>
+The turning point was the creation of the XSL specification which
+included a way to "transform" an XML page into something else. (It's
+more complex than this, but, again, I'll skip the technical details).
+</p>
+
+<p>
+So now you have:
+</p>
+
+<source><![CDATA[
+ XML page ---(transformation)--> HTML page
+                    ^
+                    |
+          transformation rules
+]]></source>
+
+<p>
+that allows you to write your pages in XML, create your "graphics" as
+transformation rules and generate HTML pages on the fly directly from your
+web server.
+</p>
+
+<p>
+Apache Cocoon 1.0 did exactly this.
+</p>
+
+    </s1>
+
+    <s1 title="The Model Evolves">
+
+<p>
+If XML is a lingua franca, it means that XML software can work on almost
+anything without caring about what it is. So, if a cell phone requests
+the page, Cocoon just has to change transformation rules and send the
+WAP page to the phone. Or, if you want a nice PDF to printout your
+monthly report, you change the transformation rules and Cocoon creates
+the PDF for you, or the VRML, or the VoiceML, or your own proprietary
+B2B markup.
+</p>
+
+<p>
+Anything without changing the basic architecture that is simply based on
+the simple "angle bracket" XML syntax.
+</p>
+
+    </s1>
+
+    <s1 title="Separation of Concerns (SoC)">
+      <moved author="BD" href="site:concepts.html">
+        This section has moved to the "concepts" document - if the
+        linking works, there should be a link to the new location
+        at the beginning of his note.
+      </moved>
+
+    </s1>
+
+    <s1 title="Here we go">
+
+<p>
+If you've reached this far in my text, you should be able to grasp the
+value of the Cocoon Project as well as distinguish most of the marketing
+hype that surrounds XML and friends.
+</p>
+
+<p>
+Just like you shouldn't care if somebody offers you software that is
+"ASCII compliant" or "ASCII based", you shouldn't care about "XML
+compliant" or "XML based": it doesn't mean anything.
+</p>
+
+<p>
+Cocoon uses XML as a core piece of its framework, but improves the model
+to give you the tools you need and is designed to be flexible enough to
+follow your current needs as well as paradigm shifts that may happen in the
+future.
+</p>
+
+    </s1>
+
+  </body>
+</document>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/meta.xml
new file mode 100644
index 0000000..ad6f58c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/c21_introduction/meta.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="dev@cocoon.apache.org">The Cocoon community</author>
+  </authors>
+  <source>legacy.21</source>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/comments_en.xml
new file mode 100644
index 0000000..c926b66
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/comments_en.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<comments>
+    <!-- hide this for now
+    <comment name="Reinhard Poetz" by="http://www.poetz.cc" subject="the first comment">
+        my first comment
+    </comment>
+    -->
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/content_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/content_en.xml
new file mode 100644
index 0000000..184c624
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/content_en.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0"?>
+<html>
+    <head>
+        <title>Cocoon concepts</title>
+    </head>
+    <body>
+        <h1>Overview</h1>
+        <p>
+            This document gives a brief overview of the most important
+            concepts used in Cocoon.
+        </p>
+
+        <h1>Separation of Concerns (SoC)</h1>
+        <p>We believe the single most important Cocoon innovation is SoC-based design.</p>
+
+        <p>SoC is something that you've always been aware of: not everybody is equal,
+    not everybody performs the same job with the same ability.</p>
+
+        <p>It can be observed that separating people with common skills in different
+    working groups increases productivity and reduces management costs, but only
+    if the groups do not overlap and have clear "contracts" that define their
+    operability and their concerns.</p>
+
+        <p>For a web publishing system, the Cocoon project uses what we call the
+            <em>pyramid of contracts</em>, with four major concern areas and five
+            contracts between them:
+        </p>
+
+        <img alt="The Cocoon Pyramid Model of Contracts" src="files/pyramid-model.gif"/>
+        <p>
+            Cocoon is <em>engineered</em> to provide you a way to isolate these four
+            concern areas using just those 5 contracts, removing the contract
+            between style and logic that has been bugging web site development since
+            the beginning of the Web.
+        </p>
+        <p>
+            Let's have an example:
+        </p>
+        <pre class="code">
+&lt;page&gt;
+    &lt;content&gt;
+        &lt;para&gt;Today is &lt;dynamic:today/&gt;&lt;/para&gt;
+    &lt;/content&gt;
+&lt;/page&gt;
+        </pre>
+        <p>
+            Such a page is written by the content writers and you give them the
+            "contract" that states that the tag &lt;dynamic:today/&gt; prints out the time of the day
+            when included in the page. Content writers don't care (nor
+            should) about what language has been used for that, nor they
+            can mess up with the programming logic that generates the
+            content since it's stored in another part of the system they
+            don't have access to.
+        </p>
+        <p>
+            So &lt;dynamic:today/&gt; is the "logic - content" contract.
+        </p>
+        <p>
+            At the same time, the structure of the page is given as a contract to
+            the graphic designers who have to come up with the transformation rules
+            that transform this structure in a language that the browser can
+            understand (HTML, for example).
+        </p>
+        <p>
+            So, the page structure is the "content - style" contract.
+        </p>
+        <p>
+            As long as these contracts don't change, the three areas can work in a
+            completely parallel way without overwhelming the human resources used to
+            manage them: costs decrease because time to market is reduced and
+            maintenance costs is decreased because errors do not propagate out of
+            the concern areas.
+        </p>
+        <p>
+            For example, you can tell your designers to come up with a "Xmas look"
+            for your web site, without even telling the other people: just switch to
+            the Xmas transformation rules on Xmas morning and you're done.... just
+            imagine how painful it would be to do this on your web site today.
+        </p>
+        <p>
+            With the Cocoon architecture all this is a couple of line changes away.
+        </p>
+
+        <h1>Semantic markup</h1>
+        <p>
+            Although it is not a Cocoon invention, <em>semantic markup</em> is
+            very important to work efficently with Cocoon.
+        </p>
+        <p>
+            By <em>semantic markup</em> we mean a way of building XML documents
+            and models which preserves semantic information (metadata) as much as possible,
+            by keeping the data in structured format and moving to presentation
+            formats as late as possible in the document transformation process.
+        </p>
+        <p>
+            This document, for example:
+            <pre class="code">
+&lt;page&gt;
+    &lt;author id="3243"&gt;Will Coyote&lt;author&gt;
+    &lt;created&gt;2005-03-12&lt;/created&gt;
+    &lt;revision&gt;1.42&lt;/revision&gt;
+    &lt;content&gt;
+        Once upon a time, John made a &lt;b&gt;bold&lt;/b&gt; move...
+    &lt;/content&gt;
+&lt;/page&gt;
+            </pre>
+            contains structured information, that can be filtered and selected
+            at Will to generate different presentations.
+        </p>
+        <p>
+            As you can see, there's nothing very sophisticated about semantic
+            markup: the basic idea is to keep <em>everything that is known</em>
+            about a given document or piece of information in a structured format.
+            This makes it possible to precisely select the information elements
+            that must be published, and to format them in as many ways as needed.
+        </p>
+
+        <h1>The sitemap</h1>
+        <p>
+            The <em>sitemap</em> is a central component of any Cocoon application,
+            acting as a very powerful <em>request dispatcher</em>. It was the single most
+            important innovation of Cocoon 2, and it is not going away soon: we <em>love</em> its power!
+        </p>
+        <p>
+            The main role of the sitemap is to trigger the execution of <em>pipelines</em>
+            to process client requests. The sitemap uses <em>matchers</em> to select
+            which pipeline to execute, matching various attributes of the incoming request
+            (often the request path, but many other attributes can be used) to activate
+            the first pipeline which matches the incoming request.
+        </p>
+        <p>
+            Here are a few examples of matchers:
+            <pre class="code">
+&lt;map:match pattern="*.html"&gt;
+    ...pipeline definition goes here
+            </pre>
+            This pipeline would be activated for any request for a filename which
+            ends in <em>*.html</em>.
+
+            <pre class="code">
+&lt;map:match pattern="**/resources/css/*.css"&gt;
+    ...pipeline definition goes here
+            </pre>
+            This pipeline would be activated for requests having paths like
+            <em>something/resources/css/mystyles.css</em>
+            or
+            <em>a/b/c/d/resources/css/mystyles.css</em>
+        </p>
+        <p>
+            Sitemap variables give access to the matched parts of the request,
+            for example to apply a common XSLT transform to all XML files found
+            in a given directory:
+            <pre class="code">
+&lt;map:match pattern="**/*.html"&gt;
+    &lt;map:generate src="content/{1}/{2}.xml"/&gt;
+    &lt;map:transform src="xslt/my-transform.xsl"/&gt;
+    &lt;map:serialize type="html"/&gt;
+&lt;/map:match&gt;
+            </pre>
+            For the request <em>docs/planets/mars.html</em>, this pipeline would
+            use the XML file <em>content/docs/planets/mars.xml</em> for input,
+            process it with the <em>xslt/my-transform.xsl</em> XSLT transform,
+            and send the result as an HTML document to the client. The double
+            star (**) in the matcher pattern matches a path, while a single star matches
+            a filename.
+        </p>
+        <p>
+            This last example also introduces the usual components of a pipeline:
+            the <em>Generator</em> produces XML data, zero or more <em>Transformers</em>
+            process the XML and at the end a <em>Serializer</em> converts the XML
+            into the appropriate format and defines the <em>Content-Type</em> of the
+            output.
+        </p>
+        <note>
+            The XML data passes as <em>SAX events</em> from one component to the
+            next in the pipeline.
+        </note>
+        <p>
+            There's much more to the sitemap: it can contain component definitions,
+            define <em>views</em> to make the various stages of the pipeline available
+            for debugging, define <em>flowscripts</em> to act as the glue between
+            pages, and several other things that we'll discuss at a later point. Sitemaps
+            can also be "mounted" to create hierarchies of sitemaps and modularize
+            applications.
+        </p>
+
+        <h1>Flow</h1>
+        <fixme author="BD">
+            TODO: a brief description of this might be good here to
+            have all the critical concepts in a single document.
+        </fixme>
+
+        <h1>Cocoon Forms</h1>
+        <fixme author="BD">
+            TODO: a brief description of this might be good here to
+            have all the critical concepts in a single document.
+        </fixme>
+
+        <h1>Business logic</h1>
+        <fixme author="BD">
+            TODO: a brief description of this might be good here to
+            have all the critical concepts in a single document.
+            <p>
+                Talk about the integration of Java code, REST backends, etc.
+            </p>
+        </fixme>
+    </body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/files/pyramid-model.gif b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/files/pyramid-model.gif
new file mode 100644
index 0000000..6217034
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/files/pyramid-model.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/meta.xml
new file mode 100644
index 0000000..69605bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/concepts/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://www.poetz.cc">Reinhard Poetz</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/content_en.html
new file mode 100644
index 0000000..2a68427
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/content_en.html
@@ -0,0 +1,219 @@
+<?xml version="1.0"?>
+<html>
+<head>
+<title>Building your own Cocoon project using Ant</title>
+</head>
+<body>
+<h1>Building your own Cocoon project using Ant</h1>
+<p>
+Now that you've studied Cocoon and you are convinced it is worth 
+spending your time on, you want to try your hand at your own project.
+There are several ways to start your own project. This is just one of them.
+</p>
+<p>
+The following HOW-TO helps you to create your own project in a subdirectory of the Cocoon root. 
+It also has its own subsitemap.
+The main advantage of this configuration is the fact that you can leave the original Cocoon 
+root sitemap intact. 
+Since it is set up in a pretty generic way and accommodating most types of generators, 
+transformers and serializers, it provides a working environment that you don't have to understand 
+thoroughly before you are able to use it. Instead, you can work the other way around. Once you 
+understand a part of the root sitemap you can tune it to your needs.
+</p>
+<p>
+Another advantage of this configuration is the strict separation of the files that are part of 
+Cocoon and those that are part of your project. The separation allows you to update Cocoon without 
+overwriting vital modifications. Or you can develop your webapp against different Cocoon 
+distributions.
+<br/>
+<b>Note:</b> This configuration will work with Cocoon 2.1.X distributions and maybe more recent.
+It will probably be more difficult to get this working with an older distribution.
+</p>
+
+<h2>Initial setup</h2>
+<p>
+The following steps explain how to set up this configuration. These steps will only be performed once. 
+You will work from the commandline.
+</p>
+<ol>
+<li>Get the Cocoon distribution. You can either download a release build or dive in and get the latest HEAD from SVN.</li>
+<li>Make a separate project directory and put <i>build-cocoon-targets.xml</i> in this directory.</li>
+<li>&quot;Seed&quot; the project by running the following on the commandline:
+<pre>ant -f build-cocoon-targets.xml -Dcocoon.distro.home=/path/to/your/cocoon/distribution</pre></li>
+<p>
+<b>Note:</b> Either you have ANT_HOME set to the appropriate directory or you use the full path to Ant.<br/>
+<b>Note:</b> The <i>cocoon.distro.home</i> is now set in <i>user.properties</i>.<br/>
+<b>Note for Windows users:</b> set the slashes as forward slashes.</p>
+<li>Customize the <i>src/cocoon/local.build.properties</i> and remove the 
+path variables in this file. Ant cannot substitute variables in property files, 
+so ${...} variables would cause build errors. 
+Remove the sections <i>build, build webapp, src, standalone demo, dir layout, tools, 
+deprecated, ide, lib, dist, site, legal, gump</i>, so that there are no more ${...} and variables in this file.</li>
+<li>Exclude all blocks you don't need in the top part of <i>local.build.properties</i>.</li>
+<li>Exclude the samples and documentation too if you don't need them. The build process is time consuming.</li>
+<li>Run the following command from the commandline:
+<pre>ant cocoon:get</pre>
+<b>Note:</b>This will only be done when changing the distribution or the settings in <i>local.build.properties</i>.</li>
+
+<li>Run the following command from the commandline:
+<pre>ant webapp</pre>
+This builds the Java classes and copies the entire project to the tools tree.<br/>
+<b>Note:</b> classes are built with <i>debug</i> flag on.</li>
+<li>Run the following command from the commandline:
+<pre>ant cocoon:run</pre>
+This starts Jetty with Cocoon and your project in it.<br/>
+<b>Note:</b> Default Cocoon is configured to automatically reload files that are changed. 
+This way Jetty can keep running while you develop your project. You only have to restart when the previous step
+has done any of the following:
+<ul>
+<li>changed any of the libraries,</li>
+<li>compiled java classes.</li>
+</ul>
+</li>
+<li>Start up your favourite browser and enter the following:
+<pre>http://localhost:8888/</pre>
+You should now see the homepage of Cocoon.</li>
+<li>Check your (now still empty) project in in your CVS.</li>
+</ol>
+<p>
+This concludes the initial setup.
+</p>
+<h3>Example</h3>
+<p>If we execute the above steps on a Windows machine with the Cocoon distribution in 
+/SVN/cocoon and your project in /projects/myprojects, the 
+commands and the resulting information on your screen will look like this:
+</p>
+<pre>
+D:\projects>mkdir myproject
+
+D:\projects>copy build-cocoon-targets.xml myproject
+        1 file(s) copied.
+
+D:\projects>cd myproject
+
+D:\projects\myproject>\apache-ant-1.6.1\bin\ant -f build-cocoon-targets.xml -Dcocoon.distro.home=/SVN/cocoon
+Buildfile: build-cocoon-targets.xml
+
+seed-check:
+
+msg-seed-localprops:
+
+seed-dirs:
+    [mkdir] Created dir: D:\projects\myproject\src\cocoon
+    [mkdir] Created dir: D:\projects\myproject\src\cocoon\webapp
+    [mkdir] Created dir: D:\projects\myproject\src\cocoon\xconf
+    [mkdir] Created dir: D:\projects\myproject\tools\cocoon
+    [mkdir] Created dir: D:\projects\myproject\tools\cocoon\webapp
+    [mkdir] Created dir: D:\projects\myproject\src\java
+    [mkdir] Created dir: D:\projects\myproject\lib
+
+seed-localprops:
+
+msg-seed-cvsignore:
+
+seed-cvsignore:
+
+msg-seed-userprops:
+
+seed-userprops:
+
+msg-seed-build:
+
+seed-build:
+     [echo] Creating build.xml...
+
+seed:
+     [echo] Done.
+     [echo]
+     [echo]     The directory src/cocoon/webapp is created to hold your cocoon
+     [echo]     webapp resources.
+     [echo]     The directory src/cocoon/xconf is created to hold XConfPatch files
+     [echo]     to (optionally) modify the cocoon.xconf log.xconf web.xml and
+     [echo]     (root) sitemap.xmap
+     [echo]
+     [echo]     From here:
+     [echo]     ---------
+     [echo]     You should now edit the file ./src/cocoon/local.build.properties to select
+     [echo]     only those optional components of Cocoon that your project needs.
+     [echo]     IMPORTANT: Remove the path-entries from that file!
+     [echo]
+     [echo]     The build.xml can freely be extended for your project needs.
+     [echo]
+     [echo]     To build a fresh Cocoon base for this project
+     [echo]     (when you updated the distro pointed to by -Dcocoon.distro.home)
+
+     [echo]         > ant cocoon:get
+     [echo]
+     [echo]     To blend in your own project resources and classes:
+     [echo]         > ant webapp
+     [echo]
+     [echo]     To test-run using the Jetty container:
+     [echo]         > ant cocoon:run
+     [echo]
+
+BUILD SUCCESSFUL
+Total time: 1 second
+D:\projects\myproject>
+</pre>
+
+<h2>Directory layout</h2>
+<table style="border: 1px solid black">
+<tr><td><img src="files/dirlayout.png" /><br/>
+<i>Figure 1: Directory layout</i>
+</td></tr></table>
+<p>
+In figure 1 you can see the resulting directory layout. We'll discuss what each of these entries contain:
+<ul>
+<li><b>lib</b> This directory contains project dependant jars. Not the Cocoon jars, 
+since they are distribution dependent.</li>
+<li><b>src/java</b> Your own Java classes and components go here.</li>
+<li><b>src/cocoon/webapp</b> Add a directory &lt;yourProjectName&gt; here. This contains your
+Cocoon related files such as the sitemap, XSL and XML files.</li>
+<li><b>src/cocoon/xconf</b> Your modifications to the Cocoon configuration files go here.<br/>
+<b>Note:</b> See <!--<a href="xpatchusage">-->xpatchusage<!--/a--> for an explanation of how to create these modifications.
+</li>
+<li><b>tools/cocoon/webapp</b> This will contain the resulting structure for Jetty to display. 
+The Cocoon jars, copied from the Cocoon distribution are put here too in <i>WEB-INF/lib</i>.</li>
+<li><b>build.xml</b> This will be your Ant buildfile. Modify it to your needs.</li>
+<li><b>user.properties</b> and <b>src/cocoon/local.build.properties</b> contain some variables
+such as cocoon.distro.home</li>
+</ul> 
+<h2>During development</h2>
+<p>
+The <i>build.xml</i> contains several useful targets, which we will explain below. <b>Note</b> that
+this file includes <i>build-cocoon-targets.xml</i>. Some of the targets below are in that file, so
+don't delete it!
+</p>
+<ul>
+<li><b>cocoon:get</b> Get Cocoon into your project. This target will compile the Cocoon 
+distribution using your <i>local.build.properties</i> and put the result in 
+<i>tools/cocoon/webapp</i>.</li>
+<li><b>cocoon:unpatch</b> During <i>cocoon:get</i> the original versions of vital Cocoon configuration
+files such as <i>sitemap.xmap, cocoon.xconf, web.xml</i> and <i>logkit.xml</i> are copied to
+<i>tools/cocoon/unpatched</i>. This target allows you to copy the original versions to their
+respective locations. Very convenient when you changed an xconf file that cannot be applied.</li>
+<li><b>webapp</b> Compile the Java classes in <i>src/java</i> and copy the relevant files in the
+source tree to the appropriate places under <i>tools/cocoon</i>. It also modifies the Cocoon
+configuration files using the xconf files.</li>
+<li><b>cocoon:run</b> Start up Jetty with your webapp. Your project can be reached under
+<pre>http://localhost:8888/yourProjectName</pre></li>
+</ul>
+
+<p>
+The <i>build-cocoon-targets.xml</i> file can be found <a href="files/build-cocoon-targets.xml">here</a>. <br/>
+<i>Credits go to Marc Portier for the content and the Ant build script.</i>
+</p>
+
+<h2>ToDo</h2>
+<ul>
+<li>Use Cocoon 2.2 import mechanism</li>
+<li>figure out the difference between the Ant 1.5 setup and the Ant 1.6 setup. OTOH: is this still necessary?</li>
+<li>check English (grammar, style, US vs EN)</li>
+<li>check if all is (still) accurate -&gt; it was as far as I can tell. </li>
+<li>Refer to this for adding it to Eclipse?</li>
+<li>create xpatchusage documentation</li>
+</ul>
+
+</body>
+</html>
+
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/build-cocoon-targets.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/build-cocoon-targets.xml
new file mode 100644
index 0000000..40b108b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/build-cocoon-targets.xml
@@ -0,0 +1,455 @@
+<?xml version="1.0"?>
+<!--
+This Apache Ant build.xml snippet contains targets for helping out 
+managing the Cocoon dependencies of your project.
+It assumes that you have Ant version 1.6.x or later that supports the 
+<import> task.
+
+Usage: [full automatic, for fresh projects starts]
+1) Copy this file to the root of your project
+   (e.g. to ./build-cocoon.targets.xml)
+2) ant -buildfile build-cocoon-targets.xml -Dcocoon.distro.home=/...abs_path_to_cocoon_src_distro...
+
+  this will generate a typical directory-structure containing:
+  ./build.xml  (minimal version to be completed to project needs)
+  ./user.properties (ready pointing to cocoon.distro.home)
+  ./src/cocoon/local.build.properties
+  ./src/cocoon/webapp
+  ./src/cocoon/xconf
+  .cvsignore (ignoring build and tools/cocoon/*)
+  
+  You manually start changing these as you go allong with your project.
+
+  The script will not overwrite files that already exist.
+
+Usage: [manual, for existing build.xml files]
+1) Copy this file to the root of your project
+   (e.g. to ./build-cocoon.targets.xml)
+2) Add the following to the top-level of your project's Ant build.xml script (possibly adjusting the path):
+   
+   <property name="cocoon.targets" value="./build-cocoon.targets.xml">
+   <import file="${cocoon.targets}">
+
+3) Add in various properties assumed to be available (change the paths to your own liking)
+
+   <property file="user.properties">
+   <property name="src" value="./src" />
+   <property name="src.cocoon" value="${src}/cocoon" />
+   <property name="cocoon.build.properties" value="${src.cocoon}/local.build.properties">
+   <property name="cocoon.xconf.dir" value="${src.cocoon}/xconf">
+   <property name="cocoon.tool.dir" value="tools/cocoon">
+
+
+How it works:
+
+All targets in this build file snippet depend upon 
+the following properties being set
+  1. cocoon.distro.home
+       location of src distribution of cocoon to use
+  2. cocoon.build.properties
+       property file with specific cocoon build settings
+       (selecting which blocks, samples,...)
+       typically src/cocoon/local.build.properties
+  3. cocoon.xconf.dir
+       location where the appropriate patch files can be found
+       typically src/cocoon/xconf
+  4. cocoon.tool.dir
+       where cocoon is build inside your project
+       typically this is tools/cocoon
+
+Updates and Background:
+http://wiki.cocoondev.org/Wiki.jsp?page=YourCocoonBasedProject
+-->
+<project name="YourCocoonBasedProject" default="seed" >
+
+  <!-- if not set yet... -->
+  <property file="user.properties" />
+  <property name="src" value="./src" />
+  <property name="src.cocoon" value="${src}/cocoon" />
+  <property name="cocoon.build.properties" value="${src.cocoon}/local.build.properties" />
+  <property name="cocoon.xconf.dir" value="${src.cocoon}/xconf" />
+  <property name="cocoon.tool.dir" value="tools/cocoon" />
+  <property name="cocoon.unpatched" value="${cocoon.tool.dir}/unpatched"/>
+
+  <!--
+    sets some essential properties for these targets
+  --> 
+  <target name="-cocoon:init">
+    <mkdir dir="${cocoon.tool.dir}" />
+    <property name="cocoon.webapp" value="${cocoon.tool.dir}/webapp" />
+    <property name="cocoon.tasks" value="${cocoon.tool.dir}/taskdefs" />
+    <property name="cocoon.lib" value="${cocoon.webapp}/WEB-INF/lib" />    
+  </target>
+
+  <!--
+    checks what kind of OS this is running on
+  -->
+  <target name="-cocoon:oscheck" >
+    <condition property="isWindows">
+      <os family="windows" />
+    </condition>
+  </target>
+    
+  <!--
+    creates Windows batch files for cocoon dependencies
+  -->
+  <target name="-cocoon:bat" if="isWindows"
+          depends="-cocoon:init, -cocoon:oscheck" >
+    <echo>Building batch files for support on windows OS</echo>
+    <property name="shbat" value="bat" />
+
+    <echo file="${cocoon.tool.dir}/getc2.${shbat}"><![CDATA[@echo off 
+if "%COCOON_HOME%"=="" then echo You haven't set the COCOON_HOME environment variable.
+echo GOING TO %COCOON_HOME%
+cd /d %COCOON_HOME%
+echo Running build.bat -propertyfile %PROJECT_PROPERTIES% clean webapp -Dbuild.webapp=%PROJECT_WEBAPP% -Dtools.tasks.dest=%PROJECT_TASKDEFS%
+build.bat -propertyfile %PROJECT_PROPERTIES% clean webapp -Dbuild.webapp=%PROJECT_WEBAPP% -Dtools.tasks.dest=%PROJECT_TASKDEFS% 
+]]></echo>
+
+    <echo file="${cocoon.tool.dir}/runc2.${shbat}"><![CDATA[@echo off
+set JETTY_WEBAPP=%PROJECT_WEBAPP%
+cd /d %COCOON_HOME%
+cocoon.bat servlet-debug
+]]></echo>
+  </target>
+
+  <!--
+    creates shell scripts for cocoon dependencies
+  -->
+  <target name="-cocoon:sh" unless="isWindows"
+          depends="-cocoon:init, -cocoon:oscheck" >
+
+    <echo>Building shell scripts for support on non-windows</echo>
+    <property name="shbat" value="sh" />
+
+    <echo file="${cocoon.tool.dir}/getc2.${shbat}"><![CDATA[#!/bin/sh
+cd $COCOON_HOME
+echo running /build.sh -propertyfile $PROJECT_PROPERTIES clean webapp -Dbuild.webapp=$PROJECT_WEBAPP -Dtools.tasks.dest=$PROJECT_TASKDEFS
+./build.sh -propertyfile $PROJECT_PROPERTIES clean webapp -Dbuild.webapp=$PROJECT_WEBAPP -Dtools.tasks.dest=$PROJECT_TASKDEFS
+]]></echo>
+       <chmod file="${cocoon.tool.dir}/getc2.${shbat}" perm="u+x"/>
+
+    <echo file="${cocoon.tool.dir}/runc2.${shbat}"><![CDATA[#!/bin/sh
+export COCOON_WEBAPP_HOME=$PROJECT_WEBAPP
+echo COCOON_WEBAPP_HOME=$COCOON_WEBAPP_HOME
+cd $COCOON_HOME
+./cocoon.sh servlet-debug
+]]></echo>
+        <chmod file="${cocoon.tool.dir}/runc2.${shbat}" perm="u+x"/>
+    </target>    
+
+  <!--
+    creates as needed batch files or shell scripts
+  -->
+  <target name="-cocoon:shbat" depends="-cocoon:bat, -cocoon:sh" />
+
+  <!--
+    checks if the cocoon dependency is holding what we expect 
+    sets a variable if all is ok
+  -->
+  <target name="-cocoon:test" depends="-cocoon:init">
+    <condition property="cocoon.ok" value="true">
+      <and>
+        <available type="dir" file="${cocoon.lib}" />
+        <available classname="XConfToolTask" 
+                   classpath="${cocoon.tasks}"/>
+      </and>
+    </condition>
+  </target>
+
+  <!--
+    fails the build if the cocoon dependency is not met
+  -->
+  <target name="-cocoon:check" depends="-cocoon:test" unless="cocoon.ok">
+    <fail>No cocoon available. Run 'ant cocoon.get' first.</fail>
+  </target>
+
+
+  <target name="-cocoon:patch">
+    <echo>Patching ${cocoon.patch.target} with 
+${cocoon.xconf.dir}/*.${cocoon.patch.src-extension} ...</echo>
+    <xpatch 
+      file="${cocoon.patch.target}"
+      srcdir="${cocoon.xconf.dir}" 
+      includes="**/*.${cocoon.patch.src-extension}"/>
+    </target>
+
+  <!-- 
+      applies the patch files in the ${cocoon.xconf.dir} 
+      on the various cocoon conf files
+  -->
+  <target name="cocoon:xconf" depends="-cocoon:check">
+    <path id="cocoon.tasks.cp">
+      <pathelement path="${cocoon.tasks}" />
+      <path>
+        <fileset dir="${cocoon.lib}">
+          <include name="xalan*.jar" />
+          <include name="xerces*.jar" />
+          <include name="xml*.jar" />
+        </fileset>
+      </path>
+    </path>
+
+    <taskdef 
+        name="xpatch" 
+        classname="XConfToolTask" 
+        classpathref="cocoon.tasks.cp"/>  
+
+    <xpatch file="${cocoon.webapp}/WEB-INF/cocoon.xconf" srcdir="">
+      <include name="${cocoon.xconf.dir}/*.xconf"/>
+    </xpatch>
+
+    <antcall target="-cocoon:patch" >
+      <param name="cocoon.patch.target" 
+           value="${cocoon.webapp}/WEB-INF/cocoon.xconf" />
+      <param name="cocoon.patch.src-extension" 
+           value="xconf" />
+    </antcall>
+
+    <antcall target="-cocoon:patch" >
+      <param name="cocoon.patch.target" 
+           value="${cocoon.webapp}/WEB-INF/logkit.xconf" />
+      <param name="cocoon.patch.src-extension" 
+           value="xlog" />
+    </antcall>
+
+    <antcall target="-cocoon:patch" >
+      <param name="cocoon.patch.target" 
+           value="${cocoon.webapp}/sitemap.xmap" />
+      <param name="cocoon.patch.src-extension" 
+           value="xmap" />
+    </antcall>
+
+    <antcall target="-cocoon:patch" >
+      <param name="cocoon.patch.target" 
+           value="${cocoon.webapp}/WEB-INF/web.xml" />
+      <param name="cocoon.patch.src-extension" 
+           value="xweb" />
+    </antcall>
+  </target>
+
+  <target name="cocoon:unpatch">
+    <copy todir="${cocoon.webapp}" overwrite="true" >
+      <fileset dir="${cocoon.unpatched}">
+        <include name="WEB-INF/web.xml" />
+        <include name="WEB-INF/cocoon.xconf" />
+        <include name="WEB-INF/logkit.xconf" />
+        <include name="sitemap.xmap" />
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="cocoon:get" depends="-cocoon:shbat" description="Get cocoon into this project">
+      <mkdir dir="${cocoon.webapp}" />
+      <exec executable="${cocoon.tool.dir}/getc2.${shbat}" >
+        <env key="COCOON_HOME" file="${cocoon.distro.home}" />
+        <env key="PROJECT_PROPERTIES" file="${cocoon.build.properties}" />
+        <env key="PROJECT_WEBAPP" file="${cocoon.webapp}" />
+        <env key="PROJECT_TASKDEFS" file="${cocoon.tasks}" />
+      </exec>
+      <mkdir dir="${cocoon.unpatched}" />
+      <copy todir="${cocoon.unpatched}">
+        <fileset dir="${cocoon.webapp}" >
+          <include name="WEB-INF/web.xml" />
+          <include name="WEB-INF/cocoon.xconf" />
+          <include name="WEB-INF/logkit.xconf" />
+          <include name="sitemap.xmap" />
+        </fileset>
+      </copy>
+  </target>
+
+  <target name="cocoon:run" depends="-cocoon:shbat, -cocoon:check" description="Run cocoon on the built-in jetty to test">
+      <exec executable="${cocoon.tool.dir}/runc2.${shbat}" >
+        <env key="COCOON_HOME" file="${cocoon.distro.home}" />
+        <env key="PROJECT_WEBAPP" file="${cocoon.webapp}" />
+      </exec>
+  </target>
+
+
+  <!-- 
+  Below are some targets that build a default project-setting which allows you to 
+  make use of the reusable targets declared in this build-script.
+
+  You can launch the 'seed' target to start-off your project.
+  -->
+  <target name="seed-check">
+    <available property="cocoonHomeOk" file="${cocoon.distro.home}" />
+    <fail unless="cocoonHomeOk" >
+    This script needs a property $${cocoon.distro.home} to be set and 
+    pointing to an existing directory containing a cocoon 2.1.x distro.
+    You can set it either by providing a -D flag to ant, or 
+    by adding it to a local ./user.properties.
+    </fail>
+
+    <available property="existsBuild" file="build.xml" />
+    <available property="existsLocalProps" file="${cocoon.build.properties}" />
+    <available property="existsUserProps" file="user.properties" />
+    <available property="existsCvsIgnore" file=".cvsignore" />
+  </target>
+
+  <target name="msg-seed-build" if="existsBuild">
+    <echo>build.xml exists. This script cannot overwrite it.
+    If you want to regenerate the build.xml then manually delete it prior to running the seed target again.</echo>
+  </target>
+
+  <target name="seed-build" depends="msg-seed-build" unless="existsBuild">
+    <echo>Creating build.xml...</echo>
+    <echo file="build.xml"><![CDATA[<?xml version="1.0"?>
+<!-- 
+  File automatically generated by ant script for YourCocoonBasedProject.
+  Manually extend it to your own needs.
+  -->
+<project name="YourProjectName" default="init">
+  <property file="user.properties" />
+
+  <property name="src"              value="src" />
+  <property name="src.java"         value="${src}/java" />
+  <property name="src.cocoon"       value="${src}/cocoon" />
+  <property name="src.webapp"       value="${src.cocoon}/webapp" />
+  
+  <property name="build"            value="build" />
+  <property name="build.classes"    value="${build}/classes" />
+  <property name="zipfile"          value="${build}/${ant.project.name}.zip" />
+  <property name="warfile"          value="${build}/${ant.project.name}.war" />
+
+  <property name="lib"            value="lib" />
+
+  <property name="cocoon-build.properties" value="${src.cocoon}/local.build.properties" />
+  <property name="cocoon-xconf.dir" value="${src.cocoon}/xconf" />
+  <property name="cocoon-tool.dir"  value="tools/cocoon" />
+  <property name="cocoon.webapp"    value="${cocoon-tool.dir}/webapp" />
+  <property name="cocoon.lib"       value="${cocoon.webapp}/WEB-INF/lib" />
+  <property name="cocoon.classes"   value="${cocoon.webapp}/WEB-INF/classes" />
+
+  <property name="cocoon-targets" value="${ant.file}" />
+  <!-- insert properties here to override defaults in the import cocoon-targets script -->
+  <import file="$${cocoon-targets}" />
+
+  <path id="all.cp">
+    <pathelement location="${build.classes}" />
+    <fileset dir="${cocoon.lib}">
+      <include name="*.jar"/>
+    </fileset>
+    <fileset dir="${lib}">
+      <include name="*.jar"/>
+    </fileset>
+  </path>
+  
+  <target name="init">
+    <mkdir dir="${build.classes}" />
+  </target>
+  
+  <target name="compile" depends="init,-cocoon:check" >
+    <javac srcdir="${src.java}" destdir="${build.classes}" debug="true" >
+      <classpath refid="all.cp"/>
+      <include name="**/*.java"/>
+    </javac>
+  </target>
+
+  <target name="webapp" depends="compile, cocoon:xconf"
+          description="configure the webapp">
+    <copy todir="${cocoon.lib}">
+      <fileset dir="${lib}">
+        <include name="*.jar"/>
+      </fileset>
+    </copy>
+    <copy todir="${cocoon.classes}">
+      <fileset dir="${build.classes}" />
+    </copy>
+    <copy todir="${cocoon.webapp}">
+      <fileset dir="${src.webapp}" />
+    </copy>          
+  </target>  
+
+  <target name="zip" depends="init">
+    <zip zipfile="${zipfile}" basedir="." excludes="**/build/**, tools/**" />
+  </target>
+
+  <target name="war" depends="webapp" >
+    <jar destfile="${warfile}" basedir="${cocoon.webapp}" />
+  </target>
+  
+</project>
+    ]]></echo>
+  </target>
+  
+  <target name="seed-dirs">
+    <mkdir dir="${src.cocoon}" />
+    <mkdir dir="${src.cocoon}/webapp" />
+    <mkdir dir="${cocoon.xconf.dir}" />
+    <mkdir dir="${cocoon.tool.dir}" />
+    <mkdir dir="${cocoon.tool.dir}/webapp" />
+    <mkdir dir="src/java" />
+    <mkdir dir="lib" />
+  </target>
+  
+  <target name="msg-seed-userprops" if="existsUserProps">
+    <echo>user.properties already exists. This script cannot overwrite it.
+    If you want to regenerate the user.properties then manually delete it prior to running the seed target again.</echo>
+  </target>
+
+  <target name="seed-userprops" depends="msg-seed-userprops" unless="existsUserProps">
+    <echo file="user.properties">#
+# File automatically generated by ant script for YourCocoonBasedProject.
+# Manually extend it to your own needs.
+#
+cocoon.distro.home=${cocoon.distro.home}</echo>
+  </target>
+
+  <target name="msg-seed-cvsignore" if="existsCvsIgnore">
+    <echo>.cvsignore already exists. This script cannot overwrite it.
+    If you want to regenerate the .cvsignore then manually delete it prior to running the seed target again.</echo>
+  </target>
+
+  <target name="seed-cvsignore" depends="msg-seed-cvsignore" unless="existsCvsIgnore">
+    <echo file=".cvsignore">build
+tools
+user.properties</echo>
+  </target>
+
+  <target name="msg-seed-localprops" if="existsLocalProps" >
+    <echo>${cocoon.build.properties} already exists. This script cannot overwrite it.
+    If you want to regenerate the ${cocoon.build.properties} then manually delete it prior to running the seed target again.</echo>
+  </target>
+
+  <target name="seed-localprops" 
+          depends="msg-seed-localprops, seed-dirs" 
+          unless="existsLocalProps" >
+    <concat destfile="${cocoon.build.properties}" >
+      <fileset dir="${cocoon.distro.home}">
+        <include name="build.properties" />
+        <include name="blocks.properties" />
+      </fileset>
+    </concat>
+  </target>
+
+  <target name="seed" depends="seed-check, seed-localprops, seed-cvsignore, seed-userprops, seed-build">
+    <echo>Done.
+       
+    The directory src/cocoon/webapp is created to hold your cocoon 
+    webapp resources.
+    The directory src/cocoon/xconf is created to hold XConfPatch files 
+    to (optionally) modify the cocoon.xconf log.xconf web.xml and 
+    (root) sitemap.xmap
+
+    From here:
+    ---------
+    You should now edit the file ${cocoon.build.properties} to select 
+    only those optional components of Cocoon that your project needs.
+    IMPORTANT: Remove the path-entries from that file!
+    
+    The build.xml can freely be extended for your project needs.
+
+    To build a fresh Cocoon base for this project 
+    (when you updated the distro pointed to by -Dcocoon.distro.home)
+        > ant cocoon:get
+
+    To blend in your own project resources and classes:
+        > ant webapp
+
+    To test-run using the Jetty container:
+        > ant cocoon:run
+    </echo>
+  </target>
+</project>
+
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.png b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.png
new file mode 100644
index 0000000..03f9f6b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.png
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.psd b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.psd
new file mode 100644
index 0000000..86d648c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/dirlayout.psd
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/example-repository.zip b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/example-repository.zip
new file mode 100644
index 0000000..5bc1679
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/files/example-repository.zip
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/meta.xml
new file mode 100644
index 0000000..76b92ef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/custom-cocoon-based-project-using-ant/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="mailto:h.vanderlinden@mi.unimaas.nl">Helma van der Linden</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/comments_en.xml
new file mode 100644
index 0000000..7eec2c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/comments_en.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<comments>
+  <comment name="Reinhard Poetz" by="http://www.poetz.cc" subject="the first comment">
+    <p>Here follows the comment text.<strong>more</strong></p>
+  </comment>
+  <comment name="Reinhard Poetz" by="http://www.poetz.cc" subject="second comment">
+    <p>Here follows the comment text.<strong>more</strong></p>
+  </comment>  
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/content_en.html b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/content_en.html
new file mode 100644
index 0000000..f1c3adb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/content_en.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+  <title>Interpreted HTML (ihtml) demonstration page</title>
+</head>
+<body>
+
+<h1><a name="intro" />Interpreted HTML (ihtml) demonstration page</h1>
+		
+<p>This HTML document is used as the source for this page, and translated
+to the intermediate Apache Forrest xdocs document structure. The sitemap then
+does the normal aggregation with the navigation content and application of
+the skin.
+</p>
+
+<p>
+Note that this source file has the .ihtml filename extension. All requests to
+the sitemap for *.html are served by looking for matching *.ihtml source,
+or by the
+<a href="http://forrest.apache.org/faq.html#link_raw">"raw content"</a>
+method, or by the normal processing of structured xml xdocs format, or by
+other specialised xml processing.
+</p>
+
+<p>
+The ihtml is being interpreted by Forrest and transformed to the
+intermediate Apache xdocs document structure. That stylesheet cannot deal
+with every possibility in unstructured html, so it tries to guess how to
+build &lt;section&gt; elements and such.
+It needs &lt;h1&gt; (&lt;h2&gt; etc.) headings in the source ihtml
+(and the page must start with a h1 element). Patches are welcome to enhance
+that transformer.
+</p>
+
+<p>
+You can still take advantage of Forrest's
+<a href="http://forrest.apache.org/docs/linking.html">"<b>site:<b>"
+method of linking</a>, for example:
+<a href="site:index">&lt;a href="site:index"&gt;</a>
+</p>
+
+<hr>
+<p><b>Note:</b> XHTML can also be used, but it is just treated as interpreted
+html. Future versions of Forrest will take much more advantage of XHTML.
+</p>
+<hr>
+
+<h1><a name="examples" />Some example uses of ihtml</h1>
+<p>
+There are situations when the Apache Forrest xdocs DTD is not sufficient.
+This interpreted html enables such extra capabilities.
+</p>
+
+<h2><a name="js" />Embedded applets and Javascript</h2>
+      
+<p>
+See the
+<a href="javascript:alert('Opened with Javascript via the body of the source html.')">Javascript alert pop-up</a>
+</p>
+
+<h2><a name="forms" />HTML forms for user interaction</h2>
+<p>
+Search the Forrest website via Google:
+<!-- Search Google -->
+<form target="_blank" action="http://www.google.com/search" method="get">
+<input value="forrest.apache.org" name="as_sitesearch" type="hidden">
+<input type=hidden name=ie value=UTF-8>
+<input type=hidden name=oe value=UTF-8>
+<a href="http://www.google.com/">
+<img src="http://www.google.com/logos/Logo_40wht.gif" 
+border="0" alt="Google Search" align="middle" width="150" height="55"></a>
+<input type="text" name="as_q" size="25" maxlength="255" value="ihtml">
+&nbsp;
+<input type="submit" name="btnG" value="Google Search">
+</form>
+<!-- Search Google -->
+</p>
+
+<p>
+See a demonstration of "ihtml" and "html forms" with our 
+<a href="http://forrest.apache.org/mirrors.cgi">Forrest download mirror</a>
+facility and the
+<a href="http://forrest.apache.org/howto/howto-asf-mirror.html">explanation</a> howto document.
+</p>
+
+<h2><a name="invalid" />Invalid HTML</h2>
+<p>
+This paragraph has a missing closing tag for the &lt;p&gt; element.
+
+<h2><a name="blink" />Other non-standard html-type abilities</h2>
+<p>
+Use other HTML <blink>delights and tricks</blink>.
+</p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/meta.xml
new file mode 100644
index 0000000..69605bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/getting-started/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://www.poetz.cc">Reinhard Poetz</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/built-with-cocoon.gif b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/built-with-cocoon.gif
new file mode 100644
index 0000000..0b38f78
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/built-with-cocoon.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-logo.gif b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-logo.gif
new file mode 100644
index 0000000..4d2794e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-logo.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-project-logo.png b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-project-logo.png
new file mode 100644
index 0000000..2773a67
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon-project-logo.png
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon.ico b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon.ico
new file mode 100644
index 0000000..6f81fa8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/cocoon.ico
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/icon.png b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/icon.png
new file mode 100644
index 0000000..3be8bbb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/images/icon.png
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/comments_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/comments_en.xml
new file mode 100644
index 0000000..7eec2c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/comments_en.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<comments>
+  <comment name="Reinhard Poetz" by="http://www.poetz.cc" subject="the first comment">
+    <p>Here follows the comment text.<strong>more</strong></p>
+  </comment>
+  <comment name="Reinhard Poetz" by="http://www.poetz.cc" subject="second comment">
+    <p>Here follows the comment text.<strong>more</strong></p>
+  </comment>  
+</comments>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/content_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/content_en.xml
new file mode 100644
index 0000000..7b9dbdd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/content_en.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<html>
+  <head>
+    <title>Cocoon documentation</title>
+  </head>
+  <body>
+    <h1>... bladf</h1>
+    <p>
+      <img src="files/test.gif"/>
+    </p>
+  </body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/files/test.gif b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/files/test.gif
new file mode 100644
index 0000000..4d2794e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/files/test.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/meta.xml
new file mode 100644
index 0000000..69605bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/index/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<meta>
+  <authors>
+    <author contact="http://www.poetz.cc">Reinhard Poetz</author>
+  </authors>
+</meta>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/content_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/content_en.xml
new file mode 100644
index 0000000..cb22d01
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/content_en.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>

+<html>

+  <head>

+    <title>File Generator</title>

+  </head>

+  <body>

+    <h1>File Generator</h1>

+    <p>the file generator...</p>

+  </body>

+</html>

diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/generated-before_en.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/generated-before_en.xml
new file mode 100644
index 0000000..7609aba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/generated-before_en.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2002-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<html>

+  <head>

+    <title>Content before</title>

+  </head>

+  <body>

+    <h1>Content before (file generator)</h1>

+    <p>Content before ...</p>

+  </body>

+</html>

diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/meta.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/meta.xml
new file mode 100644
index 0000000..11988c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/sc_file-generator/meta.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>

+<meta>

+  <authors>

+    <author></author>

+  </authors>

+</meta>

diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/site.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/site.xml
new file mode 100644
index 0000000..62b5549
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/site.xml
@@ -0,0 +1,407 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<site label="Apache Cocoon" href="" xmlns="http://apache.org/forrest/linkmap/1.0" tab="docs">
+  
+  <docs label="Documentation" href="" tab="docs">
+    <index label="Overview" href="index.html"/>
+    <status label="Changes" href="changes.html"/>
+    <doc label="Core Technologies">
+      <doc label="Concepts" href="concepts.html"/>      
+      <doc label="Sitemap">
+        <doc label="sitemap.xmap"/>
+        <doc label="Aggregation"/>
+        <doc label="..."/>        
+        <doc label="Components">
+          <doc label="Generators">
+            <doc label="File Generator" href="sc_file-generator.html"/>
+          </doc>
+          <doc label="Transformers"/>
+          <doc label="..."/>          
+        </doc>        
+      </doc>
+      <doc label="Control Flow">
+        <doc label="Flowscript">
+          <doc label="..."/>          
+        </doc>
+        <doc label="Javaflow">
+          <doc label="..."/>         
+        </doc>
+      </doc>
+      <doc label="Cocoon Forms">
+        <doc label="Widgets"/>
+        <doc label="Binding"/>
+        <doc label="Flowscript API"/>
+        <doc label="..."/>        
+      </doc>
+    </doc>
+    
+    <doc label="Configuration">
+      <doc label="Overview"/>
+      <doc label="sitemap.xmap"/>
+      <doc label="cocoon.xconf"/>
+      <doc label="web.xml"/>
+      <doc label="Logging"/>
+      <doc label="Choosing implementations">
+        <doc label="XSLT Processor"/>
+        <doc label="Store"/>
+      </doc>
+      <doc label="Caching"/>
+      <doc label="Performance"/>
+      <doc label="..."/>            
+    </doc>
+    
+    <doc label="More technologies">
+      <doc label="Protocols"/>
+      <doc label="Input Modules"/>
+      <doc label="Internationalization"/>
+      <doc label="Encoding &amp; Entity resolution"/>
+      <doc label="..."/>      
+    </doc>
+
+    <doc label="Your own project">
+      <doc label="Building Cocoon"/>      
+      <doc label="Ant integration" href="custom-cocoon-based-project-using-ant.html"/>
+      <doc label="Maven integration"/>
+      <doc label="Eclipse integration"/>
+      <doc label="Deployment">
+        <doc label="Tomcat"/>
+        <doc label="Jetty"/>
+      </doc>
+      <doc label="..."/>
+    </doc>
+
+    <doc label="Extending Cocoon">
+      <doc label="Understanding the Cocoon Container"/>
+      <doc label="Custom sitemap components"/>
+      <doc label="Custom general components"/>
+      <doc label="..."/>
+    </doc> 
+    
+    <doc label="Cocoon Internals">
+      <doc label="Overview"/>
+      <doc label="How to work on Cocoon internals?"/>      
+      <doc label="From the request to the response"/>
+      <doc label="Cocoon container ('the core')"/>
+      <doc label="Pipeline machinery (Treeprocessor)"/>
+      <doc label="Flowscript integration"/>
+      <doc label="Javaflow integration"/>
+      <doc label="How does logging work?"/>    
+    </doc>
+    
+    <doc label="External resources">
+      <doc label="Articles"/>
+      <doc label="Books"/>
+      <doc label="Other resources"/>
+    </doc>   
+        
+  </docs>
+
+  <tutorials label="Tutorials" tab="tutorials">
+    <doc label="Getting started">
+      <doc label="Overview" href="getting-started.html"/>
+      <doc label="Run Cocoon in 2 Minutes"/>
+      <doc label="What can Cocoon do for you?"/>
+      <doc label="Overview Cocoon concepts"/>
+      <doc label="Publishing (pipelines)"/>
+      <doc label="Applications (control flow)"/>
+      <doc label="Form Handling (Ccooon Forms)"/>
+    </doc> 
+    <doc label="More Tutorials">
+      <doc label="..."/>
+    </doc>
+  </tutorials>
+
+  <doc label="Blocks" tab="blocks">
+    <doc label="Overview"  href="blocks.html"/>
+    <doc label="Core blocks">
+      <doc label="Cocoon Forms"/>      
+    </doc>
+    <doc label="Core blocks under heavy development">
+      <doc label="XML-Templating"/> 
+      <doc label="Javaflow"/>         
+    </doc>         
+    <doc label="Supported blocks">
+      <doc label="Cocoon Portal" href="http://forrest.zones.apache.org/fr/build/cocoon-doco-portal/"/>
+        <!-- later to be removed by http://cocoon.apache.org/blocks/portal/1.0/index.html" -->        
+      <doc label="OJB"/>        
+      <doc label="..."/>
+    </doc>
+    <doc label="Unsupported blocks">
+      <doc label="ASCII-Art"/>       
+    </doc>        
+    <doc label="External blocks">
+      <doc label="List"/>    
+    </doc>      
+  </doc>
+
+  <legacy label="Legacy" tab="legacy">
+	  <doc label="index" href="c21-index.html"/>
+	  <doc label="introduction" href="c21-introduction.html"/>
+	  <doc label="who" href="c21-who.html"/>  
+	  <snippet label="snippet">
+	    <doc label="snippet-internal-pipeline" href="c21-internal-pipelines.html"/>
+	    <doc label="snippet-xslt-options" href="c21-specifying-xslt-options.html"/>
+	  </snippet>
+	  <doc label="license" href="c21-block-global-license.html"/>
+		  <userdocs label="userdocs">
+		    <actions label="actions">
+		      <doc label="sendmail-action" href="c21-block-mail-sendmail-action.html"/>
+		      <doc label="session-action" href="c21-block-session-fw-session-action.html"/>
+		      <doc label="actions" href="c21-actions.html"/>
+		      <doc label="script-action" href="c21-block-bsf-script-action.html"/>
+		      <doc label="database-actions" href="c21-block-databases-database-actions.html"/>
+		    </actions>
+		    <xsp label="xsp">
+		      <doc label="xsp-internals" href="c21-block-xsp-internals.html"/>
+		      <doc label="session" href="c21-block-xsp-session.html"/>
+		      <doc label="logicsheet-forms" href="c21-block-xsp-logicsheet-forms.html"/>
+		      <doc label="logicsheet" href="c21-block-xsp-logicsheet.html"/>
+		      <doc label="request" href="c21-block-xsp-request.html"/>
+		      <doc label="esql" href="c21-block-xsp-esql.html"/>
+		      <doc label="sendmail" href="c21-block-xsp-sendmail.html"/>
+		      <doc label="index" href="c21-block-xsp-index.html"/>
+		      <doc label="sessions" href="c21-block-xsp-sessions.html"/>
+		      <doc label="logicsheet-concepts" href="c21-block-xsp-logicsheet-concepts.html"/>
+		    </xsp>
+		    <serializers label="serializers">
+		      <doc label="ziparchive-serializer" href="c21-ziparchive-serializer.html"/>
+		      <doc label="xhtml-serializer" href="c21-xhtml-serializer.html"/>
+		      <doc label="vrml-serializer" href="c21-vrml-serializer.html"/>
+		      <doc label="pdf-serializer" href="c21-block-fop-pdf-serializer.html"/>
+		      <doc label="serializers" href="c21-serializers.html"/>
+		      <doc label="svgxml-serializer" href="c21-block-batik-svgxml-serializer.html"/>
+		      <doc label="pcl-serializer" href="c21-block-fop-pcl-serializer.html"/>
+		      <doc label="link-serializer" href="c21-link-serializer.html"/>
+		      <doc label="svg-serializer" href="c21-block-batik-svg-serializer.html"/>
+		      <doc label="svgpng-serializer" href="c21-block-batik-svgpng-serializer.html"/>
+		      <doc label="xls-serializer" href="c21-block-poi-xls-serializer.html"/>
+		      <doc label="text-serializer" href="c21-text-serializer.html"/>
+		      <doc label="xml-serializer" href="c21-xml-serializer.html"/>
+		      <doc label="svgjpeg-serializer" href="c21-block-batik-svgjpeg-serializer.html"/>
+		      <doc label="ps-serializer" href="c21-block-fop-ps-serializer.html"/>
+		      <doc label="svgtiff-serializer" href="c21-block-batik-svgtiff-serializer.html"/>
+		      <doc label="wap-serializer" href="c21-wap-serializer.html"/>
+		      <doc label="html-serializer" href="c21-html-serializer.html"/>
+		    </serializers>
+		    <generators label="generators">
+		      <doc label="jsp-generator" href="c21-block-jsp-jsp-generator.html"/>
+		      <doc label="serverpages-generator" href="c21-block-xsp-serverpages-generator.html"/>
+		      <doc label="xpathdirectory-generator" href="c21-xpathdirectory-generator.html"/>
+		      <doc label="stream-generator" href="c21-stream-generator.html"/>
+		      <doc label="search-generator" href="c21-block-lucene-search-generator.html"/>
+		      <doc label="script-generator" href="c21-block-bsf-script-generator.html"/>
+		      <doc label="calendar-generator" href="c21-calendar-generator.html"/>
+		      <doc label="xmldb-generator" href="c21-block-xmldb-xmldb-generator.html"/>
+		      <doc label="xmldbcollection-generator" href="c21-block-xmldb-xmldbcollection-generator.html"/>
+		      <doc label="wsproxy-generator" href="c21-block-proxy-webserviceproxy-generator.html"/>
+		      <doc label="extractor-generator" href="c21-block-batik-extractor-generator.html"/>
+		      <doc label="profile-generator" href="c21-block-profiler-profiler-generator.html"/>
+		      <doc label="jx-generator" href="c21-jxtemplate-generator.html"/>
+		      <doc label="html-generator" href="c21-html-generator.html"/>
+		      <doc label="linkstatus-generator" href="c21-linkstatus-generator.html"/>
+		      <doc label="directory-generator" href="c21-directory-generator.html"/>
+		      <doc label="velocity-generator" href="c21-block-velocity-velocity-generator.html"/>
+		      <doc label="mp3directory-generator" href="c21-mp3directory-generator.html"/>
+		      <doc label="request-generator" href="c21-request-generator.html"/>
+		      <doc label="status-generator" href="c21-status-generator.html"/>
+		      <doc label="generators" href="c21-generators.html"/>
+		      <doc label="error-generator" href="c21-error-generator.html"/>
+		      <doc label="file-generator" href="c21-file-generator.html"/>
+		      <doc label="imagedirectory-generator" href="c21-imagedirectory-generator.html"/>
+		    </generators>
+		    <forms label="forms">
+		      <doc label="formsgenerator" href="c21-cforms-formgenerator.html"/>
+		      <doc label="templategenerator" href="c21-cforms-template-generator.html"/>
+		      <doc label="xslt" href="c21-cforms-xslt.html"/>
+		      <doc label="validation" href="c21-cforms-validation.html"/>
+		      <doc label="templatetransformer" href="c21-cforms-template-transformer.html"/>
+		      <doc label="widget_field" href="c21-cforms-field-widget.html"/>
+		      <doc label="widget_aggregatefield" href="c21-cforms-aggregatefield-widget.html"/>
+		      <doc label="binding" href="c21-cforms-binding.html"/>
+		      <doc label="index" href="c21-cforms.html"/>
+		      <doc label="widget_messages" href="c21-cforms-messages-widget.html"/>
+		      <doc label="widget_action" href="c21-cforms-action-widget.html"/>
+		      <doc label="api_java" href="c21-cforms-java-api.html"/>
+		      <doc label="sample" href="c21-cforms-sample.html"/>
+		      <doc label="widget_multivaluefield" href="c21-cforms-multivaluefield-widget.html"/>
+		      <doc label="api_javascript" href="c21-cforms-javascript.html"/>
+		      <doc label="widget_booleanfield" href="c21-cforms-booleanfield-widget.html"/>
+		      <doc label="widget_submit" href="c21-cforms-submit-widget.html"/>
+		      <doc label="widget_repeater" href="c21-cforms-repeater-widget.html"/>
+		      <doc label="widget_repeater_action" href="c21-cforms-repeateraction-widget.html"/>
+		      <doc label="widget_upload" href="c21-cforms-upload-widget.html"/>
+		      <doc label="widget_row_action" href="c21-cforms-row-action-widget.html"/>
+		      <doc label="widget_output" href="c21-cforms-output-widget.html"/>
+		      <doc label="eventhandling" href="c21-cforms-eventhandling.html"/>
+		      <doc label="datatypes" href="c21-cforms-datatypes.html"/>
+		    </forms>
+		    <selectors label="selectors">
+		      <doc label="requestattribute-selector" href="c21-requestattribute-selector.html"/>
+		      <doc label="requestparameter-selector" href="c21-requestparameter-selector.html"/>
+		      <doc label="resourceexists-selector" href="c21-resourceexists-selector.html"/>
+		      <doc label="selectors" href="c21-selectors.html"/>
+		      <doc label="requestmethod-selector" href="c21-requestmethod-selector.html"/>
+		      <doc label="host-selector" href="c21-host-selector.html"/>
+		      <doc label="browser-selector" href="c21-browser-selector.html"/>
+		      <doc label="regular-expression-header-selector" href="c21-regexpheader-selector.html"/>
+		      <doc label="date-selector" href="c21-date-selector.html"/>
+		      <doc label="parameter-selector" href="c21-parameter-selector.html"/>
+		    </selectors>
+		    <transformers label="transformers">
+		      <doc label="xinclude-transformer" href="c21-xinclude-transformer.html"/>
+		      <doc label="sql-transformer" href="c21-sql-transformer.html"/>
+		      <doc label="jx-template-transformer" href="c21-jxtemplate-transformer.html"/>
+		      <doc label="xslt-transformer" href="c21-xslt-transformer.html"/>
+		      <doc label="parser-transformer" href="c21-block-chaperon-parser-transformer.html"/>
+		      <doc label="log-transformer" href="c21-log-transformer.html"/>
+		      <doc label="lexer-transformer" href="c21-block-chaperon-lexer-transformer.html"/>
+		      <doc label="writedomsession-transformer" href="c21-writedomsession-transformer.html"/>
+		      <doc label="extractor-transformer" href="c21-block-batik-extractor-transformer.html"/>
+		      <doc label="readdomsession-transformer" href="c21-readdomsession-transformer.html"/>
+		      <doc label="filter-transformer" href="c21-filter-transformer.html"/>
+		      <doc label="augment-transformer" href="c21-augment-transformer.html"/>
+		      <doc label="cinclude-transformer" href="c21-cinclude-transformer.html"/>
+		      <doc label="pattern-transformer" href="c21-block-chaperon-pattern-transformer.html"/>
+		      <doc label="transformers" href="c21-transformers.html"/>
+		      <doc label="ldap-transformer" href="c21-block-naming-ldap-transformer.html"/>
+		      <doc label="encodeurl-transformer" href="c21-encodeurl-transformer.html"/>
+		      <doc label="sourcewriting-transformer" href="c21-sourcewriting-transformer.html"/>
+		    </transformers>
+		    <matchers label="matchers">
+		      <doc label="wildcarduri-matcher" href="c21-wildcarduri-matcher.html"/>
+		      <doc label="wildcardheader-matcher" href="c21-wildcardheader-matcher.html"/>
+		      <doc label="matchers" href="c21-matchers.html"/>
+		      <doc label="template-matcher" href="c21-template-matcher.html"/>
+		    </matchers>
+		    <concepts label="concepts">
+		      <doc label="redirection" href="c21-redirection.html"/>
+		      <doc label="modules" href="c21-modules.html"/>
+		      <doc label="views" href="c21-views.html"/>
+		      <doc label="mrustore" href="c21-mru-store.html"/>
+		      <doc label="profiler" href="c21-profiler.html"/>
+		      <doc label="storejanitor" href="c21-store-janitor.html"/>
+		      <doc label="caching" href="c21-caching.html"/>
+		      <doc label="matchers_selectors" href="c21-matchers-selectors.html"/>
+		      <doc label="errorhandling" href="c21-error-handling.html"/>
+		      <doc label="index" href="c21-concepts.html"/>
+		      <doc label="sitemap" href="c21-sitemap.html"/>
+		      <doc label="databases" href="c21-databases.html"/>
+		      <doc label="catalog" href="c21-catalog.html"/>
+		      <doc label="modules-ref" href="c21-modules-ref.html"/>
+		      <doc label="sitemap-examples" href="c21-sitemap-examples.html"/>
+		      <doc label="xmlsearching" href="c21-block-lucene-xml-searching.html"/>
+		      <doc label="actions" href="c21-actions2.html"/>
+		      <doc label="persistence" href="c21-persistent-store.html"/>
+		    </concepts>
+		    <flow label="flow">
+		      <doc label="tutor" href="c21-flow-tutorial.html"/>
+		      <doc label="sitemap" href="c21-flow-sitemap.html"/>
+		      <doc label="java" href="c21-flow-java.html"/>
+		      <doc label="how-does-it-work" href="c21-flow-workings.html"/>
+		      <doc label="views" href="c21-flow-views.html"/>
+		      <doc label="using" href="c21-flow-using.html"/>
+		      <doc label="velocity" href="c21-flow-velocity.html"/>
+		      <doc label="continuations" href="c21-flow-continuations.html"/>
+		      <doc label="api" href="c21-flow-api.html"/>
+		      <doc label="index" href="c21-flow.html"/>
+		      <doc label="jxtemplate" href="c21-flow-jxtemplate.html"/>
+		      <doc label="jpath" href="c21-flow-jpath.html"/>
+		    </flow>
+		    <offline label="offline">
+		      <doc label="cli" href="c21-cli.html"/>
+		      <doc label="bean" href="c21-cocoon-bean.html"/>
+		      <doc label="ant" href="c21-cocoon-ant-task.html"/>
+		      <doc label="configuration" href="c21-offline-configuration.html"/>
+		      <doc label="index" href="c21-offline.html"/>
+		    </offline>
+		    <readers label="readers">
+		      <doc label="readers" href="c21-readers.html"/>
+		      <doc label="database-reader" href="c21-block-databases-database-reader.html"/>
+		      <doc label="image-reader" href="c21-image-reader.html"/>
+		      <doc label="directoryziparchiver-reader" href="c21-directoryziparchiver-reader.html"/>
+		      <doc label="resource-reader" href="c21-resource-reader.html"/>
+		      <doc label="axisrpc-reader" href="c21-block-axis-axisrpc-reader.html"/>
+		      <doc label="jsp-reader" href="c21-block-jsp-jsp-reader.html"/>
+		    </readers>
+		  </userdocs>
+		  <doc label="overview" href="c21-overview.html"/>
+		  <installing label="installing">
+		    <doc label="requirements" href="c21-install-requirements.html"/>
+		    <doc label="tests" href="c21-tests.html"/>
+		    <doc label="jars" href="c21-jars.html"/>
+		    <doc label="updating" href="c21-updating.html"/>
+		    <doc label="index" href="c21-installing.html"/>
+		  </installing>
+		  <developing label="developing">
+		    <doc label="web3" href="c21-block-web3-sap-r3.html"/>
+		    <doc label="deli" href="c21-block-deli-index.html"/>
+		    <doc label="extending" href="c21-extending-cocoon.html"/>
+		    <doc label="datasources" href="c21-developing-with-datasources.html"/>
+		    <doc label="source" href="c21-sources.html"/>
+		    <doc label="stores" href="c21-stores.html"/>
+		    <doc label="deliquick" href="c21-block-deli-deli-quick.html"/>
+		    <doc label="avalon" href="c21-developing-with-avalon.html"/>
+		    <doc label="parent-component-manager" href="c21-parent-component-manager.html"/>
+		    <doc label="httprequest" href="c21-http-request.html"/>
+		    <webapps label="webapps">
+		      <doc label="contexts" href="c21-block-session-fw-session-contexts.html"/>
+		      <doc label="forms" href="c21-block-session-fw-webapp-forms.html"/>
+		      <doc label="authentication" href="c21-block-authentication-fw-authentication.html"/>
+		      <doc label="session" href="c21-block-session-fw-session-transformer.html"/>
+		    </webapps>
+		    <portal label="portal">
+		      <doc label="forms" href="c21-block-portal-forms.html"/>
+		      <doc label="basket" href="c21-block-portal-basket.html"/>
+		      <doc label="events" href="c21-block-portal-events.html"/>
+		      <doc label="profiles" href="c21-block-portal-profiles.html"/>
+		      <doc label="index" href="c21-block-portal-index.html"/>
+		      <doc label="coplets" href="c21-block-portal-coplets.html"/>
+		      <doc label="portal-block" href="c21-block-portal-portal-block.html"/>
+		    </portal>
+		    <doc label="index" href="c21-developing.html"/>
+		  </developing>
+		  <doc label="features" href="c21-features.html"/>
+		  <doc label="todo" href="c21-todo2.html"/>
+		  <doc label="performancetips" href="c21-performance-tips.html"/>
+		  <tutorial label="tutorial">
+		    <doc label="tutorial-rmi-generator" href="c21-tutorial-rmi-generator.html"/>
+		    <doc label="tutorial-generator" href="c21-tutorial-custom-generator.html"/>
+		    <doc label="index" href="c21-tutorials.html"/>
+		  </tutorial>
+		  <plan label="plan">
+		    <doc label="changes-doc" href="c21-changes.html"/>
+		    <doc label="release" href="c21-release.html"/>
+		    <doc label="updating" href="c21-updating-to-2.2.html"/>
+		    <doc label="review-sitemap-docs" href="c21-review-sitemap-docs.html"/>
+		    <doc label="samples" href="c21-plan-samples.html"/>
+		    <doc label="todo-doc" href="c21-todo.html"/>
+		    <doc label="doc" href="c21-doc-plan.html"/>
+		    <doc label="index" href="c21-plan.html"/>
+		    <doc label="roadmap" href="c21-roadmap.html"/>
+		  </plan>
+		  <howto label="howto">
+		    <doc label="howto-html-pdf-publishing" href="c21-howto-pdf-publishing.html"/>
+		    <doc label="howto-paginator-transformer" href="c21-paginator-transformer.html"/>
+		    <doc label="howto-patch" href="c21-block-global-howto-patch.html"/>
+		    <doc label="howto-author-core-docs" href="c21-howto-author-docs.html"/>
+		    <doc label="howto-explore-samples" href="c21-samples.html"/>
+		    <doc label="howto-bugzilla" href="c21-block-global-howto-bugzilla.html"/>
+		    <doc label="howto-flow-debugger" href="c21-howto-flow-debugger.html"/>
+		  </howto>
+	  </legacy>
+</site>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/tabs.xml b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/tabs.xml
new file mode 100644
index 0000000..6e7a964
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/content/xdocs/tabs.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE tabs PUBLIC "-//APACHE//DTD Cocoon Documentation Tab V1.1//EN" "http://forrest.apache.org/dtd/tab-cocoon-v11.dtd">
+
+<tabs software="Apache Cocoon"
+  title="Apache Cocoon"
+  copyright="2004 Apache Software Foundation"
+  xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <!-- The rules for tabs are:
+    @dir will always have '/@indexfile' added.
+    @indexfile gets appended to @dir if the tab is selected. Defaults to 'index.html'
+    @href is not modified unless it is root-relative and obviously specifies a
+    directory (ends in '/'), in which case /index.html will be added
+    If @id's are present, site.xml entries with a matching @tab will be in that tab.
+
+   Tabs can be embedded to a depth of two. The second level of tabs will only 
+    be displayed when their parent tab is selected.    
+  -->
+
+  <tab id="project" label="Project" href="http://forrest.zones.apache.org/fr/build/cocoon-doco-global/index.html"/>
+    <!-- later to be replaced by: http://cocoon.apache.org -->
+  <tab id="community" label="Community" href="http://forrest.zones.apache.org/fr/build/cocoon-doco-global/community.html"/>
+    <!-- later to be replaced by: http://cocoon.apache.org/community.html -->
+  <tab id="tutorials" label="Tutorials" dir="" indexfile="getting-started.html"/>
+  <tab id="docs" label="Documentation" dir="" indexfile="index.html">
+    <tab id="docs-2.1" label="2.1 docs" href="http://not-available-yet/index.html"/>
+    <tab id="docs-2.0" label="2.0 docs" href="http://not-available-yet/index.html"/>    
+  </tab>
+  <tab id="blocks" label="Blocks" dir="" indexfile="blocks.html"/>
+  <tab id="legacy" label="Legacy" dir="" indexfile="c21-index.html"/>
+
+</tabs>
diff --git a/non-releases/trunk_before_flattening/src/documentation/src/skinconf.xml b/non-releases/trunk_before_flattening/src/documentation/src/skinconf.xml
new file mode 100644
index 0000000..b264d50
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/src/skinconf.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 2002-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+

+<!--

+Skin configuration file. This file contains details of your project,

+which will be used to configure the chosen Forrest skin.

+-->

+

+<!DOCTYPE skinconfig PUBLIC "-//APACHE//DTD Skin Configuration V0.6-3//EN" "http://forrest.apache.org/dtd/skinconfig-v06-3.dtd"

+[

+  <!ENTITY heading  SYSTEM "./forrest-configuration/skinconf-heading.xml">

+  <!ENTITY extracss SYSTEM "./forrest-configuration/skinconf-extracss.xml">

+  <!ENTITY colors   SYSTEM "./forrest-configuration/skinconf-colors.xml">

+  <!ENTITY pdf      SYSTEM "./forrest-configuration/skinconf-pdf.xml">

+  <!ENTITY credits  SYSTEM "./forrest-configuration/skinconf-credits.xml">       

+]>

+

+<skinconfig>

+  <!-- To enable lucene search add provider="lucene"

+    Add box-location="alt" to move the search box to an alternate location

+    (if the skin supports it) and box-location="all" to show it in all

+    available locations on the page.  Remove the <search> element to show

+    no search box.

+  -->

+  <search name="Apache Forrest" domain="cocoon.apache.org" provider="google"/>

+

+  <!-- Disable the print link? If enabled, invalid HTML 4.0.1 -->

+  <disable-print-link>true</disable-print-link>

+  <!-- Disable the PDF link? -->

+  <disable-pdf-link>false</disable-pdf-link>

+  <!-- Disable the xml source link? -->

+  <!-- The xml source link makes it possible to access the xml rendition

+    of the source frim the html page, and to have it generated statically.

+    This can be used to enable other sites and services to reuse the

+    xml format for their uses. Keep this disabled if you don't want other

+    sites to easily reuse your pages.-->

+  <disable-xml-link>true</disable-xml-link>

+

+  <!-- Disable navigation icons on all external links? -->

+  <disable-external-link-image>false</disable-external-link-image>

+

+  <!-- Disable w3c compliance links? -->

+  <disable-compliance-links>false</disable-compliance-links>

+

+  <!-- Render mailto: links unrecognisable by spam harvesters? -->

+  <obfuscate-mail-links>true</obfuscate-mail-links>

+  <obfuscate-mail-value>[.at.]</obfuscate-mail-value>

+

+  <!-- Disable the javascript facility to change the font size -->

+  <disable-font-script>false</disable-font-script>

+

+  <!-- mandatory project logo

+       skin: forrest-site renders it at the top -->

+  <project-name>Apache Cocoon</project-name>

+  <project-description>Apache Cocoon</project-description>

+  <project-url>http://cocoon.apache.org/</project-url>

+  <project-logo>images/cocoon-logo.gif</project-logo>

+

+

+  <!-- optional group logo

+       skin: forrest-site renders it at the top-left corner -->

+  <group-name>Apache</group-name>

+  <group-description>The Apache Software Foundation</group-description>

+  <group-url>http://www.apache.org/</group-url>

+  <group-logo>images/cocoon-project-logo.png</group-logo>

+

+  <!-- optional host logo (e.g. sourceforge logo)

+       skin: forrest-site renders it at the bottom-left corner -->

+  <host-url></host-url>

+  <host-logo></host-logo>

+

+  <!-- relative url of a favicon file, normally favicon.ico -->

+  <favicon-url>images/cocoon.ico</favicon-url>

+

+  <!-- The following are used to construct a copyright statement -->

+  <year>1999-2005</year>

+  <vendor>The Apache Software Foundation.</vendor>

+  <copyright-link>http://www.apache.org/licenses/</copyright-link>

+

+  <!-- Some skins use this to form a 'breadcrumb trail' of links.

+    If you don't want these, then set the attributes to blank.

+    The DTD purposefully requires them.

+    Use location="alt" to move the trail to an alternate location

+    (if the skin supports it).

+  -->

+

+  <trail>

+    <link1 name="apache" href="http://www.apache.org/"/>

+    <link2 name="cocoon" href="http://cocoon.apache.org/"/>

+    <link3 name="" href=""/>

+  </trail>

+

+  <!-- Configure the TOC, i.e. the Table of Contents.

+  @max-depth

+   how many "section" levels need to be included in the

+   generated Table of Contents (TOC).

+  @min-sections

+   Minimum required to create a TOC.

+  @location ("page","menu","page,menu")

+   Where to show the TOC.

+  -->

+  <toc max-depth="3" min-sections="2" location="page"/>

+

+  &heading;

+  &extracss;

+  &colors;

+  &pdf;

+  &credits;

+

+</skinconfig>

diff --git a/non-releases/trunk_before_flattening/src/documentation/templates/sitemap-component.xml b/non-releases/trunk_before_flattening/src/documentation/templates/sitemap-component.xml
new file mode 100644
index 0000000..876d55f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/documentation/templates/sitemap-component.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "dtd/document-v10.dtd">

+<document>

+  <header>

+    <title></title>

+    <version></version>

+    <type>Reference</type>

+    <authors>

+      <person name="The Cocoon Community" email="users@cocoon.apache.org"/>

+    </authors>

+  </header>

+  <body>

+    <s1 title="Description">

+    </s1>

+    <s1 title="Info">

+      <table>

+      </table>

+    </s1>

+  </body>

+</document>

diff --git a/non-releases/trunk_before_flattening/src/java/Manifest.mf b/non-releases/trunk_before_flattening/src/java/Manifest.mf
new file mode 100644
index 0000000..aeb9c46
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/Manifest.mf
@@ -0,0 +1,125 @@
+Manifest-Version: 1.0
+Main-Class: org.apache.cocoon.Main
+Specification-Vendor: The Apache Software Foundation
+Implementation-Vendor: The Apache Software Foundation
+Bundle-Name: cocoon
+Bundle-SymbolicName: org.apache.cocoon:cocoon:1.0.0
+Bundle-Version: 1.0.0
+Bundle-Description: Cocoon bundle
+Bundle-Vendor: Apache
+Bundle-DocURL: http://cocoon.apache.org
+Bundle-ContactAddress: http://cocoon.apache.org
+Bundle-Category: library
+Bundle-Classpath: 
+ .,
+ avalon-framework-api-4.3.jar,
+ avalon-framework-impl-4.3.jar,
+ avalon-logkit-2.1.jar,
+ commons-cli-1.0.jar,
+ commons-collections-3.1.jar,
+ commons-httpclient-2.0.2.jar,
+ commons-io-1.1.jar,
+ commons-javaflow-r306555.jar,
+ commons-jci-r306555.jar,
+ commons-jexl-1.0.jar,
+ commons-jxpath-1.2-r329470.jar,
+ commons-lang-2.1.jar,
+ commons-logging-1.0.4.jar,
+ concurrent-1.3.4.jar,
+ ehcache-1.1.jar,
+ excalibur-i18n-1.1.jar,
+ excalibur-instrument-api-2.1.jar,
+ excalibur-logger-2.1.jar,
+ excalibur-naming-1.0.jar,
+ excalibur-pool-api-2.1.jar,
+ excalibur-pool-impl-2.1.jar,
+ excalibur-pool-instrumented-2.1.jar,
+ excalibur-sourceresolve-2.1.jar,
+ excalibur-store-2.1.jar,
+ excalibur-xmlutil-2.1.jar,
+ jcs-1.2.5-dev-20050313.jar,
+ log4j-1.2.12.jar,
+ rhino-1.6R2.jar,
+ servlet-2_3.jar,
+ xml-commons-resolver-1.1.jar,
+ xmlbeans-1.0.3.jar,
+ jakarta-bcel-20040329.jar,
+ jakarta-regexp-1.4.jar,
+ xalan-2.7.0.jar,
+ xercesImpl-2.7.1.jar,
+ xml-apis-1.3.02.jar
+Export-Package: 
+ javax.servlet,
+ javax.servlet.http,
+ org.apache.avalon.excalibur.logger,
+ org.apache.avalon.framework.context,
+ org.apache.avalon.framework.logger,
+ org.apache.avalon.framework.service,
+ org.apache.avalon.framework.activity,
+ org.apache.avalon.framework.thread,
+ org.apache.avalon.framework.configuration,
+ org.apache.cocoon,
+ org.apache.cocoon.acting,
+ org.apache.cocoon.caching,
+ org.apache.cocoon.caching.impl,
+ org.apache.cocoon.components.blocks,
+ org.apache.cocoon.components.classloader,
+ org.apache.cocoon.components.fam,
+ org.apache.cocoon.components.flow,
+ org.apache.cocoon.components.flow.javascript.fom,
+ org.apache.cocoon.components.modules.input,
+ org.apache.cocoon.components.modules.output,
+ org.apache.cocoon.components.notification,
+ org.apache.cocoon.components.pipeline,
+ org.apache.cocoon.components.pipeline.impl,
+ org.apache.cocoon.components.resolver,
+ org.apache.cocoon.components.sax,
+ org.apache.cocoon.components.source,
+ org.apache.cocoon.components.source.impl,
+ org.apache.cocoon.components.store.impl,
+ org.apache.cocoon.components.thread,
+ org.apache.cocoon.components.treeprocessor,
+ org.apache.cocoon.components.treeprocessor.sitemap,
+ org.apache.cocoon.core,
+ org.apache.cocoon.core.container,
+ org.apache.cocoon.core.osgi,
+ org.apache.cocoon.environment,
+ org.apache.cocoon.environment.http,
+ org.apache.cocoon.environment.impl,
+ org.apache.cocoon.generation,
+ org.apache.cocoon.i18n,
+ org.apache.cocoon.matching,
+ org.apache.cocoon.reading,
+ org.apache.cocoon.serialization,
+ org.apache.cocoon.servlet,
+ org.apache.cocoon.servlet.multipart,
+ org.apache.cocoon.sitemap,
+ org.apache.cocoon.transformation,
+ org.apache.cocoon.transformation.helpers,
+ org.apache.cocoon.transformation.pagination,
+ org.apache.cocoon.reading,
+ org.apache.cocoon.selection,
+ org.apache.cocoon.serialization,
+ org.apache.cocoon.util,
+ org.apache.cocoon.util.log,
+ org.apache.cocoon.xml,
+ org.apache.cocoon.xml.dom,
+ org.apache.commons.jxpath,
+ org.apache.commons.lang,
+ org.apache.commons.lang.time,
+ org.apache.excalibur.source,
+ org.apache.excalibur.source.impl,
+ org.apache.excalibur.store,
+ org.apache.excalibur.xml,
+ org.apache.excalibur.xml.impl,
+ org.apache.excalibur.xml.sax,
+ org.apache.excalibur.xml.xpath,
+ org.apache.excalibur.xml.xslt,
+ org.apache.excalibur.xmlizer,
+ org.apache.log,
+ org.xml.sax
+Import-Package: 
+ org.osgi.framework,
+ org.osgi.service.log
+DynamicImport-Package: org.apache.cocoon.*
+Bundle-UUID: org.apache.cocoon:cocoon:1.0.0:all
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CascadingIOException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CascadingIOException.java
new file mode 100644
index 0000000..a7e0541
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CascadingIOException.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import org.apache.avalon.framework.CascadingThrowable;
+import org.xml.sax.SAXParseException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.SourceLocator;
+
+/**
+ * This is a wrapping IOException.
+ * 
+ * @version $Id$
+ */
+public class CascadingIOException 
+extends IOException 
+implements CascadingThrowable {
+
+    /**
+     * The Throwable that caused this exception to be thrown.
+     */
+    private final Throwable m_throwable;
+
+
+    /**
+     * Construct a new <code>ProcessingException</code> instance.
+     */
+    public CascadingIOException(String message) {
+        this(message, null);
+    }
+    
+    /**
+     * Creates a new <code>ProcessingException</code> instance.
+     *
+     * @param ex an <code>Exception</code> value
+     */
+    public CascadingIOException(Exception ex) {
+        this(ex.getMessage(), ex);
+    }
+    
+    /**
+     * Construct a new <code>ProcessingException</code> that references
+     * a parent Exception.
+     */
+    public CascadingIOException(String message, Throwable t) {
+        super( message );
+        this.m_throwable = t;
+    }
+    
+    /**
+     * Retrieve root cause of the exception.
+     *
+     * @return the root cause
+     */
+    public final Throwable getCause()
+    {
+        return this.m_throwable;
+    }
+
+    public String toString() {
+        StringBuffer s = new StringBuffer();
+        s.append(super.toString());
+        final Throwable t = getCause();
+        if(t!=null) {
+            s.append(": ");
+            // be more verbose try to get location info
+            s.append( extraInfo(t) );
+            s.append(t.toString());
+        }
+        return s.toString();
+    }
+    
+    /**
+     * Examine Throwable and try to figure out location information.
+     * <p>
+     *   At the moment only SAXParseException, and TransformerException
+     *   are considered.
+     * </p>
+     *
+     * @return String containing location information of the format
+     *  <code>{file-name}:{line}:{column}:</code>, if no location info is 
+     *  available return empty string
+     */
+    private String extraInfo( Throwable t ) {
+        StringBuffer sb = new StringBuffer();
+        if (t instanceof SAXParseException) {
+            SAXParseException spe = (SAXParseException)t;
+            sb.append( String.valueOf(spe.getSystemId()));
+            sb.append( ":" );
+            sb.append( String.valueOf(spe.getLineNumber()));
+            sb.append( ":" );
+            sb.append( String.valueOf(spe.getColumnNumber()));
+            sb.append( ":" );
+        } else if (t instanceof TransformerException) {
+            TransformerException transformerException = (TransformerException) t;
+            SourceLocator sourceLocator = transformerException.getLocator();
+            
+            if( null != sourceLocator ) {
+                sb.append( String.valueOf(sourceLocator.getSystemId()));
+                sb.append( ":" );
+                sb.append( String.valueOf(sourceLocator.getLineNumber()));
+                sb.append( ":" );
+                sb.append( String.valueOf(sourceLocator.getColumnNumber()));
+                sb.append( ":" );
+            }
+        }
+        return sb.toString();
+    }
+    
+    public void printStackTrace() {
+        super.printStackTrace();
+        if(getCause()!=null)
+            getCause().printStackTrace();
+    }
+    
+    public void printStackTrace( PrintStream s ) {
+        super.printStackTrace(s);
+        if(getCause()!=null)
+            getCause().printStackTrace(s);
+    }
+    
+    public void printStackTrace( PrintWriter s ) {
+        super.printStackTrace(s);
+        if(getCause()!=null)
+            getCause().printStackTrace(s);
+    }
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Cocoon.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Cocoon.java
new file mode 100644
index 0000000..a5c5f64
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Cocoon.java
@@ -0,0 +1,679 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.excalibur.logger.LoggerManageable;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.container.CocoonServiceManager;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.RoleManager;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.cocoon.util.location.LocationUtils;
+
+import org.apache.commons.lang.SystemUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.impl.URLSource;
+import org.xml.sax.InputSource;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The Cocoon Object is the main Kernel for the entire Cocoon system.
+ *
+ * @version $Id$
+ */
+public class Cocoon
+        extends AbstractLogEnabled
+        implements ThreadSafe,
+                   Initializable,
+                   Disposable,
+                   Modifiable,
+                   Processor,
+                   Contextualizable,
+                   Serviceable,
+                   LoggerManageable {
+
+    // Register the location finder for Avalon configuration objects and exceptions
+    // and keep a strong reference to it.
+    private static final LocationUtils.LocationFinder confLocFinder = new LocationUtils.LocationFinder() {
+        public Location getLocation(Object obj, String description) {
+            if (obj instanceof Configuration) {
+                Configuration config = (Configuration)obj;
+                String locString = config.getLocation();
+                Location result = LocationUtils.parse(locString);
+                if (LocationUtils.isKnown(result)) {
+                    // Add description
+                    StringBuffer desc = new StringBuffer().append('<');
+                    // Unfortunately Configuration.getPrefix() is not public
+                    try {
+                        if (config.getNamespace().startsWith("http://apache.org/cocoon/sitemap/")) {
+                            desc.append("map:");
+                        }
+                    } catch (ConfigurationException e) {
+                        // no namespace: ignore
+                    }
+                    desc.append(config.getName()).append('>');
+                    return new LocationImpl(desc.toString(), result);
+                } else {
+                    return result;
+                }
+            }
+            
+            if (obj instanceof Exception) {
+                // Many exceptions in Cocoon have a message like "blah blah at file://foo/bar.xml:12:1"
+                String msg = ((Exception)obj).getMessage();
+                if (msg == null) return null;
+                
+                int pos = msg.lastIndexOf(" at ");
+                if (pos != -1) {
+                    return LocationUtils.parse(msg.substring(pos + 4));
+                } else {
+                    // Will try other finders
+                    return null;
+                }
+            }
+            
+            // Try next finders.
+            return null;
+        }
+    };
+    
+    static {
+        LocationUtils.addFinder(confLocFinder);
+    }
+    
+    static Cocoon instance;
+
+    /** The root Cocoon logger */
+    private Logger rootLogger;
+
+    /** The application context */
+    private Context context;
+
+    /** The configuration file */
+    private Source configurationFile;
+
+    /** The logger manager */
+    private LoggerManager loggerManager;
+
+    /** The parent service manager. */
+    private ServiceManager parentServiceManager;
+
+    /** Flag for disposed or not */
+    private boolean disposed;
+
+    /** Active request count */
+    private volatile int activeRequestCount;
+
+    /** the Processor */
+    private Processor processor;
+
+    /** The source resolver */
+    protected SourceResolver sourceResolver;
+
+    /** The environment helper */
+    protected EnvironmentHelper environmentHelper;
+
+    /** A service manager */
+    protected CocoonServiceManager serviceManager;
+
+    /** An optional Avalon Component that is called before and after processing all requests. */
+    protected RequestListener requestListener;
+
+    /** The Cocoon Core */
+    protected Core core;
+
+    /** Processor attributes */
+    protected Map processorAttributes = new HashMap();
+
+    /**
+     * Creates a new <code>Cocoon</code> instance.
+     */
+    public Cocoon() {
+        // Set the system properties needed by Xalan2.
+        setSystemProperties();
+
+        // HACK: Provide a way to share an instance of Cocoon object between
+        //       several servlets/portlets.
+        Cocoon.instance = this;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+     */
+    public void enableLogging(Logger logger) {
+        this.rootLogger = logger;
+        super.enableLogging(logger.getChildLogger("cocoon"));
+    }
+
+    /**
+     * Get the parent service manager. For purposes of
+     * avoiding extra method calls, the manager parameter may be null.
+     *
+     * @param manager the parent component manager. May be <code>null</code>
+     */
+    public void service(ServiceManager manager)
+    throws ServiceException {
+        this.parentServiceManager = manager;
+        this.core = (Core)this.parentServiceManager.lookup(Core.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = new ComponentContext(context);
+        ((DefaultContext)this.context).makeReadOnly();
+    }
+
+    /**
+     * The <code>setLoggerManager</code> method will get a <code>LoggerManager</code>
+     * for further use.
+     *
+     * @param loggerManager a <code>LoggerManager</code> value
+     */
+    public void setLoggerManager(LoggerManager loggerManager) {
+        this.loggerManager = loggerManager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        getLogger().debug("Initializing new Cocoon object.");
+        final Settings settings = this.core.getSettings();
+        try {
+            URLSource urlSource = new URLSource();
+            urlSource.init(new URL(settings.getConfiguration()), null);
+            this.configurationFile = new DelayedRefreshSourceWrapper(urlSource,
+                                                                     settings.getReloadDelay("config"));
+
+        } catch (IOException e) {
+            throw new ConfigurationException(
+                    "Could not open configuration file: " + settings.getConfiguration(), e);
+        }
+
+        this.serviceManager = new CocoonServiceManager(this.parentServiceManager);
+        ContainerUtil.enableLogging(this.serviceManager, this.rootLogger.getChildLogger("manager"));
+        ContainerUtil.contextualize(this.serviceManager, this.context);
+
+        // Log the System Properties.
+        dumpSystemProperties();
+
+        this.configure();
+
+        // add the logger manager to the component locator
+
+        ContainerUtil.initialize(this.serviceManager);
+
+        // Get the Processor and keep it
+        this.processor = (Processor)this.serviceManager.lookup(Processor.ROLE);
+
+        this.environmentHelper = new EnvironmentHelper(
+                (URL) this.context.get(ContextHelper.CONTEXT_ROOT_URL));
+        ContainerUtil.enableLogging(this.environmentHelper, this.rootLogger);
+        ContainerUtil.service(this.environmentHelper, this.serviceManager);
+
+        this.sourceResolver = (SourceResolver)this.serviceManager.lookup(SourceResolver.ROLE);
+
+        if (this.serviceManager.hasService(RequestListener.ROLE)){
+            this.requestListener = (RequestListener) this.serviceManager.lookup(RequestListener.ROLE);
+        }
+        Core.cleanup();
+    }
+
+    /** Dump System Properties */
+    private void dumpSystemProperties() {
+        if (getLogger().isDebugEnabled()) {
+            try {
+                Enumeration e = System.getProperties().propertyNames();
+                getLogger().debug("===== System Properties Start =====");
+                for (; e.hasMoreElements();) {
+                    String key = (String) e.nextElement();
+                    getLogger().debug(key + "=" + System.getProperty(key));
+                }
+                getLogger().debug("===== System Properties End =====");
+            } catch (SecurityException se) {
+                // Ignore Exceptions.
+            }
+        }
+    }
+
+    /**
+     * Configure this <code>Cocoon</code> instance.
+     *
+     * @exception ConfigurationException if an error occurs
+     * @exception ContextException if an error occurs
+     */
+    private void configure() throws Exception {
+        InputSource is = SourceUtil.getInputSource(this.configurationFile);
+
+        final Settings settings = this.core.getSettings();
+        ConfigurationBuilder builder = new ConfigurationBuilder(settings);
+        Configuration conf = builder.build(is);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Root configuration: " + conf.getName());
+        }
+        if (!"cocoon".equals(conf.getName())) {
+            throw new ConfigurationException("Invalid configuration file\n" + conf.toString());
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Configuration version: " + conf.getAttribute("version"));
+        }
+        if (!Constants.CONF_VERSION.equals(conf.getAttribute("version"))) {
+            throw new ConfigurationException("Invalid configuration schema version. Must be '" + Constants.CONF_VERSION + "'.");
+        }
+
+        RoleManager drm = null;
+        String userRoles = conf.getAttribute("user-roles", "");
+        if (!"".equals(userRoles)) {
+            Configuration roles;
+            try {
+                org.apache.cocoon.environment.Context context =
+                    (org.apache.cocoon.environment.Context) this.context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
+                URL url = context.getResource(userRoles);
+                if (url == null) {
+                    throw new ConfigurationException("User-roles configuration '"+userRoles+"' cannot be found.");
+                }
+                is = new InputSource(new BufferedInputStream(url.openStream()));
+                is.setSystemId(url.toString());
+                roles = builder.build(is);
+            } catch (Exception e) {
+                throw new ConfigurationException("Error trying to load user-roles configuration", e);
+            }
+
+            RoleManager urm = new RoleManager(drm);
+            ContainerUtil.enableLogging(urm, this.rootLogger.getChildLogger("roles").getChildLogger("user"));
+            ContainerUtil.configure(urm, roles);
+            roles = null;
+            drm = urm;
+        }
+
+        this.serviceManager.setRoleManager(drm);
+        this.serviceManager.setLoggerManager(this.loggerManager);
+
+        getLogger().debug("Setting up components...");
+        ContainerUtil.configure(this.serviceManager, conf);
+    }
+
+    /**
+     * Queries the class to estimate its ergodic period termination.
+     *
+     * @param date a <code>long</code> value
+     * @return a <code>boolean</code> value
+     */
+    public boolean modifiedSince(long date) {
+        return date < this.configurationFile.getLastModified();
+    }
+
+    /**
+     * Helper method to retrieve system property.
+     * Returns default value if SecurityException is caught.
+     */
+    public static String getSystemProperty(String property, String value) {
+        try {
+            return System.getProperty(property, value);
+        } catch (SecurityException e) {
+            System.err.println("Caught a SecurityException reading the system property '" + property + "';" +
+                               " Cocoon will default to '" + value + "' value.");
+            return value;
+        }
+    }
+
+    /**
+     * Sets required system properties.
+     */
+    protected void setSystemProperties() {
+        try {
+            // FIXME We shouldn't have to specify the SAXParser...
+            // This is needed by Xalan2, it is used by org.xml.sax.helpers.XMLReaderFactory
+            // to locate the SAX2 driver.
+            if (getSystemProperty("org.xml.sax.driver", null) == null) {
+                System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");
+            }
+        } catch (SecurityException e) {
+            // Ignore security exceptions
+            System.out.println("Caught a SecurityException writing the system property: " + e);
+        }
+
+        try {
+            // FIXME We shouldn't have to specify these. Needed to override jaxp implementation of weblogic.
+            if (getSystemProperty("javax.xml.parsers.DocumentBuilderFactory", "").startsWith("weblogic")) {
+                System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
+                System.setProperty("javax.xml.parsers.SAXParserFactory","org.apache.xerces.jaxp.SAXParserFactoryImpl");
+            }
+        } catch (SecurityException e) {
+            // Ignore security exceptions
+            System.out.println("Caught a SecurityException writing the system property: " + e);
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.serviceManager != null) {
+            this.serviceManager.release(this.requestListener);
+            this.requestListener = null;
+
+            this.serviceManager.release(this.processor);
+            this.processor = null;
+
+            this.serviceManager.release(this.sourceResolver);
+            this.sourceResolver = null;
+
+            ContainerUtil.dispose(this.serviceManager);
+            this.serviceManager = null;
+        }
+        if ( this.parentServiceManager != null ) {
+            this.parentServiceManager.release(this.core);
+            this.core = null;
+            this.parentServiceManager = null;
+        }
+        this.context = null;
+        if (Cocoon.instance == this) {
+            Cocoon.instance = null;
+        }
+        this.disposed = true;
+    }
+
+    /**
+     * Log debug information about the current environment.
+     *
+     * @param environment an <code>Environment</code> value
+     */
+    protected void debug(Environment environment, boolean internal) {
+        String lineSeparator = SystemUtils.LINE_SEPARATOR;
+        Map objectModel = environment.getObjectModel();
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Session session = request.getSession(false);
+        StringBuffer msg = new StringBuffer();
+        msg.append("DEBUGGING INFORMATION:").append(lineSeparator);
+        if (internal) {
+            msg.append("INTERNAL ");
+        }
+        msg.append("REQUEST: ").append(request.getRequestURI()).append(lineSeparator).append(lineSeparator);
+        msg.append("CONTEXT PATH: ").append(request.getContextPath()).append(lineSeparator);
+        msg.append("SERVLET PATH: ").append(request.getServletPath()).append(lineSeparator);
+        msg.append("PATH INFO: ").append(request.getPathInfo()).append(lineSeparator).append(lineSeparator);
+
+        msg.append("REMOTE HOST: ").append(request.getRemoteHost()).append(lineSeparator);
+        msg.append("REMOTE ADDRESS: ").append(request.getRemoteAddr()).append(lineSeparator);
+        msg.append("REMOTE USER: ").append(request.getRemoteUser()).append(lineSeparator);
+        msg.append("REQUEST SESSION ID: ").append(request.getRequestedSessionId()).append(lineSeparator);
+        msg.append("REQUEST PREFERRED LOCALE: ").append(request.getLocale().toString()).append(lineSeparator);
+        msg.append("SERVER HOST: ").append(request.getServerName()).append(lineSeparator);
+        msg.append("SERVER PORT: ").append(request.getServerPort()).append(lineSeparator).append(lineSeparator);
+
+        msg.append("METHOD: ").append(request.getMethod()).append(lineSeparator);
+        msg.append("CONTENT LENGTH: ").append(request.getContentLength()).append(lineSeparator);
+        msg.append("PROTOCOL: ").append(request.getProtocol()).append(lineSeparator);
+        msg.append("SCHEME: ").append(request.getScheme()).append(lineSeparator);
+        msg.append("AUTH TYPE: ").append(request.getAuthType()).append(lineSeparator).append(lineSeparator);
+        msg.append("CURRENT ACTIVE REQUESTS: ").append(activeRequestCount).append(lineSeparator);
+
+        // log all of the request parameters
+        Enumeration e = request.getParameterNames();
+
+        msg.append("REQUEST PARAMETERS:").append(lineSeparator).append(lineSeparator);
+
+        while (e.hasMoreElements()) {
+            String p = (String) e.nextElement();
+
+            msg.append("PARAM: '").append(p).append("' ")
+               .append("VALUES: '");
+            String[] params = request.getParameterValues(p);
+            for (int i = 0; i < params.length; i++) {
+                msg.append("[" + params[i] + "]");
+                if (i != (params.length - 1)) {
+                    msg.append(", ");
+                }
+            }
+
+            msg.append("'").append(lineSeparator);
+        }
+
+        // log all of the header parameters
+        Enumeration e2 = request.getHeaderNames();
+
+        msg.append("HEADER PARAMETERS:").append(lineSeparator).append(lineSeparator);
+
+        while (e2.hasMoreElements()) {
+            String p = (String) e2.nextElement();
+
+            msg.append("PARAM: '").append(p).append("' ")
+               .append("VALUES: '");
+            Enumeration e3 = request.getHeaders(p);
+            while (e3.hasMoreElements()) {
+                msg.append("[" + e3.nextElement() + "]");
+                if (e3.hasMoreElements()) {
+                    msg.append(", ");
+                }
+            }
+
+            msg.append("'").append(lineSeparator);
+        }
+
+        msg.append(lineSeparator).append("SESSION ATTRIBUTES:").append(lineSeparator).append(lineSeparator);
+
+        // log all of the session attributes
+        if (session != null) {
+            // Fix bug #12139: Session can be modified while still
+            // being enumerated here
+            synchronized (session) {
+                e = session.getAttributeNames();
+                while (e.hasMoreElements()) {
+                    String p = (String) e.nextElement();
+                    msg.append("PARAM: '").append(p).append("' ")
+                       .append("VALUE: '").append(session.getAttribute(p)).append("'")
+                       .append(lineSeparator);
+                }
+            }
+        }
+
+        getLogger().debug(msg.toString());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#process(org.apache.cocoon.environment.Environment)
+     */
+    public boolean process(Environment environment)
+    throws Exception {
+
+        if (this.disposed) {
+            throw new IllegalStateException("You cannot process a Disposed Cocoon engine.");
+        }
+
+        environment.startingProcessing();
+        final int environmentDepth = EnvironmentHelper.markEnvironment();
+        EnvironmentHelper.enterProcessor(this, this.serviceManager, environment);
+        try {
+            boolean result;
+            if (getLogger().isDebugEnabled()) {
+                ++activeRequestCount;
+                debug(environment, false);
+            }
+
+
+            if (this.requestListener != null) {
+                try {
+                    requestListener.onRequestStart(environment);
+                } catch (Exception e) {
+                    getLogger().error("Error encountered monitoring request start: " + e.getMessage());
+                }
+            }
+
+            result = this.processor.process(environment);
+
+            if (this.requestListener != null) {
+                try {
+                    requestListener.onRequestEnd(environment);
+                } catch (Exception e) {
+                    getLogger().error("Error encountered monitoring request start: " + e.getMessage());
+                }
+            }
+
+            // commit response on success
+            environment.commitResponse();
+
+            return result;
+        } catch (Exception any) {
+            if (this.requestListener != null) {
+                try {
+                    requestListener.onRequestException(environment, any);
+                } catch (Exception e) {
+                    getLogger().error("Error encountered monitoring request start: " + e.getMessage());
+                }
+            }
+            // reset response on error
+            environment.tryResetResponse();
+            throw any;
+        } finally {
+            EnvironmentHelper.leaveProcessor();
+            environment.finishingProcessing();
+            if (getLogger().isDebugEnabled()) {
+                --activeRequestCount;
+            }
+            Core.cleanup();
+
+            EnvironmentHelper.checkEnvironment(environmentDepth, getLogger());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#buildPipeline(org.apache.cocoon.environment.Environment)
+     */
+    public InternalPipelineDescription buildPipeline(Environment environment)
+    throws Exception {
+        if (disposed) {
+            throw new IllegalStateException("You cannot process a Disposed Cocoon engine.");
+        }
+
+        try {
+            if (getLogger().isDebugEnabled()) {
+                ++activeRequestCount;
+                debug(environment, true);
+            }
+
+            return this.processor.buildPipeline(environment);
+
+        } finally {
+            if (getLogger().isDebugEnabled()) {
+                --activeRequestCount;
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getComponentConfigurations()
+     */
+    public Configuration[] getComponentConfigurations() {
+        return null;
+    }
+
+    /**
+     * Return this (Cocoon is always at the root of the processing chain).
+     * @since 2.1.1
+     */
+    public Processor getRootProcessor() {
+        return this;
+    }
+
+    /**
+     * Accessor for active request count
+     */
+    public int getActiveRequestCount() {
+        return activeRequestCount;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getEnvironmentHelper()
+     */
+    public org.apache.cocoon.environment.SourceResolver getSourceResolver() {
+        return this.environmentHelper;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getContext()
+     */
+    public String getContext() {
+        return this.environmentHelper.getContext();
+    }
+
+    /**
+     * FIXME -  Do we really need this method?
+     */
+    public ServiceManager getServiceManager() {
+        return this.serviceManager;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.processorAttributes.get(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.processorAttributes.remove(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.processorAttributes.put(name, value);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonAccess.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonAccess.java
new file mode 100644
index 0000000..41972d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonAccess.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon;
+
+/**
+ * Accessor to the Cocoon object instance
+ */
+public class CocoonAccess {
+    protected Cocoon getCocoon() {
+        return Cocoon.instance;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonTask.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonTask.java
new file mode 100644
index 0000000..58e4a9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/CocoonTask.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicConfigurator;
+import org.apache.tools.ant.ExitException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Ant task for running Cocoon. Allows for the embedding of Cocoon into 
+ *
+ * @version $Id$
+ */
+public class CocoonTask extends Task implements DynamicConfigurator {
+
+    private CommandlineJava cmdl = new CommandlineJava();
+    private boolean failOnError = false;
+    private Throwable caught = null;
+
+    private String uriGroup = null;
+    private Document xconf;
+    private Element root;
+    private ElementWrapper _wrapper;
+    
+    private static final String CLASS_DELEGATE = "org.apache.cocoon.bean.helpers.AntDelegate";
+            
+    public CocoonTask() {
+        try {
+            DocumentBuilder builder =
+                DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            xconf = builder.newDocument();
+            root = xconf.createElement("cocoon");
+            xconf.appendChild(root);
+            _wrapper = new ElementWrapper(root);
+            cmdl.setClassname(CLASS_DELEGATE);
+        }
+        catch (ParserConfigurationException e) {
+            throw new BuildException(e);
+        }
+    }
+    
+    /**
+     * Adds a path to the classpath.
+     *
+     * @return created classpath
+     */
+    public Path createClasspath() {
+        return cmdl.createClasspath(getProject()).createPath();
+    }
+
+    /**
+     * Classpath to use, by reference.
+     *
+     * @param r a reference to an existing classpath
+     */
+    public void setClasspathRef(Reference r) {
+        createClasspath().setRefid(r);
+    }
+
+    /**
+     * Set the classpath to be used when running the Java class
+     *
+     * @param s an Ant Path object containing the classpath.
+     */
+    public void setClasspath(Path s) {
+        createClasspath().append(s);
+    }
+
+    public void setUrigroup(String group) {
+        this.uriGroup = group;
+    }
+ 
+    /**
+     * A dynamic configurator for each element.
+     */
+    private static class ElementWrapper
+                         implements DynamicConfigurator {
+
+        private Node node;
+
+        /** Instantiate a root wrapper */
+        private ElementWrapper(Node node) {
+            this.node = node;
+        }
+
+        /** Instantiate a child wrapper */
+        private ElementWrapper(Node parent, String childName) {
+            Document document = parent.getOwnerDocument();
+            if (document == null) {
+              document = (Document)parent; // Node is the document!
+            }
+            node = document.createElement(childName);
+            parent.appendChild(node);
+        }
+
+        //
+        // interface DynamicConfigurator
+        public void setDynamicAttribute(String name, String value)
+                    throws BuildException {
+            // Never called for anything by Element wrappers
+            Element element = (Element)node;
+            element.setAttribute(name, value);
+        }
+
+        public Object createDynamicElement(String name)
+                      throws BuildException {
+            return new ElementWrapper(node, name);
+        }
+    }
+
+    public File getLibDir() throws BuildException {
+        Element root = xconf.getDocumentElement();
+        String contextDir = null;
+        if (root!=null) {
+            if (hasAttribute(root, "context-dir")){
+                contextDir = getAttributeValue(root, "context-dir");
+            }
+        }
+        if (contextDir != null) {
+            return new File(contextDir + "/WEB-INF/lib");
+        }
+        throw new BuildException("No context directory specified. Cannot find Cocoon");
+    }
+
+    private static String getAttributeValue(Node node, String attr) throws IllegalArgumentException {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            if (attribute != null && attribute.getNodeValue() != null) {
+                return attribute.getNodeValue();
+            }
+        }
+        throw new IllegalArgumentException("Missing " + attr + " attribute on <" + node.getNodeName() + "> node");
+    }
+
+    private static boolean hasAttribute(Node node, String attr) {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            return (attribute != null);
+        }
+        return false;
+    }
+
+    //
+    // interface DynamicConfigurator
+    public void setDynamicAttribute(String name, String value)
+                throws BuildException {
+        root.setAttribute(name, value);
+    }
+
+    public Object createDynamicElement(String name)
+                  throws BuildException {
+        return _wrapper.createDynamicElement(name);
+    }
+
+    /**
+     * Do the execution .
+     *
+     * @throws BuildException if required parameters are missing
+     */
+    public void execute() throws BuildException {
+        if (cmdl.getClasspath() == null) {
+            throw new BuildException("Could not find a classpath that points to the Cocoon classes");
+        }
+        try {
+            try {
+                execute(cmdl);
+            } catch (ExitException ex) {
+                // ignore
+            }
+        } catch (BuildException e) {
+            if (failOnError) {
+                throw e;
+            }
+            log(e.getMessage(), Project.MSG_ERR);
+        } catch (Throwable t) {
+            if (failOnError) {
+                throw new BuildException(t);
+            }
+            log(t.getMessage(), Project.MSG_ERR);
+        }
+    }
+    
+    public void execute(CommandlineJava command) throws BuildException {
+        final String classname = command.getJavaCommand().getExecutable();
+
+        AntClassLoader loader = null;
+        try {
+            if (command.getSystemProperties() != null) {
+                command.getSystemProperties().setSystem();
+            }
+
+            final Class[] param = {Class.forName("org.w3c.dom.Document"), Class.forName("java.lang.String")};
+            Class target = null;
+            if (command.getClasspath() == null) {
+                target = Class.forName(classname);
+            } else {
+                loader = new AntClassLoader(getProject().getCoreLoader(), getProject(), 
+                                            command.getClasspath(), false);
+                loader.setIsolated(true);
+                loader.setThreadContextLoader();
+                target = loader.forceLoadClass(classname);
+                Class.forName(classname, true, loader);
+            }
+            Method method = target.getMethod("process", param);
+            if (method == null) {
+                throw new BuildException("Could not find process() method in "
+                                         + classname);
+            }
+
+            run(method);
+
+            if (caught != null) {
+                throw caught;
+            }
+
+        } catch (ClassNotFoundException e) {
+            throw new BuildException("Could not find " + classname + "."
+                                     + " Make sure you have it in your"
+                                     + " classpath");
+        } catch (SecurityException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new BuildException(e);
+        } finally {
+            if (loader != null) {
+                loader.resetThreadContextLoader();
+                loader.cleanup();
+            }
+            if (command.getSystemProperties() != null) {
+                command.getSystemProperties().restoreSystem();
+            }
+        }
+    }
+
+    public void run(Method method) {
+        final Object[] argument = {xconf, uriGroup};
+        try {
+            method.invoke(null, argument);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            if (!(t instanceof InterruptedException)) {
+                caught = t;
+            } /* else { swallow, probably due to timeout } */
+        } catch (Throwable t) {
+            caught = t;
+        } finally {
+            synchronized (this) {
+                notifyAll();
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConnectionResetException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConnectionResetException.java
new file mode 100644
index 0000000..ef3cc9d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConnectionResetException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+/**
+ * This Exception is thrown every time a component detects an exception
+ * due to a connection reset by peer.
+ *
+ * @version $Id$
+ */
+public class ConnectionResetException extends ProcessingException {
+
+    /**
+     * Construct a new <code>ConnectionResetException</code> instance.
+     *
+     * @param message a <code>String</code> value
+     */
+    public ConnectionResetException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct a new <code>ConnectionResetException</code> that references
+     * a parent Exception.
+     *
+     * @param message a <code>String</code> value
+     * @param t a <code>Throwable</code> value
+     */
+    public ConnectionResetException(String message, Throwable t) {
+        super(message, t);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Constants.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Constants.java
new file mode 100644
index 0000000..9097179
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Constants.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * The <code>Constants</code> used throughout the core of the Cocoon engine.
+ *
+ * @version $Id$
+ */
+public final class Constants {
+
+    /** Our properties are now here: */
+    private static final String PROPS_FILE = "org/apache/cocoon/cocoon.properties";
+
+    static final Properties properties;
+
+    /**
+     * Load the cocoon properties
+     */
+    static {
+        properties = new Properties();
+        try {
+            final InputStream is = Constants.class.getClassLoader().getResourceAsStream(PROPS_FILE);
+            if ( null == is ) {
+                throw new ConstantsInitializationException("Cocoon cannot find required properties from " + PROPS_FILE);
+            }
+            properties.load(is);
+        } catch (IOException ioe) {
+            throw new ConstantsInitializationException("Cocoon cannot load required properties from " + PROPS_FILE, ioe);
+        }
+
+    }
+
+    /** The name of this project. */
+    public static final String NAME = properties.getProperty("name");
+
+    /** The version of this build. */
+    public static final String VERSION = properties.getProperty("version");
+
+    /** The full name of this project. */
+    public static final String COMPLETE_NAME = properties.getProperty("fullname") + " " + VERSION;
+
+    /** The version of the configuration schema */
+    public static final String CONF_VERSION  = "2.2";
+
+    /** The year of the build */
+    public static final String YEAR = properties.getProperty("year");
+
+    /** The build information */
+    public static final String BUILD_INFO = properties.getProperty("build.info");
+
+    /**
+     * The request parameter name to reload the configuration.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String RELOAD_PARAM = "cocoon-reload";
+
+    /**
+     * The request parameter name to add a line of the request duration.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String SHOWTIME_PARAM = "cocoon-showtime";
+
+    /**
+     * The request parameter name to request a specific view of a resource.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String VIEW_PARAM = "cocoon-view";
+
+    /**
+     * The request parameter name to trigger a specific action.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String ACTION_PARAM = "cocoon-action";
+
+    /**
+     * The request parameter prefix to trigger a specific action.
+     *
+     * FIXME(GP): Isn't this Servlet specific?
+     */
+    public static final String ACTION_PARAM_PREFIX = "cocoon-action-";
+
+    /** The URI for xml namespaces */
+    public static final String XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
+
+    /**
+     * Mime-type for the link view
+     *
+     * FIXME(GP): Isn't this Environment specific?
+     */
+    public static final String LINK_CONTENT_TYPE = "application/x-cocoon-links";
+
+    /**
+     * Name of the request value for the link view
+     *
+     * FIXME(GP): Isn't this Environment specific?
+     */
+    public static final String LINK_VIEW = "links";
+
+    /**
+     * Key of the Map of index translation table.
+     * <p>Presence of this Map in the ObjectModel indicates to the Sitemap that link
+     * translation mode has been requested by the environment. Sitemap adds LinkTranslator
+     * transformer to the pipeline, which replaces all the links in the input document with
+     * the links from this translation table.
+     * <p>
+     * TODO(VG): Move this declaration to ObjectModelHelper
+     * comment found at ObjectModelHelper(JH):
+     * LINK_OBJECT should also be moved to CommandLineEnvironment
+     */
+    public static final String LINK_OBJECT = "link";
+
+    /**
+     * Key of the List for collecting links.
+     * <p>Presence of this Map in the ObjectModel indicates to the Sitemap that link
+     * gathering mode has been requested by the environment. Sitemap adds LinkGatherer
+     * transformer to the pipeline, which gathers the links in the input document into
+     * this List.
+     * <p>
+     */
+    public static final String LINK_COLLECTION_OBJECT = "link-collection";
+
+    /**
+     * The name of a <code>NotifyingObject</code> in the so called objectModel <code>Map</code>.
+     */
+    public static final String NOTIFYING_OBJECT = "notifying-object";
+
+    /**
+     * The default URI to be used when a URI requested refers to
+     * a directory, e.g. http://localhost:8080/site/
+     */
+    public static final String INDEX_URI = "index";
+
+    /**
+     * The directory to use as context root.
+     */
+    public static final String DEFAULT_CONTEXT_DIR = "./webapp";
+
+    /**
+     * The diretory to use to use for the generated output.
+     */
+    public static final String DEFAULT_DEST_DIR = "./site";
+
+    /**
+     * The diretory to use for generated files.
+     */
+    public static final String DEFAULT_WORK_DIR = "./work";
+
+    /**
+     * How a default configuration file is named.
+     */
+    public static final String DEFAULT_CONF_FILE = "cocoon.xconf";
+
+    /** The namespace URI for the Error/Exception XML */
+    public static final String ERROR_NAMESPACE_URI = "http://apache.org/cocoon/error/2.1";
+
+    /** The namespace prefix for the Error/Exception XML */
+    public static final String ERROR_NAMESPACE_PREFIX = "error";
+
+    /** Application <code>Context</code> Key for the environmental Context */
+    public static final String CONTEXT_ENVIRONMENT_CONTEXT = "environment-context";
+
+    /** Application <code>Context</code> Key for the global classloader */
+    public static final String CONTEXT_CLASS_LOADER = "class-loader";
+
+    /** Application <code>Context</code> Key for the work directory path */
+    public static final String CONTEXT_WORK_DIR = "work-directory";
+
+    /** Application <code>Context</code> Key for the upload directory path */
+    public static final String CONTEXT_UPLOAD_DIR = "upload-directory";
+
+    /** Application <code>Context</code> Key for the cache directory path */
+    public static final String CONTEXT_CACHE_DIR = "cache-directory";
+
+    /** Application <code>Context</code> Key for the current classpath */
+    public static final String CONTEXT_CLASSPATH = "classpath";
+
+
+    /** Application <code>Context</code> key for the current environment URI */
+    public static final String CONTEXT_ENV_URI = "env-uri";
+
+    /** Application <code>Context</code> key for the current environment prefix */
+    public static final String CONTEXT_ENV_PREFIX = "env-prefix";
+
+    /** Application <code>Context</code> key for the current environment helper */
+    public static final String CONTEXT_ENV_HELPER = "env-helper";
+
+    /** Application <code>Context</code> key prefix for the current sitemap virtual components */
+    public static final String CONTEXT_VPC_PREFIX = "vpc-";
+
+    /** Path to the wiring.xml relative to the context root directory */
+    public static final String WIRING = "wiring.xml";    
+    
+    public static final String BLOCK_META_DIR = "COB-INF";
+    
+    /**
+     * Application <code>Context</code> Key for the URL to the configuration file
+     * (usually named cocoon.xconf)
+     * @deprecated Use {@link org.apache.cocoon.core.Settings#getConfiguration()}.
+     */
+    public static final String CONTEXT_CONFIG_URL = "config-url";
+
+    /** Application <code>Context</code> Key for the default encoding.
+     * @deprecated Use {@link org.apache.cocoon.core.Settings#getFormEncoding()}. */
+    public static final String CONTEXT_DEFAULT_ENCODING = "default-encoding";
+
+    
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConstantsInitializationException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConstantsInitializationException.java
new file mode 100644
index 0000000..d8a7dbc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ConstantsInitializationException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+public final class ConstantsInitializationException extends CascadingRuntimeException
+{
+    public ConstantsInitializationException(String message)
+    {
+        super(message, null);
+    }
+
+    public ConstantsInitializationException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Main.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Main.java
new file mode 100644
index 0000000..c5c1d09
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Main.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import java.io.File;
+import java.util.Arrays;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.cocoon.bean.CocoonBean;
+import org.apache.cocoon.bean.helpers.OutputStreamListener;
+import org.apache.cocoon.bean.helpers.BeanConfigurator;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
+import org.apache.commons.lang.BooleanUtils;
+
+import org.w3c.dom.Document;
+
+/**
+ * Command line entry point. Parses command line, create Cocoon bean and invokes it
+ * with file destination.
+ *
+ * @version $Id$
+ */
+public class Main {
+
+    protected static final String HELP_OPT =               "h";
+    protected static final String VERSION_OPT =            "v";
+    protected static final String LOG_KIT_OPT =            "k";
+    protected static final String LOGGER_OPT =             "l";
+    protected static final String LOG_LEVEL_OPT =          "u";
+    protected static final String CONTEXT_DIR_OPT =        "c";
+    protected static final String DEST_DIR_OPT =           "d";
+    protected static final String WORK_DIR_OPT =           "w";
+    protected static final String CONFIG_FILE_OPT =        "C";
+    protected static final String BROKEN_LINK_FILE_OPT =   "b";
+    protected static final String URI_FILE_OPT =           "f";
+    protected static final String XCONF_OPT =              "x";
+    protected static final String AGENT_OPT =              "a";
+    protected static final String ACCEPT_OPT =             "p";
+    protected static final String FOLLOW_LINKS_OPT =       "r";
+    protected static final String PRECOMPILE_ONLY_OPT =    "P";
+    protected static final String CONFIRM_EXTENSIONS_OPT = "e";
+    protected static final String LOAD_CLASS_OPT =         "L";
+    protected static final String DEFAULT_FILENAME_OPT =   "D";
+    protected static final String URI_GROUP_NAME_OPT =     "n";
+
+    protected static final String HELP_LONG =               "help";
+    protected static final String VERSION_LONG =            "version";
+    protected static final String LOG_KIT_LONG =            "logKitconfig";
+    protected static final String LOGGER_LONG =             "Logger";
+    protected static final String LOG_LEVEL_LONG =          "logLevel";
+    protected static final String CONTEXT_DIR_LONG =        "contextDir";
+    protected static final String DEST_DIR_LONG =           "destDir";
+    protected static final String WORK_DIR_LONG =           "workDir";
+    protected static final String CONFIG_FILE_LONG =        "configFile";
+    protected static final String BROKEN_LINK_FILE_LONG =   "brokenLinkFile";
+    protected static final String URI_FILE_LONG =           "uriFile";
+    protected static final String XCONF_LONG =              "xconf";
+    protected static final String AGENT_LONG =              "userAgent";
+    protected static final String ACCEPT_LONG =             "accept";
+    protected static final String FOLLOW_LINKS_LONG =       "followLinks";
+    protected static final String PRECOMPILE_ONLY_LONG =    "precompileOnly";
+    protected static final String CONFIRM_EXTENSIONS_LONG = "confirmExtensions";
+    protected static final String LOAD_CLASS_LONG =         "loadClass";
+    protected static final String DEFAULT_FILENAME_LONG =   "defaultFilename";
+    protected static final String URI_LONG =                "uri";
+    protected static final String URI_GROUP_NAME_LONG =     "uris";
+    
+    private static Options options;
+    private static OutputStreamListener listener;
+
+    private static void setOptions() {
+        options = new Options();
+
+        options.addOption(new Option(HELP_OPT,
+                                     HELP_LONG,
+                                     false,
+                                     "print this message and exit"));
+
+        options.addOption(new Option(VERSION_OPT,
+                                     VERSION_LONG,
+                                     false,
+                                     "print the version information and exit"));
+
+        options.addOption(new Option(LOG_KIT_OPT,
+                                     LOG_KIT_LONG,
+                                     true,
+                                     "use given file for LogKit Management configuration"));
+
+        options.addOption(new Option(LOGGER_OPT,
+                                     LOGGER_LONG,
+                                     true,
+                                     "use given logger category as default logger for the Cocoon engine"));
+
+        options.addOption(new Option(LOG_LEVEL_OPT,
+                                     LOG_LEVEL_LONG,
+                                     true,
+                                     "choose the minimum log level for logging (DEBUG, INFO, WARN, ERROR, FATAL_ERROR) for startup logging"));
+
+        options.addOption(new Option(CONTEXT_DIR_OPT,
+                                     CONTEXT_DIR_LONG,
+                                     true,
+                                     "use given dir as context"));
+
+        options.addOption(new Option(DEST_DIR_OPT,
+                                     DEST_DIR_LONG,
+                                     true,
+                                     "use given dir as destination"));
+
+        options.addOption(new Option(WORK_DIR_OPT,
+                                     WORK_DIR_LONG,
+                                     true,
+                                     "use given dir as working directory"));
+
+        options.addOption(new Option(CONFIG_FILE_OPT,
+                                     CONFIG_FILE_LONG,
+                                     true,
+                                     "specify alternate location of the configuration"
+                                     + " file (default is ${contextDir}/cocoon.xconf)"));
+
+        options.addOption(new Option(BROKEN_LINK_FILE_OPT,
+                                     BROKEN_LINK_FILE_LONG,
+                                     true,
+                                     "send a list of broken links to a file (one URI per line)"));
+
+        options.addOption(new Option(URI_FILE_OPT,
+                                     URI_FILE_LONG,
+                                     true,
+                                     "use a text file with uris to process (one URI per line)"));
+
+        options.addOption(new Option(XCONF_OPT,
+                                     XCONF_LONG,
+                                     true,
+                                     "specify a file containing XML configuration details"
+                                     + " for the command line interface"));
+
+        options.addOption(new Option(AGENT_OPT,
+                                     AGENT_LONG,
+                                     true,
+                                     "use given string for user-agent header"));
+
+        options.addOption(new Option(ACCEPT_OPT,
+                                     ACCEPT_LONG,
+                                     true,
+                                     "use given string for accept header"));
+
+        options.addOption(new Option(FOLLOW_LINKS_OPT,
+                                     FOLLOW_LINKS_LONG,
+                                     true,
+                                     "process pages linked from starting page or not"
+                                     + " (boolean argument is expected, default is true)"));
+
+        options.addOption(new Option(PRECOMPILE_ONLY_OPT,
+                                     PRECOMPILE_ONLY_LONG,
+                                     true,
+                                     "generate java code for xsp and xmap files"));
+
+        options.addOption(new Option(CONFIRM_EXTENSIONS_OPT,
+                                     CONFIRM_EXTENSIONS_LONG,
+                                     true,
+                                     "confirm that file extensions match mime-type of"
+                                     + " pages and amend filename accordingly (default"
+                                     + " is true)"));
+
+        options.addOption(new Option(LOAD_CLASS_OPT,
+                                     LOAD_CLASS_LONG,
+                                     true,
+                                     "specify a class to be loaded at startup (specifically"
+                                     + " for use with JDBC). Can be used multiple times"));
+
+        options.addOption(new Option(DEFAULT_FILENAME_OPT,
+                                     DEFAULT_FILENAME_LONG,
+                                     true,
+                                     "specify a filename to be appended to a URI when the"
+                                     + " URI refers to a directory"));
+        options.addOption(new Option(URI_GROUP_NAME_OPT,
+                                     URI_GROUP_NAME_LONG,
+                                     true,
+                                     "specify which <uris> element to process in the configuration"
+                                     + " file specified with the -x parameter"));
+    }
+
+    /**
+     * The <code>main</code> method.
+     *
+     * @param args a <code>String[]</code> of arguments
+     * @exception Exception if an error occurs
+     */
+    public static void main(String[] args) throws Exception {
+
+        Main.setOptions();
+        CommandLine line = new PosixParser().parse( options, args );
+        listener = new OutputStreamListener(System.out);
+        CocoonBean cocoon = new CocoonBean();
+        cocoon.addListener(listener);
+
+        if (line.hasOption(HELP_OPT)) {
+             printUsage();
+        } else if (line.hasOption(VERSION_OPT)) {
+             printVersion();
+        }
+
+        String uriGroup = null;
+        if (line.hasOption(URI_GROUP_NAME_OPT)) {
+            uriGroup = line.getOptionValue(URI_GROUP_NAME_OPT);
+        }
+            
+        String destDir = null;
+        if (line.hasOption(XCONF_OPT)) {
+            // destDir from command line overrides one in xconf file
+            destDir = Main.processXConf(cocoon, line.getOptionValue(XCONF_OPT), destDir, uriGroup);
+        }
+        if (line.hasOption(DEST_DIR_OPT)) {
+            destDir = line.getOptionValue(DEST_DIR_OPT);
+        }
+
+        if (line.hasOption(PRECOMPILE_ONLY_OPT)) {
+            cocoon.setPrecompileOnly(true);
+        }
+
+        if (line.hasOption(WORK_DIR_OPT)) {
+            String workDir = line.getOptionValue(WORK_DIR_OPT);
+            if (workDir.equals("")) {
+                listener.messageGenerated(
+                    "Careful, you must specify a work dir when using the -w/--workDir argument");
+                System.exit(1);
+            } else {
+                cocoon.setWorkDir(line.getOptionValue(WORK_DIR_OPT));
+            }
+        }
+        if (line.hasOption(CONTEXT_DIR_OPT)) {
+            String contextDir = line.getOptionValue(CONTEXT_DIR_OPT);
+            if (contextDir.equals("")) {
+                listener.messageGenerated(
+                    "Careful, you must specify a configuration file when using the -c/--contextDir argument");
+                System.exit(1);
+            } else {  
+                cocoon.setContextDir(contextDir);
+            }
+        }
+        if (line.hasOption(CONFIG_FILE_OPT)) {
+            cocoon.setConfigFile(line.getOptionValue(CONFIG_FILE_OPT));
+        }
+        if (line.hasOption(LOG_KIT_OPT)) {
+            cocoon.setLogKit(line.getOptionValue(LOG_KIT_OPT));
+        }
+        if (line.hasOption(LOGGER_OPT)) {
+            cocoon.setLogger(line.getOptionValue(LOGGER_OPT));
+        }
+        if (line.hasOption(LOG_LEVEL_OPT)) {
+            cocoon.setLogLevel(line.getOptionValue(LOG_LEVEL_OPT));
+        }
+        if (line.hasOption(AGENT_OPT)) {
+            cocoon.setAgentOptions(line.getOptionValue(AGENT_OPT));
+        }
+        if (line.hasOption(ACCEPT_OPT)) {
+            cocoon.setAcceptOptions(line.getOptionValue(ACCEPT_OPT));
+        }
+        if (line.hasOption(DEFAULT_FILENAME_OPT)) {
+            cocoon.setDefaultFilename(line.getOptionValue(DEFAULT_FILENAME_OPT));
+        }
+        if (line.hasOption(BROKEN_LINK_FILE_OPT)) {
+            listener.setReportFile(line.getOptionValue(BROKEN_LINK_FILE_OPT));
+        }
+        if (line.hasOption(FOLLOW_LINKS_OPT)) {
+            cocoon.setFollowLinks(BooleanUtils.toBoolean(line.getOptionValue(FOLLOW_LINKS_OPT)));
+        }
+        if (line.hasOption(CONFIRM_EXTENSIONS_OPT)) {
+            cocoon.setConfirmExtensions(BooleanUtils.toBoolean(line.getOptionValue(CONFIRM_EXTENSIONS_OPT, "yes")));
+        }
+        if (line.hasOption(LOAD_CLASS_OPT)){
+            cocoon.addLoadedClasses(Arrays.asList(line.getOptionValues(LOAD_CLASS_OPT)));
+        }
+        if (line.hasOption(URI_FILE_OPT)) {
+            cocoon.addTargets(BeanConfigurator.processURIFile(line.getOptionValue(URI_FILE_OPT)), destDir);
+        }
+
+        cocoon.addTargets(line.getArgList(), destDir);
+
+        listener.messageGenerated(CocoonBean.getProlog());
+
+        if (cocoon.getTargetCount() ==0 && cocoon.isPrecompileOnly()) {
+            listener.messageGenerated("Please, specify at least one starting URI.");
+            System.exit(1);
+        }
+
+        cocoon.initialize();
+        cocoon.process();
+        cocoon.dispose();
+
+        listener.complete();
+
+
+        int exitCode = (listener.isSuccessful() ? 0 : 1);
+        System.exit(exitCode);
+    }
+
+    private static String processXConf(CocoonBean cocoon, String filename, String destDir, String uriGroup) {
+
+        try {
+            final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            final Document xconf = builder.parse(new File(filename).toURL().toExternalForm());
+            return BeanConfigurator.configure(xconf, cocoon, destDir, uriGroup, listener);
+        } catch (Exception e) {
+            System.out.println("ERROR: " + e.getMessage());
+            return destDir;
+        }
+    }
+
+    /**
+     * Print the usage message and exit
+     */
+    private static void printUsage() {
+        HelpFormatter formatter = new HelpFormatter();
+
+        formatter.printHelp("cocoon cli [options] [targets]",
+                            CocoonBean.getProlog(),
+                            options,
+                            "Note: the context directory defaults to '"+ Constants.DEFAULT_CONTEXT_DIR + "'");
+        System.exit(0);
+    }
+
+    /**
+     * Print the version string and exit
+     */
+    private static void printVersion() {
+        System.out.println(Constants.VERSION);
+        System.exit(0);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Modifiable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Modifiable.java
new file mode 100644
index 0000000..67f0077
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Modifiable.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+/**
+ * This interface is implemented by those classes that change
+ * their behavior/results over time (non-ergodic).
+ *
+ * @version $Id$
+ */
+public interface Modifiable {
+
+    /**
+     * Queries the class to estimate its ergodic period termination.
+     * <br>
+     * This method is called to ensure the validity of a cached product. It
+     * is the class responsibility to provide the fastest possible
+     * implementation of this method or, whether this is not possible and the
+     * costs of the change evaluation is comparable to the production costs,
+     * to return <b>true</b> directly with no further delay, thus reducing
+     * the evaluation overhead to a minimum.
+     *
+     * @return <b>true</b> if the class ergodic period is over and the class
+     *         would behave differently if processed again, <b>false</b> if the
+     *         resource is still ergodic so that it doesn't require
+     *         reprocessing.
+     */
+    boolean modifiedSince( long date );
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ProcessingException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ProcessingException.java
new file mode 100644
index 0000000..d4597bc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ProcessingException.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import java.util.List;
+
+import org.apache.cocoon.util.location.LocatedException;
+import org.apache.cocoon.util.location.LocatedRuntimeException;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.MultiLocatable;
+
+/**
+ * This Exception is thrown every time there is a problem in processing
+ * a request.
+ *
+ * @version $Id$
+ */
+public class ProcessingException extends LocatedException implements MultiLocatable {
+    
+    /**
+     * Construct a new <code>ProcessingException</code> instance.
+     */
+    public ProcessingException(String message) {
+        super(message);
+    }
+    
+    /**
+     * Creates a new <code>ProcessingException</code> instance.
+     *
+     * @param ex an <code>Exception</code> value
+     */
+    public ProcessingException(Exception ex) {
+        super(ex.getMessage(), ex);
+    }
+    
+    /**
+     * Construct a new <code>ProcessingException</code> that references
+     * a parent Exception.
+     */
+    public ProcessingException(String message, Throwable t) {
+        super(message, t);
+    }
+    
+    /**
+     * Construct a new <code>ProcessingException</code> that has an associated location.
+     */
+    public ProcessingException(String message, Location location) {
+        super(message, location);
+    }
+    
+    /**
+     * Construct a new <code>ProcessingException</code> that has a parent exception
+     * and an associated location.
+     * <p>
+     * This constructor is protected to enforce the use of {@link #throwLocated(String, Throwable, Location)}
+     * which limits exception nesting as far as possible.
+     */
+    protected ProcessingException(String message, Throwable t, Location location) {
+        super(message, t, location);
+    }
+    
+    /**
+     * Throw a located exception given an existing exception and the location where
+     * this exception was catched.
+     * <p>
+     * If the exception is already a <code>ProcessingException</code> or a {@link LocatedRuntimeException},
+     * the location is added to the original exception's location chain and the original exception
+     * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
+     * <code>ProcessingException</code> is thrown, wrapping the original exception.
+     * <p>
+     * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
+     * semantics in the caller code, i.e. write<br>
+     * <code>&nbsp;&nbsp;throw ProcessingException.throwLocated(...);</code><br>
+     * instead of<br>
+     * <code>&nbsp;&nbsp;ProcessingException.throwLocated(...);</code><br>
+     * <code>&nbsp;&nbsp;return;</code>
+     * 
+     * @param message a message (can be <code>null</code>)
+     * @param thr the original exception (can be <code>null</code>)
+     * @param location the location (can be <code>null</code>)
+     * @return a (fake) located exception
+     * @throws ProcessingException or <code>LocatedRuntimeException</code>
+     */
+    public static ProcessingException throwLocated(String message, Throwable thr, Location location) throws ProcessingException {
+        if (thr instanceof ProcessingException) {
+            ProcessingException pe = (ProcessingException)thr;
+            pe.addLocation(location);
+            throw pe;
+
+        } else if (thr instanceof LocatedRuntimeException) {
+            LocatedRuntimeException re = (LocatedRuntimeException)thr;
+            re.addLocation(location);
+            // Rethrow
+            throw re;
+        }
+        
+        throw new ProcessingException(message, thr, location);
+    }
+    
+    /**
+     * Throw a located exception given an existing exception and the locations where
+     * this exception was catched.
+     * <p>
+     * If the exception is already a <code>ProcessingException</code> or a {@link LocatedRuntimeException},
+     * the locations are added to the original exception's location chain and the original exception
+     * is rethrown (<code>description</code> is ignored) to limit exception nesting. Otherwise, a new
+     * <code>ProcessingException</code> is thrown, wrapping the original exception.
+     * <p>
+     * Note: this method returns an exception as a convenience if you want to keep the <code>throw</code>
+     * semantics in the caller code, i.e. write<br>
+     * <code>&nbsp;&nbsp;throw ProcessingException.throwLocated(...);</code><br>
+     * instead of<br>
+     * <code>&nbsp;&nbsp;ProcessingException.throwLocated(...);</code><br>
+     * <code>&nbsp;&nbsp;return;</code>
+     * 
+     * @param message a message (can be <code>null</code>)
+     * @param thr the original exception (can be <code>null</code>)
+     * @param locations the locations (can be <code>null</code>)
+     * @return a (fake) located exception
+     * @throws ProcessingException or <code>LocatedRuntimeException</code>
+     */
+    public static ProcessingException throwLocated(String message, Throwable thr, List locations) throws ProcessingException {
+        MultiLocatable multiloc;
+        if (thr instanceof ProcessingException) {
+            multiloc = (ProcessingException)thr;
+        } else if (thr instanceof LocatedRuntimeException) {
+            multiloc = (LocatedRuntimeException)thr;
+        } else {
+            multiloc = new ProcessingException(message, thr);
+        }
+        
+        if (locations != null) {
+            for (int i = 0; i < locations.size(); i++) {
+                multiloc.addLocation((Location)locations.get(i));
+            }
+        }
+        
+        if (multiloc instanceof LocatedRuntimeException) {
+            throw (LocatedRuntimeException)multiloc;
+        } else {
+            throw (ProcessingException)multiloc;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Processor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Processor.java
new file mode 100644
index 0000000..ea1b6bc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/Processor.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface Processor {
+
+    /** The role of the root processor */
+    String ROLE = Processor.class.getName();
+
+    public static class InternalPipelineDescription {
+        
+        public InternalPipelineDescription(ProcessingPipeline pp, 
+                                           ServiceSelector selector,
+                                           ServiceManager manager) {
+            this.processingPipeline = pp;
+            this.pipelineSelector = selector;
+            this.pipelineManager = manager;
+        }
+        public ProcessingPipeline processingPipeline;
+        public ServiceManager pipelineManager;
+        public ServiceSelector pipelineSelector;
+        public Processor lastProcessor;
+        public String prefix;
+        public String uri;
+        
+        public void release() {
+            if (this.pipelineSelector != null) {
+                this.pipelineSelector.release(this.processingPipeline);
+                this.pipelineManager.release(this.pipelineSelector);
+            }
+            this.lastProcessor = null;
+            this.processingPipeline = null;
+            this.pipelineManager = null;
+            this.pipelineSelector = null;
+        }
+    }
+    
+    /**
+     * Process the given <code>Environment</code> producing the output.
+     * @return If the processing is successfull <code>true</code> is returned.
+     *         If no match is found in the sitemap <code>false</code>
+     *         is returned.
+     * @throws ResourceNotFoundException If a sitemap component tries
+     *                                   to access a resource which can not
+     *                                   be found, e.g. the generator
+     *         ConnectionResetException  If the connection was reset
+     */
+    boolean process(Environment environment)
+    throws Exception;
+
+    /**
+     * Process the given <code>Environment</code> to assemble
+     * a <code>ProcessingPipeline</code>.
+     * Don't forget to release the pipeline using
+     * {@link InternalPipelineDescription#release()}.
+     * @since 2.2
+     */
+    InternalPipelineDescription buildPipeline(Environment environment)
+    throws Exception;
+
+    /**
+     * Get the sitemap component configurations
+     * @since 2.2
+     */
+    Configuration[] getComponentConfigurations();
+
+    /**
+     * Get the root processor parent of this processor.
+     * @since 2.1.1
+     */
+    Processor getRootProcessor();
+    
+    /**
+     * Get the source resolver for this processor
+     * @since 2.2
+     */
+    SourceResolver getSourceResolver();
+    
+    /**
+     * Get the context URI for this processor
+     * @since 2.2
+     */
+    String getContext();
+
+    /**
+     * Sets an attribute
+     * @since 2.2
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     * Gets an attribute
+     * @since 2.2
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Remove an attribute.
+     * @since 2.2
+     */
+    Object removeAttribute(String name);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/RequestListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/RequestListener.java
new file mode 100644
index 0000000..03f9ad9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/RequestListener.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.cocoon.environment.Environment;
+
+
+/**
+ * This is called from with {@link Cocoon#process(Environment)}, before any
+ * requests are passed onto the {@link Processor} and after the request has been
+ * processed. It allows all requests to be logged or monitored.
+ * NB Cocoon does not require an instance of this Component to function, but if
+ * there is one it will be used.
+ */
+public interface RequestListener  {
+    
+    String ROLE = RequestListener.class.getName();
+
+    /** 
+     * <p>In this method you can call, for example:
+     * <code>Request req=ObjectModelHelper.getRequest(env.getObjectModel());</code>
+     * And then, you could use the following:
+     * <ul>
+     * <li>req.getRequestURI()</li>
+     * <li>req.getQueryString()</li>
+     * <li>req.getSession().getId()</li>
+     * <li>req.getLocale().getLanguage().toString()</li>
+     * </ul>
+     * <p>
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     */
+    public void onRequestStart(Environment environment);
+
+    /** 
+     * <p>This method is called when a request has completed. This method is
+     * called before the response is committed.
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     */
+    public void onRequestEnd(Environment environment);
+    /** 
+     * <p>This method is called when an exception has occurred processing the request.
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     * @param throwable the error that occurred processing the request.
+     */
+    public void onRequestException(Environment environment, Throwable throwable);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ResourceNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ResourceNotFoundException.java
new file mode 100644
index 0000000..a9e55fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/ResourceNotFoundException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.cocoon.util.location.Location;
+
+/**
+ * This Exception is thrown every time there is a problem in finding
+ * a resource.
+ *
+ * @version $Id$
+ */
+public class ResourceNotFoundException extends ProcessingException {
+
+    /**
+     * Construct a new <code>ResourceNotFoundException</code> instance.
+     */
+    public ResourceNotFoundException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct a new <code>ResourceNotFoundException</code> that references
+     * a parent Exception.
+     */
+    public ResourceNotFoundException(String message, Throwable t) {
+        super(message, t);
+    }
+    
+    public ResourceNotFoundException(String message, Location location) {
+        super(message, location);
+    }
+    
+    public ResourceNotFoundException(String message, Throwable t, Location loc) {
+        super(message, t, loc);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractAction.java
new file mode 100644
index 0000000..cbd981c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractAction.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * AbstractAction gives you the infrastructure for easily deploying more
+ * Actions.  In order to get at the Logger, use getLogger().
+ *
+ * @version $Id$
+ */
+public abstract class AbstractAction extends AbstractLogEnabled
+    implements Action {
+
+    /**
+     * Empty unmodifiable map.
+     */
+    protected static final Map EMPTY_MAP = Collections.EMPTY_MAP;
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractComplementaryConfigurableAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractComplementaryConfigurableAction.java
new file mode 100644
index 0000000..5659cb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractComplementaryConfigurableAction.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Set up environment for configurable form handling data.  This group
+ * of actions are unique in that they employ a terciary mapping.
+ *
+ * Each configuration file must use the same format in order to be
+ * effective.  The name of the root configuration element is irrelevant.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractComplementaryConfigurableAction extends ConfigurableServiceableAction {
+
+    /**
+     * Should descriptors be reloaded?
+     */
+    public static final boolean DESCRIPTOR_RELOADABLE_DEFAULT = true;
+
+    private static Map configurations = new HashMap();
+
+    /**
+     * Set up the complementary configuration file.  Please note that
+     * multiple Actions can share the same configurations.  By using
+     * this approach, we can limit the number of config files.
+     * Also note that the configuration file does not have to be a file.
+     *
+     * Defaults to reload configuration file it has changed.
+     */
+    protected Configuration getConfiguration(String descriptor) throws ConfigurationException {
+        boolean reloadable = DESCRIPTOR_RELOADABLE_DEFAULT;
+        if (this.settings.containsKey("reloadable"))
+            reloadable = Boolean.valueOf((String) this.settings.get("reloadable")).booleanValue();
+        return this.getConfiguration(descriptor, null, reloadable);
+    }
+
+    /**
+     * Set up the complementary configuration file.  Please note that
+     * multiple Actions can share the same configurations.  By using
+     * this approach, we can limit the number of config files.
+     * Also note that the configuration file does not have to be a file.
+     */
+    protected Configuration getConfiguration(String descriptor, SourceResolver resolver, boolean reloadable) throws ConfigurationException {
+        ConfigurationHelper conf = null;
+
+        if (descriptor == null) {
+            throw new ConfigurationException("The form descriptor is not set!");
+        }
+
+        synchronized (AbstractComplementaryConfigurableAction.configurations) {
+            Source resource = null;
+            try {
+                resource = resolver.resolveURI(descriptor);
+                conf = (ConfigurationHelper) AbstractComplementaryConfigurableAction.configurations.get(resource.getURI());
+                if (conf == null || (reloadable && conf.lastModified != resource.getLastModified())) {
+                    getLogger().debug("(Re)Loading " + descriptor);
+
+                    if (conf == null) {
+                        conf = new ConfigurationHelper();
+                    }
+
+                    SAXConfigurationHandler builder = new SAXConfigurationHandler();
+                    SourceUtil.parse(this.manager, resource, builder);
+
+                    conf.lastModified = resource.getLastModified();
+                    conf.configuration = builder.getConfiguration();
+
+                    AbstractComplementaryConfigurableAction.configurations.put(resource.getURI(), conf);
+                } else {
+                    getLogger().debug("Using cached configuration for " + descriptor);
+                }
+            } catch (Exception e) {
+                getLogger().error("Could not configure Database mapping environment", e);
+                throw new ConfigurationException("Error trying to load configurations for resource: "
+                    + (resource == null ? "null" : resource.getURI()));
+            } finally {
+                resolver.release(resource);
+            }
+        }
+
+        return conf.configuration;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractConfigurableAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractConfigurableAction.java
new file mode 100644
index 0000000..a6308df
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractConfigurableAction.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.util.HashMap;
+
+/**
+ * AbstractConfigurableAction gives you the infrastructure for easily
+ * deploying more Actions that take default parameters.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractConfigurableAction extends AbstractAction implements Configurable {
+
+    /**
+     * Stores (global) configuration parameters as <code>key</code> /
+     * <code>value</code> pairs.
+     */
+    protected HashMap settings = null;
+
+    /**
+     * Configures the Action.
+     *
+     * Takes the children from the <code>Configuration</code> and stores them
+     * them as key (configuration name) and value (configuration value)
+     * in <code>settings</code>.
+     * <br/>
+     * This automates parsing of flat string-only configurations.
+     * For nested configurations, override this function in your action.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        Configuration[] parameters = conf.getChildren();
+        this.settings = new HashMap(parameters.length);
+        for (int i = 0; i < parameters.length; i++) {
+            String key = parameters[i].getName();
+            String val = parameters[i].getValue(null);
+            this.settings.put(key, val);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractMultiAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractMultiAction.java
new file mode 100644
index 0000000..13cd37f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractMultiAction.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Enumeration;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * The <code>AbstractMultiAction</code> provides a way
+ * to call methods of an action specified by
+ * the <code>method</code> parameter or request parameter.
+ * This can be extremly useful for action-sets or as
+ * action-sets replacement.
+ *
+ * Example:
+ * <input type="submit" name="doSave" value="Save it"/>
+ * will call the method "doSave" of the MultiAction
+ *
+ * @version $Id$
+ */
+public abstract class AbstractMultiAction extends ConfigurableServiceableAction {
+
+    private static final String ACTION_METHOD_PREFIX = "do";
+    private static final String ACTION_METHOD_PARAMETER = "method";
+
+    private HashMap methodIndex;
+
+    private static final String removePrefix( String name ) {
+        int prefixLen = ACTION_METHOD_PREFIX.length();
+        return name.substring(prefixLen, prefixLen + 1).toLowerCase() + name.substring(prefixLen + 1);
+    }
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+
+        try {
+            Method[] methods = this.getClass().getMethods();
+            methodIndex = new HashMap();
+
+            for (int i = 0; i < methods.length; i++) {
+                String methodName = methods[i].getName();
+                if (methodName.startsWith(ACTION_METHOD_PREFIX)) {
+                    String actionName = removePrefix(methodName);
+                    methodIndex.put(actionName, methods[i]);
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("registered method \"" + methodName + "\" as action \"" + actionName + "\"");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigurationException("cannot get methods by reflection", e);
+        }
+    }
+
+
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception {
+        String actionMethod = parameters.getParameter(ACTION_METHOD_PARAMETER, null);
+
+        if (actionMethod == null) {
+            Request req = ObjectModelHelper.getRequest(objectModel);
+            if (req != null) {
+                // checking request for action method parameters
+                String name;
+                for (Enumeration e = req.getParameterNames(); e.hasMoreElements();) {
+                    name = (String) e.nextElement();
+                    if (name.startsWith(ACTION_METHOD_PREFIX)) {
+                        if (name.endsWith(".x") || name.endsWith(".y")) {
+                            name = name.substring(ACTION_METHOD_PREFIX.length(), name.length() - 2);
+                        }
+                        actionMethod = removePrefix(name);
+                        break;
+                    }
+                }
+            }
+        }
+
+        if((actionMethod != null) && (actionMethod.length() > 0)) {
+            Method method = (Method) methodIndex.get(actionMethod);
+            if (method != null) {
+                try {
+                    return ((Map) method.invoke(this, new Object[]{redirector, resolver, objectModel, source, parameters}));
+                } catch (InvocationTargetException ite) {
+                    if ((ite.getTargetException() != null) && (ite.getTargetException() instanceof Exception)) {
+                        throw (Exception)ite.getTargetException();
+                    } else {
+                        throw ite;
+                    }
+                }
+            } else {
+                throw new Exception("action has no method \"" + actionMethod + "\"");
+            }
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("you need to specify the method with parameter \"" + ACTION_METHOD_PARAMETER + "\" or have a request parameter starting with \"" + ACTION_METHOD_PREFIX + "\"");
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractValidatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractValidatorAction.java
new file mode 100644
index 0000000..1507ed8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/AbstractValidatorAction.java
@@ -0,0 +1,1072 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Abstract implementation of action that needs to perform validation of
+ * parameters (from session, from request, etc.). All `validator' actions
+ * share the same description xml file. In such file every parameter is
+ * described via its name, type and its constraints. One large description
+ * file can be used among all validator actions, because each action should
+ * explicitely specify which parameters to validate - through a sitemap
+ * parameter.
+ *
+ * <h3>Variant 1</h3>
+ * <pre>
+ * &lt;map:act type="validator"&gt;
+ *         &lt;parameter name="descriptor" value="context://descriptor.xml"&gt;
+ *         &lt;parameter name="validate" value="username,password"&gt;
+ * &lt;/map:act&gt;
+ * </pre>
+ *
+ * <p>The list of parameters to be validated is specified as a comma
+ * separated list of their names. descriptor.xml can therefore be used
+ * among many various actions. If the list contains only of <code>*</code>,
+ * all parameters in the file will be validated.</p>
+ *
+ * <h3>Variant 2</h3>
+ * <pre>
+ * &lt;map:act type="validator"&gt;
+ *         &lt;parameter name="descriptor" value="context://descriptor.xml"&gt;
+ *         &lt;parameter name="constraint-set" value="is-logged-in"&gt;
+ * &lt;/map:act&gt;
+ * </pre>
+ *
+ * <p>The parameter "constraint-set" tells to take a given
+ * "constraint-set" from description file and test all parameters
+ * against given criteria. This variant is more powerful, more aspect
+ * oriented and more flexibile than the previous one, because it
+ * allows comparsion constructs, etc. See AbstractValidatorAction
+ * documentation.</p>
+ *
+ * <p>For even more powerful validation, constraints can be grouped
+ * and used independently of the parameter name. If a validate element
+ * has a <code>rule</code> attribute, it uses the parameter with that
+ * name as a rule template and validates the parameter from the
+ * <code>name</code> attribute with that rule.</p>
+ *
+ * <p>This action returns null when validation fails, otherwise it
+ * provides all validated parameters to the sitemap via {name}
+ * expression.</p>
+ *
+ * <p>In addition a request attribute
+ * <code>org.apache.cocoon.acting.FormValidatorAction.results</code>
+ * contains the validation results in both cases and make it available
+ * to other components. The special parameter "*" contains either the validation
+ * result "OK", if all parameters were validated successfully, or
+ * "ERROR" otherwise. Mind you that redirections create new request
+ * objects and thus the result is not available for the target
+ * page.</p>
+ *
+ * <pre>
+ * &lt;root&gt;
+ *         &lt;parameter name="username" type="string" nullable="no"/&gt;
+ *         &lt;parameter name="role" type="string" nullable="no"/&gt;
+ *         &lt;parameter name="oldpassword" type="string" nullable="no"/&gt;
+ *         &lt;parameter name="newpassword" type="string" nullable="no"/&gt;
+ *         &lt;parameter name="renewpassword" type="string" nullable="no"/&gt;
+ *         &lt;parameter name="id" type="long" nullable="no"/&gt;
+ *         &lt;parameter name="sallary" type="double" nullable="no"/&gt;
+ *         &lt;parameter name="theme" type="string" nullable="yes" default="dflt"/&gt;
+ *         &lt;constraint-set name="is-logged-in"&gt;
+ *                 &lt;validate name="username"/&gt;
+ *                 &lt;validate name="role"/&gt;
+ *         &lt;/constraint-set&gt;
+ *
+ *         &lt;constraint-set name="is-in-admin-role"&gt;
+ *                 &lt;validate name="username"/&gt;
+ *                 &lt;validate name="role" equals-to="admin"/&gt;
+ *         &lt;/constraint-set&gt;
+ *
+ *         &lt;constraint-set name="new-passwords-match"&gt;
+ *                 &lt;validate name="oldpassword"/&gt;
+ *                 &lt;validate name="newpassword"/&gt;
+ *                 &lt;validate name="renewpassword"
+ *                         equals-to-param="newpass"/&gt;
+ *         &lt;/constraint-set&gt;
+ *
+ *         &lt;constraint-set name="all"&gt;
+ *                 &lt;include name="is-logged-in"/&gt;
+ *                 &lt;include name="is-in-admin-role"/&gt;
+ *                 &lt;include name="new-passwords-match"/&gt;
+ *         &lt;/constraint-set&gt;
+ * &lt;/root&gt;
+ * </pre>
+ *
+ * <h3>The types recognized by validator and their attributes</h3>
+ * <table border="1">
+ *         <tr>
+ *                 <td><b>string</b></td><td>nullable="yes|no" default="str"</td>
+ *         </tr>
+ *         <tr>
+ *                 <td><b>long</b></td><td>nullable="yes|no" default="123123"</td>
+ *         </tr>
+ *         <tr>
+ *                 <td><b>double</b></td><td>nullable="yes|no" default="0.5"</td>
+ *         </tr>
+ * </table>
+ *
+ * <p>Default value takes place only when specified parameter is
+ * nullable and really is null or empty. Long numbers may be specified
+ * in decimal, hex or octal values as accepted by java.Lang.decode
+ * (String s).</p>
+ *
+ * <h3>Constraints</h3>
+ * <table border="1">
+ * <tr>
+ *     <td>matches-regex</td><td>POSIX regular expression</td>
+ * </tr>
+ * <tr>
+ *     <td>min-len</td><td>positive integer</td>
+ * </tr>
+ * <tr>
+ *     <td>max-len</td><td>positive integer</td>
+ * </tr>
+ * <tr>
+ *     <td>min</td><td>Double / Long</td>
+ * </tr>
+ * <tr>
+ *     <td>max</td><td>Double / Long</td>
+ * </tr>
+ * </table>
+ *
+ * <p>Constraints can be defined globally for a parameter and can be
+ * overridden by redefinition in a constraint-set. Thus if e.g. a
+ * database field can take at maximum 200 character, this property can
+ * be set globally.</p>
+ *
+ * <p>Values in parameter arrays are validated individually and the
+ * worst error is reported back.</p>
+ *
+ * <h3>The attributes recognized in "constraint-set"</h3>
+ * <table>
+ * <tr>
+ *     <td>equals-to-param</td><td>parameter name</td>
+ * </tr>
+ * <tr>
+ *     <td>equals-to</td><td>string constant</td>
+ * </tr>
+ * </table>
+ * @version $Id$
+ */
+public abstract class AbstractValidatorAction
+    extends AbstractComplementaryConfigurableAction
+    implements Configurable {
+
+    /**
+     * This is the name of the request attribute containing the result
+     */
+    public static final String FORMVALIDATOR_PATH = "org.apache.cocoon.acting.FormValidatorAction.results";
+
+   /**
+     * Reads parameter values for all parameters that are contained in the active
+     * constraint list. If a parameter has multiple values, all are stored in the
+     * resulting map.
+     * 
+     * @param objectModel the object model
+     * @param set a collection of parameter names
+     * @return HashMap
+     */
+    abstract protected HashMap createMapOfParameters(Map objectModel, Collection set);
+
+    /**
+     * Are parameters encoded as strings?
+     */
+    abstract boolean isStringEncoded();
+
+    /*
+     * main method
+     */
+    public Map act(Redirector redirector,
+                   SourceResolver resolver,
+                   Map objectModel,
+                   String src,
+                   Parameters parameters) throws Exception {
+
+        Configuration conf = this.getDescriptor(resolver, objectModel, parameters);
+        if (conf == null)
+            return null;
+
+        String valStr =
+            parameters.getParameter("validate", (String)settings.get("validate", "")).trim();
+        String valSetStr =
+            parameters.getParameter("validate-set", (String)settings.get("validate-set", "")).trim();
+        String constraintSetStr =
+            parameters.getParameter("constraint-set", (String)settings.get("constraint-set", "")).trim();
+        if (!"".equals(valSetStr)) {
+            if (getLogger().isInfoEnabled()) {
+                getLogger().info("Using sitemap parameter 'validate-set' for specifying "
+                                 + "the constraint-set for the ValidatorActions is deprecated in "
+                                 + "favor of 'constraint-set' due to consistency in the naming.");
+            }
+            if ("".equals(constraintSetStr)) {
+                constraintSetStr = valSetStr;
+            }
+        }
+        Map desc = this.indexConfiguration(conf.getChildren("parameter"));
+
+        Map actionMap = new HashMap();
+        Map resultMap = new HashMap();
+        Collection params = null;
+        boolean allOK = false;
+
+        if (!"".equals(valStr)) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Validating parameters as specified via 'validate' parameter");
+            }
+            params = this.getSetOfParameterNamesFromSitemap(valStr, desc);
+        } else if (!"".equals(constraintSetStr)) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Validating parameters from given constraint-set " + constraintSetStr);
+            }
+            Map csets = this.indexConfiguration(conf.getChildren("constraint-set"));
+            params = this.resolveConstraints(constraintSetStr, csets);
+        }
+        
+        if (params == null) {
+            throw new ProcessingException("Neither a constraint-set nor parameters in the sitemap "
+                                          + "were specified for validating at "
+                                          + SitemapParameters.getLocation(parameters));
+        }
+        HashMap values = this.createMapOfParameters(objectModel, params);
+        allOK = this.validateSetOfParameters(desc, actionMap, resultMap, params, values, this.isStringEncoded());
+
+        return this.setResult(objectModel, actionMap, resultMap, allOK);
+    }
+
+    /**
+     * Try to validate given parameter.
+     * @param name The name of the parameter to validate.
+     * @param constraints Configuration of all constraints for this
+     * parameter as taken from the description XML file.
+     * @param conf Configuration of all parameters as taken from the
+     * description XML file.
+     * @param params The map of parameters.
+     * @param isString Indicates wheter given param to validate is
+     * string (as taken from HTTP request for example) or wheteher it
+     * should be regular instance of java.lang.Double, java.lang.Long,
+     * etc.
+     * @return The validated parameter.
+     */
+    public ValidatorActionHelper validateParameter(
+        String name,
+        Configuration constraints,
+        Map conf,
+        Map params,
+        boolean isString) {
+
+        return validateParameter(name, name, constraints, conf, params, isString);
+    }
+
+    /**
+     * Try to validate given parameter.
+     * @param name The actual name of the parameter to validate.
+     * @param rule The name of the parameter element that contains the
+     * rule that should be used for validation.
+     * @param constraints Configuration of all constraints for this
+     * parameter as taken from the description XML file.
+     * @param conf Configuration of all parameters as taken from the
+     * description XML file.
+     * @param params The map of parameters.
+     * @param isString Indicates wheter given param to validate is
+     * string (as taken from HTTP request for example) or wheteher it
+     * should be regular instance of java.lang.Double, java.lang.Long,
+     * etc.
+     * @return The validated parameter.
+     */
+    public ValidatorActionHelper validateParameter(
+        String name,
+        String rule,
+        Configuration constraints,
+        Map conf,
+        Map params,
+        boolean isString) {
+        String type = null;
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("Validating parameter: " + name + " using rule: " + rule);
+
+        /* try to find matching param description in conf tree */
+        try {
+            Configuration theConf = (Configuration) conf.get(rule);
+            type = theConf.getAttribute("type");
+
+            return validateValue(name, constraints, theConf, params, isString, type);
+
+        } catch (Exception e) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("No type specified for parameter " + name);
+            return null;
+        }
+    }
+
+    /**
+     * Validate a single parameter value.
+     * 
+     * @param name String holding the name of the parameter
+     * @param constraints Configuration holding the constraint set configuration for the parameter
+     * @param conf Configuration holding the parameter configuration
+     * @param params Map of parameter values to be validated
+     * @param isString boolean indicating if the value is string encoded
+     * @param type string holding the name of the datatype to validate value
+     * @return ValidatorActionHelper
+     */
+    protected ValidatorActionHelper validateValue(
+        String name,
+        Configuration constraints,
+        Configuration conf,
+        Map params,
+        boolean isString,
+        String type) {
+        Object value = params.get(name);
+
+        if (value != null && value.getClass().isArray()) {
+            Object[] values = (Object[]) value;
+            ValidatorActionHelper vaH = null;
+            ValidatorActionResult vaR = ValidatorActionResult.OK;
+            for (int j = 0; j < values.length; j++) {
+                value = values[j];
+                if ("string".equals(type)) {
+                    vaH = validateString(name, constraints, conf, params, value);
+                } else if ("long".equals(type)) {
+                    vaH = validateLong(name, constraints, conf, params, isString, value);
+                } else if ("double".equals(type)) {
+                    vaH = validateDouble(name, constraints, conf, params, isString, value);
+                } else {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug(
+                            "Unknown type " + type + " specified for parameter " + name);
+                    return null;
+                }
+                vaR = (vaR.getPos() < vaH.getResult().getPos() ? vaH.getResult() : vaR);
+            }
+            return new ValidatorActionHelper(vaH.getObject(), vaR);
+        } else {
+            if ("string".equals(type)) {
+                return validateString(name, constraints, conf, params, value);
+            } else if ("long".equals(type)) {
+                return validateLong(name, constraints, conf, params, isString, value);
+            } else if ("double".equals(type)) {
+                return validateDouble(name, constraints, conf, params, isString, value);
+            } else {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Unknown type " + type + " specified for parameter " + name);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Validates nullability and default value for given parameter. If given
+     * constraints are not null they are validated as well.
+     */
+    private ValidatorActionHelper validateString(
+        String name,
+        Configuration constraints,
+        Configuration conf,
+        Map params,
+        Object param) {
+
+        String value = null;
+        String dflt = getDefault(conf, constraints);
+        boolean nullable = getNullable(conf, constraints);
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("Validating string parameter " + name);
+        try {
+            value = getStringValue(param);
+        } catch (Exception e) {
+            // ClassCastException
+            return new ValidatorActionHelper(value, ValidatorActionResult.ERROR);
+        }
+        if (value == null) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("String parameter " + name + " is null");
+            if (!nullable) {
+                return new ValidatorActionHelper(value, ValidatorActionResult.ISNULL);
+            } else {
+                return new ValidatorActionHelper(dflt);
+            }
+        }
+        if (constraints != null) {
+            String eq = constraints.getAttribute("equals-to", "");
+            eq = conf.getAttribute("equals-to", eq);
+
+            String eqp = constraints.getAttribute("equals-to-param", "");
+            eqp = conf.getAttribute("equals-to-param", eqp);
+
+            String regex = conf.getAttribute("matches-regex", "");
+            regex = constraints.getAttribute("matches-regex", regex);
+
+            String oneOf = conf.getAttribute("one-of", "");
+            oneOf = constraints.getAttribute("one-of", oneOf);
+
+            Long minlen = getAttributeAsLong(conf, "min-len", null);
+            minlen = getAttributeAsLong(constraints, "min-len", minlen);
+
+            Long maxlen = getAttributeAsLong(conf, "max-len", null);
+            maxlen = getAttributeAsLong(constraints, "max-len", maxlen);
+
+            // Validate whether param is equal to constant
+            if (!"".equals(eq)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("String parameter " + name + " should be equal to " + eq);
+                if (!value.equals(eq)) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate whether param is equal to another param
+            // FIXME: take default value of param being compared with into
+            // account?
+            if (!"".equals(eqp)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "String parameter " + name + " should be equal to " + params.get(eqp));
+                if (!value.equals(params.get(eqp))) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate whether param length is at least of minimum length
+            if (minlen != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "String parameter "
+                            + name
+                            + " should be at least "
+                            + minlen
+                            + " characters long");
+                if (value.length() < minlen.longValue()) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is shorter (" + value.length() + ")");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOSMALL);
+                }
+            }
+
+            // Validate whether param length is at most of maximum length
+            if (maxlen != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "String parameter "
+                            + name
+                            + " should be at most "
+                            + maxlen
+                            + " characters long");
+
+                if (value.length() > maxlen.longValue()) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is longer (" + value.length() + ")");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOLARGE);
+                }
+            }
+
+            // Validate wheter param matches regular expression
+            if (!"".equals(regex)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "String parameter " + name + " should match regexp \"" + regex + "\"");
+                try {
+                    RE r = new RE(regex);
+                    if (!r.match(value)) {
+                        if (getLogger().isDebugEnabled())
+                            getLogger().debug("and it does not match");
+                        return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                    }
+                } catch (RESyntaxException rese) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().error("String parameter " + name + " regex error ", rese);
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validates against a set of possibilities
+            if (!"".equals(oneOf)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "String parameter " + name + " should be one of \"" + oneOf + "\"");
+                if (!oneOf.startsWith("|"))
+                    oneOf = "|" + oneOf;
+                if (!oneOf.endsWith("|"))
+                    oneOf = oneOf + "|";
+                if (value.indexOf("|") != -1) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug(
+                            "String parameter " + name + "contains \"|\" - can't validate that.");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.ERROR);
+                }
+                if (oneOf.indexOf("|" + value + "|") == -1) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+                return new ValidatorActionHelper(value, ValidatorActionResult.OK);
+
+            }
+
+        }
+        return new ValidatorActionHelper(value);
+    }
+
+    /**
+     * Validates nullability and default value for given parameter. If given
+     * constraints are not null they are validated as well.
+     */
+    private ValidatorActionHelper validateLong(
+        String name,
+        Configuration constraints,
+        Configuration conf,
+        Map params,
+        boolean is_string,
+        Object param) {
+
+        boolean nullable = getNullable(conf, constraints);
+        Long value = null;
+        Long dflt = getLongValue(getDefault(conf, constraints), true);
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "Validating long parameter " + name + " (encoded in a string: " + is_string + ")");
+        try {
+            value = getLongValue(param, is_string);
+        } catch (Exception e) {
+            // Unable to parse long
+            return new ValidatorActionHelper(value, ValidatorActionResult.ERROR);
+        }
+        if (value == null) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("Long parameter " + name + " is null");
+            if (!nullable) {
+                return new ValidatorActionHelper(value, ValidatorActionResult.ISNULL);
+            } else {
+                return new ValidatorActionHelper(dflt);
+            }
+        }
+        if (constraints != null) {
+            Long eq = getAttributeAsLong(constraints, "equals-to", null);
+            String eqp = constraints.getAttribute("equals-to-param", "");
+
+            Long min = getAttributeAsLong(conf, "min", null);
+            min = getAttributeAsLong(constraints, "min", min);
+
+            Long max = getAttributeAsLong(conf, "max", null);
+            max = getAttributeAsLong(constraints, "max", max);
+
+            // Validate whether param is equal to constant
+            if (eq != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Long parameter " + name + " should be equal to " + eq);
+
+                if (!value.equals(eq)) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate whether param is equal to another param
+            // FIXME: take default value of param being compared with into
+            // account?
+            if (!"".equals(eqp)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "Long parameter " + name + " should be equal to " + params.get(eqp));
+                // Request parameter is stored as string.
+                // Need to convert it beforehand.
+                try {
+                    Long _eqp = new Long(Long.parseLong((String) params.get(eqp)));
+                    if (!value.equals(_eqp)) {
+                        if (getLogger().isDebugEnabled())
+                            getLogger().debug("and it is not");
+                        return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                    }
+                } catch (NumberFormatException nfe) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug(
+                            "Long parameter " + name + ": " + eqp + " is no long",
+                            nfe);
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate wheter param is at least min
+            if (min != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Long parameter " + name + " should be at least " + min);
+
+                if (min.compareTo(value) > 0) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOSMALL);
+                }
+            }
+
+            // Validate wheter param is at most max
+            if (max != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Long parameter " + name + " should be at most " + max);
+                if (max.compareTo(value) < 0) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOLARGE);
+                }
+            }
+        }
+        return new ValidatorActionHelper(value);
+    }
+
+    /**
+     * Validates nullability and default value for given parameter. If given
+     * constraints are not null they are validated as well.
+     */
+    private ValidatorActionHelper validateDouble(
+        String name,
+        Configuration constraints,
+        Configuration conf,
+        Map params,
+        boolean is_string,
+        Object param) {
+
+        boolean nullable = getNullable(conf, constraints);
+        Double value = null;
+        Double dflt = getDoubleValue(getDefault(conf, constraints), true);
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "Validating double parameter "
+                    + name
+                    + " (encoded in a string: "
+                    + is_string
+                    + ")");
+        try {
+            value = getDoubleValue(param, is_string);
+        } catch (Exception e) {
+            // Unable to parse double
+            return new ValidatorActionHelper(value, ValidatorActionResult.ERROR);
+        }
+        if (value == null) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("double parameter " + name + " is null");
+            if (!nullable) {
+                return new ValidatorActionHelper(value, ValidatorActionResult.ISNULL);
+            } else {
+                return new ValidatorActionHelper(dflt);
+            }
+        }
+        if (constraints != null) {
+            Double eq = getAttributeAsDouble(constraints, "equals-to", null);
+            String eqp = constraints.getAttribute("equals-to-param", "");
+
+            Double min = getAttributeAsDouble(conf, "min", null);
+            min = getAttributeAsDouble(constraints, "min", min);
+
+            Double max = getAttributeAsDouble(conf, "max", null);
+            max = getAttributeAsDouble(constraints, "max", max);
+
+            // Validate whether param is equal to constant
+            if (eq != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Double parameter " + name + " should be equal to " + eq);
+
+                if (!value.equals(eq)) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate whether param is equal to another param
+            // FIXME: take default value of param being compared with into
+            // account?
+            if (!"".equals(eqp)) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "Double parameter " + name + " should be equal to " + params.get(eqp));
+                // Request parameter is stored as string.
+                // Need to convert it beforehand.
+                try {
+                    Double _eqp = new Double(Double.parseDouble((String) params.get(eqp)));
+                    if (!value.equals(_eqp)) {
+                        if (getLogger().isDebugEnabled())
+                            getLogger().debug("and it is not");
+                        return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                    }
+                } catch (NumberFormatException nfe) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug(
+                            "Double parameter " + name + ": " + eqp + " is no double",
+                            nfe);
+                    return new ValidatorActionHelper(value, ValidatorActionResult.NOMATCH);
+                }
+            }
+
+            // Validate wheter param is at least min
+            if (min != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Double parameter " + name + " should be at least " + min);
+                if (0 > value.compareTo(min)) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOSMALL);
+                }
+            }
+
+            // Validate wheter param is at most max
+            if (max != null) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Double parameter " + name + " should be at most " + max);
+                if (0 < value.compareTo(max)) {
+                    if (getLogger().isDebugEnabled())
+                        getLogger().debug("and it is not");
+                    return new ValidatorActionHelper(value, ValidatorActionResult.TOOLARGE);
+                }
+            }
+        }
+        return new ValidatorActionHelper(value);
+    }
+
+    /**
+     * Returns the parsed Double value.
+     */
+    private Double getDoubleValue(Object param, boolean is_string)
+        throws ClassCastException, NumberFormatException {
+
+        /* convert param to double */
+        if (is_string) {
+            String tmp = getStringValue(param);
+            if (tmp == null) {
+                return null;
+            }
+            return new Double(tmp);
+        } else {
+            return (Double) param;
+        }
+    }
+
+    /**
+     * Returns the parsed Long value.
+     */
+    private Long getLongValue(Object param, boolean is_string)
+        throws ClassCastException, NumberFormatException {
+
+        /* convert param to long */
+        if (is_string) {
+            String tmp = getStringValue(param);
+            if (tmp == null) {
+                return null;
+            }
+            return Long.decode(tmp);
+        } else {
+            return (Long) param;
+        }
+    }
+
+    /**
+     * Returns string
+     * @throws ClassCastException if param is not a String object
+     */
+    private String getStringValue(Object param) throws ClassCastException {
+
+        /* convert param to string */
+        String value = (String) param;
+        if (value != null && "".equals(value.trim())) {
+            value = null;
+        }
+        return value;
+    }
+
+    /**
+     * Returns the value of 'nullable' attribute from given configuration or
+     * from given constraints, value present in constraints takes precedence,
+     * false when attribute is not present in either of them.
+     */
+    private boolean getNullable(Configuration conf, Configuration cons) {
+        /* check nullability */
+        try {
+            String tmp = cons.getAttribute("nullable");
+            return BooleanUtils.toBoolean(tmp);
+        } catch (Exception e) {
+            String tmp = "no";
+            if (conf != null) {
+                tmp = conf.getAttribute("nullable", "no");
+            }
+            return BooleanUtils.toBoolean(tmp);
+        }
+    }
+
+    /**
+     * Returns the default value from given configuration or constraints.
+     * Value present in constraints takes precedence, null is returned when no
+     * default attribute is present in eiher of them.
+     */
+    private String getDefault(Configuration conf, Configuration cons) {
+        String dflt = "";
+        try {
+            dflt = cons.getAttribute("default");
+        } catch (Exception e) {
+            if (conf != null)
+                dflt = conf.getAttribute("default", "");
+        }
+        if ("".equals(dflt.trim())) {
+            dflt = null;
+        }
+        return dflt;
+    }
+
+    /**
+     * Replacement for Avalon's Configuration.getAttributeAsLong
+     * because that one doesn't take <code>Long</code> but long and
+     * thus won't take <code>null</code> as parameter value for
+     * default.
+     *
+     * @param conf Configuration
+     * @param name Parameter's name
+     * @param dflt Default value
+     * @return Parameter's value in <code>configuration</code> or
+     * <code>dflt</code> if parameter is not set or couldn't be
+     * converted to a <code>Long</code>
+     * @throws NumberFormatException if conversion fails
+     */
+    private Long getAttributeAsLong(Configuration conf, String name, Long dflt)
+        throws NumberFormatException {
+        try {
+            return new Long(conf.getAttribute(name));
+        } catch (ConfigurationException e) {
+            return dflt;
+        }
+    }
+
+    /**
+     * Addition to Avalon's Configuration.getAttributeAsFloat
+     * because that one does only deal with <code>float</code>.
+     *
+     * @param conf Configuration
+     * @param name Parameter's name
+     * @param dflt Default value
+     * @return Parameter's value in <code>configuration</code> or
+     * <code>dflt</code> if parameter is not set or couldn't be
+     * converted to a <code>Double</code>
+     * @throws NumberFormatException if conversion fails
+     */
+    private Double getAttributeAsDouble(Configuration conf, String name, Double dflt)
+        throws NumberFormatException {
+        try {
+            return new Double(conf.getAttribute(name));
+        } catch (ConfigurationException e) {
+            return dflt;
+        }
+    }
+
+    /**
+     * Create an index map to an array of configurations by their name
+     * attribute. An empty array results in an empty map.
+     * 
+     * @param descriptor
+     * @return index map or empty map
+     */
+    protected Map indexConfiguration(Configuration[] descriptor) {
+        if (descriptor == null)
+            return new HashMap();
+        Map result = new HashMap((descriptor.length > 0) ? descriptor.length * 2 : 5);
+        for (int i = descriptor.length - 1; i >= 0; i--) {
+            String name = descriptor[i].getAttribute("name", "");
+            result.put(name, descriptor[i]);
+        }
+        return result;
+    }
+
+    /**
+     * Recursively resolve constraint sets that may "include" other constraint
+     * sets and return a collection of all parameters to validate.
+     * 
+     * @param valsetstr
+     * @param consets
+     * @return collection of all parameters to validate
+     */
+    protected Collection resolveConstraints(String valsetstr, Map consets) {
+        /* get the list of params to be validated */
+        Vector rules = new Vector();
+        Configuration[] set = ((Configuration) consets.get(valsetstr)).getChildren("validate");
+        for (int j = 0; j < set.length; j++) {
+            rules.add(set[j]);
+        }
+        set = ((Configuration) consets.get(valsetstr)).getChildren("include");
+        for (int j = 0; j < set.length; j++) {
+            Collection tmp = resolveConstraints(set[j].getAttribute("name", ""), consets);
+            rules.addAll(tmp);
+        }
+        return rules;
+    }
+
+    /**
+     * Checks the default setting for reloading the descriptor file.
+     * @return boolean
+     */
+    protected boolean isDescriptorReloadable() {
+        // read global parameter settings
+        boolean reloadable = DESCRIPTOR_RELOADABLE_DEFAULT;
+        if (this.settings.containsKey("reloadable")) {
+            reloadable = Boolean.valueOf((String) this.settings.get("reloadable")).booleanValue();
+        }
+        return reloadable;
+    }
+
+    /**
+     * Get list of params to be validated from sitemap parameter and
+     * isolates the parameter names from the comma separated list.
+     * 
+     */
+    protected Collection getSetOfParameterNamesFromSitemap(String valstr, Map desc) {
+        String[] rparams = null;
+        Set set = new HashSet(20);
+        if (!"*".equals(valstr.trim())) {
+            rparams = StringUtils.split(valstr, ","); 
+            if (rparams != null) {
+                for (int i = rparams.length - 1; i >= 0; i--) {
+                    set.add(desc.get(rparams[i]));
+                }
+            }
+        } else {
+            // validate _all_ parameters
+            set = desc.entrySet();
+        }
+        return set;
+    }
+
+    /**
+     * Validate all parameters in the set with the constraints contained in
+     * desc and the values from params. Validation details are in resultMap and 
+     * successful validated parameters in resultMap. 
+     * 
+     * @param desc
+     * @param actionMap
+     * @param resultMap
+     * @param set
+     * @param params
+     * @param isString
+     * @return boolean all parameters ok or not
+     */
+    protected boolean validateSetOfParameters(
+        Map desc,
+        Map actionMap,
+        Map resultMap,
+        Collection set,
+        Map params,
+        boolean isString) {
+
+        boolean allOK = true;
+        ValidatorActionHelper result;
+        String name;
+        String rule = null;
+        for (Iterator i = set.iterator(); i.hasNext();) {
+            Configuration constr = (Configuration) i.next();
+            name = constr.getAttribute("name", null);
+            rule = constr.getAttribute("rule", name);
+            result = validateParameter(name, rule, constr, desc, params, isString);
+            if (!result.isOK()) {
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("Validation failed for parameter " + name);
+                allOK = false;
+            }
+            actionMap.put(name, result.getObject());
+            resultMap.put(name, result.getResult());
+        }
+        return allOK;
+    }
+
+    /**
+     * Add success indicator to resulting maps and clear actionMap if unsuccessful.
+     * Results are stored as request attributes.
+     * 
+     * @param objectModel the object model
+     * @param actionMap a Map containing validated parameters
+     * @param resultMap a Map containing validation results
+     * @param allOK a boolean indicating if all validations were successful
+     * @return actionMap if allOK or null otherwise
+     */
+    protected Map setResult(Map objectModel, Map actionMap, Map resultMap, boolean allOK) {
+        if (!allOK) {
+            // if any validation failed return an empty map
+            actionMap = null;
+            resultMap.put("*", ValidatorActionResult.ERROR);
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("All form params validated. An error occurred.");
+        } else {
+            resultMap.put("*", ValidatorActionResult.OK);
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("All form params successfully validated");
+        }
+        // store validation results in request attribute
+        ObjectModelHelper.getRequest(objectModel).setAttribute(
+            FORMVALIDATOR_PATH,
+            resultMap);
+        //return Collections.unmodifiableMap (actionMap);
+        return actionMap;
+    }
+
+    /**
+     * Load the descriptor containing the constraints.
+     * @param resolver
+     * @param parameters
+     * @return a Configuration containing the constraints or null if a problem occurred.
+     */
+    protected Configuration getDescriptor(
+        SourceResolver resolver,
+        Map objectModel,
+        Parameters parameters) {
+        Configuration conf = null;
+        try {
+            conf =
+                this.getConfiguration(
+                    parameters.getParameter("descriptor", (String) this.settings.get("descriptor")),
+                    resolver,
+                    parameters.getParameterAsBoolean("reloadable", isDescriptorReloadable()));
+        } catch (ConfigurationException e) {
+            if (this.getLogger().isWarnEnabled())
+                this.getLogger().warn("Exception reading descriptor: ", e);
+        }
+        return conf;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/Action.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/Action.java
new file mode 100644
index 0000000..da4db8b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/Action.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface Action {
+
+    String ROLE = Action.class.getName();
+
+    /**
+     * Controls the processing against some values of the
+     * <code>Dictionary</code> objectModel and returns a
+     * <code>Map</code> object with values used in subsequent
+     * sitemap substitution patterns.
+     *
+     * NOTE: This interface is designed so that implentations can be <code>ThreadSafe<code>.
+     * When an action is ThreadSafe, only one instance serves all requests : this
+     * reduces memory usage and avoids pooling.
+     *
+     * @param resolver    The <code>SourceResolver</code> in charge
+     * @param objectModel The <code>Map</code> with object of the
+     *                    calling environment which can be used
+     *                    to select values this controller may need
+     *                    (ie Request, Response).
+     * @param source      A source <code>String</code> to the Action
+     * @param parameters  The <code>Parameters</code> for this invocation
+     * @return Map        The returned <code>Map</code> object with
+     *                    sitemap substitution values which can be used
+     *                    in subsequent elements attributes like src=
+     *                    using a xpath like expression: src="mydir/{myval}/foo"
+     *                    If the return value is null the processing inside
+     *                    the <map:act> element of the sitemap will
+     *                    be skipped.
+     * @exception Exception Indicates something is totally wrong
+     */
+    Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters)
+            throws Exception;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearCacheAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearCacheAction.java
new file mode 100644
index 0000000..7dec7ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearCacheAction.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.caching.Cache;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+/**
+ * Simple action which ensures the cache is cleared of all
+ * cached results
+ *
+ * @version $Id$
+ */
+public class ClearCacheAction extends ServiceableAction implements ThreadSafe {
+
+    public Map act(Redirector redirector,
+                    SourceResolver resolver,
+                    Map objectModel,
+                    String src,
+                    Parameters par
+    ) throws Exception {
+        final String cacheRole = par.getParameter("cache-role", Cache.ROLE);
+        Cache cache = null;
+
+        try {
+            cache = (Cache)this.manager.lookup(cacheRole);
+            cache.clear();
+            return EMPTY_MAP;
+        } catch (Exception ex) {
+	        if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("Exception while trying to clear Cache with role " + cacheRole, ex);
+            }
+            return null;
+        } finally {
+            this.manager.release( cache );
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearPersistentStoreAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearPersistentStoreAction.java
new file mode 100644
index 0000000..86cb59a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ClearPersistentStoreAction.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.store.Store;
+
+import java.util.Map;
+
+/**
+ * Simple action which ensures the persistent store is cleared.
+ *
+ * @version $Id$
+ */
+public class ClearPersistentStoreAction extends ServiceableAction implements ThreadSafe {
+
+    public Map act(Redirector redirector,
+                    SourceResolver resolver,
+                    Map objectModel,
+                    String src,
+                    Parameters par
+    ) throws Exception {
+        if ( this.manager.hasService( Store.PERSISTENT_STORE) ) {
+            final Store store_persistent = (Store)this.manager.lookup(Store.ROLE);
+
+            try {
+                store_persistent.clear();
+                return EMPTY_MAP;
+            } catch (Exception ex) {
+                getLogger().debug("Exception while trying to Clearing the Store", ex);
+                return null;
+            } finally {
+                this.manager.release( store_persistent );
+            }
+        } else {
+            getLogger().info("Unable to clear persistent store as no persistent store is configured.");
+            return null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurableServiceableAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurableServiceableAction.java
new file mode 100644
index 0000000..e8aaf46
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurableServiceableAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * The <code>ConfigurableServiceableAction</code> will allow any <code>Action</code>
+ * that extends this to access SitemapComponents.
+ *
+ * Basically a copy of {@link ServiceableAction} that inherits from
+ * {@link AbstractConfigurableAction}.
+ *
+ * @version $Id$
+ */
+public abstract class ConfigurableServiceableAction 
+    extends AbstractConfigurableAction implements Serviceable {
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurationHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurationHelper.java
new file mode 100644
index 0000000..b29e5af
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ConfigurationHelper.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ConfigurationHelper {
+    public long lastModified = 0;
+    public Configuration configuration = null;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/CopySourceAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/CopySourceAction.java
new file mode 100644
index 0000000..947a8e0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/CopySourceAction.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.source.impl.PartSource;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * The CopySourceAction copies the content of it's "src" attribute to its "dest" parameter.
+ * The destination must of course resolve to a <code>WriteableSource</code>
+ * <p>
+ * Example :
+ * <pre>
+ *   &lt;map:act type="copy-source" src="cocoon://pipeline.xml"&gt;
+ *     &lt;map:parameter name="dest" value="context://WEB-INF/data/file.xml"/&gt;
+ *     .../...
+ *   &lt;/map:act&gt;
+ *</pre>
+ *
+ * @version $Id$
+ */
+public class CopySourceAction 
+    extends ServiceableAction 
+    implements ThreadSafe {
+
+    private SourceResolver resolver;
+
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+    }
+
+    public Map act(Redirector redirector, org.apache.cocoon.environment.SourceResolver oldResolver, Map objectModel, String source, Parameters par)
+        throws Exception {
+
+        // Get source and destination Sources
+        Source src = resolver.resolveURI(source);
+        Source dest = resolver.resolveURI(par.getParameter("dest"));
+
+        // Check that dest is writeable
+        if (! (dest instanceof ModifiableSource)) {
+            throw new IllegalArgumentException("Non-writeable URI : " + dest.getURI());
+        }
+
+        if (dest instanceof TraversableSource) {
+            TraversableSource trDest = (TraversableSource) dest;
+            if (trDest.isCollection()) {
+                if (src instanceof TraversableSource) {
+                    dest = trDest.getChild(((TraversableSource)src).getName());
+                } else if (src instanceof PartSource){
+                    // FIXME : quick hack to store "upload://xxx" sources into directories
+                    // it would be better for the PartSource to be Traversable, or to
+                    // create a new "NamedSource" interface
+                    dest = trDest.getChild(((PartSource)src).getPart().getFileName());
+                }
+            }
+        }
+
+        ModifiableSource wdest = (ModifiableSource)dest;
+
+        // Get streams
+        InputStream is = src.getInputStream();
+        OutputStream os = wdest.getOutputStream();
+
+        // And transfer all content.
+        try {
+            byte[] buffer = new byte[1024];
+            int len;
+            while ((len = is.read(buffer, 0, buffer.length)) > 0) {
+                os.write(buffer, 0, len);
+            }
+            os.close();
+        } catch(Exception e) {
+            if (wdest.canCancel(os)) {
+                wdest.cancel(os);
+            }
+        } finally {
+            is.close();
+        }
+        // Success !
+        return EMPTY_MAP;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/FormValidatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/FormValidatorAction.java
new file mode 100644
index 0000000..ed044f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/FormValidatorAction.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This is the action used to validate Request parameters.
+ * The parameters are described via the external xml
+ * file (its format is defined in AbstractValidatorAction).
+ * @see org.apache.cocoon.acting.AbstractValidatorAction
+ *
+ * @version $Id$
+ */
+public class FormValidatorAction extends AbstractValidatorAction implements ThreadSafe {
+
+    /**
+     * Reads parameter values from request parameters for all parameters
+     * that are contained in the active constraint list. If a parameter
+     * has multiple values, all are stored in the resulting map.
+     * 
+     * @param objectModel the object model
+     * @param set a collection of parameter names
+     * @return HashMap of required parameters 
+     */
+    protected HashMap createMapOfParameters(Map objectModel, Collection set) {
+        String name;
+        HashMap params = new HashMap(set.size());
+        // put required params into hash
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        for (Iterator i = set.iterator(); i.hasNext();) {
+            name = ((Configuration) i.next()).getAttribute("name", "").trim();
+            Object[] values = request.getParameterValues(name);
+            if (values != null) {
+                switch (values.length) {
+                    case 0 :
+                        params.put(name, null);
+                        break;
+                    case 1 :
+                        params.put(name, values[0]);
+                        break;
+                    default :
+                        params.put(name, values);
+                }
+            } else {
+                params.put(name, values);
+            }
+        }
+        return params;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.AbstractValidatorAction#isStringEncoded()
+     */
+    boolean isStringEncoded() {
+        return true;
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HelloAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HelloAction.java
new file mode 100644
index 0000000..8f4d610
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HelloAction.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+/**
+ * A simple Action that tracks if a <code>Session</code> object
+ * has been created or not.
+ *
+ * @version $Id$
+ */
+public class HelloAction extends ServiceableAction implements ThreadSafe {
+
+    /**
+     * A simple Action that logs if the <code>Session</code> object
+     * has been created
+     */
+    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters par) throws Exception {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        if (request != null) {
+            Session session = request.getSession (false);
+
+            if (session != null) {
+                if (session.isNew()) {
+                    getLogger().debug("Session is new");
+                } else {
+                    getLogger().debug("Session is old");
+                }
+            } else {
+                getLogger().debug("A session object was not created");
+            }
+        }
+
+        return null;
+    }
+}
+
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpCacheAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpCacheAction.java
new file mode 100644
index 0000000..c02d977
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpCacheAction.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.commons.lang.time.DateUtils;
+import org.apache.commons.lang.time.FastDateFormat;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This action adds the <code>Last-Modified</code>, <code>Expires</code> and
+ * <code>Cache-Control</code> HTTP headers to the response.
+ *
+ * <p>
+ * This action will add the <code>Last-Modified</code> header to the response
+ * with the time in which the request was executed, and an <code>Expires</code>
+ * header at a specified time difference. Additionally, it will provide an
+ * extra <code>Cache-Control</code> indicating the maximum age of the request
+ * as a delta between the expiration and last modification dates.
+ * </p>
+ * <p>
+ * This is useful (for example) when Cocoon is proxyied by a Web Server such
+ * as Apache HTTPD running mod_cache, to indicate for each request how long
+ * the output should be cached for.
+ * </p>
+ * <p>
+ * To configure the difference between <code>Last-Modified</code> and
+ * <code>Expires</code> this <code>Action</code> can be configured specifying
+ * days, hours, minutes, and seconds in this way:
+ * </p>
+ * <pre>
+ * &lt;map:action&gt;s
+ *   &lt;map:action name="xyz" src="org.apache.cocoon.acting.HttpCacheAction&gt;"
+ *     &lt;days&gt;1&lt;/day&gt;s
+ *     &lt;hours&gt;2&lt;/hour&gt;s
+ *     &lt;minutes&gt;3&lt;/minute&gt;s
+ *     &lt;seconds&gt;4&lt;/second&gt;s
+ *   &lt;/map:actio&gt;n
+ * &lt;/map:action&gt;s
+ * </pre>
+ * <p>
+ * Using this example configuration, the <code>Expires</code> header will
+ * specify a date one day, two hours, three minutes and four seconds after
+ * the time of the request (which will be in <code>Last-Modified</code>).
+ * </p>
+ * <p>
+ * Note that if any of the parameters mentioned above is <b>zero</b> or
+ * <b>less than zero</b> this action will modify the behaviour of the
+ * resulting <code>Cache-Control</code> header to emit the keyword
+ * <code>no-cache</code>.
+ * </p>
+ * <p>
+ * This action will also return the three headers it added as sitemap
+ * parameters called <code>last-modified</code>, <code>expires</code> and
+ * <code>cache-control</code> (all lowercase).
+ * </p>
+ *
+ * @version $Id$
+ */
+public class HttpCacheAction extends AbstractConfigurableAction implements ThreadSafe {
+
+    private FastDateFormat formatter = null;
+    int days = 0;
+    int hours = 0;
+    int minutes = 0;
+    int seconds = 0;
+
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        super.configure(configuration);
+
+        // RFC-822 Date with a GMT based time zone
+        this.formatter = FastDateFormat.getInstance("EEE, dd MMM yyyy kk:mm:ss zzz", DateUtils.UTC_TIME_ZONE);
+        this.days = configuration.getChild("days").getValueAsInteger(0);
+        this.hours = configuration.getChild("hours").getValueAsInteger(0);
+        this.minutes = configuration.getChild("minutes").getValueAsInteger(0);
+        this.seconds = configuration.getChild("seconds").getValueAsInteger(0);
+    }
+
+    public Map act(Redirector redirector, SourceResolver resolver,
+                   Map objectModel, String source, Parameters parameters)
+    throws Exception {
+        Response response = ObjectModelHelper.getResponse(objectModel);
+        Calendar calendar = Calendar.getInstance(DateUtils.UTC_TIME_ZONE);
+        Map values = new HashMap(3);
+
+        /* Get the current time and output as the last modified header */
+        String value = this.formatter.format(calendar);
+        long maxage = calendar.getTime().getTime();
+        response.setHeader("Last-Modified", value);
+        values.put("last-modified",  value);
+
+        /* Advance the time as much as required */
+        calendar.add(Calendar.DATE, this.days);
+        calendar.add(Calendar.HOUR, this.hours);
+        calendar.add(Calendar.MINUTE, this.minutes);
+        calendar.add(Calendar.SECOND, this.seconds);
+
+        /* Recalculate time and age to see what changed */
+        maxage = calendar.getTime().getTime() - maxage;
+
+        /* If we got more than one second everything is quite normal */
+        if (maxage > 1000) {
+            value = this.formatter.format(calendar);
+            response.setHeader("Expires", value);
+            values.put("expires", value);
+
+            value = "max-age=" + Long.toString(maxage / 1000l);
+            response.setHeader("Cache-Control", value);
+            values.put("cache-control", value);
+
+        /* If we got less than one second (even negatives) no cache */
+        } else {
+            /* We still hold the old value from Last-Modified here */
+            response.setHeader("Expires", value);
+            values.put("expires", value);
+
+            response.setHeader("Cache-Control", "no-cache");
+            values.put("cache-control", "no-cache");
+        }
+
+        /* Return the headers */
+        return(Collections.unmodifiableMap(values));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpHeaderAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpHeaderAction.java
new file mode 100644
index 0000000..ad29ca4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/HttpHeaderAction.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This action adds HTTP headers to the response.
+ *
+ * @version $Id$
+ */
+public class HttpHeaderAction
+extends AbstractConfigurableAction
+implements ThreadSafe {
+
+    /**
+     * Stores keys of global configuration.
+     */
+    private Object[] defaults = {};
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+        this.defaults = super.settings.keySet().toArray();
+    }
+
+    public Map act(Redirector redirector, SourceResolver resolver,
+                   Map objectModel, String source, Parameters parameters)
+    throws Exception {
+        final Map results = new HashMap();
+
+        final Response response = ObjectModelHelper.getResponse(objectModel);
+
+        // Process local configuration parameters
+        final String[] names = parameters.getNames();
+        for (int i = 0; i < names.length; i++) {
+            response.setHeader(names[i],parameters.getParameter(names[i]));
+            results.put(names[i], parameters.getParameter(names[i]));
+        }
+
+        // Process global defaults, that are not overridden
+        for (int i = 0; i < defaults.length; i++) {
+            if (!results.containsKey(this.defaults[i])) {
+                response.setHeader((String) this.defaults[i], (String) this.settings.get(defaults[i]));
+                results.put(this.defaults[i], this.settings.get(defaults[i]));
+            }
+        }
+
+        return Collections.unmodifiableMap(results);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/InputModuleAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/InputModuleAction.java
new file mode 100644
index 0000000..e780615
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/InputModuleAction.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.components.modules.input.InputModuleHelper;
+
+import org.apache.commons.lang.BooleanUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Simple helper action to allow passing sitemap variables to InputModules.
+ * Sitemap evaluation of input modules using the curly bracket syntax e.g.
+ * {defaults:skin} suffers from the fact that it is not
+ * possible to use a sitemap variable as part of the invocation like
+ * {defaults:{1})}. This action takes three parameters, the name
+ * of the input module, the attribute name, and whether to call getAttribute() or
+ * getAttributeValues(). Thus the above becomes
+ * <pre>
+ *   &lt;map:act type="inputmodule"&gt;
+ *     &lt;map:parameter name="module" value="defaults"/&gt;
+ *     &lt;map:parameter name="attribute" value="{1}"/&gt;
+ *     &lt;map:parameter name="single-value" value="false"/&gt;
+ * 
+ *     &lt;!-- do something with the result: "{1}" --&gt;
+ * 
+ *   &lt;/map:act&gt;
+ * </pre> 
+ * The action invokes the 
+ * {@link org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(String, Configuration, Map) getAttributeValues()}
+ * method and returns all results numbered from "0". If no result exists,
+ * "null" is returned and the nested block is skipped.
+ * The name of the input module to use may be preconfigured when
+ * declaring the action in your sitemap:
+ * <pre>
+ *     &lt;map:action name="inputmodule" 
+ *                    src="org.apache.cocoon.acting.InputModuleAction" 
+ *                    logger="sitemap.action.inputmodule"&gt;
+ *        &lt;module&gt;defaults&lt;/module&gt;
+ *        &lt;single-value&gt;false&lt;/single-value&gt;
+ *     &lt;/map:action&gt;
+ * </pre>
+ * 
+ * 
+ * @see org.apache.cocoon.components.modules.input.InputModule
+ * 
+ * @version $Id$
+ */
+public class InputModuleAction extends ConfigurableServiceableAction implements ThreadSafe {
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.Action#act(org.apache.cocoon.environment.Redirector, org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map act(Redirector redirector, SourceResolver resolver,
+                   Map objectModel, String source, Parameters parameters)
+        throws Exception {
+
+        HashMap map = null;
+        Configuration conf = null;
+        String module = parameters.getParameter("module", (String) this.settings.get("module"));
+        String attrib =
+            parameters.getParameter("attribute", (String) this.settings.get("attribute"));
+        boolean single =
+            parameters.getParameterAsBoolean(
+                "single-value",
+                ((Boolean) this.settings.get("single-value")).booleanValue());
+
+        if (module != null && attrib != null) {
+            InputModuleHelper mhelper = new InputModuleHelper();
+            mhelper.setup(manager);
+            Object[] result = null;
+            if (!single) {
+                result = mhelper.getAttributeValues(objectModel, conf, module, attrib, null);
+            } else {
+                Object tmp = mhelper.getAttribute(objectModel, conf, module, attrib, null);
+                if (tmp != null){
+                    result = new Object[1];
+                    result[0] = tmp;
+                }
+            }
+            mhelper.releaseAll();
+
+            if (result != null && result.length != 0) {
+                map = new HashMap();
+                for (int i = 0; i < result.length; i++) {
+                    map.put(Integer.toString(i), result[i]);
+                }
+            }
+        } else {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error(
+                    "Parameter is missing: module=" + module + " attribute=" + attrib);
+            }
+        }
+        return map;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+        String tmp = (String) this.settings.get("single-value", "false");
+        this.settings.put("single-value", BooleanUtils.toBooleanObject(tmp));
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/LocaleAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/LocaleAction.java
new file mode 100644
index 0000000..ec2a957
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/LocaleAction.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.i18n.I18nUtils;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * An action that locates and provides to the pipeline locale information
+ * looked up in a range of ways.
+ *
+ * <h1>Configuration</h1>
+ * <p>A sample configuration (given in the &lt;map:matchers&gt; section of the
+ * sitemap) is given below. This configuration shows default values.
+ * </p>
+ * <pre>
+ *   &lt;map:action name="locale" src="org.apache.cocoon.acting.LocaleAction"&gt;
+ *     &lt;locale-attribute&gt;locale&lt;/locale-attribute&gt;
+ *     &lt;use-locale&gt;true&lt;/use-locale&gt;
+ *     &lt;default-locale language="en" country="US"/&gt;
+ *     &lt;store-in-request&gt;false&lt;store-in-request&gt;
+ *     &lt;create-session&gt;false&lt;create-session&gt;
+ *     &lt;store-in-session&gt;false&lt;store-in-session&gt;
+ *     &lt;store-in-cookie&gt;false&lt;store-in-cookie&gt;
+ *   &lt;/map:action&gt;
+ * </pre>
+ *
+ * <p>Above configuration parameters mean:
+ *   <ul>
+ *     <li><b>locale-attribute</b> specifies the name of the request
+ *     parameter / session attribute / cookie that is to be used as a locale
+ *     (defaults to <code>locale</code>)</li>
+ *     <li><b>use-locale</b> specifies whether the primary locale provided
+ *     by the user agent (or server default, is no locale passed by the agent)
+ *     is to be used</li>
+ *     <li><b>default-locale</b> specifies the default locale to be used when
+ *     none found.</li>
+ *     <li><b>store-in-request</b> specifies whether found locale should be
+ *     stored as request attribute.</li>
+ *     <li><b>create-session</b> specifies whether session should be created
+ *     when storing found locale as session attribute.</li>
+ *     <li><b>store-in-session</b> specifies whether found locale should be
+ *     stored as session attribute.</li>
+ *     <li><b>store-in-cookie</b> specifies whether found locale should be
+ *     stored as cookie.</li>
+ *   </ul>
+ * </p>
+ *
+ * <h1>Usage</h1>
+ * <p>This action will be used in a pipeline like so:</p>
+ * <pre>
+ *   &lt;map:act type="locale"&gt;
+ *     &lt;map:generate src="file_{language}_{country}_{variant}.xml"/&gt;
+ *     ...
+ *   &lt;/map:match&gt;
+ * </pre>
+ * <p>or</p>
+ * <pre>
+ *   &lt;map:act type="locale"&gt;
+ *     &lt;map:generate src="file_{locale}.xml"/&gt;
+ *     ...
+ *   &lt;/map:match&gt;
+ * </pre>
+ *
+ * <h1>Locale Identification</h1>
+ * <p>Locales will be tested in following order:</p>
+ * <ul>
+ *   <li>Locale provided as a request parameter</li>
+ *   <li>Locale provided as a session attribute</li>
+ *   <li>Locale provided as a cookie</li>
+ *   <li>Locale provided using a sitemap parameter<br>
+ *   (&lt;map:parameter name="locale" value="{1}"/&gt; style parameter within
+ *   the &lt;map:match&gt; node)</li>
+ *   <li>Locale provided by the user agent, or server default,
+ *   if <code>use-locale</code> is set to <code>true</code></li>
+ *   <li>The default locale, if specified in the matcher's configuration</li>
+ * </ul>
+ * <p>First found locale will be returned.</p>
+ *
+ * <h1>Sitemap Variables</h1>
+ * <p>Once locale has been found, the following sitemap variables
+ * will be available to sitemap elements contained within the action:</p>
+ * <ul>
+ *   <li>{locale}: The locale string</li>
+ *   <li>{language}: The language of the found locale</li>
+ *   <li>{country}: The country of the found locale</li>
+ *   <li>{variant}: The variant of the found locale</li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class LocaleAction extends ServiceableAction implements ThreadSafe, Configurable {
+
+    private static final String DEFAULT_DEFAULT_LANG = "en";
+    private static final String DEFAULT_DEFAULT_COUNTRY = "US";
+    private static final String DEFAULT_DEFAULT_VARIANT = "";
+
+    /**
+      * Default locale attribute name.
+     */
+    public static final String LOCALE = "locale";
+
+    /**
+     * Configuration element name for locale attribute name.
+     */
+    public static final String LOCALE_ATTR = "locale-attribute";
+
+
+    /**
+     * Constant representing the request storage configuration attribute
+     */
+    public static final String STORE_REQUEST = "store-in-request";
+
+    /**
+     * Constant representing the session creation configuration attribute
+     */
+    public static final String CREATE_SESSION = "create-session";
+
+    /**
+     * Constant representing the session storage configuration attribute
+     */
+    public static final String STORE_SESSION = "store-in-session";
+
+    /**
+     * Constant representing the cookie storage configuration attribute
+     */
+    public static final String STORE_COOKIE = "store-in-cookie";
+
+
+    /**
+     * Name of the locale request parameter, session attribute, cookie.
+     */
+    private String localeAttribute;
+
+    /**
+     * Whether to query locale provided by the user agent or not.
+     */
+    private boolean useLocale;
+
+    /**
+     * Default locale if no other found and {@link #useLocale} is false.
+     */
+    private Locale defaultLocale;
+
+    /**
+     * Store the locale in request. Default is not to do this.
+     */
+    private boolean storeInRequest;
+
+    /**
+     * Store the locale in session, if available. Default is not to do this.
+     */
+    private boolean storeInSession;
+
+    /**
+     * Should we create a session if needed. Default is not to do this.
+     */
+    private boolean createSession;
+
+    /**
+     * Should we add a cookie with the locale. Default is not to do this.
+     */
+    private boolean storeInCookie;
+
+    /**
+     * Configure this action.
+     *
+     * @param config configuration information (if any)
+     */
+    public void configure(Configuration config)
+    throws ConfigurationException {
+        this.storeInRequest = config.getChild(STORE_REQUEST).getValueAsBoolean(false);
+        this.createSession = config.getChild(CREATE_SESSION).getValueAsBoolean(false);
+        this.storeInSession = config.getChild(STORE_SESSION).getValueAsBoolean(false);
+        this.storeInCookie = config.getChild(STORE_COOKIE).getValueAsBoolean(false);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug((this.storeInRequest ? "will" : "won't") + " set values in request");
+            getLogger().debug((this.createSession ? "will" : "won't") + " create session");
+            getLogger().debug((this.storeInSession ? "will" : "won't") + " set values in session");
+            getLogger().debug((this.storeInCookie ? "will" : "won't") + " set values in cookies");
+        }
+
+        this.localeAttribute = config.getChild(LOCALE_ATTR).getValue(LOCALE);
+        this.useLocale = config.getChild("use-locale").getValueAsBoolean(true);
+
+        Configuration child = config.getChild("default-locale", false);
+        if (child != null) {
+            this.defaultLocale = new Locale(child.getAttribute("language", DEFAULT_DEFAULT_LANG),
+                                            child.getAttribute("country", DEFAULT_DEFAULT_COUNTRY),
+                                            child.getAttribute("variant", DEFAULT_DEFAULT_VARIANT));
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Locale attribute name is " + this.localeAttribute);
+            getLogger().debug((this.useLocale ? "will" : "won't") + " use request locale");
+            getLogger().debug("default locale " + this.defaultLocale);
+        }
+    }
+
+    /**
+     * Action which obtains the current environments locale information, and
+     * places it in the objectModel (and optionally in a session/cookie).
+     */
+    public Map act(Redirector redirector,
+                   SourceResolver resolver,
+                   Map objectModel,
+                   String source,
+                   Parameters params)
+    throws Exception {
+        // Obtain locale information from request, session, cookies, or params
+        Locale locale = I18nUtils.findLocale(objectModel,
+                                             localeAttribute,
+                                             params,
+                                             defaultLocale,
+                                             useLocale);
+
+        if (locale == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("No locale found.");
+            }
+
+            return null;
+        }
+
+        String localeStr = locale.toString();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Found locale: " + localeStr);
+        }
+
+        I18nUtils.storeLocale(objectModel,
+                              localeAttribute,
+                              localeStr,
+                              storeInRequest,
+                              storeInSession,
+                              storeInCookie,
+                              createSession);
+
+        // Set up a map for sitemap parameters
+        Map map = new HashMap();
+        map.put("language", locale.getLanguage());
+        map.put("country", locale.getCountry());
+        map.put("variant", locale.getVariant());
+        map.put("locale", localeStr);
+        return map;
+    }
+
+    /**
+     * Helper method to retreive the attribute value containing locale
+     * information. See class documentation for locale determination algorythm.
+     *
+     * @deprecated See I18nUtils.findLocale
+     * @param objectModel requesting object's environment
+     * @return locale value or <code>null</null> if no locale was found
+     */
+    public static String getLocaleAttribute(Map objectModel,
+                                            String localeAttrName) {
+        Locale locale = I18nUtils.findLocale(objectModel,
+                                             localeAttrName,
+                                             null,
+                                             null,
+                                             true);
+        return locale.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/PropagatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/PropagatorAction.java
new file mode 100644
index 0000000..5221173
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/PropagatorAction.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.output.OutputModule;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This is the action used to propagate parameters into a store using an
+ * {@link org.apache.cocoon.components.modules.output.OutputModule}. It
+ * simply propagates given expression. Additionaly it will make all propagated values
+ * available via returned Map.
+ *
+ * <p>Example configuration:</p>
+ * <pre>
+ * &lt;map:action type="...." name="...." logger="..."&gt;
+ *   &lt;output-module name="session-attr"&gt;
+ *      &lt;!-- optional configuration for output module --&gt;
+ *   &lt;/output-module&gt;
+ *   &lt;store-empty-parameters&gt;true&lt;/store-empty-parameters&gt;
+ *   &lt;defaults&gt;
+ *     &lt;default name="..." value="...."/&gt;
+ *     &lt;default name="..." value="..."/&gt;
+ *   &lt;/defaults&gt;
+ * &lt;/map:action&gt;
+ * </pre>
+ *
+ * <p>Example use:</p>
+ * <pre>
+ * &lt;map:act type="session-propagator"&gt;
+ *      &lt;paramater name="example" value="{example}"/&gt;
+ *      &lt;paramater name="example1" value="xxx"/&gt;
+ *      &lt;parameter name="PropagatorAction:store-empty-parameters" value="true"/&gt;
+ *      &lt;parameter name="PropagatorAction:output-module" value="session-attr"/&gt;
+ * &lt;/map:act&gt;
+ * </pre>
+ *
+ * <h3>Configuration</h3>
+ * <table><tbody>
+ * <tr>
+ *  <th>output-module</th>
+ *  <td>Nested element configuring output to use. Name attribute holds
+ *      output module hint.</td>
+ *  <td></td><td>XML</td><td><code>request-attr</code></td>
+ * </tr>
+ * <tr>
+ *  <th>store-empty-parameters</th>
+ *  <td>Propagate parameters with empty values.</td>
+ *  <td></td><td>boolean</td><td><code>true</code></td>
+ * </tr>
+ * <tr>
+ *  <th>defaults</th>
+ *  <td>Parent for default parameters to propagate.</td>
+ *  <td></td><td>XML</td><td></td>
+ * </tr>
+ * <tr>
+ *  <th>defaults/default</th>
+ *  <td>Name attribute holds parameter name, value attribute holds
+ *      parameter value. Will be used when not set on use.</td>
+ *  <td></td><td>parameter</td><td></td>
+ * </tr>
+ * </tbody></table>
+ *
+ *<h3>Parameters</h3>
+ * <table><tbody>
+ * <tr>
+ *  <th>PropagatorAction:output-module</th>
+ *  <td>Alternative output module hint to use. A <code>null</code> configuration
+ *      will be passed to a module selected this way.</td>
+ *  <td></td><td>String</td><td>as determined by configuration</td>
+ * </tr>
+ * <tr>
+ *  <th>PropagatorAction:store-empty-parameters</th>
+ *  <td>Propagate parameters with empty values.</td>
+ *  <td></td><td>boolean</td><td>as determined by configuration</td>
+ * </tr>
+ * <tr>
+ *  <th>any other</th>
+ *  <td>Any other parameter will be propagated.</td>
+ *  <td></td><td>String</td><td></td>
+ * </tr>
+ * </tbody></table>
+ *
+ * @version $Id$
+ */
+public class PropagatorAction extends ServiceableAction
+                              implements Configurable, ThreadSafe {
+
+    /** Prefix for sitemap parameters targeted at this action. */
+    private static final String ACTION_PREFIX = "PropagatorAction:";
+
+    /** Configuration parameter name. */
+    private static final String CONFIG_STORE_EMPTY = "store-empty-parameters";
+
+    /** Configuration parameter name. */
+    private static final String CONFIG_OUTPUT_MODULE = "output-module";
+
+    /** Default output module name. */
+    private static final String OUTPUT_HINT = "request-attr"; // defaults to request attributes
+
+
+    /** Should empty parameter values be propagated? */
+    private boolean storeEmpty = true;
+
+    /** Configuration object for output module. */
+    private Configuration outputConf;
+
+    /** Name of output module to use. */
+    private String outputName;
+
+    /** List of {@link Entry}s holding default values. */
+    private List defaults;
+
+    /**
+     * A private helper holding default parameter entries.
+     *
+     */
+    private static class Entry {
+        public String key;
+        public String value;
+
+        public Entry(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        this.outputConf = config.getChild(CONFIG_OUTPUT_MODULE);
+        this.outputName = this.outputConf.getAttribute("name", OUTPUT_HINT);
+        this.storeEmpty =
+            config.getChild(CONFIG_STORE_EMPTY).getValueAsBoolean(this.storeEmpty);
+
+        Configuration[] dflts = config.getChild("defaults").getChildren("default");
+        if (dflts != null) {
+            this.defaults = new ArrayList(dflts.length);
+            for (int i = 0; i < dflts.length; i++) {
+                this.defaults.add(
+                        new Entry(dflts[i].getAttribute("name"),
+                                  dflts[i].getAttribute("value")));
+            }
+        } else {
+            this.defaults = new ArrayList(0);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.Action#act(Redirector, SourceResolver, Map, String, Parameters)
+     */
+    public Map act(Redirector redirector,
+                   SourceResolver resolver,
+                   Map objectModel,
+                   String source,
+                   Parameters parameters)
+    throws Exception {
+        // Read action parameters
+        String outputName = parameters.getParameter(ACTION_PREFIX + CONFIG_OUTPUT_MODULE,
+                                                    null);
+        boolean storeEmpty = parameters.getParameterAsBoolean(ACTION_PREFIX + CONFIG_STORE_EMPTY,
+                                                              this.storeEmpty);
+        parameters.removeParameter(ACTION_PREFIX + CONFIG_OUTPUT_MODULE);
+        parameters.removeParameter(ACTION_PREFIX + CONFIG_STORE_EMPTY);
+
+        Configuration outputConf = null;
+        if (outputName == null) {
+            outputName = this.outputName;
+            outputConf = this.outputConf;
+        }
+
+        // Action results map
+        final Map results = new HashMap();
+
+        OutputModule output = null;
+        ServiceSelector selector = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup(OutputModule.ROLE + "Selector");
+            if (outputName != null
+                && selector != null
+                && selector.isSelectable(outputName)) {
+
+                output = (OutputModule) selector.select(outputName);
+
+                String[] names = parameters.getNames();
+                for (int i = 0; i < names.length; i++) {
+                    String name = names[i];
+                    String value = parameters.getParameter(name);
+                    if (storeEmpty || (value != null && !value.equals(""))) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Propagating <" + name + "> value <" + value + ">");
+                        }
+                        output.setAttribute(outputConf,
+                                            objectModel,
+                                            name,
+                                            value);
+                        results.put(name, value);
+                    }
+                }
+
+                // Defaults, that are not overridden
+                for (Iterator i = defaults.iterator(); i.hasNext();) {
+                    Entry entry = (Entry) i.next();
+                    if (!results.containsKey(entry.key)) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Propagating default <" + entry.key + "> value <" + entry.value + ">");
+                        }
+                        output.setAttribute(outputConf,
+                                            objectModel,
+                                            entry.key,
+                                            entry.value);
+                        results.put(entry.key, entry.value);
+                    }
+                }
+
+                output.commit(outputConf, objectModel);
+            }
+        } catch (Exception e) {
+            if (output != null) {
+                output.rollback(outputConf, objectModel, e);
+            }
+            throw e;
+        } finally {
+            if (selector != null) {
+                if (output != null) {
+                    selector.release(output);
+                }
+                this.manager.release(selector);
+            }
+        }
+
+        return Collections.unmodifiableMap(results);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParamAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParamAction.java
new file mode 100644
index 0000000..ecda374
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParamAction.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * This action makes some request details available to the sitemap via parameter
+ * substitution.
+ *
+ * {context}      - is the context path of the servlet (usually "/cocoon")
+ * {requestURI}   - is the requested URI without parameters
+ * {requestQuery} - is the query string like "?param1=test" if there is one
+ *
+ * Additionlly all request parameters can be made available for use in the sitemap.
+ * if the parameter "parameters" is set to true.
+ * (A variable is created for each request parameter (only if it doesn't exist)
+ * with the same name as the parameter itself)
+ *
+ * Default values can be set for request parameters, by including sitemap parameters
+ * named "default.<parameter-name>".
+ *
+ * Sitemap definition:
+ *
+ * <pre>
+ * &lt;map:action name="request" src="org.apache.cocoon.acting.RequestParamAction"/&gt;
+ * </pre>
+ *
+ * <p>
+ *
+ * Example use:
+ *
+ * <pre>
+ * &lt;map:match pattern="some-resource"&gt;
+ *  &lt;map:act type="request"&gt;
+ *     &lt;map:parameter name="parameters" value="true"/&gt;
+ *     &lt;map:parameter name="default.dest" value="invalid-destination.html"/&gt;
+ *     &lt;map:redirect-to uri="{context}/somewhereelse/{dest}"/&gt;
+ *  &lt;/map:act&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * Redirection is only one example, another use:
+ *
+ * <pre>
+ * &lt;map:match pattern="some-resource"&gt;
+ *  &lt;map:act type="request"&gt;
+ *     &lt;map:parameter name="parameters" value="true"/&gt;
+ *     &lt;map:generate src="users/menu-{id}.xml"/&gt;
+ *  &lt;/map:act&gt;
+ *  &lt;map:transform src="menus/personalisation.xsl"/&gt;
+ *  &lt;map:serialize/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * etc, etc.
+ *
+ * @version $Id$
+ */
+public class RequestParamAction extends ServiceableAction implements ThreadSafe {
+
+    public final static String MAP_URI         = "requestURI";
+    public final static String MAP_QUERY       = "requestQuery";
+    public final static String MAP_CONTEXTPATH = "context";
+
+    public final static String PARAM_PARAMETERS     = "parameters";
+    public final static String PARAM_DEFAULT_PREFIX = "default.";
+
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel,
+                   String source, Parameters param) throws Exception {
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        Map map = new HashMap();
+
+        map.put(MAP_URI, request.getRequestURI());
+
+        String query = request.getQueryString();
+        if (query != null && query.length() > 0) {
+            map.put(MAP_QUERY, "?" + query);
+        } else {
+            map.put(MAP_QUERY, "");
+        }
+
+        map.put(MAP_CONTEXTPATH, request.getContextPath());
+
+        if ("true".equalsIgnoreCase(param.getParameter(PARAM_PARAMETERS, null))) {
+            Enumeration e = request.getParameterNames();
+            while (e.hasMoreElements()) {
+                String name = (String)e.nextElement();
+                String value = request.getParameter(name);
+
+                if (value != null && !map.containsKey(name)) {
+                    map.put(name, value);
+                }
+            }
+
+            String[] paramNames = param.getNames();
+            for (int i = 0; i < paramNames.length; i++) {
+                if (paramNames[i].startsWith(PARAM_DEFAULT_PREFIX)
+                        && (request.getParameter(paramNames[i].substring(PARAM_DEFAULT_PREFIX.length())) == null)) {
+                    map.put(paramNames[i].substring(PARAM_DEFAULT_PREFIX.length()),
+                            param.getParameter(paramNames[i]));
+                }
+            }
+        }
+        return (map);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParameterExistsAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParameterExistsAction.java
new file mode 100644
index 0000000..a0f96ef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/RequestParameterExistsAction.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Iterator;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * This action simply checks to see if a given request parameter
+ * exists. It takes an arbitrary number of default parameters to check
+ * named 'parameter-name'. Non-default parameters need to be separated
+ * by spaces and passed as value of a sitemap parameter named
+ * 'parameters'. The action returns a map with all parameters if all
+ * of them exist and null otherwise. Parameter names can only be added
+ * to this list but no default parameters can be overridden by
+ * specific ones.
+ *
+ * <p>This action is very closely related to @link{RequestParamAction}
+ * and {@link FormValidatorAction}. However this action is considerably
+ * simpler in that it tests only for existence of a parameter and it
+ * doesn't need a descriptor. Besides it doesn't propagate all request
+ * parameters to the sitemap but only those that are marked as
+ * required.</p> <p> One special feature is, however, that parameters
+ * can contain <strong>one</strong> wildcard ("*"). It will be
+ * checked, whether all parameters with a wildcard have the same
+ * matches. E.g. "id_* name_*" enforces, that if "id_1" exists,
+ * "name_1" must also exist and vice versa.</p>
+ *
+ * @version $Id$
+ */
+public class RequestParameterExistsAction extends AbstractConfigurableAction implements ThreadSafe
+{
+
+    protected class StringParts {
+        String prefix = null;
+        String pstfix = null;
+        int count = 0;
+
+        public StringParts ( String pre, String post ) {
+            prefix = pre;
+            pstfix = post;
+        }
+    }
+
+
+
+    public Map act( Redirector redirector,
+            SourceResolver resolver,
+            Map objectModel,
+            String source,
+            Parameters parameters
+            )
+    throws Exception {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        HashMap results = new HashMap();
+        HashMap items = new HashMap();
+        int wildcards = 0;
+
+        // check default parameters for existence
+        if (this.getLogger().isDebugEnabled()) {
+            getLogger().debug("checking default parameters");
+        }
+        Iterator reqParams = settings.values().iterator();
+        while (reqParams.hasNext()) {
+            String paramName = (String) reqParams.next();
+            StringParts sp = splitParameter(paramName);
+            if (sp != null) {
+                // wildcard: special care required (deferred until later)
+                items.put(new Integer(wildcards++), sp);
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("(default) deferring " + paramName);
+                }
+            } else {
+                String paramValue = request.getParameter(paramName);
+                if (paramValue == null) {
+                    return null;
+                }
+                results.put(paramName, paramValue);
+            }
+        }
+
+        // check parameters for existence
+        if (this.getLogger().isDebugEnabled()) {
+            getLogger().debug("checking sitemap parameters");
+        }
+        String params = parameters.getParameter("parameters", null);
+        if (params != null) {
+            StringTokenizer st = new StringTokenizer(params);
+            while (st.hasMoreTokens()) {
+                String paramName = st.nextToken();
+                StringParts sp = splitParameter(paramName);
+                if (sp != null) {
+                    // wildcard: special care required (deferred until later)
+                    items.put(new Integer(wildcards++), sp);
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug("deferring " + paramName);
+                    }
+                } else {
+
+                    String paramValue = request.getParameter(paramName);
+                    if (paramValue == null) {
+                        return null;
+                    }
+                    results.put(paramName, paramValue);
+                }
+            }
+        }
+
+        if (wildcards != 0) {
+            // special care for parameters with wildcard
+            //
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("deferred checking for parameters: " + wildcards);
+            }
+
+            // first one
+            //
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug(" checking first");
+            }
+            HashMap values = new HashMap();
+            StringParts sp1 = (StringParts) items.get(new Integer(0));
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug(
+                    "  Parameter is [" + sp1.prefix + " * " + sp1.pstfix + "] ");
+            }
+            Enumeration requestParams = request.getParameterNames();
+            Boolean dummy = Boolean.TRUE;
+            while (requestParams.hasMoreElements()) {
+                String paramName = (String) requestParams.nextElement();
+                String match = getMatch(paramName, sp1);
+                if (match != null) {
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(
+                            "  value is >"
+                            + match
+                            + "< "
+                            + sp1.prefix.length()
+                            + " "
+                            + paramName.length()
+                            + " "
+                            + sp1.pstfix.length());
+                    }
+                    values.put(match, dummy);
+                    sp1.count++;
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(
+                            "   Parameter "
+                            + sp1.prefix
+                            + "*"
+                            + sp1.pstfix
+                            + " matches "
+                            + paramName
+                            + " ("
+                            + sp1.count
+                            + " so far)");
+                    }
+                    String paramValue = request.getParameter(paramName);
+                    if (paramValue == null) {
+                        return null;
+                    }
+                    results.put(paramName, paramValue);
+                }
+            }
+
+            if (sp1.count == 0) {
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug(
+                       "   Parameter "
+                        + sp1.prefix
+                        + "*"
+                        + sp1.pstfix
+                        + " matches "
+                        + sp1.count);
+                }
+                return null;
+            }
+
+            // all other ones
+            //
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug(" checking others");
+            }
+            requestParams = request.getParameterNames();
+            while (requestParams.hasMoreElements()) {
+                String paramName = (String) requestParams.nextElement();
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("  checking request parameter " + paramName);
+                }
+                for (int i = wildcards - 1; i > 0; i--) {
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug("   checking against " + i);
+                    }
+                    StringParts sp = (StringParts) items.get(new Integer(i));
+                    String match = getMatch(paramName, sp);
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(
+                            "   Parameter is ["
+                            + sp.prefix
+                            + " * "
+                            + sp.pstfix
+                            + "] ");
+                    }
+                    if (match != null) {
+                        if (this.getLogger().isDebugEnabled()) {
+                            getLogger().debug(
+                                "   Parameter "
+                                    + sp.prefix
+                                    + "*"
+                                    + sp.pstfix
+                                    + " matches "
+                                    + paramName
+                                    + " ("
+                                    + sp.count
+                                    + " so far)");
+                        }
+                        if (values.containsKey(match)) {
+                            sp.count++;
+                            if (this.getLogger().isDebugEnabled()) {
+                                getLogger().debug(
+                                "   " + paramName + " (verified)");
+                            }
+                            String paramValue = request.getParameter(paramName);
+                            if (paramValue == null) {
+                                return null;
+                            }
+                            results.put(paramName, paramValue);
+
+                        } else {
+                            if (this.getLogger().isDebugEnabled()) {
+                                getLogger().debug(
+                                    "Match "
+                                    + match
+                                    + "not found for "
+                                    + sp1.prefix
+                                    + "*"
+                                    + sp1.pstfix
+                                    + " but for "
+                                    + sp.prefix
+                                    + "*"
+                                    + sp.pstfix);
+                            }
+                            return null;
+                        }
+                    }
+                }
+            }
+
+            // since we enforce that only matches are counted, that exist for
+            // the first parameter as well, check if every parameter has an
+            // equal number of matches.
+            //
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("checking number of matches");
+            }
+            for (int i = wildcards - 1; i > 0; i--) {
+                StringParts sp = (StringParts) items.get(new Integer(i));
+                if (sp.count != sp1.count) {
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(
+                            "Found "
+                            + sp.count
+                            + " matches for "
+                            + sp.prefix
+                            + "*"
+                            + sp.pstfix
+                            + " but expected "
+                            + sp1.count);
+                    }
+                    return null;
+                } else {
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(
+                            "Found "
+                            + sp.count
+                            + " matches for "
+                            + sp.prefix
+                            + "*"
+                            + sp.pstfix
+                            + " as expected");
+                    }
+                }
+            }
+
+        }
+
+        return Collections.unmodifiableMap(results);
+    }
+
+
+    /**
+     * Find first "*" in a String and split it into the substring
+     * before and after the "*". Returns null if no "*" is present.
+     */
+    protected StringParts splitParameter( String paramName )
+    {
+    int idx = paramName.indexOf("*");
+    if ( idx != -1 ) {
+        return new StringParts(paramName.substring(0,idx), paramName.substring(idx+1));
+    } else {
+        return null;
+    }
+    }
+
+    /**
+     * If a String matches a StringPart spec, return the substring
+     * between the specified prefix and postfix. Returns null if it
+     * doesn't match.
+     */
+    protected String getMatch( String paramName,
+                   StringParts sp
+                   )
+    {
+    if ( paramName.startsWith( sp.prefix ) && paramName.endsWith( sp.pstfix ) ) {
+        return paramName.substring( sp.prefix.length(), ( paramName.length() - sp.pstfix.length() ) );
+    } else {
+        return null;
+    }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ResourceExistsAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ResourceExistsAction.java
new file mode 100644
index 0000000..5f121c5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ResourceExistsAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+
+import java.util.Map;
+
+/**
+ * This action simply checks to see if a resource identified by the <code>src</code>
+ * sitemap attribute exists or not. The action returns empty <code>Map</code> if
+ * resource exists, <code>null</code> otherwise.
+ * 
+ * <p>Instead of src attribute, source can be specified using
+ * parameter named <code>url</code> (this is old syntax, should be removed soon).
+ * 
+ * <p><b>NOTE:</b> {@link org.apache.cocoon.selection.ResourceExistsSelector}
+ * should be preferred to this component, as the semantics of a Selector better
+ * matches the supplied functionality.
+ *
+ * @version $Id$
+ */
+public class ResourceExistsAction extends ServiceableAction implements ThreadSafe {
+
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters parameters) throws Exception {
+        String resourceURI = parameters.getParameter("url", src);
+        Source source = null;
+        try {
+            source = resolver.resolveURI(resourceURI);
+            if (source.exists()) {
+                return EMPTY_MAP;
+            }
+        } catch (SourceNotFoundException e) {
+            // Do not log
+        } catch (Exception e) {
+            getLogger().warn("Exception resolving resource " + resourceURI, e);
+        } finally {
+            if (source != null) {
+                resolver.release(source);
+            }
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ServiceableAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ServiceableAction.java
new file mode 100644
index 0000000..86a3071
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ServiceableAction.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * The <code>ServiceableAction</code> will allow any <code>Action</code>
+ * that extends this to access SitemapComponents.
+ *
+ * @version $Id$
+ */
+public abstract class ServiceableAction 
+    extends AbstractAction implements Serviceable {
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionInvalidatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionInvalidatorAction.java
new file mode 100644
index 0000000..9ffe990
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionInvalidatorAction.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+/**
+ * This is the action used to invalidate an HTTP session. The action returns
+ * empty map if everything is ok, null otherwise.
+ *
+ * @version $Id$
+ */
+public class SessionInvalidatorAction extends AbstractAction implements ThreadSafe
+{
+    /**
+     * Main invocation routine.
+     */
+    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src,
+            Parameters parameters) throws Exception {
+        Request req = ObjectModelHelper.getRequest(objectModel);
+
+        /* check session validity */
+        Session session = req.getSession (false);
+        if (session != null) {
+            session.invalidate ();
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger ().debug ("SESSIONINVALIDATOR: session invalidated");
+            }
+        } else {
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger ().debug ("SESSIONINVALIDATOR: no session object");
+            }
+        }
+
+        return EMPTY_MAP; // cut down on object creation
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionIsValidAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionIsValidAction.java
new file mode 100644
index 0000000..2b351e3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionIsValidAction.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+
+/**
+ * This action just checks if a session exists and whether the current
+ * seesion is still valid.
+ *
+ * @version $Id$
+ */
+public class SessionIsValidAction extends AbstractAction implements ThreadSafe
+{
+    /**
+     * Main invocation routine.
+     */
+    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src,
+            Parameters parameters) throws Exception {
+        Request req = ObjectModelHelper.getRequest(objectModel);
+
+        /* check session validity */
+        Session session = req.getSession (false);
+        if (session == null) {
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("No session object");
+            }
+            return null;
+        }
+        if (!req.isRequestedSessionIdValid()) {
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("Requested session id is invalid");
+            }
+            return null;
+        }
+
+        return EMPTY_MAP;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionPropagatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionPropagatorAction.java
new file mode 100644
index 0000000..fef6052
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionPropagatorAction.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * This is the action used to propagate parameters into session. It
+ * simply propagates given expression to the session. If session does not
+ * exist, action fails. Additionaly it will make all propagated values
+ * available via returned Map.
+ *
+ * <pre>
+ * &lt;map:act type="session-propagator"&gt;
+ *      &lt;paramater name="example" value="{example}"&gt;
+ *      &lt;paramater name="example1" value="xxx"&gt;
+ * &lt;/map:act&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class SessionPropagatorAction extends AbstractConfigurableAction implements ThreadSafe {
+
+    /**
+     * A private helper holding default parameter entries.
+     * 
+     */
+    private static class Entry {
+        public String key = null;
+        public String value = null;
+
+        public Entry(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+    }
+    
+    private List defaults;
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+        Configuration[] dflts = conf.getChildren();
+        if (dflts != null) {
+            this.defaults = new ArrayList(dflts.length);
+            for (int i = 0; i < dflts.length; i++) {
+                this.defaults.add(
+                    new Entry(
+                        dflts[i].getName(),
+                        dflts[i].getValue()));
+            }
+        } else {
+            this.defaults = new ArrayList(0);
+        }
+    }
+
+    /**
+     * Main invocation routine.
+     */
+    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src,
+                    Parameters parameters) throws Exception {
+        Request req = ObjectModelHelper.getRequest(objectModel);
+        HashMap actionMap = new HashMap ();
+
+        /* check session validity */
+        Session session = req.getSession (false);
+        if (session == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("No session object");
+            }
+            return null;
+        }
+
+        try {
+            String[] names = parameters.getNames();
+
+            // parameters
+            for (int i = 0; i < names.length; i++) {
+                String sessionParamName = names[i];
+                String value = parameters.getParameter(sessionParamName);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Propagating value "
+                                      + value
+                                      + " to session attribute "
+                                      + sessionParamName);
+                }
+                session.setAttribute(sessionParamName, value);
+                actionMap.put(sessionParamName, value);
+            }
+
+            // defaults, that are not overridden
+            for (int i = 0; i < defaults.size(); i++) {
+                final Entry entry = (Entry)defaults.get(i);
+                if (!actionMap.containsKey(entry.key)) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Propagating value "
+                                          + entry.value
+                                          + " to session attribute "
+                                          + entry.key);
+                    }  
+                    session.setAttribute(entry.key, entry.value);
+                    actionMap.put(entry.key, entry.value);
+                }
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("All params propagated " + "to session");
+            }
+            return Collections.unmodifiableMap(actionMap);
+        } catch (Exception e) {
+            getLogger().warn("exception: ", e);
+        }
+        return null;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionStateAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionStateAction.java
new file mode 100644
index 0000000..a3d13c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionStateAction.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Store the session's current state in a session attribute.
+ *
+ * <p> To keep track of the state of a user's session, a string is
+ * stored in a session attribute in order to allow to chose between
+ * different pipelines in the sitemap accordingly.</p>
+ *
+ * <p> For added flexibility it is possible to use sub states as
+ * well. For this declare your own name for the session state
+ * attribute and give the number of sublevels plus the level to
+ * modify. (This is <b>one</b> based!) Sub states below the current
+ * one are removed from the session so that the default sub state will
+ * be reentered when the user returns. If you don't like this
+ * behaviour and prefer independent sub states, use this action
+ * several times with different attribute names rather than sub
+ * levels. </p>
+ *
+ * <p><b>Global and local parameters:</b></p>
+ *
+ * <table border="1">
+ *   <tr>
+ *     <td><code>state-key-prefix</code></td>
+ *     <td>String that identifies the attribute that stores the session state in the
+ *     	 session object. When sublevels are used, this is a prefix ie. the
+ *     	 number of the level is appended to the prefix. Example prefix is
+ *     	 "<code>__sessionState</code>", sub-levels is 2, attributes
+ *     	 "<code>__sessionState1</code>", "<code>__sessionState2</code>", and
+ *     	 "<code>__sessionState3</code>" will be used to store the
+ *     	 information.
+ *     </td>
+ *   </tr>
+ *   <tr>
+ *     <td><code>new-state</code></td>
+ *     <td>String that identifies the current state</td>
+ *   </tr>
+ *   <tr>
+ *     <td><code>sub-levels</code></td>
+ *     <td>Number of sub levels to  use</td>
+ *   </tr>
+ *   <tr>
+ *     <td><code>state-level</code></td>
+ *     <td>Sub level to modify, this is <b>one</b> based</td>
+ *   </tr>
+ * </table>
+ *
+ * @see org.apache.cocoon.matching.WildcardSessionAttributeMatcher
+ * @see org.apache.cocoon.selection.SessionAttributeSelector
+ *
+ * @version $Id$
+ */
+public class SessionStateAction
+    extends AbstractConfigurableAction
+    implements ThreadSafe {
+
+    protected String statekey = "org.apache.cocoon.SessionState";
+    protected String newstate = null;
+    protected int sublevels = 0;
+    protected int mylevel = 0;
+
+    /**
+     * Configures the Action.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+
+        if (settings.containsKey("state-key-prefix")) {
+            statekey = (String) settings.get("state-key-prefix");
+        }
+        if (settings.containsKey("new-state")) {
+            newstate = (String) settings.get("new-state");
+        }
+        if (settings.containsKey("sub-levels")) {
+            sublevels = Integer.parseInt((String) settings.get("sub-levels"));
+        }
+        if (settings.containsKey("state-level")) {
+            mylevel = Integer.parseInt((String) settings.get("state-level"));
+        }
+    }
+
+    public Map act(Redirector redirector,
+                   SourceResolver resolver,
+                   Map objectModel,
+                   String src,
+                   Parameters par) throws Exception {
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        // read local settings
+        String newstate = par.getParameter("new-state", this.newstate);
+        String statekey = par.getParameter("state-key", this.statekey);
+        int sublevels = par.getParameterAsInteger("sublevels", this.sublevels);
+        int mylevel = par.getParameterAsInteger("state-level", this.mylevel);
+
+        if (newstate == null) {
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().error("new-state is null");
+            }
+            return null;
+        }
+
+        if (request != null) {
+            Session session = request.getSession(false);
+
+            if (session != null && request.isRequestedSessionIdValid()) {
+                String oldstate = null;
+                if (sublevels == 0) {
+                    oldstate = (String) session.getAttribute(statekey);
+                    session.setAttribute(statekey, newstate);
+                    if (this.getLogger().isDebugEnabled()) {
+                         getLogger().debug(statekey + "=" + newstate);
+                    }
+
+                } else { // sublevels != 0
+                    oldstate = (String)session.getAttribute(statekey + mylevel);
+                    for (int i = mylevel + 1; i <= sublevels; i++) {
+                        session.removeAttribute(statekey + i);
+                        if (this.getLogger().isDebugEnabled()) {
+                            getLogger().debug("Remove " + statekey + i);
+                        }
+                    }
+                    session.setAttribute(statekey + mylevel, newstate);
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug(statekey + mylevel + "=" + newstate);
+                    }
+                }
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Transition " + oldstate + " -> " + newstate);
+                }
+
+                HashMap map = new HashMap(1);
+                map.put("newstate", newstate);
+                return map;
+            } else {
+                getLogger().warn(
+                    "A session object was not present or no longer valid");
+                return null;
+            }
+        } else {
+            getLogger().warn("No request object");
+            return null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionValidatorAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionValidatorAction.java
new file mode 100644
index 0000000..8213222
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SessionValidatorAction.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Session;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This is the action used to validate Session parameters (attributes).
+ * The parameters are described via the external xml
+ * file.
+ * 
+ * @see org.apache.cocoon.acting.AbstractValidatorAction
+ *
+ * @version $Id$
+ */
+public class SessionValidatorAction extends AbstractValidatorAction implements ThreadSafe {
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.AbstractValidatorAction#createMapOfParameters(java.util.Map, java.util.Collection)
+     */
+    protected HashMap createMapOfParameters(Map objectModel, Collection set) {
+        String name;
+        HashMap params = new HashMap(set.size());
+        // put required params into hash
+        Session session = ObjectModelHelper.getRequest(objectModel).getSession();
+        for (Iterator i = set.iterator(); i.hasNext();) {
+            name = ((Configuration) i.next()).getAttribute("name", "").trim();
+            Object value = session.getAttribute(name);
+            params.put(name, value);
+        }
+        return params;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.AbstractValidatorAction#setResult(java.util.Map, java.util.Map, java.util.Map, boolean)
+     */
+    protected Map setResult(Map objectModel, Map actionMap, Map resultMap, boolean allOK) {
+        if (allOK){
+            Session session = ObjectModelHelper.getRequest(objectModel).getSession();
+            for (Iterator i = actionMap.keySet().iterator(); i.hasNext(); ){
+                String name = (String) i.next();
+                session.setAttribute(name, actionMap.get(name));
+            }
+        }
+        return super.setResult(objectModel, actionMap, resultMap, allOK);
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.AbstractValidatorAction#isStringEncoded()
+     */
+    boolean isStringEncoded() {
+        return false;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetCharacterEncodingAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetCharacterEncodingAction.java
new file mode 100644
index 0000000..f1923b5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetCharacterEncodingAction.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Map;
+
+/**
+ * Sets the character encoding of parameters.
+ * Components use this encoding as default after the action.
+ * <p>
+ * <b>Configuration parameters:</b>
+ * <dl>
+ * <dt><i>form-encoding</i> (optional)
+ * <dd>The supposed encoding of the request parameter.
+ * </dl>
+ * These configuration options supported in both declaration and use time.
+ * <p>If no encoding specified, the action does nothing.
+ *
+ * @version $Id$
+ */
+public class SetCharacterEncodingAction extends ServiceableAction implements ThreadSafe, Parameterizable {
+    private String global_form_encoding = null;
+
+    public void parameterize(Parameters parameters)
+    throws ParameterException {
+        // super.parameterize(parameters);
+
+        global_form_encoding = parameters.getParameter("form-encoding", null);
+    }
+
+    /**
+     * Set character encoding of current request.
+     */
+    public Map act (Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters par) throws Exception {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        if (request != null) {
+            String form_encoding = par.getParameter("form-encoding", global_form_encoding);
+            if (form_encoding != null) {
+                request.setCharacterEncoding(form_encoding);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetterAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetterAction.java
new file mode 100644
index 0000000..35902e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/SetterAction.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.acting;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * This action can be used to set information in either the object model,
+ * the request or the session.
+ * All parameters set for this action are set in the according location
+ * whereas the parameter name is the key and the value of the parameter
+ * will be set as a string value for this key.
+ *
+ * @version $Id$
+ */
+public class SetterAction
+    extends AbstractAction
+    implements Parameterizable, ThreadSafe {
+
+    public static final int MODE_OBJECT_MODEL = 1;
+    public static final int MODE_REQUEST_ATTR = 2;
+    public static final int MODE_SESSION_ATTR = 3;
+    
+    public static final String MODEDEF_OBJECT_MODEL = "object-model";
+    public static final String MODEDEF_REQUEST_ATTR = "request-attribute";
+    public static final String MODEDEF_SESSION_ATTR = "session-attribute";
+
+    protected int mode = MODE_OBJECT_MODEL;
+
+    /**
+     * @see Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     * @throws ParameterException
+     */
+    public void parameterize(Parameters params) 
+    throws ParameterException {
+        String modeDef = params.getParameter("mode", null);
+        if ( modeDef != null ) {
+            if ( MODEDEF_OBJECT_MODEL.equals(modeDef) ) {
+                this.mode = MODE_OBJECT_MODEL;
+            } else if ( MODEDEF_REQUEST_ATTR.equals(modeDef) ) {
+                this.mode = MODE_REQUEST_ATTR;
+            } else if ( MODEDEF_SESSION_ATTR.equals(modeDef) ) {
+                this.mode = MODE_SESSION_ATTR;
+            } else {
+                throw new ParameterException("Unknown mode: " + this.mode);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.acting.Action#act(org.apache.cocoon.environment.Redirector, org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map act(Redirector redirector,
+                   SourceResolver resolver,
+                   Map objectModel,
+                   String source,
+                   Parameters parameters)
+    throws Exception {
+        final String[] names = parameters.getNames();
+        for(int i = 0; i < names.length; i++) {
+            final String name = names[i];
+            if ( this.mode == MODE_OBJECT_MODEL ) {
+                objectModel.put(name, parameters.getParameter(name));                
+            } else if ( this.mode == MODE_REQUEST_ATTR ) {
+                ObjectModelHelper.getRequest(objectModel).setAttribute(name, parameters.getParameter(name));                
+            } else if ( this.mode == MODE_SESSION_ATTR ) {
+                ObjectModelHelper.getRequest(objectModel).getSession().setAttribute(name, parameters.getParameter(name));                
+            }
+        }
+        return EMPTY_MAP;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionHelper.java
new file mode 100644
index 0000000..d9c2b6f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionHelper.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+
+/**
+ * Helper class to pass the result of a validation back along with
+ * the validated object itself.
+ *
+ * @version $Id$
+ */
+public class ValidatorActionHelper
+{
+    protected ValidatorActionResult result = ValidatorActionResult.OK;
+    protected Object object = null;
+
+    /**
+     * Create a ValidatorActionHelper object that contains just the
+     * object. Defaults to <code>OK</code> as validation result.
+     *
+     * @param validatedObject object that has been validated
+     */
+    public ValidatorActionHelper ( Object validatedObject ) {
+        this.object = validatedObject;
+        this.result = ValidatorActionResult.OK;
+    }
+
+    /**
+     * Create a ValidatorActionHelper object that contains just the
+     * object. Defaults to <code>OK</code> as validation result.
+     *
+     * @param validatedObject object that has been validated
+     * @param validationResult result of the validation
+     */
+    public ValidatorActionHelper ( Object validatedObject, ValidatorActionResult validationResult ) {
+        this.object = validatedObject;
+        this.result = validationResult;
+    }
+
+    /**
+     * Tests if the validation result is <code>OK</code>
+     *
+     */
+    public boolean isOK() {
+        return (result.equals(ValidatorActionResult.OK));
+    }
+
+    /**
+     * Tests if the validation result is <code>NOTPRESENT</code>,
+     * e.g. when the value is null and is allowed to be null.
+     *
+     */
+    public boolean isNotPresent() {
+        return (result.equals(ValidatorActionResult.NOTPRESENT));
+    }
+
+    /**
+     * Tests if the validation result is <code>ISNULL</code>,
+     * e.g. when the value is null but is not supposed to be null.
+     *
+     */
+    public boolean isNull() {
+        return (result.equals(ValidatorActionResult.ISNULL));
+    }
+
+    /**
+     * Tests if the validation result is <code>TOOLARGE</code>,
+     * e.g. in case of a double or long the value is too large or in
+     * case of a string it is too long.
+     *
+     */
+    public boolean isTooLarge() {
+        return (result.equals(ValidatorActionResult.TOOLARGE));
+    }
+
+    /**
+     * Tests if the validation result is <code>TOOSMALL</code>,
+     * e.g. in case of a double or long the value is too small or in
+     * case of a string it is too short.
+     *
+     */
+    public boolean isTooSmall() {
+        return (result.equals(ValidatorActionResult.TOOSMALL));
+    }
+
+    /**
+     * Tests if the validation result is <code>NOMATCH</code>, can
+     * only occur when
+     *
+     */
+    public boolean doesNotMatch() {
+        return (result.equals(ValidatorActionResult.NOMATCH));
+    }
+
+    /**
+     * Returns the tested object.
+     *
+     */
+    public Object getObject() {
+        return object;
+    }
+
+    /**
+     * Returns the result.
+     *
+     */
+    public ValidatorActionResult getResult() {
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionResult.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionResult.java
new file mode 100644
index 0000000..9da024f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/acting/ValidatorActionResult.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import org.apache.cocoon.util.EnumerationFactory;
+
+/**
+ * A number of constants to represent the possible outcomes of a
+ * validation.
+ *
+ * @version $Id$
+ */
+public class ValidatorActionResult extends EnumerationFactory {
+
+    /**
+     * no error occurred, parameter successfully checked.
+     */
+    public static final ValidatorActionResult
+    OK         = new ValidatorActionResult ("OK");          // 0
+
+    /**
+     * this is returned when the result of a validation is
+     * requested but no such result is found in the request
+     * attribute.
+     */
+    public static final ValidatorActionResult
+    NOTPRESENT = new ValidatorActionResult ("NOTPRESENT");  // 1
+
+    /**
+     * some error occurred, this is a result that is never set but
+     * serves as a comparison target.
+     */
+    public static final ValidatorActionResult
+    ERROR      = new ValidatorActionResult ("ERROR");       // 2
+
+    /**
+     * the parameter is null but isn't allowed to.
+     */
+    public static final ValidatorActionResult
+    ISNULL     = new ValidatorActionResult ("ISNULL");      // 3
+
+    /**
+     * either value or length in case of a string is less than the
+     * specified minimum.
+     */
+    public static final ValidatorActionResult
+    TOOSMALL   = new ValidatorActionResult ("TOOSMALL");    // 4
+
+    /**
+     * either value or length in case of a string is greater than
+     * the specified maximum.
+     */
+    public static final ValidatorActionResult
+    TOOLARGE   = new ValidatorActionResult ("TOOLARGE");    // 5
+
+    /**
+     * a string parameter's value is not matched by the specified
+     * regular expression.
+     */
+    public static final ValidatorActionResult
+    NOMATCH    = new ValidatorActionResult ("NOMATCH");     // 6
+
+    /**
+     * maximum error, only used for comparisons.
+     */
+    public static final ValidatorActionResult
+    MAXERROR   = new ValidatorActionResult ("MAXERROR");    // 7
+
+    /**
+     * Make constructor private to inhibit creation outside.
+     */
+    private ValidatorActionResult (String image) {
+        super (image);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/BeanListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/BeanListener.java
new file mode 100644
index 0000000..7a6a117
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/BeanListener.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean;
+
+/**
+ * Interface allowing caller to install a listener so that it can be informed
+ * as the bean makes progress through the links to be called.
+ *
+ * @version $Id$
+ */
+public interface BeanListener {
+
+    /**
+     * Report a page as successfully generated
+     * @param sourceURI
+     * @param destinationURI
+     * @param pageSize
+     * @param linksInPage    Number of links found in this page
+     * @param newLinksinPage
+     * @param pagesRemaining Number of pages still to be generated
+     * @param pagesComplete
+     * @param timeTaken
+     */
+    public void pageGenerated(String sourceURI,
+                              String destinationURI, 
+                              int pageSize,
+                              int linksInPage, 
+                              int newLinksinPage, 
+                              int pagesRemaining, 
+                              int pagesComplete, 
+                              long timeTaken);
+                              
+    /**
+     * Report a that was skipped because its URI matched an
+     * include/exclude pattern.
+     * @param uri
+     * @param message            
+     */
+    public void pageSkipped(String uri, String message);
+    
+    /**
+     * Report a general message about operation of the bean
+     * @param msg            The message to be reported
+     */
+    public void messageGenerated(String msg);
+
+    /**
+     * Report a warning about something non-fatal that happened within
+     * the bean.
+     * @param uri            The page being generated when warning was triggered
+     * @param warning        The warning to be reported
+     */
+    public void warningGenerated(String uri, String warning);
+
+    /**
+     * Report a broken link
+     * @param uri            The URI that failed to be generated
+     * @param message        A reason why the link was not generated
+     */
+    public void brokenLinkFound(String uri, String parentURI, String message, Throwable t);
+    public void brokenLinkFound(Target target, Throwable t);
+    
+    /**
+     * Signals completion of the generation process. This method can
+     * be used to write out reports, display time generation duration,
+     * etc.
+     */
+    public void complete();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonBean.java
new file mode 100644
index 0000000..06a2bdb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonBean.java
@@ -0,0 +1,743 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.bean.helpers.Crawler;
+import org.apache.cocoon.bean.helpers.DelayedOutputStream;
+import org.apache.cocoon.components.notification.SimpleNotifyingBean;
+import org.apache.cocoon.components.notification.Notifier;
+import org.apache.cocoon.components.notification.DefaultNotifyingBuilder;
+import org.apache.cocoon.components.notification.Notifying;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.commons.lang.SystemUtils;
+
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceUtil;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>The Cocoon Bean simplifies usage of the Cocoon object. Allows to create,
+ * configure Cocoon instance and process requests, one by one or multiple
+ * with link traversal.</p>
+ *
+ * <p><b>WARNING:</b> This interface is not stable and could be changed in
+ * backward incompatible way without prior notice.</p>
+
+ * @version $Id$
+ */
+public class CocoonBean extends CocoonWrapper {
+
+    // User Supplied Parameters
+    private boolean followLinks = true;
+    private boolean precompileOnly = false;
+    private boolean confirmExtension = true;
+    private String defaultFilename = Constants.INDEX_URI;
+    private boolean brokenLinkGenerate = false;
+    private String brokenLinkExtension = "";
+    private List excludePatterns = new ArrayList();
+    private List includePatterns = new ArrayList();
+    private List includeLinkExtensions = null;
+
+    // Internal Objects
+    private boolean initialized;
+    private List listeners = new ArrayList();
+    SourceResolver sourceResolver;
+
+    private Crawler crawler;    
+    private String checksumsURI = null;
+    private Map checksums;
+
+    public CocoonBean() {
+        this.crawler = new Crawler();
+    }
+
+    //
+    // INITIALISATION METHOD
+    //
+
+    public void initialize() throws Exception {
+        if (this.initialized == false) {
+            super.initialize();
+
+            this.sourceResolver =
+                (SourceResolver) getServiceManager().lookup(
+                    SourceResolver.ROLE);
+
+            initialized = true;
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        dispose();
+        super.finalize();
+    }
+
+    //
+    // GETTERS AND SETTERS FOR CONFIGURATION PROPERTIES
+    //
+
+    public void setFollowLinks(boolean follow) {
+        followLinks = follow;
+    }
+
+    public void setConfirmExtensions(boolean confirmExtension) {
+        this.confirmExtension = confirmExtension;
+    }
+
+    public void setPrecompileOnly(boolean precompileOnly) {
+        this.precompileOnly = precompileOnly;
+    }
+
+    public boolean isPrecompileOnly() {
+        return precompileOnly;
+    }
+    
+    public void setDefaultFilename(String filename) {
+        defaultFilename = filename;
+    }
+
+    public void setBrokenLinkGenerate(boolean brokenLinkGenerate) {
+        this.brokenLinkGenerate = brokenLinkGenerate;
+    }
+
+    public void setBrokenLinkExtension(String brokenLinkExtension) {
+        this.brokenLinkExtension = brokenLinkExtension;
+    }
+
+    public void setChecksumURI(String uri) {
+        this.checksumsURI = uri;
+    }
+    
+    public boolean followLinks() {
+        return followLinks;
+    }
+
+    public boolean confirmExtensions() {
+        return confirmExtension;
+    }
+    /**
+     * Adds a target for processing
+     *
+     * @param type Type of target - append, replace, insert.
+     * @param root
+     * @param sourceURI URI of the starting page
+     * @param destURI URI specifying destination for the generated pages.
+     * @throws IllegalArgumentException if destURI is missing
+     */
+    public void addTarget(
+            String type,
+            String root,
+            String sourceURI,
+            String destURI)
+            throws IllegalArgumentException {
+        Target target = new Target(type, root, sourceURI, destURI);
+        target.setDefaultFilename(this.defaultFilename);
+        target.setFollowLinks(this.followLinks);
+        target.setConfirmExtension(this.confirmExtension);
+        target.setLogger(this.logger);
+        crawler.addTarget(target);
+    }
+
+    public void addTarget(String type, String sourceURI, String destURI)
+        throws IllegalArgumentException {
+        Target target = new Target(type, sourceURI, destURI);
+        target.setDefaultFilename(this.defaultFilename);
+        target.setFollowLinks(this.followLinks);
+        target.setConfirmExtension(this.confirmExtension);
+        target.setLogger(this.logger);
+        crawler.addTarget(target);
+    }
+
+    public void addTarget(String sourceURI, String destURI)
+        throws IllegalArgumentException {
+        Target target = new Target(sourceURI, destURI);
+        target.setDefaultFilename(this.defaultFilename);
+        target.setFollowLinks(this.followLinks);
+        target.setConfirmExtension(this.confirmExtension);
+        target.setLogger(this.logger);
+        crawler.addTarget(target);
+    }
+
+    public void addTargets(List uris, String destURI)
+        throws IllegalArgumentException {
+        Iterator i = uris.iterator();
+        while (i.hasNext()) {
+            Target target = new Target((String) i.next(), destURI);
+            target.setDefaultFilename(this.defaultFilename);
+            target.setFollowLinks(this.followLinks);
+            target.setConfirmExtension(this.confirmExtension);
+            target.setLogger(this.logger);
+            crawler.addTarget(target);
+        }
+    }
+
+    public void addTarget(
+        String type,
+        String root,
+        String sourceURI,
+        String destURI,
+        boolean followLinks,
+        boolean confirmExtension,
+        String logger)
+        throws IllegalArgumentException {
+
+        Target target;
+        if (root == null && type == null) {
+            target = new Target(sourceURI, destURI);
+        } else if (root == null) {
+            target = new Target(type, sourceURI, destURI);
+        } else {
+            target = new Target(type, root, sourceURI, destURI);
+        }
+        target.setDefaultFilename(this.defaultFilename);
+        target.setFollowLinks(followLinks);
+        target.setConfirmExtension(confirmExtension);
+        target.setLogger(logger);
+        crawler.addTarget(target);
+    }
+
+    public int getTargetCount() {
+        return crawler.getRemainingCount();
+    }
+    
+    public void addExcludePattern(String pattern) {
+        int preparedPattern[] = WildcardHelper.compilePattern(pattern);
+        excludePatterns.add(preparedPattern);
+    }
+
+    public void addIncludePattern(String pattern) {
+        int preparedPattern[] = WildcardHelper.compilePattern(pattern);
+        includePatterns.add(preparedPattern);
+    }
+
+    public void addIncludeLinkExtension(String extension) {
+        if (includeLinkExtensions == null) {
+            includeLinkExtensions = new ArrayList();
+        }
+        includeLinkExtensions.add(extension);
+    }
+
+    public void addListener(BeanListener listener) {
+        this.listeners.add(listener);
+    }
+
+    public void pageGenerated(String sourceURI,
+                              String destURI,
+                              int pageSize,
+                              int linksInPage,
+                              int newLinksInPage,
+                              int pagesRemaining,
+                              int pagesComplete,
+                              long timeTaken) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.pageGenerated(sourceURI,
+                            destURI,
+                            pageSize,
+                            linksInPage,
+                            newLinksInPage,
+                            pagesRemaining,
+                            pagesComplete,
+                            timeTaken);
+        }
+    }
+
+    public void sendMessage(String msg) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.messageGenerated(msg);
+        }
+    }
+
+    public void sendWarning(String uri, String warning) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.warningGenerated(uri, warning);
+        }
+    }
+
+    public void sendBrokenLinkWarning(String uri, String warning) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.brokenLinkFound(uri, "", warning, null);
+        }
+    }
+
+    public void sendBrokenLinkWarning(Target target, Throwable t) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.brokenLinkFound(target, t);
+        }
+    }
+
+    public void pageSkipped(String uri, String message) {
+        Iterator i = listeners.iterator();
+        while (i.hasNext()) {
+            BeanListener l = (BeanListener) i.next();
+            l.pageSkipped(uri, message);
+        }
+    }
+
+    public void dispose() {
+        if (this.initialized) {
+            if (this.sourceResolver != null) {
+                getServiceManager().release(this.sourceResolver);
+                this.sourceResolver = null;
+            }
+            super.dispose();
+        }
+    }
+
+    /**
+     * Process the URI list and process them all independently.
+     * @exception Exception if an error occurs
+     */
+    public void process() throws Exception {
+
+        if (!this.initialized) {
+            this.initialize();
+        }
+
+        if (crawler.getRemainingCount() == 0 && !precompileOnly) {
+            log.info("No targets for to be processed.");
+            return;
+        }
+
+        if (this.checksumsURI != null) {
+            readChecksumFile();
+        }
+        
+        if (crawler.getRemainingCount()>=0) {
+            Iterator iterator = crawler.iterator();
+            while (iterator.hasNext()) {
+                Target target = (Target) iterator.next();
+                if (!precompileOnly) {
+                    processTarget(crawler, target);
+								}
+            }
+        }
+        
+        if (this.checksumsURI != null) {
+            writeChecksumFile();
+        }
+        
+        if (log.isInfoEnabled()) {
+              log.info(
+                  "  Memory used: "
+                      + (Runtime.getRuntime().totalMemory()
+                          - Runtime.getRuntime().freeMemory()));
+              log.info(
+                  "  Processed, Translated & Left: "
+                      + crawler.getProcessedCount()
+                      + ", "
+                      + crawler.getTranslatedCount()
+                      + ", "
+                      + crawler.getRemainingCount());
+          }
+    }
+
+    /**
+     * Processes the given Target and return all links.
+     *
+     * If links are to be followed, and extensions checked then the algorithm is as
+     * follows:
+     * <ul>
+     *  <li>file name for the URI is generated. URI MIME type is checked for
+     *      consistency with the URI and, if the extension is inconsistent
+     *      or absent, the file name is changed</li>
+     *  <li>the link view of the given URI is called and the file names for linked
+     *      resources are generated and stored.</li>
+     *  <li>for each link, absolute file name is translated to relative path.</li>
+     *  <li>after the complete list of links is translated, the link-translating
+     *      view of the resource is called to obtain a link-translated version
+     *      of the resource with the given link map</li>
+     *  <li>list of absolute URI is returned, for every URI which is not yet
+     *      present in list of all translated URIs</li>
+     * </ul>
+     *
+     * If links are to be followed, but extensions are not checked, then the
+     * algorithm will be:
+     * <ul>
+     *   <li>The content for the page is generated</li>
+     *   <li>Whilst generating, all links are gathered by the LinkGatherer</li>
+     *   <li>Gathered links are added to the unprocessed links list, and
+     *       processing continues until all processing is complete
+     *   </li>
+     * </ul>
+     *
+     * @param target a <code>Target</code> target to process
+     * @exception Exception if an error occurs
+     */
+    private void processTarget(Crawler crawler, Target target) throws Exception {
+
+        int status = 0;
+
+        int linkCount = 0;
+        int newLinkCount = 0;
+        int pageSize = 0;
+        long startTimeMillis = System.currentTimeMillis();
+
+        if (target.confirmExtensions()) {
+            if (!crawler.hasTranslatedLink(target)) {
+                final String mimeType = getType(target.getDeparameterizedSourceURI(), target.getParameters());
+                target.setMimeType(mimeType);
+                crawler.addTranslatedLink(target);
+            }
+        }
+
+        // IS THIS STILL NEEDED?
+        //if ("".equals(destinationURI)) {
+        //    return new ArrayList();
+        //}
+
+        // Process links
+        final HashMap translatedLinks = new HashMap();
+        if (target.followLinks() && target.confirmExtensions() && isCrawlablePage(target)) {
+            final Iterator i =
+                this.getLinks(target.getDeparameterizedSourceURI(), target.getParameters()).iterator();
+
+            while (i.hasNext()) {
+                String linkURI = (String) i.next();
+                Target linkTarget = target.getDerivedTarget(linkURI);
+
+                if (linkTarget == null) {
+                    pageSkipped(linkURI, "link does not share same root as parent");
+                    continue;
+                }
+
+                if (!isIncluded(linkTarget.getSourceURI())) {
+                    pageSkipped(linkTarget.getSourceURI(), "matched include/exclude rules");
+                    continue;
+                }
+
+                if (!crawler.hasTranslatedLink(linkTarget)) {
+                    try {
+                        final String mimeType =
+                                getType(linkTarget.getDeparameterizedSourceURI(), linkTarget.getParameters());
+                        linkTarget.setMimeType(mimeType);
+                        crawler.addTranslatedLink(linkTarget);
+                        log.info("  Link translated: " + linkTarget.getSourceURI());
+                        if (crawler.addTarget(linkTarget)) {
+                            newLinkCount++;
+                        }
+                    } catch (ProcessingException pe) {
+                        this.sendBrokenLinkWarning(linkTarget, pe);
+                        if (this.brokenLinkGenerate) {
+                           if (crawler.addTarget(linkTarget)) {
+                               newLinkCount++;
+                           }
+                        }
+                    }
+                } else {
+                    String originalURI = linkTarget.getOriginalSourceURI();
+                    linkTarget = crawler.getTranslatedLink(linkTarget);
+                    linkTarget.setOriginalURI(originalURI);
+                }
+
+                translatedLinks.put(linkTarget.getOriginalSourceURI(), linkTarget.getTranslatedURI(target.getPath()));
+            }
+
+            linkCount = translatedLinks.size();
+        }
+
+        try {
+            // Process URI
+            DelayedOutputStream output = new DelayedOutputStream();
+            try {
+                List gatheredLinks;
+                if (!target.confirmExtensions() && target.followLinks() && isCrawlablePage(target)) {
+                    gatheredLinks = new ArrayList();
+                } else {
+                    gatheredLinks = null;
+                }
+
+                status =
+                    getPage(
+                        target.getDeparameterizedSourceURI(),
+                        getLastModified(target),
+                        target.getParameters(),
+                        target.confirmExtensions() ? translatedLinks : null,
+                        gatheredLinks,
+                        output);
+
+                if (status >= 400) {
+                    throw new ProcessingException(
+                        "Resource not found: " + status);
+                }
+
+                if (gatheredLinks != null) {
+                    for (Iterator it = gatheredLinks.iterator();it.hasNext();) {
+                        String linkURI = (String) it.next();
+                        Target linkTarget = target.getDerivedTarget(linkURI);
+
+                        if (linkTarget == null) {
+                            pageSkipped(linkURI, "link does not share same root as parent");
+                            continue;
+                        }
+
+                        if (!isIncluded(linkTarget.getSourceURI())) {
+                            pageSkipped(linkTarget.getSourceURI(), "matched include/exclude rules");
+                            continue;
+                        }
+                        if (crawler.addTarget(linkTarget)) {
+                            newLinkCount++;
+                        }
+                    }
+                    linkCount = gatheredLinks.size();
+                }
+
+            } catch (ProcessingException pe) {
+                output.close();
+                output = null;
+                this.resourceUnavailable(target);
+                this.sendBrokenLinkWarning(target,
+                    DefaultNotifyingBuilder.getRootCause(pe));
+            } finally {
+                if (output != null && status != -1) {
+
+                    ModifiableSource source = getSource(target);
+                    try {
+                        pageSize = output.size();
+                        
+                        if (this.checksumsURI == null || !isSameContent(output, target)) {
+                            OutputStream stream = source.getOutputStream();
+                            output.setFileOutputStream(stream);
+                            output.flush();
+                            output.close();
+                            pageGenerated(target.getSourceURI(), 
+                                          target.getAuthlessDestURI(), 
+                                          pageSize,
+                                          linkCount,
+                                          newLinkCount,
+                                          crawler.getRemainingCount(),
+                                          crawler.getProcessedCount(),
+                                          System.currentTimeMillis()- startTimeMillis);
+                        } else {
+                            output.close();
+                            pageSkipped(target.getSourceURI(), "Page not changed");
+                        }
+                    } catch (IOException ioex) {
+                        log.warn(ioex.toString());
+                    } finally {
+                        releaseSource(source);
+                    }
+                }
+            }
+        } catch (Exception rnfe) {
+            log.warn("Could not process URI: " + target.getSourceURI());
+            rnfe.printStackTrace();
+            this.sendBrokenLinkWarning(target.getSourceURI(), "URI not found: "+rnfe.getMessage());
+        }
+    }
+
+    /**
+     * Generate a <code>resourceUnavailable</code> message.
+     *
+     * @param target being unavailable
+     * @exception IOException if an error occurs
+     */
+    private void resourceUnavailable(Target target)
+        throws IOException, ProcessingException {
+        if (brokenLinkGenerate) {
+            //Why decode this URI now?
+            //String brokenFile = NetUtils.decodePath(destinationURI);
+
+            if (brokenLinkExtension != null) {
+                target.setExtraExtension(brokenLinkExtension);
+            }
+            SimpleNotifyingBean n = new SimpleNotifyingBean(this);
+            n.setType("resource-not-found");
+            n.setTitle("Resource not Found");
+            n.setSource("Cocoon commandline (Main.java)");
+            n.setMessage("Page Not Available.");
+            n.setDescription("The requested resource couldn't be found.");
+            n.addExtraDescription(Notifying.EXTRA_REQUESTURI, target.getSourceURI());
+            n.addExtraDescription("missing-file", target.getSourceURI());
+
+            ModifiableSource source = getSource(target);
+            try {
+                OutputStream stream = source.getOutputStream();
+
+                PrintStream out = new PrintStream(stream);
+                Notifier.notify(n, out, "text/html");
+                out.flush();
+                out.close();
+            } finally {
+                releaseSource(source);
+            }
+        }
+    }
+
+    public ModifiableSource getSource(Target target)
+        throws IOException, ProcessingException {
+        final String finalDestinationURI = target.getDestinationURI();
+        Source src = sourceResolver.resolveURI(finalDestinationURI);
+        if (!(src instanceof ModifiableSource)) {
+            sourceResolver.release(src);
+            throw new ProcessingException(
+                "Source is not Modifiable: " + finalDestinationURI);
+        }
+        return (ModifiableSource) src;
+    }
+
+    public long getLastModified(Target target) throws IOException, ProcessingException {
+        Source src = getSource(target);
+        long lastModified = src.getLastModified();
+        this.releaseSource(src);
+        return lastModified;
+    }
+
+    public void releaseSource(Source source) {
+        sourceResolver.release(source);
+    }
+    private boolean isIncluded(String uri) {
+        boolean included;
+        Iterator i;
+        HashMap map = new HashMap();
+
+        if (includePatterns.size() == 0) {
+            included = true;
+        } else {
+            included = false;
+            i = includePatterns.iterator();
+            while (i.hasNext()){
+                int pattern[] = (int[])i.next();
+                if (WildcardHelper.match(map, uri, pattern)) {
+                    included=true;
+                    break;
+                }
+            }
+        }
+        if (excludePatterns.size() != 0) {
+            i = excludePatterns.iterator();
+            while (i.hasNext()) {
+                int pattern[] = (int[])i.next();
+                if (WildcardHelper.match(map, uri, pattern)) {
+                    included=false;
+                    break;
+                }
+            }
+        }
+        return included;
+    }
+    private boolean isCrawlablePage(Target target) {
+        if (includeLinkExtensions == null) {
+            return true;
+        }
+        return includeLinkExtensions.contains(target.getExtension());
+    }
+
+    /* NB. This is a temporary solution - it may well be replaced by storing the checksum info
+     *     in the XML 'report' file, along with details of what pages were created, etc. 
+     */ 
+    private void readChecksumFile() throws Exception {
+        checksums = new HashMap();
+        
+        try {
+            Source checksumSource = sourceResolver.resolveURI(checksumsURI);
+            BufferedReader reader = new BufferedReader(new InputStreamReader(checksumSource.getInputStream()));
+            String line;
+            int lineNo=0;
+            while ((line = reader.readLine())!=null) {
+                lineNo++;
+                if (line.trim().startsWith("#") || line.trim().length()==0 ) {
+                    continue;
+                }
+                if (line.indexOf("\t")==-1) { 
+                    throw new ProcessingException("Missing tab at line "+lineNo+" of " + checksumsURI);
+                }
+                String filename = line.substring(0,line.indexOf("\t"));
+                String checksum = line.substring(line.indexOf("\t")+1);
+                checksums.put(filename, checksum);
+            }
+            reader.close();
+        } catch (SourceNotFoundException e) {
+            // return leaving checksums map empty
+        }
+    }
+    
+    private void writeChecksumFile() throws Exception {
+        Source checksumSource = sourceResolver.resolveURI(checksumsURI);
+        if (!(checksumSource instanceof ModifiableSource)) {
+            throw new ProcessingException("Checksum file is not Modifiable:" + checksumSource);
+        }
+        ModifiableSource source = (ModifiableSource) checksumSource;
+        PrintWriter writer = new PrintWriter(new OutputStreamWriter(source.getOutputStream()));
+        Iterator i = checksums.keySet().iterator();
+        while (i.hasNext()){
+            String key = (String) i.next();
+            String checksum = (String) checksums.get(key);
+            writer.println(key + "\t" + checksum);
+        }
+        writer.close();
+    }
+
+    private boolean isSameContent(DelayedOutputStream stream, Target target) {
+        try {
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            md5.update(stream.getContent());
+            String streamDigest = SourceUtil.encodeBASE64(new String(md5.digest()));
+            String targetDigest = (String)checksums.get(target.getSourceURI());
+            
+            if (streamDigest.equals(targetDigest)) {
+                return true;
+            }
+            checksums.put(target.getSourceURI(), streamDigest);
+            return false;
+        } catch (NoSuchAlgorithmException e) {
+            // or do something:
+            return false;
+        }
+    }
+    /**
+     * Print a description of the software before running
+     */
+    public static String getProlog() {
+        String lSep = SystemUtils.LINE_SEPARATOR;
+        StringBuffer msg = new StringBuffer();
+        msg.append("------------------------------------------------------------------------ ").append(lSep);
+        msg.append(Constants.NAME).append(" ").append(Constants.VERSION).append(lSep);
+        msg.append("Copyright (c) ").append(Constants.YEAR).append(" Apache Software Foundation. All rights reserved.").append(lSep);
+        msg.append("Build: ").append(Constants.BUILD_INFO).append(lSep);
+        msg.append("------------------------------------------------------------------------ ").append(lSep).append(lSep);
+        return msg.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonWrapper.java
new file mode 100644
index 0000000..1afbfe9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/CocoonWrapper.java
@@ -0,0 +1,722 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.bean;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreUtil;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.commandline.CommandLineContext;
+import org.apache.cocoon.environment.commandline.FileSavingEnvironment;
+import org.apache.cocoon.environment.commandline.LinkSamplingEnvironment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.util.IOUtils;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.xml.ContentHandlerWrapper;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.commons.lang.SystemUtils;
+import org.xml.sax.ContentHandler;
+
+/**
+ * The Cocoon Wrapper simplifies usage of the Cocoon object. Allows to create,
+ * configure Cocoon instance and process single requests.
+ *
+ * @version $Id$
+ */
+public class CocoonWrapper {
+
+    protected static final String DEFAULT_USER_AGENT = Constants.COMPLETE_NAME;
+    protected static final String DEFAULT_ACCEPT = "text/html, */*";
+
+    // User Supplied Parameters
+    private String contextDir = Constants.DEFAULT_CONTEXT_DIR;
+    private String configFile = null;
+
+    private String workDir = Constants.DEFAULT_WORK_DIR;
+    private String logKit = null;
+    protected String logger = null;
+    protected String logLevel = "ERROR";
+    private String userAgent = DEFAULT_USER_AGENT;
+    private String accept = DEFAULT_ACCEPT;
+    private List classList = new ArrayList();
+
+    // Objects used alongside User Supplied Parameters
+    private File context;
+    private File work;
+    private File conf;
+
+    // Internal Objects
+    private CommandLineContext cliContext;
+    private Cocoon cocoon;
+    protected Logger log;
+    private HashMap empty = new HashMap();
+
+    private boolean initialized = false;
+
+    private CoreUtil coreUtil;
+
+    /**
+     * INITIALISATION METHOD.
+     */
+    public void initialize() throws Exception {
+        // Install a temporary logger so that getDir() can log if needed
+        final BootstrapEnvironment.LogLevel level = BootstrapEnvironment.LogLevel.getLogLevelForName(this.logLevel);
+        final Logger envLogger = new ConsoleLogger(level.getLevel());
+        this.log = envLogger;
+
+        this.context = getDir(this.contextDir, "context");
+        this.work = getDir(workDir, "working");
+
+        this.conf = getConfigurationFile(this.context, this.configFile);
+        cliContext = new CommandLineContext(contextDir);
+        cliContext.enableLogging(envLogger);
+
+        // setup Cocoon core
+        File cacheDir = getDir(workDir + File.separator + "cache-dir", "cache");
+
+        WrapperBootstrapper env = this.getBootstrapEnvironment();
+        env.setContextDirectory(contextDir);
+        env.setEnvironmentLogger(envLogger);
+        env.setEnvironmentContext(cliContext);
+        env.setWorkingDirectory(this.work);
+        env.setCachingDirectory(cacheDir);
+        env.setBootstrapLogLevel(this.logLevel);
+        env.setLoggingConfiguration(this.logKit);
+        env.setConfigFile(this.conf);
+        env.setLoadClassList(this.classList);
+        this.coreUtil = new CoreUtil(env);
+        this.cocoon = this.coreUtil.createCocoon();
+        this.log = env.logger;
+        this.initialized = true;
+    }
+
+    protected ServiceManager getServiceManager() {
+        return cocoon.getServiceManager();
+    }
+
+    /**
+     * Look around for the configuration file.
+     *
+     * @param dir a <code>File</code> where to look for configuration files
+     * @return a <code>File</code> representing the configuration
+     * @exception IOException if an error occurs
+     */
+    private File getConfigurationFile(File dir, String configFile)
+    throws IOException {
+        File conf;
+        if (configFile == null) {
+            conf = tryConfigurationFile(dir + File.separator + Constants.DEFAULT_CONF_FILE);
+            if (conf == null) {
+                conf = tryConfigurationFile(dir
+                            + File.separator
+                            + "WEB-INF"
+                            + File.separator
+                            + Constants.DEFAULT_CONF_FILE);
+            }
+            if (conf == null) {
+                conf =  tryConfigurationFile(
+                        SystemUtils.USER_DIR
+                            + File.separator
+                            + Constants.DEFAULT_CONF_FILE);
+            }
+            if (conf == null) {
+                conf = tryConfigurationFile(
+                        "/usr/local/etc/" + Constants.DEFAULT_CONF_FILE);
+            }
+        } else {
+            conf = new File(configFile);
+            if (!conf.canRead()) {
+                conf = new File(dir, configFile);
+                if (!conf.canRead()) {
+                    conf = null;
+                }
+            }
+        }
+        if (conf == null) {
+            log.error("Could not find the configuration file.");
+            throw new FileNotFoundException("The configuration file could not be found.");
+        }
+        return conf;
+    }
+
+    /**
+     * Try loading the configuration file from a single location
+     */
+    private File tryConfigurationFile(String filename) {
+        if (log.isDebugEnabled()) {
+            log.debug("Trying configuration file at: " + filename);
+        }
+        File conf = new File(filename);
+        if (conf.canRead()) {
+            return conf;
+        }
+        return null;
+    }
+
+    /**
+     * Get a <code>File</code> representing a directory.
+     *
+     * @param dir a <code>String</code> with a directory name
+     * @param type a <code>String</code> describing the type of directory
+     * @return a <code>File</code> value
+     * @exception IOException if an error occurs
+     */
+    private File getDir(String dir, String type) throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug("Getting handle to " + type + " directory '" + dir + "'");
+        }
+        File d = new File(dir);
+
+        if (!d.exists()) {
+            if (!d.mkdirs()) {
+                throw new IOException(
+                    "Error creating " + type + " directory '" + d + "'");
+            }
+        }
+
+        if (!d.isDirectory()) {
+            throw new IOException("'" + d + "' is not a directory.");
+        }
+
+        if (!d.canRead()) {
+            throw new IOException(
+                "Directory '" + d + "' is not readable");
+        }
+
+        if ("working".equals( type ) && !d.canWrite()) {
+            throw new IOException(
+                "Directory '" + d + "' is not writable");
+        }
+
+        return d;
+    }
+
+    protected void finalize() throws Throwable {
+        dispose();
+        super.finalize();
+    }
+
+    //
+    // GETTERS AND SETTERS FOR CONFIGURATION PROPERTIES
+    //
+
+    /**
+     * Set LogKit configuration file name
+     * @param logKit LogKit configuration file
+     */
+    public void setLogKit(String logKit) {
+        this.logKit = logKit;
+    }
+
+    /**
+     * Set log level. Default is DEBUG.
+     * @param logLevel log level
+     */
+    public void setLogLevel(String logLevel) {
+        this.logLevel = logLevel;
+    }
+
+    /**
+     * Set logger category as default logger for the Cocoon engine
+     * @param logger logger category
+     */
+    public void setLogger(String logger) {
+        this.logger = logger;
+    }
+
+    public String getLoggerName() {
+        return logger;
+    }
+
+    /**
+     * Set context directory
+     * @param contextDir context directory
+     */
+    public void setContextDir(String contextDir) {
+        this.contextDir = contextDir;
+    }
+
+    /**
+     * Set working directory
+     * @param workDir working directory
+     */
+    public void setWorkDir(String workDir) {
+        this.workDir = workDir;
+    }
+
+    public void setConfigFile(String configFile) {
+        this.configFile = configFile;
+    }
+
+    public void setAgentOptions(String userAgent) {
+        this.userAgent = userAgent;
+    }
+
+    public void setAcceptOptions(String accept) {
+        this.accept = accept;
+    }
+
+    public void addLoadedClass(String className) {
+        this.classList.add(className);
+    }
+
+    public void addLoadedClasses(List classList) {
+        this.classList.addAll(classList);
+    }
+    /**
+     * Process single URI into given output stream.
+     *
+     * @param uri to process
+     * @param outputStream to write generated contents into
+     */
+    public void processURI(String uri, OutputStream outputStream)
+        throws Exception {
+
+        if (!initialized) {
+            initialize();
+        }
+        log.info("Processing URI: " + uri);
+
+        // Get parameters, deparameterized URI and path from URI
+        final TreeMap parameters = new TreeMap();
+        final String deparameterizedURI =
+            NetUtils.deparameterize(uri, parameters);
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        int status =
+            getPage(deparameterizedURI, 0L, parameters, null, null, outputStream);
+
+        if (status >= 400) {
+            throw new ProcessingException("Resource not found: " + status);
+        }
+    }
+
+    /**
+     * Process single URI into given content handler, skipping final
+     * serializer
+     *
+     * @param uri to process
+     * @param handler to write generated contents into
+     */
+    public void processURI(String uri, ContentHandler handler)
+        throws Exception {
+
+        if (!initialized) {
+            initialize();
+        }
+        log.info("Processing URI: " + uri);
+
+        // Get parameters, deparameterized URI and path from URI
+        final TreeMap parameters = new TreeMap();
+        final String deparameterizedURI =
+            NetUtils.deparameterize(uri, parameters);
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        int status =
+            getPage(deparameterizedURI, 0L, parameters, null, null, handler);
+
+        if (status >= 400) {
+            throw new ProcessingException("Resource not found: " + status);
+        }
+    }
+
+    public void dispose() {
+        if (this.initialized) {
+            this.initialized = false;
+            this.coreUtil.destroy();
+            this.cocoon = null;
+            this.coreUtil = null;
+            if (log.isDebugEnabled()) {
+                log.debug("Disposed");
+            }
+        }
+    }
+
+    /**
+     * Samples an URI for its links.
+     *
+     * @param deparameterizedURI a <code>String</code> value of an URI to start sampling from
+     * @param parameters a <code>Map</code> value containing request parameters
+     * @return a <code>Collection</code> of links
+     * @exception Exception if an error occurs
+     */
+    protected Collection getLinks(String deparameterizedURI, Map parameters)
+        throws Exception {
+
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        LinkSamplingEnvironment env =
+            new LinkSamplingEnvironment(deparameterizedURI, context, null,
+                                        parameters, cliContext, log);
+        processLenient(env);
+        return env.getLinks();
+    }
+
+    /**
+     * Processes an URI for its content.
+     *
+     * @param deparameterizedURI a <code>String</code> value of an URI to start sampling from
+     * @param parameters a <code>Map</code> value containing request parameters
+     * @param links a <code>Map</code> value
+     * @param stream an <code>OutputStream</code> to write the content to
+     * @return a <code>String</code> value for the content
+     * @exception Exception if an error occurs
+     */
+    protected int getPage(String deparameterizedURI,
+                          long lastModified,
+                          Map parameters,
+                          Map links,
+                          List gatheredLinks,
+                          OutputStream stream)
+    throws Exception {
+
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        FileSavingEnvironment env =
+            new FileSavingEnvironment(deparameterizedURI, lastModified, context,
+                                      null, parameters, links,
+                                      gatheredLinks, cliContext, stream, log);
+
+        // Here Cocoon can throw an exception if there are errors in processing the page
+        cocoon.process(env);
+
+        // if we get here, the page was created :-)
+        int status = env.getStatus();
+        if (!env.isModified()) {
+            status = -1;
+        }
+        return status;
+    }
+
+    /**
+     * Processes an URI for its content.
+     *
+     * @param deparameterizedURI a <code>String</code> value of an URI to start sampling from
+     * @param parameters a <code>Map</code> value containing request parameters
+     * @param links a <code>Map</code> value
+     * @param handler an <code>ContentHandler</code> to send the content to
+     * @return a <code>String</code> value for the content
+     * @exception Exception if an error occurs
+     */
+    protected int getPage(String deparameterizedURI,
+                          long lastModified,
+                          Map parameters,
+                          Map links,
+                          List gatheredLinks,
+                          ContentHandler handler)
+    throws Exception {
+
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        FileSavingEnvironment env =
+            new FileSavingEnvironment(deparameterizedURI, lastModified, context,
+                                      null, parameters, links,
+                                      gatheredLinks, cliContext, null, log);
+
+        XMLConsumer consumer = new ContentHandlerWrapper(handler);
+        Processor.InternalPipelineDescription pipeline = cocoon.buildPipeline(env);
+        EnvironmentHelper.enterProcessor(pipeline.lastProcessor, pipeline.pipelineManager, env);
+        try {
+            pipeline.processingPipeline.prepareInternal(env);
+            pipeline.processingPipeline.process(env, consumer);
+        } finally {
+            EnvironmentHelper.leaveProcessor();
+        }
+
+        // if we get here, the page was created :-)
+        int status = env.getStatus();
+        if (!env.isModified()) {
+            status = -1;
+        }
+        return status;
+    }
+
+    /** Class <code>NullOutputStream</code> here. */
+    static class NullOutputStream extends OutputStream {
+        public void write(int b) throws IOException {
+            // ignore
+        }
+        public void write(byte b[]) throws IOException {
+            // ignore
+        }
+        public void write(byte b[], int off, int len) throws IOException {
+            // ignore
+        }
+    }
+
+    /**
+     * Analyze the type of content for an URI.
+     *
+     * @param deparameterizedURI a <code>String</code> value to analyze
+     * @param parameters a <code>Map</code> value for the request
+     * @return a <code>String</code> value denoting the type of content
+     * @exception Exception if an error occurs
+     */
+    protected String getType(String deparameterizedURI, Map parameters)
+        throws Exception {
+
+        parameters.put("user-agent", userAgent);
+        parameters.put("accept", accept);
+
+        FileSavingEnvironment env =
+            new FileSavingEnvironment(deparameterizedURI, context, null,
+                                      parameters, empty, null, cliContext,
+                                      new NullOutputStream(), log);
+        processLenient(env);
+        return env.getContentType();
+    }
+
+    /**
+     * Try to process something but don't throw a ProcessingException.
+     *
+     * @param env the <code>Environment</code> to process
+     * @return boolean true if no error were cast, false otherwise
+     * @exception Exception if an error occurs, except RNFE
+     */
+    private boolean processLenient(Environment env) throws Exception {
+        try {
+            this.cocoon.process(env);
+        } catch (ProcessingException pe) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * This builds the important ClassPath used by this class.  It
+     * does so in a neutral way.
+     * It iterates in alphabetical order through every file in the
+     * lib directory and adds it to the classpath.
+     *
+     * Also, we add the files to the ClassLoader for the Cocoon system.
+     * In order to protect ourselves from skitzofrantic classloaders,
+     * we need to work with a known one.
+     *
+     * @param context  The context path
+     * @return a <code>String</code> value
+     */
+    protected String getClassPath(final String context) {
+        StringBuffer buildClassPath = new StringBuffer();
+
+        String classDir = context + "/WEB-INF/classes";
+        buildClassPath.append(classDir);
+
+        File root = new File(context + "/WEB-INF/lib");
+        if (root.isDirectory()) {
+            File[] libraries = root.listFiles();
+            Arrays.sort(libraries);
+            for (int i = 0; i < libraries.length; i++) {
+                if (libraries[i].getAbsolutePath().endsWith(".jar")) {
+                    buildClassPath.append(File.pathSeparatorChar).append(
+                        IOUtils.getFullFilename(libraries[i]));
+                }
+            }
+        }
+
+        buildClassPath.append(File.pathSeparatorChar).append(SystemUtils.JAVA_CLASS_PATH);
+
+        // Extra class path is necessary for non-classloader-aware java compilers to compile XSPs
+        //        buildClassPath.append(File.pathSeparatorChar)
+        //                      .append(getExtraClassPath(context));
+
+        if (log.isDebugEnabled()) {
+            log.debug("Context classpath: " + buildClassPath);
+        }
+        return buildClassPath.toString();
+    }
+
+    protected WrapperBootstrapper getBootstrapEnvironment() {
+        return new WrapperBootstrapper();
+    }
+
+    /**
+     * This class provides wrapper specific environment information
+     *
+     */
+    public static class WrapperBootstrapper implements BootstrapEnvironment {
+
+        public Logger logger;
+
+        protected Logger environmentLogger;
+        protected Context environmentContext;
+        protected String workingDirectory;
+        protected String bootstrapLogLevel;
+        protected String loggingConfiguration;
+        protected String cachingDirectory;
+        protected String contextDirectory;
+        protected String configFile;
+        protected List loadClassList;
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getBootstrapLogger(org.apache.cocoon.core.BootstrapEnvironment.LogLevel)
+         */
+        public Logger getBootstrapLogger(LogLevel logLevel) {
+            return new ConsoleLogger(logLevel.getLevel());
+        }
+
+        public void setEnvironmentLogger(Logger log) {
+            this.environmentLogger = log;
+        }
+
+        public void setEnvironmentContext(Context context) {
+            this.environmentContext = context;
+        }
+
+        public void setWorkingDirectory(File dir) {
+            this.workingDirectory = dir.getAbsolutePath();
+        }
+
+        public void setBootstrapLogLevel(String bootstrapLogLevel) {
+            this.bootstrapLogLevel = bootstrapLogLevel;
+        }
+
+        public void setLoggingConfiguration(String config) {
+            this.loggingConfiguration = config;
+        }
+
+        public void setCachingDirectory(File dir) {
+            this.cachingDirectory = dir.getAbsolutePath();
+        }
+
+        public void setContextDirectory(String dir) {
+            this.contextDirectory = dir;
+        }
+
+        public void setConfigFile(File file) {
+            this.configFile = file.getAbsolutePath();
+        }
+
+        public void setLoadClassList(List l) {
+            this.loadClassList = l;
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.avalon.framework.context.DefaultContext)
+         */
+        public void configure(DefaultContext context) {
+            // nothing to add
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.cocoon.core.MutableSettings)
+         */
+        public void configure(MutableSettings settings) {
+            settings.setWorkDirectory(this.workingDirectory);
+            settings.setCacheDirectory(this.cachingDirectory);
+            settings.setUploadDirectory(this.contextDirectory + "upload-dir");
+            settings.setBootstrapLogLevel(this.bootstrapLogLevel);
+            settings.setLoggingConfiguration(this.loggingConfiguration);
+            settings.setFormEncoding("ISO-8859-1");
+            settings.setConfiguration(this.configFile);
+            if ( this.loadClassList != null ) {
+                final Iterator i = this.loadClassList.iterator();
+                while ( i.hasNext() ) {
+                    settings.addToLoadClasses(i.next().toString());
+                }
+            }
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configureLoggingContext(org.apache.avalon.framework.context.DefaultContext)
+         */
+        public void configureLoggingContext(DefaultContext context) {
+            // nothing to add
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getConfigFile(java.lang.String)
+         */
+        public URL getConfigFile(String configFileName) throws Exception {
+            return new File(configFileName).toURL();
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getContextForWriting()
+         */
+        public File getContextForWriting() {
+            return new File(this.contextDirectory);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getContextURL()
+         */
+        public String getContextURL() {
+            try {
+                return new File(this.contextDirectory).toURL().toExternalForm();
+            } catch (MalformedURLException mue) {
+                return "file://" + this.contextDirectory;
+            }
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getEnvironmentContext()
+         */
+        public Context getEnvironmentContext() {
+            return this.environmentContext;
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String, java.lang.Throwable)
+         */
+        public void log(String message, Throwable error) {
+            this.environmentLogger.error(message, error);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String)
+         */
+        public void log(String message) {
+            this.environmentLogger.debug(message);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#setLogger(org.apache.avalon.framework.logger.Logger)
+         */
+        public void setLogger(Logger rootLogger) {
+            this.logger = rootLogger;
+        }
+        
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/Target.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/Target.java
new file mode 100644
index 0000000..8f99d0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/Target.java
@@ -0,0 +1,456 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.MIMEUtils;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * A Target is a single page for generation. It encapsulates the URI 
+ * arithmetic required to transform the URI of the page to be generated 
+ * (the source URI) into the URI to which the resulting page should be 
+ * written (the destination URI).
+ *
+ * @version $Id$
+ */
+public class Target {
+    // Defult type is append
+    private static final String APPEND_TYPE = "append";
+    private static final String REPLACE_TYPE = "replace";
+    private static final String INSERT_TYPE = "insert";
+
+    private final String type;
+    private final String root;
+    private final String sourceURI;
+    private final String destURI;
+    private final String deparameterizedSourceURI;
+    private final TreeMap parameters;
+    
+    private String parentURI = null;
+    private String originalURI = null;
+    private String mimeType = null; 
+    private String defaultFilename = Constants.INDEX_URI;
+    private String finalDestinationURI = null;
+    private String extension = null;    
+    private List referringURIs = null;
+    
+    private boolean followLinks;
+    private boolean confirmExtension;
+    private String logger;
+                 
+    private transient int _hashCode;
+    private transient String _toString;
+
+    public Target(String type,
+                  String root,
+                  String sourceURI,
+                  String destURI)
+    throws IllegalArgumentException {
+        this.type = type;
+        this.root = root;
+        
+        if (destURI == null || destURI.length() == 0) {
+            throw new IllegalArgumentException("You must specify a destination directory when defining a target");
+        }
+        if (!destURI.endsWith("/")) {
+            destURI += "/";
+        }
+        this.destURI = destURI;
+        
+        this.parameters = new TreeMap();
+        
+        // Normalize sourceURI, and make sure that parameters is always in the same order
+        sourceURI = NetUtils.normalize(root + sourceURI);
+        this.deparameterizedSourceURI = NetUtils.deparameterize(sourceURI, this.parameters);
+        this.sourceURI = NetUtils.parameterize(this.deparameterizedSourceURI, this.parameters);
+        this.referringURIs = new ArrayList();
+    }
+
+    public Target(String type, String sourceURI, String destURI)
+        throws IllegalArgumentException {
+        this(type, "", sourceURI, destURI);
+    }
+
+    public Target(String sourceURI, String destURI)
+        throws IllegalArgumentException {
+        this(APPEND_TYPE, "", sourceURI, destURI);
+    }
+
+    public Target getDerivedTarget(String originalLinkURI)
+        throws IllegalArgumentException {
+
+        String linkURI = originalLinkURI;
+        // Fix relative links starting with "?"
+        if (linkURI.startsWith("?")) {
+            linkURI = this.getPageURI() + linkURI;
+        }
+        linkURI =
+            NetUtils.normalize(NetUtils.absolutize(this.getPath(), linkURI));
+
+        // Ignore pages outside the root folder
+        if (!linkURI.startsWith(this.root)) {
+            return null;
+        }
+        linkURI = linkURI.substring(root.length());
+        
+        Target target = new Target(this.type, this.root, linkURI, this.destURI);
+        target.setOriginalURI(originalLinkURI);
+        target.addReferringURI(this.sourceURI);
+        target.setConfirmExtension(this.confirmExtension);
+        target.setFollowLinks(this.followLinks);
+        target.setDefaultFilename(this.defaultFilename);
+        target.setLogger(this.logger);
+        return target;
+    }
+
+    /**
+     * Sets the original URI. This is used to record the URI that
+     * caused the creation of this Target, for example as a link
+     * in another page. It is needed for doing link translation, as
+     * this is the URI that must be replaced by the translated one.
+     */
+    public void setOriginalURI(String uri) {
+        this.originalURI = uri;
+    }
+    
+    /**
+     * Sets the URI of the page that contained the link to this 
+     * URI. Used for reporting purposes.
+     * @deprecated Use the addPerentURIs method instead
+     */
+    public void setParentURI(String uri) {
+        this.referringURIs.add(uri);
+    }
+    
+    /**
+     * Sets the mime type for the resource referenced by this target.
+     * If a mime type is specified, the file extension of the 
+     * destination URI will be checked to see that it matches the
+     * default extension for the specified mime type. If it doesn't,
+     * the default extension will be appended to the destination URI.
+     *
+     * This URI change will be taken into account in pages that link
+     * to the current page.
+     * 
+     * If the mime type is not specified (and thus null), no extension
+     * checking will take place. 
+     */
+    public void setMimeType(String mimeType) {
+        this.mimeType = mimeType;
+        this.finalDestinationURI = null;
+    }
+    
+    /**
+     * Sets a file extension to be appended to the end of the destination
+     * URI. The main use of this is to create broken link error files that
+     * stand out, within the file structure of the generated site, by, for
+     * example, adding '.error' to the end of the filename.
+     */
+    public void setExtraExtension(String extension) {
+        this.extension = extension;
+        this.finalDestinationURI = null;
+    }
+    /**
+     * Sets the default filename. This filename is appended to URIs
+     * that refer to a directory, i.e. end with a slash, as resources
+     * referred to by such a URI cannot be written to a file system
+     * without a filename. 
+     *
+     * This URI change will be taken into account in pages that link
+     * to the current page.
+     * 
+     * If no default is specified, the Cocoon constants value will 
+     * be used.
+     */
+    public void setDefaultFilename(String filename) {
+        this.defaultFilename = filename;
+    }
+    
+    /**
+     * Adds a URI for a referring page. This will be used later if 
+     * this page causes a broken link in order to list all pages
+     * that refer to this broken link
+     * @param uri
+     */
+    public void addReferringURI(String uri) {
+        this.referringURIs.add(uri);
+    }
+    
+    /**
+     * Returns the first referring URI. If this method is 
+     * called, their should only be one entry in the list 
+     */
+    public String getReferringURI() {
+        return (String)referringURIs.get(0);
+    }
+
+    /**
+     * Get all referring URIs.
+     */
+    public List getReferringURIs() {
+        return referringURIs;
+    }
+    /**
+     * Gets the filename from the source URI, without the path.
+     * This is used to fill out relative URIs that have
+     * parameters but no filename such as ?page=123
+     */
+    public String getPageURI() {
+        String pageURI = this.getSourceURI();
+        if (pageURI.indexOf("/") != -1) {
+            pageURI = pageURI.substring(pageURI.lastIndexOf("/") + 1);
+            if (pageURI.length() == 0) {
+                pageURI = "./";
+            }
+        }
+        return pageURI;
+    }
+
+    /**
+     * Gets the path from the source URI, without the filename. 
+     * This is used when absolutizing/relativizing link URIs.
+     */
+    public String getPath() {
+        return NetUtils.getPath(this.getSourceURI());
+    }
+
+    /**
+     * Gets the file extension for the source URI
+     */
+    public String getExtension() {
+        return NetUtils.getExtension(this.getSourceURI());
+    }
+    
+    /** 
+     * Gets the parent URI (the URI of the page that contained
+     * a link to this URI). null is returned if this page was
+     * not referred to in a link.
+     */
+    public String getParentURI() {
+        return this.parentURI;
+    }
+    
+    /**
+     * Calculates the destination URI - the URI to which the generated
+     * page should be written. This will be a URI that, when resolved
+     * by a SourceResolver, will return a modifiableSource.
+     * 
+     * This calculation is only done once per target. It is therefore
+     * necessary to ensure that the mime type has been set (if required)
+     * before this method is called.
+     */
+    public String getDestinationURI()
+        throws ProcessingException {
+        
+        if (this.finalDestinationURI == null) {
+            
+            String actualSourceURI = this.sourceURI;
+            if (!actualSourceURI.startsWith(root)) {
+                throw new ProcessingException(
+                    "Derived target does not share same root: "
+                        + actualSourceURI);
+            }
+            actualSourceURI = actualSourceURI.substring(root.length());
+            actualSourceURI = mangle(actualSourceURI);
+            
+            String destinationURI;
+            if (APPEND_TYPE.equals(this.type)) {
+                destinationURI = destURI + actualSourceURI;
+            } else if (REPLACE_TYPE.equals(this.type)) {
+                destinationURI = destURI;
+            } else if (INSERT_TYPE.equals(this.type)) {
+                int starPos = destURI.indexOf("*");
+                if (starPos == -1) {
+                    throw new ProcessingException("Missing * in replace mapper uri");
+                } else if (starPos == destURI.length() - 1) {
+                    destinationURI = destURI.substring(0, starPos) + actualSourceURI;
+                } else {
+                    destinationURI = destURI.substring(0, starPos)
+                        + actualSourceURI
+                        + destURI.substring(starPos + 1);
+                }
+            } else {
+                throw new ProcessingException(
+                    "Unknown mapper type: " + this.type);
+            }
+            if (mimeType != null) {
+                final String ext = NetUtils.getExtension(destinationURI);
+                final String defaultExt = MIMEUtils.getDefaultExtension(mimeType);
+                if (defaultExt != null) {
+                    if ((ext == null) || (!ext.equals(defaultExt))) {
+                        destinationURI += defaultExt;
+                    }
+                }
+            }
+            if (this.extension != null) {
+                destinationURI += this.extension; 
+            }
+            this.finalDestinationURI = destinationURI;
+        }
+        return this.finalDestinationURI;
+    }
+
+    /**
+     * Gets a translated version of a link, ready for insertion
+     * into another page as a link. This link needs to be
+     * relative to the original page.
+     */
+    public String getTranslatedURI(String path) {
+                    
+        String actualSourceURI = this.sourceURI;
+        if (!actualSourceURI.startsWith(root)) {
+            return actualSourceURI;
+        }
+        actualSourceURI = mangle(actualSourceURI);
+        
+        if (mimeType != null) {
+            final String ext = NetUtils.getExtension(actualSourceURI);
+            final String defaultExt = MIMEUtils.getDefaultExtension(mimeType);
+            if (defaultExt != null) {
+                if ((ext == null) || (!ext.equals(defaultExt))) {
+                    actualSourceURI += defaultExt;
+                }
+            }
+        }
+        return NetUtils.relativize(path, actualSourceURI);
+    }
+
+    /**
+     * 
+     * @return destination URI after all authentication details have been
+     *         removed
+     */
+    public String getAuthlessDestURI() throws ProcessingException {
+        return NetUtils.removeAuthorisation(this.getDestinationURI());
+    }
+    
+    /**
+     * Gets the original URI used to create this Target.
+     * This URI is completely unprocessed.
+     */
+    public String getOriginalSourceURI() {
+        return this.originalURI;
+    }
+
+    /**
+     * Gets the source URI for this target, after
+     * the URI has been 'prepared' by normalisation,
+     * absolutization and deparameterization followed
+     * by reparameterization. This final step is to 
+     * ensure that all parameters appear in a consistent
+     * order. For example page?a=1&b=2 and page?b=2&a=1
+     * should be considered the same resource, and thus
+     * have the same sourceURI. 
+     */
+    public String getSourceURI() {
+        return this.sourceURI;
+    }
+    
+    /**
+     * Gets the source URI for this target, with 
+     * parameters removed. This is the URI that is 
+     * to be passed to Cocoon in order to generate 
+     * the page.
+     */
+    public String getDeparameterizedSourceURI() {
+        return this.deparameterizedSourceURI;
+    }
+
+    /**
+     * Gets the parameters that have been removed from
+     * the URI. These need to be passed to Cocoon when
+     * generating a page.
+     */
+    public TreeMap getParameters() {
+        return this.parameters;
+    }
+
+    /**
+     * Mangle a URI.
+     *
+     * @param uri a URI to mangle
+     * @return a mangled URI
+     */
+    private String mangle(String uri) {
+        if (uri.length()==0 || uri.charAt(uri.length() - 1) == '/') {
+            uri += defaultFilename;
+        }
+        uri = uri.replace('"', '\'');
+        uri = uri.replace('?', '_');
+        uri = uri.replace(':', '_');
+
+        return uri;
+    }
+
+    public boolean equals(Object o) {
+        return (o instanceof Target) && o.toString().equals(toString());
+    }
+
+    public int hashCode() {
+        if (_hashCode == 0) {
+            return _hashCode = toString().hashCode();
+        }
+        return _hashCode;
+    }
+
+    public String toString() {
+        if (_toString == null) {
+            return _toString =
+                "<"
+                    + type
+                    + "|"
+                    + root
+                    + "|"
+                    + sourceURI
+                    + "|"
+                    + destURI
+                    + ">";
+        }
+        return _toString;
+    }
+    /**
+     * @return boolean
+     */
+    public boolean confirmExtensions() {
+        return confirmExtension;
+    }
+
+    public boolean followLinks() {
+        return followLinks;
+    }
+
+    public String getLogger() {
+        return logger;
+    }
+
+    public void setConfirmExtension(boolean b) {
+        confirmExtension = b;
+    }
+
+    public void setFollowLinks(boolean b) {
+        followLinks = b;
+    }
+
+    public void setLogger(String string) {
+        logger = string;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/AntDelegate.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/AntDelegate.java
new file mode 100644
index 0000000..5ab7b5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/AntDelegate.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean.helpers;
+
+import org.w3c.dom.Document;
+import org.apache.cocoon.bean.CocoonBean;
+import org.apache.cocoon.bean.helpers.OutputStreamListener;
+import org.apache.cocoon.bean.helpers.BeanConfigurator;
+
+/**
+ * Delegate class for use by the Cocoon Ant task. Allows Ant to run
+ * Cocoon with a single method call that can happily be started with 
+ * introspection (due to classpath issues).
+ *  
+ * @version $Id$
+ */
+public class AntDelegate {
+
+    public static int process(Document xconf, String uriGroup) throws Exception {
+        CocoonBean cocoon = new CocoonBean();
+        OutputStreamListener listener = new OutputStreamListener(System.out);
+        cocoon.addListener(listener);
+        BeanConfigurator.configure(xconf, cocoon, "", uriGroup, listener);
+
+        System.out.println(CocoonBean.getProlog());
+
+        if (!cocoon.isPrecompileOnly() && cocoon.getTargetCount() ==0) {
+            listener.messageGenerated("Please, specify at least one starting URI.");
+            System.exit(1);
+        }
+
+        cocoon.initialize();
+        cocoon.process();
+        cocoon.dispose();
+
+        listener.complete();
+        return listener.isSuccessful() ? 0 : 1;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java
new file mode 100644
index 0000000..aba9277
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean.helpers;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cocoon.bean.CocoonBean;
+import org.apache.cocoon.bean.helpers.OutputStreamListener;
+import org.apache.commons.lang.BooleanUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Static class for configuring a CocoonBean from a DOM Document object
+ *
+ * @version $Id$
+ */
+public class BeanConfigurator {
+
+    private static final String NODE_ROOT = "cocoon";
+
+    private static final String NODE_LOGGING = "logging";
+    private static final String ATTR_LOG_KIT = "log-kit";
+    private static final String ATTR_LOG_LEVEL = "level";
+    private static final String ATTR_LOGGER = "logger";
+
+    private static final String NODE_CONTEXT_DIR = "context-dir";
+    private static final String NODE_DEST_DIR = "dest-dir";
+    private static final String NODE_WORK_DIR = "work-dir";
+    private static final String NODE_CONFIG_FILE = "config-file";
+    private static final String NODE_URI_FILE = "uri-file";
+    private static final String NODE_CHECKSUMS_URI = "checksums-uri";
+ 
+    private static final String ATTR_CONTEXT_DIR = "context-dir";
+    private static final String ATTR_DEST_DIR = "dest-dir";
+    private static final String ATTR_WORK_DIR = "work-dir";
+    private static final String ATTR_CONFIG_FILE = "config-file";
+    private static final String ATTR_URI_FILE = "uri-file";
+    private static final String ATTR_CHECKSUMS_URI = "checksums-uri";
+    private static final String ATTR_AGENT = "user-agent";
+    private static final String ATTR_ACCEPT = "accept";
+    private static final String ATTR_DEFAULT_FILENAME = "default-filename";
+     
+    private static final String NODE_BROKEN_LINKS = "broken-links";
+    private static final String ATTR_BROKEN_LINK_REPORT_TYPE = "type";
+    private static final String ATTR_BROKEN_LINK_REPORT_FILE = "file";
+    private static final String ATTR_BROKEN_LINK_GENERATE = "generate";
+    private static final String ATTR_BROKEN_LINK_EXTENSION = "extension";
+    private static final String ATTR_BROKEN_LINK_SHOW_REFERRERS="show-referrers";
+
+    private static final String NODE_AGENT = "user-agent";
+    private static final String NODE_ACCEPT = "accept";
+
+    private static final String ATTR_FOLLOW_LINKS = "follow-links";
+    private static final String ATTR_PRECOMPILE_ONLY = "precompile-only";
+    private static final String ATTR_CONFIRM_EXTENSIONS = "confirm-extensions";
+    private static final String NODE_LOAD_CLASS = "load-class";
+    private static final String NODE_DEFAULT_FILENAME = "default-filename";
+
+    private static final String NODE_INCLUDE = "include";
+    private static final String NODE_EXCLUDE = "exclude";
+    private static final String ATTR_INCLUDE_EXCLUDE_PATTERN = "pattern";
+    
+    private static final String NODE_INCLUDE_LINKS = "include-links";
+    private static final String ATTR_LINK_EXTENSION = "extension";
+    
+    private static final String NODE_URI = "uri";
+    private static final String ATTR_URI_TYPE = "type";
+    private static final String ATTR_URI_SOURCEPREFIX = "src-prefix";
+    private static final String ATTR_URI_SOURCEURI = "src";
+    private static final String ATTR_URI_DESTURI = "dest";
+
+    private static final String NODE_URIS = "uris";
+    private static final String ATTR_NAME = "name";
+    
+    public static String configure(Document xconf, CocoonBean cocoon, String destDir, String uriGroup, OutputStreamListener listener) 
+        throws IllegalArgumentException {
+
+        Node root = xconf.getDocumentElement();
+        if (!NODE_ROOT.equals(root.getNodeName())) {
+            throw new IllegalArgumentException("Expected root node of "+ NODE_ROOT);
+        }
+
+        if (hasAttribute(root, ATTR_FOLLOW_LINKS)) {
+            cocoon.setFollowLinks(getBooleanAttributeValue(root, ATTR_FOLLOW_LINKS));
+        }
+        if (hasAttribute(root, ATTR_PRECOMPILE_ONLY)) {
+            cocoon.setPrecompileOnly(getBooleanAttributeValue(root, ATTR_PRECOMPILE_ONLY));
+        }
+        if (hasAttribute(root, ATTR_CONFIRM_EXTENSIONS)) {
+            cocoon.setConfirmExtensions(getBooleanAttributeValue(root, ATTR_CONFIRM_EXTENSIONS));
+        }
+        if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
+            cocoon.setContextDir(getAttributeValue(root, ATTR_CONTEXT_DIR));
+        }
+        if (hasAttribute(root, ATTR_DEST_DIR)) {
+            destDir = getAttributeValue(root, ATTR_DEST_DIR);
+        }
+        if (hasAttribute(root, ATTR_WORK_DIR)) {
+            cocoon.setWorkDir(getAttributeValue(root, ATTR_WORK_DIR));
+        }
+        if (hasAttribute(root, ATTR_CONFIG_FILE)) {
+            cocoon.setConfigFile(getAttributeValue(root, ATTR_CONFIG_FILE));
+        }
+        if (hasAttribute(root, ATTR_URI_FILE)) {
+            cocoon.addTargets(processURIFile(getAttributeValue(root, ATTR_URI_FILE)), destDir);
+        }
+        if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
+            cocoon.setChecksumURI(getAttributeValue(root, ATTR_CHECKSUMS_URI));
+        }
+        if (hasAttribute(root, ATTR_AGENT)) {
+            cocoon.setAgentOptions(getAttributeValue(root, ATTR_AGENT));
+        }
+        if (hasAttribute(root, ATTR_ACCEPT)) {
+            cocoon.setAcceptOptions(getAttributeValue(root, ATTR_ACCEPT));
+        }
+        if (hasAttribute(root, ATTR_DEFAULT_FILENAME)) {
+            cocoon.setDefaultFilename(getAttributeValue(root, ATTR_DEFAULT_FILENAME));
+        }
+
+        if (destDir == null || destDir.length() == 0) {
+            destDir = getNodeValue(root, NODE_DEST_DIR);
+        }
+ 
+        NodeList nodes = root.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType()== Node.ELEMENT_NODE) {
+                String nodeName = node.getNodeName();
+                if (nodeName.equals(NODE_BROKEN_LINKS)) {
+                    parseBrokenLinkNode(cocoon, node, listener);
+
+                } else if (nodeName.equals(NODE_LOAD_CLASS)) {
+                    cocoon.addLoadedClass(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_LOGGING)) {
+                    parseLoggingNode(cocoon, node);
+
+                } else if (nodeName.equals(NODE_CONTEXT_DIR)) {
+                    if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CONTEXT_DIR+" as both element and attribute");
+                    }
+                    cocoon.setContextDir(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_CONFIG_FILE)) {
+                    if (hasAttribute(root, ATTR_CONFIG_FILE)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CONFIG_FILE+" as both element and attribute");
+                    }
+                    cocoon.setConfigFile(getNodeValue(node));
+                } else if (nodeName.equals(NODE_DEST_DIR)) {
+                    // Ignore
+
+                } else if (nodeName.equals(NODE_WORK_DIR)) {
+                    if (hasAttribute(root, ATTR_WORK_DIR)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_WORK_DIR+" as both element and attribute");
+                    }
+                    cocoon.setWorkDir(getNodeValue(node));
+                } else if (nodeName.equals(NODE_CHECKSUMS_URI)) {
+                    if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CHECKSUMS_URI+" as both element and attribute");
+                    }
+                    cocoon.setChecksumURI(getNodeValue(node));
+                } else if (nodeName.equals(NODE_AGENT)) {
+                    cocoon.setAgentOptions(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_ACCEPT)) {
+                    cocoon.setAcceptOptions(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_DEFAULT_FILENAME)) {
+                    cocoon.setDefaultFilename(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_INCLUDE)) {
+                    String pattern = parseIncludeExcludeNode(cocoon, node, NODE_INCLUDE);
+                    cocoon.addIncludePattern(pattern);
+
+                } else if (nodeName.equals(NODE_EXCLUDE)) {
+                    String pattern = parseIncludeExcludeNode(cocoon, node, NODE_EXCLUDE);
+                    cocoon.addExcludePattern(pattern);
+
+                } else if (nodeName.equals(NODE_INCLUDE_LINKS)) {
+                    parseIncludeLinksNode(cocoon, node);
+
+                } else if (nodeName.equals(NODE_URI)) {
+                    parseURINode(cocoon, node, destDir);
+
+                } else if (nodeName.equals(NODE_URIS)) {
+                    parseURIsNode(cocoon, node, destDir, uriGroup);
+
+                } else if (nodeName.equals(NODE_URI_FILE)) {
+                    if (hasAttribute(root, ATTR_URI_FILE)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_URI_FILE+" as both element and attribute");
+                    }
+                    cocoon.addTargets(processURIFile(getNodeValue(node)), destDir);
+                } else {
+                    throw new IllegalArgumentException("Unknown element: <" + nodeName + ">");
+                }
+            }
+        }
+        return destDir;
+    }
+
+    private static void parseLoggingNode(CocoonBean cocoon, Node node) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_LOG_KIT)) {
+            cocoon.setLogKit(getAttributeValue(node, ATTR_LOG_KIT));
+        }
+        if (hasAttribute(node, ATTR_LOGGER)) {
+            cocoon.setLogger(getAttributeValue(node, ATTR_LOGGER));
+        }
+        if (hasAttribute(node, ATTR_LOG_LEVEL)) {
+            cocoon.setLogLevel(getAttributeValue(node, ATTR_LOG_LEVEL));
+        }
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength()!=0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_LOGGING + "> node");
+        }
+    }
+
+    private static void parseIncludeLinksNode(CocoonBean cocoon, Node node) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_LINK_EXTENSION)) {
+            cocoon.addIncludeLinkExtension(getAttributeValue(node, ATTR_LINK_EXTENSION));
+        }
+    }
+
+    private static void parseBrokenLinkNode(CocoonBean cocoon, Node node, OutputStreamListener listener) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_FILE)) {
+            listener.setReportFile(getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_FILE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_TYPE)) {
+            listener.setReportType(getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_TYPE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_GENERATE)) {
+            cocoon.setBrokenLinkGenerate(getBooleanAttributeValue(node, ATTR_BROKEN_LINK_GENERATE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_EXTENSION)) {
+            cocoon.setBrokenLinkExtension(getAttributeValue(node, ATTR_BROKEN_LINK_EXTENSION));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_SHOW_REFERRERS)) {
+            listener.setIsShowingReferrers(getBooleanAttributeValue(node, ATTR_BROKEN_LINK_SHOW_REFERRERS));
+        }
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength()!=0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_BROKEN_LINKS + "> node");
+        }
+    }
+
+    private static String parseIncludeExcludeNode(CocoonBean cocoon, Node node, final String NODE_TYPE) throws IllegalArgumentException {
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength() != 0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_INCLUDE + "> node");
+        }
+
+        if (hasAttribute(node, ATTR_INCLUDE_EXCLUDE_PATTERN)) {
+            return getAttributeValue(node, ATTR_INCLUDE_EXCLUDE_PATTERN);
+        }
+        throw new IllegalArgumentException("Expected a "+ATTR_INCLUDE_EXCLUDE_PATTERN+" attribute for <"+NODE_TYPE+"> node");
+    }
+
+    private static void parseURIsNode(CocoonBean cocoon, Node node, String destDir, String uriGroup) throws IllegalArgumentException {
+
+        boolean followLinks = cocoon.followLinks();
+        boolean confirmExtensions = cocoon.confirmExtensions();
+        String logger = cocoon.getLoggerName();
+        String destURI = destDir;
+        String root = null;
+        String type = null;
+        String name = null;
+        
+        if (hasAttribute(node, ATTR_FOLLOW_LINKS)) {
+            followLinks = getBooleanAttributeValue(node, ATTR_FOLLOW_LINKS);
+        }
+        if (hasAttribute(node, ATTR_CONFIRM_EXTENSIONS)) {
+            confirmExtensions = getBooleanAttributeValue(node, ATTR_CONFIRM_EXTENSIONS);
+        }
+        if (hasAttribute(node, ATTR_URI_TYPE)) {
+            type = getAttributeValue(node, ATTR_URI_TYPE);
+        }
+        if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
+            root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
+        }
+        if (hasAttribute(node, ATTR_URI_DESTURI)) {
+            destURI = getAttributeValue(node, ATTR_URI_DESTURI);
+        }
+        if (hasAttribute(node, ATTR_LOGGER)) {
+            logger = getAttributeValue(node, ATTR_LOGGER);
+        }
+        if (hasAttribute(node, ATTR_NAME)) {
+            name = getAttributeValue(node, ATTR_NAME);
+            if (name != null && uriGroup != null && !name.equals(uriGroup)) {
+                // The user has not selected this URI group, so ignore it.
+                return;
+            }
+        }
+        NodeList nodes = node.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node child = nodes.item(i);
+            if (child.getNodeType()== Node.ELEMENT_NODE) {
+                String childName = child.getNodeName();
+                if (childName.equals(NODE_URI)) {
+                    String _sourceURI = null;
+                    String _destURI = destURI;
+                    String _root = root;
+                    String _type = type;
+                    
+                    if (child.getAttributes().getLength() == 0) {
+                        _sourceURI = getNodeValue(child);
+                        //destURI is inherited 
+                    } else {
+                        _sourceURI = getAttributeValue(child, ATTR_URI_SOURCEURI);
+
+                        if (hasAttribute(child, ATTR_URI_TYPE)) {
+                            _type = getAttributeValue(child, ATTR_URI_TYPE);
+                        }
+                        if (hasAttribute(child, ATTR_URI_SOURCEPREFIX)) {
+                            _root = getAttributeValue(child, ATTR_URI_SOURCEPREFIX);
+                        }
+                        if (hasAttribute(child, ATTR_URI_DESTURI)) {
+                            _destURI = getAttributeValue(child, ATTR_URI_DESTURI);
+                        }
+                    }
+                    cocoon.addTarget(_type, _root, _sourceURI, _destURI, followLinks, confirmExtensions, logger);
+                } else {
+                    throw new IllegalArgumentException("Unknown element: <" + childName + ">");
+                }
+            }
+        }
+    }
+        
+    private static void parseURINode(CocoonBean cocoon, Node node, String destDir) throws IllegalArgumentException {
+        NodeList nodes = node.getChildNodes();
+
+        if (node.getAttributes().getLength() == 0 && nodes.getLength() != 0) {
+            cocoon.addTarget(getNodeValue(node), destDir);
+        } else if (node.getAttributes().getLength() !=0 && nodes.getLength() ==0){
+
+            String src = getAttributeValue(node, ATTR_URI_SOURCEURI);
+
+            String type = null;
+            if (hasAttribute(node, ATTR_URI_TYPE)) {
+                type = getAttributeValue(node, ATTR_URI_TYPE);
+            }
+            String root = null;
+            if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
+                root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
+            }
+            String dest = null;
+            if (hasAttribute(node, ATTR_URI_DESTURI)) {
+                dest = getAttributeValue(node, ATTR_URI_DESTURI);
+            }
+
+            if (root != null && type != null & dest != null) {
+                cocoon.addTarget(type, root, src, dest);
+            } else if (root != null & dest != null) {
+                cocoon.addTarget(root, src, dest);
+            } else if (dest != null) {
+                cocoon.addTarget(src, dest);
+            } else {
+                cocoon.addTarget(src, destDir);
+            }
+        } else if (node.getAttributes().getLength() !=0 && nodes.getLength() != 0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_URI + "> node");
+        } else {
+            throw new IllegalArgumentException("Not enough information for <"+ NODE_URI + "> node");
+        }
+    }
+
+    private static String getNodeValue(Node root, String name) throws IllegalArgumentException {
+        NodeList nodes = root.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType()== Node.ELEMENT_NODE) {
+                String nodeName = node.getNodeName();
+                if (nodeName.equals(name)) {
+                    return getNodeValue(node);
+                }
+            }
+        }
+        return null;
+    }
+
+    private static String getNodeValue(Node node) throws IllegalArgumentException {
+        StringBuffer s = new StringBuffer();
+        NodeList children = node.getChildNodes();
+        boolean found = false;
+
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.TEXT_NODE) {
+                s.append(child.getNodeValue());
+                found = true;
+            } else {
+                throw new IllegalArgumentException("Unexpected node:" + child.getLocalName());
+            }
+        }
+        if (!found) {
+            throw new IllegalArgumentException("Expected value for " + node.getLocalName() + " node");
+        }
+        return s.toString();
+    }
+
+    private static String getAttributeValue(Node node, String attr) throws IllegalArgumentException {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            if (attribute != null && attribute.getNodeValue() != null) {
+                return attribute.getNodeValue();
+            }
+        }
+        throw new IllegalArgumentException("Missing " + attr + " attribute on <" + node.getNodeName() + "> node");
+    }
+
+    private static boolean hasAttribute(Node node, String attr) {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            return (attribute != null);
+        }
+        return false;
+    }
+
+    private static boolean getBooleanAttributeValue(Node node, String attr) {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+
+            if (attribute != null) {
+                String value = attribute.getNodeValue();
+                return BooleanUtils.toBoolean(value);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * <code>processURIFile</code> method.
+     *
+     * @param filename a <code>String</code> value
+     * @return uris a <code>List</code> of URIs
+     */
+    public static List processURIFile(String filename) {
+        List uris = new ArrayList();
+        try {
+            BufferedReader uriFile = new BufferedReader(new FileReader(filename));
+
+            while (true) {
+                String uri = uriFile.readLine();
+
+                if (null == uri) {
+                    break;
+                }
+                
+                uri = uri.trim();
+                if (!uri.equals("") && !uri.startsWith("#")){
+                    uris.add(uri.trim());
+                }
+            }
+
+            uriFile.close();
+        } catch (Exception e) {
+            // ignore errors.
+        }
+        return uris;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/Crawler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/Crawler.java
new file mode 100644
index 0000000..52f279e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/Crawler.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean.helpers;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cocoon.bean.Target;
+
+/**
+ * A simple Cocoon crawler.
+ *
+ * @version $Id$
+ */
+
+public class Crawler {
+
+    private Map allTranslatedLinks;
+    private Map stillNotVisited;
+    private Map visitedAlready;
+    
+    public Crawler() {
+        visitedAlready = new HashMap();
+        stillNotVisited = new HashMap();
+        allTranslatedLinks = new HashMap();
+    }
+    
+    /**
+     * Add a target for future processing
+     */
+    public boolean addTarget(Target target) {
+        String targetString = target.toString();
+        if (!visitedAlready.containsKey(targetString)) {
+            if (!stillNotVisited.containsKey(targetString)) {
+                stillNotVisited.put(targetString, target);
+                return true;
+            }
+            Target existingTarget = (Target)stillNotVisited.get(targetString);
+            existingTarget.addReferringURI(target.getReferringURI());
+        } else {
+            Target visitedTarget = (Target)visitedAlready.get(targetString);
+            visitedTarget.addReferringURI(target.getReferringURI());
+        }
+        
+        return false;
+    }
+
+    /**
+     * Returns the number of targets for processing
+     */
+    public int getRemainingCount() {
+        return stillNotVisited.size();
+    }
+    
+    public int getProcessedCount() {
+        return visitedAlready.size();
+    }
+    
+    public int getTranslatedCount() {
+        return allTranslatedLinks.size();
+    }
+    
+    public void addTranslatedLink(Target target) {
+        allTranslatedLinks.put(target.getSourceURI(), target);
+    }
+    
+    public boolean hasTranslatedLink(Target link) {
+        return allTranslatedLinks.get(link.getSourceURI())!=null;
+    }
+    
+    public Target getTranslatedLink(Target link) {
+        return (Target) allTranslatedLinks.get(link.getSourceURI());
+    }
+    
+    /**
+     * Returns an iterator for reading targets
+     */
+    public CrawlingIterator iterator() {
+        return new CrawlingIterator(visitedAlready, stillNotVisited);
+    }
+    
+    public class CrawlingIterator implements Iterator {
+
+        private Map stillNotVisited;
+        private Map visitedAlready;
+        
+        public CrawlingIterator(Map visitedAlready, Map stillNotVisited) {
+            this.visitedAlready = visitedAlready;
+            this.stillNotVisited = stillNotVisited;
+        }
+
+        /**
+         *   Check if list of not visited URIs is empty
+         *
+         * @return    boolean true iff list of not visited URIs is not empty
+         */
+        public boolean hasNext() {
+            return !stillNotVisited.isEmpty();
+        }
+
+        /**
+         *   Removing objects is not supported, and will always throw
+         *   a <code>UnsupportedOperationException</code>.
+         */
+        public void remove(){ 
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         *   Get next not visited URIs
+         *
+         * @return    object from list of not visited URIs, move it immediatly
+         *   to set of visited URIs
+         */
+        public Object next() {
+            // could this be simpler:
+            Object nextKey = stillNotVisited.keySet().toArray()[0];
+            Object nextElement = stillNotVisited.remove(nextKey);
+            visitedAlready.put(nextKey, nextElement);
+            return nextElement;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java
new file mode 100644
index 0000000..f0670eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ *   A output stream writing to a ByteArrayOutputStream, until an OutputStream target is defined.
+ *
+ * @version $Id$
+ */
+public class DelayedOutputStream extends OutputStream {
+    /**
+     * write to baos as long as fos member is still null,
+     * create a ByteArrayOutputStream only
+     */
+    private ByteArrayOutputStream baos;
+    /**
+     * If fos is defined write into fos, dump content of
+     * baos to fos first
+     */
+    private OutputStream fos;
+
+
+    /**
+     * Constructor for the DelayedFileOutputStream object,
+     * create a ByteArrayOutputStream only
+     */
+    public DelayedOutputStream() {
+        baos = new ByteArrayOutputStream();
+        fos = null;
+    }
+
+    /**
+     * Creates a file output stream to write to the file represented by the specified File object.
+     *
+     * @param  outputStream               The new fileOutputStream value
+     */
+    public void setFileOutputStream(OutputStream outputStream) {
+        if (fos == null) {
+            fos = outputStream;
+        }
+    }
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(int b) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b);
+    }
+
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(byte b[]) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b);
+    }
+
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @param  off              Description of Parameter
+     * @param  len              Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(byte b[], int off, int len) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b, off, len);
+    }
+
+
+    /**
+     *   Close ByteArrayOutputStrem, and FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or closing
+     *   of baos, or fos fails
+     */
+    public void close() throws IOException {
+        IOException ioexception = null;
+
+        getTargetOutputStream();
+
+        // close baos
+        try {
+            if (baos != null) {
+                baos.close();
+            }
+        } catch (IOException ioe) {
+            ioexception = ioe;
+        } finally {
+            baos = null;
+        }
+
+        // close fos
+        try {
+            if (fos != null) {
+                fos.close();
+            }
+        } catch (IOException ioe) {
+            if (ioexception == null) {
+                ioexception = ioe;
+            }
+        } finally {
+            fos = null;
+        }
+
+        if (ioexception != null) {
+            throw ioexception;
+        }
+    }
+
+
+    /**
+     *   Flush ByteArrayOutputStrem, writing content to FileOutputStream,
+     *   flush FileOutputStream
+     *
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or flushing
+     *   of baos, or fos fails
+     */
+    public void flush() throws IOException {
+        IOException ioexception = null;
+
+        // flush baos, writing to fos, if neccessary
+        getTargetOutputStream();
+
+        // flush baos
+        try {
+            if (baos != null) {
+                baos.flush();
+            }
+        } catch (IOException ioe) {
+            ioexception = ioe;
+        }
+
+        // flush fos
+        try {
+            if (fos != null) {
+                fos.flush();
+            }
+        } catch (IOException ioe) {
+            if (ioexception == null) {
+                ioexception = ioe;
+            }
+        }
+        if (ioexception != null) {
+            throw ioexception;
+        }
+    }
+
+
+    /**
+     *   Gets the targetOutputStream attribute of the DelayedFileOutputStream object
+     *
+     * @return                  The targetOutputStream value
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails
+     */
+    private OutputStream getTargetOutputStream() throws IOException {
+        if (baos != null && fos == null) {
+
+            // no fos is defined, just write to baos in the mean time
+            return baos;
+        } else if (baos != null && fos != null) {
+            // fos is defined, flush boas to fos, and destroy baos
+            try {
+                baos.flush();
+                baos.writeTo(fos);
+                baos.close();
+            } finally {
+                baos = null;
+            }
+
+            return fos;
+        } else if (baos == null && fos != null) {
+            // no more temporary baos writing, write directly to fos
+            return fos;
+        } else {
+            // neither baos, nor fos are valid
+            throw new IOException("No outputstream available!");
+        }
+    }
+
+    /**
+     * Gets the size of the content of the current output stream
+     */
+    public int size() {
+        if (baos != null) {
+            return baos.size();
+        }
+        return 0;
+    }
+
+    /**
+     * Return the contents of the stream as a byte array
+     */
+    public byte[] getContent() {
+        if (baos != null) {
+            return baos.toByteArray();
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java
new file mode 100644
index 0000000..2dc0e86
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean.helpers;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cocoon.bean.BeanListener;
+import org.apache.cocoon.bean.Target;
+
+/**
+ * Command line entry point. Parses command line, create Cocoon bean and invokes it
+ * with file destination.
+ *
+ * @version $Id$
+ */
+public class OutputStreamListener implements BeanListener {
+
+    private final PrintWriter writer;
+    private final Map brokenLinks = new HashMap();
+    private final long startTimeMillis;
+    private String reportFile = null;
+    private String reportType = "text";
+    private long siteSize = 0L;
+    private int sitePages = 0;
+    private boolean isShowingReferrers = false;
+    
+    public OutputStreamListener(OutputStream os) {
+        writer = new PrintWriter(os);
+        startTimeMillis = System.currentTimeMillis();
+    }
+
+    public void setReportFile(String filename) {
+        reportFile = filename;
+    }
+
+    public void setReportType(String type) {
+        reportType = type;
+    }
+
+    public void setIsShowingReferrers(boolean isShowingReferrers) {
+        this.isShowingReferrers = isShowingReferrers;
+    }
+    
+    public void pageGenerated(String sourceURI,
+                              String destinationURI,
+                              int pageSize,
+                              int linksInPage,
+                              int newLinksInPage,
+                              int pagesRemaining,
+                              int pagesComplete,
+                              long timeTaken) {
+        this.siteSize += pageSize;
+        this.sitePages++;
+
+        double time = (((double)timeTaken)/1000);
+
+        String size;
+        if (pageSize < 1024) {
+            size = pageSize + "b";
+        } else {
+            size = ((float)((int)(pageSize/102.4)))/10 + "Kb";
+        }
+
+        if (linksInPage == -1) {
+            this.print("* " + sourceURI);
+        } else {
+            this.print(pad(12, "* [" + pagesComplete + "/" + pagesRemaining + "] ") +
+                       pad(10, "[" + newLinksInPage + "/" + linksInPage + "] ") +
+                       pad(7,time + "s ") +
+                       pad(7, size) + " " +
+                       sourceURI);
+        }
+
+    }
+    public void messageGenerated(String msg) {
+        this.print(msg);
+    }
+
+    public void warningGenerated(String uri, String warning) {
+        this.print("Warning: "+warning + " when generating " + uri);
+    }
+
+    /**
+     * @deprecated use brokenLinkFound(String, List, String, Throwable) instead
+     */
+    public void brokenLinkFound(String uri, String parentURI, String message, Throwable t) {
+        this.print(pad(42,"X [0] ")+uri+"\tBROKEN: "+message);
+        brokenLinks.put(uri + "\t" + message, "");
+    }
+
+    public void brokenLinkFound(Target target, Throwable t) {
+        this.print(pad(42,"X [0] ")+target.getSourceURI()+"\tBROKEN: "+t.getMessage());
+        brokenLinks.put(target.getSourceURI() + "\t" + t.getMessage(), target);
+
+    }
+
+    public void pageSkipped(String uri, String message) {
+        this.print(pad(37, "^ ") + uri);
+    }
+
+    public void complete() {
+        outputBrokenLinks();
+
+        long duration = System.currentTimeMillis() - startTimeMillis;
+        DecimalFormat df = new DecimalFormat("###,###,##0");
+
+        this.print("Total time: " +
+                   (duration / 60000) + " minutes " +
+                   (duration % 60000)/1000 + " seconds, " +
+                   " Site size: " + df.format(this.siteSize) +
+                   " Site pages: " + this.sitePages);
+        this.close();
+    }
+
+    public boolean isSuccessful() {
+        return brokenLinks.size() == 0;
+    }
+
+    private void outputBrokenLinks() {
+        if (reportFile == null) {
+            return;
+        } else if ("text".equalsIgnoreCase(reportType)) {
+            outputBrokenLinksAsText();
+        } else if ("xml".equalsIgnoreCase(reportType)) {
+            outputBrokenLinksAsXML();
+        }
+    }
+
+    private void outputBrokenLinksAsText() {
+        PrintWriter writer;
+        try {
+            writer =
+                    new PrintWriter(
+                            new FileWriter(new File(reportFile)),
+                            true);
+            for (Iterator i = brokenLinks.keySet().iterator(); i.hasNext();) {
+                writer.println((String) i.next());
+            }
+            writer.close();
+        } catch (IOException ioe) {
+            this.print("Broken link file does not exist: " + reportFile);
+        }
+    }
+    private void outputBrokenLinksAsXML() {
+        PrintWriter writer;
+        try {
+            writer =
+                    new PrintWriter(
+                            new FileWriter(new File(reportFile)),
+                            true);
+            writer.println("<broken-links>");
+            for (Iterator i = brokenLinks.keySet().iterator(); i.hasNext();) {
+                String linkMsg = (String) i.next();
+                String uri = linkMsg.substring(0,linkMsg.indexOf('\t'));
+                String msg = linkMsg.substring(linkMsg.indexOf('\t')+1);
+                if (!isShowingReferrers) {
+                    writer.println("  <link message=\"" + msg + "\">" + uri + "</link>");
+                } else {
+                    writer.println("  <link message=\"" + msg + "\" uri=\"" + uri + "\">");
+                    Object t = brokenLinks.get(linkMsg);
+                    if (t instanceof Target) {
+                        Target target = (Target)t;
+                        for (Iterator j = target.getReferringURIs().iterator(); j.hasNext();) {
+                            String referrer=(String) j.next();
+                            writer.println("    <referrer uri=\"" + referrer + "\"/>");
+                        }
+                    }
+                    writer.println("  </link>");
+                }
+            }
+            writer.println("</broken-links>");
+            writer.close();
+        } catch (IOException ioe) {
+            this.print("Could not create broken link file: " + reportFile);
+        }
+    }
+
+    private String pad(int chars, String str) {
+        int len = str.length();
+        if (len < chars) {
+            StringBuffer sb = new StringBuffer(chars > len ? chars+1 : len+1);
+            sb.append(str);
+            for (int i=len; i<chars; i++) {
+                sb.append(" ");
+            }
+            return sb.toString();
+        }
+        return str;
+    }
+
+    private void print(String message) {
+        writer.println(message);
+        writer.flush();
+    }
+
+    private void close() {
+        // Flush the writer, but don't close the underlying stream.
+        writer.flush();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Block.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Block.java
new file mode 100644
index 0000000..8cded9d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Block.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Processor;
+
+/**
+ * @version $Id$
+ */
+public interface Block extends Processor { 
+
+    public static String NAME = Block.class.getName() + "-name";
+    public static String SUPER = "super";
+
+    /**
+     * Get the mount path of the block
+     */
+    public String getMountPath();
+
+    /**
+     * Get a block property
+     */
+    public String getProperty(String name);
+
+    // TODO: We should have a reflection friendly Map getProperties() also
+
+    /**
+     * The exported components of the block. Return null if the block doesn't export components.
+     * 
+     * @return a ServiceManager containing the blocks exported components
+     */
+    public ServiceManager getServiceManager();
+    
+    /**
+     * Takes the scheme specific part of a block URI (the scheme is
+     * the responsibilty of the BlockSource) and resolve it with
+     * respect to the blocks mount point.
+     */
+    public URI absolutizeURI(URI uriToResolve, URI base) throws URISyntaxException;
+
+    /**
+     * Parses and resolves the scheme specific part of a block URI
+     * with respect to the base URI of the current sitemap. The scheme
+     * specific part of the block URI has the form
+     * <code>foo:/bar</code> when refering to another block, in this
+     * case only an absolute path is allowed. For reference to the own
+     * block, both absolute <code>/bar</code> and relative
+     * <code>./foo</code> paths are allowed.
+     */
+    public URI resolveURI(URI uriToResolve, URI base) throws URISyntaxException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockContext.java
new file mode 100644
index 0000000..5893160
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockContext.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.cocoon.environment.impl.AbstractContext;
+
+/**
+* @version $Id$
+*/
+public class BlockContext extends AbstractContext {
+
+    private Hashtable attributes;
+    private BlockWiring wiring;
+    private BlockManager blockManager;
+    
+    public BlockContext(BlockWiring wiring, BlockManager blockManager) {
+        this.wiring = wiring;
+        this.blockManager = blockManager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.attributes.put(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getAttributes()
+     */
+    public Map getAttributes() {
+        return this.attributes;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.attributes.remove(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.attributes.keys();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getResource(java.lang.String)
+     */
+    public URL getResource(String path) throws MalformedURLException {
+        // A path starting with '/' should be resolved relative to the context and
+        // the '/' need to be removed to work with the URI resolver.
+        while (path.length() >= 1 && path.charAt(0) == '/') {
+            path = path.substring(1);
+        }
+        String contextURL = this.wiring.getContextURL().toExternalForm();
+        URL resolvedURL = null;
+        try {
+            resolvedURL = ((new URI(contextURL)).resolve(path)).toURL();
+        } catch (URISyntaxException e) {
+            throw new MalformedURLException("Couldn't resolve " + path + " relative " + contextURL +
+                    " error " + e.getMessage());
+        }
+        return resolvedURL;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getRealPath(java.lang.String)
+     */
+    public String getRealPath(String path) {
+        // We better don't assume that blocks are unpacked
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getMimeType(java.lang.String)
+     */
+    public String getMimeType(String file) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getInitParameter(java.lang.String)
+     */
+    public String getInitParameter(String name) {
+        return this.blockManager.getProperty(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Context#getResourceAsStream(java.lang.String)
+     */
+    public InputStream getResourceAsStream(String path) {
+        try {
+            return this.getResource(path).openStream();
+        } catch (IOException e) {
+            // FIXME Error handling
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockDispatcherProcessor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockDispatcherProcessor.java
new file mode 100644
index 0000000..5fcbdc3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockDispatcherProcessor.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * @version $Id$
+ */
+public class BlockDispatcherProcessor extends AbstractLogEnabled implements Processor {
+
+    private Blocks blocks;
+
+    /** Processor attributes */
+    private Map processorAttributes = new HashMap();
+   
+    /**
+     * @param blocks
+     */
+    public BlockDispatcherProcessor(Blocks blocks) {
+        this.blocks = blocks;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#process(org.apache.cocoon.environment.Environment)
+     */
+    public boolean process(Environment environment) throws Exception {
+        String uri = environment.getURI();
+        String oldPrefix = environment.getURIPrefix();
+        String oldURI = uri;
+        // The mount points start with '/' make sure that the URI also
+        // does, so that they are compareable.
+        if (uri.length() == 0 || uri.charAt(0) != '/') {
+            uri = "/" + uri;
+        }
+        Block block = this.blocks.getMountedBlock(uri);
+        if (block == null) {
+            return false;
+        } else {
+            // Resolve the URI relative to the mount point
+            String mountPoint = block.getMountPath();
+            uri = uri.substring(mountPoint.length());
+            getLogger().debug("Enter processing in block at " + mountPoint);
+            try {
+                environment.setURI("", uri);
+                // It is important to set the current block each time
+                // a new block is entered, this is used for the block
+                // protocol
+                BlockEnvironmentHelper.enterBlock(block);
+                return block.process(environment);
+            } finally {
+                BlockEnvironmentHelper.leaveBlock();
+                environment.setURI(oldPrefix, oldURI);
+                getLogger().debug("Leaving processing in block at " + mountPoint);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * Not relevant for the block dispatcher as it don't has an own pipeline
+     * @see org.apache.cocoon.Processor#buildPipeline(org.apache.cocoon.environment.Environment)
+     */
+    public InternalPipelineDescription buildPipeline(Environment environment)
+            throws Exception {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getComponentConfigurations()
+     */
+    public Configuration[] getComponentConfigurations() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * The block dispatcher is always the root processor in the processing chain
+     * @see org.apache.cocoon.Processor#getRootProcessor()
+     */
+    public Processor getRootProcessor() {
+        return this;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getSourceResolver()
+     */
+    public SourceResolver getSourceResolver() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getContext()
+     */
+    public String getContext() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.processorAttributes.put(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.processorAttributes.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.processorAttributes.remove(name);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockEnvironmentHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockEnvironmentHelper.java
new file mode 100644
index 0000000..ae33839
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockEnvironmentHelper.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.blocks;
+
+import java.util.Stack;
+
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * Stack used for geting hold on the current block manager
+ *
+ * @version $Id$
+ * @since 2.2 
+ */
+public class BlockEnvironmentHelper {
+
+    /** The block stack */
+    static protected final ThreadLocal blockStack = new ThreadLocal();
+
+    /**
+     * This hook must be called each time a block is entered.
+     *
+     * <p>This method should never raise an exception, except when the
+     * parameters are not set!</p>
+     *
+     * @throws ProcessingException if block is null
+     */
+    public static void enterBlock(Block block)
+    throws ProcessingException {
+        if (null == block) {
+            throw new ProcessingException("Block is not set.");
+        }
+
+        Stack stack = (Stack)blockStack.get();
+        if (stack == null) {
+            stack = new Stack();
+            blockStack.set(stack);
+        }
+        stack.push(block);
+    }
+
+    /**
+     * This hook must be called each time a block is left.
+     *
+     * <p>It's the counterpart to the {@link #enterBlock(Block)}
+     * method.</p>
+     */
+    public static void leaveBlock() {
+        final Stack stack = (Stack)blockStack.get();
+        stack.pop();
+    }
+
+    public static Block getCurrentBlock() {
+        final Stack stack = (Stack)blockStack.get();
+        if ( stack != null && !stack.isEmpty()) {
+        	return (Block)stack.peek();
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockManager.java
new file mode 100644
index 0000000..b45f70e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockManager.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.container.CocoonServiceManager;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * @version $Id$
+ */
+public class BlockManager
+    extends AbstractLogEnabled
+    implements Block, Configurable, Contextualizable, Disposable, Initializable, Serviceable { 
+
+    public static String ROLE = BlockManager.class.getName();
+
+    private Context context;
+    private Configuration config;
+    private ServiceManager parentServiceManager;
+    private ServiceManager serviceManager;
+
+    private Processor blockProcessor;
+    private BlockWiring blockWiring;
+    private BlockContext blockContext;
+    private Blocks blocks;
+
+    // Life cycle
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.parentServiceManager = manager;
+    }
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    public void configure(Configuration config)
+        throws ConfigurationException {
+        this.config = config;
+    }
+
+    public void initialize() throws Exception {
+        this.blockWiring = new BlockWiring();
+        LifecycleHelper.setupComponent(this.blockWiring,
+                                       this.getLogger(),
+                                       this.context,
+                                       null,
+                                       this.config);    
+
+        getLogger().debug("Initializing new Block Manager: " + this.blockWiring.getId());
+
+        this.blockContext = new BlockContext(this.blockWiring, this);
+        Context newContext = this.getAvalonContext();
+        String confLocation = this.blockWiring.getContextURL() + "::";
+
+        if (this.blockWiring.isCore()) {
+            this.getLogger().debug("Block with core=true");
+            this.serviceManager = this.parentServiceManager;
+       } else {
+            // Create a service manager for getting components from other blocks
+            ServiceManager topServiceManager = new InterBlockServiceManager(this.blockWiring, this.blocks);
+            ((InterBlockServiceManager)topServiceManager).enableLogging(this.getLogger());
+
+            this.serviceManager =
+                this.createLocalSourceResolverSM(newContext, topServiceManager, confLocation);
+        }
+        
+        // Create a service manager with the exposed components of the block
+        if (this.blockWiring.getComponentConfiguration() != null) {
+            DefaultConfiguration componentConf =
+                new DefaultConfiguration("components", confLocation);
+            componentConf.addAll(this.blockWiring.getComponentConfiguration());
+            this.serviceManager = new CocoonServiceManager(this.serviceManager);
+            LifecycleHelper.setupComponent(this.serviceManager,
+                    this.getLogger(),
+                    newContext,
+                    null,
+                    componentConf);
+        }
+
+        // Create a processor for the block
+        if (this.blockWiring.getProcessorConfiguration() != null) {
+            this.blockProcessor = new BlockProcessor();
+            LifecycleHelper.setupComponent(this.blockProcessor,
+                    this.getLogger(),
+                    newContext,
+                    this.serviceManager,
+                    this.blockWiring.getProcessorConfiguration());    
+            
+        }
+    }
+
+    public void dispose() {
+        this.parentServiceManager = null;
+    }
+
+    /**
+     * @throws Exception
+     */
+    protected Context getAvalonContext() throws Exception {
+        ComponentContext newContext = new ComponentContext(this.context);
+        // A block is supposed to be an isolated unit so it should not have
+        // any direct access to the global root context
+        newContext.put(ContextHelper.CONTEXT_ROOT_URL, new URL(this.blockWiring.getContextURL().toExternalForm()));
+        newContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, this.blockContext);
+        newContext.makeReadOnly();
+        
+        return newContext;
+    }
+
+    /**
+     * @param newContext
+     * @param confLocation
+     * @throws Exception
+     */
+    protected ServiceManager createLocalSourceResolverSM(Context newContext, ServiceManager parentServiceManager, String confLocation) throws Exception {
+        // The source resolver must be defined in this service
+        // manager, otherwise the root path will be the one from the
+        // parent manager, we add a resolver to get it right. If the
+        // components section contain includes the CoreComponentManager
+        // use the location of the configuration an the parent SourceResolver
+        // for resolving the include.
+        DefaultConfiguration sourceManagerConf =
+            new DefaultConfiguration("components", confLocation);
+        // FIXME: Need a local role manager as it is not inherited through the InterBlockServiceManager 
+        DefaultConfiguration roleInclude =
+            new DefaultConfiguration("include");
+        roleInclude.setAttribute("src", "resource://org/apache/cocoon/cocoon.roles");
+        sourceManagerConf.addChild(roleInclude);
+        DefaultConfiguration resolverConf =
+            new DefaultConfiguration("source-resolver");
+        sourceManagerConf.addChild(resolverConf);
+        ServiceManager sourceResolverSM =
+            new CoreServiceManager(parentServiceManager);
+        LifecycleHelper.setupComponent(
+                sourceResolverSM,
+                this.getLogger(),
+                newContext,
+                null,
+                sourceManagerConf);
+        return sourceResolverSM;
+    }
+
+    // Block methods
+
+    // The blocks manager should not be available within a block so I
+    // didn't want to make it part of the parent manager. But this is
+    // a little bit clumsy. Question is what components, if any, the
+    // blocks should have in common.
+    public void setBlocks(Blocks blocks) {
+    	this.blocks = blocks;
+    }
+
+    /**
+     * Get the mount path of the block
+     */
+    public String getMountPath() {
+        return this.blockWiring.getMountPath();
+    }
+
+    /**
+     * Get a block property
+     */
+    public String getProperty(String name) {
+		String value = this.blockWiring.getProperty(name);
+		if (value == null) {
+		    // Ask the super block for the property
+		    String superId = this.blockWiring.getBlockId(Block.SUPER);
+		    this.getLogger().debug("Try super property=" + name + " block=" + superId);
+		    Block block = this.blocks.getBlock(superId);
+		    if (block != null) {
+		        value =  block.getProperty(name);
+		    }
+		}
+		return value;
+    }
+
+    // TODO: We should have a reflection friendly Map getProperties() also
+
+    /**
+     * The exported components of the block. Return null if the block doesn't export components.
+     * 
+     * @return a ServiceManager containing the blocks exported components
+     */
+    public ServiceManager getServiceManager() {
+        // Check that the block have a local service manager
+        if (this.blockWiring.getComponentConfiguration() != null) {
+            return this.serviceManager;
+        } else {
+            return null;
+        }
+    }
+    
+    /**
+     * Takes the scheme specific part of a block URI (the scheme is
+     * the responsibilty of the BlockSource) and resolve it with
+     * respect to the blocks mount point.
+     */
+    public URI absolutizeURI(URI uriToResolve, URI base) throws URISyntaxException {
+        URI uri = resolveURI(uriToResolve, base);
+        String blockName = uri.getScheme();
+        Block block = null;
+        if (blockName == null) {
+            // this block
+            block = this;
+        } else {
+            // another block
+        	String blockId = this.blockWiring.getBlockId(blockName);
+            block = this.blocks.getBlock(blockId);
+        }
+        if (block == null)
+            throw new URISyntaxException(uriToResolve.toString(), "Unknown block name");
+
+        String mountPath = block.getMountPath();
+        if (mountPath == null)
+            throw new URISyntaxException(uri.toString(), "No mount point for this URI");
+        if (mountPath.endsWith("/"))
+            mountPath = mountPath.substring(0, mountPath.length() - 1);
+        String absoluteURI = mountPath + uri.getSchemeSpecificPart();
+        getLogger().debug("Resolving " + uri.toString() + " to " + absoluteURI);
+        return new URI(absoluteURI);
+    }
+
+    /**
+     * Parses and resolves the scheme specific part of a block URI
+     * with respect to the base URI of the current sitemap. The scheme
+     * specific part of the block URI has the form
+     * <code>foo:/bar</code> when refering to another block, in this
+     * case only an absolute path is allowed. For reference to the own
+     * block, both absolute <code>/bar</code> and relative
+     * <code>./foo</code> paths are allowed.
+     */
+    public URI resolveURI(URI uri, URI base) throws URISyntaxException {
+        getLogger().debug("BlockManager: resolving " + uri.toString() + " with scheme " +
+                          uri.getScheme() + " and ssp " + uri.getSchemeSpecificPart());
+        if (uri.getPath() != null && uri.getPath().length() >= 2 &&
+            uri.getPath().startsWith("./")) {
+            // self reference relative to the current sitemap, e.g. ./foo
+            if (uri.isAbsolute())
+                throw new URISyntaxException(uri.toString(), "When the protocol refers to other blocks the path must be absolute");
+            URI resolvedURI = base.resolve(uri);
+            getLogger().debug("BlockManager: resolving " + uri.toString() +
+                              " to " + resolvedURI.toString() + " with base URI " + base.toString());
+            uri = resolvedURI;
+        }
+        return uri;
+    }
+
+    // The Processor methods
+
+    public boolean process(Environment environment) throws Exception {
+        String blockName = (String)environment.getAttribute(Block.NAME);
+
+        if (blockName != null) {
+            // Request to other block.
+        	String blockId = this.blockWiring.getBlockId(blockName);
+        	boolean superCall = false;
+            // Call to named block
+            if (blockId != null && !Block.SUPER.equals(blockName)) {
+                // The block name should not be used in the recieving block.
+                environment.removeAttribute(Block.NAME);
+            } else {
+            	if (Block.SUPER.equals(blockName)) {
+            		// Explicit call to super block
+            		// The block name should not be used in the recieving block.
+            		environment.removeAttribute(Block.NAME);
+            	} else if (blockId == null) {
+            		// If there is a super block, the connection might
+            		// be defined there instead.
+            		blockId = this.blockWiring.getBlockId(Block.SUPER);
+            	}
+        		superCall = true;
+            }
+            Block block = this.blocks.getBlock(blockId);
+    		if (block == null) {
+    			return false;
+    		}
+            this.getLogger().debug("Enter processing in block " + blockName);
+            try {
+				// A super block should be called in the context of
+				// the called block to get polymorphic calls resolved
+				// in the right way. Therefore no new current block is
+				// set.
+            	if (!superCall) {
+                	// It is important to set the current block each time
+                	// a new block is entered, this is used for the block
+                	// protocol
+            		BlockEnvironmentHelper.enterBlock(block);
+            	}
+            	return block.process(environment);
+            } finally {
+            	if (!superCall) {
+            		BlockEnvironmentHelper.leaveBlock();
+            	}
+            	this.getLogger().debug("Leaving processing in block " + blockName);
+			}            	
+
+        } else {
+            // Request to the own block
+            boolean result = this.blockProcessor.process(environment);
+
+            return result;
+
+            // Pipelines seem to throw an exception instead of
+            // returning false when the pattern is not found. For the
+            // moment an explicit call of the super block is called in
+            // the end of the sitemap. It might be better to be
+            // explicit about it anyway.
+
+//             if (result) {
+//                 return true;
+//             } else if (this.superId != null) {
+//                 // Wasn't defined in the current block try super block
+//                 return this.process(this.superId, environment, true);
+//             } else {
+//                 return false;
+//             }
+        }
+    }
+
+    // FIXME: Not consistently supported for blocks yet. Most of the
+    // code just use process.
+    public InternalPipelineDescription buildPipeline(Environment environment)
+        throws Exception {
+        return this.blockProcessor.buildPipeline(environment);
+    }
+
+    public Configuration[] getComponentConfigurations() {
+        return this.blockProcessor.getComponentConfigurations();
+    }
+
+    // A block is supposed to be an isolated unit so it should not have
+    // any direct access to the global root sitemap
+    public Processor getRootProcessor() {
+        return this.blockProcessor;
+    }
+    
+    public SourceResolver getSourceResolver() {
+        return this.blockProcessor.getSourceResolver();
+    }
+    
+    public String getContext() {
+        return this.blockProcessor.getContext();
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.blockProcessor.getAttribute(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.blockProcessor.removeAttribute(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.blockProcessor.setAttribute(name, value);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockProcessor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockProcessor.java
new file mode 100644
index 0000000..2e0f8bd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockProcessor.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.container.CocoonServiceManager;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * @version $Id$
+ */
+public class BlockProcessor
+    extends AbstractLogEnabled
+    implements Processor, Configurable, Contextualizable, Disposable, Initializable, Serviceable { 
+
+    private Context context;
+    private ServiceManager parentServiceManager;
+    private ServiceManager serviceManager;
+    private Configuration config;
+    private SourceResolver sourceResolver;
+    private Processor processor;
+    private EnvironmentHelper environmentHelper;
+
+    /** Processor attributes */
+    protected Map processorAttributes = new HashMap();
+
+    // Life cycle
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.parentServiceManager = manager;
+    }
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    public void configure(Configuration config)
+        throws ConfigurationException {
+        this.config = config;
+    }
+
+    public void initialize() throws Exception {
+        // Create an own service manager
+        this.serviceManager = new CocoonServiceManager(this.parentServiceManager);
+
+        String sitemapPath = this.config.getAttribute("src");
+
+        // Hack to put a sitemap configuration for the main sitemap of
+        // the block into the service manager
+        getLogger().debug("BlockProcessor: create sitemap " + sitemapPath);
+        DefaultConfiguration sitemapConf =
+            new DefaultConfiguration("sitemap", "BlockProcessor sitemap: " + " for " + sitemapPath);
+        sitemapConf.setAttribute("file", sitemapPath);
+        sitemapConf.setAttribute("check-reload", "yes");
+        // The source resolver must be defined in this service
+        // manager, otherwise the root path will be the one from the
+        // parent manager
+        DefaultConfiguration resolverConf =
+            new DefaultConfiguration("source-resolver", "BlockProcessor source resolver");
+        DefaultConfiguration conf =
+            new DefaultConfiguration("components", "BlockProcessor components");
+        conf.addChild(sitemapConf);
+        conf.addChild(resolverConf);
+
+        LifecycleHelper.setupComponent(this.serviceManager,
+                                       this.getLogger(),
+                                       this.context,
+                                       null,
+                                       conf);
+
+        this.sourceResolver = (SourceResolver)this.serviceManager.lookup(SourceResolver.ROLE);
+        final Processor processor = EnvironmentHelper.getCurrentProcessor();
+        if (processor != null) {
+            getLogger().debug("processor context" + processor.getContext());
+        }
+        Source sitemapSrc = this.sourceResolver.resolveURI(sitemapPath);
+        getLogger().debug("Sitemap Source " + sitemapSrc.getURI());
+        this.sourceResolver.release(sitemapSrc);
+
+        // Get the Processor and keep it
+        this.processor = (Processor)this.serviceManager.lookup(Processor.ROLE);
+
+        this.environmentHelper =
+            new EnvironmentHelper((URL)this.context.get(ContextHelper.CONTEXT_ROOT_URL));
+        LifecycleHelper.setupComponent(this.environmentHelper,
+                                       this.getLogger(),
+                                       null,
+                                       this.serviceManager,
+                                       null);
+    }
+
+    public void dispose() {
+        if (this.serviceManager != null) {
+            this.serviceManager.release(this.sourceResolver);
+            this.sourceResolver = null;
+            LifecycleHelper.dispose(this.serviceManager);
+            this.serviceManager = null;
+        }
+        if (this.environmentHelper != null) {
+            LifecycleHelper.dispose(this.environmentHelper);
+            this.environmentHelper = null;
+        }
+        this.parentServiceManager = null;
+    }
+
+    // The Processor methods
+
+    public boolean process(Environment environment) throws Exception {
+        return this.processor.process(environment);
+    }
+
+
+    // FIXME: Not consistently supported for blocks yet. Most of the
+    // code just use process.
+    public InternalPipelineDescription buildPipeline(Environment environment)
+        throws Exception {
+        return this.processor.buildPipeline(environment);
+    }
+
+    public Configuration[] getComponentConfigurations() {
+        return null;
+    }
+
+    // A block is supposed to be an isolated unit so it should not have
+    // any direct access to the global root sitemap
+    public Processor getRootProcessor() {
+        return this;
+    }
+    
+    public org.apache.cocoon.environment.SourceResolver getSourceResolver() {
+        return this.environmentHelper;
+    }
+    
+    public String getContext() {
+        return this.environmentHelper.getContext();
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.processorAttributes.get(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.processorAttributes.remove(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.processorAttributes.put(name, value);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockWiring.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockWiring.java
new file mode 100644
index 0000000..2c528a3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlockWiring.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.excalibur.source.Source;
+import org.xml.sax.SAXException;
+
+/**
+ * @version $Id$
+ */
+public class BlockWiring
+    extends AbstractLogEnabled
+    implements Configurable, Contextualizable { 
+
+    private Context context;
+    private URL contextRootURL;
+    private String id;
+    private String location;
+    private Map connections = new HashMap();
+    private Map properties = new HashMap();
+    private Vector connectionNames;
+
+    private String mountPath;
+    private String sitemapPath;
+
+    private Configuration componentConfiguration;
+    private Configuration processorConfiguration;
+    
+    private boolean core = false;
+
+    // Life cycle
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+        this.contextRootURL = (URL) this.context.get(ContextHelper.CONTEXT_ROOT_URL);
+    }
+
+    public void configure(Configuration config)
+        throws ConfigurationException {
+        this.id = config.getAttribute("id");
+        this.location = config.getAttribute("location");
+        this.mountPath = config.getChild("mount").getAttribute("path", null);
+
+        getLogger().debug("BlockWiring configure: " +
+                          " id=" + this.id +
+                          " location=" + this.location +
+                          " mountPath=" + this.mountPath);
+
+        Configuration[] connections =
+            config.getChild("connections").getChildren("connection");
+        this.connectionNames = new Vector(connections.length);
+        for (int i = 0; i < connections.length; i++) {
+            Configuration connection = connections[i];
+            String name = connection.getAttribute("name");
+            this.connectionNames.add(name);
+            String block = connection.getAttribute("block");
+            this.connections.put(name, block);
+            getLogger().debug("connection: " + " name=" + name + " block=" + block);
+        }
+
+        Configuration[] properties =
+            config.getChild("properties").getChildren("property");
+        for (int i = 0; i < properties.length; i++) {
+            Configuration property = properties[i];
+            String name = property.getAttribute("name");
+            String value = property.getAttribute("value");
+            this.properties.put(name, value);
+            getLogger().debug("property: " + " name=" + name + " value=" + value);
+        }
+
+        // Read the block.xml file
+        String blockPath = this.location + "COB-INF/block.xml";
+        Source source = null;
+        Configuration block = null;
+
+        SimpleSourceResolver resolver = new SimpleSourceResolver();
+        resolver.enableLogging(this.getLogger());
+
+        try {
+            resolver.contextualize(this.context);
+            source = resolver.resolveURI(blockPath);
+	    // FIXME: Have used different locations for block.xml in the OSGi and the block stuff.
+	    if (!source.exists()) {
+		blockPath = this.location + "WEB-INF/block.xml";
+		source = resolver.resolveURI(blockPath);
+	    }
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            block = builder.build(source.getInputStream(), source.getURI());
+        } catch (IOException e) {
+            String msg = "Exception while reading " + blockPath + ": " + e.getMessage();
+            throw new ConfigurationException(msg, e);
+        } catch (SAXException e) {
+            String msg = "Exception while reading " + blockPath + ": " + e.getMessage();
+            throw new ConfigurationException(msg, e);
+        } catch (ContextException e) {
+            String msg = "Exception while reading " + blockPath + ": " + e.getMessage();
+            throw new ConfigurationException(msg, e);
+        } finally {
+            if (resolver != null) {
+                resolver.release(source);
+            }
+        }
+
+        properties =
+            block.getChild("properties").getChildren("property");
+        for (int i = 0; i < properties.length; i++) {
+            Configuration property = properties[i];
+            String name = property.getAttribute("name");
+            String defaultVal = property.getChild("default").getValue(null);
+            getLogger().debug("listing property: " + " name=" + name + " default=" + defaultVal);
+            if (this.properties.get(name) == null && defaultVal != null) {
+                // add default properties for those not set. This will
+                // override values from the extended class, question
+                // is if that is what we intend.
+                this.properties.put(name, defaultVal);
+                getLogger().debug("property: " + " name=" + name + " default=" + defaultVal);
+            }
+        }
+
+        this.sitemapPath = block.getChild("sitemap").getAttribute("src", null);
+        getLogger().debug("sitemapPath=" + this.sitemapPath);
+        this.processorConfiguration = block.getChild("sitemap", false);
+
+        this.componentConfiguration = block.getChild("components", false);
+        this.core = block.getChild("components").getAttributeAsBoolean("core", false);
+    }
+
+    /**
+     * Get the identifier of the block
+     */
+    public String getId() {
+        return this.id;
+    }
+
+    /**
+     * Get the URL of the root of the block
+     */
+    public URL getContextURL() throws MalformedURLException {
+        URL contextURL = null;
+        try {
+            contextURL = ((new URI(this.contextRootURL.toExternalForm())).resolve(this.location)).toURL();
+            getLogger().debug("Root URL " + contextRootURL);
+            getLogger().debug("Block Root URL " + contextURL.toString());
+        } catch (URISyntaxException e) {
+            throw new MalformedURLException("Couldn't create context URL from " + this.contextRootURL.toExternalForm() +
+                " and " + this.location + " error: " + e.getMessage());
+        }
+        return contextURL;
+    }
+
+    /**
+     * Get the names for the connections from this block. The name (super) of the super block is not included.
+     */
+    public Enumeration getConnectionNames() {
+        return this.connectionNames.elements();
+    }
+        
+    /**
+     * Get a block id from the blockname.
+     */
+    public String getBlockId(String blockName) {
+        String blockId = (String)this.connections.get(blockName);
+        getLogger().debug("Resolving block: " + blockName + " to " + blockId);
+        return blockId;
+    }
+
+    /**
+     * Get a block property
+     */
+    public String getProperty(String name) {
+        String value = (String)this.properties.get(name);
+        getLogger().debug("Accessing property=" + name + " value=" + value + " block=" + this.id);
+        return value;
+    }
+
+    /**
+     * Get path where the block should be mounted
+     */
+    String getMountPath() {
+        return this.mountPath;
+    }
+
+    /**
+     * Get the component configuration of the block
+     */
+    Configuration getComponentConfiguration() {
+        return this.componentConfiguration;
+    }
+
+    /**
+     * Get the processor configuration of the block
+     */
+    Configuration getProcessorConfiguration() {
+        return this.processorConfiguration;
+    }
+
+    /**
+     * Is it the block containing the Core object.
+     */
+    public boolean isCore() {
+        return this.core;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Blocks.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Blocks.java
new file mode 100644
index 0000000..83bd14c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/Blocks.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+/**
+ * @version $Id$
+ */
+public interface Blocks { 
+
+    /**
+     * Returns the block with the specified identity
+     * @param blockId
+     */
+    Block getBlock(String blockId);
+    
+    /**
+     * The block with the largest mount point that is a prefix of the URI is
+     * chosen.
+     * @param uri
+     */
+    Block getMountedBlock(String uri);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlocksManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlocksManager.java
new file mode 100644
index 0000000..3b211e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/BlocksManager.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.blocks;
+
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Modifiable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.environment.http.HttpEnvironment;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.impl.URLSource;
+import org.xml.sax.InputSource;
+
+/**
+ * @version $Id$
+ */
+public class BlocksManager
+	extends
+		HttpServlet
+    implements
+    	Blocks,
+        Modifiable
+	{ 
+
+    public static String ROLE = BlocksManager.class.getName();
+    private ServletConfig servletConfig;
+    private ServletContext servletContext;
+    private ServiceManager serviceManager;
+    private Context context;
+    private org.apache.cocoon.environment.Context environmentContext;
+    private Settings settings;
+    private String contextURL;
+    private String containerEncoding;
+
+    private String wiringFileName = "/" + Constants.WIRING;
+    private Source wiringFile;
+    private HashMap blocks = new HashMap();
+    private TreeMap mountedBlocks = new TreeMap(new InverseLexicographicalOrder());
+    
+    private Processor processor;
+    private Logger logger;    
+
+    public void init(ServletConfig servletConfig) throws ServletException {
+    	super.init(servletConfig);
+        this.containerEncoding = servletConfig.getInitParameter("container-encoding");
+        if (this.containerEncoding == null) {
+        	this.containerEncoding = "ISO-8859-1";
+        }
+    	this.servletConfig = servletConfig;
+    	this.servletContext = servletConfig.getServletContext();
+    	CoreUtil coreUtil = new CoreUtil(servletConfig, Constants.WIRING);
+		Core core = coreUtil.getCore();
+		this.settings = coreUtil.getSettings();
+		this.environmentContext = core.getEnvironmentContext();
+		this.context = core.getContext();
+		this.contextURL = coreUtil.getContextURL();
+		this.serviceManager = coreUtil.getServiceManager();
+		LoggerUtil loggerUtil = new LoggerUtil(servletConfig, this.context, this.settings);
+		this.logger = loggerUtil.getCocoonLogger();
+		this.getLogger().debug("Initializing the Blocks Manager");
+		
+		InputSource is = null;
+		try {
+			this.getLogger().debug("Wiring file: " + this.servletContext.getResource(this.wiringFileName));
+			URLSource urlSource = new URLSource();
+			urlSource.init(this.servletContext.getResource(this.wiringFileName), null);
+			this.wiringFile = new DelayedRefreshSourceWrapper(urlSource, 1000);
+			is = SourceUtil.getInputSource(this.wiringFile);
+		} catch (IOException e) {
+			throw new ServletException("Could not open configuration file: " + this.wiringFileName, e);
+		} catch (ProcessingException e) {
+			throw new ServletException("Could not open configuration file: " + this.wiringFileName, e);			
+		}
+				
+		DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+		Configuration wiring = null;
+		try {
+			wiring = builder.build(is);
+		} catch (Exception e) {
+			throw new ServletException("Could not create configuration from file: " + this.wiringFileName, e);			
+		}
+		
+		Configuration[] blockConfs = wiring.getChildren("block");
+		
+		try {
+		// Create and store all blocks
+		for (int i = 0; i < blockConfs.length; i++) {
+			Configuration blockConf = blockConfs[i];
+			this.getLogger().debug("Creating " + blockConf.getName() +
+					" id=" + blockConf.getAttribute("id") +
+					" location=" + blockConf.getAttribute("location"));
+			BlockManager blockManager = new BlockManager();
+			blockManager.setBlocks(this);
+			LifecycleHelper.setupComponent(blockManager,
+					this.getLogger(),
+					this.context,
+					this.serviceManager,
+					blockConf);
+			this.blocks.put(blockConf.getAttribute("id"), blockManager);
+			String mountPath = blockConf.getChild("mount").getAttribute("path", null);
+			if (mountPath != null) {
+				this.mountedBlocks.put(mountPath, blockManager);
+				this.getLogger().debug("Mounted block " + blockConf.getAttribute("id") +
+						" at " + mountPath);
+			}
+		}
+		} catch (Exception e) {
+			throw new ServletException(e);
+		}
+		this.createProcessor();
+    }
+    
+    public void destroy() {
+        Iterator blocksIter = this.blocks.entrySet().iterator();
+        while (blocksIter.hasNext()) {
+            LifecycleHelper.dispose(blocksIter.next());
+        }
+        if (this.serviceManager != null) {
+            this.serviceManager = null;            
+        }
+        this.blocks = null;
+        this.mountedBlocks = null;
+    }
+    
+    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        HttpEnvironment env;
+
+        // We got it... Process the request
+        String uri = request.getServletPath();
+        if (uri == null) {
+            uri = "";
+        }
+        String pathInfo = request.getPathInfo();
+        if (pathInfo != null) {
+            // VG: WebLogic fix: Both uri and pathInfo starts with '/'
+            // This problem exists only in WL6.1sp2, not in WL6.0sp2 or WL7.0b.
+            if (uri.length() > 0 && uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            uri += pathInfo;
+        }
+
+        if (uri.length() == 0) {
+            /* empty relative URI
+                 -> HTTP-redirect from /cocoon to /cocoon/ to avoid
+                    StringIndexOutOfBoundsException when calling
+                    "".charAt(0)
+               else process URI normally
+            */
+            String prefix = request.getRequestURI();
+            if (prefix == null) {
+                prefix = "";
+            }
+
+            response.sendRedirect(response.encodeRedirectURL(prefix + "/"));
+            return;
+        }
+
+        if (uri.charAt(0) == '/') {
+        	uri = uri.substring(1);
+        }
+
+        String formEncoding = request.getParameter("cocoon-form-encoding");
+        if (formEncoding == null) {
+            formEncoding = this.settings.getFormEncoding();
+        }
+        env = new HttpEnvironment(uri,
+                                  this.contextURL,
+                                  request,
+                                  response,
+                                  this.servletContext,
+                                  this.environmentContext,
+                                  this.containerEncoding,
+                                  formEncoding);
+        env.enableLogging(getLogger());
+		
+        try {
+	        this.processor.process(env);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new ServletException(e);
+		}
+		env.commitResponse();
+	}
+
+	public ServletConfig getServletConfig() {
+		return this.servletConfig;
+	}
+
+	public String getServletInfo() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	private Logger getLogger() {
+    	return this.logger;
+    }
+
+    private void createProcessor() {
+        this.processor = new BlockDispatcherProcessor(this);
+        ((BlockDispatcherProcessor)this.processor).enableLogging(this.getLogger());
+    }
+    
+    public Block getBlock(String blockId) {
+        return (Block)this.blocks.get(blockId);
+    }
+    
+    /**
+     * The block with the largest mount point that is a prefix of the URI is
+     * chosen. The implementation could be made much more efficient.
+     * @param uri
+     */
+    public Block getMountedBlock(String uri) {
+        Block block = null;
+        // All mount points that are before or equal to the URI in
+        // lexicographical order. This includes all prefixes.
+        Map possiblePrefixes = this.mountedBlocks.tailMap(uri);
+        Iterator possiblePrefixesIt = possiblePrefixes.entrySet().iterator();
+        // Find the largest prefix to the uri
+        while (possiblePrefixesIt.hasNext()) {
+            Map.Entry entry = (Map.Entry) possiblePrefixesIt.next();
+            String mountPoint = (String)entry.getKey();
+            if (uri.startsWith(mountPoint)) {
+                block = (BlockManager)entry.getValue();
+                break;
+            }
+        }
+        return block;
+    }
+
+    /**
+     * Queries the class to estimate its ergodic period termination.
+     *
+     * @param date a <code>long</code> value
+     * @return a <code>boolean</code> value
+     */
+    public boolean modifiedSince(long date) {
+        return date < this.wiringFile.getLastModified();
+    }
+
+    private static class InverseLexicographicalOrder implements Comparator {
+        public int compare(Object o1, Object o2) {
+            return ((String)o2).compareTo((String)o1);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/CoreUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/CoreUtil.java
new file mode 100644
index 0000000..fec3d0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/CoreUtil.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.CoreFatalException;
+import org.apache.cocoon.core.CoreInitializationException;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.core.PropertyProvider;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.SingleComponentServiceManager;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.http.HttpContext;
+import org.apache.cocoon.servlet.SettingsHelper;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * This is an utility class to create a new Cocoon instance.
+ * 
+ * TODO - Remove dependencies to LogKit and Log4J
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class CoreUtil {
+
+    /** Parameter map for the context protocol */
+    private static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /**
+     * Application <code>Context</code> Key for the servlet configuration
+     * @since 2.1.3
+     */
+    public static final String CONTEXT_SERVLET_CONFIG = "servlet-config";
+
+    private ServletConfig config;
+	private ServletContext servletContext;
+
+    /** "legacy" support: create an avalon context. */
+    private final DefaultContext appContext = new ComponentContext();
+    
+    private Context environmentContext;
+
+    /** The settings. */
+    private MutableSettings settings;
+
+    /** The parent service manager. */
+    private ServiceManager parentManager;
+
+    /** The root logger. */
+    private Logger log;
+
+    private ClassLoader classloader;
+
+	private File contextForWriting = null;
+	private String contextURL;
+	// path to a file that is supposed to be present in the servlet context
+	// and that is used for calculating the context URI
+	private String knownFile;
+
+	public CoreUtil(ServletConfig config) throws ServletException {
+		this(config, "WEB-INF/web.xml");
+	}
+	/**
+     * Setup a new instance.
+     * @param config
+     * @throws ServletException
+     */
+    public CoreUtil(ServletConfig config, String knownFile) throws ServletException {
+		this.config = config;
+		this.knownFile = knownFile;
+		this.servletContext = this.config.getServletContext();
+		this.servletContext.log("Initializing Apache Cocoon " + Constants.VERSION);
+		
+		String writeableContextPath = this.servletContext.getRealPath("/");
+		String path = writeableContextPath;
+		if (path == null) {
+		    // Try to figure out the path of the root from that of a known file
+			this.servletContext.log("Figuring out root from " + this.knownFile);
+		    try {
+		        path = this.servletContext.getResource("/" + this.knownFile).toString();
+				this.servletContext.log("Got " + path);
+		    } catch (MalformedURLException me) {
+		        throw new ServletException("Unable to get resource '" + this.knownFile + "'.", me);
+		    }
+		    path = path.substring(0, path.length() - this.knownFile.length());
+			this.servletContext.log("And servlet root " + path);
+		}
+		try {
+		    if (path.indexOf(':') > 1) {
+		        this.contextURL = path;
+		    } else {
+		        this.contextURL = new File(path).toURL().toExternalForm();
+		    }
+		} catch (MalformedURLException me) {
+		    // VG: Novell has absolute file names starting with the
+		    // volume name which is easily more then one letter.
+		    // Examples: sys:/apache/cocoon or sys:\apache\cocoon
+		    try {
+		        this.contextURL= new File(path).toURL().toExternalForm();
+		    } catch (MalformedURLException ignored) {
+		        throw new ServletException("Unable to determine servlet context URL.", me);
+		    }
+		}
+		if (writeableContextPath != null) {
+			this.contextForWriting = new File(writeableContextPath);
+		}
+    	this.environmentContext = new HttpContext(config.getServletContext());
+    	this.init();
+    }
+    
+    private void init() throws ServletException {
+        // first let's set up the appContext with some values to make
+        // the simple source resolver work
+
+        // add root url
+        try {
+            appContext.put(ContextHelper.CONTEXT_ROOT_URL,
+                           new URL(this.contextURL));
+        } catch (MalformedURLException ignore) {
+            // we simply ignore this
+        }
+
+        // add environment context
+        this.appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT,
+                            this.environmentContext);
+
+        // now add environment specific information
+        this.appContext.put(CONTEXT_SERVLET_CONFIG, this.config);
+
+        // create settings
+        this.settings = this.createSettings();
+
+        // first init the work-directory for the logger.
+        // this is required if we are running inside a war file!
+        final String workDirParam = this.settings.getWorkDirectory();
+        File workDir;
+        if (workDirParam != null) {
+            if (this.contextForWriting == null) {
+                // No context path : consider work-directory as absolute
+                workDir = new File(workDirParam);
+            } else {
+                // Context path exists : is work-directory absolute ?
+                File workDirParamFile = new File(workDirParam);
+                if (workDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    workDir = workDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    workDir = new File(this.contextForWriting, workDirParam);
+                }
+            }
+        } else {
+            workDir = new File("cocoon-files");
+        }
+        workDir.mkdirs();
+        this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
+        this.settings.setWorkDirectory(workDir.getAbsolutePath());
+
+        // Output some debug info
+        this.servletContext.log("Context URL: " + this.contextURL);
+        this.servletContext.log("Writeable Context: " + this.contextForWriting);
+        if (workDirParam != null) {
+        	this.servletContext.log("Using work-directory " + workDir);
+        } else {
+        	this.servletContext.log("Using default work-directory " + workDir);
+        }
+
+        final String uploadDirParam = this.settings.getUploadDirectory();
+        File uploadDir;
+        if (uploadDirParam != null) {
+            if (this.contextForWriting == null) {
+                uploadDir = new File(uploadDirParam);
+            } else {
+                // Context path exists : is upload-directory absolute ?
+                File uploadDirParamFile = new File(uploadDirParam);
+                if (uploadDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    uploadDir = uploadDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    uploadDir = new File(this.contextForWriting, uploadDirParam);
+                }
+            }
+            this.servletContext.log("Using upload-directory " + uploadDir);
+        } else {
+            uploadDir = new File(workDir, "upload-dir" + File.separator);
+            this.servletContext.log("Using default upload-directory " + uploadDir);
+        }
+        uploadDir.mkdirs();
+        appContext.put(Constants.CONTEXT_UPLOAD_DIR, uploadDir);
+        this.settings.setUploadDirectory(uploadDir.getAbsolutePath());
+
+        String cacheDirParam = this.settings.getCacheDirectory();
+        File cacheDir;
+        if (cacheDirParam != null) {
+            if (this.contextForWriting == null) {
+                cacheDir = new File(cacheDirParam);
+            } else {
+                // Context path exists : is cache-directory absolute ?
+                File cacheDirParamFile = new File(cacheDirParam);
+                if (cacheDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    cacheDir = cacheDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    cacheDir = new File(this.contextForWriting, cacheDirParam);
+                }
+            }
+            this.servletContext.log("Using cache-directory " + cacheDir);
+        } else {
+            cacheDir = new File(workDir, "cache-dir" + File.separator);
+            File parent = cacheDir.getParentFile();
+            if (parent != null) {
+                parent.mkdirs();
+            }
+            this.servletContext.log("cache-directory was not set - defaulting to " + cacheDir);
+        }
+        cacheDir.mkdirs();
+        appContext.put(Constants.CONTEXT_CACHE_DIR, cacheDir);
+        this.settings.setCacheDirectory(cacheDir.getAbsolutePath());
+		String configFileName = this.settings.getConfiguration();
+		final String usedFileName;
+		
+		if (configFileName == null) {
+			this.servletContext.log("Servlet initialization argument 'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
+			usedFileName = "/WEB-INF/cocoon.xconf";
+		} else {
+			usedFileName = configFileName;
+		}
+		
+		this.servletContext.log("Using configuration file: " + usedFileName);
+		
+		URL result;
+		try {
+			// test if this is a qualified url
+			if (usedFileName.indexOf(':') == -1) {
+				result = this.config.getServletContext().getResource(usedFileName);
+			} else {
+				result = new URL(usedFileName);
+			}
+		} catch (Exception mue) {
+			String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+			this.servletContext.log(msg, mue);
+			throw new ServletException(msg, mue);
+		}
+		
+		if (result == null) {
+			File resultFile = new File(usedFileName);
+			if (resultFile.isFile()) {
+				try {
+					result = resultFile.getCanonicalFile().toURL();
+				} catch (Exception e) {
+					String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+					this.servletContext.log(msg, e);
+					throw new ServletException(msg, e);
+				}
+			}
+		}
+		
+		if (result == null) {
+			String msg = "Init parameter 'configurations' doesn't name an existing resource : " + usedFileName;
+			this.servletContext.log(msg);
+			throw new ServletException(msg);
+		}
+
+        // update configuration
+        final URL u = result;
+        this.settings.setConfiguration(u.toExternalForm());
+        this.appContext.put(Constants.CONTEXT_CONFIG_URL, u);
+
+        // set encoding
+        this.appContext.put(Constants.CONTEXT_DEFAULT_ENCODING, settings.getFormEncoding());
+
+        // set class loader
+        this.appContext.put(Constants.CONTEXT_CLASS_LOADER, this.classloader);
+
+        // create the Core object
+        final Core core = this.createCore();
+
+        // create parent service manager
+        this.parentManager = this.getParentServiceManager(core);
+
+        // settings can't be changed anymore
+        settings.makeReadOnly();
+
+        // put the core into the context - this is for internal use only
+        // The Cocoon container fetches the Core object using the context.
+        this.appContext.put(Core.ROLE, core);
+
+        // FIXME - for now we just set an empty string as this information is looked up
+        //         by other components
+        this.appContext.put(Constants.CONTEXT_CLASSPATH, "");
+    }
+
+    public Core getCore() {
+        try {
+            return (Core)this.parentManager.lookup(Core.ROLE);
+        } catch (ServiceException neverIgnore) {
+            // this should never happen!
+            throw new CoreFatalException("Fatal exception: no Cocoon core available.", neverIgnore);
+        }
+    }
+
+    /**
+     * Create a new core instance.
+     * This method can be overwritten in sub classes.
+     * @return A new core object.
+     */
+    private Core createCore() {
+        final Core c = new Core(this.settings, this.appContext);
+        return c;
+    }
+
+    /**
+     * Return the settings object.
+     */
+    public Settings getSettings() {
+        return this.settings;
+    }
+
+    public ServiceManager getServiceManager() {
+    	return this.parentManager;
+    }
+    
+    /**
+     * The root context path for the servlet
+     * @return context URL
+     */
+    public String getContextURL() {
+    	return this.contextURL;
+    }
+    /**
+     * Instatiates the parent service manager, as specified in the
+     * parent-service-manager init parameter.
+     *
+     * If none is specified, the method returns <code>null</code>.
+     *
+     * @return the parent service manager, or <code>null</code>.
+     */
+    private ServiceManager getParentServiceManager(Core core) {
+        String parentServiceManagerClass = this.settings.getParentServiceManagerClassName();
+        String parentServiceManagerInitParam = null;
+        if (parentServiceManagerClass != null) {
+            int dividerPos = parentServiceManagerClass.indexOf('/');
+            if (dividerPos != -1) {
+                parentServiceManagerInitParam = parentServiceManagerInitParam.substring(dividerPos + 1);
+                parentServiceManagerClass = parentServiceManagerClass.substring(0, dividerPos);
+            }
+        }
+
+        ServiceManager parentServiceManager = null;
+        if (parentServiceManagerClass != null) {
+            try {
+                Class pcm = ClassUtils.loadClass(parentServiceManagerClass);
+                Constructor pcmc = pcm.getConstructor(new Class[]{String.class});
+                parentServiceManager = (ServiceManager) pcmc.newInstance(new Object[]{parentServiceManagerInitParam});
+
+                ContainerUtil.enableLogging(parentServiceManager, this.log);
+                ContainerUtil.contextualize(parentServiceManager, this.appContext);
+                ContainerUtil.initialize(parentServiceManager);
+            } catch (Exception e) {
+                if (this.log.isErrorEnabled()) {
+                    this.log.error("Could not initialize parent component manager.", e);
+                }
+            }
+        }
+        return new SingleComponentServiceManager(parentServiceManager, core, Core.ROLE);
+    }
+
+    /**
+     * Get the settings for Cocoon.
+     * This method reads several property files and merges the result. If there
+     * is more than one definition for a property, the last one wins.
+     * The property files are read in the following order:
+     * 1) context://WEB-INF/properties/*.properties
+     *    Default values for the core and each block - the order in which the files are read is not guaranteed.
+     * 2) context://WEB-INF/properties/[RUNNING_MODE]/*.properties
+     *    Default values for the running mode - the order in which the files are read is not guaranteed.
+     * 3) Property providers (ToBeDocumented)
+     * 4) The environment (CLI, Servlet etc.) adds own properties (e.g. from web.xml)
+     * 5) Additional property file specified by the "org.apache.cocoon.settings" system property or
+     *    if the property is not found, the file ".cocoon/settings.properties" is tried to be read from
+     *    the user directory.
+     * 6) System properties
+     *
+     * @return A new Settings object
+     */
+    private MutableSettings createSettings() {
+        // get the running mode
+        final String mode = System.getProperty(Settings.PROPERTY_RUNNING_MODE, Settings.DEFAULT_RUNNING_MODE);
+        this.config.getServletContext().log("Running in mode: " + mode);
+
+        // create an empty settings objects
+        final MutableSettings s = new MutableSettings();
+
+        // we need our own resolver
+        final SourceResolver resolver = this.createSourceResolver(new LoggerWrapper(this.config.getServletContext()));
+
+        // now read all properties from the properties directory
+        this.readProperties("context://WEB-INF/properties", s, resolver);
+        // read all properties from the mode dependent directory
+        this.readProperties("context://WEB-INF/properties/" + mode, s, resolver);
+
+        // Next look for custom property providers
+        Iterator i = s.getPropertyProviders().iterator();
+        while ( i.hasNext() ) {
+            final String className = (String)i.next();
+            try {
+                PropertyProvider provider = (PropertyProvider)ClassUtils.newInstance(className);
+                s.fill(provider.getProperties());
+            } catch (Exception ignore) {
+                this.config.getServletContext().log("Unable to get property provider for class " + className, ignore);
+                this.config.getServletContext().log("Continuing initialization.");            
+            }
+        }
+        // fill from the environment configuration, like web.xml etc.
+        // fill from the servlet parameters
+		SettingsHelper.fill(s, this.config);
+		if ( s.getWorkDirectory() == null ) {
+			final File workDir = (File)this.config.getServletContext().getAttribute("javax.servlet.context.tempdir");
+			s.setWorkDirectory(workDir.getAbsolutePath());
+		}
+		if ( s.getLoggingConfiguration() == null ) {
+			s.setLoggingConfiguration("/WEB-INF/logkit.xconf");
+		}
+
+        // read additional properties file
+        String additionalPropertyFile = s.getProperty(Settings.PROPERTY_USER_SETTINGS, 
+                                                      System.getProperty(Settings.PROPERTY_USER_SETTINGS));
+        // if there is no property defining the addition file, we try it in the home directory
+        if ( additionalPropertyFile == null ) {
+            additionalPropertyFile = System.getProperty("user.home") + File.separator + ".cocoon/settings.properties";
+            final File testFile = new File(additionalPropertyFile);
+            if ( !testFile.exists() ) {
+                additionalPropertyFile = null;
+            }
+        }
+        if ( additionalPropertyFile != null ) {
+            this.config.getServletContext().log("Reading user settings from '" + additionalPropertyFile + "'");
+            final Properties p = new Properties();
+            try {
+                FileInputStream fis = new FileInputStream(additionalPropertyFile);
+                p.load(fis);
+                fis.close();
+            } catch (IOException ignore) {
+                this.config.getServletContext().log("Unable to read '" + additionalPropertyFile + "'.", ignore);
+                this.config.getServletContext().log("Continuing initialization.");
+            }
+        }
+        // now overwrite with system properties
+        s.fill(System.getProperties());
+
+        return s;
+    }
+
+    /**
+     * Read all property files from the given directory and apply them to the settings.
+     */
+    private void readProperties(String directoryName,
+                                  MutableSettings s,
+                                  SourceResolver resolver) {
+        Source directory = null;
+        try {
+            directory = resolver.resolveURI(directoryName, null, CONTEXT_PARAMETERS);
+            if (directory.exists() && directory instanceof TraversableSource) {
+                final Iterator c = ((TraversableSource) directory).getChildren().iterator();
+                while (c.hasNext()) {
+                    final Source src = (Source) c.next();
+                    if ( src.getURI().endsWith(".properties") ) {
+                        final InputStream propsIS = src.getInputStream();
+                        this.config.getServletContext().log("Reading settings from '" + src.getURI() + "'.");
+                        final Properties p = new Properties();
+                        p.load(propsIS);
+                        propsIS.close();
+                        s.fill(p);
+                    }
+                }
+            }
+        } catch (IOException ignore) {
+            this.config.getServletContext().log("Unable to read from directory 'WEB-INF/properties'.", ignore);
+            this.config.getServletContext().log("Continuing initialization.");            
+        } finally {
+            resolver.release(directory);
+        }
+    }
+
+    /**
+     * Create a simple source resolver.
+     */
+    private SourceResolver createSourceResolver(Logger logger) {
+        // Create our own resolver
+        final SimpleSourceResolver resolver = new SimpleSourceResolver();
+        resolver.enableLogging(logger);
+        try {
+            resolver.contextualize(this.appContext);
+        } catch (ContextException ce) {
+            throw new CoreInitializationException(
+                    "Cannot setup source resolver.", ce);
+        }
+        return resolver;        
+    }
+
+    private static final class LoggerWrapper implements Logger {
+        private final ServletContext context;
+
+        public LoggerWrapper(ServletContext context) {
+            this.context = context;
+        }
+
+        private void text(String arg0, Throwable arg1) {
+            if ( arg1 != null ) {
+                this.context.log(arg0, arg1);
+            } else {
+                this.context.log(arg0);
+            }
+        }
+
+        public void debug(String arg0, Throwable arg1) {
+            // we ignore debug
+        }
+
+        public void debug(String arg0) {
+            // we ignore debug
+        }
+
+        public void error(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void error(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public void fatalError(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void fatalError(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public Logger getChildLogger(String arg0) {
+            return this;
+        }
+
+        public void info(String arg0, Throwable arg1) {
+            // we ignore info
+        }
+
+        public void info(String arg0) {
+            // we ignore info
+        }
+
+        public boolean isDebugEnabled() {
+            return false;
+        }
+
+        public boolean isErrorEnabled() {
+            return true;
+        }
+
+        public boolean isFatalErrorEnabled() {
+            return true;
+        }
+
+        public boolean isInfoEnabled() {
+            return false;
+        }
+
+        public boolean isWarnEnabled() {
+            return false;
+        }
+
+        public void warn(String arg0, Throwable arg1) {
+            // we ignore warn
+        }
+
+        public void warn(String arg0) {
+            // we ignore warn
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/InterBlockServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/InterBlockServiceManager.java
new file mode 100644
index 0000000..bfb9b1a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/InterBlockServiceManager.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * Look for a component in blocks that are connected to the current block.
+ * 
+ * @version $Id$
+ */
+public class InterBlockServiceManager extends AbstractLogEnabled implements ServiceManager {
+    
+    private BlockWiring blockWiring;
+    private Blocks blocks;
+    private Map managers = new HashMap();
+    private boolean called;
+
+    /**
+     * @param blockWiring
+     * @param blocks
+     */
+    public InterBlockServiceManager(BlockWiring blockWiring, Blocks blocks) {
+        this.blockWiring = blockWiring;
+        this.blocks = blocks;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup(String role) throws ServiceException {
+        ServiceManager manager = this.findServiceManager(role);
+        if (manager == null) {
+            throw new ServiceException(role, "Could not find any manager in connected blocks that contains the role");
+        }
+        Object component = manager.lookup(role);
+        // Keep track on what manager that was used so that we can return the component
+        this.managers.put(component, manager);
+        return component;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService(String role) {
+        ServiceManager manager = this.findServiceManager(role);
+        return manager != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        if (component == null)
+            return;
+        ServiceManager manager = (ServiceManager)this.managers.get(component);
+        if (manager != null) {
+            manager.release(component);
+        }
+    }
+
+    
+    /**
+     * Find a service manager that contains a given role from one of the connected blocks. The component
+     * managers of the connected blocks are searched in the order they are declared in the block configuration.
+     * The super block, if there is one, is tried after the connected blocks. This is to make certain that
+     * a blocks connections is searched before its super blocks connections. 
+     * 
+     * @param role the role to find a service manager for
+     * @return the found service manager or null if not found
+     */
+    private ServiceManager findServiceManager(String role) {
+        this.getLogger().debug("findServiceManager: blockId=" + this.blockWiring.getId() + " role=" + role);
+        // FIXME: Called is used for protection about infinite loops for blocks with circular dependencies.
+        // It must be made thread safe.
+        if (called) {
+            return null;
+        } else {
+            this.called = true;
+        }
+        ServiceManager manager = null;
+        try {
+            Enumeration connectionNames = this.blockWiring.getConnectionNames();
+            while (connectionNames.hasMoreElements()) {
+                String blockName = (String)connectionNames.nextElement();
+                String blockId = this.blockWiring.getBlockId(blockName);
+                Block block = this.blocks.getBlock(blockId);
+                // Don't access blocks that isn't setup yet
+                if (block != null) {
+                    manager = block.getServiceManager();
+                    if (manager != null && manager.hasService(role)) {
+                        return manager;
+                    }
+                } else {
+                    this.getLogger().debug("Serching for role=" + role + " in blockId=" + blockId + " that isn't setup.");
+                }
+            }
+            String superId = this.blockWiring.getBlockId(Block.SUPER);
+            if (superId != null) {
+                Block superBlock = this.blocks.getBlock(superId);
+                // Don't access blocks that isn't setup yet
+                if (superBlock != null) {
+                    manager = superBlock.getServiceManager();
+                    if (manager.hasService(role)) {
+                        return manager;
+                    }
+                } else {
+                    this.getLogger().debug("Serching for role=" + role + " in blockId=" + superId + " that isn't setup.");
+                }
+            }
+        } finally {
+            this.called = false;
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/LoggerUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/LoggerUtil.java
new file mode 100644
index 0000000..b3b639c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/LoggerUtil.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.blocks;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import javax.servlet.ServletConfig;
+import org.apache.avalon.excalibur.logger.Log4JConfLoggerManager;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.excalibur.logger.ServletLogger;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreInitializationException;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.SingleComponentServiceManager;
+import org.apache.cocoon.core.logging.CocoonLogKitLoggerManager;
+import org.apache.cocoon.core.logging.PerRequestLoggerManager;
+import org.apache.cocoon.core.logging.SettingsContext;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * This is an utility class to create a new Cocoon instance.
+ * 
+ * TODO - Remove dependencies to LogKit and Log4J
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class LoggerUtil {
+
+    /** Parameter map for the context protocol */
+    private static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    private ServletConfig config;
+	/** "legacy" support: create an avalon context. */
+    private Context appContext;
+    
+    /** The settings. */
+    private Settings settings;
+
+    /** The root logger. */
+    private Logger log;
+
+    /** The logger manager. */
+    private LoggerManager loggerManager;
+
+    private File contextForWriting;
+
+    /**
+     * Setup a new instance.
+     * @param config
+     */
+    public LoggerUtil(ServletConfig config, Context appContext, Settings settings) {
+    	this.config = config;
+    	this.appContext = appContext;
+    	this.settings = settings;
+    	// Init logger
+		this.initLogger();
+    }
+    
+    /**
+     * Create a simple source resolver.
+     */
+    private SourceResolver createSourceResolver(Logger logger) {
+        // Create our own resolver
+        final SimpleSourceResolver resolver = new SimpleSourceResolver();
+        resolver.enableLogging(logger);
+        try {
+            resolver.contextualize(this.appContext);
+        } catch (ContextException ce) {
+            throw new CoreInitializationException(
+                    "Cannot setup source resolver.", ce);
+        }
+        return resolver;        
+    }
+
+    private void initLogger() {
+        String logLevel = settings.getBootstrapLogLevel();
+        if (logLevel == null) {
+            logLevel = "INFO";
+        }
+
+        String accesslogger = settings.getEnvironmentLogger();
+        if (accesslogger == null) {
+            accesslogger = "cocoon";
+        }
+
+        // create bootstrap logger
+        final BootstrapEnvironment.LogLevel level = BootstrapEnvironment.LogLevel.getLogLevelForName(logLevel);
+        final Logger bootstrapLogger = new ServletLogger(this.config, level.getLevel());
+
+        // Create our own resolver
+        final SourceResolver resolver = this.createSourceResolver(bootstrapLogger);
+
+        // create an own service manager for the logger manager
+        final ServiceManager loggerManagerServiceManager = new SingleComponentServiceManager(
+                 null, resolver, SourceResolver.ROLE);
+
+        // create an own context for the logger manager
+        final DefaultContext subcontext = new SettingsContext(this.appContext, this.settings);
+        subcontext.put("context-work", new File(this.settings.getWorkDirectory()));
+        if (this.contextForWriting == null) {
+            File logSCDir = new File(this.settings.getWorkDirectory(), "log");
+            logSCDir.mkdirs();
+            subcontext.put("context-root", logSCDir.toString());
+        } else {
+            subcontext.put("context-root", this.contextForWriting.toString());
+        }
+        subcontext.put("servlet-context", this.config.getServletContext());
+
+        String loggerManagerClass = settings.getLoggerManagerClassName();
+
+        // the log4j support requires currently that the log4j system is already
+        // configured elsewhere
+
+        final LoggerManager loggerManager = this.newLoggerManager(loggerManagerClass);
+        ContainerUtil.enableLogging(loggerManager, bootstrapLogger);
+
+        try {
+            ContainerUtil.contextualize(loggerManager, subcontext);
+            ContainerUtil.service(loggerManager, loggerManagerServiceManager);
+
+            this.loggerManager = loggerManager;
+
+            if (loggerManager instanceof Configurable) {
+                //Configure the logkit management
+                String logkitConfig = settings.getLoggingConfiguration();
+
+                if ( logkitConfig != null ) {
+                    Source source = null;
+                    try {
+                        source = resolver.resolveURI(logkitConfig);
+                        final ConfigurationBuilder builder = new ConfigurationBuilder(
+                                settings);
+                        final Configuration conf = builder.build(source.getInputStream());
+                        final DefaultConfiguration categories = (DefaultConfiguration) conf
+                                .getChild("categories");
+                        final DefaultConfiguration targets = (DefaultConfiguration) conf
+                                .getChild("targets");
+                        final DefaultConfiguration factories = (DefaultConfiguration) conf
+                                .getChild("factories");
+    
+                        // now process includes
+                        final Configuration[] children = conf
+                                .getChildren("include");
+                        for (int i = 0; i < children.length; i++) {
+                            String directoryURI = children[i].getAttribute("dir");
+                            final String pattern = children[i].getAttribute(
+                                    "pattern", null);
+                            int[] parsedPattern = null;
+                            if (pattern != null) {
+                                parsedPattern = WildcardHelper
+                                        .compilePattern(pattern);
+                            }
+                            Source directory = null;
+                            try {
+                                directory = resolver.resolveURI(directoryURI,
+                                        source.getURI(), CONTEXT_PARAMETERS);
+                                if (directory instanceof TraversableSource) {
+                                    final Iterator c = ((TraversableSource) directory)
+                                            .getChildren().iterator();
+                                    while (c.hasNext()) {
+                                        final Source s = (Source) c.next();
+                                        if (parsedPattern == null
+                                                || this.match(s.getURI(),
+                                                        parsedPattern)) {
+                                            final Configuration includeConf = builder
+                                                    .build(s.getInputStream());
+                                            // add targets and categories
+                                            categories.addAllChildren(includeConf
+                                                    .getChild("categories"));
+                                            targets.addAllChildren(includeConf
+                                                    .getChild("targets"));
+                                            factories.addAllChildren(includeConf
+                                                    .getChild("factories"));
+                                        }
+                                    }
+                                } else {
+                                    throw new ConfigurationException(
+                                            "Include.dir must point to a directory, '"
+                                                    + directory.getURI()
+                                                    + "' is not a directory.'");
+                                }
+                            } catch (IOException ioe) {
+                                throw new ConfigurationException(
+                                        "Unable to read configurations from "
+                                                + directoryURI);
+                            } finally {
+                                resolver.release(directory);
+                            }
+    
+                            // finally remove include
+                            ((DefaultConfiguration) conf).removeChild(children[i]);
+                        }
+                        // override log level?
+                        if (settings.getOverrideLogLevel() != null) {
+                            this.overrideLogLevel(conf.getChild("categories"),
+                                    settings.getOverrideLogLevel());
+                        }
+                        ContainerUtil.configure(loggerManager, conf);
+                    } finally {
+                        resolver.release(source);
+                    }
+                }
+            }
+            ContainerUtil.initialize(loggerManager);
+        } catch (Exception e) {
+            bootstrapLogger.error(
+                    "Could not set up Cocoon Logger, will use screen instead",
+                    e);
+        }
+
+        this.log = this.loggerManager.getLoggerForCategory(accesslogger);
+    }
+
+    /**
+     * Create a new logger manager.
+     * @param loggerManagerClass The class name or one of the allowed shortcuts.
+     * @return A new logger manager.
+     */
+    private LoggerManager newLoggerManager(String loggerManagerClass) {
+        if ("LogKit".equalsIgnoreCase(loggerManagerClass) || loggerManagerClass == null) {
+            loggerManagerClass = CocoonLogKitLoggerManager.class.getName();
+        } else if ("LOG4J".equalsIgnoreCase(loggerManagerClass)) {
+            loggerManagerClass = Log4JConfLoggerManager.class.getName();
+        }
+        try {
+            Class clazz = Class.forName(loggerManagerClass);
+            if ( PerRequestLoggerManager.class.isAssignableFrom(clazz) ) {
+            }
+            return (LoggerManager) clazz.newInstance();
+        } catch (Exception e) {
+            return new CocoonLogKitLoggerManager();
+        }
+    }
+
+    public void overrideLogLevel(Configuration root, String value) {
+        Configuration[] c = root.getChildren("category");
+        for(int i=0;i<c.length;i++) {
+            ((DefaultConfiguration)c[i]).setAttribute("log-level", value);
+            this.overrideLogLevel(c[i], value);
+        }
+    }
+
+    private boolean match(String uri, int[] parsedPattern ) {
+        int pos = uri.lastIndexOf('/');
+        if ( pos != -1 ) {
+            uri = uri.substring(pos+1);
+        }
+        return WildcardHelper.match(null, uri, parsedPattern);
+    }
+
+    public Logger getCocoonLogger() {
+        final String rootlogger = this.settings.getCocoonLogger();
+        if (rootlogger != null) {
+            return this.loggerManager.getLoggerForCategory(rootlogger);
+        }
+        return this.log;
+    }
+    
+    public LoggerManager getCocoonLoggerManager() {
+    	return this.loggerManager;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/core-components.xconf b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/core-components.xconf
new file mode 100644
index 0000000..74b2d9c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/blocks/core-components.xconf
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<components>
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <source-resolver/>
+
+  <fam/>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+</components>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/Cache.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/Cache.java
new file mode 100644
index 0000000..2721567
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/Cache.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.Serializable;
+
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * This is the Cocoon cache. This component is responsible for storing
+ * and retrieving cached responses. It can be used to monitor the cache
+ * or to investigate which responses are cached etc.
+ * This interface will grow!
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public interface Cache {
+
+    /** The Avalon Role **/
+    String ROLE = Cache.class.getName();
+
+    /**
+     * Store a cached response
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     * @param response    the cached response
+     */
+    void store(Serializable     key,
+               CachedResponse   response)
+    throws ProcessingException;
+
+    /**
+     * Get a cached response.
+     * If it is not available <code>null</code> is returned.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    CachedResponse get(Serializable key);
+
+    /**
+     * Remove a cached response.
+     * If it is not available no operation is performed.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    void remove(Serializable key);
+    
+    /**
+     * clear cache of all cached responses 
+     */
+    void clear();
+
+    /**
+     * See if a response is cached under this key.
+     */
+    boolean containsKey(Serializable key);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CacheableProcessingComponent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CacheableProcessingComponent.java
new file mode 100644
index 0000000..803ceea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CacheableProcessingComponent.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import org.apache.excalibur.source.SourceValidity;
+import java.io.Serializable;
+
+/**
+ * This interface declares a (sitemap) component as cacheable.
+ * This interface deprecates the org.apache.cocoon.caching.Cacheable interface!
+ * <p>
+ * Just about everything can be cached, so it makes sense to provide some
+ * controls to make sure that the user always gets valid results. There are
+ * two aspects to a cacheable component: the key and the validition. The key
+ * is used to determine within the component's scheme of things whether a
+ * result is unique. For example, if your generator provides dynamic
+ * information based on an ID and a user, you want to combine the two elements
+ * into one key. That way Cocoon can determine whether to use the cached
+ * information for the given ID/User combination or create it from scratch.
+ * </p>
+ * <p>
+ * The CachingPipeline will check the component's key to see if it even has
+ * the information cached to begin with. Next, it will check the validity of
+ * the cached value if there is one. If the cache has the resource and it is
+ * valid, the CachingPipeline will return the cached results. If either
+ * condition is false, then the CachingPipeline will generate the results and
+ * cache it for later use. It is important to realize that only the
+ * <code>CachingPipeline</code> will respect the contracts defined in this
+ * interface.
+ * </p>
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public interface CacheableProcessingComponent {
+
+    /**
+     * Generate the unique key for the resource being rendered.
+     * <p>
+     * The cache key is the single most important part of the caching
+     * implementation. If you don't get it right, you can introduce more load
+     * on the caching engine than is necessary. It is important that the cache
+     * key has the following attributes:
+     * </p>
+     * <ul>
+     * <li>It must be Serializable (part of the contract of this method).</li>
+     * <li>It must be Immutable--the key is used as a lookup value.</li>
+     * <li>It must be Unique within the space of the component (i.e. the key
+     *     "1" for MyCacheableComponent must be for the same resource every
+     *     time, but we don't have to worry about the key "1" for
+     *     YourCacheableComponent).</li>
+     * <li>The equals() and hashCode() methods must be consistent (i.e. if two
+     *     keys are equal, the hashCode must also be equal).</li>
+     * </ul>
+     * <p>
+     * Thankfully there is a perfectly suitable object that satisfies these
+     * obligations from Java's core: <code>java.lang.String</code>. You can
+     * also use your own specific key objects provided they respect the above
+     * contracts.
+     * </p>
+     * <p>
+     * <strong>Important:</strong>If the cache key is <code>null</code> then
+     * your component will not be cached at all. You can use this to your
+     * advantage to cache some things but not others.
+     * </p>
+     *
+     * @return The generated key or <code>null</code> if the component
+     *              is currently not cacheable.
+     */
+    Serializable getKey();
+
+    /**
+     * Generate the validity object.  This method is invoked after the
+     * <code>getKey()</code> method.
+     * <p>
+     * The caching contracts use the Excalibur <code>SourceValidity</code>
+     * interface to determine whether a resource is valid or not. The validity
+     * can be a compound check that incorporates time since creation, parameter
+     * values, etc. As long as the sitemap can determine whether the cached
+     * resource is valid or not. More information is available on the 
+     * <a href="http://excalibur.apache.org/sourceresolve/index.html">Apache
+     * Excalibur site</a>. 
+     * </p>
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    SourceValidity getValidity();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachedResponse.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachedResponse.java
new file mode 100644
index 0000000..3efe191
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachedResponse.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.Serializable;
+
+import org.apache.excalibur.source.SourceValidity;
+
+/**
+ * This is a cached response. This can either contain a byte array with
+ * the complete character response or a byte array with compiled SAX events.
+ *
+ * This class replaces the <code>CachedEventObject</code> and the
+ * <code>CachedStreamObject</code>.
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class CachedResponse
+        implements Serializable {
+
+    protected final SourceValidity[] validityObjects;
+    protected final byte[]           response;
+    protected Long                   expires;
+    protected final long             lastModified;
+    protected String                 contentType;
+    
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObjects The SourceValidity objects in the order
+     *                        they occured in the pipeline
+     * @param response        The cached sax stream or character stream
+     */
+    public CachedResponse(SourceValidity[] validityObjects,
+                          byte[]           response) {
+        this(validityObjects, response, null);
+    }
+
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObject  The SourceValidity object 
+     * @param response        The cached sax stream or character stream
+     */
+    public CachedResponse(SourceValidity   validityObject,
+                          byte[]           response) {
+        this(new SourceValidity[] {validityObject}, response, null);
+    }
+
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObjects The SourceValidity objects in the order
+     *                        they occured in the pipeline
+     * @param response        The cached sax stream or character stream
+     * @param expires         The configured expires, or null if no
+     *                        expires was defined.
+     */
+    public CachedResponse(SourceValidity[] validityObjects,
+                          byte[]           response,
+                          Long expires) {
+        this.validityObjects = validityObjects;
+        this.response = response;
+        this.expires = expires;
+        this.lastModified = this.setLastModified(System.currentTimeMillis());
+    }
+
+    /**
+     * Get the validity objects
+     */
+    public SourceValidity[] getValidityObjects() {
+        return this.validityObjects;
+    }
+
+    /**
+     * Get the cached response.
+     *
+     * @return The sax stream or character stream
+     */
+    public byte[] getResponse() {
+        return this.response;
+    }
+
+    /**
+     * Get the configured expires.
+     *
+     * @return The configured expires, or null if no expires was defined
+     */
+    public Long getExpires() {
+        return this.expires;
+    }
+    
+    /**
+     * Set the (newly) configured expires.
+     * 
+     */
+    public void setExpires(Long newExpires) {
+        this.expires = newExpires;    
+    }
+    
+    /**
+     * Set the (newly) configured last modified.
+     * 
+     */
+    protected long setLastModified(long lastModified) {
+        // Return the value rounded to the nearest second.
+        return lastModified - (lastModified % 1000);
+    }
+    
+    /**
+     * @return the last modified time 
+     */
+    public long getLastModified() {
+        return lastModified;
+    }
+
+    /**
+     * @return Returns the cached content type (or null).
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+    /**
+     * @param value The content type to cache.
+     */
+    public void setContentType(String value) {
+        this.contentType = value;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachingOutputStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachingOutputStream.java
new file mode 100644
index 0000000..923af73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/CachingOutputStream.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This is an {@link OutputStream} which forwards all received bytes to another
+ * output stream and in addition caches all bytes, thus acting like a
+ * TeeOutputStream.
+ *
+ * @version $Id$
+ */
+public final class CachingOutputStream
+extends OutputStream {
+
+    private OutputStream receiver;
+
+    /** The buffer for the compile xml byte stream. */
+    private byte buf[];
+
+    /** The number of valid bytes in the buffer. */
+    private int bufCount;
+
+    public CachingOutputStream(OutputStream os) {
+        this.receiver = os;
+        this.buf = new byte[1024];
+        this.bufCount = 0;
+    }
+
+    public byte[] getContent() {
+        byte newbuf[] = new byte[this.bufCount];
+        System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+        return newbuf;
+    }
+
+    public void write(int b) throws IOException {
+        this.receiver.write(b);
+        int newcount = this.bufCount + 1;
+        if (newcount > this.buf.length) {
+            byte newbuf[] = new byte[Math.max(this.buf.length << 1, newcount)];
+            System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+            this.buf = newbuf;
+        }
+        this.buf[this.bufCount] = (byte)b;
+        this.bufCount = newcount;
+    }
+
+    public void write( byte b[] ) throws IOException {
+        this.write(b, 0, b.length);
+    }
+
+    public void write(byte b[], int off, int len) throws IOException {
+        this.receiver.write(b, off, len);
+        if (len == 0) return;
+        int newcount = this.bufCount + (len-off);
+        if (newcount > this.buf.length) {
+            byte newbuf[] = new byte[Math.max(this.buf.length << 1, newcount)];
+            System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+            this.buf = newbuf;
+        }
+        System.arraycopy(b, off, this.buf, this.bufCount, len);
+        this.bufCount = newcount;
+    }
+
+    public void flush() throws IOException {
+        this.receiver.flush();
+    }
+
+    public void close() throws IOException {
+        this.receiver.close();
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/ComponentCacheKey.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/ComponentCacheKey.java
new file mode 100644
index 0000000..899441a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/ComponentCacheKey.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.Serializable;
+/**
+ * This is the cache key for one sitemap component.
+ * It consists of three parts:<br/>
+ * a.) The component type (generator, transformer etc.)<br/>
+ * b.) The component identifier - a unique handle for the sitemap
+ *      component<br/>
+ * c.) The cache key - a key, generated by the component, which
+ *      is unique inside the components space.
+ *
+ * @version $Id$
+ */
+public final class ComponentCacheKey
+    implements Serializable {
+
+    public static final int ComponentType_Generator   = 1;
+    public static final int ComponentType_Transformer = 3;
+    public static final int ComponentType_Serializer  = 5;
+    public static final int ComponentType_Reader      = 7;
+
+    // Converts Generator / Transformer / Serializer / Reader constants above
+    // into string.
+    private static final String[] COMPONENTS = { "X", "G", "X", "T", "X", "S", "X", "R" };
+
+    /** The component type */
+    private final int type;
+    /** The component identifier */
+    private final String identifier;
+    /** The unique key */
+    private final Serializable key;
+    /** the hash code */
+    private final int hashCode;
+    /** cachePoint */
+    private final boolean cachePoint;
+
+    /**
+     * Constructor
+     */
+    public ComponentCacheKey(int          componentType,
+                             String       componentIdentifier,
+                             Serializable cacheKey) {
+        this(componentType, componentIdentifier, cacheKey, false);
+    }
+
+    /**
+     * alternate cachepoint Constructor
+     */
+    public ComponentCacheKey(int          componentType,
+                             String       componentIdentifier,
+                             Serializable cacheKey,
+			     boolean cachePoint) {
+        this.type = componentType;
+        this.identifier = componentIdentifier;
+        this.key = cacheKey;
+        /** cachePoint */
+        this.cachePoint = cachePoint;
+        this.hashCode = this.type +
+                (this.identifier.length() << 3) +
+                this.key.hashCode();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof ComponentCacheKey) {
+            ComponentCacheKey ccp = (ComponentCacheKey)object;
+            if (this.type == ccp.type
+                && this.identifier.equals(ccp.identifier)
+                && this.key.equals(ccp.key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * HashCode
+     */
+    public int hashCode() {
+        return this.hashCode;
+    }
+
+    private String toString;
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            toString = COMPONENTS[this.type] + '-' + this.identifier + '-' + this.key.toString();
+        }
+        return toString;
+    }
+
+    /**
+     * Check if we are a cachepoint 
+     */
+    public boolean isCachePoint() {
+        return cachePoint;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/IdentifierCacheKey.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/IdentifierCacheKey.java
new file mode 100644
index 0000000..c22fe6b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/IdentifierCacheKey.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.Serializable;
+
+/**
+ * This is a "simple" cache key that does not consider the components used in the
+ * pipeline. It simply consists of a key (unique identifier for the request) and
+ * a boolean value that defines if the key is for a complete pipeline call or
+ * for an internal pipeline call.
+ *
+ * @version $Id$
+ * @since 2.1.1
+ */
+public class IdentifierCacheKey
+    implements Serializable {
+
+    /** The key */
+    final protected String key;
+
+    /** Is this an external pipeline call? */
+    final protected boolean external;
+
+    /** cache key */
+    final protected String cacheKey;
+    
+    /** cache toString() */
+    protected String toString;
+    
+    /**
+     * Constructor
+     */
+    public IdentifierCacheKey(String key, boolean external) {
+        this.key = key;
+        this.external = external;
+        final StringBuffer buf = new StringBuffer();
+        buf.append(this.external).append(':').append(this.key);
+        this.cacheKey = buf.toString();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof IdentifierCacheKey) {
+            IdentifierCacheKey pck = (IdentifierCacheKey)object;
+            return this.cacheKey.equals( pck.cacheKey );
+        }
+        return false;
+    }
+
+    /**
+     * Generate a hash code
+     */
+    public int hashCode() {
+        return this.cacheKey.hashCode();
+    }
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            StringBuffer buffer = new StringBuffer();
+            buffer.append("IK:");
+            buffer.append(this.cacheKey);
+            this.toString = buffer.toString();
+        }
+        return toString;
+    }
+    
+    /**
+     * The cache key
+     */
+    public String getKey() {
+        return this.key;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/PipelineCacheKey.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/PipelineCacheKey.java
new file mode 100644
index 0000000..480f905
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/PipelineCacheKey.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the cache key for one pipeline (or the first part of a pipeline).
+ * It consists of one or more {@link ComponentCacheKey}s.
+ *
+ * @version $Id$
+ */
+public final class PipelineCacheKey
+        implements Serializable {
+
+    /** The keys */
+    private final List keys;
+
+    /** the hash code */
+    private int hashCode;
+
+    /**
+     * Constructor
+     */
+    public PipelineCacheKey() {
+        this.keys = new ArrayList(6);
+    }
+
+    /**
+     * Constructor
+     */
+    public PipelineCacheKey(int size) {
+        this.keys = new ArrayList(size);
+    }
+
+    /**
+     * Add a key
+     */
+    public void addKey(ComponentCacheKey key) {
+        this.keys.add(key);
+        this.hashCode = 0;
+        this.toString = null;
+    }
+
+    /**
+     * Remove the last key
+     */
+    public void removeLastKey() {
+        this.keys.remove(this.keys.size()-1);
+        this.hashCode = 0;
+        this.toString = null;
+    }
+
+    /**
+     * Remove unitl cachepoint (including cachePoint) 
+     */
+    public void removeUntilCachePoint() {
+        this.hashCode = 0;
+        this.toString = null;
+        int keyCount = this.keys.size();
+
+        while (keyCount > 0) {
+            if (((ComponentCacheKey)this.keys.get(keyCount-1)).isCachePoint()) {
+                this.keys.remove(keyCount-1);
+                return;
+            }
+            this.keys.remove(keyCount-1);
+            keyCount--;
+        }
+    }
+
+    /**
+     * Return the number of keys
+     */
+    public int size() {
+        return this.keys.size();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof PipelineCacheKey) {
+            PipelineCacheKey pck = (PipelineCacheKey)object;
+            final int len = this.keys.size();
+            if (pck.keys.size() == len) {
+                boolean cont = true;
+                int i = 0;
+                while (i < len && cont) {
+                    cont = this.keys.get(i).equals(pck.keys.get(i));
+                    i++;
+                }
+                return cont;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Generate a hash code
+     */
+    public int hashCode() {
+        if (this.hashCode == 0) {
+            final int len = this.keys.size();
+            for(int i=0; i < len; i++) {
+                this.hashCode += this.keys.get(i).hashCode();
+            }
+            if (len % 2 == 0) this.hashCode++;
+        }
+        return this.hashCode;
+    }
+
+    /**
+     * Clone the object (but not the component keys)
+     */
+    public PipelineCacheKey copy() {
+        final int len = this.keys.size();
+        PipelineCacheKey pck = new PipelineCacheKey(len);
+        for(int i=0; i < len; i++) {
+            pck.keys.add(this.keys.get(i));
+        }
+        return pck;
+    }
+
+    private String toString;
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            StringBuffer buffer = new StringBuffer();
+            buffer.append("PK");
+            final int len = this.keys.size();
+            for(int i=0; i < len; i++) {
+                buffer.append('_').append(this.keys.get(i).toString());
+            }
+            this.toString = buffer.toString();
+        }
+        return toString;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/impl/CacheImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/impl/CacheImpl.java
new file mode 100644
index 0000000..ba8b48f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/caching/impl/CacheImpl.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.caching.impl;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.Cache;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.excalibur.store.Store;
+
+/**
+ * This is the Cocoon cache. This component is responsible for storing
+ * and retrieving cached responses. It can be used to monitor the cache
+ * or the investigate which responses are cached etc.
+ * This component will grow!
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class CacheImpl
+extends AbstractLogEnabled
+implements Cache, ThreadSafe, Serviceable, Disposable, Parameterizable {
+
+    /** The store containing the cached responses */
+    protected Store store;
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    /**
+     * Serviceable Interface
+     */
+    public void service (ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Disposable Interface
+     */
+    public void dispose() {
+        this.manager.release(this.store);
+        this.store = null;
+        this.manager = null;
+    }
+
+    /**
+     * Store a cached response
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     * @param response    the cached response
+     */
+    public void store(Serializable     key,
+                      CachedResponse   response)
+    throws ProcessingException {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Caching new response for " + key);
+        }
+        try {
+            this.store.store(key, response);
+        } catch (IOException ioe) {
+            throw new ProcessingException("Unable to cache response.", ioe);
+        }
+    }
+
+    /**
+     * Get a cached response.
+     * If it is not available <code>null</code> is returned.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    public CachedResponse get(Serializable key) {
+        final CachedResponse r = (CachedResponse)this.store.get(key);
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Cached response for " + key + " : " + 
+                                   (r == null ? "not found" : "found"));
+        }
+        return r;
+    }
+
+    /**
+     * Remove a cached response.
+     * If it is not available no operation is performed.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    public void remove(Serializable key) {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Removing cached response for " + key); 
+        }
+        this.store.remove(key);
+    }
+
+    /**
+     * clear cache of all cached responses 
+     */
+    public void clear() {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Clearing cache"); 
+        }
+        // FIXME this clears the whole store!
+        this.store.clear();
+    }
+
+	/**
+	 * See if a response is cached under this key
+	 */
+	public boolean containsKey(Serializable key) {
+		return this.store.containsKey(key);
+	}
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+        String storeName = parameters.getParameter("store", Store.ROLE);
+        try {
+            this.store = (Store)this.manager.lookup(storeName);
+        } catch (ServiceException e) {
+            throw new ParameterException("Unable to lookup store: " + storeName, e);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.properties b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.properties
new file mode 100644
index 0000000..e25f955
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.properties
@@ -0,0 +1,28 @@
+# ------ System Properties -----------------------------------------------------
+
+# Copyright 1999-2005 The Apache Software Foundation
+#
+# Licensed 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.
+
+
+# WARNING: you shouldn't need to modify anything below here since there is a
+# very high chance of breaking the build system. Do it only if you know what
+# you're doing.
+
+version=2.2.0-dev
+released.version=2.1.7
+year=1999-2005
+name=cocoon
+Name=Cocoon
+fullname=Apache Cocoon
+build.info=@date@ (TargetVM=@target.vm@, SourceVM=@source.vm@, Debug=@compiler.debug@, Optimize=@compiler.optimize@)
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.roles b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.roles
new file mode 100644
index 0000000..62fa224
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/cocoon.roles
@@ -0,0 +1,241 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<!DOCTYPE role-list [
+<!ELEMENT role-list (role+)>
+<!ELEMENT role (hint*)>
+<!ELEMENT hint EMPTY>
+<!ATTLIST role-list cocoon-version CDATA #IMPLIED
+>
+<!ATTLIST role name CDATA #REQUIRED
+               shorthand CDATA #REQUIRED
+               default-class CDATA #IMPLIED
+>
+<!ATTLIST hint shorthand CDATA #REQUIRED
+               class CDATA #REQUIRED
+>
+]>
+
+<!-- Roles for the cocoon core. The "cocoon-version" attribute is used by the Cocoon build system
+     for shared blocks, that should add their roles here in 2.1 but not in 2.2 -->
+<role-list cocoon-version = '2.2'>
+  <role name="org.apache.cocoon.components.classloader.ClassLoaderFactory"
+        default-class="org.apache.cocoon.components.classloader.DefaultClassLoaderFactory"/>
+
+  <role name="org.apache.excalibur.source.SourceFactorySelector"
+        shorthand="source-factories"
+        default-class="org.apache.cocoon.core.container.DefaultServiceSelector">
+  </role>
+
+  <role name="org.apache.excalibur.source.SourceResolver"
+        shorthand="source-resolver"
+        default-class="org.apache.cocoon.components.source.CocoonSourceResolver"/>
+
+  <!-- The entity resolver used by most parsers -->
+  <role name="org.apache.excalibur.xml.EntityResolver"
+        shorthand="entity-resolver"
+        default-class="org.apache.cocoon.components.resolver.DefaultResolver"/>
+
+  <!-- Parser:
+
+       Starting with Cocoon 2.1 we have a bunch of different parser:
+       - a SAX parser (producing SAX events)
+       - a DOM parser (producint a document)
+       - an HTML parser (producing SAX events from an HTML document)
+       ...
+  -->
+
+  <!-- This is the usual SAX parser -->
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <!-- This is the usual DOM parser -->
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <!-- A Dom Serializer -->
+  <role default-class="org.apache.excalibur.xml.dom.DefaultDOMSerializer" name="org.apache.excalibur.xml.dom.DOMSerializer" shorthand="dom-serializer"/>
+
+  <!-- XSLT: -->
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.cocoon.components.xslt.TraxProcessor"/>
+
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <!-- Stores: -->
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="store"
+       default-class="org.apache.cocoon.components.store.impl.EHDefaultStore"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.cocoon.components.store.impl.DefaultTransientStore"/>
+
+<!--
+  The persistent store is only an auxiliary store that shouldn't be
+  used by Cocoon users. It should only be used - if required - by
+  the Store. If we use JCS, we don't need a persistent store.
+  <role name="org.apache.excalibur.store.Store/PersistentStore"
+        shorthand="persistent-store"
+        default-class="org.apache.cocoon.components.store.impl.DefaultPersistentStore"/>
+-->
+  <!-- Normally uses the org.apache.excalibur.store.impl.StoreJanitorImpl as
+       the default-class but as that uses its own Thread spawning there is
+       the org.apache.cocoon.components.store.impl.CocoonStoreJanitor class
+       to use a daemon thread from the org.apache.cocoon.components.thread.RunnableManager
+       component 
+       NOT: As soon as our patch has been accepted by the Excalibur community and an
+            excalibur-store has been release we can switch back to the original 
+            org.apache.excalibur.store.impl.StoreJanitorImpl class
+  -->
+  <role name="org.apache.excalibur.store.StoreJanitor"
+       shorthand="store-janitor"
+       default-class="org.apache.cocoon.components.store.impl.CocoonStoreJanitor"/>
+
+  <!--=========================================================================
+       Sitemap engine
+      =========================================================================-->
+
+  <!-- the sitemap engine -->
+  <role name="org.apache.cocoon.Processor"
+        shorthand="sitemap"
+        default-class="org.apache.cocoon.components.treeprocessor.TreeProcessor"/>
+  
+  <!-- the tree builder for the sitemap language (additional implementations can be added here
+       or in cocoon.xconf for other implementations) -->
+  <role name="org.apache.cocoon.components.treeprocessor.TreeBuilder/sitemap-1.0"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.SitemapLanguage"/>
+
+  <!-- the various elements of map:components -->
+  <role name="org.apache.cocoon.components.pipeline.ProcessingPipelineSelector"
+        shorthand="pipes"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+
+  <role name="org.apache.cocoon.acting.ActionSelector"
+        shorthand="actions"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.generation.GeneratorSelector"
+        shorthand="generators"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.transformation.TransformerSelector"
+        shorthand="transformers"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.serialization.SerializerSelector"
+        shorthand="serializers"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+      
+  <role name="org.apache.cocoon.reading.ReaderSelector"
+        shorthand="readers"
+        default-class="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsSelector"/>
+          
+  <role name="org.apache.cocoon.components.notification.NotifyingBuilder"
+        shorthand="notifying-builder"
+        default-class="org.apache.cocoon.components.notification.DefaultNotifyingBuilder"
+        model="non-thread-safe-pooled"/>  
+
+  <!-- system-defined sitemap components -->
+  <role name="org.apache.cocoon.generation.Generator/&lt;notifier&gt;"
+        default-class="org.apache.cocoon.generation.NotifyingGenerator"
+        model="non-thread-safe-pooled"/>
+        
+  <role name="org.apache.cocoon.generation.Generator/&lt;aggregator&gt;"
+        default-class="org.apache.cocoon.sitemap.DefaultContentAggregator"
+        model="non-thread-safe-pooled"/>
+
+  <role name="org.apache.cocoon.transformation.Transformer/&lt;translator&gt;"
+        default-class="org.apache.cocoon.sitemap.LinkTranslator"
+        model="non-thread-safe-pooled"/>
+
+  <role name="org.apache.cocoon.transformation.Transformer/&lt;gatherer&gt;"
+        default-class="org.apache.cocoon.sitemap.LinkGatherer"
+        model="non-thread-safe-pooled"/>
+	
+  <!--=========================================================================-->
+  
+  <role name="org.apache.cocoon.components.fam.SitemapMonitor"
+        shorthand="fam"
+        default-class="org.apache.cocoon.components.fam.SitemapMonitorImpl"/>
+        
+  <role name="org.apache.cocoon.components.image.ImageEncoderSelector"
+        shorthand="image-encoder"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.cocoon.components.notification.NotifyingBuilder"
+        shorthand="notifying-builder"
+        default-class="org.apache.cocoon.components.notification.DefaultNotifyingBuilder"/>
+
+  <role name="org.apache.cocoon.caching.Cache"
+        shorthand="cache"
+        default-class="org.apache.cocoon.caching.impl.CacheImpl"/>
+
+  <!-- i18n components for resource bundle handling -->
+  <role name="org.apache.cocoon.i18n.BundleFactory"
+        shorthand="i18n-bundles"
+        default-class="org.apache.cocoon.i18n.XMLResourceBundleFactory"/>
+
+  <!-- Control flow layer: the interpreters selector and continuations  manager -->
+  <role name="org.apache.cocoon.components.flow.InterpreterSelector" 
+        shorthand="flow-interpreters"
+        default-class="org.apache.cocoon.core.container.DefaultServiceSelector"/>
+
+  <role name="org.apache.cocoon.components.flow.ContinuationsManager"
+        shorthand="continuations-manager"
+        default-class="org.apache.cocoon.components.flow.ContinuationsManagerImpl" />
+
+  <!-- input/output modules -->
+  <role name="org.apache.cocoon.components.modules.input.InputModuleSelector"
+        shorthand="input-modules"
+        default-class="org.apache.cocoon.core.container.DefaultServiceSelector"/>
+
+  <role name="org.apache.cocoon.components.modules.output.OutputModuleSelector"
+        shorthand="output-modules"
+        default-class="org.apache.cocoon.core.container.DefaultServiceSelector"/>
+
+  <role name="org.apache.cocoon.components.modules.input.SitemapVariableHolder"
+        shorthand="global-variables"
+        default-class="org.apache.cocoon.components.modules.input.SitemapVariableHolder"/>
+
+  <!-- Storing data in the current request -->
+  <role name="org.apache.cocoon.components.persistence.RequestDataStore"
+        shorthand="request-data-store"
+        default-class="org.apache.cocoon.components.persistence.RequestDataStoreImpl"/>
+  
+  <!-- Running commands (Runnable) in background -->
+  <role name="org.apache.cocoon.components.thread.RunnableManager"
+        shorthand="runnable-manager"
+        default-class="org.apache.cocoon.components.thread.DefaultRunnableManager"/>
+
+</role-list>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ChainedConfiguration.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ChainedConfiguration.java
new file mode 100644
index 0000000..a485fc6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ChainedConfiguration.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * This configuration object is used for {@link SitemapConfigurable} 
+ * components. It 'extends' {@link Configuration} by a parent.
+ * 
+ * @since 2.1
+ * 
+ * @version $Id$
+ */
+public final class ChainedConfiguration implements Configuration {
+
+    private Configuration wrappedConfiguration;
+    
+    private ChainedConfiguration parentConfiguration;
+    
+    /**
+     * Constructor
+     */
+    public ChainedConfiguration(Configuration wrapped,
+                                 ChainedConfiguration parent) {
+        this.wrappedConfiguration = wrapped;
+        this.parentConfiguration = parent;
+    }
+    
+    /** 
+     * Get the parent configuration
+     * @return the parent configuration or null.
+     */
+    public ChainedConfiguration getParent() {
+        return this.parentConfiguration;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttribute(java.lang.String, java.lang.String)
+     */
+    public String getAttribute(String arg0, String arg1) {
+        return this.wrappedConfiguration.getAttribute(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttribute(java.lang.String)
+     */
+    public String getAttribute(String arg0) throws ConfigurationException {
+        return this.wrappedConfiguration.getAttribute(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsBoolean(java.lang.String, boolean)
+     */
+    public boolean getAttributeAsBoolean(String arg0, boolean arg1) {
+        return this.wrappedConfiguration.getAttributeAsBoolean(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsBoolean(java.lang.String)
+     */
+    public boolean getAttributeAsBoolean(String arg0)
+        throws ConfigurationException {
+        return this.wrappedConfiguration.getAttributeAsBoolean(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsFloat(java.lang.String, float)
+     */
+    public float getAttributeAsFloat(String arg0, float arg1) {
+        return this.wrappedConfiguration.getAttributeAsFloat(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsFloat(java.lang.String)
+     */
+    public float getAttributeAsFloat(String arg0)
+        throws ConfigurationException {
+        return this.wrappedConfiguration.getAttributeAsFloat(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsInteger(java.lang.String, int)
+     */
+    public int getAttributeAsInteger(String arg0, int arg1) {
+        return this.wrappedConfiguration.getAttributeAsInteger(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsInteger(java.lang.String)
+     */
+    public int getAttributeAsInteger(String arg0)
+        throws ConfigurationException {
+        return this.wrappedConfiguration.getAttributeAsInteger(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsLong(java.lang.String, long)
+     */
+    public long getAttributeAsLong(String arg0, long arg1) {
+        return this.wrappedConfiguration.getAttributeAsLong(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsLong(java.lang.String)
+     */
+    public long getAttributeAsLong(String arg0) throws ConfigurationException {
+        return this.wrappedConfiguration.getAttributeAsLong(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeNames()
+     */
+    public String[] getAttributeNames() {
+        return this.wrappedConfiguration.getAttributeNames();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getChild(java.lang.String, boolean)
+     */
+    public Configuration getChild(String arg0, boolean arg1) {
+        return this.wrappedConfiguration.getChild(arg0, arg1);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getChild(java.lang.String)
+     */
+    public Configuration getChild(String arg0) {
+        return this.wrappedConfiguration.getChild(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getChildren()
+     */
+    public Configuration[] getChildren() {
+        return this.wrappedConfiguration.getChildren();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getChildren(java.lang.String)
+     */
+    public Configuration[] getChildren(String arg0) {
+        return this.wrappedConfiguration.getChildren(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getLocation()
+     */
+    public String getLocation() {
+        return this.wrappedConfiguration.getLocation();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getName()
+     */
+    public String getName() {
+        return this.wrappedConfiguration.getName();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getNamespace()
+     */
+    public String getNamespace() throws ConfigurationException {
+        return this.wrappedConfiguration.getNamespace();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValue()
+     */
+    public String getValue() throws ConfigurationException {
+        return this.wrappedConfiguration.getValue();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValue(java.lang.String)
+     */
+    public String getValue(String arg0) {
+        return this.wrappedConfiguration.getValue(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsBoolean()
+     */
+    public boolean getValueAsBoolean() throws ConfigurationException {
+        return this.wrappedConfiguration.getValueAsBoolean();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsBoolean(boolean)
+     */
+    public boolean getValueAsBoolean(boolean arg0) {
+        return this.wrappedConfiguration.getValueAsBoolean(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsFloat()
+     */
+    public float getValueAsFloat() throws ConfigurationException {
+        return this.wrappedConfiguration.getValueAsFloat();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsFloat(float)
+     */
+    public float getValueAsFloat(float arg0) {
+        return this.wrappedConfiguration.getValueAsFloat(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsInteger()
+     */
+    public int getValueAsInteger() throws ConfigurationException {
+        return this.wrappedConfiguration.getValueAsInteger();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsInteger(int)
+     */
+    public int getValueAsInteger(int arg0) {
+        return this.wrappedConfiguration.getValueAsInteger(arg0);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsLong()
+     */
+    public long getValueAsLong() throws ConfigurationException {
+        return this.wrappedConfiguration.getValueAsLong();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsLong(long)
+     */
+    public long getValueAsLong(long arg0) {
+        return this.wrappedConfiguration.getValueAsLong(arg0);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsDouble(java.lang.String, double)
+     */
+    public double getAttributeAsDouble(String arg0, double arg1) {
+        return this.wrappedConfiguration.getAttributeAsDouble(arg0, arg1);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configuration#getAttributeAsDouble(java.lang.String)
+     */
+    public double getAttributeAsDouble(String arg0) throws ConfigurationException {
+        return this.wrappedConfiguration.getAttributeAsDouble(arg0);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsDouble()
+     */
+    public double getValueAsDouble() throws ConfigurationException {
+        return this.wrappedConfiguration.getValueAsDouble();
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configuration#getValueAsDouble(double)
+     */
+    public double getValueAsDouble(double arg0) {
+        return this.wrappedConfiguration.getValueAsDouble(arg0);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ComponentInfo.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ComponentInfo.java
new file mode 100644
index 0000000..9f95806
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ComponentInfo.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+/**
+ * Meta-information about a service
+ *  
+ * @version $Id$
+ */
+public final class ComponentInfo {
+
+    public static final int MODEL_UNKNOWN   = -1;
+    public static final int MODEL_PRIMITIVE = 0;
+    public static final int MODEL_SINGLETON = 1;
+    public static final int MODEL_POOLED    = 2;
+    public static final int MODEL_NON_THREAD_SAFE_POOLED = 3;
+
+    public static final String TYPE_SINGLETON = "singleton";
+    public static final String TYPE_POOLED = "pooled";
+    public static final String TYPE_NON_THREAD_SAFE_POOLED = "non-thread-safe-pooled";
+
+    private int model;
+    private String initMethodName;
+    private String destroyMethodName;
+    private String poolInMethodName;
+    private String poolOutMethodName;
+    private String serviceClassName;
+    private Configuration configuration;
+    private String loggerCategory;
+    private String jmxDomain;
+    private String jmxName;
+    private String role;
+
+    public ComponentInfo() {
+        this.model = MODEL_PRIMITIVE;
+    }
+
+    /**
+     * @return Returns the model.
+     */
+    public int getModel() {
+        return model;
+    }
+
+    /**
+     * @param model The model to set.
+     */
+    public void setModel(int model) {
+        this.model = model;
+    }
+
+    /**
+     * @return Returns the destroyMethod.
+     */
+    public String getDestroyMethodName() {
+        return destroyMethodName;
+    }
+
+    /**
+     * @param destroyMethod The destroyMethod to set.
+     */
+    public void setDestroyMethodName(String destroyMethod) {
+        this.destroyMethodName = destroyMethod;
+    }
+
+    /**
+     * @return Returns the initMethod.
+     */
+    public String getInitMethodName() {
+        return initMethodName;
+    }
+
+    /**
+     * @param initMethod The initMethod to set.
+     */
+    public void setInitMethodName(String initMethod) {
+        this.initMethodName = initMethod;
+    }
+
+    /**
+     * @return Returns the poolInMethodName
+     */
+    public String getPoolInMethodName() {
+        return this.poolInMethodName;
+    }
+
+    /**
+     * @param poolMethod The poolInMethod name to set.
+     */
+    public void setPoolInMethodName(String poolMethod) {
+        this.poolInMethodName = poolMethod;
+    }
+
+    /**
+     * @return Returns the poolOutMethodName
+     */
+    public String getPoolOutMethodName() {
+        return this.poolOutMethodName;
+    }
+
+    /**
+     * @param poolMethod The poolOutMethod name to set.
+     */
+    public void setPoolOutMethodName(String poolMethod) {
+        this.poolOutMethodName = poolMethod;
+    }
+
+    /**
+     * @return Returns the serviceClassName.
+     */
+    public String getServiceClassName() {
+        return serviceClassName;
+    }
+
+    /**
+     * @param serviceClassName The serviceClassName to set.
+     */
+    public void setServiceClassName(String serviceClassName) {
+        this.serviceClassName = serviceClassName;
+    }
+
+    /**
+     * @return Returns the configuration.
+     */
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+
+    /**
+     * @param configuration The configuration to set.
+     */
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+    public String getLocation() {
+        return this.configuration.getLocation();
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "ServiceInfo: {class=" + this.getServiceClassName()+"}";
+    }
+
+    public void fill(Configuration attr) {
+        // test model
+        final String model = attr.getAttribute("model", null);
+        if ( TYPE_POOLED.equals(model) ) {
+            this.setModel(ComponentInfo.MODEL_POOLED);
+            this.setPoolInMethodName(attr.getAttribute("pool-in", null));
+            this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
+        } else if (TYPE_NON_THREAD_SAFE_POOLED.equals(model)) {
+            this.setModel(ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED);
+            this.setPoolInMethodName(attr.getAttribute("pool-in", null));
+            this.setPoolOutMethodName(attr.getAttribute("pool-out", null));
+        } else if ( TYPE_SINGLETON.equals(model) ) {
+            this.setModel(ComponentInfo.MODEL_SINGLETON);
+        }
+        // init/destroy methods
+        this.setInitMethodName(attr.getAttribute("init", null));
+        this.setDestroyMethodName(attr.getAttribute("destroy", null));
+        // logging
+        this.setLoggerCategory(attr.getAttribute("logger", null));
+        this.setJmxDomain(attr.getAttribute(CoreServiceManager.JMX_DOMAIN_ATTR_NAME, null));
+        this.setJmxName(attr.getAttribute(CoreServiceManager.JMX_NAME_ATTR_NAME, null));
+        this.setRole(attr.getAttribute("role", null));
+    }
+
+    public ComponentInfo duplicate() {
+        ComponentInfo info = new ComponentInfo();
+        info.model = this.model;
+        info.initMethodName = this.initMethodName;
+        info.destroyMethodName = this.destroyMethodName;
+        info.poolInMethodName = this.poolInMethodName;
+        info.poolOutMethodName = this.poolOutMethodName;
+        info.serviceClassName = this.serviceClassName;
+        info.configuration = this.configuration;
+        info.loggerCategory = this.loggerCategory;
+        info.jmxDomain = this.jmxDomain;
+        info.jmxName = this.jmxName;
+        info.role = this.role;
+
+        return info;
+    }
+
+    /**
+     * @return Returns the loggerCategory.
+     */
+    public String getLoggerCategory() {
+        return this.loggerCategory;
+    }
+
+    /**
+     * @param loggerCategory The loggerCategory to set.
+     */
+    public void setLoggerCategory(String loggerCategory) {
+        this.loggerCategory = loggerCategory;
+    }
+    
+    /**
+     * @return The JMX domain name
+     */
+    public String getJmxDomain() {
+        if (this.jmxDomain == null && this.configuration != null) {
+            this.setJmxDomain(getConfiguration().getAttribute(CoreServiceManager.JMX_DOMAIN_ATTR_NAME, null));
+        }
+        if(this.jmxDomain == null) {
+            return CoreServiceManager.JMX_DEFAULT_DOMAIN_NAME;
+        }
+        return this.jmxDomain;
+    }
+    
+    /**
+     * @param jmxDomain JMX domain name
+     */
+    public void setJmxDomain(final String jmxDomain) {
+        this.jmxDomain = jmxDomain;
+    }
+    
+    /**
+     * @return The JMX object name (without domain prefix)
+     */
+    public String getJmxName() {
+        if (this.jmxName == null && this.configuration != null) {
+            this.setJmxName(getConfiguration().getAttribute(CoreServiceManager.JMX_NAME_ATTR_NAME, null));
+        }
+        return this.jmxName;
+    }
+    
+    /**
+     * @param jmxName JMX object name (without domain prefix)
+     */
+    public void setJmxName(final String jmxName) {
+        this.jmxName = jmxName;
+    }
+
+    /**
+     * @param role The role to set.
+     */
+    public void setRole( String role )
+    {
+        this.role = role;
+    }
+
+    /**
+     * @return Returns the role.
+     */
+    public String getRole()
+    {
+        return role;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextHelper.java
new file mode 100644
index 0000000..8236457
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextHelper.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+
+/**
+ * A set of constants and methods to access the content of the context
+ * object. Some of the constants are defined in {@link org.apache.cocoon.Constants}.
+ *
+ * @version $Id$
+ */
+public final class ContextHelper {
+		
+    /** Application <code>Context</code> Key for the current object model */
+    public static final String CONTEXT_OBJECT_MODEL = "object-model";
+
+    /** Application <code>Context</code> Key for the current request object */
+    public static final String CONTEXT_REQUEST_OBJECT = CONTEXT_OBJECT_MODEL + '.' + ObjectModelHelper.REQUEST_OBJECT;
+
+    /** Application <code>Context</code> Key for the current response object */
+    public static final String CONTEXT_RESPONSE_OBJECT = CONTEXT_OBJECT_MODEL + '.' + ObjectModelHelper.RESPONSE_OBJECT;
+
+    /** Application <code>Context</code> Key for the current sitemap service manager */
+    public static final String CONTEXT_SITEMAP_SERVICE_MANAGER = "sitemap-service-manager";
+    
+    /** Application root directory (as a URL object) @since 2.2 */
+    public static final String CONTEXT_ROOT_URL = "context-root";
+    
+    private ContextHelper() {
+        // Forbid instantiation
+    }
+
+    /**
+     * Return the current request
+     * @param context The component context
+     * @return The request object
+     */
+    public static final Request getRequest(Context context) {
+        // the request object is always present
+        try {
+            return (Request)context.get(CONTEXT_REQUEST_OBJECT);
+        } catch (ContextException ce) {
+            throw new ContextResourceNotFoundException("Unable to get the request object from the context.", ce);
+        }
+    }
+
+    /**
+     * Return the current response
+     * @param context The component context
+     * @return The response
+     */
+    public static final Response getResponse(Context context) {
+        // the response object is always present
+        try {
+            return (Response)context.get(CONTEXT_RESPONSE_OBJECT);
+        } catch (ContextException ce) {
+            throw new ContextResourceNotFoundException("Unable to get the response object from the context.", ce);
+        }
+    }
+
+    /**
+     * Return the current object model
+     * @param context The component context
+     * @return The object model
+     */
+    public static final Map getObjectModel(Context context) {
+        // the object model is always present
+        try {
+            return (Map)context.get(CONTEXT_OBJECT_MODEL);
+        } catch (ContextException ce) {
+            throw new ContextResourceNotFoundException("Unable to get the object model from the context.", ce);
+        }
+    }
+    
+    /**
+     * Return the current sitemap service manager
+     * @param context The component context
+     * @return The sitemap manager if currently a request is processed
+     * @since 2.2
+     */
+    public static final ServiceManager getSitemapServiceManager(Context context) {
+        // the service manager is always present
+        try {
+            return (ServiceManager)context.get(CONTEXT_SITEMAP_SERVICE_MANAGER);
+        } catch (ContextException ce) {
+            throw new ContextResourceNotFoundException("Unable to get the service manager from the context.", ce);
+        }        
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextResourceNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextResourceNotFoundException.java
new file mode 100644
index 0000000..92ea1f3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/ContextResourceNotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+/**
+ * The exception thrown when the ContextHelper can't find the necessary
+ * resource.
+ */
+public final class ContextResourceNotFoundException extends CascadingRuntimeException
+{
+    public ContextResourceNotFoundException(String message)
+    {
+        super(message, null);
+    }
+
+    public ContextResourceNotFoundException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/LifecycleHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/LifecycleHelper.java
new file mode 100644
index 0000000..d405470
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/LifecycleHelper.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * Utility class for setting up Avalon components. Similar to Excalibur's
+ * <code>DefaultComponentFactory</code>, but on existing objects.
+ * <p>
+ *
+ * @version $Id$
+ */
+public class LifecycleHelper {
+
+    /** The Logger for the component
+     */
+    final private Logger logger;
+
+    /** The Context for the component
+     */
+    final private Context context;
+
+    /** The service manager for this component.
+     */
+    final private ServiceManager serviceManager;
+
+    /** The configuration for this component.
+     */
+    final private Configuration configuration;
+
+    /**
+     * Construct a new <code>LifecycleHelper</code> that can be used repeatedly to
+     * setup several components. 
+     * <p>
+     * <b>Note</b> : if a parameter is <code>null</code>,
+     * the corresponding method isn't called (e.g. if <code>configuration</code> is
+     * <code>null</code>, <code>configure()</code> isn't called).
+     *
+     * @param logger the <code>Logger</code> to pass to <code>LogEnabled</code>s, unless there is
+     *        a <code>LogKitManager</code> and the configuration specifies a logger name.
+     * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
+     * @param serviceManager the service manager to pass to <code>Serviceable</code>s.
+     * @param configuration the <code>Configuration</code> object to pass to new instances.
+     */
+    public LifecycleHelper(final Logger logger,
+                           final Context context,
+                           final ServiceManager serviceManager,
+                           final Configuration configuration) {
+        this.logger = logger;
+        this.context = context;
+        this.serviceManager = serviceManager;
+        this.configuration = configuration;
+    }
+
+
+    /**
+     * Setup a component, including initialization and start.
+     *
+     * @param component the component to setup.
+     * @return the component passed in, to allow function chaining.
+     * @throws Exception if something went wrong.
+     */
+    public Object setupComponent(Object component) throws Exception {
+        return setupComponent(component, true);
+    }
+
+    /**
+     * Setup a component, and optionnaly initializes (if it's <code>Initializable</code>)
+     * and starts it (if it's <code>Startable</code>).
+     *
+     * @param component the component to setup.
+     * @param initializeAndStart if true, <code>intialize()</code> and <code>start()</code>
+     *        will be called.
+     * @return the component passed in, to allow function chaining.
+     * @throws Exception if something went wrong.
+     */
+    public Object setupComponent(Object component, boolean initializeAndStart)
+    throws Exception {
+        return setupComponent(
+            component,
+            this.logger,
+            this.context,
+            this.serviceManager,
+            this.configuration,
+            initializeAndStart);
+    }
+
+    /**
+     * Alternative setupComponent method that takes a ServiceManager instead of a ComponentManger.
+     */
+    public static Object setupComponent(final Object component,
+                                         final Logger logger,
+                                         final Context context,
+                                         final ServiceManager serviceManager,
+                                        final Configuration configuration)
+    throws Exception {
+        return setupComponent(
+            component,
+            logger,
+            context,
+            serviceManager,
+            configuration,
+            true);
+    }
+
+    /**
+     * Alternative setupComponent method that takes a ServiceManager instead of a ComponentManger.
+     */
+    public static Object setupComponent(final Object component,
+                                        final Logger logger,
+                                        final Context context,
+                                        final ServiceManager serviceManager,
+                                        final Configuration configuration,
+                                        final boolean initializeAndStart)
+    throws Exception {
+        if (component instanceof LogEnabled) {
+            ((LogEnabled) component).enableLogging(logger);
+        }
+
+        if (null != context && component instanceof Contextualizable) {
+            ((Contextualizable) component).contextualize(context);
+        }
+
+        if (null != serviceManager && component instanceof Serviceable) {
+            ((Serviceable) component).service(serviceManager);
+        } 
+        
+        if (null != configuration && component instanceof Configurable) {
+            ((Configurable) component).configure(configuration);
+        }
+
+        if (null != configuration && component instanceof Parameterizable) {
+            ((Parameterizable) component).parameterize(
+                Parameters.fromConfiguration(configuration));
+        }
+
+        if (initializeAndStart && component instanceof Initializable) {
+            ((Initializable) component).initialize();
+        }
+
+        if (initializeAndStart && component instanceof Startable) {
+            ((Startable) component).start();
+        }
+
+        return component;
+    }
+
+    /**
+     * Decomission a component, by stopping (if it's <code>Startable</code>) and
+     * disposing (if it's <code>Disposable</code>) a component.
+     */
+    public static final void decommission(final Object component)
+    throws Exception {
+        if (component instanceof Startable) {
+            ((Startable) component).stop();
+        }
+
+        dispose(component);
+    }
+
+    /**
+     * Dispose a component if it's <code>Disposable</code>. Otherwhise, do nothing.
+     */
+    public static final void dispose(final Object component) {
+        if (component instanceof Disposable) {
+            ((Disposable) component).dispose();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/Preloadable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/Preloadable.java
new file mode 100644
index 0000000..5d964d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/Preloadable.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+/**
+ * Marker interface for Avalon-managed components that need to be loaded at startup time.
+ * <p>
+ * Components implementing this interface will always be initialized when the service manager that
+ * holds them is created, even if lazy-loading of components is enabled.
+ * <p>
+ * Note that there are also other ways to require a component to be loaded at startup:
+ * <ul>
+ * <li>by implementing the <code>Startable</code> Avalon interface, which defines two additional
+ *     <code>start()</code> and <code>stop()</code> methods</li>
+ * <li>by adding the <code>preload="true"</code> attribute on a component's configuration</li>
+ * </ul>
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public interface Preloadable {
+    // nothing, it's just a marker
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurable.java
new file mode 100644
index 0000000..2770f6d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurable.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * Objects implementing this marker interface can get a configuration
+ * from the map:pipelines section of the sitemap when they are created.
+ * Due to a problem in the component handling the
+ * {@link #configure(SitemapConfigurationHolder)} method is actually called
+ * each time the component is looked up!
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public interface SitemapConfigurable {
+
+    /**
+     * Set the <code>Configuration</code>.
+     */
+    void configure(SitemapConfigurationHolder holder)
+    throws ConfigurationException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurationHolder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurationHolder.java
new file mode 100644
index 0000000..9f73d6f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/SitemapConfigurationHolder.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components;
+
+/**
+ * A {@link SitemapConfigurable} component gets the sitemap configuration
+ * using this object.
+ * 
+ * @since 2.1
+ * 
+ * @version $Id$
+ */
+public interface SitemapConfigurationHolder {
+
+    /**
+     * Get the  configuration for the current sitemap
+     * @return The configuration
+     */
+    ChainedConfiguration getConfiguration();
+    
+    /**
+     * Get the prepared configuration for the current sitemap
+     * @return The configuration or null if no prepared is available
+     */
+    Object getPreparedConfiguration();
+    
+    /**
+     * Set the prepared configuration for the current sitemap.
+     * After it is set by a component, it can be get using
+     * {@link #getPreparedConfiguration()}.
+     * 
+     * @param preparedConfig The prepared configuration
+     */
+    void setPreparedConfiguration(ChainedConfiguration configuration, Object preparedConfig);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java
new file mode 100644
index 0000000..b496039
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ClassLoaderFactory.java
@@ -0,0 +1,32 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.classloader;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * A <code>ClassLoader</code> factory, setting up the classpath given a
+ * &lt;classpath&gt; configuration.
+ * 
+ * @version $Id$
+ */
+public interface ClassLoaderFactory {
+    final static String ROLE = ClassLoaderFactory.class.getName();
+    
+    ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java
new file mode 100644
index 0000000..d510d9e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/DefaultClassLoaderFactory.java
@@ -0,0 +1,268 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.classloader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * Default implementation of {@link ClassLoaderFactory}. It accepts both class directory and jar
+ * directory configurations.
+ * <p>
+ * Wildcard patterns can also be specified to include or exclude some classes to be loaded in the
+ * classloader. In such case, the class is directly loaded from the parent classloader. The default
+ * is to include all classes.
+ * <p>
+ * Example:
+ * <pre>
+ * &lt;classpath&gt;
+ *   &lt;class-dir src="BLOCK-INF/classes"/&gt;
+ *   &lt;lib-dir src="BLOCK-INF/lib"/&gt;
+ *   &lt;include-classes pattern="org.apache.cocoon.**"/&gt;
+ *   &lt;exclude-classes pattern="org.apache.cocoon.transformation.**"/&gt;
+ * &/lt;classpath&gt;
+ * </pre>
+ */
+public class DefaultClassLoaderFactory extends AbstractLogEnabled implements ClassLoaderFactory,
+    Serviceable, ThreadSafe, Disposable {
+
+    private ServiceManager manager;
+    private SourceResolver resolver;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+    }
+    
+    private void ensureIsDirectory(Source src, String location) throws ConfigurationException {
+        if (!src.exists()) {
+            throw new ConfigurationException(src.getURI() + " doesn't exist, at " + location);
+        } else if (!(src instanceof TraversableSource) || !((TraversableSource)src).isCollection()) {
+            throw new ConfigurationException(src.getURI() + " is not a directory, at " + location);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.ClassLoaderFactory#createClassLoader(java.lang.ClassLoader)
+     */
+    public ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException {
+        List urlList = new ArrayList();
+        List includeList = new ArrayList();
+        List excludeList = new ArrayList();
+        Configuration[] children = config.getChildren();
+        for (int i = 0; i < children.length; i++) {
+            Configuration child = children[i];
+            String name = child.getName();
+            Source src = null;
+            try {
+                // A class dir: simply add its URL
+                if ("class-dir".equals(name)) {
+                    src = resolver.resolveURI(child.getAttribute("src"));
+                    ensureIsDirectory(src, child.getLocation());
+                    urlList.add(new URL(src.getURI()));
+                    resolver.release(src);
+                    src = null;
+                
+                // A lib dir: scan for all jar and zip it contains
+                } else if ("lib-dir".equals(name)) {
+                    src = resolver.resolveURI(child.getAttribute("src"));
+                    ensureIsDirectory(src, child.getLocation());
+                    Iterator iter = ((TraversableSource)src).getChildren().iterator();
+                    while (iter.hasNext()) {
+                        Source childSrc = (Source)iter.next();
+                        String childURI = childSrc.getURI();
+                        resolver.release(childSrc);
+                        if (childURI.endsWith(".jar") || childURI.endsWith(".zip")) {
+                            urlList.add(new URL(childURI));
+                        }
+                    }
+                    resolver.release(src);
+                    src = null;
+                } else if  ("include-classes".equals(name)) {
+                    includeList.add(WildcardHelper.compilePattern(child.getAttribute("pattern")));
+                } else if ("exclude-classes".equals(name)) {
+                    excludeList.add(WildcardHelper.compilePattern(child.getAttribute("pattern")));
+                } else {
+                    throw new ConfigurationException("Unexpected element " + name + " at " + child.getLocation());
+                }
+            } catch(ConfigurationException ce) {
+                resolver.release(src);
+                throw ce;
+            } catch(Exception e) {
+                resolver.release(src);
+                throw new ConfigurationException("Error loading " + name + " at " + child.getLocation(), e);
+            }
+        }
+        
+        URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
+        int[][] includes = includeList.isEmpty() ? null : (int[][])includeList.toArray(new int[includeList.size()][]);
+        int[][] excludes = excludeList.isEmpty() ? null : (int[][])excludeList.toArray(new int[excludeList.size()][]);
+        
+        return new DefaultClassLoader(urls, includes, excludes, parent);
+    }
+
+    public static class DefaultClassLoader extends URLClassLoader {
+        
+        private final int[][] includes;
+        private final int[][] excludes;
+
+        /**
+         * Alternate constructor to define a parent and initial <code>URL</code>
+         * s.
+         */
+        public DefaultClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
+            this(urls, includes, excludes, parent, null);
+        }
+
+        /**
+         * Alternate constructor to define a parent, initial <code>URL</code>s,
+         * and a default <code>URLStreamHandlerFactory</code>.
+         */
+        public DefaultClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
+            super(urls, parent, factory);
+            this.includes = includes;
+            this.excludes = excludes;
+        }
+        
+        private boolean tryClassHere(String name) {
+            // Scan includes, then excludes
+            boolean tryHere;
+            
+            // If no explicit includes, try here
+            if (this.includes == null) {
+                tryHere = true;
+            } else {
+                // See if it matches include patterns
+                tryHere = false;
+                for (int i = 0; i < this.includes.length; i++) {
+                    if (WildcardHelper.match(null, name, includes[i])) {
+                        tryHere = true;
+                        break;
+                    }
+                }
+            }
+            
+            // Go through the exclusion list
+            if (tryHere && excludes != null) {
+                for (int i = 0; i < this.excludes.length; i++) {
+                    if (WildcardHelper.match(null, name, excludes[i])) {
+                        tryHere = false;
+                        break;
+                    }
+                }
+            }
+            
+            return tryHere;
+        }
+
+        /**
+         * Loads the class from this <code>ClassLoader</class>.  If the
+         * class does not exist in this one, we check the parent.  Please
+         * note that this is the exact opposite of the
+         * <code>ClassLoader</code> spec.  We use it to work around
+         * inconsistent class loaders from third party vendors.
+         *
+         * @param     name the name of the class
+         * @param     resolve if <code>true</code> then resolve the class
+         * @return    the resulting <code>Class</code> object
+         * @exception ClassNotFoundException if the class could not be found
+         */
+        public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            // First check if it's already loaded
+            Class clazz = findLoadedClass(name);
+
+            if (clazz == null) {
+                
+                ClassLoader parent = getParent();
+
+                if (tryClassHere(name)) {
+                    try {
+                        clazz = findClass(name);
+                        //System.err.println("Paranoid load : " + name);
+                    } catch (ClassNotFoundException cnfe) {
+                        if (parent == null) {
+                            // Propagate exception
+                            throw cnfe;                        
+                        }
+                    }
+                }
+                
+                if (clazz == null) {
+                    if (parent == null) {
+                        throw new ClassNotFoundException(name);
+                    } else {
+                        // Will throw a CFNE if not found in parent
+                        clazz = parent.loadClass(name);
+                    }
+                }
+            }
+
+            if (resolve) {
+                resolveClass(clazz);
+            }
+
+            return clazz;
+        }
+
+        /**
+         * Gets a resource from this <code>ClassLoader</class>.  If the
+         * resource does not exist in this one, we check the parent.
+         * Please note that this is the exact opposite of the
+         * <code>ClassLoader</code> spec.  We use it to work around
+         * inconsistent class loaders from third party vendors.
+         *
+         * @param name of resource
+         */
+        public final URL getResource(final String name) {
+
+            URL resource = findResource(name);
+            ClassLoader parent = this.getParent();
+            if (resource == null && parent != null) {
+                resource = parent.getResource(name);
+            }
+
+            return resource;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.manager.release(this.resolver);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
new file mode 100644
index 0000000..31bdb90
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/classloader/ReloadingClassLoaderFactory.java
@@ -0,0 +1,306 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.classloader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * Default implementation of {@link ClassLoaderFactory}. It accepts both class directory and jar
+ * directory configurations.
+ * <p>
+ * Wildcard patterns can also be specified to include or exclude some classes to be loaded in the
+ * classloader. In such case, the class is directly loaded from the parent classloader. The default
+ * is to include all classes.
+ * <p>
+ * Example:
+ * <pre>
+ * &lt;classpath&gt;
+ *   &lt;class-dir src="BLOCK-INF/classes"/&gt;
+ *   &lt;lib-dir src="BLOCK-INF/lib"/&gt;
+ *   &lt;include-classes pattern="org.apache.cocoon.**"/&gt;
+ *   &lt;exclude-classes pattern="org.apache.cocoon.transformation.**"/&gt;
+ * &/lt;classpath&gt;
+ * </pre>
+ */
+public class ReloadingClassLoaderFactory extends AbstractLogEnabled implements ClassLoaderFactory,
+    Serviceable, ThreadSafe, Disposable {
+
+    private ServiceManager manager;
+    private SourceResolver resolver;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+    }
+    
+    private void ensureIsDirectory(Source src, String location) throws ConfigurationException {
+        if (!src.exists()) {
+            throw new ConfigurationException(src.getURI() + " doesn't exist, at " + location);
+        } else if (!(src instanceof TraversableSource) || !((TraversableSource)src).isCollection()) {
+            throw new ConfigurationException(src.getURI() + " is not a directory, at " + location);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.ClassLoaderFactory#createClassLoader(java.lang.ClassLoader)
+     */
+    public ClassLoader createClassLoader(ClassLoader parent, Configuration config) throws ConfigurationException {
+        List urlList = new ArrayList();
+
+        Configuration[] libDirConfig = config.getChildren("lib-dir");
+        for (int i = 0; i < libDirConfig.length; i++) {
+            Configuration child = libDirConfig[i];
+
+            Source src = null;
+            try {
+                src = resolver.resolveURI(child.getAttribute("src"));
+                ensureIsDirectory(src, child.getLocation());
+                Iterator iter = ((TraversableSource)src).getChildren().iterator();
+                while (iter.hasNext()) {
+                    Source childSrc = (Source)iter.next();
+                    String childURI = childSrc.getURI();
+                    resolver.release(childSrc);
+                    if (childURI.endsWith(".jar") || childURI.endsWith(".zip")) {
+                        urlList.add(new URL(childURI));
+                    }
+                }
+            } catch(ConfigurationException ce) {
+                throw ce;
+            } catch(Exception e) {
+                throw new ConfigurationException("Error loading classpath at " + child.getLocation(), e);
+            } finally {
+                resolver.release(src);
+                src = null;
+            }
+        }
+        
+        URL[] urls = (URL[])urlList.toArray(new URL[urlList.size()]);
+
+        int[][] includes = compilePatterns(config.getChildren("include-classes"));
+        int[][] excludes = compilePatterns(config.getChildren("exclude-classes"));
+        
+        return new DefaultClassLoader(urls, includes, excludes, parent);
+    }
+
+    private int[][] compilePatterns(Configuration[] patternConfigs) throws ConfigurationException {
+        if (patternConfigs.length == 0) {
+            return null;
+        }
+        
+        int[][] patterns = new int[patternConfigs.length][];
+        
+        for (int i = 0; i < patternConfigs.length; i++) {
+            patterns[i] = WildcardHelper.compilePattern(patternConfigs[i].getAttribute("pattern"));
+        }
+        
+        return patterns;
+    }
+    
+    public class DefaultClassLoader extends URLClassLoader {
+        
+        private ResourceStore[] stores = new ResourceStore[0];
+        private final int[][] includes;
+        private final int[][] excludes;
+
+        /**
+         * Alternate constructor to define a parent and initial <code>URL</code>
+         * s.
+         */
+        public DefaultClassLoader(URL[] urls, int[][] includes, int[][] excludes, final ClassLoader parent) {
+            this(urls, includes, excludes, parent, null);
+        }
+
+        /**
+         * Alternate constructor to define a parent, initial <code>URL</code>s,
+         * and a default <code>URLStreamHandlerFactory</code>.
+         */
+        public DefaultClassLoader(final URL[] urls, int[][] includes, int[][] excludes, ClassLoader parent, URLStreamHandlerFactory factory) {
+            super(urls, parent, factory);
+            this.includes = includes;
+            this.excludes = excludes;
+        }
+        
+        
+        public void addResourceStore(final ResourceStore pStore) {
+            final int n = this.stores.length;
+            final ResourceStore[] newStores = new ResourceStore[n + 1];
+            System.arraycopy(this.stores, 0, newStores, 0, n);
+            newStores[n] = pStore;
+            this.stores = newStores;
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("added store " + stores);
+            }
+        }
+
+        private Class fastFindClass(final String name) {
+            
+            if (stores != null) {
+                for (int i = 0; i < stores.length; i++) {
+                    final ResourceStore store = stores[i];
+                    final byte[] clazzBytes = store.read(name);
+                    if (clazzBytes != null) {
+                        
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("found class " + name + " in stores");
+                        }
+
+                        return defineClass(name, clazzBytes, 0, clazzBytes.length);
+                    }            
+                }
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("did not find class " + name + " in stores");
+            }
+            
+            return null;            
+        }
+        
+        private boolean tryClassHere(String name) {
+            // Scan includes, then excludes
+            boolean tryHere;
+            
+            // If no explicit includes, try here
+            if (this.includes == null) {
+                tryHere = true;
+            } else {
+                // See if it matches include patterns
+                tryHere = false;
+                for (int i = 0; i < this.includes.length; i++) {
+                    if (WildcardHelper.match(null, name, includes[i])) {
+                        tryHere = true;
+                        break;
+                    }
+                }
+            }
+            
+            // Go through the exclusion list
+            if (tryHere && excludes != null) {
+                for (int i = 0; i < this.excludes.length; i++) {
+                    if (WildcardHelper.match(null, name, excludes[i])) {
+                        tryHere = false;
+                        break;
+                    }
+                }
+            }
+            
+            return tryHere;
+        }
+
+        /**
+         * Loads the class from this <code>ClassLoader</class>.  If the
+         * class does not exist in this one, we check the parent.  Please
+         * note that this is the exact opposite of the
+         * <code>ClassLoader</code> spec.  We use it to work around
+         * inconsistent class loaders from third party vendors.
+         *
+         * @param     name the name of the class
+         * @param     resolve if <code>true</code> then resolve the class
+         * @return    the resulting <code>Class</code> object
+         * @exception ClassNotFoundException if the class could not be found
+         */
+        public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            // First check if it's already loaded
+            Class clazz = findLoadedClass(name);
+
+            if (clazz == null) {
+                
+                ClassLoader parent = getParent();
+
+                if (tryClassHere(name)) {
+                    
+                    clazz = fastFindClass(name);
+                    
+                    if (clazz == null) {                    
+                        try {
+                            clazz = findClass(name);
+                            //System.err.println("Paranoid load : " + name);
+                        } catch (ClassNotFoundException cnfe) {
+                            if (parent == null) {
+                                // Propagate exception
+                                throw cnfe;                        
+                            }
+                        }
+                    }
+                }
+                
+                if (clazz == null) {
+                    if (parent == null) {
+                        throw new ClassNotFoundException(name);
+                    } else {
+                        // Will throw a CFNE if not found in parent
+                        clazz = parent.loadClass(name);
+                    }
+                }
+            }
+
+            if (resolve) {
+                resolveClass(clazz);
+            }
+
+            return clazz;
+        }
+
+        /**
+         * Gets a resource from this <code>ClassLoader</class>.  If the
+         * resource does not exist in this one, we check the parent.
+         * Please note that this is the exact opposite of the
+         * <code>ClassLoader</code> spec.  We use it to work around
+         * inconsistent class loaders from third party vendors.
+         *
+         * @param name of resource
+         */
+        public final URL getResource(final String name) {
+
+            URL resource = findResource(name);
+            ClassLoader parent = this.getParent();
+            if (resource == null && parent != null) {
+                resource = parent.getResource(name);
+            }
+
+            return resource;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.manager.release(this.resolver);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java
new file mode 100644
index 0000000..beddcb6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/CocoonServiceManager.java
@@ -0,0 +1,108 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  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.cocoon.components.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.SitemapConfigurable;
+import org.apache.cocoon.components.SitemapConfigurationHolder;
+import org.apache.cocoon.components.treeprocessor.ProcessorComponentInfo;
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+/**
+ * Default service manager for Cocoon's components.
+ *
+ * @version $Id$
+ */
+public class CocoonServiceManager extends CoreServiceManager {
+    
+    /** The {@link SitemapConfigurationHolder}s */
+    private Map sitemapConfigurationHolders = new HashMap(15);
+    
+    private ProcessorComponentInfo info;
+
+    /** Create the ServiceManager with a parent ServiceManager */
+    public CocoonServiceManager( final ServiceManager parent) {
+        this(parent, null);
+    }
+    
+    /** Create the ServiceManager with a parent ServiceManager and a ClassLoader */
+    public CocoonServiceManager( final ServiceManager parent, final ClassLoader classloader) {
+        super(parent, classloader);
+        ProcessorComponentInfo parentInfo = null;
+        if (parent != null) {
+            try {
+                parentInfo = (ProcessorComponentInfo) parent.lookup(ProcessorComponentInfo.ROLE);
+            } catch (ServiceException e) {
+                // no parent
+            }
+        }
+        this.info = new ProcessorComponentInfo(parentInfo);
+    }
+    
+    public void addComponent(String role, String clazz, Configuration config, ComponentInfo i) throws ConfigurationException {
+        this.info.prepareConfig(role, clazz, config);
+
+        super.addComponent(role, clazz, config, i);
+        // Let's ProcessorComponentInfo do its stuff.
+        // Note: if more behaviours of this kind are needed, we may setup an
+        // event listener mechanism on the core service manager
+        this.info.componentAdded(role, clazz, config);
+    }
+
+    public void addRoleAlias(String existingRole, String newRole) throws ServiceException {
+        super.addRoleAlias(existingRole, newRole);
+        this.info.roleAliased(existingRole, newRole);
+    }
+
+    public void initialize() throws Exception {
+        this.info.lock();
+        this.addInstance(ProcessorComponentInfo.ROLE, this.info);
+        super.initialize();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.CocoonServiceManager#initialize(java.lang.String, java.lang.Object)
+     */
+    protected void initialize(String role, Object component) throws ServiceException {
+        super.initialize(role, component);
+        if ( null != component && component instanceof SitemapConfigurable) {
+
+            // FIXME: how can we prevent that this is called over and over again?
+            SitemapConfigurationHolder holder;
+
+            holder = (SitemapConfigurationHolder)this.sitemapConfigurationHolders.get( role );
+            if ( null == holder ) {
+                // create new holder
+                holder = new DefaultSitemapConfigurationHolder( role, this.roleManager );
+                this.sitemapConfigurationHolders.put( role, holder );
+            }
+
+            try {
+                ((SitemapConfigurable)component).configure(holder);
+            } catch (ConfigurationException ce) {
+                throw new ServiceException(role, "Exception during setup of SitemapConfigurable.", ce);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/ComponentContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/ComponentContext.java
new file mode 100644
index 0000000..395aa51
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/ComponentContext.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.container;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ * This is the {@link Context} implementation for Cocoon components.
+ * It extends the {@link DefaultContext} by a special handling for
+ * getting objects from the object model and other application information.
+ * 
+ * @see org.apache.cocoon.components.ContextHelper
+ * @version $Id$
+ */
+public class ComponentContext 
+    extends DefaultContext {
+
+    protected static final String OBJECT_MODEL_KEY_PREFIX = ContextHelper.CONTEXT_OBJECT_MODEL + '.';
+    
+    /**
+     * Create a Context with specified data and parent.
+     *
+     * @param contextData the context data
+     * @param parent the parent Context (may be null)
+     */
+    public ComponentContext(final Map contextData, final Context parent) {
+        super( contextData, parent );
+    }
+
+    /**
+     * Create a Context with specified data.
+     *
+     * @param contextData the context data
+     */
+    public ComponentContext(final Map contextData) {
+        super( contextData );
+    }
+
+    /**
+     * Create a Context with specified parent.
+     *
+     * @param parent the parent Context (may be null)
+     */
+    public ComponentContext(final Context parent) {
+        super( parent );
+    }
+
+    /**
+     * Create a Context with no parent.
+     *
+     */
+    public ComponentContext() {
+        super();
+    }
+
+    /**
+     * Retrieve an item from the Context.
+     *
+     * @param key the key of item
+     * @return the item stored in context
+     * @throws ContextException if item not present
+     */
+    public Object get( final Object key )
+    throws ContextException {
+        if ( ContextHelper.CONTEXT_OBJECT_MODEL.equals(key)) {
+            final Environment env = EnvironmentHelper.getCurrentEnvironment();
+            if ( env == null ) {
+                throw new ContextException("Unable to locate " + key + " (No environment available)");
+            }
+            return env.getObjectModel();
+        } else if ( ContextHelper.CONTEXT_SITEMAP_SERVICE_MANAGER.equals(key)) {
+            final ServiceManager manager = EnvironmentHelper.getSitemapServiceManager();
+            if ( manager == null ) {
+                throw new ContextException("Unable to locate " + key + " (No environment available)");
+            }
+            return manager;
+        }
+        if ( key instanceof String ) {
+            String stringKey = (String)key;
+            if ( stringKey.startsWith(OBJECT_MODEL_KEY_PREFIX) ) {
+                final Environment env = EnvironmentHelper.getCurrentEnvironment();
+                if ( env == null ) {
+                    throw new ContextException("Unable to locate " + key + " (No environment available)");
+                }
+                final Map objectModel = env.getObjectModel();
+                String objectKey = stringKey.substring(OBJECT_MODEL_KEY_PREFIX.length());
+                
+                Object o = objectModel.get( objectKey );
+                if ( o == null ) {
+                    final String message = "Unable to locate " + key;
+                    throw new ContextException( message );
+                }
+                return o;
+            }
+        }
+        return super.get( key );
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
new file mode 100644
index 0000000..fc0c92e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/container/DefaultSitemapConfigurationHolder.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.container;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.ChainedConfiguration;
+import org.apache.cocoon.components.SitemapConfigurationHolder;
+import org.apache.cocoon.core.container.RoleManager;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ *
+ * @version $Id$
+ */
+public final class DefaultSitemapConfigurationHolder 
+    implements SitemapConfigurationHolder {
+
+    /** The role of the sitemap component */
+    private final String role;
+    
+    /** The role manager */
+    private final RoleManager roleManager;
+
+    /** The prepared configurations indexed by the ChainedConfiguration */
+    private Map preparedConfigurations;
+    
+    public DefaultSitemapConfigurationHolder(String role, RoleManager manager) {
+        this.role = role;
+        this.roleManager = manager;
+    }
+    
+    protected Map convert(Configuration[] configs, int index) {
+        Map sitemapComponentConfigurations;
+        
+        // do we have configurations?
+        final Configuration[] childs = configs[index].getChildren();
+
+        if ( null != childs && childs.length > 0 ) {
+
+            if ( index == configs.length - 1 ) {
+                sitemapComponentConfigurations = new HashMap(12);
+            } else {
+                // copy all configurations from parent
+                sitemapComponentConfigurations = new HashMap(this.convert(configs, index+1));
+            }
+
+            // and now check for new configurations
+            for(int m = 0; m < childs.length; m++) {
+
+                final String r = this.roleManager.getRoleForName(childs[m].getName());
+                sitemapComponentConfigurations.put(r, new ChainedConfiguration(childs[m],
+                                                                 (ChainedConfiguration)sitemapComponentConfigurations.get(r)));
+            }
+        } else {
+            // we don't have configurations
+            if ( index == configs.length - 1 ) {
+                sitemapComponentConfigurations = Collections.EMPTY_MAP;
+            } else {
+                // use configuration from parent
+                sitemapComponentConfigurations = this.convert(configs, index+1);
+            }
+        }
+        return sitemapComponentConfigurations;        
+    }
+    
+    /**
+     * @see SitemapConfigurationHolder#getConfiguration()
+     */
+    public ChainedConfiguration getConfiguration() {
+        Map confs = this.convert(EnvironmentHelper.getCurrentProcessor().getComponentConfigurations(), 0);
+        return (ChainedConfiguration) (confs == null ? null : confs.get(this.role));
+    }
+
+    /**
+     * @see SitemapConfigurationHolder#getPreparedConfiguration()
+     */
+    public Object getPreparedConfiguration() {
+        if ( null != this.preparedConfigurations ) {
+            ChainedConfiguration conf = this.getConfiguration();
+            if ( null != conf ) {
+                return this.preparedConfigurations.get( conf );
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see SitemapConfigurationHolder#setPreparedConfiguration(ChainedConfiguration, java.lang.Object)
+     */
+    public void setPreparedConfiguration(ChainedConfiguration configuration, 
+                                          Object preparedConfig) {
+        if ( null == this.preparedConfigurations ) {
+            this.preparedConfigurations = new HashMap(5);                                              
+        }
+        this.preparedConfigurations.put(configuration, preparedConfig);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/CocoonCrawler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/CocoonCrawler.java
new file mode 100644
index 0000000..5eac05e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/CocoonCrawler.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.crawler;
+
+import java.net.URL;
+import java.util.Iterator;
+
+/**
+ * The avalon behavioural component interface of crawling.
+ *
+ * @version $Id$
+ */
+public interface CocoonCrawler {
+    /**
+     * Role name of this avalon component.
+     * Its value is <code>org.apache.cocoon.components.crawler.CocoonCrawler</code>.
+     */
+    String ROLE = CocoonCrawler.class.getName();
+
+
+    /**
+     * This is the same as calling crawl(url,-1);
+     *
+     * @param  url  The URL to start crawling from.
+     */
+    void crawl(URL url);
+    
+    
+	/**
+     * start crawling the URL.
+     * <p>
+     *   Calling this method initiates the crawling and tells the
+     *   crawler not to crawl beyond a maximum depth.
+     * </p>
+     * 
+	 * @param url  The URL to start crawling from
+	 * @param maxDepth  The maximum depth to crawl to. -1 for no maxiumum.
+	 */
+    void crawl(URL url, int maxDepth);
+    
+
+    /**
+     * Iterate over crawling URLs.
+     * <p>
+     *   This iterator will returns URL as result of crawling
+     *   the base URL passed via crawling().
+     * </p>
+     *
+     * @return    Iterator iterates over crawling URLs.
+     */
+    Iterator iterator();
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/SimpleCocoonCrawlerImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/SimpleCocoonCrawlerImpl.java
new file mode 100644
index 0000000..5882490
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/SimpleCocoonCrawlerImpl.java
@@ -0,0 +1,648 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.crawler;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.Constants;
+import org.apache.commons.lang.StringUtils;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A simple cocoon crawler.
+ *
+ * @version $Id$
+ */
+public class SimpleCocoonCrawlerImpl extends AbstractLogEnabled
+implements CocoonCrawler, Configurable, Disposable, Recyclable {
+    
+    /**
+     * Config element name specifying expected link content-typ.
+     * <p>
+     *   Its value is <code>link-content-type</code>.
+     * </p>
+     */
+    public final static String LINK_CONTENT_TYPE_CONFIG = "link-content-type";
+    
+    /**
+     * Default value of <code>link-content-type</code> configuration value.
+     * <p>
+     *   Its value is <code>application/x-cocoon-links</code>.
+     * </p>
+     */
+    public final String LINK_CONTENT_TYPE_DEFAULT = Constants.LINK_CONTENT_TYPE;
+    
+    /**
+     * Config element name specifying query-string appendend for requesting links
+     * of an URL.
+     * <p>
+     *  Its value is <code>link-view-query</code>.
+     * </p>
+     */
+    public final static String LINK_VIEW_QUERY_CONFIG = "link-view-query";
+    
+    /**
+     * Default value of <code>link-view-query</code> configuration option.
+     * <p>
+     *   Its value is <code>?cocoon-view=links</code>.
+     * </p>
+     */
+    public final static String LINK_VIEW_QUERY_DEFAULT = "cocoon-view=links";
+    
+    /**
+     * Config element name specifying excluding regular expression pattern.
+     * <p>
+     *  Its value is <code>exclude</code>.
+     * </p>
+     */
+    public final static String EXCLUDE_CONFIG = "exclude";
+    
+    /**
+     * Config element name specifying including regular expression pattern.
+     * <p>
+     *  Its value is <code>include</code>.
+     * </p>
+     */
+    public final static String INCLUDE_CONFIG = "include";
+    
+    /**
+     * Config element name specifying http header value for user-Agent.
+     * <p>
+     *  Its value is <code>user-agent</code>.
+     * </p>
+     */
+    public final static String USER_AGENT_CONFIG = "user-agent";
+    
+    /**
+     * Default value of <code>user-agent</code> configuration option.
+     * @see Constants#COMPLETE_NAME
+     */
+    public final static String USER_AGENT_DEFAULT = Constants.COMPLETE_NAME;
+    
+    /**
+     * Config element name specifying http header value for accept.
+     * <p>
+     *  Its value is <code>accept</code>.
+     * </p>
+     */
+    public final static String ACCEPT_CONFIG = "accept";
+    
+    /**
+     * Default value of <code>accept</code> configuration option.
+     * <p>
+     *   Its value is <code>* / *</code>
+     * </p>
+     */
+    public final static String ACCEPT_DEFAULT = "*/*";
+    
+    
+    private String linkViewQuery = LINK_VIEW_QUERY_DEFAULT;
+    private String linkContentType = LINK_CONTENT_TYPE_DEFAULT;
+    private HashSet excludeCrawlingURL;
+    private HashSet includeCrawlingURL;
+    private String userAgent = USER_AGENT_DEFAULT;
+    private String accept = ACCEPT_DEFAULT;
+    
+    private int depth;
+    
+    private HashSet crawled;
+    private HashSet urlsToProcess;
+    private HashSet urlsNextDepth;
+    
+    
+    
+    /**
+     * Constructor for the SimpleCocoonCrawlerImpl object
+     */
+    public SimpleCocoonCrawlerImpl() {
+        // by default include everything
+        includeCrawlingURL = null;
+        // by default exclude common image patterns
+        excludeCrawlingURL = null;
+    }
+    
+    
+    /**
+     * Configure the crawler component.
+     * <p>
+     *  Configure can specify which URI to include, and which URI to exclude
+     *  from crawling. You specify the patterns as regular expressions.
+     * </p>
+     * <p>
+     *  Morover you can configure
+     *  the required content-type of crawling request, and the
+     *  query-string appended to each crawling request.
+     * </p>
+     * <pre><tt>
+     * &lt;include&gt;.*\.html?&lt;/exclude&gt; or &lt;exclude&gt;.*\.html?, .*\.xsp&lt;/exclude&gt;
+     * &lt;exclude&gt;.*\.gif&lt;/exclude&gt; or &lt;exclude&gt;.*\.gif, .*\.jpe?g&lt;/exclude&gt;
+     * &lt;link-content-type&gt; application/x-cocoon-links &lt;/link-content-type&gt;
+     * &lt;link-view-query&gt; ?cocoon-view=links &lt;/link-view-query&gt;
+     * </tt></pre>
+     *
+     * @param  configuration               XML configuration of this avalon component.
+     * @exception  ConfigurationException  is throwing if configuration is invalid.
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        
+        Configuration[] children;
+        children = configuration.getChildren(INCLUDE_CONFIG);
+        if (children.length > 0) {
+            includeCrawlingURL = new HashSet();
+            for (int i = 0; i < children.length; i++) {
+                String pattern = children[i].getValue();
+                try {
+                    String params[] = StringUtils.split(pattern, ", ");
+                    for (int index = 0; index < params.length; index++) {
+                        String tokenized_pattern = params[index];
+                        this.includeCrawlingURL.add(new RE(tokenized_pattern));
+                    }
+                } catch (RESyntaxException rese) {
+                    getLogger().error("Cannot create including regular-expression for " +
+                    pattern, rese);
+                }
+            }
+        } else {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Include all URLs");
+            }
+        }
+        
+        children = configuration.getChildren(EXCLUDE_CONFIG);
+        if (children.length > 0) {
+            excludeCrawlingURL = new HashSet();
+            for (int i = 0; i < children.length; i++) {
+                String pattern = children[i].getValue();
+                try {
+                    String params[] = StringUtils.split(pattern, ", ");
+                    for (int index = 0; index < params.length; index++) {
+                        String tokenized_pattern = params[index];
+                        this.excludeCrawlingURL.add(new RE(tokenized_pattern));
+                    }
+                } catch (RESyntaxException rese) {
+                    getLogger().error("Cannot create excluding regular-expression for " +
+                    pattern, rese);
+                }
+            }
+        } else {
+            excludeCrawlingURL = new HashSet();
+            setDefaultExcludeFromCrawling();
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Exclude default URLs only");
+            }
+        }
+        
+        Configuration child;
+        String value;
+        child = configuration.getChild(LINK_CONTENT_TYPE_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.linkContentType = value.trim();
+            }
+        }
+        child = configuration.getChild(LINK_VIEW_QUERY_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.linkViewQuery = value.trim();
+            }
+        }
+        
+        child = configuration.getChild(USER_AGENT_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.userAgent = value;
+            }
+        }
+        
+        child = configuration.getChild(ACCEPT_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.accept = value;
+            }
+        }
+        
+    }
+    
+    
+    /**
+     * dispose at end of life cycle, releasing all resources.
+     */
+    public void dispose() {
+        crawled = null;
+        urlsToProcess = null;
+        urlsNextDepth = null;
+        excludeCrawlingURL = null;
+        includeCrawlingURL = null;
+    }
+    
+    
+    /**
+     * recylcle this object, relasing resources
+     */
+    public void recycle() {
+        crawled = null;
+        urlsToProcess = null;
+        urlsNextDepth = null;
+        depth = -1;
+    }
+    
+    
+    /**
+     * The same as calling crawl(url,-1);
+     *
+     * @param  url  Crawl this URL, getting all links from this URL.
+     */
+    public void crawl(URL url) {
+        crawl(url, -1);
+    }
+    
+    /**
+     * Start crawling a URL.
+     *
+     * <p>
+     *   Use this method to start crawling.
+     *   Get the this url, and all its children  by using <code>iterator()</code>.
+     *   The Iterator object will return URL objects.
+     * </p>
+     * <p>
+     *  You may use the crawl(), and iterator() methods the following way:
+     * </p>
+     * <pre><tt>
+     *   SimpleCocoonCrawlerImpl scci = ....;
+     *   scci.crawl( "http://foo/bar" );
+     *   Iterator i = scci.iterator();
+     *   while (i.hasNext()) {
+     *     URL url = (URL)i.next();
+     *     ...
+     *   }
+     * </tt></pre>
+     * <p>
+     *   The i.next() method returns a URL, and calculates the links of the
+     *   URL before return it.
+     * </p>
+     *
+     * @param  url  Crawl this URL, getting all links from this URL.
+     * @param  maxDepth  maximum depth to crawl to. -1 for no maximum.
+     */
+    public void crawl(URL url, int maxDepth) {
+        crawled = new HashSet();
+        urlsToProcess = new HashSet();
+        urlsNextDepth = new HashSet();
+        depth = maxDepth;
+        
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("crawl URL " + url + " to depth " + maxDepth);
+        }
+        
+        urlsToProcess.add(url);
+    }
+    
+    
+    /**
+     * Return iterator, iterating over all links of the currently crawled URL.
+     * <p>
+     *   The Iterator object will return URL objects at its <code>next()</code>
+     *   method.
+     * </p>
+     *
+     * @return    Iterator iterator of all links from the crawl URL.
+     * @since
+     */
+    public Iterator iterator() {
+        return new CocoonCrawlerIterator(this);
+    }
+    
+    
+    /**
+     * Default exclude patterns.
+     * <p>
+     *   By default URLs matching following patterns are excluded:
+     * </p>
+     * <ul>
+     *   <li>.*\\.gif(\\?.*)?$ - exclude gif images</li>
+     *   <li>.*\\.png(\\?.*)?$ - exclude png images</li>
+     *   <li>.*\\.jpe?g(\\?.*)?$ - exclude jpeg images</li>
+     *   <li>.*\\.js(\\?.*)?$ - exclude javascript </li>
+     *   <li>.*\\.css(\\?.*)?$ - exclude cascaded stylesheets</li>
+     * </ul>
+     *
+     * @since
+     */
+    private void setDefaultExcludeFromCrawling() {
+        String[] EXCLUDE_FROM_CRAWLING_DEFAULT = {
+            ".*\\.gif(\\?.*)?$",
+            ".*\\.png(\\?.*)?$",
+            ".*\\.jpe?g(\\?.*)?$",
+            ".*\\.js(\\?.*)?$",
+            ".*\\.css(\\?.*)?$"
+        };
+        
+        for (int i = 0; i < EXCLUDE_FROM_CRAWLING_DEFAULT.length; i++) {
+            String pattern = EXCLUDE_FROM_CRAWLING_DEFAULT[i];
+            try {
+                excludeCrawlingURL.add(new RE(pattern));
+            } catch (RESyntaxException rese) {
+                getLogger().error("Cannot create excluding regular-expression for " +
+                pattern, rese);
+            }
+        }
+    }
+    
+    
+    /**
+     * Compute list of links from the url.
+     * <p>
+     *   Check for include, exclude pattern, content-type, and if url
+     *   has been craweled already.
+     * </p>
+     *
+     * @param  url  Crawl this URL
+     * @return      List of URLs, which are links from url, asserting the conditions.
+     * @since
+     */
+    private List getLinks(URL url) {
+        ArrayList url_links = null;
+        String sURL = url.toString();
+        
+        if (!isIncludedURL(sURL) || isExcludedURL(sURL)) {
+            return null;
+        }
+        
+        // don't try to get links for url which has been crawled already
+        if (crawled.contains(sURL)) {
+            return null;
+        }
+        
+        // mark it as crawled
+        crawled.add(sURL);
+        
+        // get links of url
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Getting links of URL " + sURL);
+        }
+        BufferedReader br = null;
+        try {
+            sURL = url.getFile();
+            URL links = new URL(url, sURL
+            + ((sURL.indexOf("?") == -1) ? "?" : "&")
+            + linkViewQuery);
+            URLConnection links_url_connection = links.openConnection();
+            links_url_connection.setRequestProperty("Accept", accept);
+            links_url_connection.setRequestProperty("User-Agent", userAgent);
+            links_url_connection.connect();
+            InputStream is = links_url_connection.getInputStream();
+            br = new BufferedReader(new InputStreamReader(is));
+            
+            String contentType = links_url_connection.getContentType();
+            if (contentType == null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Ignoring " + sURL + " (no content type)");
+                }
+                // there is a check on null in the calling method
+                return null;
+            }
+            
+            int index = contentType.indexOf(';');
+            if (index != -1) {
+                contentType = contentType.substring(0, index);
+            }
+            
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Content-type: " + contentType);
+            }
+            
+            if (contentType.equals(linkContentType)) {
+                url_links = new ArrayList();
+                
+                // content is supposed to be a list of links,
+                // relative to current URL
+                String line;
+                while ((line = br.readLine()) != null) {
+                    final URL newUrl = new URL(url, line);
+                    final String sNewUrl = newUrl.toString();
+                    
+                    boolean add_url = true;
+                    // don't add new_url twice
+                    if (add_url) {
+                        add_url &= !url_links.contains(sNewUrl);
+                    }
+                    
+                    // don't add new_url if it has been crawled already
+                    if (add_url) {
+                        add_url &= !crawled.contains(sNewUrl);
+                    }
+                    
+                    // don't add if is not matched by existing include definition
+                    if (add_url) {
+                        add_url &= isIncludedURL(sNewUrl);
+                    }
+                    
+                    // don't add if is matched by existing exclude definition
+                    if (add_url) {
+                        add_url &= !isExcludedURL(sNewUrl);
+                    }
+                    if (add_url) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Add URL: " + sNewUrl);
+                        }
+                        url_links.add(newUrl);
+                    }
+                }
+                // now we have a list of URL which should be examined
+            }
+        } catch (IOException ioe) {
+            getLogger().warn("Problems get links of " + url, ioe);
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                    br = null;
+                } catch (IOException ignored) {
+                }
+            }
+        }
+        return url_links;
+    }
+    
+    
+    /**
+     * check if URL is a candidate for indexing
+     *
+     * @param  url  the URL to check
+     * @return      The excludedURL value
+     */
+    private boolean isExcludedURL(String url) {
+        // by default do not exclude URL for crawling
+        if (excludeCrawlingURL == null) {
+            return false;
+        }
+        
+        final String s = url.toString();
+        Iterator i = excludeCrawlingURL.iterator();
+        while (i.hasNext()) {
+            RE pattern = (RE) i.next();
+            if (pattern.match(s)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Excluded URL " + url);
+                }
+                return true;
+            }
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Not excluded URL " + url);
+        }
+        return false;
+    }
+    
+    
+    /**
+     * check if URL is a candidate for indexing
+     *
+     * @param  url  Description of Parameter
+     * @return      The includedURL value
+     */
+    private boolean isIncludedURL(String url) {
+        // by default include URL for crawling
+        if (includeCrawlingURL == null) {
+            return true;
+        }
+        
+        final String s = url.toString();
+        Iterator i = includeCrawlingURL.iterator();
+        while (i.hasNext()) {
+            RE pattern = (RE) i.next();
+            if (pattern.match(s)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Included URL " + url);
+                }
+                return true;
+            }
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Not included URL " + url);
+        }
+        return false;
+    }
+    
+    
+    /**
+     * Helper class implementing an Iterator
+     * <p>
+     *   This Iterator implementation calculates the links of an URL
+     *   before returning in the next() method.
+     * </p>
+     *
+     * @version    $Id$
+     */
+    public static class CocoonCrawlerIterator implements Iterator {
+        private SimpleCocoonCrawlerImpl cocoonCrawler;
+        
+        
+        /**
+         * Constructor for the CocoonCrawlerIterator object
+         *
+         * @param  cocoonCrawler  the containing CocoonCrawler instance.
+         */
+        CocoonCrawlerIterator(SimpleCocoonCrawlerImpl cocoonCrawler) {
+            this.cocoonCrawler = cocoonCrawler;
+        }
+        
+        
+        /**
+         * check if crawling is finished.
+         *
+         * @return    <code>true</code> if crawling has finished,
+         * else <code>false</code>.
+         */
+        public boolean hasNext() {
+            return cocoonCrawler.urlsToProcess.size() > 0
+            || cocoonCrawler.urlsNextDepth.size() > 0;
+        }
+        
+        
+        /**
+         * @return    the next URL
+         */
+        public Object next() {
+            if (cocoonCrawler.urlsToProcess.size() == 0
+            && cocoonCrawler.urlsNextDepth.size() > 0) {
+                // process queued urls belonging to the next depth level
+                cocoonCrawler.urlsToProcess = cocoonCrawler.urlsNextDepth;
+                cocoonCrawler.urlsNextDepth = new HashSet();
+                // fix Bugzilla Bug 25270
+                // only decrease if depth > 0, excluding decreasing
+                // if depth is already equal to -1
+                if (cocoonCrawler.depth > 0) {
+                    cocoonCrawler.depth--;
+                }
+            }
+            URL theNextUrl = null;
+            // fix Bugzilla Bug 25270
+            // return NextUrl != null only if getLinks() returns non-null
+            // list
+            for (Iterator i = cocoonCrawler.urlsToProcess.iterator(); 
+              i.hasNext() && theNextUrl == null;) {
+                // fetch a URL
+                URL url = (URL) i.next();
+
+                // remove it from the to-do list
+                i.remove();
+
+                if (cocoonCrawler.depth == -1 || cocoonCrawler.depth > 0) {
+                    // calc all links from this url
+                    List url_links = cocoonCrawler.getLinks(url);
+                    if (url_links != null) {
+                        // add links of this url to the to-do list
+                        cocoonCrawler.urlsNextDepth.addAll(url_links);
+                        theNextUrl = url;
+                    }
+                }
+            }
+            // finally return url
+            return theNextUrl;
+        }
+        
+        
+        /**
+         * remove is not implemented
+         */
+        public void remove() {
+            throw new UnsupportedOperationException("remove is not implemented");
+        }
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/package.html
new file mode 100644
index 0000000..e421f03
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/crawler/package.html
@@ -0,0 +1,33 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+  <title>Crawler - starts from a given URL and follows the links</title>
+</head>
+<body>
+  <h1>Crawler - starts from a given URL and follows the links</h1>
+  <p>
+    This package provides Cocoon crawler components.
+  </p>
+  <p>
+    A crawler component crawls through URLs.
+    The process is initiated by calling <code>crawl()</code>.
+    The method <code>iterator()</code> returns an Iterator object.
+    This Iterator object iterates over all URLs reachable from
+    the passed URL of method <code>crawl()</code>.
+  </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java
new file mode 100644
index 0000000..96907be
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitor.java
@@ -0,0 +1,26 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.fam;
+
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+
+public interface SitemapMonitor {
+	String ROLE = SitemapMonitor.class.getName();
+    
+    void subscribe(final FilesystemAlterationListener listener);    
+    void unsubscribe(final FilesystemAlterationListener listener);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java
new file mode 100644
index 0000000..fa0df02
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/fam/SitemapMonitorImpl.java
@@ -0,0 +1,48 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.fam;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+
+public final class SitemapMonitorImpl 
+    extends AbstractLogEnabled 
+    implements SitemapMonitor, ThreadSafe, Initializable, Disposable {
+
+    private FilesystemAlterationMonitor monitor;
+
+    public void initialize() throws Exception {
+        monitor = new FilesystemAlterationMonitor();
+        monitor.start();
+    }
+
+    public void dispose() {
+        monitor.stop();
+    }
+    
+    public void subscribe(final FilesystemAlterationListener listener) {
+        monitor.addListener(listener);
+    }
+    
+    public void unsubscribe(final FilesystemAlterationListener listener) {
+        monitor.removeListener(listener);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/AbstractInterpreter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/AbstractInterpreter.java
new file mode 100644
index 0000000..28ee159
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/AbstractInterpreter.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.SingleThreaded;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.util.PipelineUtil;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.excalibur.source.SourceUtil;
+
+/**
+ * Abstract superclass for various scripting languages used by Cocoon
+ * for flow control. Defines some useful behavior like the ability to
+ * reload script files if they get modified (useful when doing
+ * development), and passing the control to Cocoon's sitemap for
+ * result page generation.
+ * <p>
+ * Flow intrepreters belonging to different sitemaps should be isolated. To achieve this,
+ * class implements the {@link org.apache.avalon.framework.thread.SingleThreaded}. Since
+ * the sitemap engine looks up the flow intepreter once at sitemap build time, this ensures
+ * that each sitemap will use a different instance of this class. But that instance will
+ * handle all flow calls for a given sitemap, and must therefore be thread safe.
+ *
+ * @since March 15, 2002
+ * @version $Id$
+ */
+public abstract class AbstractInterpreter
+        extends AbstractLogEnabled
+        implements Serviceable, Contextualizable, Interpreter,
+                   SingleThreaded, Configurable, Disposable {
+
+    // The instance ID of this interpreter, used to identify user scopes
+    private String instanceID;
+
+    protected org.apache.avalon.framework.context.Context avalonContext;
+
+    /**
+     * List of source locations that need to be resolved.
+     */
+    protected ArrayList needResolve = new ArrayList();
+
+    protected org.apache.cocoon.environment.Context context;
+    protected ServiceManager manager;
+    protected ContinuationsManager continuationsMgr;
+
+    /** The settings of Cocoon. */
+    protected Settings settings;
+
+    /**
+     * Whether reloading of scripts should be done. Specified through
+     * the "reload-scripts" attribute in <code>flow.xmap</code>.
+     */
+    protected boolean reloadScripts;
+
+    /**
+     * Interval between two checks for modified script files. Specified
+     * through the "check-time" XML attribute in <code>flow.xmap</code>.
+     */
+    protected long checkTime;
+
+    /**
+     * Set the unique ID for this interpreter, which can be used to distinguish user value scopes
+     * attached to the session.
+     */
+    public void setInterpreterID(String interpreterID) {
+        this.instanceID = interpreterID;
+    }
+
+    /**
+     * Get the unique ID for this interpreter, which can be used to distinguish user value scopes
+     * attached to the session.
+     *
+     * @return a unique ID for this interpreter
+     */
+    public String getInterpreterID() {
+        return this.instanceID;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        this.reloadScripts = config.getChild("reload-scripts").getValueAsBoolean(this.settings.isReloadingEnabled("flow"));
+        this.checkTime = config.getChild("check-time").getValueAsLong(this.settings.getReloadDelay("flow"));
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager sm) throws ServiceException {
+        this.manager = sm;
+        this.continuationsMgr = (ContinuationsManager)sm.lookup(ContinuationsManager.ROLE);
+        final Core core = (Core)this.manager.lookup(Core.ROLE);
+        this.settings = core.getSettings();
+        this.manager.release(core);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(org.apache.avalon.framework.context.Context context)
+    throws ContextException{
+        this.avalonContext = context;
+        this.context = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release( this.continuationsMgr );
+            this.continuationsMgr = null;
+            this.manager = null;
+            this.settings = null;
+        }
+    }
+
+    /**
+     * Registers a source file with the interpreter. Using this method
+     * an implementation keeps track of all the script files which are
+     * compiled. This allows them to reload the script files which get
+     * modified on the file system.
+     *
+     * <p>The parsing/compilation of a script file by an interpreter
+     * happens in two phases. In the first phase the file's location is
+     * registered in the <code>needResolve</code> array.
+     *
+     * <p>The second is possible only when a Cocoon
+     * <code>Environment</code> is passed to the Interpreter. This
+     * allows the file location to be resolved using Cocoon's
+     * <code>SourceFactory</code> class.
+     *
+     * <p>Once a file's location can be resolved, it is removed from the
+     * <code>needResolve</code> array and placed in the
+     * <code>scripts</code> hash table. The key in this hash table is
+     * the file location string, and the value is a
+     * DelayedRefreshSourceWrapper instance which keeps track of when
+     * the file needs to re-read.
+     *
+     * @param source the location of the script
+     *
+     * @see org.apache.cocoon.environment.Environment
+     * @see org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper
+     */
+    public void register(String source) {
+        synchronized (this) {
+            needResolve.add(source);
+        }
+    }
+
+    /**
+     * Call the Cocoon sitemap for the given URI, sending the output of the
+     * eventually matched pipeline to the specified outputstream.
+     *
+     * @param uri The URI for which the request should be generated.
+     * @param biz Extra data associated with the subrequest.
+     * @param out An OutputStream where the output should be written to.
+     * @exception Exception If an error occurs.
+     */
+    protected void process(String uri, Object biz, OutputStream out)
+    throws Exception {
+        // FIXME (SW): should we deprecate this method in favor of PipelineUtil?
+        PipelineUtil pipeUtil = new PipelineUtil();
+        try {
+            pipeUtil.contextualize(this.avalonContext);
+            pipeUtil.service(this.manager);
+            pipeUtil.processToStream(uri, biz, out);
+        } finally {
+            pipeUtil.dispose();
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.components.flow.Interpreter#forwardTo(java.lang.String, java.lang.Object, org.apache.cocoon.components.flow.WebContinuation, org.apache.cocoon.environment.Redirector)
+     */
+    public void forwardTo(String uri, Object bizData,
+                          WebContinuation continuation,
+                          Redirector redirector)
+    throws Exception {
+        if (SourceUtil.indexOfSchemeColon(uri) == -1) {
+            uri = "cocoon:/" + uri;
+            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
+            FlowHelper.setWebContinuation(objectModel, continuation);
+            FlowHelper.setContextObject(objectModel, bizData);
+            if (redirector.hasRedirected()) {
+                throw new IllegalStateException("Pipeline has already been processed for this request");
+            }
+            // this is a hint for the redirector
+            objectModel.put("cocoon:forward", "true");
+            redirector.redirect(false, uri);
+        } else {
+            throw new Exception("uri is not allowed to contain a scheme (cocoon:/ is always automatically used)");
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/CompilingInterpreter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/CompilingInterpreter.java
new file mode 100644
index 0000000..a54d82b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/CompilingInterpreter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+
+/**
+ * This is a base class for all interpreters compiling the scripts
+ *
+ * @version $Id$
+ */
+public abstract class CompilingInterpreter
+        extends AbstractInterpreter {
+
+    /**
+     * A source resolver
+     */
+    protected SourceResolver sourceresolver;
+
+    /**
+     * Mapping of String objects (source uri's) to ScriptSourceEntry's
+     */
+    protected Map compiledScripts = new HashMap();
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.sourceresolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.compiledScripts != null) {
+            Iterator i = this.compiledScripts.values().iterator();
+            while (i.hasNext()) {
+                ScriptSourceEntry current = (ScriptSourceEntry)i.next();
+                this.sourceresolver.release(current.getSource());
+            }
+            this.compiledScripts = null;
+        }
+        if (this.manager != null) {
+            this.manager.release(this.sourceresolver);
+            this.sourceresolver = null;
+        }
+        super.dispose();
+    }
+
+    /**
+     * TODO - This is a little bit strange, the interpreter calls
+     * get Script on the ScriptSourceEntry which in turn
+     * calls compileScript on the interpreter. I think we
+     * need more refactoring here.
+     */
+    protected abstract Script compileScript(Context context,
+                                            Scriptable scope,
+                                            Source source) throws Exception;
+
+    protected class ScriptSourceEntry {
+        final private Source source;
+        private Script script;
+        private long compileTime;
+
+        public ScriptSourceEntry(Source source) {
+            this.source = source;
+        }
+
+        public ScriptSourceEntry(Source source, Script script, long t) {
+            this.source = source;
+            this.script = script;
+            this.compileTime = t;
+        }
+
+        public Source getSource() {
+            return source;
+        }
+
+        public Script getScript(Context context, Scriptable scope,
+                                boolean refresh, CompilingInterpreter interpreter)
+        throws Exception {
+            if (refresh) {
+                source.refresh();
+            }
+            if (script == null || compileTime < source.getLastModified()) {
+                script = interpreter.compileScript(context, scope, source);
+                compileTime = source.getLastModified();
+            }
+            return script;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsDisposer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsDisposer.java
new file mode 100644
index 0000000..85f47ef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsDisposer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow;
+
+/**
+ * ContinuationsDisposer declares the contract for the clean-up of specfic 
+ * continuations.
+ * <p>
+ * Typically a {@link Interpreter} implementation that produces continuation 
+ * objects which require proper clean up will implement this interface to get
+ * a call-back in the event of the ContinuationsManager deciding to invalidate 
+ * a WebContinuation. 
+ */
+public interface ContinuationsDisposer {
+    /**
+     * Disposes the passed continuation object.
+     * <p>
+     * This method is called from the ContinuationsManager in the event of
+     * the invalidation of a continuation upon the {@link ContinuationsDisposer}
+     * object passed during the creation of the WebContinuation.
+     * 
+     * @param webContinuation the {@link WebContinuation} value representing the  
+     * continuation object. 
+     */
+    public void disposeContinuation(WebContinuation webContinuation);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManager.java
new file mode 100644
index 0000000..bd70902
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManager.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow;
+
+import java.util.List;
+
+/**
+ * The interface of the Continuations manager.
+ *
+ * The continuation manager maintains a forrest of {@link
+ * WebContinuation} trees. Each tree defines the flow of control for a
+ * user within the application.
+ *
+ * A <code>WebContinuation</code> is created for a continuation object
+ * from the scripting language used. A continuation object in the
+ * implementation of the scripting language is an opaque object
+ * here. It is only stored inside the <code>WebContinuation</code>,
+ * without being interpreted in any way.
+ *
+ * @since March 19, 2002
+ * @see WebContinuation
+ * @version $Id$
+ */
+public interface ContinuationsManager {
+    public final String ROLE = ContinuationsManager.class.getName();
+
+    /**
+     * Create a <code>WebContinuation</code> object given a native
+     * continuation object and its parent. If the parent continuation is
+     * null, the <code>WebContinuation</code> returned becomes the root
+     * of a tree in the forrest.
+     *
+     * @param kont an <code>Object</code> value
+     * @param parentKont a <code>WebContinuation</code> value
+     * @param timeToLive an <code>int</code> value indicating how long
+     * in seconds this continuation will live in the server if not
+     * accessed
+     * @param interpreterId id of interpreter invoking continuation creation
+     * @param disposer a <code>ContinuationsDisposer</code> instance to called when 
+     * the continuation gets cleaned up.
+     * @return a <code>WebContinuation</code> value
+     * @see WebContinuation
+     */
+    public WebContinuation createWebContinuation(Object kont,
+                                                 WebContinuation parentKont,
+                                                 int timeToLive,
+                                                 String interpreterId,
+                                                 ContinuationsDisposer disposer);
+
+    /**
+     * Invalidates a <code>WebContinuation</code>. This effectively
+     * means that the continuation object associated with it will no
+     * longer be accessible from Web pages. Invalidating a
+     * <code>WebContinuation</code> invalidates all the
+     * <code>WebContinuation</code>s which are children of it.
+     *
+     * @param k a <code>WebContinuation</code> value
+     */
+    public void invalidateWebContinuation(WebContinuation k);
+
+    /**
+     * Given a <code>WebContinuation</code> id, retrieve the associated
+     * <code>WebContinuation</code> object.
+     * @param id a <code>String</code> value
+     * @param interpreterId Id of an interpreter that queries for 
+     * the continuation
+     *
+     * @return a <code>WebContinuation</code> object, null if no such
+     * <code>WebContinuation</code> could be found. Also null if 
+     * <code>WebContinuation</code> was found but interpreter id does 
+     * not match the one that the continuation was initialy created for.
+     */
+    public WebContinuation lookupWebContinuation(String id, String interpreterId);
+
+    /**
+     * Prints debug information about all web continuations into the log file.
+     * @see WebContinuation#display()
+     */
+    public void displayAllContinuations();
+    
+    /**
+     * Get a list of all continuations as <code>WebContinuationDataBean</code> objects. 
+     */
+    public List getWebContinuationsDataBeanList();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
new file mode 100644
index 0000000..07de5ef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java
@@ -0,0 +1,581 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.thread.RunnableManager;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+
+
+/**
+ * The default implementation of {@link ContinuationsManager}. <br/>There are
+ * two modes of work: <br/>
+ * <ul>
+ * <li><b>standard mode </b>- continuations are stored in single holder. No
+ * security is applied to continuation lookup. Anyone can invoke a continuation
+ * only knowing the ID. Set "session-bound-continuations" configuration option
+ * to false to activate this mode.</li>
+ * <li><b>secure mode </b>- each session has it's own continuations holder. A
+ * continuation is only valid for the same session it was created for. Session
+ * invalidation causes all bound continuations to be invalidated as well. Use
+ * this setting for web applications. Set "session-bound-continuations"
+ * configuration option to true to activate this mode.</li>
+ * </ul>
+ * 
+ * @since March 19, 2002
+ * @see ContinuationsManager
+ * @version $Id$
+ */
+public class ContinuationsManagerImpl
+        extends AbstractLogEnabled
+        implements ContinuationsManager, Configurable, ThreadSafe, Serviceable, Contextualizable  {
+
+    static final int CONTINUATION_ID_LENGTH = 20;
+    static final String EXPIRE_CONTINUATIONS = "expire-continuations";
+
+    /**
+     * Random number generator used to create continuation ID
+     */
+    protected SecureRandom random;
+    protected byte[] bytes;
+
+    /**
+     * How long does a continuation exist in memory since the last
+     * access? The time is in miliseconds, and the default is 1 hour.
+     */
+    protected int defaultTimeToLive;
+
+    /**
+     * Maintains the forest of <code>WebContinuation</code> trees.
+     * This set is used only for debugging puroses by
+     * {@link #displayAllContinuations()} method.
+     */
+    protected Set forest = Collections.synchronizedSet(new HashSet());
+
+    /**
+     * Main continuations holder. Used unless continuations are stored in user
+     * session.
+     */
+    protected WebContinuationsHolder continuationsHolder;
+    
+    /**
+     * Sorted set of <code>WebContinuation</code> instances, based on
+     * their expiration time. This is used by the background thread to
+     * invalidate continuations.
+     */
+    protected SortedSet expirations = Collections.synchronizedSortedSet(new TreeSet());
+
+    protected boolean bindContinuationsToSession;
+
+    protected ServiceManager serviceManager;
+    protected Context context;
+
+    protected long expirationCheckInterval;
+    
+    public ContinuationsManagerImpl() throws Exception {
+        try {
+            random = SecureRandom.getInstance("SHA1PRNG");
+        } catch(java.security.NoSuchAlgorithmException nsae) {
+            // Maybe we are on IBM's SDK
+            random = SecureRandom.getInstance("IBMSecureRandom");
+        }
+        random.setSeed(System.currentTimeMillis());
+        bytes = new byte[CONTINUATION_ID_LENGTH];
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.serviceManager = manager;
+    }
+
+    public void configure(Configuration config) {
+        this.defaultTimeToLive = config.getAttributeAsInteger("time-to-live", (3600 * 1000));
+        this.bindContinuationsToSession = config.getAttributeAsBoolean( "session-bound-continuations", false );
+        // create a global ContinuationsHolder if this the "session-bound-continuations" parameter is set to false
+        if (!this.bindContinuationsToSession) {
+            this.continuationsHolder = new WebContinuationsHolder();
+        }
+        
+        final Configuration expireConf = config.getChild("expirations-check");
+        final long initialDelay = expireConf.getChild("offset", true).getValueAsLong(180000);
+        this.expirationCheckInterval = expireConf.getChild("period", true).getValueAsLong(180000);
+        try {
+            final RunnableManager runnableManager = (RunnableManager)serviceManager.lookup(RunnableManager.ROLE);
+            runnableManager.execute( new Runnable() {
+                    public void run()
+                    {
+                        expireContinuations();
+                    }
+                }, initialDelay, expirationCheckInterval);
+            serviceManager.release(runnableManager);
+        } catch (Exception e) {
+            getLogger().warn("Could not enqueue continuations expiration task. " +
+                             "Continuations will not automatically expire.", e);
+        }
+    }
+
+    
+    public WebContinuation createWebContinuation(Object kont,
+                                                 WebContinuation parent,
+                                                 int timeToLive,
+                                                 String interpreterId, 
+                                                 ContinuationsDisposer disposer) {
+        int ttl = (timeToLive == 0 ? defaultTimeToLive : timeToLive);
+
+        WebContinuation wk = generateContinuation(kont, parent, ttl, interpreterId, disposer);
+        wk.enableLogging(getLogger());
+
+        if (parent == null) {
+            forest.add(wk);
+        } else {
+            handleParentContinuationExpiration(parent);
+        }
+
+        handleLeafContinuationExpiration(wk);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("WK: Created continuation " + wk.getId());
+        }
+
+        return wk;
+    }
+    
+    /**
+     * When a new continuation is created in @link #createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer),
+     * it is registered in the expiration set in order to be evaluated by the invalidation mechanism.
+     */
+    protected void handleLeafContinuationExpiration(WebContinuation wk) {
+        expirations.add(wk);
+    }
+
+    /**
+     * When a new continuation is created in @link #createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer),
+     * its parent continuation is removed from the expiration set. This way only leaf continuations are part of
+     * the expiration set.
+     */
+    protected void handleParentContinuationExpiration(WebContinuation parent) {
+        if (parent.getChildren().size() < 2) {
+            expirations.remove(parent);
+        }
+    }    
+    
+    /**
+     * Get a list of all web continuations (data only)
+     */
+    public List getWebContinuationsDataBeanList() {
+        List beanList = new ArrayList();
+        for(Iterator it = this.forest.iterator(); it.hasNext();) {
+            beanList.add(new WebContinuationDataBean((WebContinuation) it.next()));
+        }
+        return beanList;
+    }
+
+    public WebContinuation lookupWebContinuation(String id, String interpreterId) {
+        // REVISIT: Is the following check needed to avoid threading issues:
+        // return wk only if !(wk.hasExpired) ?
+        WebContinuationsHolder continuationsHolder = lookupWebContinuationsHolder(false);
+        if (continuationsHolder == null)
+            return null;
+        
+        WebContinuation kont = continuationsHolder.get(id);
+        if (kont == null)
+            return null;
+            
+        if (!kont.interpreterMatches(interpreterId)) {
+            getLogger().error(
+                    "WK: Continuation (" + kont.getId()
+                            + ") lookup for wrong interpreter. Bound to: "
+                            + kont.getInterpreterId() + ", looked up for: "
+                            + interpreterId);
+            return null;
+        }
+        return kont;
+    }
+
+    /**
+     * Create <code>WebContinuation</code> and generate unique identifier for
+     * it. The identifier is generated using a cryptographically strong
+     * algorithm to prevent people to generate their own identifiers.
+     * 
+     * <p>
+     * It has the side effect of interning the continuation object in the
+     * <code>idToWebCont</code> hash table.
+     * 
+     * @param kont
+     *            an <code>Object</code> value representing continuation
+     * @param parent
+     *            value representing parent <code>WebContinuation</code>
+     * @param ttl
+     *            <code>WebContinuation</code> time to live
+     * @param interpreterId
+     *            id of interpreter invoking continuation creation
+     * @param disposer
+     *            <code>ContinuationsDisposer</code> instance to use for
+     *            cleanup of the continuation.
+     * @return the generated <code>WebContinuation</code> with unique
+     *         identifier
+     */
+    protected WebContinuation generateContinuation(Object kont,
+                                                 WebContinuation parent,
+                                                 int ttl,
+                                                 String interpreterId,
+                                                 ContinuationsDisposer disposer) {
+
+        char[] result = new char[bytes.length * 2];
+        WebContinuation wk = null;
+        WebContinuationsHolder continuationsHolder = lookupWebContinuationsHolder(true);
+        while (true) {
+            random.nextBytes(bytes);
+
+            for (int i = 0; i < CONTINUATION_ID_LENGTH; i++) {
+                byte ch = bytes[i];
+                result[2 * i] = Character.forDigit(Math.abs(ch >> 4), 16);
+                result[2 * i + 1] = Character.forDigit(Math.abs(ch & 0x0f), 16);
+            }
+
+            final String id = new String(result);
+            synchronized (continuationsHolder) {
+                if (!continuationsHolder.contains(id)) {
+                    if (this.bindContinuationsToSession)
+                        wk = new HolderAwareWebContinuation(id, kont, parent,
+                                ttl, interpreterId, disposer,
+                                continuationsHolder);
+                    else
+                        wk = new WebContinuation(id, kont, parent, ttl,
+                                interpreterId, disposer);
+                    continuationsHolder.addContinuation(wk);
+                    break;
+                }
+            }
+        }
+
+        return wk;
+    }
+
+    public void invalidateWebContinuation(WebContinuation wk) {
+        WebContinuationsHolder continuationsHolder = lookupWebContinuationsHolder(false);
+        if (!continuationsHolder.contains(wk)) {
+            //TODO this looks like a security breach - should we throw?
+            return;
+        }
+        _detach(wk);
+        _invalidate(continuationsHolder, wk);
+    }
+
+    private void _invalidate(WebContinuationsHolder continuationsHolder, WebContinuation wk) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("WK: Manual expire of continuation " + wk.getId());
+        }
+        disposeContinuation(continuationsHolder, wk);
+        expirations.remove(wk);
+
+        // Invalidate all the children continuations as well
+        List children = wk.getChildren();
+        int size = children.size();
+        for (int i = 0; i < size; i++) {
+            _invalidate(continuationsHolder, (WebContinuation) children.get(i));
+        }
+    }
+
+    /**
+     * Detach this continuation from parent. This method removes
+     * continuation from {@link #forest} set, or, if it has parent,
+     * from parent's children collection.
+     * @param continuationsHolder
+     * @param wk Continuation to detach from parent.
+     */
+    protected void _detach(WebContinuation wk) {
+        WebContinuation parent = wk.getParentContinuation();
+        if (parent == null) {
+            forest.remove(wk);
+        } else 
+            wk.detachFromParent();
+    }
+
+    /**
+     * Makes the continuation inaccessible for lookup, and triggers possible needed
+     * cleanup code through the ContinuationsDisposer interface.
+     * @param continuationsHolder
+     *
+     * @param wk the continuation to dispose.
+     */
+    protected void disposeContinuation(WebContinuationsHolder continuationsHolder, WebContinuation wk) {
+        continuationsHolder.removeContinuation(wk);
+        wk.dispose();
+    }
+
+    /**
+     * Removes an expired leaf <code>WebContinuation</code> node
+     * from its continuation tree, and recursively removes its
+     * parent(s) if it they have expired and have no (other) children.
+     * @param continuationsHolder
+     *
+     * @param wk <code>WebContinuation</code> node
+     */
+    protected void removeContinuation(WebContinuationsHolder continuationsHolder,
+            WebContinuation wk) {
+        if (wk.getChildren().size() != 0) {
+            return;
+        }
+
+        // remove access to this contination
+        disposeContinuation(continuationsHolder, wk);
+        _detach(wk);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("WK: Deleted continuation: " + wk.getId());
+        }
+
+        // now check if parent needs to be removed.
+        WebContinuation parent = wk.getParentContinuation();
+        if (null != parent && parent.hasExpired()) {
+            //parent must have the same continuations holder, lookup not needed
+            removeContinuation(continuationsHolder, parent);
+        }
+    }
+
+    /**
+     * Dump to Log file the current contents of
+     * the expirations <code>SortedSet</code>
+     */
+    protected void displayExpireSet() {
+        StringBuffer wkSet = new StringBuffer("\nWK; Expire set size: " + expirations.size());
+        Iterator i = expirations.iterator();
+        while (i.hasNext()) {
+            final WebContinuation wk = (WebContinuation) i.next();
+            final long lat = wk.getLastAccessTime() + wk.getTimeToLive();
+            wkSet.append("\nWK: ")
+                    .append(wk.getId())
+                    .append(" ExpireTime [");
+
+            if (lat < System.currentTimeMillis()) {
+                wkSet.append("Expired");
+            } else {
+                wkSet.append(lat);
+            }
+            wkSet.append("]");
+        }
+
+        getLogger().debug(wkSet.toString());
+    }
+
+    /**
+     * Dump to Log file all <code>WebContinuation</code>s
+     * in the system
+     */
+    public void displayAllContinuations() {
+        final Iterator i = forest.iterator();
+        while (i.hasNext()) {
+            ((WebContinuation) i.next()).display();
+        }
+    }
+
+    /**
+     * Remove all continuations which have already expired.
+     */
+    protected void expireContinuations() {
+        long now = 0;
+        if (getLogger().isDebugEnabled()) {
+            now = System.currentTimeMillis();
+
+            /* Continuations before clean up:
+            getLogger().debug("WK: Forest before cleanup: " + forest.size());
+            displayAllContinuations();
+            displayExpireSet();
+            */
+        }
+
+        // Clean up expired continuations
+        int count = 0;
+        WebContinuation wk;
+        Iterator i = expirations.iterator();
+        while (i.hasNext() && ((wk = (WebContinuation) i.next()).hasExpired())) {
+            i.remove();
+            WebContinuationsHolder continuationsHolder = null;
+            if ( wk instanceof HolderAwareWebContinuation )
+                continuationsHolder = ((HolderAwareWebContinuation) wk).getContinuationsHolder();
+            else
+                continuationsHolder = this.continuationsHolder;
+            removeContinuation(continuationsHolder, wk);
+            count++;
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("WK Cleaned up " + count + " continuations in " +
+                              (System.currentTimeMillis() - now));
+
+            /* Continuations after clean up:
+            getLogger().debug("WK: Forest after cleanup: " + forest.size());
+            displayAllContinuations();
+            displayExpireSet();
+            */
+        }
+    }
+
+    /**
+     * Method used by WebContinuationsHolder to notify the continuations manager
+     * about session invalidation. Invalidates all continuations held by passed
+     * continuationsHolder.
+     */
+    protected void invalidateContinuations(
+            WebContinuationsHolder continuationsHolder) {
+        // TODO: this avoids ConcurrentModificationException, still this is not
+        // the best solution and should be changed
+        Object[] continuationIds = continuationsHolder.getContinuationIds()
+                .toArray();
+        
+        for (int i = 0; i < continuationIds.length; i++) {
+            WebContinuation wk = continuationsHolder.get(continuationIds[i]);
+            if (wk != null) {
+                _detach(wk);
+                _invalidate(continuationsHolder, wk);
+            }
+        }
+    }
+
+    /**
+     * Lookup a proper web continuations holder. 
+     * @param createNew
+     *            should the manager create a continuations holder in session
+     *            when none found?
+     */
+    public WebContinuationsHolder lookupWebContinuationsHolder(boolean createNew) {
+        //there is only one holder if continuations are not bound to session
+        if (!this.bindContinuationsToSession)
+            return this.continuationsHolder;
+        
+        //if continuations bound to session lookup a proper holder in the session
+        Map objectModel = ContextHelper.getObjectModel(this.context);
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        if (!createNew && request.getSession(false) == null)
+            return null;
+
+        Session session = request.getSession(true);
+        WebContinuationsHolder holder = 
+            (WebContinuationsHolder) session.getAttribute(
+                    WebContinuationsHolder.CONTINUATIONS_HOLDER);
+        if (!createNew)
+            return holder;
+
+        if (holder != null)
+            return holder;
+
+        holder = new WebContinuationsHolder();
+        session.setAttribute(WebContinuationsHolder.CONTINUATIONS_HOLDER,
+                holder);
+        return holder;
+    }
+
+    /**
+     * A holder for WebContinuations. When bound to session notifies the
+     * continuations manager of session invalidation.
+     */
+    public class WebContinuationsHolder implements HttpSessionBindingListener {
+        private final static String CONTINUATIONS_HOLDER = 
+                                       "o.a.c.c.f.SCMI.WebContinuationsHolder";
+
+        private Map holder = Collections.synchronizedMap(new HashMap());
+
+        public WebContinuation get(Object id) {
+            return (WebContinuation) this.holder.get(id);
+        }
+
+        public void addContinuation(WebContinuation wk) {
+            this.holder.put(wk.getId(), wk);
+        }
+
+        public void removeContinuation(WebContinuation wk) {
+            this.holder.remove(wk.getId());
+        }
+
+        public Set getContinuationIds() {
+            return holder.keySet();
+        }
+        
+        public boolean contains(String continuationId) {
+            return this.holder.containsKey(continuationId);
+        }
+        
+        public boolean contains(WebContinuation wk) {
+            return contains(wk.getId());
+        }
+
+        public void valueBound(HttpSessionBindingEvent event) {
+        }
+
+        public void valueUnbound(HttpSessionBindingEvent event) {
+            invalidateContinuations(this);
+        }
+    }
+
+    /**
+     * WebContinuation extension that holds also the information about the
+     * holder. This information is needed to cleanup a proper holder after
+     * continuation's expiration time.
+     */
+    protected class HolderAwareWebContinuation extends WebContinuation {
+        private WebContinuationsHolder continuationsHolder;
+
+        public HolderAwareWebContinuation(String id, Object continuation,
+                WebContinuation parentContinuation, int timeToLive,
+                String interpreterId, ContinuationsDisposer disposer,
+                WebContinuationsHolder continuationsHolder) {
+            super(id, continuation, parentContinuation, timeToLive,
+                    interpreterId, disposer);
+            this.continuationsHolder = continuationsHolder;
+        }
+
+        public WebContinuationsHolder getContinuationsHolder() {
+            return continuationsHolder;
+        }
+
+        //retain comparation logic from parent
+        public int compareTo(Object other) {
+            return super.compareTo(other);
+        }
+    }
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;        
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImplMBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImplMBean.java
new file mode 100644
index 0000000..187e1b4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImplMBean.java
@@ -0,0 +1,97 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.flow;
+
+
+import org.mortbay.util.jmx.ModelMBeanImpl;
+
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+
+/**
+ * The ContinuationsManagerImplMBean adds JMX managability for ContinuationsManagerImpl.
+ *
+ * @version $Id: ThreadSafeComponentHandler.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class ContinuationsManagerImplMBean
+extends ModelMBeanImpl {
+    
+    private final ContinuationsManagerImpl manager;
+    
+    protected void defineManagedResource() {
+        super.defineManagedResource();
+        defineAttribute("defaultTimeToLive", false, true);
+        defineAttribute("bindContinuationsToSession", false, true);
+        defineAttribute("expirationCheckInterval", false, true);
+        defineAttribute("expirationSet", false, true);
+    }
+    /**
+     * Construction of PoolableComponentHandlerMBean
+     *
+     * @param manager The managed ContinuationsManager instance
+     */
+    public ContinuationsManagerImplMBean(final ContinuationsManagerImpl manager)
+        throws MBeanException, InstanceNotFoundException {
+        super( manager );
+        this.manager = manager;
+    }
+    
+    public int getDefaultTimeToLive() {
+        return manager.defaultTimeToLive;
+    }
+    
+    public void setDefaultTimeToLive(final int ttl) {
+        manager.defaultTimeToLive = ttl;
+    }
+    
+    public boolean getBindContinuationsToSession() {
+        return manager.bindContinuationsToSession;
+    }
+    
+    public long getExpirationCheckInterval() {
+        return manager.expirationCheckInterval;
+    }
+    
+    public String[] getExpirationSet() {
+        final String [] lines = new String[ manager.expirations.size()];
+        int idx = 0;
+        for(final Iterator i = manager.expirations.iterator(); i.hasNext(); ) {
+            final StringBuffer wkSet = new StringBuffer();
+            final WebContinuation wk = (WebContinuation) i.next();
+            final long lat = wk.getLastAccessTime() + wk.getTimeToLive();
+            wkSet.append("WK: ")
+                    .append(wk.getId())
+                    .append(" ExpireTime [");
+
+            if (lat < System.currentTimeMillis()) {
+                wkSet.append("Expired");
+            } else {
+                final Date date = new Date();
+                date.setTime(lat);
+                wkSet.append(date);
+            }
+            wkSet.append("]");
+            lines[idx++] = wkSet.toString();
+        }
+        return lines;
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/FlowHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/FlowHelper.java
new file mode 100644
index 0000000..7e0ddc9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/FlowHelper.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow;
+
+import org.mozilla.javascript.Undefined;
+import org.mozilla.javascript.Wrapper;
+
+import java.util.Map;
+
+/**
+ * Provides the interface between the flow controller layer and the 
+ * view layer. A view can obtain the context object sent by a flow
+ * script and the current web continuation, if any.
+ */
+public class FlowHelper {
+
+    // Constants defining keys in the object model used to store the various objects.
+    // These constants are private so that access to these objects only go through the
+    // accessors provided below.
+    //
+    // These objects are stored in the object model rather than as request attributes,
+    // as object model is cloned for subrequests (see EnvironmentWrapper), whereas
+    // request attributes are shared between the "real" request and all of its
+    // child requests.
+
+    /**
+     * Request attribute name used to store flow context.
+     */
+    private static final String CONTEXT_OBJECT = "cocoon.flow.context";
+
+    /**
+     * Request attribute name used to store flow continuation.
+     */
+    private static final String CONTINUATION_OBJECT = "cocoon.flow.continuation";
+
+    /**
+     * Get the flow context object associated with the current request
+     *
+     * @param objectModel The Cocoon Environment's object model
+     * @return The context object 
+     */
+    public final static Object getContextObject(Map objectModel) {
+        return objectModel.get(CONTEXT_OBJECT);
+    }
+
+    /**
+     * Get the web continuation associated with the current request
+     *
+     * @param objectModel The Cocoon Environment's object model
+     * @return The web continuation
+     */
+    public final static WebContinuation getWebContinuation(Map objectModel) {
+        return (WebContinuation)objectModel.get(CONTINUATION_OBJECT);
+    }
+
+    /**
+     * Set the web continuation associated with the current request
+     *
+     * @param objectModel The Cocoon Environment's object model
+     * @param kont The web continuation
+     */
+    public final static void setWebContinuation(Map objectModel,
+                                          WebContinuation kont) {
+        objectModel.put(CONTINUATION_OBJECT, kont);
+    }
+
+    /**
+     * Set the flow context object associated with the current request
+     *
+     * @param objectModel The Cocoon Environment's object model
+     * @param obj The context object 
+     */
+    public final static void setContextObject(Map objectModel, Object obj) {
+        objectModel.put(CONTEXT_OBJECT, obj);
+    }
+    
+    /**
+     * Unwrap a Rhino object (getting the raw java object) and convert undefined to null
+     */
+    public static Object unwrap(Object obj) {
+        if (obj instanceof Wrapper) {
+            obj = ((Wrapper)obj).unwrap();
+        } else if (obj == Undefined.instance) {
+            obj = null;
+        }
+        return obj;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/Interpreter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/Interpreter.java
new file mode 100644
index 0000000..7e726a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/Interpreter.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import org.apache.cocoon.environment.Redirector;
+
+import java.util.List;
+
+/**
+ * The interface to the flow scripting languages. This interface is
+ * for a component, which implements the appropriate language to be
+ * used for describing the flow. A system could have multiple
+ * components that implement this interface, each of them for a
+ * different scripting language.
+ *
+ * <p>A flow script defines what is the page flow in an interactive
+ * Web application. Usually the flow is defined in a high level
+ * programming language which provides the notion of continuations,
+ * which allows for the flow of the application to be described as a
+ * simple procedural program, without having to think about the
+ * application as a finite state machine which changes its internal
+ * state on each HTTP request from the client browser.
+ *
+ * <p>However an implementation may choose to use its own
+ * representation of an application, which may include XML
+ * representations of finite state machines. Note: this API has no
+ * provision for such implementations.
+ *
+ * <p>The component represented by this interface is called in three
+ * situations:
+ *
+ * <ul>
+ *  <li>
+ *    <p>From the sitemap, to invoke a top level function defined in a
+ *    * given implementation language of the flow. This is done from
+ *    the * sitemap using the construction:
+ *
+ *    <pre>
+ *      &lt;map:call function="..." language="..."/&gt;
+ *    </pre>
+ *
+ *    <p>The <code>language</code> attribute can be ignored if the *
+ *    default language is used.
+ *
+ *  <li>
+ *    <p>From the sitemap, to continue a previously started
+ *    computation. A previously started computation is saved in the
+ *    form of a continuation inside the flow implementation language.
+ *
+ *    <p>This case is similar with the above one, but the function
+ *    invoked has a special name, specific to each language
+ *    implementation. See the language implementation for more
+ *    information on the function name and the arguments it receives.
+ *
+ *  <li>
+ *    <p>From a program in the flow layer. This is done to invoke a
+ *    pipeline defined in the sitemap, to generate the response of the
+ *    request.
+ * </ul>
+ *
+ * @since March 11, 2002
+ * @version $Id$
+ */
+public interface Interpreter {
+
+    public static class Argument {
+        public String name;
+        public String value;
+
+        public Argument(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        public String toString() {
+            return name + ": " + value;
+        }
+    }
+
+    public static final String ROLE = Interpreter.class.getName();
+
+	/**
+	 * @return the unique ID for this interpreter.
+	 */
+	String getInterpreterID();
+	
+	/**
+     * Set the unique ID for this interpreter.
+     */
+    void setInterpreterID(String interpreterID);
+
+    /**
+     * This method is called from the sitemap, using the syntax
+     *
+     * <pre>
+     *   &lt;map:call function="..."/&gt;
+     * </pre>
+     *
+     * The method will execute the named function, which must be defined
+     * in the given language. There is no assumption made on how various
+     * arguments are passed to the function.
+     *
+     * <p>The <code>params</code> argument is a <code>List</code> object
+     * that contains <code>Interpreter.Argument</code> instances,
+     * representing the parameters to be passed to the called
+     * function. An <code>Argument</code> instance is a key-value pair,
+     * where the key is the name of the parameter, and the value is its
+     * desired value. Most languages will ignore the name value and
+     * simply pass to the function, in a positional order, the values of
+     * the argument. Some languages however can pass the arguments in a
+     * different order than the original prototype of the function. For
+     * these languages the ability to associate the actual argument with
+     * a formal parameter using its name is essential.
+     *
+     * <p>A particular language implementation may decide to put the
+     * environment, request, response etc. objects in the dynamic scope
+     * available to the function at the time of the call. Other
+     * implementations may decide to pass these as arguments to the
+     * called function.
+     *
+     * <p>The current implementation assumes the sitemap implementation
+     * is TreeProcessor.
+     *
+     * @param funName a <code>String</code> value, the name of the
+     * function to call
+     * @param params a <code>List</code> object whose components are
+     * CallFunctionNode.Argument instances. The interpretation of the
+     * parameters is left to the actual implementation of the
+     * interpreter.
+     * @param redirector a <code>Redirector</code> used to call views
+     */
+    void callFunction(String funName, List params, Redirector redirector)
+    throws Exception;
+
+    /**
+     * Forward the request to a Cocoon pipeline.
+     *
+     * @param uri a <code>String</code>, the URI of the forwarded request
+     * @param bizData an <code>Object</code>, the business data object
+     * to be made available to the forwarded pipeline
+     * @param continuation a <code>WebContinuation</code>, the
+     * continuation to be called to resume the processing
+     * @param redirector a <code>Redirector</code> used to call views
+     * @exception Exception if an error occurs
+     */
+    void forwardTo(String uri, Object bizData, WebContinuation continuation,
+                   Redirector redirector)
+    throws Exception;
+
+    /**
+     * Continues a previously started processing. The continuation
+     * object where the processing should start from is indicated by the
+     * <code>continuationId</code> string.
+     *
+     * @param continuationId a <code>String</code> value
+     *
+     * @param params a <code>List</code> value, containing the
+     * parameters to be passed when invoking the continuation. As
+     * opposed to the parameters passed by <code>callFunction</code>,
+     * these parameters will only become available in the language's
+     * environment, if at all.
+     *
+     * @param redirector a <code>Redirector</code> used to call views
+     * @exception Exception if an error occurs
+     */
+    void handleContinuation(String continuationId, List params,
+                            Redirector redirector)
+    throws Exception;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
new file mode 100644
index 0000000..dfa4a7a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/InvalidContinuationException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow;
+
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * This Exception is thrown whenever an invalid continuation is given.
+ *
+ * @version $Id$
+ */
+public class InvalidContinuationException extends ProcessingException {
+
+    /**
+     * Construct a new <code>InvalidContinuationException</code> instance.
+     */
+    public InvalidContinuationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct a new <code>InvalidContinuationException</code> that references
+     * a parent Exception.
+     */
+    public InvalidContinuationException(String message, Throwable t) {
+        super(message, t);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuation.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuation.java
new file mode 100644
index 0000000..98caced
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuation.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.commons.collections.iterators.IteratorEnumeration;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Representation of continuations in a Web environment.
+ *
+ * <p>Because a user may click on the back button of the browser and
+ * restart a saved computation in a continuation, each
+ * <code>WebContinuation</code> becomes the parent of a subtree of
+ * continuations.
+ *
+ * <p>If there is no parent <code>WebContinuation</code>, the created
+ * continuation becomes the root of a tree of
+ * <code>WebContinuation</code>s.
+ *
+ * @since March 19, 2002
+ * @version $Id$
+ */
+public class WebContinuation extends AbstractLogEnabled
+                             implements Comparable {
+
+    /**
+     * The continuation this object represents.
+     */
+    protected Object continuation;
+
+    /**
+     * The parent <code>WebContinuation</code> from which processing
+     * last started. If null, there is no parent continuation
+     * associated, and this is the first one to be created in a
+     * processing. In this case this <code>WebContinuation</code>
+     * instance becomes the root of the tree maintained by the
+     * <code>ContinuationsManager</code>.
+     *
+     * @see ContinuationsManager
+     */
+    protected WebContinuation parentContinuation;
+
+    /**
+     * The children continuations. These are continuations created by
+     * resuming the processing from the point stored by
+     * <code>continuation</code>.
+     */
+    protected List children = new ArrayList();
+
+    /**
+     * The continuation id used to represent this instance in Web pages.
+     */
+    protected String id;
+    
+    /**
+     * Interpreter id that this continuation is bound to
+     */
+    protected String interpreterId;
+
+    /**
+     * A user definable object. This is present for convenience, to
+     * store any information associated with this
+     * <code>WebContinuation</code> a particular implementation might
+     * need.
+     */
+    protected Object userObject;
+
+    /**
+     * When was this continuation accessed last time. Each time the
+     * continuation is accessed, this time is set to the time of the
+     * access.
+     */
+    protected long lastAccessTime;
+
+    /**
+     * Indicates how long does this continuation will live (in
+     * seconds). The continuation will be removed once the current time
+     * is bigger than <code>lastAccessTime + timeToLive</code>.
+     */
+    protected int timeToLive;
+
+    /**
+     * Holds the <code>ContinuationsDisposer</code> to call when this continuation
+     * gets invalidated.
+     */
+    protected ContinuationsDisposer disposer;
+
+    /**
+     * The attributes of this continuation
+     */
+    private Map attributes;
+
+    /**
+     * Create a <code>WebContinuation</code> object. Saves the object in
+     * the hash table of continuations maintained by
+     * <code>manager</code> (this is done as a side effect of obtaining
+     * and identifier from it).
+     *
+     * @param continuation an <code>Object</code> value
+     * @param parentContinuation a <code>WebContinuation</code> value
+     * @param timeToLive time this continuation should live
+     * @param disposer a <code>ContinuationsDisposer</code> to call when this
+     * continuation gets invalidated.
+     */
+    WebContinuation(String id,
+                    Object continuation,
+                    WebContinuation parentContinuation,
+                    int timeToLive,
+                    String interpreterId,
+                    ContinuationsDisposer disposer) {
+        this.id = id;
+        this.continuation = continuation;
+        this.parentContinuation = parentContinuation;
+        this.updateLastAccessTime();
+        this.timeToLive = timeToLive;
+        this.interpreterId = interpreterId;
+        this.disposer = disposer;
+
+        if (parentContinuation != null) {
+            this.parentContinuation.children.add(this);
+        }
+    }
+
+    /**
+     * Get an attribute of this continuation
+     * 
+     * @param name the attribute name.
+     */
+    public Object getAttribute(String name) {
+        if (this.attributes == null)
+            return null;
+        
+        return this.attributes.get(name);
+    }
+    
+    /**
+     * Set an attribute of this continuation
+     * 
+     * @param name the attribute name
+     * @param value its value
+     */
+    public void setAttribute(String name, Object value) {
+        if (this.attributes == null) {
+            this.attributes = Collections.synchronizedMap(new HashMap());
+        }
+        
+        this.attributes.put(name, value);
+    }
+    
+    /**
+     * Remove an attribute of this continuation
+     * 
+     * @param name the attribute name
+     */
+    public void removeAttribute(String name) {
+        if (this.attributes == null)
+            return;
+        
+        this.attributes.remove(name);
+    }
+    
+    /**
+     * Enumerate the attributes of this continuation.
+     * 
+     * @return an enumeration of strings
+     */
+    public Enumeration getAttributeNames() {
+        if (this.attributes == null)
+            return new IteratorEnumeration();
+        
+        ArrayList keys = new ArrayList(this.attributes.keySet());
+        return new IteratorEnumeration(keys.iterator());
+    }
+
+    /**
+     * Return the continuation object.
+     *
+     * @return an <code>Object</code> value
+     */
+    public Object getContinuation() {
+        updateLastAccessTime();
+        return continuation;
+    }
+
+    /**
+     * Return the ancestor continuation situated <code>level</code>s
+     * above the current continuation. The current instance is
+     * considered to be at level 0. The parent continuation of the
+     * receiving instance at level 1, its parent is at level 2 relative
+     * to the receiving instance. If <code>level</code> is bigger than
+     * the depth of the tree, the root of the tree is returned.
+     *
+     * @param level an <code>int</code> value
+     * @return a <code>WebContinuation</code> value
+     */
+    public WebContinuation getContinuation(int level) {
+        if (level <= 0) {
+            updateLastAccessTime();
+            return this;
+        } else if (parentContinuation == null) {
+            return this;
+        } else {
+            return parentContinuation.getContinuation(level - 1);
+        }
+    }
+
+    /**
+     * Return the parent <code>WebContinuation</code>. Equivalent with
+     * <code>getContinuation(1)</code>.
+     *
+     * @return a <code>WebContinuation</code> value
+     */
+    public WebContinuation getParentContinuation() {
+        return parentContinuation;
+    }
+
+    /**
+     * Return the children <code>WebContinuation</code> which were
+     * created as a result of resuming the processing from the current
+     * <code>continuation</code>.
+     *
+     * @return a <code>List</code> value
+     */
+    public List getChildren() {
+        return children;
+    }
+
+    /**
+     * Returns the string identifier of this
+     * <code>WebContinuation</code>.
+     *
+     * @return a <code>String</code> value
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Returns the string identifier of the interpreter to which
+     * this <code>WebContinuation</code> is bound.
+     *
+     * @return a <code>String</code> value
+     */
+    public String getInterpreterId() {
+        return interpreterId;
+    }
+
+    /**
+     * Returns the last time this
+     * <code>WebContinuation</code> was accessed.
+     *
+     * @return a <code>long</code> value
+     */
+    public long getLastAccessTime() {
+        return lastAccessTime;
+    }
+
+    /**
+     * Returns the the timetolive for this
+     * <code>WebContinuation</code>.
+     *
+     * @return a <code>long</code> value
+     */
+    public long getTimeToLive() {
+        return this.timeToLive;
+    }
+
+    /**
+     * Sets the user object associated with this instance.
+     *
+     * @param obj an <code>Object</code> value
+     */
+    public void setUserObject(Object obj) {
+        this.userObject = obj;
+    }
+
+    /**
+     * Obtains the user object associated with this instance.
+     *
+     * @return an <code>Object</code> value
+     */
+    public Object getUserObject() {
+        return userObject;
+    }
+
+    /**
+     * Obtains the <code>ContinuationsDisposer</code> to call when this continuation
+     * is invalidated.
+     *
+     * @return a <code>ContinuationsDisposer</code> instance or null if there are
+     * no specific clean-up actions required.
+     */
+    ContinuationsDisposer getDisposer() {
+        return this.disposer;
+    }
+
+    /**
+     * Returns the hash code of the associated identifier.
+     *
+     * @return an <code>int</code> value
+     */
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    /**
+     * True if the identifiers are the same, false otherwise.
+     *
+     * @param another an <code>Object</code> value
+     * @return a <code>boolean</code> value
+     */
+    public boolean equals(Object another) {
+        if (another instanceof WebContinuation) {
+            return id.equals(((WebContinuation) another).id);
+        }
+        return false;
+    }
+
+    /**
+     * Compares the expiration time of this instance with that of the
+     * WebContinuation passed as argument.
+     *
+     * <p><b>Note:</b> this class has a natural ordering that is
+     * inconsistent with <code>equals</code>.</p>.
+     *
+     * @param other an <code>Object</code> value, which should be a
+     * <code>WebContinuation</code> instance
+     * @return an <code>int</code> value
+     */
+    public int compareTo(Object other) {
+        WebContinuation wk = (WebContinuation) other;
+        return (int) ((lastAccessTime + timeToLive)
+                - (wk.lastAccessTime + wk.timeToLive));
+    }
+
+    /**
+     * Debugging method.
+     *
+     * <p>Assumes the receiving instance as the root of a tree and
+     * displays the tree of continuations.
+     */
+    public void display() {
+        getLogger().debug("\nWK: Tree" + display(0));
+    }
+
+    /**
+     * Debugging method.
+     *
+     * <p>Displays the receiving instance as if it is at the
+     * <code>indent</code> depth in the tree of continuations. Each
+     * level is indented 2 spaces.
+     *
+     * @param depth an <code>int</code> value
+     */
+    protected String display(int depth) {
+        StringBuffer tree = new StringBuffer("\n");
+        for (int i = 0; i < depth; i++) {
+            tree.append("  ");
+        }
+
+        tree.append("WK: WebContinuation ")
+                .append(id)
+                .append(" ExpireTime [");
+
+        if ((lastAccessTime + timeToLive) < System.currentTimeMillis()) {
+            tree.append("Expired");
+        } else {
+            tree.append(lastAccessTime + timeToLive);
+        }
+
+        tree.append("]");
+
+        // REVISIT: is this needed for some reason?
+        // System.out.print(spaces); System.out.println("WebContinuation " + id);
+
+        int size = children.size();
+        depth++;
+
+        for (int i = 0; i < size; i++) {
+            tree.append(((WebContinuation) children.get(i)).display(depth));
+        }
+
+        return tree.toString();
+    }
+
+    /**
+     * Update the continuation in the
+     */
+    protected void updateLastAccessTime() {
+        lastAccessTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Determines whether this continuation has expired
+     *
+     * @return a <code>boolean</code> value
+     */
+    public boolean hasExpired() {
+        long currentTime = System.currentTimeMillis();
+        long expireTime = this.getLastAccessTime() + this.timeToLive;
+
+        return (currentTime > expireTime);
+    }
+
+    /**
+     * Dispose this continuation. Should be called on invalidation.
+     */
+    public void dispose() {
+        // Call possible implementation-specific clean-up on this continuation.
+        if (this.disposer != null) {
+            this.disposer.disposeContinuation(this);
+        }
+        // Remove continuation object - will also serve as "disposed" flag
+        this.continuation = null;
+    }
+
+    /**
+     * Return true if this continuation was disposed of
+     */
+    public boolean disposed() {
+        return this.continuation == null;
+    }
+    
+    public boolean interpreterMatches( String interpreterId ) {
+        return StringUtils.equals( this.interpreterId, interpreterId );
+    }
+
+    public void detachFromParent() {
+        if (getParentContinuation() != null)
+            getParentContinuation().getChildren().remove(this);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuationDataBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuationDataBean.java
new file mode 100644
index 0000000..2ae90ea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/WebContinuationDataBean.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Access to continuation data for monitoring applications
+ */
+public class WebContinuationDataBean {
+
+    private static final String TYPE_JAVAFLOW = "javaflow";
+    private static final String TYPE_FLOWSCRIPT = "flowscript";
+    private static final String HAS_EXPIRED_NO = "no";
+    private static final String HAS_EXPIRED_YES = "yes";
+
+    private WebContinuation wc;
+    private SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
+    private List _children = new ArrayList();
+
+    public WebContinuationDataBean(WebContinuation wc) {
+        this.wc = wc;
+        for (Iterator it = wc.getChildren().iterator(); it.hasNext();) {
+            WebContinuationDataBean child = new WebContinuationDataBean(
+                    (WebContinuation) it.next());
+            this._children.add(child);
+        }
+    }
+
+    public String getId() {
+        return wc.getId();
+    }
+
+    public String getLastAccessTime() {
+        return formatter.format(new Date(wc.getLastAccessTime()));
+    }
+
+    public String getInterpreterId() {
+        return wc.getInterpreterId();
+    }
+
+    public String getTimeToLiveInMinutes() {
+        return Long.toString(wc.getTimeToLive() / 1000 / 60);
+    }
+
+    public String getTimeToLive() {
+        return Long.toString(wc.getTimeToLive());
+    }
+
+    public String getExpireTime() {
+        return formatter.format(new Date(wc.getLastAccessTime()
+                + wc.getTimeToLive()));
+    }
+
+    public String hasExpired() {
+        if ((wc.getLastAccessTime() + wc.getTimeToLive()) < System
+                .currentTimeMillis()) {
+            return HAS_EXPIRED_YES;
+        }
+        return HAS_EXPIRED_NO;
+
+    }
+
+    public String getType() {
+        if (wc.getUserObject().getClass().getName().indexOf(
+                "FOM_WebContinuation") > 0) {
+            return TYPE_FLOWSCRIPT;
+        }
+        return TYPE_JAVAFLOW;
+    }
+
+    public List get_children() {
+        return this._children;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/JSErrorReporter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/JSErrorReporter.java
new file mode 100644
index 0000000..16cf7a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/JSErrorReporter.java
@@ -0,0 +1,124 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.components.flow.javascript;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+/**
+ * Implements a Rhino JavaScript {@link
+ * org.mozilla.javascript.ErrorReporter}. 
+ * Like ToolErrorReporter but logs to supplied logger instead of stdout
+ *
+ * @version $Id$
+ */
+public class JSErrorReporter implements ErrorReporter
+{
+  private Logger logger;
+  private Location location;
+  private StringBuffer message;
+
+  public JSErrorReporter(Logger logger)
+  {
+      this.logger = logger;
+  }
+  
+  private void appendMessage(String text, String sourceName, int line, int column) {
+      if (location == null) {
+          location = new LocationImpl(null, sourceName, line, column);
+          message = new StringBuffer();
+      } else {
+          // Append a linefeed
+          message.append("\n");
+      }
+      
+      message.append(text);
+  }
+
+  public void error(String message,
+                    String sourceName, int line,
+                    String lineSrc, int column)
+  {
+      String errMsg = getErrorMessage("msg.error", message, 
+                                      sourceName, line, lineSrc, column);
+      appendMessage(errMsg, sourceName, line, column);
+      System.err.println(errMsg);
+      logger.error(errMsg);
+  }
+
+  public void warning(String message, String sourceName, int line,
+                      String lineSrc, int column)
+  {
+      String errMsg = getErrorMessage("msg.warning", message, 
+                                    sourceName, line, lineSrc, column);
+      appendMessage(errMsg, sourceName, line, column);
+      System.err.println(errMsg);
+      logger.warn(errMsg);
+  }
+    
+  public EvaluatorException runtimeError(String message, String sourceName,
+                                         int line, String lineSrc,
+                                         int column)
+  {
+      String errMsg = getErrorMessage("msg.error", message,
+                                      sourceName, line,
+                                      lineSrc, column);
+      appendMessage(errMsg, sourceName, line, column);
+      System.err.println(errMsg);
+      // FIXME(SW): need to build a locatable extension to EvaluatorException
+      return new EvaluatorException(this.message.toString());
+  }
+
+  /**
+   * Formats error message
+   *
+   * @param type a <code>String</code> value, indicating the error
+   * type (error or warning)
+   * @param message a <code>String</code> value, the error or warning
+   * message
+   * @param line an <code>int</code> value, the original cummulative
+   * line number
+   * @param lineSource a <code>String</code> value, the text of the
+   * line in the file
+   * @param column an <code>int</code> value, the column in
+   * <code>lineSource</code> where the error appeared
+   * @return a <code>String</code> value, the aggregated error
+   * message, with the source file and line number adjusted to the
+   * real values
+   */
+    String getErrorMessage(String type,
+                           String message,
+                           String sourceName, int line,
+                           String lineSource, int column)
+    {
+        if (line > 0) {
+            if (sourceName != null) {
+                Object[] errArgs = { sourceName, new Integer(line), message };
+                return ToolErrorReporter.getMessage("msg.format3", errArgs);
+          } else {
+              Object[] errArgs = { new Integer(line), message };
+              return ToolErrorReporter.getMessage("msg.format2", errArgs);
+            }
+        } else {
+            Object[] errArgs = { message };
+            return ToolErrorReporter.getMessage("msg.format1", errArgs);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java
new file mode 100644
index 0000000..e2bde94
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/LocationTrackingDebugger.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.cocoon.util.location.LocationUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.EcmaError;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.debug.DebugFrame;
+import org.mozilla.javascript.debug.DebuggableScript;
+import org.mozilla.javascript.debug.Debugger;
+
+/**
+ * A Rhino debugger that tracks location information when an exception is raised in some JavaScript code.
+ * It's purpose is to build a {@link org.apache.cocoon.ProcessingException} that holds the stacktrace
+ * in the JavaScript code.
+ * <p>
+ * This debugger implementation is designed to be as lightweight and fast as possible, in order to have a
+ * negligible impact on the performances of the Rhino interpreter.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocationTrackingDebugger implements Debugger {
+    
+    // Strong reference to the location finder
+    private static final LocationUtils.LocationFinder rhinoLocFinder = new LocationUtils.LocationFinder() {
+
+        public Location getLocation(Object obj, String description) {
+            if (obj instanceof EcmaError) {
+                EcmaError ex = (EcmaError)obj;
+                if (ex.sourceName() != null) {
+                    return new LocationImpl(ex.getName(), ex.sourceName(), ex.lineNumber(), ex.columnNumber());
+                } else {
+                    return Location.UNKNOWN;
+                }
+    
+            } else if (obj instanceof JavaScriptException) {
+                JavaScriptException ex = (JavaScriptException)obj;
+                if (ex.sourceName() != null) {
+                    return new LocationImpl(description, ex.sourceName(), ex.lineNumber(), -1);
+                } else {
+                    return Location.UNKNOWN;
+                }
+            }
+            
+            return null;
+        } 
+    };
+
+    
+    static {
+        // Register what's needed to analyze exceptions produced by Rhino
+        ExceptionUtils.addCauseMethodName("getWrappedException");
+        LocationUtils.addFinder(rhinoLocFinder);
+    }
+    
+    private List locations;
+    private Throwable throwable;
+    
+    public void handleCompilationDone(Context cx, DebuggableScript fnOrScript, String source) {
+        // nothing
+    }
+
+    public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
+        return new StackTrackingFrame(fnOrScript);
+    }
+
+    /**
+     * Get an exception that reflects the known location stack
+     *
+     * @param description a description for the exception
+     * @param originalException the original exception
+     * 
+     * @return a suitable exception to throw
+     * @see ProcessingException#throwLocated(String, Throwable, Location)
+     */
+    public Exception getException(String description, Exception originalException) throws ProcessingException {
+        if (throwable == null || locations == null) {
+            // Cannot to better for now
+            return originalException;
+        }
+
+        // Unwrap original exception, if any, wrapped by Rhino (the wrapping
+        // class is different in Rhino+cont and Rhino 1.6)
+        Throwable cause = ExceptionUtils.getCause(throwable);
+        if (cause != null)
+            throwable = cause;
+
+        return ProcessingException.throwLocated(description, throwable, locations);
+    }
+
+    private class StackTrackingFrame implements DebugFrame {
+        
+        DebuggableScript script;
+        int line;
+
+        public StackTrackingFrame(DebuggableScript script) {
+            this.script = script;
+        }
+        
+        public void onEnter(Context cx, Scriptable activation, Scriptable thisObj, Object[] args) {
+            // nothing
+        }
+        
+        public void onLineChange(Context cx, int lineNumber) {
+            line = lineNumber;
+        }
+
+        public void onExceptionThrown(Context cx, Throwable ex) {
+            throwable = ex;
+        }
+
+        public void onExit(Context cx, boolean byThrow, Object resultOrException) {
+            if (byThrow) {
+                String name = null;
+                if (script.isFunction()) {
+                    name = script.getFunctionName();
+                } else {
+                    name = "[script]";
+                }
+
+                if (locations == null) {
+                    locations = new ArrayList(1); // start small
+                }
+
+                locations.add(new LocationImpl(name, script.getSourceName(), line, -1));
+
+            } else if (locations != null) {
+                // The exception was handled by the script: clear any recorded locations
+                locations = null;
+            }
+        }
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptableMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptableMap.java
new file mode 100644
index 0000000..e760a61
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptableMap.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import org.mozilla.javascript.NativeJavaObject;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.Wrapper;
+
+import java.util.Map;
+
+/**
+ * Wrap a java.util.Map for JavaScript.
+ *
+ * @version $Id$
+ */
+public class ScriptableMap implements Scriptable, Wrapper {
+
+    private Map map;
+    private Scriptable prototype, parent;
+
+    public ScriptableMap() {
+    }
+
+    public ScriptableMap(Map map) {
+        this.map = map;
+    }
+
+    public String getClassName() {
+        return "Map";
+    }
+
+    public boolean has(String name, Scriptable start) {
+        return this.map.containsKey(name);
+    }
+
+    /**
+     * no numeric properties
+     */
+    public boolean has(int index, Scriptable start) {
+        return false;
+    }
+
+    public Object get(String name, Scriptable start) {
+        if (this.map.containsKey(name))
+            return this.map.get(name);
+
+        return NOT_FOUND;
+    }
+
+    public Object get(int index, Scriptable start) {
+        return NOT_FOUND;
+    }
+
+    public void put(String name, Scriptable start, Object value) {
+        if (value instanceof NativeJavaObject) {
+            value = ((NativeJavaObject)value).unwrap();
+        }
+        map.put(name, value);
+    }
+
+    public void put(int index, Scriptable start, Object value) {
+    }
+
+    public void delete(String id) {
+        map.remove(id);
+    }
+
+    public void delete(int index) {
+    }
+
+    public Scriptable getPrototype() {
+        return prototype;
+    }
+
+    public void setPrototype(Scriptable prototype) {
+        this.prototype = prototype;
+    }
+
+    public Scriptable getParentScope() {
+        return parent;
+    }
+
+    public void setParentScope(Scriptable parent) {
+        this.parent = parent;
+    }
+
+    public Object[] getIds() {
+        return this.map.keySet().toArray();
+    }
+
+    public Object getDefaultValue(Class typeHint) {
+        return this.map.toString();
+    }
+
+    public boolean hasInstance(Scriptable value) {
+        Scriptable proto = value.getPrototype();
+        while (proto != null) {
+            if (proto.equals(this)) 
+                return true;
+            proto = proto.getPrototype();
+        }
+
+        return false;
+    }
+
+    /**
+     * Return the java.util.Map that is wrapped by this class.
+     */
+    public Object unwrap() {
+        return this.map;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointer.java
new file mode 100644
index 0000000..0b529d1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointer.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import java.util.Locale;
+
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
+import org.apache.commons.jxpath.ri.model.dynamic.DynamicPointer;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Wrapper;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ScriptablePointer extends DynamicPointer {
+
+    Scriptable node;
+
+    final static ScriptablePropertyHandler handler = 
+        new ScriptablePropertyHandler();
+
+    public ScriptablePointer(NodePointer parent,
+                             QName name,
+                             Scriptable object) {
+        super(parent, name, object, handler);
+        node = object;
+    }
+
+    public ScriptablePointer(QName name,
+                             Scriptable object,
+                             Locale locale) {
+        super(name, object, handler, locale);
+        node = object;
+    }
+
+    public PropertyPointer getPropertyPointer(){
+        return new ScriptablePropertyPointer(this, handler);
+    }
+
+    public int getLength() {
+        Object obj = getBaseValue();
+        if (obj instanceof Scriptable) {
+            Scriptable node = (Scriptable)obj;
+            if (node instanceof NativeArray) {
+                return (int)((NativeArray)node).jsGet_length();
+            }
+            if (ScriptableObject.hasProperty(node, "length")) {
+                Object val = ScriptableObject.getProperty(node, "length");
+                if (val instanceof Number) {
+                    return ((Number)val).intValue();
+                }
+            }
+        }
+        return super.getLength();
+    }
+
+    public Object getImmediateNode() {
+        Object value;
+        if (index == WHOLE_COLLECTION) {
+            value = node;
+        } else {
+            value = ScriptableObject.getProperty(node, index);
+            if (value == Scriptable.NOT_FOUND) {
+                value = node; // hack: same behavior as ValueUtils.getValue()
+            } 
+        }
+        if (value instanceof Wrapper) {
+            value = ((Wrapper)value).unwrap();
+        }
+        return value;
+    }
+
+    public void setValue(Object value){
+        if (getParent() != null) {
+            getParent().setValue(value);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointerFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointerFactory.java
new file mode 100644
index 0000000..6fd9000
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePointerFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import org.apache.commons.jxpath.ri.model.NodePointerFactory;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.apache.commons.jxpath.ri.QName;
+import java.util.Locale;
+import org.mozilla.javascript.Scriptable;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ScriptablePointerFactory implements NodePointerFactory {
+
+    public int getOrder() {
+        return 1;
+    }
+
+    public NodePointer createNodePointer(QName name, Object object,
+                                         Locale locale) {
+        if (object instanceof Scriptable) {
+            return new ScriptablePointer(name, (Scriptable)object, locale);
+        }
+        return null;
+    }
+
+    public NodePointer createNodePointer(NodePointer parent,
+                                         QName name, Object object) {
+        if (object instanceof Scriptable) {
+            return new ScriptablePointer(parent, name, 
+                                         (Scriptable)object);
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyHandler.java
new file mode 100644
index 0000000..7a099ca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyHandler.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import org.apache.commons.jxpath.DynamicPropertyHandler;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+import org.mozilla.javascript.Wrapper;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ScriptablePropertyHandler implements DynamicPropertyHandler {
+
+    public Object getProperty(Object obj, String propertyName) {
+        Context cx = null;
+        try {
+            cx = Context.enter();
+            Scriptable s = (Scriptable)obj;
+            Object result = ScriptableObject.getProperty(s, propertyName);
+            if (result == Scriptable.NOT_FOUND) {
+                result = ScriptableObject.getProperty(s, "get" + propertyName.substring(0, 1).toUpperCase() + (propertyName.length() > 1 ? propertyName.substring(1) : ""));
+                if (result != Scriptable.NOT_FOUND &&
+                    result instanceof Function) {
+                    try {
+                        result = ((Function)result).call(cx, 
+                                                         ScriptableObject.getTopLevelScope(s), s, new Object[] {});
+                    } catch (JavaScriptException exc) {
+                        exc.printStackTrace();
+                        result = Undefined.instance;
+                    }
+                } 
+                if (result == Undefined.instance ||
+                    result == Scriptable.NOT_FOUND) {
+                    result = null;
+                }
+            } else if (result instanceof Wrapper) {
+                result = ((Wrapper)result).unwrap();
+            } else if (result == Undefined.instance) {
+                result = null;
+            }
+            return result;
+        } finally {
+            Context.exit();
+        }
+    }
+    
+    public String[] getPropertyNames(Object obj) {
+        Context.enter();
+        try {
+            Object[] ids;
+            if (obj instanceof ScriptableObject) {
+                ids = ((ScriptableObject)obj).getAllIds();
+            } else {
+                ids = ((Scriptable)obj).getIds();
+            }
+            String[] result = new String[ids.length];
+            for (int i = 0; i < result.length; i++) {
+                result[i] = (String)ids[i];
+            }
+            return result;
+        } finally {
+            Context.exit();
+        }
+    }
+    
+    public void setProperty(Object obj, String propertyName,
+                            Object value) {
+        Context.enter();
+        try {
+            if (!(value == null
+                  || value instanceof String 
+                  || value instanceof Number 
+                  || value instanceof Boolean)) {
+                value = Context.toObject(value, 
+                                         (Scriptable)obj);
+            }
+            ScriptableObject.putProperty((Scriptable)obj,
+                                         propertyName, value);
+        } finally {
+            Context.exit();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyPointer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyPointer.java
new file mode 100644
index 0000000..71b0dc2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/ScriptablePropertyPointer.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.jxpath.DynamicPropertyHandler;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+import org.mozilla.javascript.Wrapper;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ScriptablePropertyPointer extends DynamicPropertyPointer {
+
+    DynamicPropertyHandler handler;
+
+    public ScriptablePropertyPointer(NodePointer parent,
+                                     DynamicPropertyHandler handler) {
+        super(parent, handler);
+        this.handler = handler;
+    }
+
+    public int getLength() {
+        Object obj = getBaseValue();
+        if (obj instanceof Scriptable) {
+            Scriptable node = (Scriptable)obj;
+            if (node instanceof NativeArray) {
+                return (int)((NativeArray)node).jsGet_length();
+            }
+            if (ScriptableObject.hasProperty(node, "length")) {
+                Object val = ScriptableObject.getProperty(node, "length");
+                if (val instanceof Number) {
+                    return ((Number)val).intValue();
+                }
+            }
+        }
+        return super.getLength();
+    }
+
+    public Object getImmediateNode() {
+        Object value;
+        if (index == WHOLE_COLLECTION) {
+            value = getBaseValue();
+        }
+        else {
+            value = getBaseValue();
+            if (value instanceof Scriptable) {
+                Object property = 
+                    ScriptableObject.getProperty((Scriptable)value, index);
+                if (property != Scriptable.NOT_FOUND) { 
+                    value = property; // hack?
+                } 
+            } else {
+                return super.getImmediateNode();
+            }
+        }
+        if (value instanceof Wrapper) {
+            value = ((Wrapper)value).unwrap();
+        }
+        return value;
+    }
+
+    public Object getValue() {
+        Object val = getNode();
+        if (val instanceof NativeArray) {
+            NativeArray arr = (NativeArray)val;
+            List list = new LinkedList();
+            int len = (int)arr.jsGet_length();
+            for (int i = 0; i < len; i++) {
+                Object obj = arr.get(i, arr);
+                if (obj == Undefined.instance) {
+                    obj = null;
+                }
+                list.add(obj);
+            }
+            return list;
+        }
+        return super.getValue();
+    }
+
+    public void setValue(Object value){
+        if (index == WHOLE_COLLECTION){
+            handler.setProperty(getBean(), getPropertyName(), value);
+        } else {
+            Object val = handler.getProperty(getBean(), getPropertyName());
+            if (val instanceof Scriptable) {
+                ScriptableObject.putProperty((Scriptable)val, index, value);
+            } else {
+                super.setValue(value);
+            }
+        }
+    }
+
+    public void remove(){
+        if (index == WHOLE_COLLECTION){
+            handler.setProperty(getBean(), "length", new Integer(0));
+        } else {
+            Object val = handler.getProperty(getBean(), getPropertyName());
+            if (val instanceof Scriptable) {
+                try {
+                    ScriptableObject.deleteProperty((Scriptable)val, index);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            } else {
+                super.remove();
+            }
+        }
+    }
+
+    public boolean isCollection() {
+        Object obj = getBaseValue();
+        if (obj instanceof NativeArray) {
+            return true;
+        }
+        return super.isCollection();
+    }
+
+    public String asPath(){
+        Object obj = getBaseValue();
+        if (!(obj instanceof Scriptable)) {
+            return super.asPath();
+        }
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(getParent().asPath());
+        if (buffer.length() == 0){
+            buffer.append("/.");
+        }
+        else if (buffer.charAt(buffer.length() - 1) == '/'){
+            buffer.append('.');
+        }
+        buffer.append("[@name = '");
+        buffer.append(escape(getPropertyName()));
+        buffer.append("']");
+        if (index != WHOLE_COLLECTION && (obj instanceof NativeArray)) {
+            buffer.append('[').append(index+1).append(']');
+        }
+        return buffer.toString();
+    }
+
+    private String escape(String string){
+        int index = string.indexOf('\'');
+        while (index != -1){
+            string = string.substring(0, index) + "&apos;" + string.substring(index + 1);
+            index = string.indexOf('\'');
+        }
+        index = string.indexOf('\"');
+        while (index != -1){
+            string = string.substring(0, index) + "&quot;" + string.substring(index + 1);
+            index = string.indexOf('\"');
+        }
+        return string;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOMResourceNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOMResourceNotFoundException.java
new file mode 100644
index 0000000..0843e5e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOMResourceNotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+/**
+ * The exception thrown when the FOM classes can't find the necessary
+ * resource.
+ */
+public final class FOMResourceNotFoundException extends CascadingRuntimeException
+{
+    public FOMResourceNotFoundException(String message)
+    {
+        super(message, null);
+    }
+
+    public FOMResourceNotFoundException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_Cocoon.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_Cocoon.java
new file mode 100644
index 0000000..492915b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_Cocoon.java
@@ -0,0 +1,793 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.flow.ContinuationsManager;
+import org.apache.cocoon.components.flow.WebContinuation;
+import org.apache.cocoon.components.flow.Interpreter.Argument;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.util.ClassUtils;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.NativeJavaClass;
+import org.mozilla.javascript.NativeJavaObject;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+import org.mozilla.javascript.Wrapper;
+import org.mozilla.javascript.continuations.Continuation;
+
+/**
+ * Implementation of FOM (Flow Object Model).
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class FOM_Cocoon extends ScriptableObject {
+
+    class CallContext {
+        CallContext caller;
+        Context avalonContext;
+        ServiceManager serviceManager;
+        FOM_JavaScriptInterpreter interpreter;
+        Redirector redirector;
+        Logger logger;
+        Scriptable request;
+        Scriptable response;
+        Scriptable session;
+        Scriptable context;
+        Scriptable parameters;
+        Scriptable log;
+        WebContinuation lastContinuation;
+        FOM_WebContinuation fwk;
+        PageLocalScopeImpl currentPageLocal;
+
+        public CallContext(CallContext caller,
+                           FOM_JavaScriptInterpreter interp,
+                           Redirector redirector,
+                           ServiceManager manager,
+                           Context avalonContext,
+                           Logger logger,
+                           WebContinuation lastContinuation) {
+            this.caller = caller;
+            this.interpreter = interp;
+            this.redirector = redirector;
+            this.serviceManager = manager;
+            this.avalonContext = avalonContext;
+            this.logger = logger;
+            this.lastContinuation = lastContinuation;
+            if (lastContinuation != null) {
+                fwk = new FOM_WebContinuation(lastContinuation);
+                Scriptable scope = FOM_Cocoon.this.getParentScope();
+                fwk.setParentScope(scope);
+                fwk.setPrototype(getClassPrototype(scope, fwk.getClassName()));
+                this.currentPageLocal = fwk.getPageLocal();
+            }
+            if (this.currentPageLocal != null) {
+                // "clone" the page local scope
+                this.currentPageLocal = this.currentPageLocal.duplicate();
+            } else {
+                this.currentPageLocal = new PageLocalScopeImpl(getTopLevelScope(FOM_Cocoon.this));
+            }
+            pageLocal.setDelegate(this.currentPageLocal);
+        }
+
+        public FOM_WebContinuation getLastContinuation() {
+            return fwk;
+        }
+
+        public void setLastContinuation(FOM_WebContinuation fwk) {
+            this.fwk = fwk;
+            if (fwk != null) {
+                pageLocal.setDelegate(fwk.getPageLocal());
+                this.lastContinuation = fwk.getWebContinuation();
+            } else {
+                this.lastContinuation = null;
+            }
+        }
+
+        public Scriptable getSession() {
+            if (session != null) {
+                return session;
+            }
+            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);            
+            session = new FOM_Session(
+                    getParentScope(),
+                    ObjectModelHelper.getRequest(objectModel).getSession(true));
+            return session;
+        }
+
+        public Scriptable getRequest() {
+            if (request != null) {
+                return request;
+            }
+            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
+            request = new FOM_Request(
+                    getParentScope(),
+                    ObjectModelHelper.getRequest(objectModel));
+            return request;
+        }
+
+        public Scriptable getContext() {
+            if (context != null) {
+                return context;
+            }
+            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
+            context = new FOM_Context(
+                    getParentScope(),
+                    ObjectModelHelper.getContext(objectModel));
+            return context;
+        }
+
+        public Scriptable getResponse() {
+            if (response != null) {
+                return response;
+            }
+            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
+            response = org.mozilla.javascript.Context.toObject(
+                    ObjectModelHelper.getResponse(objectModel),
+                    getParentScope());
+            return response;
+        }
+
+        public Scriptable getLog() {
+            if (log != null) {
+                return log;
+            }
+            log = org.mozilla.javascript.Context.toObject(logger, getParentScope());
+            return log;
+        }
+
+        public Scriptable getParameters() {
+            return parameters;
+        }
+
+        public void setParameters(Scriptable parameters) {
+            this.parameters = parameters;
+        }
+    }
+
+    private CallContext currentCall;
+    protected PageLocalScopeHolder pageLocal;
+
+    public String getClassName() {
+        return "FOM_Cocoon";
+    }
+
+
+    // Called by FOM_JavaScriptInterpreter
+    static void init(Scriptable scope) throws Exception {
+        //FIXME(SW) what is the exact purpose of defineClass() ??
+        defineClass(scope, FOM_Cocoon.class);
+//        defineClass(scope, FOM_Request.class);
+//        defineClass(scope, FOM_Response.class);
+//        defineClass(scope, FOM_Cookie.class);
+//        defineClass(scope, FOM_Session.class);
+//        defineClass(scope, FOM_Context.class);
+//        defineClass(scope, FOM_Log.class);
+        defineClass(scope, FOM_WebContinuation.class);
+        defineClass(scope, PageLocalImpl.class);
+    }
+
+    void pushCallContext(FOM_JavaScriptInterpreter interp,
+                         Redirector redirector,
+                         ServiceManager manager,
+                         Context avalonContext,
+                         Logger logger,
+                         WebContinuation lastContinuation) {
+        if (pageLocal == null) {
+            pageLocal = new PageLocalScopeHolder(getTopLevelScope(this));
+        }
+        
+        // The call context will use the current sitemap's service manager when looking up components
+        ServiceManager sitemapManager;
+        try {
+            sitemapManager = (ServiceManager)avalonContext.get(ContextHelper.CONTEXT_SITEMAP_SERVICE_MANAGER);
+        } catch (ContextException e) {
+            throw new FOMResourceNotFoundException("Cannot get sitemap service manager", e);
+        }
+
+        this.currentCall = new CallContext(currentCall, interp, redirector, sitemapManager,
+                                           avalonContext,
+                                           logger, lastContinuation);
+    }
+
+    void popCallContext() {
+        // Clear the scope attribute
+        FOM_JavaScriptFlowHelper.setFOM_FlowScope(this.getObjectModel(), null);
+
+        this.currentCall = this.currentCall.caller;
+        // reset current page locals
+        if (this.currentCall != null) {
+            pageLocal.setDelegate(this.currentCall.currentPageLocal);
+        } else {
+            pageLocal.setDelegate(null);
+        }
+    }
+
+
+    public FOM_WebContinuation jsGet_continuation() {
+        // FIXME: This method can return invalid continuation! Is it OK to do so?
+        return currentCall.getLastContinuation();
+    }
+
+    public void jsSet_continuation(Object obj) {
+        FOM_WebContinuation fwk = (FOM_WebContinuation)unwrap(obj);
+        currentCall.setLastContinuation(fwk);
+    }
+
+    public FOM_WebContinuation jsFunction_sendPage(String uri,
+                                                   Object obj,
+                                                   Object wk)
+        throws Exception {
+        FOM_WebContinuation fom_wk = (FOM_WebContinuation)unwrap(wk);
+        if (fom_wk != null) {
+            // save page locals
+            fom_wk.setPageLocal(pageLocal.getDelegate());
+        }
+        forwardTo(uri, unwrap(obj), fom_wk);
+        return fom_wk;
+    }
+
+    public Scriptable jsFunction_createPageLocal() {
+        return pageLocal.createPageLocal();
+    }
+
+    public void jsFunction_processPipelineTo(String uri,
+                                             Object map,
+                                             Object outputStream)
+    throws Exception {
+        Object out = unwrap(outputStream);
+        if (!(out instanceof OutputStream)) {
+            throw new JavaScriptException("expected a java.io.OutputStream instead of " + out);
+        }
+        getInterpreter().process(getParentScope(), this, uri, map,
+                                 (OutputStream)out);
+    }
+
+    public void jsFunction_redirectTo(String uri, boolean isGlobal) throws Exception {
+        if (isGlobal) {
+            this.currentCall.redirector.globalRedirect(false, uri);
+        } else {
+            this.currentCall.redirector.redirect(false, uri);
+        }
+    }
+
+    public void jsFunction_sendStatus(int sc) {
+        this.currentCall.redirector.sendStatus(sc);
+    }
+
+/*
+
+ NOTE (SM): These are the hooks to the future FOM Event Model that will be
+ designed in the future. It has been postponed because we think
+ there are more important things to do at the moment, but these
+ are left here to indicate that they are planned.
+
+    public void jsFunction_addEventListener(String eventName,
+                                            Object function) {
+        // what is this?
+    }
+
+    public void jsFunction_removeEventListener(String eventName,
+                                               Object function) {
+        // what is this?
+    }
+
+*/
+
+    /**
+     * Access components.
+     *
+     * TODO: Do we want to restrict the access of sitemap components? (RP)
+     * TODO: Do we want to raise an error or return null? (RP)
+     */
+    public Object jsFunction_getComponent(String id)
+        throws Exception {
+        return org.mozilla.javascript.Context.javaToJS(getServiceManager().lookup(id), 
+                                                       getParentScope());
+    }
+
+    /**
+     * Release pooled components.
+     *
+     * @param component a component
+     */
+    public void jsFunction_releaseComponent( Object component ) throws Exception {
+        this.getServiceManager().release( unwrap(component) );
+    }
+
+    /**
+     * Load the script file specified as argument.
+     *
+     * @param filename a <code>String</code> value
+     * @return an <code>Object</code> value
+     * @exception JavaScriptException if an error occurs
+     */
+    public Object jsFunction_load( String filename )
+        throws Exception {
+        org.mozilla.javascript.Context cx =
+            org.mozilla.javascript.Context.getCurrentContext();
+        Scriptable scope = getParentScope();
+        Script script = getInterpreter().compileScript(cx, filename);
+        return script.exec( cx, scope );
+    }
+
+    /**
+     * Setup an object so that it can access the information provided to regular components.
+     * This is done by calling the various Avalon lifecycle interfaces implemented by the object, which
+     * are <code>LogEnabled</code>, <code>Contextualizable</code>, <code>Serviceable</code>
+     * and <code>Initializable</code>.
+     * <p>
+     * <code>Contextualizable</code> is of primary importance as it gives access to the whole object model
+     * (request, response, etc.) through the {@link org.apache.cocoon.components.ContextHelper} class.
+     * <p>
+     * Note that <code>Configurable</code> is ignored, as no configuration exists in a flowscript that
+     * can be passed to the object.
+     *
+     * @param obj the object to setup
+     * @return the same object (convenience that allows to write <code>var foo = cocoon.setupObject(new Foo());</code>).
+     * @throws Exception if something goes wrong during setup.
+     */
+    public Object jsFunction_setupObject(Object obj) throws Exception {
+        LifecycleHelper.setupComponent(
+             unwrap(obj),
+             this.getLogger(),
+             this.getAvalonContext(),
+             this.getServiceManager(),
+             null,// configuration
+             true);
+         return org.mozilla.javascript.Context.javaToJS(obj, getParentScope());
+    }
+
+    /**
+     * Create and setup an object so that it can access the information provided to regular components.
+     * This is done by calling the various Avalon lifecycle interfaces implemented by the object, which
+     * are <code>LogEnabled</code>, <code>Contextualizable</code>, <code>Serviceable</code>
+     * and <code>Initializable</code>.
+     * <p>
+     * <code>Contextualizable</code> is of primary importance as it gives access to the whole object model
+     * (request, response, etc.) through the {@link org.apache.cocoon.components.ContextHelper} class.
+     * <p>
+     * Note that <code>Configurable</code> is ignored, as no configuration exists in a flowscript that
+     * can be passed to the object.
+     *
+     * @param classObj the class to instantiate, either as a String or a Rhino NativeJavaClass object
+     * @return an set up instance of <code>clazz</code>
+     * @throws Exception if something goes wrong either during instantiation or setup.
+     */
+    public Object jsFunction_createObject(Object classObj) throws Exception {
+        Object result;
+
+        if (classObj instanceof String) {
+            result = ClassUtils.newInstance((String)classObj);
+
+        } else if (classObj instanceof NativeJavaClass) {
+            Class clazz = ((NativeJavaClass)classObj).getClassObject();
+            result = clazz.newInstance();
+
+        } else {
+            throw new IllegalArgumentException("cocoon.createObject expects either a String or Class argument, but got "
+                + classObj.getClass());
+        }
+
+        return jsFunction_setupObject(result);
+    }
+
+    /**
+     * Dispose an object that has been created using {@link #jsFunction_createObject(Object)}.
+     *
+     * @param obj
+     * @throws Exception
+     */
+    public void jsFunction_disposeObject(Object obj) throws Exception {
+        LifecycleHelper.decommission(obj);
+    }
+
+    /**
+     * Base JS wrapper for Cocoon's request/session/context objects.
+     * <p>
+     * FIXME(SW): The only thing added to the regular Java object is the fact that
+     * attributes can be accessed as properties. Do we want to keep this?
+     */
+    private static abstract class AttributeHolderJavaObject extends NativeJavaObject {
+        
+        private static Map classProps = new HashMap();
+        private Set propNames;
+
+        public AttributeHolderJavaObject(Scriptable scope, Object object, Class clazz) {
+            super(scope, object, clazz);
+            this.propNames = getProperties(object.getClass());
+        }
+        
+        /** Compute the names of JavaBean properties so that we can filter them our in get() */
+        private static Set getProperties(Class clazz) {
+            Set result = (Set)classProps.get(clazz);
+            if (result == null) {
+                try {
+                    PropertyDescriptor[] descriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
+                    result = new HashSet();
+                    for (int i = 0; i < descriptors.length; i++) {
+                        result.add(descriptors[i].getName());
+                    }
+                } catch (IntrospectionException e) {
+                    // Cannot introspect: just consider there are no properties
+                    result = Collections.EMPTY_SET;
+                }
+                classProps.put(clazz, result);
+            }
+            return result;
+        }
+        
+        
+        protected abstract Enumeration getAttributeNames();
+        protected abstract Object getAttribute(String name);
+        
+        public Object[] getIds() {
+            // Get class Ids
+            Object [] classIds = super.getIds();
+            
+            // and add attribute names
+            ArrayList idList = new ArrayList(Arrays.asList(classIds));
+            Enumeration iter = getAttributeNames();
+            while(iter.hasMoreElements()) {
+                idList.add(iter.nextElement());
+            }
+            return idList.toArray();
+        }
+        
+        public boolean has(String name, Scriptable start) {
+            return super.has(name, start) || getAttribute(name) != null;
+        }
+        
+        public Object get(String name, Scriptable start) {
+            Object result;
+            // Filter out JavaBean properties. We only want methods of the underlying object.
+            if (this.propNames.contains(name)) {
+                result = NOT_FOUND;
+            } else {
+                result = super.get(name, start);
+            }
+            if (result == NOT_FOUND) {
+                result = getAttribute(name);
+                if (result != null) {
+                    result = org.mozilla.javascript.Context.javaToJS(result, start);
+                } else {
+                    result = NOT_FOUND;
+                }
+            }
+            return result;
+        }
+    }
+
+    /**
+     * JS wrapper for Cocoon's request object.
+     * <p>
+     * Request <em>parameters</em> are also present as properties on this object.
+     * Note that this is different from <code>FOM_Context</code> and <code>FOM_Session</code>
+     * that do the same with <em>attributes</em>.
+     */
+    public static class FOM_Request extends AttributeHolderJavaObject {
+        private final Request request;
+        
+        public FOM_Request(Scriptable scope, Request request) {
+            super(scope, request, Request.class);
+            this.request = request;
+        }
+        
+        protected Enumeration getAttributeNames() {
+            return this.request.getParameterNames();
+        }
+        
+        protected Object getAttribute(String name) {
+            return this.request.getParameter(name);
+        }
+    }
+
+    /**
+     * JS wrapper for Cocoon's session object.
+     * <p>
+     * Session attributes are also present as properties on this object.
+     */
+    public static class FOM_Session extends AttributeHolderJavaObject {
+        private final Session session;
+        
+        public FOM_Session(Scriptable scope, Session session) {
+            super(scope, session, Session.class);
+            this.session = session;
+        }
+        
+        protected Enumeration getAttributeNames() {
+            return this.session.getAttributeNames();
+        }
+        
+        protected Object getAttribute(String name) {
+            return this.session.getAttribute(name);
+        }
+    }
+
+    /**
+     * JS wrapper for Cocoon's context object.
+     * <p>
+     * Context attributes are also present as properties on this object.
+     */
+    public static class FOM_Context extends AttributeHolderJavaObject {
+        private final org.apache.cocoon.environment.Context context;
+        
+        public FOM_Context(Scriptable scope, org.apache.cocoon.environment.Context context) {
+            super(scope, context, org.apache.cocoon.environment.Context.class);
+            this.context = context;
+        }
+        
+        protected Enumeration getAttributeNames() {
+            return this.context.getAttributeNames();
+        }
+        
+        protected Object getAttribute(String name) {
+            return this.context.getAttribute(name);
+        }
+    }
+
+    public Scriptable jsGet_request() {
+        return currentCall.getRequest();
+    }
+
+    public Scriptable jsGet_response() {
+        return currentCall.getResponse();
+    }
+
+    public Scriptable jsGet_log() {
+        return currentCall.getLog();
+    }
+
+    public Scriptable jsGet_context() {
+        return currentCall.getContext();
+    }
+
+    public Scriptable jsGet_session() {
+        return currentCall.getSession();
+    }
+
+    /**
+     * Get Sitemap parameters
+     *
+     * @return a <code>Scriptable</code> value whose properties represent
+     * the Sitemap parameters from <map:call>
+     */
+    public Scriptable jsGet_parameters() {
+        return getParameters();
+    }
+
+    public Scriptable getParameters() {
+        return currentCall.getParameters();
+    }
+
+    void setParameters(Scriptable value) {
+        currentCall.setParameters(value);
+    }
+
+    // unwrap Wrapper's and convert undefined to null
+    private static Object unwrap(Object obj) {
+        if (obj instanceof Wrapper) {
+            obj = ((Wrapper)obj).unwrap();
+        } else if (obj == Undefined.instance) {
+            obj = null;
+        }
+        return obj;
+    }
+
+    // Make everything available to JavaScript objects implemented in Java:
+
+    /**
+     * Get the current request
+     * @return The request
+     */
+    public Request getRequest() {
+        return ObjectModelHelper.getRequest(ContextHelper.getObjectModel(currentCall.avalonContext));
+    }
+
+    /**
+     * Get the current session
+     * @return The session (may be null)
+     */
+    public Session getSession() {
+        return ObjectModelHelper.getRequest(ContextHelper.getObjectModel(currentCall.avalonContext)).getSession(true);
+    }
+
+    /**
+     * Get the current response
+     * @return The response
+     */
+    public Response getResponse() {
+        return ObjectModelHelper.getResponse(ContextHelper.getObjectModel(currentCall.avalonContext));
+    }
+
+    /**
+     * Get the current context
+     * @return The context
+     */
+    public org.apache.cocoon.environment.Context getContext() {
+        return ObjectModelHelper.getContext(ContextHelper.getObjectModel(currentCall.avalonContext));
+    }
+
+    /**
+     * Get the current object model
+     * @return The object model
+     */
+    public Map getObjectModel() {
+        return ContextHelper.getObjectModel(currentCall.avalonContext);
+    }
+
+    private Context getAvalonContext() {
+        return currentCall.avalonContext;
+    }
+
+    private Logger getLogger() {
+        return currentCall.logger;
+    }
+
+    public ServiceManager getServiceManager() {
+        return currentCall.serviceManager;
+    }
+
+    private FOM_JavaScriptInterpreter getInterpreter() {
+        return currentCall.interpreter;
+    }
+
+    /**
+     * Required by FOM_WebContinuation. This way we do not make whole Interpreter public
+     * @return interpreter Id associated with this FOM.
+     */
+    public String getInterpreterId() {
+        return getInterpreter().getInterpreterID();
+    }
+    
+    /**
+     * Call the Cocoon Sitemap to process a page
+     * @param uri Uri to match
+     * @param bean Input to page
+     * @param fom_wk Current Web continuation (may be null)
+     */
+
+    public void forwardTo(String uri,
+                          Object bean,
+                          FOM_WebContinuation fom_wk)
+        throws Exception {
+        getInterpreter().forwardTo(getTopLevelScope(this),
+                                   this,
+                                   uri,
+                                   bean,
+                                   fom_wk,
+                                   this.currentCall.redirector);
+    }
+
+    /**
+     * Perform the behavior of <map:call continuation="blah">
+     * This can be used in cases where the continuation id is not encoded
+     * in the request in a form convenient to access in the sitemap.
+     * Your script can extract the id from the request and then call
+     * this method to process it as normal.
+     * @param kontId The continuation id
+     * @param parameters Any parameters you want to pass to the continuation (may be null)
+     */
+    public void handleContinuation(String kontId, Scriptable parameters)
+        throws Exception {
+        List list = null;
+        if (parameters == null || parameters == Undefined.instance) {
+            parameters = getParameters();
+        }
+        Object[] ids = parameters.getIds();
+        list = new ArrayList();
+        for (int i = 0; i < ids.length; i++) {
+            String name = ids[i].toString();
+            Argument arg = new Argument(name,
+                                        org.mozilla.javascript.Context.toString(getProperty(parameters, name)));
+            list.add(arg);
+        }
+        getInterpreter().handleContinuation(kontId, list, this.currentCall.redirector);
+    }
+
+    /**
+     * Return this continuation if it is valid, or first valid parent
+     */
+    private FOM_WebContinuation findValidParent(FOM_WebContinuation wk) {
+        if (wk != null) {
+            WebContinuation wc = wk.getWebContinuation();
+            while (wc != null && wc.disposed()) {
+                wc = wc.getParentContinuation();
+            }
+            if (wc != null) {
+                return new FOM_WebContinuation(wc);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Create a Bookmark WebContinuation from a JS Continuation with the last
+     * continuation of sendPageAndWait as its parent.
+     * PageLocal variables will be shared with the continuation of
+     * the next call to sendPageAndWait().
+     * @param k The JS continuation
+     * @param ttl Lifetime for this continuation (zero means no limit)
+     */
+    public FOM_WebContinuation jsFunction_makeWebContinuation(Object k,
+                                                              Object ttl)
+        throws Exception {
+        double d = org.mozilla.javascript.Context.toNumber(ttl);
+        FOM_WebContinuation result =
+            makeWebContinuation((Continuation)unwrap(k),
+                                findValidParent(jsGet_continuation()),
+                                (int)d);
+        result.setPageLocal(pageLocal.getDelegate());
+        currentCall.setLastContinuation(result);
+        return result;
+    }
+
+    /**
+     * Create a Web Continuation from a JS Continuation
+     * @param k The JS continuation (may be null - null will be returned in that case)
+     * @param parent The parent of this continuation (may be null)
+     * @param timeToLive Lifetime for this continuation (zero means no limit)
+     */
+    public FOM_WebContinuation makeWebContinuation(Continuation k,
+                                                   FOM_WebContinuation parent,
+                                                   int timeToLive)
+        throws Exception {
+        if (k == null) {
+            return null;
+        }
+        WebContinuation wk;
+        ContinuationsManager contMgr;
+        contMgr = (ContinuationsManager)
+            getServiceManager().lookup(ContinuationsManager.ROLE);
+        wk = contMgr.createWebContinuation(unwrap(k),
+                                           (parent == null ? null : parent.getWebContinuation()),
+                                           timeToLive,
+                                           getInterpreter().getInterpreterID(),
+                                           null);
+        FOM_WebContinuation result = new FOM_WebContinuation(wk);
+        result.setParentScope(getParentScope());
+        result.setPrototype(getClassPrototype(getParentScope(),
+                                              result.getClassName()));
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptFlowHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptFlowHelper.java
new file mode 100644
index 0000000..58f1e08
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptFlowHelper.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.apache.cocoon.components.flow.FlowHelper;
+
+import org.mozilla.javascript.Scriptable;
+
+import java.util.Map;
+
+/**
+ * Provides the interface between the JavaScript flow controller layer and the
+ * view layer. A view can obtain the JavaScript "live connect" objects (that
+ * allow access to Java constructors) through this interface, as well as
+ * the FOM objects.
+ *
+ * @version $Id$
+ */
+public class FOM_JavaScriptFlowHelper extends FlowHelper {
+
+    // Constants defining keys in the object model used to store the various objects.
+    // These constants are private so that access to these objects only go through the
+    // accessors provided below.
+    //
+    // These objects are stored in the object model rather than as request attributes,
+    // as object model is cloned for subrequests (see EnvironmentWrapper), whereas
+    // request attributes are shared between the "real" request and all of its
+    // child requests.
+    private static final String PACKAGES_OBJECT =
+        "cocoon.flow.js.packages";
+    private static final String JAVA_PACKAGE_OBJECT =
+        "cocoon.flow.js.packages.java";
+    private static final String FOM_REQUEST =
+        "cocoon.flow.js.fom.FOM_Request";
+    private static final String FOM_RESPONSE =
+        "cocoon.flow.js.fom.FOM_Response";
+    private static final String FOM_SESSION =
+        "cocoon.flow.js.fom.FOM_Session";
+    private static final String FOM_CONTEXT =
+        "cocoon.flow.js.fom.FOM_Context";
+    private static final String FOM_WEB_CONTINUATION =
+        "cocoon.flow.js.fom.FOM_WebContinuation";
+    /**
+     * The parent scope to be used by nested scripts (e.g. Woody event handlers)
+     */
+    private static final String FOM_SCOPE =
+        "cocoon.flow.js.fom.FOM_Scope";
+
+    /**
+     * Return the JS "Packages" property (that gives access to Java
+     * packages) for use by the view layer
+     * @param objectModel The Cocoon Environment's object model
+     * @return The Packages property
+     */
+    public static Scriptable getPackages(Map objectModel) {
+        return (Scriptable)objectModel.get(PACKAGES_OBJECT);
+    }
+
+    /**
+     * Set the JS "Packages" property in the current request
+     * @param objectModel The Cocoon Environment's object model
+     */
+    public static void setPackages(Map objectModel, Scriptable pkgs) {
+        objectModel.put(PACKAGES_OBJECT, pkgs);
+    }
+
+    /**
+     * Return the JS "java" property (that gives access to the "java"
+     * package) for use by the view layer
+     * @param objectModel The Cocoon Environment's object model
+     * @return The java package property
+     */
+    public static Scriptable getJavaPackage(Map objectModel) {
+        return (Scriptable)objectModel.get(JAVA_PACKAGE_OBJECT);
+    }
+
+    /**
+     * Set the JS "java" property in the current request
+     * @param objectModel The Cocoon Environment's object model
+     */
+    public static void setJavaPackage(Map objectModel, Scriptable javaPkg) {
+        objectModel.put(JAVA_PACKAGE_OBJECT, javaPkg);
+    }
+
+    public static Scriptable getFOM_Request(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_REQUEST);
+    }
+
+    public static void setFOM_Request(Map objectModel, Scriptable fom_request) {
+        objectModel.put(FOM_REQUEST, fom_request);
+    }
+
+    public static Scriptable getFOM_Response(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_RESPONSE);
+    }
+
+    public static void setFOM_Response(Map objectModel, Scriptable fom_response) {
+        objectModel.put(FOM_RESPONSE, fom_response);
+    }
+
+    public static Scriptable getFOM_Session(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_SESSION);
+    }
+
+    public static void setFOM_Session(Map objectModel, Scriptable fom_session) {
+        objectModel.put(FOM_SESSION, fom_session);
+    }
+
+    public static Scriptable getFOM_Context(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_CONTEXT);
+    }
+
+    public static void setFOM_Context(Map objectModel, Scriptable fom_context) {
+        objectModel.put(FOM_CONTEXT, fom_context);
+    }
+
+    public static Scriptable getFOM_WebContinuation(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_WEB_CONTINUATION);
+    }
+
+    public static void setFOM_WebContinuation(Map objectModel,
+                                              Scriptable fom_webContinuation) {
+        objectModel.put(FOM_WEB_CONTINUATION, fom_webContinuation);
+    }
+    
+    /**
+     * Get the flowscript scope, usable by JS snippets part of the control layer, such
+     * as forms event listeners.
+     * 
+     * @param objectModel the object model where the scope is stored
+     * @return the flowscript scope
+     */
+    public static Scriptable getFOM_FlowScope(Map objectModel) {
+        return (Scriptable)objectModel.get(FOM_SCOPE);
+    }
+    
+    /**
+     * Set the flowscript scope usable by JS snippets.
+     * 
+     * @see #getFOM_FlowScope(Map)
+     * @param objectModel
+     * @param fom_scope
+     */
+    public static void setFOM_FlowScope(Map objectModel, Scriptable fom_scope) {
+        objectModel.put(FOM_SCOPE, fom_scope);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java
new file mode 100644
index 0000000..de97c07
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_JavaScriptInterpreter.java
@@ -0,0 +1,742 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.CompilingInterpreter;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.flow.InvalidContinuationException;
+import org.apache.cocoon.components.flow.WebContinuation;
+import org.apache.cocoon.components.flow.javascript.JSErrorReporter;
+import org.apache.cocoon.components.flow.javascript.LocationTrackingDebugger;
+import org.apache.cocoon.components.flow.javascript.ScriptablePointerFactory;
+import org.apache.cocoon.components.flow.javascript.ScriptablePropertyHandler;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.commons.jxpath.JXPathIntrospector;
+import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
+import org.apache.excalibur.source.Source;
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.REProgram;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.EcmaError;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.NativeJavaClass;
+import org.mozilla.javascript.NativeJavaPackage;
+import org.mozilla.javascript.PropertyException;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.ScriptRuntime;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.WrappedException;
+import org.mozilla.javascript.continuations.Continuation;
+import org.mozilla.javascript.tools.debugger.Main;
+import org.mozilla.javascript.tools.shell.Global;
+
+
+/**
+ * Interface with the JavaScript interpreter.
+ *
+ * @since March 25, 2002
+ * @version $Id$
+ */
+public class FOM_JavaScriptInterpreter extends CompilingInterpreter
+        implements Configurable, Initializable {
+
+    /**
+     * A long value is stored under this key in each top level JavaScript
+     * thread scope object. When you enter a context any scripts whose
+     * modification time is later than this value will be recompiled and reexecuted,
+     * and this value will be updated to the current time.
+     */
+    private final static String LAST_EXEC_TIME = "__PRIVATE_LAST_EXEC_TIME__";
+
+    /**
+     * Prefix for session/request attribute storing JavaScript global scope object.
+     */
+    private static final String USER_GLOBAL_SCOPE = "FOM JavaScript GLOBAL SCOPE/";
+
+    /**
+     * This is the only optimization level that supports continuations
+     * in the Christoper Oliver's Rhino JavaScript implementation
+     */
+    private static final int OPTIMIZATION_LEVEL = -2;
+
+    /**
+     * When was the last time we checked for script modifications. Used
+     * only if {@link #reloadScripts} is true.
+     */
+    private long lastTimeCheck;
+
+    /**
+     * Shared global scope for scripts and other immutable objects
+     */
+    private Global scope;
+
+    /**
+     * List of <code>String</code> objects that represent files to be
+     * read in by the JavaScript interpreter.
+     */
+    private List topLevelScripts = new ArrayList();
+
+    private boolean enableDebugger;
+
+    /**
+     * Needed to get things working with JDK 1.3. Can be removed once we
+     * don't support that platform any more.
+     */
+    protected ServiceManager getServiceManager() {
+        return manager;
+    }
+
+    /**
+     * JavaScript debugger: there's only one of these: it can debug multiple
+     * threads executing JS code.
+     */
+    private static Main debugger;
+
+    static synchronized Main getDebugger() {
+        if (debugger == null) {
+            final Main db = new Main("Cocoon Flow Debugger");
+            db.pack();
+            Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
+            size.width *= 0.75;
+            size.height *= 0.75;
+            db.setSize(size);
+            db.setExitAction(new Runnable() {
+                    public void run() {
+                        db.setVisible(false);
+                    }
+                });
+            db.setOptimizationLevel(OPTIMIZATION_LEVEL);
+            db.setVisible(true);
+            debugger = db;
+            Context.addContextListener(debugger);
+        }
+        return debugger;
+    }
+
+    public void configure(Configuration config) throws ConfigurationException {
+        super.configure(config);
+
+        String loadOnStartup = config.getChild("load-on-startup").getValue(null);
+        if (loadOnStartup != null) {
+            register(loadOnStartup);
+        }
+
+        String debugger = config.getChild("debugger").getValue(null);
+        enableDebugger = "enabled".equalsIgnoreCase(debugger);
+    }
+
+    public void initialize() throws Exception {
+        if (enableDebugger) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Flow debugger enabled, creating");
+            }
+            getDebugger().doBreak();
+        }
+        Context context = Context.enter();
+        context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+        context.setCompileFunctionsWithDynamicScope(true);
+        context.setGeneratingDebug(true);
+        // add support for Rhino objects to JXPath
+        JXPathIntrospector.registerDynamicClass(Scriptable.class,
+                                                ScriptablePropertyHandler.class);
+        JXPathContextReferenceImpl.addNodePointerFactory(new ScriptablePointerFactory());
+
+        try {
+            scope = new Global(context);
+            // Access to Cocoon internal objects
+            FOM_Cocoon.init(scope);
+        } catch (Exception e) {
+            Context.exit();
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+
+    /**
+     * Returns the JavaScript scope, a Scriptable object, from the user
+     * session instance. Each interpreter instance can have a scope
+     * associated with it.
+     *
+     * @return a <code>ThreadScope</code> value
+     */
+    private ThreadScope getSessionScope() throws Exception {
+        final String scopeID = USER_GLOBAL_SCOPE + getInterpreterID();
+        final Request request = ContextHelper.getRequest(this.avalonContext);
+
+        ThreadScope scope = null;
+
+        // Get/create the scope attached to the current context
+        Session session = request.getSession(false);
+        if (session != null) {
+            scope = (ThreadScope) session.getAttribute(scopeID);
+        } else {
+            scope = (ThreadScope) request.getAttribute(scopeID);
+        }
+
+        if (scope == null) {
+            scope = createThreadScope();
+            // Save scope in the request early to allow recursive Flow calls
+            request.setAttribute(scopeID, scope);
+        }
+
+        return scope;
+    }
+
+    /**
+     * Associates a JavaScript scope, a Scriptable object, with
+     * {@link #getInterpreterID() identifier} of this {@link Interpreter}
+     * instance.
+     *
+     * @param scope a <code>ThreadScope</code> value
+     */
+    private void setSessionScope(ThreadScope scope) throws Exception {
+        if (scope.useSession) {
+            final String scopeID = USER_GLOBAL_SCOPE + getInterpreterID();
+            final Request request = ContextHelper.getRequest(this.avalonContext);
+
+            // FIXME: Where "session scope" should go when session is invalidated?
+            // Attach the scope to the current context
+            try {
+                Session session = request.getSession(true);
+                session.setAttribute(scopeID, scope);
+            } catch (IllegalStateException e) {
+                // Session might be invalidated already.
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Got '" + e + "' while trying to set session scope.", e);
+                }
+            }
+        }
+    }
+
+    public static class ThreadScope extends ScriptableObject {
+        private static final String[] BUILTIN_PACKAGES = {"javax", "org", "com"};
+
+        private ClassLoader classLoader;
+
+        /* true if this scope has assigned any global vars */
+        boolean useSession;
+
+        boolean locked = false;
+
+        /**
+         * Initializes new top-level scope.
+         */
+        public ThreadScope(Global scope) throws Exception {
+            final Context context = Context.getCurrentContext();
+
+            final String[] names = { "importClass" };
+            try {
+                defineFunctionProperties(names,
+                                         ThreadScope.class,
+                                         ScriptableObject.DONTENUM);
+            } catch (PropertyException e) {
+                throw new Error();  // should never happen
+            }
+
+            setPrototype(scope);
+
+            // We want this to be a new top-level scope, so set its
+            // parent scope to null. This means that any variables created
+            // by assignments will be properties of this.
+            setParentScope(null);
+
+            // Put in the thread scope the Cocoon object, which gives access
+            // to the interpreter object, and some Cocoon objects. See
+            // FOM_Cocoon for more details.
+            final Object[] args = {};
+            FOM_Cocoon cocoon = (FOM_Cocoon) context.newObject(this,
+                                                               "FOM_Cocoon",
+                                                               args);
+            cocoon.setParentScope(this);
+            super.put("cocoon", this, cocoon);
+
+            defineProperty(LAST_EXEC_TIME,
+                           new Long(0),
+                           ScriptableObject.DONTENUM | ScriptableObject.PERMANENT);
+        }
+
+        public String getClassName() {
+            return "ThreadScope";
+        }
+
+        public void setLock(boolean lock) {
+            this.locked = lock;
+        }
+
+        public void put(String name, Scriptable start, Object value) {
+            //Allow setting values to existing variables, or if this is a
+            //java class (used by importClass & importPackage)
+            if (this.locked && !has(name, start) && !(value instanceof NativeJavaClass)) {
+                // Need to wrap into a runtime exception as Scriptable.put has no throws clause...
+                throw new WrappedException (new JavaScriptException("Implicit declaration of global variable '" + name +
+                  "' forbidden. Please ensure all variables are explicitely declared with the 'var' keyword"));
+            }
+            this.useSession = true;
+            super.put(name, start, value);
+        }
+
+        public void put(int index, Scriptable start, Object value) {
+            // FIXME(SW): do indexed properties have a meaning on the global scope?
+            if (this.locked && !has(index, start)) {
+                throw new WrappedException(new JavaScriptException("Global scope locked. Cannot set value for index " + index));
+            }
+            this.useSession = true;
+            super.put(index, start, value);
+        }
+
+        // Invoked after script execution
+        void onExec() {
+            this.useSession = false;
+            super.put(LAST_EXEC_TIME, this, new Long(System.currentTimeMillis()));
+        }
+
+        /** Override importClass to allow reloading of classes */
+        public static void importClass(Context ctx,
+                                       Scriptable thisObj,
+                                       Object[] args,
+                                       Function funObj) {
+            for (int i = 0; i < args.length; i++) {
+                Object clazz = args[i];
+                if (!(clazz instanceof NativeJavaClass)) {
+                    throw Context.reportRuntimeError("Not a Java class: " +
+                                                     Context.toString(clazz));
+                }
+                String s = ((NativeJavaClass) clazz).getClassObject().getName();
+                String n = s.substring(s.lastIndexOf('.') + 1);
+                thisObj.put(n, thisObj, clazz);
+            }
+        }
+
+        public void setupPackages(ClassLoader cl) throws Exception {
+            final String JAVA_PACKAGE = "JavaPackage";
+            if (classLoader != cl) {
+                classLoader = cl;
+                Scriptable newPackages = new NativeJavaPackage("", cl);
+                newPackages.setParentScope(this);
+                newPackages.setPrototype(ScriptableObject.getClassPrototype(this, JAVA_PACKAGE));
+                super.put("Packages", this, newPackages);
+                for (int i = 0; i < BUILTIN_PACKAGES.length; i++) {
+                    String pkgName = BUILTIN_PACKAGES[i];
+                    Scriptable pkg = new NativeJavaPackage(pkgName, cl);
+                    pkg.setParentScope(this);
+                    pkg.setPrototype(ScriptableObject.getClassPrototype(this, JAVA_PACKAGE));
+                    super.put(pkgName, this, pkg);
+                }
+            }
+        }
+
+        public ClassLoader getClassLoader() {
+            return classLoader;
+        }
+    }
+
+    private ThreadScope createThreadScope() throws Exception {
+        return new ThreadScope(scope);
+    }
+
+    /**
+     * Returns a new Scriptable object to be used as the global scope
+     * when running the JavaScript scripts in the context of a request.
+     *
+     * <p>If you want to maintain the state of global variables across
+     * multiple invocations of <code>&lt;map:call
+     * function="..."&gt;</code>, you need to instanciate the session
+     * object which is a property of the cocoon object
+     * <code>var session = cocoon.session</code>. This will place the
+     * newly create Scriptable object in the user's session, where it
+     * will be retrieved from at the next invocation of {@link #callFunction}.</p>
+     *
+     * @exception Exception if an error occurs
+     */
+    private void setupContext(Redirector redirector, Context context,
+                              ThreadScope thrScope)
+    throws Exception {
+        // Try to retrieve the scope object from the session instance. If
+        // no scope is found, we create a new one, but don't place it in
+        // the session.
+        //
+        // When a user script "creates" a session using
+        // cocoon.createSession() in JavaScript, the thrScope is placed in
+        // the session object, where it's later retrieved from here. This
+        // behaviour allows multiple JavaScript functions to share the
+        // same global scope.
+
+        FOM_Cocoon cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope);
+        long lastExecTime = ((Long) thrScope.get(LAST_EXEC_TIME,
+                                                 thrScope)).longValue();
+        boolean needsRefresh = false;
+        if (reloadScripts) {
+            long now = System.currentTimeMillis();
+            if (now >= lastTimeCheck + checkTime) {
+                needsRefresh = true;
+            }
+            lastTimeCheck = now;
+        }
+
+        // We need to setup the FOM_Cocoon object according to the current
+        // request. Everything else remains the same.
+        ClassLoader contextClassloader = Thread.currentThread().getContextClassLoader();
+        thrScope.setupPackages(contextClassloader);
+        cocoon.pushCallContext(this, redirector, manager,
+                               avalonContext, getLogger(), null);
+
+        // Check if we need to compile and/or execute scripts
+        synchronized (compiledScripts) {
+            List execList = new ArrayList();
+            // If we've never executed scripts in this scope or
+            // if reload-scripts is true and the check interval has expired
+            // or if new scripts have been specified in the sitemap,
+            // then create a list of scripts to compile/execute
+            if (lastExecTime == 0 || needsRefresh || needResolve.size() > 0) {
+                topLevelScripts.addAll(needResolve);
+                if (lastExecTime != 0 && !needsRefresh) {
+                    execList.addAll(needResolve);
+                } else {
+                    execList.addAll(topLevelScripts);
+                }
+                needResolve.clear();
+            }
+            // Compile all the scripts first. That way you can set breakpoints
+            // in the debugger before they execute.
+            for (int i = 0, size = execList.size(); i < size; i++) {
+                String sourceURI = (String)execList.get(i);
+                ScriptSourceEntry entry =
+                    (ScriptSourceEntry)compiledScripts.get(sourceURI);
+                if (entry == null) {
+                    Source src = this.sourceresolver.resolveURI(sourceURI);
+                    entry = new ScriptSourceEntry(src);
+                    compiledScripts.put(sourceURI, entry);
+                }
+                // Compile the script if necessary
+                entry.getScript(context, this.scope, needsRefresh, this);
+            }
+            // Execute the scripts if necessary
+            for (int i = 0, size = execList.size(); i < size; i++) {
+                String sourceURI = (String) execList.get(i);
+                ScriptSourceEntry entry =
+                    (ScriptSourceEntry) compiledScripts.get(sourceURI);
+                long lastMod = entry.getSource().getLastModified();
+                Script script = entry.getScript(context, this.scope, false, this);
+                if (lastExecTime == 0 || lastMod > lastExecTime) {
+                    script.exec(context, thrScope);
+                    thrScope.onExec();
+                }
+            }
+        }
+    }
+
+    /**
+     * Compile filename as JavaScript code
+     *
+     * @param cx Rhino context
+     * @param fileName resource uri
+     * @return compiled script
+     */
+    Script compileScript(Context cx, String fileName) throws Exception {
+        Source src = this.sourceresolver.resolveURI(fileName);
+        if (src != null) {
+            synchronized (compiledScripts) {
+                ScriptSourceEntry entry =
+                    (ScriptSourceEntry)compiledScripts.get(src.getURI());
+                Script compiledScript = null;
+                if (entry == null) {
+                    compiledScripts.put(src.getURI(),
+                            entry = new ScriptSourceEntry(src));
+                } else {
+                    this.sourceresolver.release(src);
+                }
+                compiledScript = entry.getScript(cx, this.scope, false, this);
+                return compiledScript;
+            }
+        }
+        throw new ResourceNotFoundException(fileName + ": not found");
+
+    }
+
+    protected Script compileScript(Context cx, Scriptable scope, Source src)
+    throws Exception {
+        PushbackInputStream is = new PushbackInputStream(src.getInputStream(), ENCODING_BUF_SIZE);
+        try {
+            String encoding = findEncoding(is);
+            Reader reader = encoding == null ? new InputStreamReader(is) : new InputStreamReader(is, encoding);
+            reader = new BufferedReader(reader);
+            Script compiledScript = cx.compileReader(reader,
+                    src.getURI(), 1, null);
+            return compiledScript;
+        } finally {
+            is.close();
+        }
+    }
+    
+    // A charset name can be up to 40 characters taken from the printable characters of US-ASCII
+    // (see http://www.iana.org/assignments/character-sets). So reading 100 bytes should be more than enough.
+    private final static int ENCODING_BUF_SIZE = 100;
+    // Match 'encoding = xxxx' on the first line
+    REProgram encodingRE = new RECompiler().compile("^.*encoding\\s*=\\s*([^\\s]*)");
+    
+    /**
+     * Find the encoding of the stream, or null if not specified
+     */
+    String findEncoding(PushbackInputStream is) throws IOException {
+        // Read some bytes
+        byte[] buffer = new byte[ENCODING_BUF_SIZE];
+        int len = is.read(buffer, 0, buffer.length);
+        // and push them back
+        is.unread(buffer, 0, len);
+        
+        // Interpret them as an ASCII string
+        String str = new String(buffer, 0, len, "ASCII");
+        RE re = new RE(encodingRE);
+        if (re.match(str)) {
+            return re.getParen(1);
+        }
+        return null;
+    }
+
+    /**
+     * Calls a JavaScript function, passing <code>params</code> as its
+     * arguments. In addition to this, it makes available the parameters
+     * through the <code>cocoon.parameters</code> JavaScript array
+     * (indexed by the parameter names).
+     *
+     * @param funName a <code>String</code> value
+     * @param params a <code>List</code> value
+     * @param redirector
+     * @exception Exception if an error occurs
+     */
+    public void callFunction(String funName, List params, Redirector redirector)
+    throws Exception {
+        Context context = Context.enter();
+        context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+        context.setGeneratingDebug(true);
+        context.setCompileFunctionsWithDynamicScope(true);
+        context.setErrorReporter(new JSErrorReporter(getLogger()));
+        
+        LocationTrackingDebugger locationTracker = new LocationTrackingDebugger();
+        if (!enableDebugger) {
+            //FIXME: add a "tee" debugger that allows both to be used simultaneously
+            context.setDebugger(locationTracker, null);
+        }
+
+        ThreadScope thrScope = getSessionScope();
+        synchronized (thrScope) {
+            ClassLoader savedClassLoader =
+                Thread.currentThread().getContextClassLoader();
+            FOM_Cocoon cocoon = null;
+            try {
+                try {
+                    setupContext(redirector, context, thrScope);
+                    cocoon = (FOM_Cocoon) thrScope.get("cocoon", thrScope);
+
+                    // Register the current scope for scripts indirectly called from this function
+                    FOM_JavaScriptFlowHelper.setFOM_FlowScope(cocoon.getObjectModel(), thrScope);
+
+                    if (enableDebugger) {
+                        if (!getDebugger().isVisible()) {
+                            // only raise the debugger window if it isn't already visible
+                            getDebugger().setVisible(true);
+                        }
+                    }
+
+                    int size = (params != null ? params.size() : 0);
+                    Scriptable parameters = context.newObject(thrScope);
+                    for (int i = 0; i < size; i++) {
+                        Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
+                        if (arg.name == null) {
+                            arg.name = "";
+                        }
+                        parameters.put(arg.name, parameters, arg.value);
+                    }
+                    cocoon.setParameters(parameters);
+
+                    Object fun = ScriptableObject.getProperty(thrScope, funName);
+                    if (fun == Scriptable.NOT_FOUND) {
+                        throw new ResourceNotFoundException("Function \"javascript:" + funName + "()\" not found");
+                    }
+
+                    thrScope.setLock(true);
+                    ScriptRuntime.call(context, fun, thrScope, new Object[0], thrScope);
+                } catch (JavaScriptException ex) {
+                    throw locationTracker.getException("Error calling flowscript function " + funName, ex);
+                } catch (EcmaError ee) {
+                    throw locationTracker.getException("Error calling function " + funName, ee);
+                } catch (WrappedException ee) {
+                    throw locationTracker.getException("Error calling function " + funName, ee);
+                }
+            } finally {
+                thrScope.setLock(false);
+                setSessionScope(thrScope);
+                if (cocoon != null) {
+                    cocoon.popCallContext();
+                }
+                Context.exit();
+                Thread.currentThread().setContextClassLoader(savedClassLoader);
+            }
+        }
+    }
+
+    public void handleContinuation(String id, List params,
+                                   Redirector redirector) throws Exception
+    {
+        WebContinuation wk = continuationsMgr.lookupWebContinuation(id, getInterpreterID());
+
+        if (wk == null) {
+            /*
+             * Throw an InvalidContinuationException to be handled inside the
+             * <map:handle-errors> sitemap element.
+             */
+            throw new InvalidContinuationException("The continuation ID " + id + " is invalid.");
+        }
+
+        Context context = Context.enter();
+        context.setOptimizationLevel(OPTIMIZATION_LEVEL);
+        context.setGeneratingDebug(true);
+        context.setCompileFunctionsWithDynamicScope(true);
+        LocationTrackingDebugger locationTracker = new LocationTrackingDebugger();
+        if (!enableDebugger) {
+            //FIXME: add a "tee" debugger that allows both to be used simultaneously
+            context.setDebugger(locationTracker, null);
+        }
+
+        // Obtain the continuation object from it, and setup the
+        // FOM_Cocoon object associated in the dynamic scope of the saved
+        // continuation with the environment and context objects.
+        Continuation k = (Continuation)wk.getContinuation();
+        ThreadScope kScope = (ThreadScope)k.getParentScope();
+        synchronized (kScope) {
+            ClassLoader savedClassLoader =
+                Thread.currentThread().getContextClassLoader();
+            FOM_Cocoon cocoon = null;
+            try {
+                Thread.currentThread().setContextClassLoader(kScope.getClassLoader());
+                cocoon = (FOM_Cocoon)kScope.get("cocoon", kScope);
+                kScope.setLock(true);
+                cocoon.pushCallContext(this, redirector, manager,
+                                       avalonContext,
+                                       getLogger(), wk);
+
+                // Register the current scope for scripts indirectly called from this function
+                FOM_JavaScriptFlowHelper.setFOM_FlowScope(cocoon.getObjectModel(), kScope);
+
+                if (enableDebugger) {
+                    getDebugger().setVisible(true);
+                }
+                Scriptable parameters = context.newObject(kScope);
+                int size = params != null ? params.size() : 0;
+                for (int i = 0; i < size; i++) {
+                    Interpreter.Argument arg = (Interpreter.Argument)params.get(i);
+                    parameters.put(arg.name, parameters, arg.value);
+                }
+                cocoon.setParameters(parameters);
+                FOM_WebContinuation fom_wk = new FOM_WebContinuation(wk);
+                fom_wk.setParentScope(kScope);
+                fom_wk.setPrototype(ScriptableObject.getClassPrototype(kScope,
+                                                                       fom_wk.getClassName()));
+                Object[] args = new Object[] {k, fom_wk};
+                try {
+                    ScriptableObject.callMethod(cocoon,
+                                                "handleContinuation", args);
+                } catch (JavaScriptException ex) {
+                    throw locationTracker.getException("Error calling continuation", ex);
+
+                } catch (EcmaError ee) {
+                    throw locationTracker.getException("Error calling continuation", ee);
+
+                }
+            } finally {
+                kScope.setLock(false);
+                setSessionScope(kScope);
+                if (cocoon != null) {
+                    cocoon.popCallContext();
+                }
+                Context.exit();
+                Thread.currentThread().setContextClassLoader(savedClassLoader);
+            }
+        }
+    }
+
+    public void forwardTo(Scriptable scope, FOM_Cocoon cocoon, String uri,
+                          Object bizData, FOM_WebContinuation fom_wk,
+                          Redirector redirector)
+    throws Exception {
+        setupView(scope, cocoon, fom_wk);
+        super.forwardTo(uri, bizData,
+                        fom_wk == null ? null : fom_wk.getWebContinuation(),
+                        redirector);
+    }
+
+    // package access as this is called by FOM_Cocoon
+    void process(Scriptable scope, FOM_Cocoon cocoon, String uri,
+                 Object bizData, OutputStream out)
+    throws Exception {
+        setupView(scope, cocoon, null);
+        super.process(uri, bizData, out);
+    }
+
+    private void setupView(Scriptable scope, FOM_Cocoon cocoon, FOM_WebContinuation kont) {
+        Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
+
+        // Make the JS live-connect objects available to the view layer
+        FOM_JavaScriptFlowHelper.setPackages(objectModel,
+               (Scriptable)ScriptableObject.getProperty(scope, "Packages"));
+        FOM_JavaScriptFlowHelper.setJavaPackage(objectModel,
+               (Scriptable)ScriptableObject.getProperty(scope, "java"));
+
+        // Make the FOM objects available to the view layer
+        FOM_JavaScriptFlowHelper.setFOM_Request(objectModel,
+                                            cocoon.jsGet_request());
+        FOM_JavaScriptFlowHelper.setFOM_Response(objectModel,
+                                             cocoon.jsGet_response());
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Scriptable session = null;
+        if (request.getSession(false) != null) {
+            session = cocoon.jsGet_session();
+        }
+        FOM_JavaScriptFlowHelper.setFOM_Session(objectModel, session);
+
+        FOM_JavaScriptFlowHelper.setFOM_Context(objectModel,
+                                                cocoon.jsGet_context());
+        if (kont != null) {
+            FOM_JavaScriptFlowHelper.setFOM_WebContinuation(objectModel, kont);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_WebContinuation.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_WebContinuation.java
new file mode 100644
index 0000000..af49a7d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/FOM_WebContinuation.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.flow.ContinuationsManager;
+import org.apache.cocoon.components.flow.WebContinuation;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+import org.mozilla.javascript.Wrapper;
+import org.mozilla.javascript.continuations.Continuation;
+
+/**
+ *
+ * @version $Id$
+ */
+public class FOM_WebContinuation extends ScriptableObject {
+
+    WebContinuation wk;
+
+
+    static class UserObject {
+        boolean isBookmark;
+        PageLocalScopeImpl pageLocal;
+    }
+
+    static private boolean isBookmark(WebContinuation wk) {
+        UserObject userObj = (UserObject)wk.getUserObject();
+        if (userObj == null) {
+            return false;
+        }
+        return userObj.isBookmark;
+    }
+
+    public FOM_WebContinuation() {
+        this(null);
+    }
+
+
+    public FOM_WebContinuation(WebContinuation wk) {
+        this.wk = wk;
+    }
+
+    // new FOM_WebContinuation([Continuation] continuation,
+    //                         [FOM_WebContinuation] parent,
+    //                         [Number] timeToLive)
+    public static Object jsConstructor(Context cx, Object[] args,
+                                       Function ctorObj,
+                                       boolean inNewExpr)
+        throws Exception {
+        FOM_WebContinuation result = null;
+        if (args.length < 1) {
+            // error
+        }
+        Continuation c = (Continuation)unwrap(args[0]);
+        FOM_WebContinuation parent = null;
+        if (args.length > 1) {
+            parent = (FOM_WebContinuation)args[1];
+        }
+        int timeToLive = 0;
+        if (args.length > 2) {
+            timeToLive =
+                (int)org.mozilla.javascript.Context.toNumber(args[2]);
+        }
+        WebContinuation wk;
+        Scriptable scope = getTopLevelScope(c);
+        FOM_Cocoon cocoon = (FOM_Cocoon)getProperty(scope, "cocoon");
+        ServiceManager componentManager =  cocoon.getServiceManager();
+        ContinuationsManager contMgr = (ContinuationsManager)
+            componentManager.lookup(ContinuationsManager.ROLE);
+        wk = contMgr.createWebContinuation(c,
+                                           (parent == null ? null : parent.getWebContinuation()),
+                                           timeToLive,
+                                           cocoon.getInterpreterId(), 
+                                           null);
+        result = new FOM_WebContinuation(wk);
+        result.setParentScope(getTopLevelScope(scope));
+        result.setPrototype(getClassPrototype(scope, result.getClassName()));
+        return result;
+    }
+
+    public String getClassName() {
+        return "FOM_WebContinuation";
+    }
+
+    public Object jsFunction_getAttribute(String name) {
+        return org.mozilla.javascript.Context.javaToJS(
+                wk.getAttribute(name),
+                getParentScope());
+    }
+
+    public void jsFunction_setAttribute(String name, Object value) {
+        wk.setAttribute(name, unwrap(value));
+    }
+
+    public void jsFunction_removeAttribute(String name) {
+        wk.removeAttribute(name);
+    }
+
+    public Object jsFunction_getAttributeNames() {
+        return org.mozilla.javascript.Context.javaToJS(
+                wk.getAttributeNames(),
+                getParentScope());
+    }
+
+    public String jsGet_id() {
+        return wk.getId();
+    }
+
+
+    public Continuation jsGet_continuation() {
+        return (Continuation)wk.getContinuation();
+    }
+
+    public FOM_WebContinuation jsFunction_getParent() {
+        WebContinuation parent = wk.getParentContinuation();
+        if (parent == null) {
+            return null;
+        }
+
+        FOM_WebContinuation pwk = new FOM_WebContinuation(parent);
+        pwk.setParentScope(getParentScope());
+        pwk.setPrototype(getClassPrototype(getParentScope(),
+                                           pwk.getClassName()));
+        return pwk;
+    }
+
+    public NativeArray jsFunction_getChildren() throws Exception {
+        List list = wk.getChildren();
+        NativeArray arr =
+            (NativeArray)org.mozilla.javascript.Context.getCurrentContext().newObject(getParentScope(),
+                                                                                      "Array",
+                                                                                      new Object[]{new Integer(list.size())});
+        Iterator iter = list.iterator();
+        for (int i = 0; iter.hasNext(); i++) {
+            WebContinuation child = (WebContinuation)iter.next();
+            FOM_WebContinuation cwk = new FOM_WebContinuation(child);
+            cwk.setParentScope(getParentScope());
+            cwk.setPrototype(getClassPrototype(getParentScope(),
+                                               cwk.getClassName()));
+            arr.put(i, arr, cwk);
+        }
+        return arr;
+    }
+
+    public void jsFunction_invalidate() throws Exception {
+        ContinuationsManager contMgr = null;
+        FOM_Cocoon cocoon =
+            (FOM_Cocoon)getProperty(getTopLevelScope(this), "cocoon");
+        ServiceManager componentManager = cocoon.getServiceManager();
+        contMgr = (ContinuationsManager)
+            componentManager.lookup(ContinuationsManager.ROLE);
+        contMgr.invalidateWebContinuation(wk);
+    }
+
+    public void jsFunction_display() {
+        wk.display();
+    }
+
+    public WebContinuation getWebContinuation() {
+        return wk;
+    }
+
+    private static Object unwrap(Object obj) {
+        if (obj instanceof Wrapper) {
+            obj = ((Wrapper)obj).unwrap();
+        } else if (obj == Undefined.instance) {
+            obj = null;
+        }
+        return obj;
+    }
+
+    PageLocalScopeImpl getPageLocal() {
+        UserObject userObj = (UserObject)wk.getUserObject();
+        if (userObj == null) return null;
+        return userObj.pageLocal;
+    }
+
+    void setPageLocal(PageLocalScopeImpl pageLocal) {
+        UserObject userObj = (UserObject)wk.getUserObject();
+        if (userObj == null) {
+            userObj = new UserObject();
+            wk.setUserObject(userObj);
+        }
+        userObj.pageLocal = pageLocal;
+    }
+
+    public void jsFunction_setBookmark(boolean value) {
+        UserObject userObj = (UserObject)wk.getUserObject();
+        if (userObj == null) {
+            userObj = new UserObject();
+            wk.setUserObject(userObj);
+        }
+        userObj.isBookmark = value;
+    }
+
+    public boolean jsGet_bookmark() {
+        return isBookmark(wk);
+    }
+
+    public boolean jsFunction_isBookmark() {
+        return isBookmark(wk);
+    }
+
+    public FOM_WebContinuation jsGet_previousBookmark() {
+        WebContinuation c = wk.getParentContinuation();
+        if (c == null) {
+            return null;
+        }
+
+        // If this is a continuation of sendPageAndWait()
+        // and the immediate parent is a bookmark, then
+        // it is the bookmark for this page, so skip it.
+        if (!isBookmark(wk) && isBookmark(c)) {
+            c = c.getParentContinuation();
+        }
+        while (c != null && !isBookmark(c)) {
+            c = c.getParentContinuation();
+        }
+        if (c == null) {
+            return null;
+        }
+
+        FOM_WebContinuation pwk = new FOM_WebContinuation(c);
+        pwk.setParentScope(getParentScope());
+        pwk.setPrototype(getClassPrototype(getParentScope(), pwk.getClassName()));
+        return pwk;
+    }
+
+    /**
+     * Return text representation of the WebContinuation.
+     */
+    public String toString() {
+        return "WC" + wk.getId();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocal.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocal.java
new file mode 100644
index 0000000..384dfaf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocal.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.mozilla.javascript.Scriptable;
+
+/**
+ * @version $Id$
+ */
+public interface PageLocal extends Scriptable {
+
+    public Object getId();
+
+    public void setPageLocalScope(PageLocalScope scope);
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalImpl.java
new file mode 100644
index 0000000..6da1c13
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalImpl.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+/**
+ * @version $Id$
+ */
+public class PageLocalImpl extends ScriptableObject implements PageLocal {
+
+    private PageLocalScope scope; // null if this is the prototype
+    private String id;
+
+    public PageLocalImpl() {
+        this.id = String.valueOf(System.identityHashCode(this));
+    }
+
+    public void setPageLocalScope(PageLocalScope scope) {
+        this.scope = scope;
+    }
+
+    public Object getId() {
+        return id;
+    }
+
+    public String getClassName() {
+        return "PageLocal";
+    }
+
+    public boolean has(String name, Scriptable start) {
+        if (scope == null) {
+            return super.has(name, start);
+        }
+        return scope.has(this, name);
+    }
+
+    public boolean has(int index, Scriptable start) {
+        if (scope == null) {
+            return super.has(index, start);
+        }
+        return scope.has(this, index);
+    }
+
+    public void put(String name, Scriptable start, Object value) {
+        if (scope == null) {
+             super.put(name, start, value);
+        } else {
+            scope.put(this, name, value);
+        }
+    }
+
+    public void put(int index, Scriptable start, Object value) {
+        if (scope == null) {
+             super.put(index, start, value);
+        } else {
+            scope.put(this, index, value);
+        }
+    }
+
+    public Object get(String name, Scriptable start) {
+        if (scope == null) {
+            return super.get(name, start);
+        }
+        return scope.get(this, name);
+    }
+
+    public Object get(int index, Scriptable start) {
+        if (scope == null) {
+            return super.get(index, start);
+        }
+        return scope.get(this, index);
+    }
+
+    public void delete(int index) {
+        if (scope == null) {
+            super.delete(index);
+        } else {
+            scope.delete(this, index);
+        }
+    }
+
+    public void delete(String name) {
+        if (scope == null) {
+            super.delete(name);
+        } else {
+            scope.delete(this, name);
+        }
+    }
+
+    public Object[] getIds() {
+        if (scope == null) {
+            return super.getIds();
+        }
+        return scope.getIds(this);
+    }
+
+    public Object getDefaultValue(Class hint) {
+        if (scope == null) {
+            return super.getDefaultValue(hint);
+        }
+        return scope.getDefaultValue(this, hint);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScope.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScope.java
new file mode 100644
index 0000000..4f8df83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScope.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+/**
+ * @version $Id$
+ */
+public interface PageLocalScope {
+
+    boolean has(PageLocal local, String name);
+
+    boolean has(PageLocal local, int index);
+
+    Object get(PageLocal local, String name);
+
+    Object get(PageLocal local, int index);
+
+    void put(PageLocal local, String name, Object value);
+
+    void put(PageLocal local, int index, Object value);
+
+    void delete(PageLocal local, String name);
+
+    void delete(PageLocal local, int index);
+
+    Object[] getIds(PageLocal local);
+
+    Object getDefaultValue(PageLocal local, Class hint);
+
+    PageLocal createPageLocal();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeHolder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeHolder.java
new file mode 100644
index 0000000..090d5b9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeHolder.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+/**
+ * @version $Id$
+ */
+public class PageLocalScopeHolder implements PageLocalScope {
+
+    private Scriptable scope;
+    private PageLocalScopeImpl delegate;
+
+    public PageLocalScopeHolder(Scriptable scope) {
+        this.scope = scope;
+    }
+
+    public boolean has(PageLocal local, String name) {
+        return delegate.has(local, name);
+    }
+
+    public boolean has(PageLocal local, int index) {
+        return delegate.has(local, index);
+    }
+
+    public Object get(PageLocal local, String name) {
+        return delegate.get(local, name);
+    }
+
+    public Object get(PageLocal local, int index) {
+        return delegate.get(local, index);
+    }
+
+    public void put(PageLocal local, String name, Object value) {
+        delegate.put(local, name, value);
+    }
+
+    public void put(PageLocal local, int index, Object value) {
+        delegate.put(local, index, value);
+    }
+
+    public void delete(PageLocal local, String name) {
+        delegate.delete(local, name);
+    }
+
+    public void delete(PageLocal local, int index) {
+        delegate.delete(local, index);
+    }
+
+    public Object[] getIds(PageLocal local) {
+        return delegate.getIds(local);
+    }
+
+    public Object getDefaultValue(PageLocal local, Class hint) {
+        return delegate.getDefaultValue(local, hint);
+    }
+
+    public void setDelegate(PageLocalScopeImpl delegate) {
+        this.delegate = delegate;
+    }
+
+    public PageLocalScopeImpl getDelegate() {
+        return delegate;
+    }
+
+    public PageLocal createPageLocal() {
+        PageLocalImpl pageLocal = new PageLocalImpl();
+        pageLocal.setPrototype(ScriptableObject.getClassPrototype(scope,
+                                                                  pageLocal.getClassName()));
+        pageLocal.setParentScope(scope);
+        pageLocal.setPageLocalScope(this);
+        return pageLocal;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeImpl.java
new file mode 100644
index 0000000..af943b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/PageLocalScopeImpl.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.flow.javascript.fom;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class PageLocalScopeImpl implements PageLocalScope {
+
+    private Map locals;
+    private Scriptable scope;
+
+    public PageLocalScopeImpl(Scriptable scope) {
+        locals = new HashMap();
+        this.scope = scope;
+    }
+
+    private Scriptable newObject() {
+        try {
+            return Context.getCurrentContext().newObject(scope);
+        } catch (Exception ignored) {
+            // can't happen here
+            ignored.printStackTrace();
+            throw new Error("error: " + ignored);
+        }
+    }
+
+    private PageLocalScopeImpl(PageLocalScopeImpl toBeCloned) {
+        this.scope = toBeCloned.scope;
+        locals = new HashMap();
+        Iterator iter = toBeCloned.locals.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry e = (Map.Entry)iter.next();
+            Object key = e.getKey();
+            Object value = e.getValue();
+            // clone it
+            Scriptable obj = (Scriptable)value;
+            Scriptable newObj = newObject();
+            Object[] ids = obj.getIds();
+            for (int i = 0; i < ids.length; i++) {
+                String name = ids[i].toString();
+                newObj.put(name, newObj, obj.get(name, obj));
+            }
+            value = newObj;
+            locals.put(key, value);
+        }
+   }
+
+    private Scriptable resolve(PageLocal local) {
+        final Object id = local.getId();
+        Scriptable result = (Scriptable)locals.get(id);
+        if (result == null) {
+            locals.put(id, result = newObject());
+        }
+        return result;
+    }
+
+    public boolean has(PageLocal local, String name) {
+        Scriptable obj = resolve(local);
+        return obj.has(name, obj);
+    }
+
+    public boolean has(PageLocal local, int index) {
+        Scriptable obj = resolve(local);
+        return obj.has(index, obj);
+    }
+
+    public Object get(PageLocal local, String name) {
+        Scriptable obj = resolve(local);
+        return obj.get(name, obj);
+    }
+
+    public Object get(PageLocal local, int index) {
+        Scriptable obj = resolve(local);
+        return obj.get(index, obj);
+    }
+
+    public void put(PageLocal local, String name, Object value) {
+        Scriptable obj = resolve(local);
+        obj.put(name, obj, value);
+    }
+
+    public void put(PageLocal local, int index, Object value) {
+        Scriptable obj = resolve(local);
+        obj.put(index, obj, value);
+    }
+
+    public void delete(PageLocal local, String name) {
+        Scriptable obj = resolve(local);
+        obj.delete(name);
+    }
+
+    public void delete(PageLocal local, int index) {
+        Scriptable obj = resolve(local);
+        obj.delete(index);
+    }
+
+    public Object[] getIds(PageLocal local) {
+        Scriptable obj = resolve(local);
+        return obj.getIds();
+    }
+
+    public Object getDefaultValue(PageLocal local, Class hint) {
+        Scriptable obj = resolve(local);
+        return obj.getDefaultValue(hint);
+    }
+
+    public PageLocalScopeImpl duplicate() {
+        return new PageLocalScopeImpl(this);
+    }
+
+    public PageLocal createPageLocal() {
+        // not used
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/fom_system.js b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/fom_system.js
new file mode 100644
index 0000000..c95dc86
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/javascript/fom/fom_system.js
@@ -0,0 +1,56 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+FOM_Cocoon.suicide = new Continuation();
+
+FOM_Cocoon.prototype.sendPageAndWait = function(uri, bizData, fun, ttl) {
+    this.sendPage(uri, bizData,
+                  new FOM_WebContinuation(new Continuation(), 
+                                          this.continuation, ttl));
+    if (fun) {
+        if (!(fun instanceof Function)) {
+            throw "Expected a function instead of: " + fun;
+        }
+        fun();
+    }
+    FOM_Cocoon.suicide();
+}
+
+FOM_Cocoon.prototype.handleContinuation = function(k, wk) {
+    k(wk);
+}
+
+FOM_Cocoon.prototype.createWebContinuation = function(ttl) {
+   var wk = this.makeWebContinuation(new Continuation(), ttl);
+   wk.setBookmark(true);
+   return wk;
+}
+
+/**
+ * Exit the current flowscript invocation.
+ * <p>
+ * There are some flowscript use cases where we want to stop the current 
+ * flowscript without creating a continuation, as we don't want the user 
+ * to go back to the script.
+ * <p>
+ * An example is a "login" function where the caller function expects this 
+ * function to exit only if login is successful, but that has to handle 
+ * e.g. a registration process that includes a "cancel" button.
+ */
+FOM_Cocoon.prototype.exit = function() {
+    FOM_Cocoon.suicide();
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/mbean.properties b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/mbean.properties
new file mode 100644
index 0000000..d64258a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/mbean.properties
@@ -0,0 +1,7 @@
+ContinuationsManagerImpl = Manages the Continuations
+
+ContinuationsManagerImpl.defaultTimeToLive = How many milliseconds a continuation can live by default
+ContinuationsManagerImpl.bindContinuationsToSession = Whether Continuations will be bind to the Http Session
+ContinuationsManagerImpl.expirationCheckInterval = The expiration check interval in milliseconds
+ContinuationsManagerImpl.expirationCheckInterval = The expiration check interval in milliseconds
+ContinuationsManagerImpl.expirationSet = The set of expirations of Continuations
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/util/PipelineUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/util/PipelineUtil.java
new file mode 100644
index 0000000..d252412
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/flow/util/PipelineUtil.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.flow.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.commons.io.IOUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.w3c.dom.Document;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Utility class to process a pipeline to various destinations.
+ * This class must be setup from the flowscript before being used. This means that instances must
+ * be created with <code>cocoon.createObject(Packages.org.apache.cocoon.components.flow.util.PipelineUtil);
+ *
+ * @version $Id$
+ */
+public class PipelineUtil implements Contextualizable, Serviceable, Disposable {
+
+    private Context context;
+    private ServiceManager manager;
+    private SourceResolver resolver;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            this.manager.release(this.resolver);
+            this.manager = null;
+            this.resolver = null;
+        }
+    }
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+    }
+
+    /**
+     * Check that this object has been correctly set up.
+     *
+     * @throws IllegalStateException if not already set up.
+     */
+    private void checkSetup() {
+        if (this.manager == null) {
+            throw new IllegalStateException("Instances of " + getClass().getName() +
+                                            " must be setup using either cocoon.createObject() or cocoon.setupObject().");
+        }
+    }
+
+    /**
+     * Process a pipeline to a stream.
+     *
+     * @param uri the pipeline URI
+     * @param viewData the view data object
+     * @param output the stream where pipeline result is output. Note: this stream is not closed.
+     * @throws IOException
+     */
+    public void processToStream(String uri, Object viewData, OutputStream output)
+    throws IOException {
+        checkSetup();
+
+        Map objectModel = ContextHelper.getObjectModel(this.context);
+
+        // Keep the previous view data, if any (is it really necessary?), and set the new one
+        Object oldViewData = FlowHelper.getContextObject(objectModel);
+        FlowHelper.setContextObject(objectModel, FlowHelper.unwrap(viewData));
+
+        Source src = null;
+        InputStream input = null;
+        try {
+            src = this.resolver.resolveURI("cocoon:/" + uri);
+            input = src.getInputStream();
+            IOUtils.copy(input, output);
+        } finally {
+            if (input != null) {
+                try {
+                    input.close();
+                } catch (IOException ignored) {}
+            }
+
+            // Restore the previous view data
+            FlowHelper.setContextObject(objectModel, oldViewData);
+
+            if (src != null) {
+                this.resolver.release(src);
+            }
+        }
+    }
+
+    /**
+     * Process a pipeline to a SAX <code>ContentHandler</code>
+     *
+     * @param uri the pipeline URI
+     * @param viewData the view data object
+     * @param handler where the pipeline should be streamed to.
+     */
+    public void processToSAX(String uri, Object viewData, ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        checkSetup();
+
+        Map objectModel = ContextHelper.getObjectModel(this.context);
+        Object oldViewData = FlowHelper.getContextObject(objectModel);
+        FlowHelper.setContextObject(objectModel, FlowHelper.unwrap(viewData));
+
+        Source src = null;
+        try {
+            src = this.resolver.resolveURI("cocoon:/" + uri);
+            SourceUtil.toSAX(src, handler);
+        } finally {
+            FlowHelper.setContextObject(objectModel, oldViewData);
+            if (src != null) {
+                this.resolver.release(src);
+            }
+        }
+    }
+
+    /**
+     * Process a pipeline and gets is result as a DOM <code>Document</code>
+     *
+     * @param uri the pipeline URI
+     * @param viewData the view data object
+     * @return the document
+     */
+    public Document processToDOM(String uri, Object viewData) throws ProcessingException, SAXException, IOException  {
+        checkSetup();
+
+        Map objectModel = ContextHelper.getObjectModel(this.context);
+        Object oldViewData = FlowHelper.getContextObject(objectModel);
+        FlowHelper.setContextObject(objectModel, FlowHelper.unwrap(viewData));
+
+        Source src = null;
+
+        try {
+            src = this.resolver.resolveURI("cocoon:/" + uri);
+            return SourceUtil.toDOM(src);
+        } finally {
+            FlowHelper.setContextObject(objectModel, oldViewData);
+            if (src != null) {
+                this.resolver.release(src);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractInputModule.java
new file mode 100644
index 0000000..2a86aa3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractInputModule.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import org.apache.cocoon.util.HashMap;
+
+/**
+ * AbstractInputModule gives you the infrastructure for easily
+ * deploying more InputModules.  In order to get at the Logger, use
+ * getLogger().
+ *
+ * @version $Id$
+ */
+public abstract class AbstractInputModule extends AbstractLogEnabled
+    implements InputModule, Configurable, Disposable {
+
+    /**
+     * For those modules that access only one attribute, have a 
+     * fixed collection we can return an iterator for.
+     */
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("attribute");
+        returnNames = tmp;
+    }
+
+
+
+    /**
+     * Stores (global) configuration parameters as <code>key</code> /
+     * <code>value</code> pairs.
+     */
+    protected HashMap settings = null;
+
+    /**
+     * Configures the database access helper.
+     *
+     * Takes all elements nested in component declaration and stores
+     * them as key-value pairs in <code>settings</code>. Nested
+     * configuration option are not catered for. This way global
+     * configuration options can be used.
+     *
+     * For nested configurations override this function.
+     * */
+    public void configure(Configuration conf) throws ConfigurationException {
+        Configuration[] parameters = conf.getChildren();
+        this.settings = new HashMap(parameters.length);
+        for (int i = 0; i < parameters.length; i++) {
+            String key = parameters[i].getName();
+            String val = parameters[i].getValue("");
+            this.settings.put (key, val);
+        }
+    }
+
+    /**
+     *  dispose
+     */
+    public void dispose() {
+        // Purposely empty so that we don't need to implement it in every
+        // class.
+    }
+    
+    //
+    // you need to implement at least one of the following two methods
+    // since the ones below have a cyclic dependency!
+    // 
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel) throws ConfigurationException {
+        Object[] result = this.getAttributeValues(name, modeConf, objectModel);
+        return (result == null ? null : result[0]);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        Object result = this.getAttribute(name, modeConf, objectModel);
+        return (result == null ? null : new Object[] {result});
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel) throws ConfigurationException {
+        return AbstractInputModule.returnNames.iterator();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractJXPathModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractJXPathModule.java
new file mode 100644
index 0000000..b88927a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractJXPathModule.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * JXPathModule allows to access properties of any object in generic
+ * way.  JXPath provides APIs for the traversal of graphs of
+ * JavaBeans, DOM and other types of objects using the XPath
+ * syntax.
+ *
+ * <p><strong>Note:</strong> JXPathMetaModule is based on this class
+ * and duplicates the code since multiple inheritance is not possible.
+ * Please keep both classes in sync.</p>
+ *
+ * <h3>Configuration</h3>
+ * <table>
+ * <tr>
+ *   <td><code>&lt;lenient&gt;false&lt;/lenient&gt;</code></td>
+ *   <td>When set to true, non-existing attributes return null; when set to false,
+ *       an exception is thrown. Default is true.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;parameter&gt;foo&lt;/parameter&gt;</td>
+ *   <td>When set overrides attribute name passed to module.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;function name="java.lang.String" prefix="str"/&gt;</td>
+ *   <td>Imports the class "String" as extension class to the JXPathContext using
+ *   the prefix "str". Thus "str:length(xpath)" would apply the method "length" to
+ *   the string object obtained from the xpath expression. Please note that the class
+ *   needs to be fully qualified.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;package name="java.util" prefix="util"/&gt;</td>
+ *   <td>Imports all classes in the package "java.util" as extension classes to the
+ *   JXPathContext using the prefix "util". Thus "util:Date.new()" would create a
+ *   new java.util.Date object.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;namespace uri="uri:foo" prefix="bar"/&gt;</td>
+ *   <td>Registers the namespace identified by URI <code>uri:foo</code>
+ *   with the JXPathContext using the prefix <code>bar</code>. Thus
+ *   expressions can query XML with nodes in this namespace using
+ *   registered prefix.</td>
+ * </tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public abstract class AbstractJXPathModule extends AbstractInputModule {
+
+    /**
+     * Contains all globally registered extension classes and
+     * packages. Thus the lookup and loading of globally registered
+     * extensions is done only once.
+     */
+    protected JXPathHelperConfiguration configuration;
+
+    /**
+     * Overrides attribute name
+     */
+    protected String parameter;
+
+    /**
+     * Configure component. Preprocess list of packages and functions
+     * to add to JXPath context later.
+     *
+     * @param config a <code>Configuration</code> value
+     * @exception ConfigurationException if an error occurs
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.configuration = JXPathHelper.setup(config);
+    }
+
+
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        if (modeConf != null) {
+            name = modeConf.getChild("parameter").getValue(this.parameter != null ? this.parameter : name);
+        }
+        return JXPathHelper.getAttribute(name, modeConf, this.configuration, contextObj);
+    }
+
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        return JXPathHelper.getAttributeNames(this.configuration, contextObj);
+    }
+
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        if (modeConf != null) {
+            name = modeConf.getChild("parameter").getValue(this.parameter != null ? this.parameter : name);
+        }
+        return JXPathHelper.getAttributeValues(name, modeConf, this.configuration, contextObj);
+    }
+
+
+    /**
+     * Returns the object which should be used as JXPath context.
+     * Descendants should override this method to return a specific object
+     * that is requried by the implementing class.
+     * Examples are: request, session and application context objects.
+     */
+    protected abstract Object getContextObject(Configuration modeConf,
+                                               Map objectModel)
+    throws ConfigurationException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractMetaModule.java
new file mode 100644
index 0000000..a961a7e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/AbstractMetaModule.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * AbstractMetaModule gives you the infrastructure for easily
+ * deploying more "meta" InputModules i.e. InputModules that are
+ * composed of other InputModules.  In order to get at the Logger, use
+ * getLogger().
+ *
+ * @version $Id$
+ */
+public abstract class AbstractMetaModule extends AbstractInputModule
+    implements Serviceable, Disposable {
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    /** The cached InputModule-Selector */
+    protected ServiceSelector inputSelector;
+
+    /** The cached default InputModule */
+    protected InputModule input;
+
+    /** The default InputModule name / shorthand. Defaults to 'request-param' */
+    protected String defaultInput = "request-param"; // default to request parameters
+
+    /** The default InputModule configuration */
+    protected Configuration inputConf;  // will become an empty configuration object
+                                        // during configure() so why bother here...
+    
+    /** Is this instance initialized? */
+    protected boolean initialized = false;
+
+    /* Constants */
+
+    protected final static String INPUT_MODULE_SELECTOR = InputModule.ROLE+"Selector";
+
+    /* Operation codes */
+    private final static int OP_GET = 0;
+    private final static int OP_VALUES = 1;
+    private final static int OP_NAMES = 2;
+    private final static String[] OPNAME = new String[] {"GET_VALUE", "GET_VALUES", "GET_NAMES"};
+
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager=manager;
+    }
+
+    /**
+     * Initialize the meta module with exactly one other input
+     * module. Since "meta" modules require references to components
+     * of the same role, initialization cannot be done in initialize()
+     * when also implementing ThreadSafe since at that point the
+     * component selector is not yet initialized it would trigger the
+     * creation of a new one resulting in an endless loop of
+     * initializations. Therefore, every module needs to call this
+     * method when it first requires access to another module if the
+     * module itself has not been initialized. Override this method
+     * and dispose() to keep references to more than one module.
+     */
+    public synchronized void lazy_initialize() {
+
+        try {
+            // obtain input modules
+            if (!this.initialized) {
+                this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+                if (this.inputSelector != null && this.inputSelector instanceof ThreadSafe) {
+                    
+                    if (this.defaultInput != null) {
+                        this.input = obtainModule(this.defaultInput);
+                    }
+                    
+                } else if (!(this.inputSelector instanceof ThreadSafe) ) {
+                    this.manager.release(this.inputSelector);
+                    this.inputSelector = null;
+                }
+                
+                this.initialized = true;
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().error("A problem occurred setting up input modules :'" + e.getMessage(), e);
+        }
+    }
+
+
+    /**
+     * Dispose exactly one cached InputModule. To work on more than
+     * one, override this method and initialize().
+     */
+    public void dispose() {
+
+        if (this.inputSelector != null) {
+            if (this.input != null)
+                this.inputSelector.release(this.input);
+            this.manager.release(this.inputSelector);
+        }
+    }
+
+
+    /**
+     * Obtain a permanent reference to an InputModule.
+     */
+    protected InputModule obtainModule(String type) {
+        ServiceSelector inputSelector = this.inputSelector;
+        InputModule module = null;
+        try {
+            if (inputSelector == null) 
+                inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+
+            if (inputSelector.isSelectable(type)){
+                
+                if (type != null && inputSelector.isSelectable(type))
+                    module = (InputModule) inputSelector.select(type);
+                
+                if (!(module instanceof ThreadSafe) ) {
+                    inputSelector.release(module);
+                    module = null;
+                }
+            }
+            if (type != null && module == null)
+                if (getLogger().isWarnEnabled())
+                    getLogger().warn("A problem occurred setting up '" + type
+                                     +"': Selector is "+(inputSelector!=null?"not ":"")
+                                     +"null, Component is "
+                                     +(inputSelector!=null && inputSelector.isSelectable(type)?"known":"unknown"));
+            
+        } catch (ServiceException ce) {
+            if (getLogger().isWarnEnabled())
+                getLogger().warn("Could not obtain selector for InputModules: "+ce.getMessage());
+        } finally {
+            if (this.inputSelector == null) 
+                this.manager.release(inputSelector);
+            // FIXME: Is it OK to keep a reference to the module when we release the selector?
+        }
+
+        return module;
+    }
+
+
+    /**
+     * release a permanent reference to an InputModule.
+     */
+    protected void releaseModule(InputModule module) {
+        ServiceSelector inputSelector = this.inputSelector;
+        if (module != null) {
+            try {
+                // FIXME: Is it OK to release a module when we have released the selector before?
+                if (inputSelector == null) 
+                    inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+                
+                inputSelector.release(module);
+                module = null;
+                
+            } catch (ServiceException ce) {
+                if (getLogger().isWarnEnabled())
+                    getLogger().warn("Could not obtain selector for InputModules: "+ce.getMessage());
+            } finally {
+                if (this.inputSelector == null) 
+                    this.manager.release(inputSelector);
+            }
+        }
+    }
+
+    /**
+     * Get names of available attributes in the specified (usually statically
+     * assigned) Input Module.
+     * @see InputModule#getAttributeNames(Configuration, Map)
+     */
+    protected Iterator getNames(Map objectModel, 
+                                InputModule staticMod, String staticModName, Configuration staticModConf) 
+        throws ConfigurationException {
+
+        return (Iterator) this.get(OP_NAMES, null, objectModel, staticMod, staticModName, staticModConf, null, null, null);
+    }
+
+    /**
+     * Get names of available attributes in one of the specified Input Modules
+     * (static or dynamic, dynamic preferred).  Dynamic IM may be
+     * <code>null</code>.
+     * @see InputModule#getAttributeNames(Configuration, Map)
+     */
+     protected Iterator getNames(Map objectModel, 
+                                InputModule staticMod, String staticModName, Configuration staticModConf,
+                                InputModule dynamicMod, String dynamicModName, Configuration dynamicModConf)
+        throws ConfigurationException {
+
+        return (Iterator) this.get(OP_NAMES, null, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
+    }
+
+    protected Object getValue(String attr, Map objectModel, ModuleHolder holder) throws ConfigurationException{
+        return this.getValue(attr, objectModel, holder.input, holder.name, holder.config);
+    }
+
+    protected Object getValue(String attr, Map objectModel, ModuleHolder staticHolder, ModuleHolder dynamicHolder) throws ConfigurationException{
+        return this.getValue(attr, objectModel, staticHolder.input, staticHolder.name, dynamicHolder.config);
+    }
+
+    protected Object[] getValues(String attr, Map objectModel, ModuleHolder holder) throws ConfigurationException{
+        return this.getValues(attr, objectModel, holder.input, holder.name, holder.config);
+    }
+
+    protected Object[] getValues(String attr, Map objectModel, ModuleHolder staticHolder, ModuleHolder dynamicHolder) throws ConfigurationException{
+        return this.getValues(attr, objectModel, staticHolder.input, staticHolder.name, dynamicHolder.config);
+    }
+
+    /**
+     * Get an attribute's value from a (usually statically assigned) Input
+     * Module.
+     * @see InputModule#getAttribute(String, Configuration, Map)
+     */
+     protected Object getValue(String attr, Map objectModel, 
+                              InputModule staticMod, String staticModName, Configuration staticModConf)
+        throws ConfigurationException {
+
+        return this.get(OP_GET, attr, objectModel, staticMod, staticModName, staticModConf, null, null, null);
+    }
+
+
+    /**
+     * Get attribute's value in one of the specified Input Modules 
+     * (static or dynamic, dynamic preferred).  Dynamic IM may be
+     * <code>null</code>.
+     * @see InputModule#getAttribute(String, Configuration, Map)
+     */
+     protected Object getValue(String attr, Map objectModel, 
+                              InputModule staticMod, String staticModName, Configuration staticModConf,
+                              InputModule dynamicMod, String dynamicModName, Configuration dynamicModConf)
+        throws ConfigurationException {
+
+        return this.get(OP_GET, attr, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
+    }
+
+    /**
+     * Get an attribute's values from a (usually statically assigned) Input
+     * Module.
+     * @see InputModule#getAttributeValues(String, Configuration, Map)
+     */
+     protected Object[] getValues(String attr, Map objectModel, 
+                                 InputModule staticMod, String staticModName, Configuration staticModConf)
+        throws ConfigurationException {
+
+        return (Object[]) this.get(OP_VALUES, attr, objectModel, staticMod, staticModName, staticModConf, null, null, null);
+    }
+
+    /**
+     * Get attribute's values in one of the specified Input Modules 
+     * (static or dynamic, dynamic preferred).  Dynamic IM may be
+     * <code>null</code>.
+     * @see InputModule#getAttributeValues(String, Configuration, Map)
+     */
+     protected Object[] getValues(String attr, Map objectModel, 
+                                 InputModule staticMod, String staticModName, Configuration staticModConf,
+                                 InputModule dynamicMod, String dynamicModName, Configuration dynamicModConf)
+        throws ConfigurationException {
+
+        return (Object[]) this.get(OP_VALUES, attr, objectModel, staticMod, staticModName, staticModConf, dynamicMod, dynamicModName, dynamicModConf);
+    }
+
+
+    /**
+     * Encapsulates use of an InputModule. Does all the lookups and so on.  
+     * The second module (dynamic) is preferred if it has an non null name. If
+     * an exception is encountered, a warn message is printed and null is
+     * returned.
+     * @param op Operation to perform ({@link #OP_GET}, {@link #OP_NAMES}, {@link #OP_VALUES}).
+     *
+     * @return Either an Object, an Object[], or an Iterator, depending on <code>op</code> param.
+     */ 
+    private Object get(int op, String attr, Map objectModel,
+                         InputModule staticMod, String staticModName, Configuration staticModConf,
+                         InputModule dynamicMod, String dynamicModName, Configuration dynamicModConf)
+        throws ConfigurationException {
+
+        ServiceSelector cs = this.inputSelector;
+        Object value = null;
+        String name = null;
+        InputModule input = null;
+        Configuration conf = null;
+        boolean release = false;
+
+        try {
+            if (cs == null) {
+                try {
+                cs = (ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+                } catch (ServiceException e) {
+                    throw new ConfigurationException("Could not find MetaModule's module selector", e);
+                }
+            }
+
+            boolean useDynamic;
+            if (dynamicMod == null && dynamicModName == null) {
+                useDynamic = false;
+                input = staticMod;
+                name = staticModName;
+                conf = staticModConf;
+            } else {
+                useDynamic = true;
+                input = dynamicMod;
+                name = dynamicModName;
+                conf = dynamicModConf;
+            }
+        
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("MetaModule performing op "+OPNAME[op]+" on " + 
+                        (useDynamic?"dynamically":"statically") + " " +
+                        (input==null?"created":"assigned") +
+                        " module '"+name+"', using config "+dynamicModConf);
+            }
+
+            if (input == null) {
+                if (cs.isSelectable(name)) {
+                    release = true;
+                    try {
+                        input = (InputModule) cs.select(name);
+                    } catch (ServiceException e) {
+                        throw new ConfigurationException(
+                                "MetaModule unable to create "+
+                                (useDynamic ? "dynamically" : "statically")+
+                                " specified internal module '"+name+"'", e);
+                    }
+                } else {
+                    throw new ConfigurationException("MetaModule: No such InputModule: "+name);
+                }
+            }
+
+            switch (op) {
+            case OP_GET:    
+                value = input.getAttribute(attr, conf, objectModel);
+                break;
+            case OP_VALUES:
+                value = input.getAttributeValues(attr, conf, objectModel);
+                break;
+            case OP_NAMES:
+                value = input.getAttributeNames(conf, objectModel);
+                break;
+            }
+
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("using "+name+" as "+input+" for "+op+" ("+attr+") and "+conf+" gives "+value);
+            
+        } finally {         
+            if (release)
+                cs.release(input);
+
+            if (this.inputSelector == null)
+                this.manager.release(cs);
+        }
+
+        return value;
+    }
+                              
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BaseLinkModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BaseLinkModule.java
new file mode 100644
index 0000000..cce5e7c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BaseLinkModule.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1999-2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+/**
+ * BaseLinkModule returns a relative link (<code>../</code>,
+ * <code>../../</code> etc) to the base of the current request or sitemap URI.  For
+ * instance, if called within a &lt;map:match pattern="a/b/c.xsp"> pipeline,
+ * <code>{baselink:SitemapBaseLink}</code> would evaluate to <code>../../</code>.
+ *
+ * based on RequestURIModule
+ *
+ */
+public class BaseLinkModule extends AbstractInputModule implements ThreadSafe {
+
+    final static Vector returnNames = new Vector() {
+        {
+            add("RequestBaseLink");
+            add("SitemapBaseLink");
+        }
+    };
+
+    public Object getAttribute(
+        final String name,
+        final Configuration modeConf,
+        final Map objectModel)
+        throws ConfigurationException {
+
+        String uri;
+        if (name.equals("SitemapBaseLink"))
+            uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+        else if (name.equals("RequestBaseLink"))
+            uri = ObjectModelHelper.getRequest(objectModel).getRequestURI();
+        else
+            uri = "";
+
+        if (uri.startsWith("/")) {
+            uri = uri.substring(1);
+        }
+
+        StringBuffer result = new StringBuffer(uri.length());
+
+        int nextIndex = 0;
+        while ((nextIndex = uri.indexOf('/', nextIndex) + 1) > 0) {
+            result.append("../");
+        }
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("Returns " + result + " for uri " + uri + " and attribute " + name);
+
+        return result.toString();
+    }
+
+    public Iterator getAttributeNames(final Configuration modeConf, final Map objectModel)
+        throws ConfigurationException {
+
+        return RequestURIModule.returnNames.iterator();
+    }
+
+    public Object[] getAttributeValues(
+        final String name,
+        final Configuration modeConf,
+        final Map objectModel)
+        throws ConfigurationException {
+
+        Object result = new Object[1];
+        result = getAttribute(name, modeConf, objectModel);
+        return (result == null? null : new Object[]{result});        
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPathModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPathModule.java
new file mode 100644
index 0000000..4404630
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPathModule.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.blocks.Block;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.blocks.BlockEnvironmentHelper;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ * BlockPathModule returns the absolute path of a block protocol path.
+ *
+ * @version $Id$
+ */
+public class BlockPathModule implements InputModule, ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        Environment env = EnvironmentHelper.getCurrentEnvironment();
+        Block block = BlockEnvironmentHelper.getCurrentBlock();
+        String absoluteURI = null;
+        String baseURI = env.getURIPrefix();
+        if (baseURI.length() == 0 || !baseURI.startsWith("/"))
+            baseURI = "/" + baseURI;
+        try {
+            URI uri = block.absolutizeURI(new URI(name), new URI(null, null, baseURI, null));
+            absoluteURI = uri.toString();
+        } catch (URISyntaxException e) {
+            throw new ConfigurationException("Couldn't absolutize " + name);
+        }
+        return absoluteURI;
+    }
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPropertyModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPropertyModule.java
new file mode 100644
index 0000000..86d6ddb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/BlockPropertyModule.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.blocks.BlockEnvironmentHelper;
+
+/**
+ * BlockPropertyModule provides access to the properties of the current block.
+ *
+ * @version $Id$
+ */
+public class BlockPropertyModule implements InputModule, ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return BlockEnvironmentHelper.getCurrentBlock().getProperty(name);
+    }
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ChainMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ChainMetaModule.java
new file mode 100644
index 0000000..bf18cc2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ChainMetaModule.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+/**
+ * This modules allows to "chain" several other modules. If a module
+ * returns "null" as attribute value, the next module in the chain is
+ * queried until either a value can be obtained or the end of the
+ * chain is reached.
+ *
+ * <p>A typical example would be to "chain" request parameters,
+ * session attributes, and constants in this order. This way, an
+ * application could have a default skin that could be overridden by a
+ * user in her/his profile stored in the session. In addition, the
+ * user could request a different skin through passing a request
+ * parameter.</p>
+ *
+ * <p>Usage:</p>
+ *
+ * <p> Any number of &lt;input-module/&gt; blocks may appear in the
+ * component configuration. The @name attribute is used as the name of
+ * the requested input module. The complete &lt;input-module/&gt;
+ * block is passed at run-time to the module and thus can contain any
+ * configuration data for that particular module.</p>
+ *
+ * <p>Configuration:</p>
+ *
+ * <p>It can be controlled whether it returns a flat or a deep view,
+ * i.e. whether only values from the first module are returned if
+ * non-null or they are merged with values from other modules
+ * <code>&lt;all-values&gt;true&lt;/all-values&gt;</code>. The same is
+ * possible for the attribute names
+ * (<code>&lt;all-names/&gt;</code>). In addition, empty strings could
+ * be treated the same as null values
+ * (<code>&lt;empty-as-null/&gt;</code>).</p>
+ *
+ * @version $Id$
+ */
+public class ChainMetaModule extends AbstractMetaModule implements ThreadSafe {
+
+    private ModuleHolder[] inputs = null;
+
+    private boolean emptyAsNull = false;
+    private boolean allNames = false;
+    private boolean allValues = false;
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        Configuration[] confs = config.getChildren("input-module");
+        if (confs.length > 0) {
+            this.inputs = new ModuleHolder[confs.length];
+            int j = 0;
+            for (int i=0; i<confs.length; i++) {
+                ModuleHolder module = new ModuleHolder();
+                module.name = confs[i].getAttribute("name",null);
+                if (module.name == null) {
+                    if (getLogger().isErrorEnabled())
+                        getLogger().error("No name attribute for module configuration. Skipping.");
+                    continue;
+                }
+                module.config = confs[i];
+                this.inputs[j]=module;
+                j++;
+            }
+        }
+        this.emptyAsNull = config.getChild("empty-as-null").getValueAsBoolean(this.emptyAsNull);
+        this.allNames = config.getChild("all-names").getValueAsBoolean(this.allNames);
+        this.allValues = config.getChild("all-values").getValueAsBoolean(this.allValues);
+    }
+
+
+    public synchronized void lazy_initialize() {
+
+        try {
+            // obtain input modules
+            if (!this.initialized) {
+                this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+                if (this.inputSelector != null && this.inputSelector instanceof ThreadSafe) {
+                    
+                    for (int i=0; i<this.inputs.length; i++) {
+                        if (this.inputs[i].name != null) 
+                            this.inputs[i].input = obtainModule(this.inputs[i].name);
+                    }
+                    
+                } else if (!(this.inputSelector instanceof ThreadSafe) ) {
+                    this.manager.release(this.inputSelector);
+                    this.inputSelector = null;
+                }
+                
+                this.initialized = true;
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("A problem occurred setting up input modules :'" + e.getMessage());
+        }
+    }
+
+    
+    public void dispose() {
+        
+        if (this.inputSelector != null) {
+            
+            for (int i=0; i<this.inputs.length; i++) {
+                if (this.inputs[i].input != null)
+                    this.inputSelector.release(this.inputs[i].input);
+            }
+            
+            this.manager.release(this.inputSelector);
+        }
+    }
+
+
+    public Object[] getAttributeValues( String attr, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration[] inputConfigs = null;
+        boolean allValues = this.allValues;
+        boolean emptyAsNull = this.emptyAsNull;
+        if (modeConf!=null && modeConf.getChildren().length > 0) {
+            inputConfigs = modeConf.getChildren("input-module");
+            emptyAsNull = modeConf.getChild("empty-as-null").getValueAsBoolean(emptyAsNull);
+            allValues = modeConf.getChild("all-values").getValueAsBoolean(allValues);
+            if (inputConfigs.length == 0) inputConfigs = null;
+        }
+
+        Object[] value = null;
+        boolean debug = getLogger().isDebugEnabled();
+        List values = null;
+        if (allValues) values = new ArrayList();
+
+        if (inputConfigs == null) {
+            // static configuration branch
+            int i = 0;
+            while (i < this.inputs.length && (value == null || allValues)) {
+                if (this.inputs[i].name != null) {
+                    value = getValues(attr, objectModel, this.inputs[i].input, this.inputs[i].name, this.inputs[i].config);
+                    if (emptyAsNull && value != null && value.length == 0) value = null;
+                    if (emptyAsNull && value != null && value.length == 1 && 
+                        value[0] instanceof String && value[0].equals("")) value = null;
+                    if (debug) getLogger().debug("read from "+this.inputs[i].name+" attribute "+attr+" as "+value);
+                    if (allValues && value != null) values.addAll(Arrays.asList(value));
+                }
+                i++;
+            }
+        } else {
+            // run-time configuration branch
+            int i = 0;
+            while (i < inputConfigs.length && (value == null || allValues)) {
+                String name = inputConfigs[i].getAttribute("name",null);
+                if (name != null) {
+                    value = getValues(attr, objectModel, null, name, inputConfigs[i]);
+                    if (emptyAsNull && value != null && value.length == 0) value = null;
+                    if (emptyAsNull && value != null && value.length == 1 && 
+                        value[0] instanceof String && value[0].equals("")) value = null;
+                    if (debug) getLogger().debug("read from "+name+" attribute "+attr+" as "+value);
+                    if (allValues && value != null) values.addAll(Arrays.asList(value));
+                }
+                i++;
+            }
+        }
+        if (debug) getLogger().debug("result chaining for "+attr+" is "+(allValues? values.toArray() : value));
+        return (allValues? values.toArray() : value);
+    }
+
+    private void addIterator(Collection col, Iterator iter) {
+        while (iter != null && iter.hasNext())
+            col.add(iter.next());
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration[] inputConfigs = null;
+        boolean emptyAsNull = this.emptyAsNull;
+        boolean allNames = this.allNames;
+        if (modeConf!=null && modeConf.getChildren().length > 0) {
+            inputConfigs = modeConf.getChildren("input-module");
+            emptyAsNull = modeConf.getChild("empty-as-null").getValueAsBoolean(emptyAsNull);
+            allNames = modeConf.getChild("all-names").getValueAsBoolean(allNames);
+            if (inputConfigs.length == 0) inputConfigs = null;
+        }
+
+        Iterator value = null;
+        Collection values = null;
+        if (allNames) values = new ArrayList();
+        boolean debug = getLogger().isDebugEnabled();
+
+        if (inputConfigs == null) {
+            // static configuration branch
+            int i = 0;
+            while (i < this.inputs.length && (value == null || allNames)) {
+                if (this.inputs[i].name != null) {
+                    value = getNames(objectModel, this.inputs[i].input, this.inputs[i].name, this.inputs[i].config);
+                    if (debug) getLogger().debug("read from "+this.inputs[i].name+" AttributeNames as "+value);
+                    if (allNames && value != null) addIterator(values, value);
+                }
+                i++;
+            }
+        } else {
+            // run-time configuration branch
+            int i = 0;
+            while (i < inputConfigs.length && value == null) {
+                String name = inputConfigs[i].getAttribute("name",null);
+                if (name != null) {
+                    value = getNames(objectModel, null, name, inputConfigs[i]);
+                    if (debug) getLogger().debug("read from "+name+" AttributeNames as "+value);
+                    if (allNames && value != null) addIterator(values, value);
+                }
+                i++;
+            }
+        }
+        if (debug) getLogger().debug("result chaining names is "+(allNames? values.iterator() : value));
+        return (allNames? values.iterator() : value);
+     }
+
+
+    public Object getAttribute( String attr, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        Object[] values = this.getAttributeValues(attr,modeConf,objectModel);
+        if (getLogger().isDebugEnabled()) getLogger().debug("result chaining single for "+attr+" is "+(values != null? values[0] : "null"));
+        return (values != null? values[0] : null);
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ContextPathModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ContextPathModule.java
new file mode 100644
index 0000000..92d57fe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ContextPathModule.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.SourceResolver;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * ContextPathModule provides a real filesystem path for a virtual
+ * context-relative path.  If this mapping cannot be performed (e.g. Cocoon is
+ * running in a .war file), <code>null</code> will be returned. Compared to
+ * the {@link RealPathModule} this module is able to provide the "real" absolute 
+ * path even if the application is mounted outside the webapp tree of Cocoon.
+ * <p>
+ * Note: the primary use for this is to support external code that wants a
+ * filesystem path.  For example, The FOP 0.20.x serializer doesn't like
+ * relative image paths, and doesn't understand Cocoon URLs (context:, cocoon:
+ * etc).  So we pass the *2fo.xsl stylesheet a real filesystem path to where we
+ * keep our images:
+ * </p>
+ * <p>
+ * A absolute path argument like {contextpath:/resources} will be resolved  
+ * from the root context path (ie. COCOON_HOME/build/webapp) whereas a relative
+ * path attribute like {contextpath:./resources} will be resolved from the
+ * location of the sitemap that uses it. If that sitemap is mounted outside the
+ * usual COCOON_HOME/build/webapp the path resolved with this modules points to
+ * the correct location.
+ * </p>
+ * <p>
+ * <pre>
+ * <map:transform src="skins/{forrest:skin}/xslt/fo/document2fo.xsl">
+ *    <map:parameter name="basedir" value="{contextpath:resources}/"/>
+ * </map:transform>
+ *
+ * And then prepend this to all image paths:
+ *  ...
+ *  <xsl:param name="basedir" select="''"/>
+ *  ...
+ *  <xsl:template match="img">
+ *      <xsl:variable name="imgpath" select="concat($basedir, @src)"/>
+ *      <fo:external-graphic src="{$imgpath}" ...
+ *      ...
+ *  </xsl:template>
+ *  </pre>
+ *  </p>
+ *
+ * @version $Id$
+ */
+public class ContextPathModule extends AbstractInputModule implements Serviceable, ThreadSafe {
+
+    private ServiceManager m_manager;
+    private SourceResolver m_resolver;
+
+    final  static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("contextPath");
+        returnNames = tmp;
+    }
+
+        /** (non-Javadoc)
+	 *      * @see Serviceable#service(ServiceManager)
+	 *           */
+    public void service(ServiceManager manager) throws ServiceException {
+        m_manager = manager;
+        m_resolver = (SourceResolver) m_manager.lookup(SourceResolver.ROLE);
+    }
+
+    /** (non-Javadoc)
+     *
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     *
+     */
+    public void dispose() {
+        super.dispose();
+        if ( this.m_manager != null ) {
+            this.m_manager.release( this.m_resolver );
+            this.m_manager = null;
+            this.m_resolver = null;
+        }
+    }
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+        try {
+            if(name.startsWith("/")) {
+                return m_resolver.resolveURI("context:/"+name).getURI().substring("file:".length());
+            }
+            return m_resolver.resolveURI(name).getURI().substring("file:".length());
+        } catch( final IOException mue ) {
+            throw new ConfigurationException( "Cannot resolve realpath", mue);
+        }
+    }
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return ContextPathModule.returnNames.iterator();
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+            List values = new LinkedList();
+            values.add( this.getAttribute(name, modeConf, objectModel) );
+
+            return values.toArray();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/CookieModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/CookieModule.java
new file mode 100644
index 0000000..6fcff06
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/CookieModule.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.modules.input.AbstractInputModule;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.http.HttpCookie;
+
+/**
+ * Input module for cookies. Retrieves the value of the requested cookie.
+ * 
+ * @version $Id$
+ */
+public class CookieModule extends AbstractInputModule implements ThreadSafe {
+    
+    /**
+     * @return the value of the cookie whose name matches the one requested,
+     * or <code>null</code> if there is no match.
+     */
+    public Object getAttribute(String name, Configuration modeConf,
+            Map objectModel) throws ConfigurationException {
+        
+        HttpCookie cookie = (HttpCookie) getCookieMap(objectModel).get(name);
+        String value = (cookie == null ? null : cookie.getValue());
+        
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Cookie[" + name + "]=" + value);
+        }
+        return value;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration,
+     *      java.util.Map)
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+            throws ConfigurationException {
+        
+        return getCookieMap(objectModel).keySet().iterator();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String,
+     *      org.apache.avalon.framework.configuration.Configuration,
+     *      java.util.Map)
+     */
+    public Object[] getAttributeValues(String name, Configuration modeConf,
+            Map objectModel) throws ConfigurationException {
+        
+        Map allCookies = getCookieMap(objectModel);
+        
+        Iterator it = allCookies.values().iterator();
+        List matched = new LinkedList();
+        while (it.hasNext()) {
+            HttpCookie cookie = (HttpCookie) it.next();
+            if (cookie.getName().matches(name)) {
+                matched.add(cookie.getValue());
+            }
+        }
+        return matched.toArray();
+    }
+
+    /**
+     * @param objectModel
+     *            Object Model for the current request
+     * @return a Map of {see: HttpCookie}s for the current request, keyed on
+     *         cookie name.
+     */
+    protected Map getCookieMap(Map objectModel) {
+        return ObjectModelHelper.getRequest(objectModel).getCookieMap();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateInputModule.java
new file mode 100644
index 0000000..95afc02
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateInputModule.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * DateInputModule returns current date, optionally formated as
+ * string. Format given through attribute "format" of configuration
+ * root node or nested &lt;format/&gt; tag on module declaration.
+ *
+ * @version $Id$
+ * @see java.text.SimpleDateFormat
+ */
+public class DateInputModule extends AbstractInputModule implements ThreadSafe {
+
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("currentDate");
+        returnNames = tmp;
+    }
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+        
+        String format = (String) this.settings.get("format",name);
+        if (modeConf != null) {
+            format = modeConf.getAttribute("format", format);
+            // this is preferred:
+            format = modeConf.getChild("format").getValue(format);
+        }
+
+        if (format==null) {
+            return new Date();
+        } else {
+            try {
+                return new SimpleDateFormat(format).format(new Date());
+            } catch (Exception e) {
+                return new Date();
+            }           
+        }
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return DateInputModule.returnNames.iterator();
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+            List values = new LinkedList();
+            values.add( this.getAttribute(name, modeConf, objectModel) );
+
+            return values.toArray();
+            
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateMetaInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateMetaInputModule.java
new file mode 100644
index 0000000..ccf89a8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DateMetaInputModule.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Parses a date string according to a given format and returns a date
+ * object. Configuration options: element "format" to hold a {@link
+ * java.text.SimpleDateFormat} format string, child element
+ * "input-module" holds InputModule to obtain the string from.
+ *
+ * @version $Id$
+ */
+public class DateMetaInputModule extends AbstractMetaModule implements ThreadSafe {
+
+    private String defaultFormat = "yyyy-MM-dd";
+    private DateFormat defaultFormatter = null;
+
+    
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+        this.defaultFormat = this.inputConf.getAttribute("format",this.defaultFormat);
+        if (this.defaultFormat != null) {
+            this.defaultFormatter = new SimpleDateFormat(this.defaultFormat);
+        }
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given");
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration mConf = null;
+        String inputName=null;
+        String parameter=name;
+        String format=this.defaultFormat;
+        DateFormat formatter=null;
+        if (modeConf!=null) {
+            mConf       = modeConf.getChild("input-module");
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            parameter   = modeConf.getAttribute("parameter",parameter);
+            format      = modeConf.getAttribute("format",format);
+            // preferred:
+            parameter   = modeConf.getChild("parameter").getValue(parameter);
+            format      = modeConf.getChild("format").getValue(format);
+        }
+        if (this.defaultFormat.equals(format)) {
+            formatter = this.defaultFormatter;
+        } else {
+            formatter = new SimpleDateFormat(format);
+        }
+        
+        Object[] values = getValues(parameter, objectModel, 
+                                    this.input, this.defaultInput, this.inputConf,
+                                    null, inputName, mConf);
+        
+        Object[] dates = null;
+        if (values != null) {
+            dates = new Object[values.length];
+            for (int i=0; i<values.length; i++) 
+                try {
+                    dates[i] = formatter.parse(String.valueOf(values[i]));
+                } catch (Exception e) {
+                    if(getLogger().isWarnEnabled()) 
+                        getLogger().warn("Problem: Aquired '"+values[i]+"' from '" + inputName + "' for '"
+                                         +name+"' using format '"+format+"' : "+e.getMessage());
+                }
+        }
+        return dates;
+    }
+
+
+
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given");
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = this.inputConf;
+        Configuration mConf = null;
+        String inputName=null;
+        if (modeConf!=null) {
+            mConf       = modeConf.getChild("input-module");
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+        }
+
+        // done reading configuration
+        // setup modules and read values
+        Iterator enumeration = getNames(objectModel,
+                                    this.input, this.defaultInput, inputConfig,
+                                    null, inputName, mConf);
+        return enumeration;
+     }
+
+
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        Object[] values = this.getAttributeValues(name,modeConf,objectModel);
+        return (values != null ? values[0] : null);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DefaultsModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DefaultsModule.java
new file mode 100644
index 0000000..2107a83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DefaultsModule.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Set a number of constants. To override the values with input from
+ * another module, combine this one with the ChainMetaModule and an
+ * arbitrary number of other modules.
+ *
+ * &lt;values&gt;
+ *  &lt;skin&gt;myskin&lt;/skin&gt;
+ *  &lt;base&gt;baseurl&lt;/base&gt;
+ *  ...
+ * &lt;/values&gt;
+ *
+ * @version $Id$
+ */
+public class DefaultsModule extends AbstractLogEnabled
+    implements InputModule, Configurable, ThreadSafe {
+
+    private Map constants = null;
+    
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.constants = new HashMap();
+        Configuration[] consts = config.getChild("values").getChildren();
+        for (int i=0; i<consts.length; i++) {
+            this.constants.put(consts[i].getName(), consts[i].getValue(""));
+        }
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        String parameter=name;
+        Configuration mConf = null;
+        if (modeConf!=null) {
+            mConf       = modeConf.getChild("values");
+        }
+
+        Object[] values = new Object[1];
+        values[0] = (mConf!=null? mConf.getChild(parameter).getValue((String) this.constants.get(parameter)) 
+                     : this.constants.get(parameter));
+        return values;
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        SortedSet matchset = new TreeSet(this.constants.keySet());
+        if (modeConf!=null) {
+            Configuration[] consts = modeConf.getChild("values").getChildren();
+            for (int i=0; i<consts.length; i++)
+                matchset.add(consts[i].getName());
+        }
+        return matchset.iterator();
+     }
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        Object[] values = this.getAttributeValues(name,modeConf,objectModel);
+        return values[0];
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DigestMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DigestMetaModule.java
new file mode 100644
index 0000000..5554a16
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/DigestMetaModule.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.util.HashMap;
+
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Iterator;
+import java.util.Map;
+import java.io.UnsupportedEncodingException;
+
+/** Meta module that obtains values from other module and returns
+ * message digest of value. Very useful for storing and checking
+ * passwords. Input module configured through nested element
+ * "input-module", message digest algorithm, security provider, salt,
+ * and URL encoded output configurable through elements "algorithm",
+ * "provider", "salt", "encode". Defaults are "sha", null, "salt", and
+ * "false". Available value for encode are "none" (returns byte[]),
+ * "string" (return hash as string), "url" (returns url encoded
+ * string), "hex" (returns string of hex values).
+ *
+ * @version $Id$
+ */
+public class DigestMetaModule extends AbstractMetaModule implements ThreadSafe {
+
+    private String defaultAlgorithm = "SHA";
+    private String defaultProvider = null;
+    private String defaultSalt = "salt";
+    private String defaultEncode = "false";
+
+    /** output encoding none */
+    static final int ENCODING_NONE = 0;
+    /** output encoding url encoding */
+    static final int ENCODING_STR = 1;
+    /** output encoding hex */
+    static final int ENCODING_URL = 2;
+    /** output encoding hex */
+    static final int ENCODING_HEX = 3;
+
+    private static final HashMap encodingNames;
+    /** setup mapping tables */
+    static {
+        HashMap names = new HashMap();
+        names.put("false", new Integer(ENCODING_NONE));
+        names.put("no", new Integer(ENCODING_NONE));
+        names.put("none", new Integer(ENCODING_NONE));
+        names.put("string", new Integer(ENCODING_STR));
+        names.put("yes", new Integer(ENCODING_URL));
+        names.put("true", new Integer(ENCODING_URL));
+        names.put("hex", new Integer(ENCODING_HEX));
+        encodingNames = names;
+        names = null;
+    }
+
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name", this.defaultInput);
+
+        this.defaultAlgorithm = this.inputConf.getAttribute("algorithm",this.defaultAlgorithm);
+        this.defaultProvider = this.inputConf.getAttribute("provider",this.defaultProvider);
+        this.defaultSalt = this.inputConf.getAttribute("salt",this.defaultSalt);
+        this.defaultEncode = this.inputConf.getAttribute("encode","false");
+
+        // preferred
+        this.defaultAlgorithm = config.getChild("algorithm").getValue(this.defaultAlgorithm);
+        this.defaultProvider = config.getChild("provider").getValue(this.defaultProvider);
+        this.defaultSalt = config.getChild("salt").getValue(this.defaultSalt);
+        this.defaultEncode = config.getChild("encode").getValue(this.defaultEncode);
+
+        if (encodingNames.get(this.defaultEncode) == null) {
+            if (getLogger().isErrorEnabled())
+                getLogger().error("Requested encoding is unknown: "+this.defaultEncode);
+            this.defaultEncode="false";
+        }
+    }
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = null;
+        String inputName=null;
+        String algorithm = this.defaultAlgorithm;
+        String provider  = this.defaultProvider;
+        String salt  = this.defaultSalt;
+        int encode = ((Integer) encodingNames.get(this.defaultEncode)).intValue();
+        if (modeConf!=null) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+            // read necessary parameters
+            algorithm = modeConf.getAttribute("algorithm", algorithm);
+            provider  = modeConf.getAttribute("provider", provider);
+            salt  = modeConf.getAttribute("salt", salt);
+            encode = ((Integer) encodingNames.get(modeConf.getAttribute("encode", this.defaultEncode))).intValue();
+
+            // preferred
+            algorithm = modeConf.getChild("algorithm").getValue(algorithm);
+            provider  = modeConf.getChild("provider").getValue(provider);
+            salt  = modeConf.getChild("salt").getValue(salt);
+            encode = ((Integer) encodingNames.get(modeConf.getChild("encode").getValue(this.defaultEncode))).intValue();
+        }
+
+
+        Object value = getValue(name, objectModel,
+                                this.input, this.defaultInput, this.inputConf,
+                                null, inputName, inputConfig);
+        
+        if (value != null)
+            try {
+                MessageDigest md = (provider==null ? MessageDigest.getInstance(algorithm) : 
+                                    MessageDigest.getInstance(algorithm,provider));
+                
+                md.update((salt+(value instanceof String? (String)value : value.toString())).getBytes());
+                return encodeByteArray(md.digest(),encode);
+
+            } catch (NoSuchAlgorithmException nsae) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring digest algorithm '" + algorithm 
+                                     + (provider==null?"":"' from '"+provider) +"': " + nsae.getMessage());
+            } catch (NoSuchProviderException nspe) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring digest algorithm '" + algorithm 
+                                     + (provider==null?"":"' from '"+provider) +"': " + nspe.getMessage());
+            }
+
+        return null;        
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+         if (!this.initialized) {
+             this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = null;
+        String inputName=null;
+        if (modeConf!=null) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+        }
+
+        Iterator names = getNames(objectModel, 
+                                  this.input, this.defaultInput, this.inputConf, 
+                                  null, inputName, inputConfig);
+        
+        return names;
+
+   }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = null;
+        String inputName=null;
+        String algorithm = this.defaultAlgorithm;
+        String provider  = this.defaultProvider;
+        String salt  = this.defaultSalt;
+        int encode = ((Integer) encodingNames.get(this.defaultEncode)).intValue();
+        if (modeConf!=null) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+            // read necessary parameters
+            algorithm = modeConf.getAttribute("algorithm", algorithm);
+            provider  = modeConf.getAttribute("provider" , provider );
+            salt  = modeConf.getAttribute("salt" , salt );
+            encode = ((Integer) encodingNames.get(modeConf.getAttribute("encode" , this.defaultEncode))).intValue();
+
+            // preferred
+            algorithm = modeConf.getChild("algorithm").getValue(algorithm);
+            provider  = modeConf.getChild("provider").getValue(provider);
+            salt  = modeConf.getChild("salt").getValue(salt);
+            encode = ((Integer) encodingNames.get(modeConf.getChild("encode").getValue(this.defaultEncode))).intValue();
+        }
+
+        Object[] values = getValues(name, objectModel, 
+                                    this.input, this.defaultInput, this.inputConf, 
+                                    null, inputName, inputConfig);
+        Object[] result = null;
+
+        if (values != null) {
+            try {
+                MessageDigest md = (provider==null ? MessageDigest.getInstance(algorithm) : 
+                                    MessageDigest.getInstance(algorithm,provider));
+                
+                result = new Object[values.length];
+                for (int i=0; i<values.length; i++) {
+                    md.update((salt + (values[i] instanceof String? (String)values[i] : 
+                                       values[i].toString())).getBytes());
+                    result[i] = encodeByteArray(md.digest(), encode);
+                }
+                return result;
+            } catch (NoSuchAlgorithmException nsae) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring digest algorithm '" + algorithm 
+                                     + (provider==null?"":"' from '"+provider) +"': " + nsae.getMessage());
+            } catch (NoSuchProviderException nspe) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring digest algorithm '" + algorithm 
+                                     + (provider==null?"":"' from '"+provider) +"': " + nspe.getMessage());
+            }
+        }
+        return result;
+    }
+
+
+    /**
+     * Create the output representation.
+     * @param b a <code>byte[]</code>
+     * @param encode an <code>int</code>, one of {@link #ENCODING_NONE},{@link #ENCODING_URL},{@link #ENCODING_HEX}
+     * @return an <code>Object</code>
+     */
+    Object encodeByteArray(byte[] b, int encode) {
+        Object result = null;
+        switch(encode) {
+        case ENCODING_HEX:
+            result = byte2Hex(b);
+            break;
+        case ENCODING_STR:
+            try {
+                result = new String(b, "UTF-8");
+            } catch (UnsupportedEncodingException uee) {
+                if (getLogger().isErrorEnabled())
+                    getLogger().error("UTF-8 not supported -- cannot convert message digest to String.");
+            }
+            break;
+        case ENCODING_URL:
+            try {
+                String str = new String(b, "UTF-8");
+                result = URLEncoder.encode(str, "utf-8");
+            } catch (UnsupportedEncodingException uee) {
+                if (getLogger().isErrorEnabled())
+                    getLogger().error("UTF-8 not supported -- cannot convert message digest to String.");
+            }
+            break;
+        case ENCODING_NONE:
+            // nothing to do
+            break;
+        default:
+            // should not happen
+        }
+        return result;
+    }
+
+    /**
+     * Create a hex representation of a byte array.
+     *
+     * @param b a <code>byte[]</code> value
+     * @return a <code>String</code> value
+     */
+    static String byte2Hex ( byte[] b ) {
+        StringBuffer sb = new StringBuffer( b.length * 2 );
+        for ( int i=0 ; i < b.length ; i++ ) {
+            sb.append( hexChar [ ( b[i] & 0xf0 ) >>> 4 ] ) ;
+            sb.append( hexChar [ ( b[i] & 0x0f )       ] ) ;
+        }
+        return sb.toString() ;
+    }
+
+
+    /** 
+     * hex digits lookup table
+     */
+    static char[] hexChar = {
+        '0' , '1' , '2' , '3' ,
+        '4' , '5' , '6' , '7' ,
+        '8' , '9' , 'a' , 'b' ,
+        'c' , 'd' , 'e' , 'f' 
+    };
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/EnvironmentAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/EnvironmentAttributeModule.java
new file mode 100644
index 0000000..41886d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/EnvironmentAttributeModule.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ * EnvironmentAttributeModule provides access to the current
+ * Environment, intended for internal use in VPCs.
+ *
+ * @version $Id$
+ */
+public class EnvironmentAttributeModule implements InputModule, ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return EnvironmentHelper.getCurrentEnvironment().getAttribute(name);
+    }
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowAttributeModule.java
new file mode 100644
index 0000000..df40f0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowAttributeModule.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.flow.FlowHelper;
+
+import java.util.Map;
+
+/**
+ * FlowAttributeModule provides access to the flow business object properties.
+ * To get access to the properties use XPath syntax. If requested
+ * object is not found then an exception will be thrown.
+ *
+ * @version $Id$
+ */
+public class FlowAttributeModule extends AbstractJXPathModule
+    implements ThreadSafe {
+
+    protected Object getContextObject(Configuration modeConf,
+                                      Map objectModel) {
+
+        return FlowHelper.getContextObject(objectModel);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowContinuationModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowContinuationModule.java
new file mode 100644
index 0000000..a9f94d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/FlowContinuationModule.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.flow.FlowHelper;
+
+import java.util.Map;
+
+/**
+ * FlowContinuationModule provides access to the flow web continuation
+ * object. To get access to the properties use XPath syntax. If
+ * requested object is not found then an exception will be thrown.
+ *
+ * @version $Id$
+ */
+public class FlowContinuationModule extends AbstractJXPathModule
+    implements ThreadSafe {
+
+    protected Object getContextObject(Configuration modeConf,
+                                      Map objectModel) {
+
+        return FlowHelper.getWebContinuation(objectModel);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/GlobalInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/GlobalInputModule.java
new file mode 100644
index 0000000..65a399c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/GlobalInputModule.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This simple module allows to define global parameters in a sitemap. The
+ * values are inherited from one sitemap to its sub sitemaps and can be
+ * extended there.
+ *
+ * @version $Id$
+ */
+public final class GlobalInputModule
+    extends AbstractLogEnabled
+    implements InputModule, Serviceable, ThreadSafe {
+
+    private ServiceManager manager;
+
+    /**
+     * Serviceable
+     */
+    public void service(ServiceManager manager) {
+        this.manager = manager;
+    }
+
+    /**
+     * Standard access to an attribute's value. If more than one value
+     * exists, the first is returned. If the value does not exist,
+     * null is returned. To get all values, use
+     * {@link #getAttributeValues(String, Configuration, Map)} or
+     * {@link #getAttributeNames(Configuration, Map)} and
+     * {@link #getAttribute(String, Configuration, Map)} to get them one by one.
+     * @param name a String that specifies what the caller thinks
+     * would identify an attribute. This is mainly a fallback if no
+     * modeConf is present.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        SitemapVariableHolder holder = null;
+        try {
+            holder = (SitemapVariableHolder)this.manager.lookup(SitemapVariableHolder.ROLE);
+            return holder.get(name);
+        } catch (ServiceException ce) {
+            throw new ConfigurationException("Unable to lookup SitemapVariableHolder.", ce);
+        } finally {
+            this.manager.release(holder);
+        }
+    }
+
+    /**
+     * Returns an Iterator of String objects containing the names
+     * of the attributes available. If no attributes are available,
+     * the method returns an empty Iterator.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        SitemapVariableHolder holder = null;
+        try {
+            holder = (SitemapVariableHolder)this.manager.lookup(SitemapVariableHolder.ROLE);
+            return holder.getKeys();
+        } catch (ServiceException ce) {
+            throw new ConfigurationException("Unable to lookup SitemapVariableHolder.", ce);
+        } finally {
+            this.manager.release(holder);
+        }
+    }
+
+    /**
+     * Returns an array of String objects containing all of the values
+     * the given attribute has, or null if the attribute does not
+     * exist. As an alternative,
+     * {@link #getAttributeNames(Configuration, Map)} together with
+     * {@link #getAttribute(String, Configuration, Map)} can be used to get the
+     * values one by one.
+     * @param name a String that specifies what the caller thinks
+     * would identify an attributes. This is mainly a fallback
+     * if no modeConf is present.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        Object o = this.getAttribute(name, modeConf, objectModel);
+        if (o != null) {
+            return new Object[] {o};
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/HeaderAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/HeaderAttributeModule.java
new file mode 100644
index 0000000..f96af20
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/HeaderAttributeModule.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * HeaderAttributeModule accesses request header attributes. If the
+ * attribute name contains an askerisk "*" this is considered a
+ * wildcard and all attributes that would match this wildcard are
+ * considered to be part of an array of that name for
+ * getAttributeValues. Only one "*" is allowed.
+ *
+ * @version $Id$
+ */
+public class HeaderAttributeModule extends AbstractInputModule implements ThreadSafe {
+    
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        String pname = (String) this.settings.get("parameter",name);
+        if ( modeConf != null ) {
+            pname = modeConf.getAttribute( "parameter", pname );
+            // preferred
+            pname = modeConf.getChild("parameter").getValue(pname);
+        }
+        return ObjectModelHelper.getRequest(objectModel).getHeader( pname );
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        return new IteratorHelper(ObjectModelHelper.getRequest(objectModel).getHeaderNames());
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        String wildcard = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            wildcard = modeConf.getAttribute( "parameter", wildcard );
+            // preferred
+            wildcard = modeConf.getChild("parameter").getValue(wildcard);
+        }
+        int wildcardIndex = wildcard.indexOf( "*" );
+        if ( wildcardIndex != -1 ) {
+            // "*" contained in attribute name => combine all
+            // attributes' values that match prefix, suffix
+            
+            // split the attribute's name so that the "*" could be
+            // determined by looking at the attributes' names that
+            // start with the prefix and end with the suffix
+            //
+            String prefix = wildcard.substring( 0, wildcardIndex );
+            String suffix;
+            if ( wildcard.length() >= wildcardIndex + 1 ) {
+                suffix = wildcard.substring( wildcardIndex + 1 );
+            } else {
+                suffix = "";
+            }
+            SortedSet names = new TreeSet();
+            Enumeration allNames = request.getHeaderNames();
+
+            while (allNames.hasMoreElements()) {
+                String pname = (String) allNames.nextElement();
+                if ( pname.startsWith( prefix ) && pname.endsWith( suffix ) ) {
+                    names.add(pname);
+                }
+            }
+
+            List values = new LinkedList();
+            Iterator j = names.iterator();
+            while (j.hasNext()){
+                String pname = (String) j.next();
+                values.add( request.getHeader( pname ) );
+            }
+            
+            return values.toArray();
+
+        } else {
+            // no "*" in attribute name => just return all values of
+            // this one attribute. Make sure, it's an array.
+            
+            Object value = request.getHeader( wildcard );
+            if ( value != null && !value.getClass().isArray() ) {
+                Object[] values = new Object[1];
+                values[0] = value;
+                return values;
+            } else {
+                return (Object[]) value;
+            }
+            
+        }
+    
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModule.java
new file mode 100644
index 0000000..c633039
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModule.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * InputModule specifies an interface for components that provide
+ * access to individual attributes e.g. request parameters, request
+ * attributes, session attributes &c.
+ *
+ * @version $Id$
+ */
+public interface InputModule {
+
+    String ROLE = InputModule.class.getName();
+
+
+    /**
+     * Standard access to an attribute's value. If more than one value
+     * exists, the first is returned. If the value does not exist,
+     * null is returned. To get all values, use
+     * {@link #getAttributeValues(String, Configuration, Map)} or
+     * {@link #getAttributeNames(Configuration, Map)} and
+     * {@link #getAttribute(String, Configuration, Map)} to get them one by one.
+     * @param name a String that specifies what the caller thinks
+     * would identify an attribute. This is mainly a fallback if no
+     * modeConf is present.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException;
+
+
+    /**
+     * Returns an Iterator of String objects containing the names
+     * of the attributes available. If no attributes are available,
+     * the method returns an empty Iterator.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException;
+
+
+    /**
+     * Returns an array of String objects containing all of the values
+     * the given attribute has, or null if the attribute does not
+     * exist. As an alternative,
+     * {@link #getAttributeNames(Configuration, Map)} together with
+     * {@link #getAttribute(String, Configuration, Map)} can be used to get the
+     * values one by one.
+     * @param name a String that specifies what the caller thinks
+     * would identify an attributes. This is mainly a fallback
+     * if no modeConf is present.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel
+     */
+    Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException;
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleAttributeException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleAttributeException.java
new file mode 100644
index 0000000..213c9f7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleAttributeException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+public final class InputModuleAttributeException extends InputModuleException
+{
+    public InputModuleAttributeException(String message)
+    {
+        super(message, null);
+    }
+
+    public InputModuleAttributeException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleDestructionException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleDestructionException.java
new file mode 100644
index 0000000..107fabd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleDestructionException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+public final class InputModuleDestructionException extends InputModuleException
+{
+    public InputModuleDestructionException(String message)
+    {
+        super(message, null);
+    }
+
+    public InputModuleDestructionException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleException.java
new file mode 100644
index 0000000..c663d31
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+public class InputModuleException extends CascadingRuntimeException
+{
+    public InputModuleException(String message)
+    {
+        super(message, null);
+    }
+
+    public InputModuleException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleHelper.java
new file mode 100644
index 0000000..1ca8352
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleHelper.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class InputModuleHelper {
+    
+    // TODO consolidate code with AbstractMetaModule to use this class as delegate
+
+    protected final static String INPUT_MODULE_SELECTOR = InputModule.ROLE+"Selector";
+
+    /* Operation codes */
+    private final static int OP_GET = 0;
+    private final static int OP_VALUES = 1;
+    private final static int OP_NAMES = 2;
+
+    
+    private Map inputModules;
+    private ServiceManager serviceManager;
+    private ServiceSelector serviceInputSelector;
+    
+    /**
+     * Get the input module
+     */
+    private InputModule getInputModule(String name)
+    throws InputModuleException {
+        if ( this.inputModules == null ) {
+            throw new InputModuleInitializationException("ModuleHelper is not setup correctly.");
+        }
+        InputModule module = (InputModule) this.inputModules.get(name);
+        if ( module == null ) {
+            try {
+                if (this.serviceInputSelector.isSelectable(name)) {
+                    module = (InputModule) this.serviceInputSelector.select(name);
+                }
+            } catch (Exception e) {
+                throw new InputModuleNotFoundException("Unable to lookup input module " + name, e);
+            }
+            if ( module == null ) {
+                throw new InputModuleNotFoundException("No such InputModule: "+name);
+            }
+            this.inputModules.put(name, module);
+        }
+        return module;
+    }
+    
+    /**
+     * Capsules use of an InputModule. Does all the lookups and so
+     * on. Returns either an Object, an Object[], or an Iterator,
+     * depending on the method called i.e. the op specified. The
+     * second module is preferred and has an non null name. If an
+     * exception is encountered, a warn message is printed and null is
+     * returned.
+     * @param op an <code>int</code> value encoding the desired operation
+     * @param name a <code>String</code> value holding the name of the
+     * InputModule
+     * @param attr a <code>String</code> value holding the name of the
+     * attribute to return. Is disregarded when attribute names is
+     * requested.
+     * @param objectModel a <code>Map</code> value holding the current
+     * ObjectModel
+     * @return an <code>Object</code> value
+     * @throws InputModuleException if an error occurs. The real
+     * exception can be obtained with <code>getCause</code>.
+     */
+    private Object get(int op, String name, String attr, Map objectModel, Configuration conf) throws InputModuleException {
+
+        Object value = null;
+        final InputModule input = this.getInputModule(name);
+
+        try {
+
+            switch (op) {
+            case OP_GET:    
+                value = input.getAttribute(attr, conf, objectModel);
+                break;
+            case OP_VALUES:
+                value = input.getAttributeValues(attr, conf, objectModel);
+                break;
+            case OP_NAMES:
+                value = input.getAttributeNames(conf, objectModel);
+                break;
+            }
+
+        } catch (Exception e) {
+            throw new InputModuleAttributeException("Error accessing attribute '"+attr+"' from input module '"+name+"'. "+e.getMessage(), e);
+        }
+
+        return value;
+    }
+
+    private Object get(int op, String name, String attr, Map objectModel) throws InputModuleException {
+        return get(op, name, attr, objectModel, null);
+    }
+
+
+
+    /**
+     * Initializes the instance for first use. Stores references to
+     * service manager and service selector in instance 
+     * 
+     * @param manager a <code>ServiceManager</code> value
+     * @throws InputModuleException if an error occurs
+     */
+    public void setup(ServiceManager manager) throws InputModuleException {
+
+        this.inputModules = new HashMap();
+        this.serviceManager = manager;
+        try {
+            this.serviceInputSelector = (ServiceSelector) this.serviceManager.lookup(INPUT_MODULE_SELECTOR); 
+        } catch (Exception e) {
+            throw new InputModuleInitializationException("Could not obtain selector for InputModule.",e);
+        }
+    }
+
+
+    /**
+     * Get a single attribute value from a module. Uses cached
+     * reference if existing.
+     *
+     * @param objectModel a <code>Map</code> value
+     * @param conf a <code>Configuration</code> containing the module dynamic configuration (aka modeConf)
+     * @param module a <code>String</code> value holding the module name
+     * @param name a <code>String</code> value holding the attribute name
+     * @param deflt an <code>Object</code> value holding a default value
+     * @return an <code>Object</code> value
+     * @throws InputModuleException if an error occurs
+     */
+    public Object getAttribute(Map objectModel, Configuration conf, String module, String name, Object deflt) throws InputModuleException {
+
+        Object result = this.get(OP_GET, module, name, objectModel, conf);
+        if (result == null) result = deflt;
+        return result;
+    }
+
+    /**
+     * Get a single attribute value from a module.  Same as {@link
+     * #getAttribute(Map, Configuration, String, String, Object)} with a
+     * <code>null</code> configuration.
+     */
+    public Object getAttribute(Map objectModel, String module, String name, Object deflt) throws InputModuleException {
+        return getAttribute(objectModel, null, module, name, deflt);
+    }
+
+
+    /**
+     * Get an array of values from a module. Uses cached reference if
+     * existing.
+     *
+     * @param objectModel a <code>Map</code> value
+     * @param conf a <code>Configuration</code> containing the module dynamic configuration (aka modeConf)
+     * @param module a <code>String</code> value holding the module name
+     * @param name a <code>String</code> value holding the attribute name
+     * @param deflt an <code>Object[]</code> value holding a default value
+     * @return an <code>Object[]</code> value
+     * @throws InputModuleException if an error occurs
+     */
+    public Object[] getAttributeValues(Map objectModel, Configuration conf, String module, String name, Object[] deflt) throws InputModuleException {
+
+        Object[] result = (Object[]) this.get(OP_VALUES, module, name, objectModel, conf);
+        if (result == null) result = deflt;
+        return result;
+    }
+
+    /**
+     * Get an array of values from a module. Same as
+     * {@link #getAttributeValues(Map, Configuration, String, String, Object[])}
+     * with a <code>null</code> configuration.
+     */
+    public Object[] getAttributeValues(Map objectModel, String module, String name, Object[] deflt) throws InputModuleException {
+        return getAttributeValues(objectModel, null, module, name, deflt);
+    }
+
+
+    /**
+     * Get an iterator to a collection of attribute names from a
+     * module.
+     *
+     * @param objectModel a <code>Map</code> value
+     * @param module the module's name
+     * @return an <code>Iterator</code> value
+     * @throws InputModuleException if an error occurs
+     */
+    public Iterator getAttributeNames(Map objectModel, Configuration conf, String module) throws InputModuleException {
+
+        return (Iterator) this.get(OP_NAMES, module, null, objectModel);
+    }
+
+    /**  Get an iterator to a collection of attribute names from a module. Same
+     * as {@link #getAttributeNames(Map, Configuration, String)} with a
+     * <code>null</code> configuration.
+     */
+    public Iterator getAttributeNames(Map objectModel, String module) throws InputModuleException {
+        return getAttributeNames(objectModel, (Configuration)null, module);
+    }
+
+
+
+    /**
+     * Releases all obtained module references.
+     *
+     * @throws InputModuleException if an error occurs
+     */
+    public void releaseAll() throws InputModuleException {
+
+        if ( this.inputModules != null ) {
+            if ( this.serviceManager != null ) {
+                try {
+                    Iterator iter = this.inputModules.keySet().iterator();
+                    while (iter.hasNext()) {
+                        this.serviceInputSelector.release(this.inputModules.get(iter.next()));
+                    }
+                    this.inputModules = null;
+                    this.serviceManager.release(this.serviceInputSelector);
+                    this.serviceManager = null;
+                    this.inputModules = null;
+                } catch (Exception e) {
+                    throw new InputModuleDestructionException("Could not release InputModules.",e);
+                }
+                
+            }
+        }
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleInitializationException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleInitializationException.java
new file mode 100644
index 0000000..ec65479
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleInitializationException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+public final class InputModuleInitializationException extends InputModuleException
+{
+    public InputModuleInitializationException(String message)
+    {
+        super(message, null);
+    }
+
+    public InputModuleInitializationException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleNotFoundException.java
new file mode 100644
index 0000000..40a3068
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/InputModuleNotFoundException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+public final class InputModuleNotFoundException extends InputModuleException
+{
+    public InputModuleNotFoundException(String message)
+    {
+        super(message, null);
+    }
+
+    public InputModuleNotFoundException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/IteratorHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/IteratorHelper.java
new file mode 100644
index 0000000..90e910a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/IteratorHelper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+/**
+ * Wraps an Enumeration and provides Iterator interface.
+ *
+ * @version $Id$
+ */
+class IteratorHelper implements Iterator {
+
+    protected Enumeration enumeration;
+
+    public IteratorHelper( Enumeration e ) { this.enumeration = e; }
+    public boolean hasNext() { return this.enumeration.hasMoreElements(); }
+    public Object next() { return this.enumeration.nextElement(); }
+    /** ignored */
+    public void remove() {}
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelper.java
new file mode 100644
index 0000000..92303e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelper.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.commons.jxpath.JXPathBeanInfo;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.JXPathIntrospector;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class JXPathHelper {
+
+    private JXPathHelper() {
+        // no instances allowed
+    }
+
+    /**
+     * Configure component. Preprocess list of packages, functions
+     * and namespaces to add to the JXPath context later.
+     *
+     * This method used in both AbstractJXPathModule and JXPathMetaModule
+     * to configure JXPath.
+     *
+     * @param config a <code>Configuration</code> value
+     * @exception ConfigurationException if an error occurs
+     */
+    public static JXPathHelperConfiguration setup(Configuration config)
+    throws ConfigurationException {
+
+        return new JXPathHelperConfiguration(config);
+    }
+
+
+    /**
+     * Actually add global functions and packages as well as those
+     * listed in the configuration object.
+     *
+     * @param context a <code>JXPathContext</code> value
+     * @param conf a <code>Configuration</code> value holding local
+     * packages and functions.
+     */
+    private static void setup(JXPathHelperConfiguration setup, JXPathContext context, Configuration conf)
+    throws ConfigurationException {
+
+        // Create local config (if necessary)
+        JXPathHelperConfiguration local = conf == null ? setup : new JXPathHelperConfiguration(setup, conf);
+
+        // Setup context with local config
+        context.setLenient(setup.isLenient());
+        context.setFunctions(local.getLibrary());
+        if (local.getNamespaces() != null) {
+            for (Iterator i = local.getNamespaces().entrySet().iterator(); i.hasNext();) {
+                final Map.Entry entry = (Map.Entry) i.next();
+                context.registerNamespace((String) entry.getKey(), (String) entry.getValue());
+            }
+        }
+    }
+
+    public static Object getAttribute(String name,
+                                      Configuration modeConf,
+                                      JXPathHelperConfiguration setup,
+                                      Object contextObj)
+    throws ConfigurationException {
+
+        if (contextObj == null) {
+            return null;
+        }
+
+        try {
+            JXPathContext jxContext = JXPathContext.newContext(contextObj);
+            setup(setup, jxContext, modeConf);
+
+            Object obj = jxContext.getValue(name);
+            return obj;
+        } catch (Exception e) {
+            throw new ConfigurationException("Module does not support <" + name + ">" + "attribute.", e);
+        }
+    }
+
+    public static Object[] getAttributeValues(String name,
+                                              Configuration modeConf,
+                                              JXPathHelperConfiguration setup,
+                                              Object contextObj)
+    throws ConfigurationException {
+
+        if (contextObj == null) {
+            return null;
+        }
+
+        try {
+            JXPathContext jxContext = JXPathContext.newContext(contextObj);
+            setup(setup, jxContext, modeConf);
+
+            List values = null;
+            Iterator i = jxContext.iterate(name);
+            if (i.hasNext()) {
+                values = new LinkedList();
+            }
+            while (i.hasNext()) {
+                values.add(i.next());
+            }
+            Object[] obj = null;
+            if (values != null) {
+                obj = values.toArray();
+                if (obj.length == 0) {
+                    obj = null;
+                }
+            }
+            return obj;
+        } catch (Exception e) {
+            throw new ConfigurationException("Module does not support <" + name + ">" + "attribute.", e);
+        }
+    }
+
+
+    public static Iterator getAttributeNames(JXPathHelperConfiguration setup, Object contextObj)
+    throws ConfigurationException {
+
+        if (contextObj == null) {
+            return null;
+        }
+
+        try {
+            JXPathBeanInfo info = JXPathIntrospector.getBeanInfo(contextObj.getClass());
+            java.beans.PropertyDescriptor[] properties = info.getPropertyDescriptors();
+
+            List names = new LinkedList();
+            for (int i = 0; i < properties.length; i++) {
+                names.add(properties[i].getName());
+            }
+
+            return names.listIterator();
+        } catch (Exception e) {
+            throw new ConfigurationException("Error retrieving attribute names for class: " + contextObj.getClass(), e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelperConfiguration.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelperConfiguration.java
new file mode 100644
index 0000000..b65d44a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathHelperConfiguration.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.commons.jxpath.ClassFunctions;
+import org.apache.commons.jxpath.FunctionLibrary;
+import org.apache.commons.jxpath.PackageFunctions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class JXPathHelperConfiguration {
+
+    /**
+     * Contains all globally registered extension classes and
+     * packages. Thus the lookup and loading of globally registered
+     * extensions is done only once.
+     */
+    private FunctionLibrary library;
+
+    /**
+     * Set lenient mode for jxpath
+     * (i.e. throw an exception on unsupported attributes)?
+     * Defaults to true.
+     */
+    private boolean lenient;
+
+    /**
+     * Contains all registered namespace prefixes.
+     */
+    private Map namespaces;
+
+
+    /**
+     * Create empty jxpath configuration
+     */
+    public JXPathHelperConfiguration() {
+        this.lenient = true;
+    }
+
+    /**
+     * Create root jxpath configuration
+     */
+    public JXPathHelperConfiguration(Configuration config)
+    throws ConfigurationException {
+        this.lenient = config.getChild("lenient").getValueAsBoolean(true);
+        this.library = new FunctionLibrary();
+        setup(config);
+
+        // the following is necessary to be able to use methods on objects without
+        // explicitely registering extension functions (see PackageFunctions javadoc)
+        this.library.addFunctions(new PackageFunctions("", null));
+    }
+
+    /**
+     * Create child jxpath configuration
+     */
+    public JXPathHelperConfiguration(JXPathHelperConfiguration global, Configuration config)
+    throws ConfigurationException {
+        this.lenient = global.lenient;
+        this.library = new FunctionLibrary();
+        this.library.addFunctions(global.getLibrary());
+        if (global.getNamespaces() != null) {
+            this.namespaces = new HashMap(global.getNamespaces());
+        }
+        setup(config);
+    }
+
+
+    public boolean isLenient() {
+        return this.lenient;
+    }
+
+    public FunctionLibrary getLibrary() {
+        return this.library;
+    }
+
+    public Map getNamespaces() {
+        return this.namespaces;
+    }
+
+
+    private void setup(Configuration config)
+    throws ConfigurationException {
+        getFunctions(config);
+        getPackages(config);
+        getNamespaces(config);
+    }
+
+    /**
+     * Register all extension functions listed in the configuration
+     * through <code>&lt;function name="fully.qualified.Class"
+     * prefix="prefix"/&gt;</code> in the given FunctionLibrary.
+     *
+     * @param conf a <code>Configuration</code> value
+     */
+    private void getFunctions(Configuration conf) {
+
+        Configuration[] children = conf.getChildren("function");
+        int i = children.length;
+        while (i-- > 0) {
+            String clazzName = children[i].getAttribute("name", null);
+            String prefix = children[i].getAttribute("prefix", null);
+            if (clazzName != null && prefix != null) {
+                try {
+                    Class clazz = Class.forName(clazzName);
+                    this.library.addFunctions(new ClassFunctions(clazz, prefix));
+                } catch (ClassNotFoundException cnf) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    /**
+     * Register all extension packages listed in the configuration
+     * through <code>&lt;package name="fully.qualified.package"
+     * prefix="prefix"/&gt;</code> in the given FunctionLibrary.
+     *
+     * @param conf a <code>Configuration</code> value
+     */
+    private void getPackages(Configuration conf) {
+
+        Configuration[] children = conf.getChildren("package");
+        int i = children.length;
+        while (i-- > 0) {
+            String packageName = children[i].getAttribute("name", null);
+            String prefix = children[i].getAttribute("prefix", null);
+            if (packageName != null && prefix != null) {
+                this.library.addFunctions(new PackageFunctions(packageName, prefix));
+            }
+        }
+    }
+
+    /**
+     * Register all namespaces listed in the configuration
+     * through <code>&lt;namespace uri="uri:foo"
+     * prefix="bar"/&gt;</code> in the configuration.
+     *
+     * @param conf a <code>Configuration</code> value
+     */
+    private void getNamespaces(Configuration conf)
+    throws ConfigurationException {
+
+        Configuration[] children = conf.getChildren("namespace");
+        int i = children.length;
+        if (i > 0) {
+            this.namespaces = new HashMap(i + 2);
+        }
+        while (i-- > 0) {
+            String uri = children[i].getAttribute("uri");
+            String prefix = children[i].getAttribute("prefix");
+            if (uri != null && prefix != null) {
+                this.namespaces.put(prefix, uri);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathMetaModule.java
new file mode 100644
index 0000000..7f7e3f0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/JXPathMetaModule.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * JXPathModule allows to access properties of any object in generic
+ * way.  JXPath provides APIs for the traversal of graphs of
+ * JavaBeans, DOM and other types of objects using the XPath
+ * syntax.
+ *
+ * <p><strong>Note:</strong> This is based on the AbstractJXPathModule
+ * and duplicates the code since multiple inheritance is not possible.
+ * Please keep both classes in sync.</p>
+ *
+ * <p>Configuration example:</p>
+ * <table>
+ * <tr>
+ *   <td><code>&lt;lenient&gt;false&lt;/lenient&gt;</td>
+ *   <td>When set to true, non-existing attributes return null, when set to false,
+ *       an exception is thrown. Default is true.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;parameter&gt;false&lt;/parameter&gt;</td>
+ *   <td>Attribute name to be used instead of passed attribute name.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;from-parameter&gt;false&lt;/from-parameter&gt;</td>
+ *   <td>Attribute name to pass to configured input module</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;input-module name="request-attr"/&gt;</td>
+ *   <td>Uses the "request-attr" input module to obtain a value and
+ *       applies the given JXPath expression to it.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;function name="java.lang.String" prefix="str"/&gt;</td>
+ *   <td>Imports the class "String" as extension class to the JXPathContext using
+ *   the prefix "str". Thus "str:length(xpath)" would apply the method "length" to
+ *   the string object obtained from the xpath expression. Please note that the class
+ *   needs to be fully qualified.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;package name="java.util" prefix="util"/&gt;</td>
+ *   <td>Imports all classes in the package "java.util" as extension classes to the
+ *   JXPathContext using the prefix "util". Thus "util:Date.new()" would create a
+ *   new java.util.Date object.</td>
+ * </tr>
+ * <tr>
+ *   <td><code>&lt;namespace uri="uri:foo" prefix="bar"/&gt;</td>
+ *   <td>Registers the namespace identified by URI <code>uri:foo</code>
+ *   with the JXPathContext using the prefix <code>bar</code>. Thus
+ *   expressions can query XML with nodes in this namespace using
+ *   registered prefix.</td>
+ * </tr>
+ * </table>
+ *
+ * <p>In addition, it accepts the attributes "parameter" to override
+ * the attribute name and "from-parameter" to pass as attribute name
+ * to the configured input module.</p>
+ *
+ * @version $Id$
+ */
+public class JXPathMetaModule extends AbstractMetaModule
+                              implements Configurable, ThreadSafe {
+
+    /**
+     * Contains all globally registered extension classes and
+     * packages. Thus the lookup and loading of globally registered
+     * extensions is done only once.
+     */
+    protected JXPathHelperConfiguration configuration;
+
+    /**
+     * Overrides attribute name
+     */
+    protected String parameter = "";
+
+
+    public JXPathMetaModule() {
+        // this value has a default in the super class
+        super.defaultInput = "request-attr";
+    }
+
+
+    /**
+     * Configure component. Preprocess list of packages and functions
+     * to add to JXPath context later.
+     *
+     * @param config a <code>Configuration</code> value
+     * @exception ConfigurationException if an error occurs
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+        this.parameter = config.getChild("parameter").getValue(this.parameter);
+
+        this.configuration = JXPathHelper.setup(config);
+    }
+
+
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        if (modeConf != null) {
+            name = modeConf.getChild("parameter").getValue(!this.parameter.equals("") ? this.parameter : name);
+        }
+        return JXPathHelper.getAttribute(name, modeConf, this.configuration, contextObj);
+    }
+
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        return JXPathHelper.getAttributeNames(this.configuration, contextObj);
+    }
+
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        Object contextObj = getContextObject(modeConf, objectModel);
+        if (modeConf != null) {
+            name = modeConf.getChild("parameter").getValue(!this.parameter.equals("") ? this.parameter : name);
+        }
+        return JXPathHelper.getAttributeValues(name, modeConf, this.configuration, contextObj);
+    }
+
+
+    /**
+     * Looks up object from configured InputModule.
+     *
+     * @param modeConf a <code>Configuration</code> value
+     * @param objectModel a <code>Map</code> value
+     * @return an <code>Object</code> value
+     */
+    protected  Object getContextObject(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        if (!this.initialized) {
+            lazy_initialize();
+        }
+
+        Configuration mConf = null;
+        String inputName = null;
+        String parameter = this.parameter;
+        if (modeConf != null) {
+            mConf = modeConf.getChild("input-module");
+            inputName = mConf.getAttribute("name", null);
+            parameter = modeConf.getChild("from-parameter").getValue(parameter);
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("modeConf is " + modeConf + " this.inputConf is " + this.inputConf
+                              + " mConf is " + mConf + " this.input is " + this.input
+                              + " this.defaultInput is " + this.defaultInput
+                              + " inputName is " + inputName + " parameter is " + parameter);
+        }
+
+        Object obj = getValue(parameter, objectModel,
+                              this.input, this.defaultInput, this.inputConf,
+                              null, inputName, mConf);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("returning an " + (obj == null ? "null" : obj.getClass().getName()) +
+                              " as " + obj);
+        }
+
+        return obj;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/LocateResource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/LocateResource.java
new file mode 100644
index 0000000..1ba7719
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/LocateResource.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.Vector;
+
+/**
+ * Locate a resource in a resource tree. Any attribute name is interpreted as a
+ * URI with the last part being the resource name unless it ends with a slash. 
+ * The URI is checked if the resource exists and the URI is returned. If the
+ * resource does not exist, the URI is shortened until the resource name is found
+ * and the new URI is returned. If no resource with the given name exists, null
+ * is returned. 
+ * 
+ * <p>A use case is to locate the closest menu file or when moving a site from
+ * a filesystem path == URL system from a httpd to Cocoon and provide similar
+ * functions to .htaccess files.</p>
+ * 
+ * <p>Example: for context:/some/path/to/a/file.xml the following URIs
+ * are tested: context:/some/path/to/a/file.xml, context:/some/path/to/file.xml,
+ * context:/some/path/file.xml, context:/some/file.xml, and context:/file.xml.
+ * For the attribute name context:/some/path/foo/ tests context:/some/path/foo/,
+ * context:/some/path/, context:/some/, and context:/ are tested.</p> 
+ * 
+ * <p>The getAttribute() method will return the URI for the first match while 
+ * getAttributeValues() will return an array of all existing paths. 
+ * getAttributeNames() will return an Iterator to an empty collection.</p>
+ * 
+ * @version $Id$
+ */
+public class LocateResource extends AbstractInputModule implements Serviceable, ThreadSafe {
+
+    protected static Collection col;
+    static {
+        col = new TreeSet();
+    }
+
+    protected ServiceManager manager;
+
+    /**
+     * Calculate the minimal length of the URL, that is the position
+     * of the first ":" if a protocol is provided or otherwise 0.
+     * @param name
+     * @return minimal length
+     */
+    protected int calculateMinLen(String name) {
+
+        int minLen = name.indexOf(':');
+        minLen = (minLen == -1 ? 0 : minLen);
+
+        return minLen;
+    }
+
+    /**
+     * Remove one path element from the URL unless minimum length has
+     * been reached.
+     * 
+     * @param urlstring
+     * @param minLen
+     * @return shortened URI
+     */
+    protected String shortenURI(String urlstring, int minLen) {
+
+        int idx = urlstring.lastIndexOf('/');
+        idx = (idx <= minLen + 1) ? minLen : idx;
+        urlstring = urlstring.substring(0, idx);
+
+        return urlstring;
+    }
+
+    /** 
+     * if the url does not end with a "/", keep the last part in
+     * order to add it later again after traversing up
+     */
+    protected String extractFilename(String urlstring) {
+
+        String filename = "";
+        if (!urlstring.endsWith("/")) {
+            int idx = urlstring.lastIndexOf('/');
+            filename = urlstring.substring(idx);
+        }
+
+        return filename;
+    }
+
+    /**
+     * Locate a resource with the given URL consisting of urlstring + filename.
+     * The filename is appended each time the path is shortened. Returns the first
+     * existing occurance.
+     * 
+     * @param urlstring
+     * @param filename
+     * @param minLen
+     * @return urlstring if resource was found, <code>null</code> otherwise
+     */
+    protected String locateResource(String urlstring, String filename, int minLen) {
+        String sourcename = null;
+        Source src = null;
+        SourceResolver resolver = null;
+        boolean found = false;
+        try {
+            resolver =
+                (SourceResolver) this.manager.lookup(
+                    org.apache.excalibur.source.SourceResolver.ROLE);
+            while (!found && urlstring.length() > minLen) {
+                sourcename = urlstring + filename;
+                try {
+                    src = resolver.resolveURI(sourcename);
+                    if (src.exists())
+                        found = true;
+                } catch (Exception e) {
+                    if (this.getLogger().isWarnEnabled())
+                        this.getLogger().warn("Exception resolving URL " + sourcename, e);
+                } finally {
+                    resolver.release(src);
+                }
+                if (!found) {
+                    urlstring = shortenURI(urlstring, minLen);
+                }
+            }
+        } catch (ServiceException e1) {
+            if (this.getLogger().isErrorEnabled())
+                this.getLogger().error("Exception obtaining source resolver ", e1);
+        } finally {
+            if (resolver != null) {
+                this.manager.release(resolver);
+            }
+        }
+        return (found ? urlstring : null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+
+        String urlstring = name;
+        String filename = extractFilename(urlstring);
+        int minLen = calculateMinLen(name);
+        if (filename != "") {
+            urlstring = shortenURI(urlstring, minLen);
+        }
+
+        String result = locateResource(urlstring, filename, minLen);
+        result = (result == null? result : result + filename);
+        if (this.getLogger().isDebugEnabled())
+            this.getLogger().debug(
+                "located " + name + " @ " + result);
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+        // return an iterator to an empty collection
+        return LocateResource.col.iterator();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+        throws ConfigurationException {
+
+        Vector uris = null;
+        String urlstring = name;
+        String filename = extractFilename(urlstring);
+        int minLen = calculateMinLen(name);
+        if (filename != "") {
+            urlstring = shortenURI(urlstring, minLen);
+        }
+
+        while (urlstring != null && urlstring.length() > minLen) {
+            urlstring = this.locateResource(urlstring, filename, minLen);
+            if (urlstring != null) {
+                if (uris == null)
+                    uris = new Vector();
+                if (this.getLogger().isDebugEnabled())
+                    this.getLogger().debug("-> located " + name + " @ " + urlstring + filename);
+                uris.add(urlstring + filename);
+                urlstring = shortenURI(urlstring, minLen);
+            }
+        }
+        return (uris == null ? null : uris.toArray());
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/MapMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/MapMetaModule.java
new file mode 100644
index 0000000..7ea28cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/MapMetaModule.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/** 
+ * Meta module that obtains an Object from another module, assumes
+ * that this Object implements the java.util.Map interface, and gives
+ * access to the map contents. Possible use is to propagate data from
+ * flow through request attributes to database actions.
+ * The same can be achieved by using the {@link JXPathMetaModule}.
+ *
+ * <p>Configuration: "input-module", "object", "parameter"</p>
+ *
+ * @version $Id$
+ */
+public class MapMetaModule extends AbstractMetaModule implements ThreadSafe {
+
+    protected String objectName = null;
+    protected String parameter = null;
+
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name", this.defaultInput);
+        this.objectName = this.inputConf.getAttribute("object",this.objectName);
+        this.parameter = this.inputConf.getAttribute("parameter",this.parameter);
+
+        // preferred
+        this.objectName = config.getChild("object").getValue(this.objectName);
+        this.parameter = config.getChild("parameter").getValue(this.parameter);
+    }
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        String inputName=null;
+        String objectName = this.objectName;
+        String parameter = this.parameter;
+        if (modeConf != null) {
+            inputName  = modeConf.getChild("input-module").getAttribute("name",null);
+            objectName = modeConf.getAttribute("object",objectName);
+            parameter  = modeConf.getAttribute("parameter",parameter);
+
+            // preferred
+            objectName = modeConf.getChild("object").getValue(objectName);
+            parameter  = modeConf.getChild("parameter").getValue(parameter);
+        }
+        parameter = (parameter != null? parameter : name);
+
+        Object value = getValue(objectName, objectModel, 
+                                this.input, this.defaultInput, this.inputConf, 
+                                null, inputName, modeConf);
+
+        value = (value!=null? ((Map) value).get(parameter) : null);
+
+        return value;        
+    }
+
+
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+         if (!this.initialized) {
+             this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = null;
+        String inputName=null;
+        String objectName = this.objectName;
+        if (modeConf!=null) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            objectName = modeConf.getAttribute("object",this.objectName);
+
+            // preferred
+            objectName = modeConf.getChild("object").getValue(objectName);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+        }
+
+        Iterator keys = ((Map) getValue(objectName, objectModel, 
+                                        this.input, this.defaultInput, this.inputConf,
+                                        null, inputName, inputConfig)).keySet().iterator();
+
+        return keys;        
+   }
+
+
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        Object[] values = new Object[1];
+        values[0] = this.getAttribute(name, modeConf, objectModel);
+        return (values[0]!=null?values:null);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ModuleHolder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ModuleHolder.java
new file mode 100644
index 0000000..f2b4b2d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ModuleHolder.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ * @version $Id$
+ */
+public class ModuleHolder {
+
+    public String name = null;
+    public InputModule input = null;
+    public Configuration config = null;
+
+    public ModuleHolder() {
+        super();
+    }
+
+    public ModuleHolder(String name, Configuration config) {
+        this();
+        this.name = name;
+        this.config = config;
+    }
+    
+    public ModuleHolder(String name, Configuration config, InputModule input) {
+        this(name, config);
+        this.input = input;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NamingInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NamingInputModule.java
new file mode 100644
index 0000000..a2d3dad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NamingInputModule.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * NamingInputModule accesses values stored in the JNDI context.
+ *
+ * <p>This module accept any configuration parameters and passes them as
+ * properties to the InitialContext. When connecting to the Naming context
+ * of the server Cocoon is running in, no parameters are required.</p>
+ *
+ * <p>Example module configuration when connecting to external WebLogic server:
+ * <pre>
+ *   &lt;java.naming.factory.initial&gt;weblogic.jndi.WLInitialContextFactory&lt;/java.naming.factory.initial&gt;
+ *   &lt;java.naming.provider.url&gt;t3://localhost:7001&lt;/java.naming.provider.url&gt;
+ * </pre>
+ *
+ * <p>Example usage:
+ * <pre>
+ *   &lt;map:generate src="{naming:java:comp/env/greeting}"/&gt;
+ * </pre>
+ * This lookups <code>greeting</code> entry from the environment of the webapp.
+ * Webapp's web.xml should define this entry:
+ * <pre>
+ *   &lt;env-entry&gt;
+ *     &lt;env-entry-name&gt;greeting&lt;/env-entry-name&gt;
+ *     &lt;env-entry-value&gt;Hello, World&lt;/env-entry-value&gt;
+ *     &lt;env-entry-type&gt;java.lang.String&lt;/env-entry-type&gt;
+ *   &lt;/env-entry&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class NamingInputModule extends AbstractInputModule implements ThreadSafe, Initializable {
+
+    /**
+     * Initial context properties.
+     */
+    private Properties properties;
+
+    /**
+     * Initial context.
+     */
+    private InitialContext context;
+
+    /**
+     * Fill in InitialContext properties from passed configuration.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        Configuration[] parameters = conf.getChildren();
+        this.properties = new Properties();
+        for (int i = 0; i < parameters.length; i++) {
+            String key = parameters[i].getName();
+            String val = parameters[i].getValue("");
+            this.properties.put(key, val);
+        }
+    }
+
+    /**
+     * Creates InitialContext with configured properties.
+     */
+    public void initialize() throws Exception {
+        this.context = new InitialContext(this.properties);
+    }
+
+    /**
+     * Close InitialContext.
+     */
+    public void dispose() {
+        super.dispose();
+        if (this.context != null) {
+            try {
+                this.context.close();
+            } catch (NamingException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Look up <code>name</code> from the InitialContext.
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        // Why properties can override passed name parameter? See RequestParameterModule
+        String pname = (String) this.properties.get("path");
+        if (pname == null) {
+            pname = name;
+        }
+
+        if (modeConf != null) {
+            pname = modeConf.getAttribute("path", pname);
+            // preferred
+            pname = modeConf.getChild("path").getValue(pname);
+        }
+
+        try {
+            return this.context.lookup(pname);
+        } catch (NamingException e) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Can't get parameter " + pname, e);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Returns empty iterator
+     */
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        return Collections.EMPTY_LIST.iterator();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NullInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NullInputModule.java
new file mode 100644
index 0000000..e7f191f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/NullInputModule.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * NullInputModule returns a null object.  Use this if you want to
+ * explicitly forbid a parameter to be filled. E.g. a database column
+ * shall be filled with a default value, your forms never contain that
+ * parameter but you don't want anyone to provide this parameter
+ * manually.
+ *
+ * @version $Id$
+ */
+public class NullInputModule extends AbstractInputModule implements ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+        
+        return null;
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return null;
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        return null;
+            
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ProjectPathModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ProjectPathModule.java
new file mode 100644
index 0000000..626bd88
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/ProjectPathModule.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+
+/**
+ * ProjectPathModule provides relative and absolute paths with regards to the root of a project.
+ * <p>Config:
+ * <pre>
+ *    <component-instance logger="core.modules.input"
+ *           name="myproject"
+ *           class="org.apache.cocoon.components.modules.input.ProjectPathModule">
+ *      	<uri-prefix>my/project/</uri-prefix>
+ *    </component-instance>
+ * </pre>
+ * </p>
+ * <p>Usage:
+ * <pre>
+ * <map:transform src="skins/{forrest:skin}/xslt/fo/document2html.xsl">
+ *    <map:parameter name="base" value="{myproject:relative}"/>
+ * </map:transform>
+ *
+ * And then prepend this to all image paths:
+ *  ...
+ *  <xsl:param name="base"/>
+ *  ...
+ *  <xsl:template match="img">
+ *      <img src="{concat($base, @src)}" ...
+ *      ...
+ *  </xsl:template>
+ *  </pre>
+ * Then if you are in my/project/some/folder/page.html, the image will have a relative path bact to the root of the project.
+ * <pre>
+ *   <img src="../../imagename.png"/>
+ * </pre>
+ * Using 'myproject:path' would have given you: /some/folder/page.html<br/>
+ * Using 'myproject:folder' would have given you: /some/folder/
+ * </p>
+ *
+ */
+public class ProjectPathModule
+    extends AbstractInputModule
+    implements Configurable, ThreadSafe {
+
+    protected static String PROJECT_PARAM_NAME = "uri-prefix";
+    protected static String PROJECT_PARAM_DEFAULT = "/";
+
+    protected String projectBase;
+	
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("relative");
+        tmp.add("path");
+        tmp.add("folder");
+        returnNames = tmp;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        this.projectBase = conf.getChild(PROJECT_PARAM_NAME).getValue();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Configuration supplied: " + this.projectBase);
+        }
+        if (this.projectBase == null) {
+       	    this.projectBase = PROJECT_PARAM_DEFAULT;
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("No configuration supplied, using default: " + PROJECT_PARAM_DEFAULT);
+            }
+        }
+        if (this.projectBase.equals("")) {
+            this.projectBase = PROJECT_PARAM_DEFAULT;
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Empty configuration supplied, using default: " + PROJECT_PARAM_DEFAULT);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        String uri = ObjectModelHelper.getRequest(objectModel).getServletPath();
+        StringBuffer result = new StringBuffer(uri.length());
+        int baseIndex = uri.indexOf(this.projectBase);
+        if (baseIndex != -1) {
+            uri = uri.substring(baseIndex + this.projectBase.length());
+        } else {
+            throw new ConfigurationException( "No project-base path found in URI");
+        }
+        try {
+            // provide a relative path back to the project
+            if (name.startsWith("relative")) {
+                int nextIndex = 0;
+                while ((nextIndex = uri.indexOf('/', nextIndex) + 1) > 0) {
+                    result.append("../");
+                }
+            } else if (name.startsWith("path")) {
+                // provide the full path from the project
+                result.append("/");
+                result.append(uri);
+            } else if (name.startsWith("folder")) {
+                // provide the folder path from the project
+                result.append("/");
+                result.append(uri.substring(0,uri.lastIndexOf("/") + 1));
+            } else {
+                if (getLogger().isWarnEnabled()) {
+                    getLogger().warn("Invalid verb: " + name);
+                }
+            }
+            return result;
+        } catch( final Exception mue ) {
+            throw new ConfigurationException( "Problems resolving project path.", mue);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return ProjectPathModule.returnNames.iterator();
+    }
+
+    /**
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        List values = new LinkedList();
+        values.add( this.getAttribute(name, modeConf, objectModel) );
+
+        return values.toArray();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/PropertiesFileModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/PropertiesFileModule.java
new file mode 100644
index 0000000..93c939f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/PropertiesFileModule.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * Input module for accessing properties in a properties file.
+ *
+ * <p>
+ *  The properties file can only be configured statically and
+ *  is resolved via the SourceResolver system.
+ * </p>
+ *
+ */
+public class PropertiesFileModule extends AbstractJXPathModule
+implements InputModule, Serviceable, Configurable, ThreadSafe {
+
+    private ServiceManager m_manager;
+    private SourceResolver m_resolver;
+    private Properties m_properties;
+
+
+    /* (non-Javadoc)
+     * @see Serviceable#service(ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        m_manager = manager;
+        m_resolver = (SourceResolver) m_manager.lookup(SourceResolver.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        super.dispose();
+        if (this.m_manager != null) {
+            this.m_manager.release(this.m_resolver);
+            this.m_manager = null;
+            this.m_resolver = null;
+        }
+    }
+
+    /**
+     * Configure the location of the properties file:
+     * <p>
+     *  <code>&lt;file src="resource://my.properties" /&gt;</code>
+     * </p>
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        super.configure(configuration);
+        String file = configuration.getChild("file").getAttribute("src");
+        load(file);
+    }
+
+    private void load(String file) throws ConfigurationException {
+        Source source = null;
+        InputStream stream = null;
+        try {
+            source = m_resolver.resolveURI(file);
+            stream = source.getInputStream();
+            m_properties = new Properties();
+            m_properties.load(stream);
+        } catch (IOException e) {
+            throw new ConfigurationException("Cannot load properties file " + file);
+        } finally {
+            if (source != null) {
+                m_resolver.release(source);
+            }
+            if (stream != null) {
+                try {
+                    stream.close();
+                } catch (IOException ignored) {
+                }
+            }
+        }
+    }
+
+    protected Object getContextObject(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+
+        return m_properties;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RandomNumberModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RandomNumberModule.java
new file mode 100644
index 0000000..bf765f0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RandomNumberModule.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * RandomNumberModule returns a random number as a string.
+ * Configuration through child elements: "min", "max" setting
+ * range of random number. Defaults to "0" and "9999999999"
+ * respectively.
+ *
+ * @version $Id$
+ */
+public class RandomNumberModule extends AbstractInputModule implements ThreadSafe {
+
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("randomNumber");
+        returnNames = tmp;
+    }
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+        
+        long min = 0;
+        long max = java.lang.Long.MAX_VALUE;
+        if (modeConf != null) {
+            min = Long.parseLong(modeConf.getAttribute("min","0"));
+            max = Long.parseLong(modeConf.getAttribute("max",String.valueOf(max)));
+            
+            //preferred
+            min = Long.parseLong(modeConf.getChild("min").getValue("0"));
+            max = Long.parseLong(modeConf.getChild("max").getValue(String.valueOf(max)));
+        }
+        return Long.toString(java.lang.Math.round(java.lang.Math.random()*(max-min)));
+
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return RandomNumberModule.returnNames.iterator();
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+            List values = new LinkedList();
+            values.add( this.getAttribute(name, modeConf, objectModel ) );
+
+            return values.toArray();
+            
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RawRequestParameterModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RawRequestParameterModule.java
new file mode 100644
index 0000000..571d427
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RawRequestParameterModule.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * RawRequestParameterModule accesses request parameters without
+ * decoding to the specified <code>form-encoding</code> or casting. It uses the
+ * {@link org.apache.cocoon.environment.Request#get} method instead of the
+ * {@link org.apache.cocoon.environment.Request#getParameter} method of the
+ * {@link org.apache.cocoon.environment.Request Request} This is useful for example
+ * in conjunction with uploads.
+ *
+ * <p>If <code>get()</code> returns a Vector, <code>getAttribute()</code> will return
+ * the first element, otherwise it will return the same as <code>get()</code>.
+ * <code>getAttributeValues()</code> will either convert the Vector to an array,
+ * place the result in a new array, or return the array as is.</p>
+ *
+ * @version $Id$
+ */
+public class RawRequestParameterModule extends AbstractInputModule implements ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        String pname = (String) this.settings.get("parameter",name);
+        if ( modeConf != null ) {
+            pname = modeConf.getAttribute( "parameter", pname );
+            // preferred
+            pname = modeConf.getChild("parameter").getValue(pname);
+        }
+        Object obj = ObjectModelHelper.getRequest(objectModel).get( pname );
+        if (obj instanceof Vector) {
+            return ((Vector) obj).firstElement();
+        } else {
+            return obj;
+        }
+
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return new IteratorHelper(ObjectModelHelper.getRequest(objectModel).getParameterNames());
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        Object obj = getAttribute(name, modeConf, objectModel);
+        if (obj instanceof Vector) {
+           return ((Vector)obj).toArray();
+        } else if (obj.getClass().isArray()) {
+            return (Object[]) obj;
+        } else {
+            Object[] tmp = new Object[1];
+            tmp[0] = obj;
+            return tmp;
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RealPathModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RealPathModule.java
new file mode 100644
index 0000000..e71eda0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RealPathModule.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * RealPathModule provides a real filesystem path for a virtual
+ * context-relative path.  If this mapping cannot be performed (e.g. Cocoon is
+ * running in a .war file), <code>null</code> will be returned.
+ *
+ * @version $Id$
+ */
+
+/*
+ * Note: the primary use for this is to support external code that wants a
+ * filesystem path.  For example, The FOP 0.20.x serializer doesn't like
+ * relative image paths, and doesn't understand Cocoon URLs (context:, cocoon:
+ * etc).  So we pass the *2fo.xsl stylesheet a real filesystem path to where we
+ * keep our images:
+ *
+ * <map:transform src="skins/{forrest:skin}/xslt/fo/document2fo.xsl">
+ *    <map:parameter name="basedir" value="{realpath:resources}/"/>
+ * </map:transform>
+ *
+ * And then prepend this to all image paths:
+ *  ...
+ *  <xsl:param name="basedir" select="''"/>
+ *  ...
+ *  <xsl:template match="img">
+ *      <xsl:variable name="imgpath" select="concat($basedir, @src)"/>
+ *      <fo:external-graphic src="{$imgpath}" ...
+ *      ...
+ *  </xsl:template>
+ */
+public class RealPathModule extends AbstractInputModule implements ThreadSafe {
+
+    private final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("realPath");
+        returnNames = tmp;
+    }
+
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        String uri = ObjectModelHelper.getContext(objectModel).getRealPath(name);
+        if (uri == null) {
+            return null;
+        }
+
+        int lastCharPos = uri.length() - 1;
+        if (uri.charAt(lastCharPos) == '\\') {
+            uri = uri.substring(0, lastCharPos);
+        }
+        return uri;
+    }
+
+    public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        return RealPathModule.returnNames.iterator();
+    }
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return new Object[] { getAttribute(name, modeConf, objectModel) };
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestAttributeModule.java
new file mode 100644
index 0000000..8951acc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestAttributeModule.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * RequestAttributeModule accesses request attributes. If the
+ * attribute name contains an askerisk "*" this is considered a
+ * wildcard and all attributes that would match this wildcard are
+ * considered to be part of an array of that name for
+ * getAttributeValues. Only one "*" is allowed.
+ *
+ * @version $Id$
+ */
+public class RequestAttributeModule extends AbstractInputModule implements ThreadSafe {
+
+    protected Object getAttribute( String name, Configuration modeConf, Map objectModel, int scope)
+    throws ConfigurationException {
+        String pname = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            pname = modeConf.getAttribute( "parameter", pname );
+            // preferred
+            pname = modeConf.getChild("parameter").getValue(pname);
+        }
+        return ObjectModelHelper.getRequest(objectModel).getAttribute( pname, scope );        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return this.getAttribute(name, modeConf, objectModel, Request.GLOBAL_SCOPE);
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeNames(org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return new IteratorHelper(ObjectModelHelper.getRequest(objectModel).getAttributeNames());
+    }
+
+
+    protected Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel, int scope )
+    throws ConfigurationException {
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+        
+        String wildcard = (String) this.settings.get("parameter",name);
+        if ( modeConf != null ) {
+            wildcard = modeConf.getAttribute( "parameter", wildcard );
+            // preferred
+            wildcard = modeConf.getChild("parameter").getValue(wildcard);
+        }
+        int wildcardIndex = wildcard.indexOf( "*" );
+        if ( wildcardIndex != -1 ) {
+            // "*" contained in attribute name => combine all
+            // attributes' values that match prefix, suffix
+
+            // split the attribute's name so that the "*" could be
+            // determined by looking at the attributes' names that
+            // start with the prefix and end with the suffix
+            //
+            String prefix = wildcard.substring( 0, wildcardIndex );
+            String suffix;
+            if ( wildcard.length() >= wildcardIndex + 1 ) {
+                suffix = wildcard.substring( wildcardIndex + 1 );
+            } else {
+                suffix = "";
+            }
+            SortedSet names = new TreeSet();
+            Enumeration allNames = request.getAttributeNames( scope );
+
+            while (allNames.hasMoreElements()) {
+                String pname = (String) allNames.nextElement();
+                if ( pname.startsWith( prefix ) && pname.endsWith( suffix ) ) {
+                    names.add(pname);
+                }
+            }
+
+            List values = new LinkedList();
+            Iterator j = names.iterator();
+            while (j.hasNext()){
+                String pname = (String) j.next();
+                values.add( request.getAttribute( pname ) );
+            }
+
+            return values.toArray();
+
+        } else {
+            // no "*" in attribute name => just return all values of
+            // this one attribute. Make sure, it's an array.
+
+            Object value = request.getAttribute( wildcard, scope );
+            if ( value != null && !value.getClass().isArray() ) {
+                Object[] values = new Object[1];
+                values[0] = value;
+                return values;
+            } else {
+                return (Object[]) value;
+            }
+
+        }
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        return this.getAttributeValues(name, modeConf, objectModel, Request.GLOBAL_SCOPE );
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestModule.java
new file mode 100644
index 0000000..1ee7ce1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestModule.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * RequestModule provides access to Request object properties.
+ * To get access to request properties use XPath syntax, e.g. to get the request
+ * context path use <code>'contextPath'</code> as the attribute name.<br/>
+ * More complex expressions are also supported, e.g.:
+ * <pre>
+ * 'userPrincipal/name'
+ * </pre>
+ * will return the name property of the Principal object returned by the
+ * request.getUserPrincipal() method. If requested object is not found then
+ * an exception will be thrown.
+ *
+ * @version $Id$
+ */
+public class RequestModule extends AbstractJXPathModule
+    implements ThreadSafe {
+
+    protected Object getContextObject(Configuration modeConf,
+                                      Map objectModel) {
+
+        return ObjectModelHelper.getRequest(objectModel);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestParameterModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestParameterModule.java
new file mode 100644
index 0000000..d94df95
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestParameterModule.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * RequestParameterModule accesses request parameters. If the
+ * parameter name contains an askerisk "*" this is considered a
+ * wildcard and all parameters that would match this wildcard are
+ * considered to be part of an array of that name for
+ * getAttributeValues. Only one "*" is allowed. Wildcard matches take
+ * precedence over real arrays. In that case only the first value of
+ * such array is returned.
+ *
+ * @version $Id$
+ */
+public class RequestParameterModule extends AbstractInputModule implements ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        String pname = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            pname = modeConf.getAttribute( "parameter", pname );
+            // preferred
+            pname = modeConf.getChild("parameter").getValue(pname);
+        }
+        return ObjectModelHelper.getRequest(objectModel).getParameter( pname );
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return new IteratorHelper(ObjectModelHelper.getRequest(objectModel).getParameterNames());
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        String wildcard = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            wildcard = modeConf.getAttribute( "parameter", wildcard );
+            // preferred
+            wildcard = modeConf.getChild("parameter").getValue(wildcard);
+        }
+        int wildcardIndex = wildcard.indexOf( "*" );
+        if ( wildcardIndex != -1 ) {
+            // "*" contained in parameter name => combine all
+            // parameters' values that match prefix, suffix
+
+            // split the parameter's name so that the "*" could be
+            // determined by looking at the parameters' names that
+            // start with the prefix and end with the suffix
+            //
+            String prefix = wildcard.substring( 0, wildcardIndex );
+            String suffix;
+            if ( wildcard.length() >= wildcardIndex + 1 ) {
+                suffix = wildcard.substring( wildcardIndex + 1 );
+            } else {
+                suffix = "";
+            }
+            SortedSet names = new TreeSet();
+            Enumeration allNames = request.getParameterNames();
+
+            while (allNames.hasMoreElements()) {
+                String pname = (String) allNames.nextElement();
+                if ( pname.startsWith( prefix ) && pname.endsWith( suffix ) ) {
+                    names.add(pname);
+                }
+            }
+
+            List values = new LinkedList();
+            Iterator j = names.iterator();
+            while (j.hasNext()){
+                String pname = (String) j.next();
+                values.add( request.getParameter( pname ) );
+            }
+
+            return values.toArray();
+
+        } else {
+            // no "*" in parameter name => just return all values of
+            // this one parameter.
+
+            return request.getParameterValues( wildcard );
+
+        }
+
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestScopedAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestScopedAttributeModule.java
new file mode 100644
index 0000000..5274500
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestScopedAttributeModule.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.environment.Request;
+
+/**
+ * This is an extension of the {@link RequestAttributeModule}. It has the same
+ * features but requires to define the scope of an attribute: either "global" or
+ * "request"; so the name follows this form: SCOPE:KEY.
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public class RequestScopedAttributeModule extends RequestAttributeModule {
+
+    private static final class KeyInfo {
+        public final int scope;
+        public final String key;
+        
+        public KeyInfo(String name) throws ConfigurationException {
+            final int pos = name.indexOf(':');
+            if ( pos == -1 ) {
+                throw new ConfigurationException("Scope is missing in '" + name + '.');
+            }
+            final String scopeValue = name.substring(0, pos);
+            this.key = name.substring(pos + 1);
+            if ( "global".equalsIgnoreCase(scopeValue) ) {
+                this.scope = Request.GLOBAL_SCOPE;
+            } else if ("request".equalsIgnoreCase(scopeValue)) {
+                this.scope = Request.REQUEST_SCOPE;
+            } else {
+                throw new ConfigurationException("Unknown value for scope: " + scopeValue);
+            }
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        final KeyInfo info = new KeyInfo(name);
+        return this.getAttribute(info.key, modeConf, objectModel, info.scope);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttributeValues(java.lang.String, org.apache.avalon.framework.configuration.Configuration, java.util.Map)
+     */
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+    throws ConfigurationException {
+        final KeyInfo info = new KeyInfo(name);
+        return this.getAttributeValues(info.key, modeConf, objectModel, info.scope );
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestURIModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestURIModule.java
new file mode 100644
index 0000000..ac630de
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/RequestURIModule.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * RequestURIModule accesses the request URI. The {@link
+ * RequestModule} provides similar functionality based on JXPath.
+ *
+ * @version $Id$
+ */
+public class RequestURIModule extends AbstractInputModule implements ThreadSafe {
+
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("requestURI");
+        returnNames = tmp;
+    }
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        String uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+
+        if (uri.startsWith("/")) {
+            uri = uri.substring(1);
+        }
+
+        return uri;
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return RequestURIModule.returnNames.iterator();
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+            Object values = new Object[1];
+            values = this.getAttribute(name, modeConf, objectModel);
+
+            return (values == null? null : new Object[]{values});            
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SelectMetaInputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SelectMetaInputModule.java
new file mode 100644
index 0000000..5b87db2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SelectMetaInputModule.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ *
+ * <h2>Configuration</h2>
+ * <table><tbody>
+ * <tr><th>input-module</th>
+ *  <td>Configuration and name of input module used for the selection.</td>
+ *  <td>req</td>
+ *  <td>String</td><td><code>null</code></td>
+ * </tr>
+ * <tr><th>when</th>
+ *  <td>Selection case, condition in test attribute, input module name
+ *      in name attribute. Optional configuration as nested content.</td>
+ *  <td>req</td><td>String</td><td><code>null</code></td>
+ * </tr>
+ * <tr><th>otherwise</th>
+ *  <td>Default selection case. If not present and no case matches, <code>null</code>
+ *      is returned.</td>
+ *  <td></td><td>String</td><td><code>null</code></td>
+ * </tr>
+ * </tbody></table>
+ *
+ * @version $Id$
+ */
+public class SelectMetaInputModule extends AbstractMetaModule implements ThreadSafe {
+
+    private Map whenTest = null;
+    private ModuleHolder expression = null;
+    private ModuleHolder otherwise = null;
+    private String parameter = null;
+
+    public SelectMetaInputModule() {
+        super();
+        this.defaultInput = null; // not needed
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+
+        Configuration[] expr = config.getChildren("input-module");
+        if (expr == null || expr.length != 1) {
+            throw new ConfigurationException("Need to have exactly one input-module element.");
+        }
+        this.parameter = config.getChild("parameter").getValue();
+        Configuration[] whens = config.getChildren("when");
+        Configuration[] others = config.getChildren("otherwise");
+        if ((whens == null && others == null)
+            || ((whens == null || whens.length == 0) && (others == null || others.length == 0))) {
+            throw new ConfigurationException("Need to have at least one when or otherwise element.");
+        }
+        if (others != null && others.length > 1) {
+            throw new ConfigurationException("Need to have at most one otherwise element.");
+        }
+        this.whenTest = new TreeMap();
+        for (int i = 0; i < expr.length; i++) {
+            String name = expr[i].getAttribute("name");
+            this.expression = new ModuleHolder(name, expr[i], null);
+        }
+
+        if (others != null) {
+            for (int i = 0; i < others.length; i++) {
+                String name = others[i].getAttribute("name");
+                this.otherwise = new ModuleHolder(name, others[i], null);
+            }
+        }
+
+        if (whens != null) {
+            for (int i = 0; i < whens.length; i++) {
+                String name = whens[i].getAttribute("name");
+                this.whenTest.put(
+                    whens[i].getAttribute("test"),
+                    new ModuleHolder(name, whens[i], null));
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.InputModule#getAttribute(String, Configuration, Map)
+     */
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        Object result = this.getAttribute(name, modeConf, objectModel, false);
+        return result;
+    }
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        Object result = this.getAttribute(name, modeConf, objectModel, true);
+        return (result != null ? (Object[]) result : null );
+    }
+
+    private Object getAttribute(String name, Configuration modeConf, Map objectModel, boolean getValues)
+    throws ConfigurationException {
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        ModuleHolder expression = this.expression;
+        ModuleHolder otherwise = this.otherwise;
+        ModuleHolder module = null;
+        String parameter = this.parameter;
+        boolean needRelease = false;
+        boolean dynamicConfig = (modeConf != null && modeConf.getChildren().length > 0);
+
+        if (dynamicConfig) {
+            // clear all configured values so that they
+            // don't get mixed up
+            expression = null;
+            otherwise = null;
+            needRelease = true;
+
+            Configuration[] expr = modeConf.getChildren("input-module");
+            Configuration[] other = modeConf.getChildren("otherwise");
+            if (expr != null && expr.length == 1) {
+                expression = new ModuleHolder(expr[0].getAttribute("name"), expr[0]);
+            }
+            if (other != null && other.length == 1) {
+                otherwise = new ModuleHolder(other[0].getAttribute("name"), other[0]);
+            }
+            parameter = modeConf.getChild("parameter").getValue();
+        }
+
+        String value =
+            (String) this.getValue(parameter, objectModel, expression.input, expression.name, expression.config);
+        if (needRelease) {
+            this.releaseModule(expression.input);
+        }
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug(
+                (dynamicConfig ? "(dyn)" : "(static)")
+                    + " select ("
+                    + value
+                    + ") from "
+                    + expression.name
+                    + ":"
+                    + parameter);
+        }
+
+        if (dynamicConfig && value != null) {
+            Configuration[] whens = modeConf.getChildren("when");
+            if (whens != null && whens.length > 0) {
+                int i = 0;
+                boolean found = false;
+                while (!found && i < whens.length) {
+                    if (whens[i].getAttribute("test").equals(value)) {
+                        found = true;
+                        break;
+                    }
+                    i++;
+                }
+                if (found) {
+                    module = new ModuleHolder(whens[i].getAttribute("name"), whens[i]);
+                }
+            }
+        } else if (value != null) {
+            module = (ModuleHolder) this.whenTest.get(value);
+        }
+        if (module != null) {
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("found matching when : "+module.name);
+            }
+        } else {
+            module = otherwise;
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("using otherwise : "+module.name);
+            }
+        }
+
+        Object result;
+        if (getValues){
+            result = (module == null ? null : this.getValues(name, objectModel, module));
+        } else {
+            result = (module == null ? null : this.getValue(name, objectModel, module));
+        }
+
+        if (needRelease && module != null) {
+            this.releaseModule(module.input);
+        }
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Obtained value : "+result);
+        }
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.releaseModule(this.expression.input);
+        this.expression = null;
+
+        if (this.otherwise != null) {
+            this.releaseModule(this.otherwise.input);
+            this.otherwise = null;
+        }
+
+        for (Iterator i = this.whenTest.values().iterator(); i.hasNext();) {
+            ModuleHolder holder = (ModuleHolder) i.next();
+            this.releaseModule(holder.input);
+        }
+        this.whenTest = null;
+
+        super.dispose();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.modules.input.AbstractMetaModule#lazy_initialize()
+     */
+    public synchronized void lazy_initialize() {
+        if (this.initialized) {
+            return;
+        }
+
+        super.lazy_initialize();
+
+        if (this.expression != null) {
+            this.expression.input = this.obtainModule(this.expression.name);
+        }
+        if (this.otherwise != null){
+            this.otherwise.input = this.obtainModule(this.otherwise.name);
+        }
+        if (this.whenTest != null){
+            for (Iterator i = this.whenTest.values().iterator(); i.hasNext(); ){
+                ModuleHolder moduleHolder = (ModuleHolder) i.next();
+                moduleHolder.input = this.obtainModule(moduleHolder.name);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionAttributeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionAttributeModule.java
new file mode 100644
index 0000000..463ee3c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionAttributeModule.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * SessionAttributeModule accesses session attributes. If the
+ * attribute name contains an askerisk "*" this is considered a
+ * wildcard and all attributes that would match this wildcard are
+ * considered to be part of an array of that name for
+ * getAttributeValues. Only one "*" is allowed.
+ *
+ * @version $Id$
+ */
+public class SessionAttributeModule extends AbstractInputModule implements ThreadSafe {
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        String pname = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            pname = modeConf.getAttribute( "parameter", pname );
+            // preferred
+            pname = modeConf.getChild("parameter").getValue(pname);
+        }
+        return ObjectModelHelper.getRequest(objectModel).getSession().getAttribute( pname );
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        return new IteratorHelper(ObjectModelHelper.getRequest(objectModel).getSession().getAttributeNames());
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        String wildcard = (String) this.settings.get("parameter", name);
+        if ( modeConf != null ) {
+            wildcard = modeConf.getAttribute( "parameter", wildcard );
+            // preferred
+            wildcard = modeConf.getChild("parameter").getValue(wildcard);
+        }
+        int wildcardIndex = wildcard.indexOf( "*" );
+        if ( wildcardIndex != -1 ) {
+            // "*" contained in attribute name => combine all
+            // attributes' values that match prefix, suffix
+
+            // split the attribute's name so that the "*" could be
+            // determined by looking at the attributes' names that
+            // start with the prefix and end with the suffix
+            //
+            String prefix = wildcard.substring( 0, wildcardIndex );
+            String suffix;
+            if ( wildcard.length() >= wildcardIndex + 1 ) {
+                suffix = wildcard.substring( wildcardIndex + 1 );
+            } else {
+                suffix = "";
+            }
+            SortedSet names = new TreeSet();
+            Session session = request.getSession();
+            Enumeration allNames = session.getAttributeNames();
+
+            while (allNames.hasMoreElements()) {
+                String pname = (String) allNames.nextElement();
+                if ( pname.startsWith( prefix ) && pname.endsWith( suffix ) ) {
+                    names.add(pname);
+                }
+            }
+
+            List values = new LinkedList();
+            Iterator j = names.iterator();
+            while (j.hasNext()){
+                String pname = (String) j.next();
+                values.add( session.getAttribute(pname) );
+            }
+
+            return values.toArray();
+
+        } else {
+            // no "*" in attribute name => just return all values of
+            // this one attribute. Make sure, it's an array.
+
+            Object value = request.getSession().getAttribute( wildcard );
+            if ( value != null && !value.getClass().isArray() ) {
+                Object[] values = new Object[1];
+                values[0] = value;
+                return values;
+            } else {
+                return (Object[]) value;
+            }
+
+        }
+
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionModule.java
new file mode 100644
index 0000000..567e705
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SessionModule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * SessionModule provides access to Session object properties.
+ * To get access to session properties use XPath syntax, e.g. to get the session
+ * id use <code>'id'</code> as the attribute name.<br/>
+ * More complex expressions with functions are also supported, e.g.:
+ * <pre>
+ * 'substring(id, 8)'
+ * </pre>
+ * will return the substring of id property of the session object.
+ * <strong>NOTE:</strong> The module does not create a new session.
+ *
+ * @version $Id$
+ */
+public class SessionModule extends AbstractJXPathModule
+    implements ThreadSafe {
+
+    protected Object getContextObject(Configuration modeConf,
+                                      Map objectModel) {
+
+        return ObjectModelHelper.getRequest(objectModel).getSession(false);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SimpleMappingMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SimpleMappingMetaModule.java
new file mode 100644
index 0000000..be6c0c2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SimpleMappingMetaModule.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/** Meta module that obtains values from an other module and by
+ * replacing the requested attribute name with another name. This is
+ * done first through a replacement table and may additionally prepend
+ * or append a string. Replacement works in both ways, it is applied
+ * to the returned attribute names as well.
+ *
+ * <p>Example configuration:<pre>
+ * &lt;prefix&gt;cocoon.&lt;/prefix&gt;
+ * &lt;suffix&gt;.attr&lt;/suffix&gt;
+ * &lt;mapping in="foo" out="bar"/&gt;
+ * &lt;mapping in="yuk" out="yeeha"/&gt;
+ *</pre>
+ *
+ * Will map a parameter "foo" to the real one named
+ * "cocoon.bar.attr". If parameters "coocoon.yeeha.attr" and
+ * "shopping.cart" exist, the iterator will return
+ * "yeeha". "shopping.cart" does not contain the pre-/ suffix and thus
+ * is dropped.</p> 
+ *
+ * <p>Similarily, rm-prefix and rm-suffix will be removed from the
+ * attribute name.</p>
+ *
+ * @version $Id$
+ */
+public class SimpleMappingMetaModule extends AbstractMetaModule implements ThreadSafe {
+
+    String prefix = null;
+    String suffix = null;
+    String rmPrefix = null;
+    String rmSuffix = null;
+    Mapping mapping = null;
+
+    protected class Mapping {
+        Map toMap = null;
+        Map fromMap = null;
+
+        public Mapping() {
+        }       
+
+        public Mapping(Map to, Map from) {
+            this.toMap = to;
+            this.fromMap = from;
+        }
+
+        public Mapping(Configuration config) throws ConfigurationException {
+            Configuration[] mappings = config.getChildren("mapping");
+            if (mappings!=null) {
+                if (this.toMap == null) this.toMap = new HashMap();
+                if (this.fromMap == null) this.fromMap = new HashMap();
+                for (int i=0; i < mappings.length; i++){
+                    String in = mappings[i].getAttribute("in",null);
+                    String out = mappings[i].getAttribute("out",null);
+                    if (in != null && out != null) {
+                        this.toMap.put(in,out);
+                        this.fromMap.put(out,in);
+                    }
+                }
+            }
+        }
+
+        private String mapIt(Map map, String param) {
+            Object newParam = param;
+            if (map != null) {
+                newParam = map.get(param);
+                if (!map.containsKey(param) || newParam == null)
+                    newParam = param;
+            }
+            return (String) newParam;
+        }
+
+        public String mapFrom(String param) {
+            return this.mapIt(this.fromMap, param);
+        }
+
+        public String mapTo(String param) {
+            return this.mapIt(this.toMap, param);
+        }
+    }
+
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        // It seems that even if there is no config, we'll get an empty
+        // input-module element here, so it will never be null (JT)
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name", this.defaultInput);
+        this.prefix = config.getChild("prefix").getValue(null);
+        this.suffix = config.getChild("suffix").getValue(null);
+        this.rmPrefix = config.getChild("rm-prefix").getValue(null);
+        this.rmSuffix = config.getChild("rm-suffix").getValue(null);
+        this.mapping = new Mapping(config);
+    }
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        Configuration inputConfig = null;
+        String inputName=null;
+        Mapping mapping = this.mapping;
+        String prefix = this.prefix;
+        String suffix = this.suffix;
+        String rmPrefix = this.rmPrefix;
+        String rmSuffix = this.rmSuffix;
+
+        if (modeConf!=null && modeConf.getChildren().length > 0) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+            mapping = new Mapping(modeConf);
+            prefix = modeConf.getChild("prefix").getValue(null);
+            suffix = modeConf.getChild("suffix").getValue(null);
+            rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
+            rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
+        }
+        
+        // remove rm-prefix and rm-suffix
+        if (rmPrefix != null && name.startsWith(rmPrefix)) {
+            name = name.substring(rmPrefix.length());
+        }
+        if (rmSuffix != null && name.endsWith(rmSuffix)) {
+            name = name.substring(0,name.length() - rmSuffix.length());
+        }
+        // map
+        String param = mapping.mapTo(name);
+        // add prefix and suffix
+        if (prefix != null) param = prefix + param;
+        if (suffix != null) param = param + suffix;
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("mapping ['"+name+"'] to ['"+param+"']");
+
+        Object res = getValue(param, objectModel,
+                              this.input, this.defaultInput, this.inputConf,
+                              null, inputName, inputConfig);
+        
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("getting for real attribute ['"+param+"'] value: "+res);
+
+        return res;
+    }
+
+
+
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        Configuration inputConfig = null;
+        String inputName=null;
+        Mapping mapping = this.mapping;
+        String prefix = this.prefix;
+        String suffix = this.suffix;
+        String rmPrefix = this.rmPrefix;
+        String rmSuffix = this.rmSuffix;
+
+        if (modeConf!=null && modeConf.getChildren().length > 0) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+            mapping = new Mapping(modeConf);
+            prefix = modeConf.getChild("prefix").getValue(null);
+            suffix = modeConf.getChild("suffix").getValue(null);
+            rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
+            rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
+        }
+        
+        // remove rm-prefix and rm-suffix
+        if (rmPrefix != null && name.startsWith(rmPrefix)) {
+            name = name.substring(rmPrefix.length());
+        }
+        if (rmSuffix != null && name.endsWith(rmSuffix)) {
+            name = name.substring(0,name.length() - rmSuffix.length());
+        }
+        // map
+        String param = mapping.mapTo(name);
+        // add prefix and suffix
+        if (prefix != null) param = prefix + param;
+        if (suffix != null) param = param + suffix;
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("mapping ['"+name+"'] to ['"+param+"']");
+
+        Object[] res = getValues(param, objectModel,
+                                 this.input, this.defaultInput, this.inputConf,
+                                 null, inputName, inputConfig);
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("getting for real attribute ['"+param+"'] value: "+res);
+
+        return res;
+    }
+
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        Configuration inputConfig = null;
+        String inputName=null;
+        Mapping mapping = this.mapping;
+        String prefix = this.prefix;
+        String suffix = this.suffix;
+        String rmPrefix = this.rmPrefix;
+        String rmSuffix = this.rmSuffix;
+        if (modeConf!=null && modeConf.getChildren().length > 0) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+            mapping = new Mapping(modeConf);
+            prefix = modeConf.getChild("prefix").getValue(null);
+            suffix = modeConf.getChild("suffix").getValue(null);
+            rmPrefix = modeConf.getChild("rm-prefix").getValue(null);
+            rmSuffix = modeConf.getChild("rm-suffix").getValue(null);
+        }
+        
+        Iterator names = getNames(objectModel, 
+                                  this.input, this.defaultInput, this.inputConf, 
+                                  null, inputName, inputConfig);
+
+        Set set = new HashSet();
+        while (names.hasNext()) {
+            String param = (String) names.next();
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("reverse mapping starts with ['"+param+"']");
+            if (prefix != null) 
+                if (param.startsWith(prefix))
+                    param = param.substring(prefix.length());
+                else 
+                    continue; // prefix is set but parameter does not start with it.
+            
+            //if (getLogger().isDebugEnabled())
+            //    getLogger().debug("reverse mapping after remove prefix ['"+param+"']");
+
+            if (suffix != null)
+                if (param.endsWith(suffix))
+                    param = param.substring(0,param.length() - suffix.length());
+                else 
+                    continue; // suffix is set but parameter does not end with it.
+
+            //if (getLogger().isDebugEnabled())
+            //    getLogger().debug("reverse mapping after remove suffix ['"+param+"']");
+
+            if (param.length() < 1)
+                continue; // nothing left
+
+            String newName = mapping.mapFrom(param);
+
+            if (rmPrefix != null) newName = rmPrefix + newName;
+            if (rmSuffix != null) newName = newName + rmSuffix;
+
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("reverse mapping results in ['"+newName+"']");
+
+            set.add(newName);
+        }
+
+        return set.iterator();
+
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SitemapVariableHolder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SitemapVariableHolder.java
new file mode 100644
index 0000000..8bec79c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SitemapVariableHolder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ChainedConfiguration;
+import org.apache.cocoon.components.SitemapConfigurable;
+import org.apache.cocoon.components.SitemapConfigurationHolder;
+
+/**
+ * This "component" is a trick to get global variables on a per
+ * sitemap base
+ *
+ * @version $Id$
+ */
+public final class SitemapVariableHolder
+    extends AbstractLogEnabled
+    implements Configurable, SitemapConfigurable, ThreadSafe {
+
+    public static final String ROLE = SitemapVariableHolder.class.getName();
+
+    /**
+     * Stores (global) configuration parameters as <code>key</code> /
+     * <code>value</code> pairs from the component configuration
+     */
+    private Map globalValues;
+
+    /** Manager for sitemap/sub sitemap configuration */
+    private SitemapConfigurationHolder holder;
+
+    /**
+     * Configures the database access helper.
+     *
+     * Takes all elements nested in component declaration and stores
+     * them as key-value pairs in <code>settings</code>. Nested
+     * configuration option are not catered for. This way global
+     * configuration options can be used.
+     *
+     * For nested configurations override this function.
+     * */
+    public void configure(Configuration conf)
+    throws ConfigurationException {
+        final Configuration[] parameters = conf.getChildren();
+        this.globalValues = new HashMap(parameters.length);
+        for (int i = 0; i < parameters.length; i++) {
+            final String key = parameters[i].getName();
+            final String value = parameters[i].getValue();
+            this.globalValues.put(key, value);
+        }
+    }
+
+    /**
+     * Set the <code>Configuration</code> from a sitemap
+     */
+    public void configure(SitemapConfigurationHolder holder) {
+        this.holder = holder;
+    }
+
+    /**
+     * Get a value
+     */
+    public Object get(String key) {
+        return this.getValues().get(key);
+    }
+
+    /**
+     * Get keys
+     */
+    public Iterator getKeys() {
+        return this.getValues().keySet().iterator();
+    }
+
+    protected Map getValues() {
+        Map values = (Map)this.holder.getPreparedConfiguration();
+        if (null == values) {
+            values = new HashMap(this.globalValues);
+            ChainedConfiguration conf = this.holder.getConfiguration();
+            if (conf != null) {
+                this.prepare(conf, values);
+                this.holder.setPreparedConfiguration(conf, values);
+            }
+        }
+        return values;
+    }
+
+    protected void prepare(ChainedConfiguration conf, Map values) {
+        ChainedConfiguration parent = conf.getParent();
+        if (null != parent) {
+            this.prepare(parent, values);
+        }
+        final Configuration[] parameters = conf.getChildren();
+        final int len = parameters.length;
+        for (int i = 0; i < len; i++) {
+            final String key = parameters[i].getName();
+            final String value = parameters[i].getValue("");
+            if (key != null && value != null) {
+                values.put(key, value);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/StringConstantModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/StringConstantModule.java
new file mode 100644
index 0000000..b985349
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/StringConstantModule.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * StringConstantModule returns a constant string.
+ * Constant must be the only content of the configuration object.
+ *
+ * @version $Id$
+ */
+public class StringConstantModule extends AbstractInputModule implements ThreadSafe {
+
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("stringConstant");
+        returnNames = tmp;
+    }
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) throws ConfigurationException {
+        
+        if (modeConf == null) {
+            return null;
+        } else {
+            return modeConf.getValue();
+        }
+    }
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) throws ConfigurationException {
+
+        return StringConstantModule.returnNames.iterator();
+    }
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel )
+        throws ConfigurationException {
+
+            List values = new LinkedList();
+            values.add( this.getAttribute(name, modeConf, objectModel) );
+
+            return values.toArray();
+            
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SystemPropertyModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SystemPropertyModule.java
new file mode 100644
index 0000000..48887d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/SystemPropertyModule.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Map;
+
+/**
+ * SystemPropertyModule is an JXPath based InputModule implementation that
+ * provides access to system properties.
+ * Available system properties are defined by Java's <a
+ * href="http://java.sun.com/j2se/1.4.1/docs/api/java/lang/System.html#getProperties()">System.getProperties()</a>.
+ *
+ * JXPath allows to apply XPath functions to system properties.
+ *
+ * <p>If there is a security manager, its <code>checkPropertiesAccess</code>
+ * method is called with no arguments. This may result in a security exception
+ * which is wrapped into a configuration exception and re-thrown.</p>
+ *
+ * @version $Id$
+ */
+public class SystemPropertyModule extends AbstractJXPathModule
+                                  implements ThreadSafe {
+
+    /**
+     * @throws SecurityException if access is denied
+     */
+    protected Object getContextObject(Configuration modeConf,
+                                      Map objectModel) {
+        return System.getProperties();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLDecodeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLDecodeModule.java
new file mode 100644
index 0000000..eb7c063
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLDecodeModule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.util.NetUtils;
+
+/**
+ * This module provides functionality for converting a String from the
+ * application/x-www-form-urlencoded MIME format. It is useful for example for
+ * calling remote services: <br/>
+ * &lt;map:generate src="http://remote/page?param1={url-encode:{request-param:param1}}"/&gt;<br/>
+ * Module configuration takes only one configuration parameter:
+ * "encoding" which is a target string encoding. This is utf-8 by default.
+ */
+public final class URLDecodeModule extends AbstractInputModule
+                                   implements ThreadSafe {
+
+    public Object getAttribute(String name,
+                               Configuration modeConf,
+                               Map objectModel) throws ConfigurationException {
+        if (name == null) {
+            return null;
+        }
+
+        String encoding = (String) this.settings.get("encoding", "utf-8");
+        try {
+            return NetUtils.decode(name, encoding);
+        } catch (UnsupportedEncodingException e) {
+            throw new ConfigurationException("URLDecodeModule, invalid encoding: " + encoding);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLEncodeModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLEncodeModule.java
new file mode 100644
index 0000000..b98122b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/URLEncodeModule.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.util.NetUtils;
+
+/**
+ * This module provides functionality for converting a String to the
+ * application/x-www-form-urlencoded MIME format. It is useful for example for
+ * calling remote services: <br/>
+ * &lt;map:generate src="http://remote/page?param1={url-encode:{request-param:param1}}"/&gt;<br/>
+ * Module configuration takes only one configuration parameter:
+ * "encoding" which is a target string encoding. This is utf-8 by default.
+ */
+public final class URLEncodeModule extends AbstractInputModule
+                                   implements ThreadSafe {
+
+    public Object getAttribute(String name,
+                               Configuration modeConf,
+                               Map objectModel) throws ConfigurationException {
+        if (name == null) {
+            return null;
+        }
+
+        String encoding = (String) this.settings.get("encoding", "utf-8");
+        try {
+            return NetUtils.encode(name, encoding);
+        } catch (UnsupportedEncodingException e) {
+            throw new ConfigurationException("URLEncodeModule, invalid encoding: " + encoding);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLFileModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLFileModule.java
new file mode 100644
index 0000000..f8fdf2e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLFileModule.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.input;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.w3c.dom.Document;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+
+ <grammar>
+    <define name="input.module.config.contents" combine="choice">
+       <optional><element name="reloadable"><data type="boolean"/></element></optional>
+       <optional><element name="cacheable"><data type="boolean"/></element></optional>
+       <optional>
+          <ref name="org.apache.cocoon.components.modules.input.XMLFileModule:file">
+       </optional>
+    </define>
+
+    <define name="input.module.runtime.contents" combine="choice">
+       <optional>
+          <ref name="org.apache.cocoon.components.modules.input.XMLFileModule:file">
+       </optional>
+    </define>
+
+    <define name="org.apache.cocoon.components.modules.input.XMLFileModule:file">
+       <element name="file">
+          <attribute name="src"><data type="anyURI"/></attribute>
+          <optional><attribute name="reloadable"><data type="boolean"/></attribute></optional>
+          <optional><attribute name="cacheable"><data type="boolean"/></attribute></optional>
+       </element>
+    </define>
+ </grammar>
+
+ * This module provides an Input Module interface to any XML document, by using
+ * XPath expressions as attribute keys.
+ * The XML can be obtained from any Cocoon <code>Source</code> (e.g.,
+ * <code>cocoon:/...</code>, <code>context://..</code>, and regular URLs).
+ * Sources can be held in memory for better performance and reloaded if
+ * changed.
+ *
+ * <p>Caching and reloading can be turned on / off (default: caching on,
+ * reloading off) through <code>&lt;reloadable&gt;false&lt;/reloadable&gt;</code>
+ * and <code>&lt;cacheable&gt;false&lt;/cacheable&gt;</code>. The file
+ * (source) to use is specified through <code>&lt;file
+ * src="protocol:path/to/file.xml" reloadable="true"
+ * cacheable="true"/&gt;</code> optionally overriding defaults for
+ * caching and/or reloading.</p>
+ *
+ * <p>In addition, xpath expressions are cached for higher performance.
+ * Thus, if an expression has been evaluated for a file, the result
+ * is cached and will be reused, the expression is not evaluated
+ * a second time. This can be turned off using the <code>cache-expressions</code>
+ * configuration option.</p>
+ *
+ * @version $Id$
+ */
+public class XMLFileModule extends AbstractJXPathModule
+                           implements Serviceable, ThreadSafe {
+
+    /** Static (cocoon.xconf) configuration location, for error reporting */
+    String staticConfLocation;
+
+    /** Cached documents */
+    Map documents;
+
+    /** Default value for reloadability of sources. Defaults to false. */
+    boolean reloadAll;
+
+    /** Default value for cacheability of sources. Defaults to true. */
+    boolean cacheAll;
+
+    /** Default value for cacheability of xpath expressions. Defaults to true. */
+    boolean cacheExpressions;
+
+    /** Default src */
+    String src;
+
+    SourceResolver resolver;
+    ServiceManager manager;
+
+    //
+    // need two caches for Object and Object[]
+    //
+
+    /** XPath expression cache for single attribute values. */
+    private Map expressionCache;
+
+    /** XPath expression cache for multiple attribute values. */
+    private Map expressionValuesCache;
+
+
+    /**
+     * Takes care of (re-)loading and caching of sources.
+     */
+    protected class DocumentHelper {
+        private boolean reloadable;
+        private boolean cacheable;
+
+        /** Source location */
+        private String uri;
+
+        /** Source validity */
+        private SourceValidity validity;
+
+        /** Source content cached as DOM Document */
+        private Document document;
+
+        /** Remember who created us (and who's caching us) */
+        private XMLFileModule instance;
+
+        /**
+         * Creates a new <code>DocumentHelper</code> instance.
+         *
+         * @param reload a <code>boolean</code> value, whether this source should be reloaded if changed.
+         * @param cache a <code>boolean</code> value, whether this source should be kept in memory.
+         * @param src a <code>String</code> value containing the URI
+         */
+        public DocumentHelper(boolean reload, boolean cache, String src, XMLFileModule instance) {
+            this.reloadable = reload;
+            this.cacheable = cache;
+            this.uri = src;
+            this.instance = instance;
+            // defer loading of the document
+        }
+
+        /**
+         * Returns the Document belonging to the configured
+         * source. Transparently handles reloading and caching.
+         *
+         * @param manager a <code>ServiceManager</code> value
+         * @param resolver a <code>SourceResolver</code> value
+         * @return a <code>Document</code> value
+         * @exception Exception if an error occurs
+         */
+        public synchronized Document getDocument(ServiceManager manager, SourceResolver resolver, Logger logger)
+        throws Exception {
+            Source src = null;
+            Document dom = null;
+            try {
+                if (this.document == null) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Document not cached... Loading uri " + this.uri);
+                    }
+                    src = resolver.resolveURI(this.uri);
+                    this.validity = src.getValidity();
+                    this.document = SourceUtil.toDOM(src);
+                } else if (this.reloadable) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Document cached... checking validity of uri " + this.uri);
+                    }
+
+                    int valid = this.validity == null? SourceValidity.INVALID: this.validity.isValid();
+                    if (valid != SourceValidity.VALID) {
+                        // Get new source and validity
+                        src = resolver.resolveURI(this.uri);
+                        SourceValidity newValidity = src.getValidity();
+                        // If already invalid, or invalid after validities comparison, reload
+                        if (valid == SourceValidity.INVALID || this.validity.isValid(newValidity) != SourceValidity.VALID) {
+                            if (logger.isDebugEnabled()) {
+                                logger.debug("Reloading document... uri " + this.uri);
+                            }
+                            this.validity = newValidity;
+                            this.document = SourceUtil.toDOM(src);
+
+                            /*
+                             * Clear the cache, otherwise reloads won't do much.
+                             *
+                             * FIXME (pf): caches should be held in the DocumentHelper
+                             *             instance itself, clearing global cache will
+                             *             clear everything for each configured document.
+                             *             (this is a quick fix, no time to do the whole)
+                             */
+                            this.instance.flushCache();
+                        }
+                    }
+                }
+
+                dom = this.document;
+            } finally {
+                if (src != null) {
+                    resolver.release(src);
+                }
+
+                if (!this.cacheable) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Not caching document cached... uri " + this.uri);
+                    }
+                    this.validity = null;
+                    this.document = null;
+                }
+            }
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("Done with document... uri " + this.uri);
+            }
+            return dom;
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+    }
+
+    /**
+     * Static (cocoon.xconf) configuration.
+     * Configuration is expected to be of the form:
+     * &lt;...&gt;
+     *   &lt;reloadable&gt;true|<b>false</b>&lt;/reloadable&gt;
+     *   &lt;cacheable&gt;<b>true</b>|false&lt;/cacheable&gt;
+     *   &lt;file src="<i>src1</i>" reloadable="true|<b>false</b>" cacheable="<b>true</b>|false"/&gt;
+     *   &lt;file src="<i>src2</i>" reloadable="true|<b>false</b>" cacheable="<b>true</b>|false"/&gt;
+     *   ...
+     * &lt;/...&gt;
+     *
+     * Each &lt;file/&gt; element pre-loads an XML DOM for querying. Typically only one
+     * &lt;file&gt; is specified, and its <i>src</i> is used as a default if not
+     * overridden in the {@link #getContextObject(Configuration, Map)}
+     *
+     * @param config a <code>Configuration</code> value, as described above.
+     * @exception ConfigurationException if an error occurs
+     */
+    public void configure(Configuration config)
+    throws ConfigurationException {
+        super.configure(config);
+        this.staticConfLocation = config.getLocation();
+        this.reloadAll = config.getChild("reloadable").getValueAsBoolean(false);
+
+        if (config.getChild("cachable", false) != null) {
+            throw new ConfigurationException("Bzzt! Wrong spelling at " +
+                                             config.getChild("cachable").getLocation() +
+                                             ": please use 'cacheable', not 'cachable'");
+        }
+        this.cacheAll = config.getChild("cacheable").getValueAsBoolean(true);
+
+        this.documents = Collections.synchronizedMap(new HashMap());
+        Configuration[] files = config.getChildren("file");
+        for (int i = 0; i < files.length; i++) {
+            boolean reload = files[i].getAttributeAsBoolean("reloadable", this.reloadAll);
+            boolean cache = files[i].getAttributeAsBoolean("cacheable", this.cacheAll);
+            this.src = files[i].getAttribute("src");
+            // by assigning the source uri to this.src the last one will be the default
+            // OTOH caching / reload parameters can be specified in one central place
+            // if multiple file tags are used.
+            this.documents.put(files[i], new DocumentHelper(reload, cache, this.src, this));
+        }
+
+        // init caches
+        this.cacheExpressions = config.getChild("cache-expressions").getValueAsBoolean(true);
+        if (this.cacheExpressions) {
+            this.expressionCache = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT);
+            this.expressionValuesCache = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT);
+        }
+    }
+
+    /**
+     * Dispose this component
+     */
+    public void dispose() {
+        super.dispose();
+        if (this.manager != null) {
+            this.manager.release(this.resolver);
+            this.resolver = null;
+            this.manager = null;
+        }
+
+        this.documents = null;
+        this.expressionCache = null;
+        this.expressionValuesCache = null;
+    }
+
+
+    /**
+     * Retrieve document helper
+     */
+    private DocumentHelper getDocumentHelper(Configuration modeConf)
+    throws ConfigurationException {
+        boolean hasDynamicConf = false; // whether we have a <file src="..."> dynamic configuration
+        Configuration fileConf = null;  // the nested <file>, if any
+
+        if (modeConf != null && modeConf.getChildren().length > 0) {
+            fileConf = modeConf.getChild("file", false);
+            if (fileConf == null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Missing 'file' child element at " + modeConf.getLocation());
+                }
+            } else {
+                hasDynamicConf = true;
+            }
+        }
+
+        String src = this.src;
+        if (hasDynamicConf) {
+            src = fileConf.getAttribute("src");
+        }
+
+        if (src == null) {
+            throw new ConfigurationException(
+                "No source specified"
+                    + (modeConf != null ? ", either dynamically in " + modeConf.getLocation() + ", or " : "")
+                    + " statically in "
+                    + staticConfLocation);
+        }
+
+        if (!this.documents.containsKey(src)) {
+            boolean reload = this.reloadAll;
+            boolean cache = this.cacheAll;
+            if (hasDynamicConf) {
+                reload = fileConf.getAttributeAsBoolean("reloadable", reload);
+                cache = fileConf.getAttributeAsBoolean("cacheable", cache);
+                if (fileConf.getAttribute("cachable", null) != null) {
+                    throw new ConfigurationException(
+                        "Bzzt! Wrong spelling at "
+                            + fileConf.getLocation()
+                            + ": please use 'cacheable', not 'cachable'");
+                }
+            }
+
+            this.documents.put(src, new DocumentHelper(reload, cache, src, this));
+        }
+
+        return (DocumentHelper) this.documents.get(src);
+    }
+
+    /**
+     * Get the DOM object that JXPath will operate on when evaluating
+     * attributes.  This DOM is loaded from a Source, specified in the
+     * modeConf, or (if modeConf is null) from the
+     * {@link #configure(Configuration)}.
+     * @param modeConf The dynamic configuration for the current operation. May
+     * be <code>null</code>, in which case static (cocoon.xconf) configuration
+     * is used.  Configuration is expected to have a &lt;file> child node, and
+     * be of the form:
+     * &lt;...&gt;
+     *   &lt;file src="..." reloadable="true|false"/&gt;
+     * &lt;/...&gt;
+     * @param objectModel Object Model for the current module operation.
+     */
+    protected Object getContextObject(Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        DocumentHelper helper = getDocumentHelper(modeConf);
+
+        try {
+            return helper.getDocument(this.manager, this.resolver, getLogger());
+        } catch (Exception e) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Error using source " + src + "\n" + e.getMessage(), e);
+            }
+            throw new ConfigurationException("Error using source " + src, e);
+        }
+    }
+
+    public Object getAttribute(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        return getAttribute(name, modeConf, objectModel, false);
+    }
+
+    public Object[] getAttributeValues(String name, Configuration modeConf, Map objectModel)
+    throws ConfigurationException {
+        Object result = getAttribute(name, modeConf, objectModel, true);
+        return (result != null ? (Object[]) result : null);
+    }
+
+    private Object getAttribute(String name, Configuration modeConf, Map objectModel, boolean getValues)
+    throws ConfigurationException {
+        Object contextObj = getContextObject(modeConf, objectModel);
+        if (modeConf != null) {
+            name = modeConf.getChild("parameter").getValue(this.parameter != null ? this.parameter : name);
+        }
+
+        Object result = null;
+        Map cache = null;
+        boolean hasBeenCached = false;
+        if (this.cacheExpressions) {
+            cache = getExpressionCache(getValues? this.expressionValuesCache: this.expressionCache, contextObj);
+            hasBeenCached = cache.containsKey(name);
+            if (hasBeenCached) {
+                result = cache.get(name);
+            }
+        }
+
+        if (!hasBeenCached) {
+            if (getValues){
+                result = JXPathHelper.getAttributeValues(name, modeConf, this.configuration, contextObj);
+            } else {
+                result = JXPathHelper.getAttribute(name, modeConf, this.configuration, contextObj);
+            }
+            if (this.cacheExpressions) {
+                cache.put(name, result);
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("for " + name + " newly caching result " + result);
+                }
+            } else {
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("for " + name + " result is " + result);
+                }
+            }
+        } else {
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("for " + name + " using cached result " + result);
+            }
+        }
+
+        return result;
+    }
+
+    protected void flushCache() {
+        if (this.cacheExpressions) {
+            synchronized(this.expressionCache) {
+                this.expressionCache.clear();
+            }
+            synchronized(this.expressionValuesCache) {
+                this.expressionValuesCache.clear();
+            }
+        }
+    }
+
+    private Map getExpressionCache(Map cache, Object key) {
+        synchronized (cache) {
+            Map map = (Map) cache.get(key);
+            if (map == null) {
+                map = Collections.synchronizedMap(new HashMap());
+                cache.put(key, map);
+            }
+            return map;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLMetaModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLMetaModule.java
new file mode 100644
index 0000000..2c5174f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/XMLMetaModule.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.input;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.xml.dom.DOMUtil;
+import org.apache.cocoon.xml.dom.DocumentWrapper;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/** 
+ * Meta module that obtains values from other module and returns all
+ * parameters as XML.
+ * 
+ * <p>Config</p>
+ * <pre>
+ *   &lt;!-- in cocoon.xconf --&gt;
+ *   &lt;ignore&gt;do-&lt;/ignore&gt;
+ *   &lt;strip&gt;user.&lt;/strip&gt;
+ *   &lt;input-module name="request-param"/&gt;
+ *
+ *   &lt;!-- e.g. in database.xml --&gt;
+ *   &lt;mode type="all" name="xmlmeta"/&gt;
+ *      &lt;ignore&gt;foo.&lt;/ignore&gt;
+ *      &lt;strip&gt;f&lt;/strip&gt;
+ *      &lt;use&gt;foo&lt;/use&gt;
+ *      &lt;root&gt;my-root&lt;/root&gt;
+ *      &lt;input-module name="request-param"/&gt;
+ *   &lt;/mode&gt;
+ * </pre>
+ *
+ * <p>If present, "ignore" gives a prefix of parameters to ignore,
+ * ignore has precedence over the "use" attribute, "strip" a prefix
+ * that will be removed from the final parameter names in the produced
+ * XML, "use" is a prefix for parameters to include in the XML, and
+ * "root" is the name of the root element in the created XML.</p>
+ *
+ * <p>Input</p>
+ * <pre>
+ *    foo.one = ['abc']
+ *    foo.two = ['def']
+ *    foo1 = ['bar']
+ *    foo2 = ['one','two','three']
+ *    bar = ['rubber duck']
+ * </pre>
+ *
+ * <p>Output</p>
+ * <pre> 
+ *   &lt;my-root&gt;
+ *     &lt;item name="oo1"&gt;bar&lt;/item&gt;
+ *     &lt;item name="oo2"&gt;
+ *        &lt;value&gt;one&lt;/value&gt;
+ *        &lt;value&gt;two&lt;/value&gt;
+ *        &lt;value&gt;three&lt;/value&gt;
+ *     &lt;/item&gt;
+ *   &lt;/my-root&gt;
+ * </pre>
+ *
+ * <p>Produces Objects of type {@link org.apache.cocoon.xml.dom.DocumentWrapper DocumentWrapper}</p>
+ *
+ * @version $Id$
+ */
+public class XMLMetaModule extends AbstractMetaModule implements ThreadSafe {
+
+    protected String rootName = "root";
+    protected String ignore;
+    protected String use;
+    protected String strip;
+    protected Object config;
+    protected XPathProcessor xpathProcessor;
+    
+    protected static final String CACHE_OBJECT_NAME = "org.apache.cocoon.component.modules.input.XMLMetaModule";
+
+    final static Vector returnNames;
+    static {
+        Vector tmp = new Vector();
+        tmp.add("XML");
+        returnNames = tmp;
+    }
+
+
+    
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name", this.defaultInput);
+        this.rootName = this.inputConf.getAttribute("root",this.rootName);
+        this.ignore = this.inputConf.getAttribute("ignore",this.ignore);
+        this.use = this.inputConf.getAttribute("use",this.use);
+        this.strip = this.inputConf.getAttribute("strip",this.strip);
+        this.config = config;
+
+        // preferred
+        this.rootName = config.getChild("root").getValue(this.rootName);
+        this.ignore = config.getChild("ignore").getValue(this.ignore);
+        this.use = config.getChild("use").getValue(this.use);
+        this.strip = config.getChild("strip").getValue(this.strip);
+    }
+
+
+
+
+    public Object getAttribute( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+
+        // obtain correct configuration objects
+        // default vs dynamic
+        Configuration inputConfig = null;
+        String inputName=null;
+        String rootName = this.rootName;
+        String ignore  = this.ignore;
+        String use  = this.use;
+        String strip  = this.strip;
+        if (modeConf!=null) {
+            inputName   = modeConf.getChild("input-module").getAttribute("name",null);
+            rootName = modeConf.getAttribute("root",this.rootName);
+            ignore  = modeConf.getAttribute("ignore" ,this.ignore );
+            use  = modeConf.getAttribute("use" ,this.use );
+            strip  = modeConf.getAttribute("strip" ,this.strip );
+
+            // preferred
+            rootName = modeConf.getChild("root").getValue(rootName);
+            ignore  = modeConf.getChild("ignore").getValue(ignore );
+            use  = modeConf.getChild("use").getValue(use );
+            strip  = modeConf.getChild("strip").getValue(strip );
+            if (inputName != null) {
+                inputConfig = modeConf.getChild("input-module");
+            }
+        }
+
+        // see whether the Document is already stored as request
+        // attribute and return that
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Map cache = (Map) request.getAttribute(CACHE_OBJECT_NAME);
+        Object key = (modeConf != null ? modeConf : this.config);
+        Document doc = null;
+
+        if (cache != null && cache.containsKey(key)) {
+            doc = (Document) cache.get(key);
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("using cached copy "+doc);
+            return doc;
+        }
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("no cached copy "+cache+" / "+key);
+
+
+        // get InputModule and all attribute names
+        InputModule input = null;
+        if (inputName != null) input = obtainModule(inputName);
+
+        Iterator names = getNames(objectModel, 
+                                  this.input, this.defaultInput, this.inputConf,
+                                  input, inputName, inputConfig);
+
+        // first, sort all attribute names that the DOM can be created in one go
+        // while doing so, remove unwanted attributes
+        SortedSet set = new TreeSet();
+        String aName = null;
+        while (names.hasNext()){
+            aName = (String) names.next();
+            if ((use == null || aName.startsWith(use)) &&
+                (ignore == null || !aName.startsWith(ignore))) {
+                set.add(aName);
+            }
+        }
+
+        try {
+            names = set.iterator();
+            
+            // create new document and append root node
+            doc = DOMUtil.createDocument();
+            Element elem = doc.createElement(rootName);
+            doc.appendChild(elem);
+
+            while (names.hasNext()){
+                aName = (String) names.next();
+                // obtain values from input module
+                Object[] value = getValues(aName, objectModel,
+                                           this.input, this.defaultInput, this.inputConf,
+                                           input, inputName, inputConfig);
+
+                // strip unwanted prefix from attribute name if present
+                if (strip != null && aName.startsWith(strip)) 
+                    aName = aName.substring(strip.length());
+
+                if (value.length > 0) {
+                    // add new node from xpath 
+                    // (since the names are in a set, the node cannot exist already)
+                    Node node = DOMUtil.selectSingleNode(doc.getDocumentElement(), aName, this.xpathProcessor);
+                    node.appendChild( node.getOwnerDocument().createTextNode(value[0].toString()));
+
+                    if (value.length > 1) {
+                        // if more than one value was obtained, append
+                        // further nodes (same name)
+
+                        // isolate node name, selection expressions
+                        // "[...]" may not be part of it
+                        int endPos = aName.length() - (aName.endsWith("/") ? 1 : 0);
+                        int startPos = aName.lastIndexOf("/", endPos) +1;
+                        String nodeName = aName.substring(startPos, endPos);
+                        if (nodeName.indexOf("[") != -1) {
+                            endPos = nodeName.lastIndexOf("]");
+                            startPos = nodeName.indexOf("[") +1;
+                            nodeName = nodeName.substring(startPos, endPos);
+                        }
+
+                        // append more nodes
+                        Node parent = node.getParentNode();
+                        for (int i = 1; i < value.length; i++) {
+                            Node newNode = parent.getOwnerDocument().createElementNS(null, nodeName);
+                            parent.appendChild( newNode );
+                            newNode.appendChild( newNode.getOwnerDocument().createTextNode(value[i].toString()));
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new ConfigurationException(e.getMessage());
+        }
+
+        if (input != null) releaseModule(input);
+
+        // create a wrapped instance that is XMLizable
+        doc = new DocumentWrapper(doc);
+
+        // store Document as request attribute
+        if (cache == null)
+            cache = new HashMap();
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("no cached copy "+cache+" / "+key);
+        cache.put(key, doc);
+        request.setAttribute(CACHE_OBJECT_NAME,cache);
+        
+        
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("returning "+doc.toString());
+        return doc;
+    }
+
+
+
+
+
+    public Iterator getAttributeNames( Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+         if (!this.initialized) {
+             this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        return XMLMetaModule.returnNames.iterator();
+   }
+
+
+
+
+    public Object[] getAttributeValues( String name, Configuration modeConf, Map objectModel ) 
+        throws ConfigurationException {
+
+        if (!this.initialized) {
+            this.lazy_initialize();
+        }
+        if (this.defaultInput == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+        
+        Object[] values = new Object[1];
+        values[0] = this.getAttribute(name, modeConf, objectModel);
+        return values;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release(this.xpathProcessor);
+            this.xpathProcessor = null;
+        }
+        super.dispose();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/package.html
new file mode 100644
index 0000000..7fb55eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/input/package.html
@@ -0,0 +1,169 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>input</title>
+             
+  <meta http-equiv="content-type"
+ content="text/html; charset=ISO-8859-1">
+</head>
+<body>
+   
+<h1>InputModules</h1>
+
+<h2>Introduction</h2>
+<p>
+Input modules are generic components that let one map a key to one or more
+values.  In concept and API, input modules are closest to the <a
+    href="http://java.sun.com/j2se/1.4/docs/api/java/util/Properties.html">java.util.Properties</a>
+class. An input module has a number of named attributes, each of which has an
+associated value or values, which will be computed or looked up when requested.
+</p>
+<pre>
+    |       InputModule          |
+    |----------------------------|
+    | PropName   | PropValue(s)  |
+    |----------------------------|
+    | prop1      | value1        |
+    | prop2      | value2        |
+    | ...        | ...           |
+    | propn      | valuen        |
+    +----------------------------+
+</pre>
+<p>Three operations are defined by the <a
+    href="InputModule.html">InputModule</a> interface:</p>
+<dl>
+    <dt>getAttributeNames</dt>
+    <dd>Retrieve a list of all available attributes (the set <i>prop1, prop2, ..., propn</i>).</dd>
+    <dt>getAttribute</dt>
+    <dd>
+    Retrieve the value of an attribute.  For instance,
+    <code>getAttribute(<i>prop1</i>)</code> would return <i>value1</i>
+    </dd>
+    <dt>GetAttributeValues</dt>
+    <dd>Retrieve an Iterator for a list of values for an attribute.</dd>
+</dl>
+
+<h2>Usage</h2>
+<p>
+Input modules are used in various places in Cocoon, notably from within the
+sitemap, XSPs, and matchers.</p>
+<p>
+In the sitemap, input modules are made available
+through a {modulename:attributename} syntax.  For instance, if a <a
+    href="RequestParameterModule.html">RequestParameterModule</a> named
+<code>request-param</code> is defined in cocoon.xconf, then
+<code>{request-param:user}</code> will in effect be replaced by the value of
+the <code>user</code> request parameter (e.g. index.html?user=joe).  Similarly,
+a <a href="SystemPropertyModule.html">SystemPropertyModule</a> named
+<code>system-property</code> would allow
+<code>{system-property:user.home}</code> to represent user's home directory
+path.
+</p>
+
+<h2>Configuration</h2>
+<p>
+Input modules are declared in cocoon.xconf.  There is a section dedicated to
+input modules:</p>
+<pre>
+  &lt;input-modules>
+    &lt;component-instance name="global"
+             class="org.apache.cocoon.components.modules.input.GlobalInputModule"
+             logger="core.modules.input"/>
+    &lt;component-instance name="request"
+             class="org.apache.cocoon.components.modules.input.RequestModule"
+             logger="core.modules.input"/>
+    &lt;component-instance name="session"
+             class="org.apache.cocoon.components.modules.input.SessionModule"
+             logger="core.modules.input"/>
+    &lt;component-instance name="request-param"
+             class="org.apache.cocoon.components.modules.input.RequestParameterModule"
+             logger="core.modules.input"/>
+    ...
+    &lt;component-instance name="defaults"
+             class="org.apache.cocoon.components.modules.input.DefaultsModule"
+             logger="core.modules.input">
+      &lt;values>
+        &lt;skin>defaultSkin&lt;/skin>
+        &lt;base-url>http://localhost:8080/cocoon&lt;/base-url>
+      &lt;/values>
+    &lt;/component-instance>
+  &lt;input-modules>
+</pre>
+<h3>Static/dynamic configuration</h3>
+<p>
+In cocoon.xconf, each input module can take a <em>static</em> configuration.
+This is made available to the class via the <code>configure()</code> method,
+called once on startup.  In the example above, an Avalon
+<code>Configuration</code> object representing the &lt;values> node will be
+passed to the DefaultsModule.
+</p>
+<p>
+In addition, every time an input module is used, a <em>dynamic</em>
+configuration is passed to it, as well as the current "object model".  You can
+see these in the <a href="InputModule.html">InputModule</a> interface
+definition for all three methods.  This dynamic, per-request configuration will
+usually <strong>override</strong> the static configuration.  This dual
+static/dynamic configuration makes input modules useful in a wide variety of
+circumstances.
+</p>
+  
+
+<h2>Meta Modules</h2>
+<p>
+So-called "meta" modules are modules that act on other modules. The simplest
+example of a meta module is the <a
+href="SimpleMappingMetaModule.html">SimpleMappingMetaModule</a>, which will
+query another module with a modified version of an attribute name.  For
+instance, if configured with:</p>
+<pre>
+&lt;component-instance name="mappingmodule"
+    class="org.apache.cocoon.components.modules.input.SimpleMappingMetaModule"
+    logger="core.modules.mapper">
+  &lt;input-module name="xmlmodule"/>
+  &lt;prefix>/site/&lt;/prefix>
+  &lt;suffix>/@href&lt;/suffix>
+&lt;/component-instance>
+</pre>
+<p>
+Then a key <code>foo</code> will cause <code>xmlmodule</code> to be queried for
+attribute <code>/site/foo/@href</code>, and that value will be returned.</p>
+<p>
+Another useful example is <a href="ChainMetaModule.html">ChainMetaModule</a>,
+which will query a set of input modules until one returns a non-null value for
+an attribute, providing "fall-back" behaviour.
+</p>
+<p>
+The machinery for meta modules is provided in <a
+href="AbstractMetaModule.html">AbstractMetaModule</a>.
+
+<h2>JXPath use in Input Modules</h2>
+<p>Many input modules make use of the <a
+href="http://jakarta.apache.org/commons/jxpath/">JXPath</a> library, which lets
+one traverse Java object structures with an XPath-like syntax.  Support for
+this is mostly located in the <a
+href="JXPathMetaModule.html">JXPathMetaModule</a> and <a
+href="AbstractJXPathModule.html">AbstractJXPathModule</a> superclasses, which
+should be kept synchronised.
+</p>
+
+<h2>Further Information</h2>
+<p>The best way to learn what can be done with input modules is by examining
+the samples that come with the Cocoon application.  The main Cocoon
+documentation and Cocoon Wiki should have further information.
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/AbstractOutputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/AbstractOutputModule.java
new file mode 100644
index 0000000..88821b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/AbstractOutputModule.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.output;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.util.HashMap;
+
+import java.util.Map;
+
+/**
+ * AbstractOutputModule gives you the infrastructure for easily
+ * deploying more output modules.
+ *
+ * <p>In order to get at the logger, use <code>getLogger()</code>.</p>
+ *
+ * @version $Id$
+ */
+public abstract class AbstractOutputModule extends AbstractLogEnabled
+    implements OutputModule, Configurable, Disposable {
+
+    /**
+     * Stores (global) configuration parameters as <code>key</code> /
+     * <code>value</code> pairs.
+     */
+    protected HashMap settings;
+
+    /**
+     * Configures the module.
+     *
+     * <p>Takes all elements nested in component declaration and stores
+     * them as key-value pairs in <code>settings</code>. Nested
+     * configuration option are not catered for. This way global
+     * configuration options can be used.</p>
+     *
+     * <p>For nested configurations override this function.</p>
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        Configuration[] parameters = conf.getChildren();
+        // Ideally here should be length * 1.333(3) but simple +1 will do for lengths up to 3
+        this.settings = new HashMap(parameters.length + 1);
+        for (int i = 0; i < parameters.length; i++) {
+            String key = parameters[i].getName();
+            String val = parameters[i].getValue("");
+            this.settings.put(key, val);
+        }
+    }
+
+    /**
+     * Dispose
+     */
+    public void dispose() {
+        // Implemeted so that we don't need to implement it in every subclass
+        this.settings = null;
+    }
+
+    /**
+     * Utility method to store parameters in a map as request attribute until
+     * either {@link #rollback(Map, String)} or {@link #prepareCommit(Map, String)}
+     * is called.
+     * @param objectModel - the objectModel
+     * @param trans_place - request attribute name used for the transient data
+     * @param name - name of the attribute to set
+     * @param value - attribute value
+     */
+    protected void transientSetAttribute(Map objectModel, String trans_place, String name, Object value) {
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+
+        Map map = (Map) request.getAttribute(trans_place);
+        if (map == null) {
+            // Need java.util.HashMap here since JXPath does not like the extended version...
+            map = new java.util.HashMap();
+        }
+
+        map.put(name, value);
+        request.setAttribute(trans_place, map);
+    }
+
+    /**
+     * Clears all uncommitted transient attributes.
+     *
+     * @param objectModel - the objectModel
+     * @param trans_place - request attribute name used for the transient data
+     */
+    protected void rollback(Map objectModel, String trans_place) {
+        ObjectModelHelper.getRequest(objectModel).removeAttribute(trans_place);
+    }
+
+    /**
+     * Returns a whether an transient attribute already exists.
+     * {@link #transientSetAttribute(Map, String, String, Object)} since the last call to
+     * {@link #rollback(Map, String)} or {@link #prepareCommit(Map, String)}
+     *
+     * @param objectModel - the objectModel
+     * @param trans_place - request attribute name used for the transient data
+     */
+    protected boolean attributeExists(Map objectModel, String trans_place, String name) {
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+
+        Map map = (Map) request.getAttribute(trans_place);
+        if (map == null) {
+            return false;
+        }
+
+        return map.containsKey(name);
+    }
+
+    /**
+     * Returns a map containing all transient attributes and remove them i.e. attributes set with
+     * {@link #transientSetAttribute(Map, String, String, Object)} since the last call to
+     * {@link #rollback(Map, String)} or {@link #prepareCommit(Map, String)}
+     *
+     * @param objectModel - the objectModel
+     * @param trans_place - request attribute name used for the transient data
+     */
+    protected Map prepareCommit(Map objectModel, String trans_place) {
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+
+        Map data = (Map) request.getAttribute(trans_place);
+        request.removeAttribute(trans_place);
+        return data;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/OutputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/OutputModule.java
new file mode 100644
index 0000000..70672ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/OutputModule.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.output;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import java.util.Map;
+
+/**
+ * Communicate results to other components. This could be done via
+ * request attributes, session attribute etc. Implementors should obey
+ * the transactional nature and e.g. queue values as request
+ * attributes and do the real communication e.g. to a bean only when
+ * the transaction completes successfully.
+ *
+ * @version $Id$
+ */
+public interface OutputModule {
+
+    String ROLE = OutputModule.class.getName();
+
+    /**
+     * communicate an attribute value to further processing logic. OutputModules
+     * work in implicit transaction mode, thus setting an attribute starts an
+     * transaction and sttributes are only visible after the transaction is
+     * successfully completed with a call to commit
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel The objectModel
+     * @param name The attribute's label, consisting of "table.column"
+     * or "table.column[index]" in case of multiple attributes of the
+     * same spec.
+     * @param value The attriute's value.
+     * */
+    void setAttribute( Configuration modeConf, Map objectModel, String name, Object value );
+
+
+    /**
+     * If a database transaction needs to rollback, this is called to
+     * inform the further processing logic about this fact. All
+     * already set attribute values are invalidated. <em>This is difficult
+     * because only the request object can be used to synchronize this
+     * and build some kind of transaction object. Beaware that sending
+     * your data straight to some beans or other entities could result
+     * in data corruption!</em>
+     * */
+    void rollback( Configuration modeConf, Map objectModel, Exception e );
+
+
+    /**
+     * Signal that the database transaction completed
+     * successfully. See notes on {@link #rollback(Configuration, Map, Exception)}.
+     * */
+    void commit( Configuration modeConf, Map objectModel );
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeMap.java
new file mode 100644
index 0000000..920a68e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeMap.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.output;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+/**
+ * Abstraction layer to encapsulate different output
+ * destinations. This module outputs to a request attribute
+ * java.util.Map object that contains all the attributes that were
+ * set. Configuration option &lt;key-prefix&gt; defaults to
+ * "org.apache.cocoon.components.modules.output.OutputModule"
+ *
+ * @version $Id$
+ */
+public class RequestAttributeMap extends AbstractOutputModule implements OutputModule, ThreadSafe {
+    
+    public final String PREFIX = "org.apache.cocoon.components.modules.output.OutputModule";
+    public final String TRANS_PREFIX = "org.apache.cocoon.components.modules.output.OutputModule.RequestAttributeMap.transient";
+    
+    /**
+     * communicate an attribute value to further processing logic.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel The objectModel
+     * @param name The attribute's label, consisting of "table.column"
+     * or "table.column[index]" in case of multiple attributes of the
+     * same spec.
+     * @param value The attriute's value.
+     * */
+    public void setAttribute( Configuration modeConf, Map objectModel, String name, Object value ) {
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("setting transient ['"+name+"'] to ['"+value+"']");
+        super.transientSetAttribute(objectModel, TRANS_PREFIX, name, value );
+    }
+    
+    
+    /**
+     * If a database transaction needs to rollback, this is called to
+     * inform the further processing logic about this fact. All
+     * already set attribute values are invalidated. <em>This is difficult
+     * because only the request object can be used to synchronize this
+     * and build some kind of transaction object. Beaware that sending
+     * your data straight to some beans or other entities could result
+     * in data corruption!</em>
+     * */
+    public void rollback( Configuration modeConf, Map objectModel, Exception e ) {
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("rolling back");
+        super.rollback(objectModel, TRANS_PREFIX);
+    }
+    
+    
+    /**
+     * Signal that the database transaction completed
+     * successfully. See notes on @link{rollback}.
+     * */
+    public void commit( Configuration modeConf, Map objectModel ) {
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("prepare commit");
+        Map aMap = super.prepareCommit(objectModel,TRANS_PREFIX);
+        if (aMap == null) {
+            // nothing to do
+            return;
+        }
+        
+        String prefix = (String) this.settings.get("key-prefix", PREFIX);
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Object temp = request.getAttribute(prefix);
+        Map old = null;
+        if (temp == null) {
+            old = aMap;
+        } else {
+            old = (Map) temp;
+            old.putAll(aMap);
+        }
+        request.setAttribute(prefix, old);
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("done commit to ['"+prefix+"']");
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeOutputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeOutputModule.java
new file mode 100644
index 0000000..bf4efa3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/RequestAttributeOutputModule.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.modules.output;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Abstraction layer to encapsulate different output
+ * destinations. Configuration option &lt;key-prefix&gt; defaults to
+ * <code>"org.apache.cocoon.components.modules.output.OutputModule" + ":"</code>
+ *
+ * <p>Can be used with different isolation-level: default is "0" being
+ * no isolation at all, values are immediately visible but are removed
+ * on a rollback; "1" keeps the values at a safe place until either
+ * rollback or commit is called. Then values are either discarded or
+ * copied to the final destination.</p>
+ *
+ * @version $Id$
+ */
+public class RequestAttributeOutputModule extends AbstractOutputModule implements OutputModule, ThreadSafe {
+
+    public static final String PREFIX = OutputModule.ROLE;
+    public static final String TRANS_PREFIX = PREFIX + ".RequestAttributeOutputModule.transient";
+    public static final String ROLLBACK_LIST = PREFIX + ".RequestAttributeOutputModule.rollback";
+
+    /**
+     * communicate an attribute value to further processing logic.
+     * @param modeConf column's mode configuration from resource
+     *                 description. This argument is optional.
+     * @param objectModel The objectModel
+     * @param name The attribute's label, consisting of "table.column"
+     *             or "table.column[index]" in case of multiple attributes
+     *             of the same spec.
+     * @param value The attriute's value.
+     */
+    public void setAttribute(Configuration modeConf, Map objectModel, String name, Object value) {
+        if (this.settings.get("isolation-level", "0").equals("1")) {
+            // Read committed isolation level
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Setting transient ['" + name + "'] to ['" + value + "']");
+            }
+            transientSetAttribute(objectModel, TRANS_PREFIX, name, value);
+        } else {
+            // Read uncommitted isolation level
+            final Request request = ObjectModelHelper.getRequest(objectModel);
+
+            name = getName(name);
+
+            if (!attributeExists(objectModel, ROLLBACK_LIST, name)) {
+                Object tmp = request.getAttribute(name);
+                transientSetAttribute(objectModel, ROLLBACK_LIST, name, tmp);
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Setting ['" + name + "'] to ['" + value + "']");
+            }
+            request.setAttribute(name, value);
+        }
+    }
+
+    /**
+     * If a database transaction needs to rollback, this is called to
+     * inform the further processing logic about this fact. All
+     * already set attribute values are invalidated.
+     *
+     * <em>This is difficult
+     * because only the request object can be used to synchronize this
+     * and build some kind of transaction object. Beware that sending
+     * your data straight to some beans or other entities could result
+     * in data corruption!</em>
+     */
+    public void rollback(Configuration modeConf, Map objectModel, Exception e) {
+        getLogger().debug("Rollback");
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+
+        if (this.settings.get("isolation-level", "0").equals("1")) {
+            rollback(objectModel, TRANS_PREFIX);
+        } else {
+            Map rollbackList = prepareCommit(objectModel, ROLLBACK_LIST);
+            if (rollbackList != null) {
+                for (Iterator i = rollbackList.entrySet().iterator(); i.hasNext();) {
+                    final Map.Entry me = (Map.Entry) i.next();
+                    String key = (String) me.getKey();
+                    Object val = me.getValue();
+                    if (val != null) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Rolling back ['" + key + "'] to ['" + val + "']");
+                        }
+                        request.setAttribute(key, val);
+                    } else {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Rolling back ['" + key + "']");
+                        }
+                        request.removeAttribute(key);
+                    }
+                }
+            }
+        }
+
+        String prefix = (String) this.settings.get("key-prefix", PREFIX);
+        if (prefix.equals("")) {
+            request.setAttribute("errorMessage", e.getMessage());
+        } else {
+            request.setAttribute(prefix + ':' + "errorMessage", e.getMessage());
+        }
+    }
+
+    /**
+     * Signal that the database transaction completed
+     * successfully. See notes on @link{rollback}.
+     */
+    public void commit(Configuration modeConf, Map objectModel) {
+        getLogger().debug("Commit");
+        if (this.settings.get("isolation-level", "0").equals("1")) {
+            Map data = prepareCommit(objectModel, TRANS_PREFIX);
+            if (data == null || data.isEmpty()) {
+                return;
+            }
+
+            String prefix = (String) this.settings.get("key-prefix", PREFIX);
+            if (prefix.length() == 0) {
+                prefix = null;
+            }
+
+            Request request = ObjectModelHelper.getRequest(objectModel);
+            for (Iterator i = data.entrySet().iterator(); i.hasNext();) {
+                final Map.Entry me = (Map.Entry) i.next();
+                String key = (String) me.getKey();
+                Object value = me.getValue();
+                if (prefix != null) {
+                    key = prefix + ':' + key;
+                }
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Committing ['" + key + "'] to ['" + value + "']");
+                }
+                request.setAttribute(key, value);
+            }
+        } else {
+            prepareCommit(objectModel, ROLLBACK_LIST);
+        }
+        
+        
+    }
+
+    protected String getName(String name) {
+        String prefix = (String) this.settings.get("key-prefix", PREFIX);
+        return prefix.equals("") ? name : prefix + ':' + name;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/SessionAttributeOutputModule.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/SessionAttributeOutputModule.java
new file mode 100644
index 0000000..ff0b092
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/SessionAttributeOutputModule.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.modules.output;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Session;
+
+/**
+ * Abstraction layer to encapsulate different output
+ * destinations. Configuration option &lt;key-prefix&gt; defaults to
+ * "org.apache.cocoon.components.modules.output.OutputModule"+":"
+ *
+ * Can be used with different isolation-level: default is "0" being
+ * no isolation at all, values are immediately visible but are removed
+ * on a rollback; "1" keeps the values at a save place until either
+ * rollback or commit is called. Then values are either discarded or
+ * copied to the final destination.
+ *
+ * @version $Id$
+ */
+public class SessionAttributeOutputModule extends AbstractOutputModule implements OutputModule, ThreadSafe {
+    
+    public final String PREFIX = "org.apache.cocoon.components.modules.output.OutputModule";
+    public final String TRANS_PREFIX = "org.apache.cocoon.components.modules.output.OutputModule.SessionAttributeOutputModule.transient";
+    public final String ROLLBACK_LIST = "org.apache.cocoon.components.modules.output.OutputModule.SessionAttributeOutputModule.rollback";
+    
+    /**
+     * communicate an attribute value to further processing logic.
+     * @param modeConf column's mode configuration from resource
+     * description. This argument is optional.
+     * @param objectModel The objectModel
+     * @param name The attribute's label, consisting of "table.column"
+     * or "table.column[index]" in case of multiple attributes of the
+     * same spec.
+     * @param value The attriute's value.
+     * */
+    public void setAttribute( Configuration modeConf, Map objectModel, String name, Object value ) {
+        if (this.settings.get("isolation-level","0").equals("1")) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("setting transient ['"+name+"'] to ['"+value+"']");
+            this.transientSetAttribute(objectModel, TRANS_PREFIX, name, value);
+        } else {
+            // use read uncommitted isolation level
+
+            Session session = ObjectModelHelper.getRequest(objectModel).getSession();
+
+            name = getName(name);
+
+            if (!this.attributeExists(objectModel, ROLLBACK_LIST, name)) {
+                Object tmp = session.getAttribute(name);
+                this.transientSetAttribute(objectModel, ROLLBACK_LIST, name, tmp);
+            }
+
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("setting ['"+name+"'] to ['"+value+"']");
+            session.setAttribute(name, value);
+        }
+
+    }
+    
+    
+    
+    /**
+     * If a database transaction needs to rollback, this is called to
+     * inform the further processing logic about this fact. All
+     * already set attribute values are invalidated. <em>This is difficult
+     * because only the request object can be used to synchronize this
+     * and build some kind of transaction object. Beaware that sending
+     * your data straight to some beans or other entities could result
+     * in data corruption!</em>
+     * */
+    public void rollback( Configuration modeConf, Map objectModel, Exception e ) {
+        if (this.settings.get("isolation-level","0").equals("1")) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("rolling back");
+            this.rollback(objectModel, TRANS_PREFIX);
+        } else {
+
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("start rolling back");
+            
+            Session session = ObjectModelHelper.getRequest(objectModel).getSession();
+            Object tmp = this.prepareCommit(objectModel,ROLLBACK_LIST);
+            if (tmp != null) {
+                Map rollbackList = (Map) tmp;
+                Iterator iter = rollbackList.keySet().iterator();
+                while(iter.hasNext()) {
+                    String key = (String) iter.next();
+                    Object val = rollbackList.get(key);
+                    if (val != null) {
+                        if (getLogger().isDebugEnabled())
+                            getLogger().debug("rolling back ['"+key+"'] to ['"+val+"']");
+                        session.setAttribute(key, val);
+                    } else {
+                        if (getLogger().isDebugEnabled())
+                            getLogger().debug("rolling back ['"+key+"']");
+                        session.removeAttribute(key);
+                    }
+                }
+            }
+        }
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("done rolling back");
+
+        String prefix = (String) this.settings.get("key-prefix", PREFIX );
+        if (!(prefix.equals(""))) {
+            ObjectModelHelper.getRequest(objectModel).getSession().setAttribute(prefix+":",e.getMessage());
+        } else {
+            ObjectModelHelper.getRequest(objectModel).getSession().setAttribute("errorMessage",e.getMessage());
+        }
+    }
+    
+    
+    /**
+     * Signal that the database transaction completed
+     * successfully. See notes on @link{rollback}.
+     * */
+    public void commit( Configuration modeConf, Map objectModel ) {
+        if (this.settings.get("isolation-level","0").equals("1")) {
+
+            Logger logger = getLogger();
+            if (logger.isDebugEnabled())
+                logger.debug("prepare commit");
+
+            Map aMap = this.prepareCommit(objectModel, TRANS_PREFIX);
+            if (aMap == null) {
+                return;
+            }
+            
+            Iterator iter = aMap.keySet().iterator();
+            if (!iter.hasNext()){
+                return;
+            }
+            
+            String prefix = (String) this.settings.get("key-prefix", PREFIX );
+            if (prefix != "") {
+                prefix = prefix+":";
+            } else {
+                prefix = null;
+            }
+            Session session = ObjectModelHelper.getRequest(objectModel).getSession();
+            while (iter.hasNext()) {
+                String key = (String) iter.next();
+                Object value = aMap.get(key);
+                if (prefix != null) { key = prefix + key; }
+                if (logger.isDebugEnabled())
+                    logger.debug("committing ['"+key+"'] to ['"+value+"']");
+                session.setAttribute(key, value);
+            }
+
+            if (logger.isDebugEnabled())
+                logger.debug("done commit");
+
+        } else {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("commit");
+            this.prepareCommit(objectModel, ROLLBACK_LIST);
+        }
+        
+    }
+    
+    protected String getName( String name ) {
+        String prefix = (String) this.settings.get("key-prefix", PREFIX );
+        return (prefix == "" ? name : prefix+":"+name);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/package.html
new file mode 100644
index 0000000..821ff2b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/output/package.html
@@ -0,0 +1,36 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>output</title>
+             
+  <meta http-equiv="content-type"
+ content="text/html; charset=ISO-8859-1">
+</head>
+<body>
+   
+<h1>output<br>
+</h1>
+   
+<p>Output modules provide a simple interface to set values largely based
+on the methods provided by request and session to set values of attributes.
+Output modules should support transactional behaviour. Transaction begin
+is implicit with the first setAttribute method call. Transactions must be
+terminated either by commit or rollback.&nbsp;</p>
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/package.html
new file mode 100644
index 0000000..1d672a0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/modules/package.html
@@ -0,0 +1,32 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>modules</title>
+             
+  <meta http-equiv="content-type"
+ content="text/html; charset=ISO-8859-1">
+</head>
+<body>
+   
+<h1>modules</h1>
+   
+<p>Modules decouple other components (i.e. sitemap components) from input, 
+output, and specific database behaviour.</p>
+  
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
new file mode 100644
index 0000000..355c8c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/DefaultNotifyingBuilder.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.notification;
+
+import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
+/**
+ *  Generates an Notifying representation of widely used objects.
+ *
+ * @version $Id$
+ */
+public class DefaultNotifyingBuilder implements NotifyingBuilder {
+
+    /**
+     * Builds a Notifying object (SimpleNotifyingBean in this case)
+     * that tries to explain what the Object o can reveal.
+     *
+     * @param sender who sent this Object.
+     * @param o the object to use when building the SimpleNotifyingBean
+     * @return the  Notifying Object that was build
+     * @see org.apache.cocoon.components.notification.Notifying
+     */
+    public Notifying build (Object sender, Object o) {
+        if (o instanceof Notifying) {
+            return (Notifying) o;
+        } else if (o instanceof Throwable) {
+            Throwable t = (Throwable) o;
+            SimpleNotifyingBean n = new SimpleNotifyingBean(sender);
+            n.setType(Notifying.ERROR_NOTIFICATION);
+            n.setTitle("An Error Occurred");
+
+            if (t != null) {
+                Throwable rootCause = getRootCause(t);
+
+                n.setSource(t.getClass().getName());
+
+                // NullPointerException usually does not have a message
+                if (rootCause.getMessage() != null) {
+                    n.setMessage(rootCause.getMessage());
+                } else {
+                    n.setMessage(t.getMessage());
+                }
+
+                n.setDescription(t.toString());
+                n.addExtraDescription(Notifying.EXTRA_CAUSE, rootCause.toString());
+
+                if (rootCause instanceof SAXParseException) {
+                    SAXParseException saxParseException = (SAXParseException) rootCause;
+
+                    n.addExtraDescription(Notifying.EXTRA_LOCATION,
+                                          String.valueOf(saxParseException.getSystemId()));
+                    n.addExtraDescription(Notifying.EXTRA_LINE,
+                                          String.valueOf(saxParseException.getLineNumber()));
+                    n.addExtraDescription(Notifying.EXTRA_COLUMN,
+                                          String.valueOf(saxParseException.getColumnNumber()));
+                } else if (rootCause instanceof TransformerException) {
+                    TransformerException transformerException = (TransformerException) rootCause;
+                    SourceLocator sourceLocator = transformerException.getLocator();
+
+                    if (null != sourceLocator) {
+                        n.addExtraDescription(Notifying.EXTRA_LOCATION,
+                                              String.valueOf(sourceLocator.getSystemId()));
+                        n.addExtraDescription(Notifying.EXTRA_LINE,
+                                              String.valueOf(sourceLocator.getLineNumber()));
+                        n.addExtraDescription(Notifying.EXTRA_COLUMN,
+                                              String.valueOf(sourceLocator.getColumnNumber()));
+                    }
+                }
+
+                // Add root cause exception stacktrace
+                StringWriter sw = new StringWriter();
+                rootCause.printStackTrace(new PrintWriter(sw));
+                n.addExtraDescription(Notifying.EXTRA_STACKTRACE, sw.toString());
+
+                // Add full exception chain
+                sw = new StringWriter();
+                appendTraceChain(sw, t);
+                n.addExtraDescription(Notifying.EXTRA_FULLTRACE, sw.toString());
+            }
+
+            return n;
+        } else {
+            SimpleNotifyingBean n = new SimpleNotifyingBean(sender);
+            n.setType(Notifying.UNKNOWN_NOTIFICATION);
+            n.setTitle("Object Notification");
+            n.setMessage(String.valueOf(o));
+            n.setDescription("No details available.");
+            return n;
+        }
+    }
+
+    /**
+     * Builds a Notifying object (SimpleNotifyingBean in this case)
+     * that explains a notification.
+     *
+     * @param sender who sent this Object.
+     * @param o the object to use when building the SimpleNotifyingBean
+     * @param type see the Notifying apidocs
+     * @param title see the Notifying apidocs
+     * @param source see the Notifying apidocs
+     * @param message see the Notifying apidocs
+     * @param description see the Notifying apidocs
+     * @param extra see the Notifying apidocs
+     * @return the  Notifying Object that was build
+     * @see org.apache.cocoon.components.notification.Notifying
+     */
+    public Notifying build(Object sender, Object o, String type, String title,
+                           String source, String message, String description, Map extra) {
+        // NKB Cast here is secure, the method is of this class
+        SimpleNotifyingBean n = (SimpleNotifyingBean) build (sender, o);
+
+        if (type != null)
+            n.setType(type);
+        if (title != null)
+            n.setTitle(title);
+        if (source != null)
+            n.setSource(source);
+        if (message != null)
+            n.setMessage(message);
+        if (description != null)
+            n.setDescription(description);
+        if (extra != null)
+            n.addExtraDescriptions(extra);
+
+        return n;
+    }
+
+
+    /**
+     * Print stacktrace of the Throwable and stacktraces of its all nested causes into a Writer.
+     */
+    private static void appendTraceChain(Writer out, Throwable t) {
+        PrintWriter pw = new PrintWriter(out);
+        if (SystemUtils.isJavaVersionAtLeast(140)) {
+            t.printStackTrace(pw);
+        } else {
+            for (Throwable cause = t; cause != null; cause = ExceptionUtils.getCause(cause)) {
+                if (cause != t) {
+                    pw.println();
+                }
+                cause.printStackTrace(pw);
+            }
+        }
+    }
+
+    /**
+     * Get root cause Throwable.
+     */
+    public static Throwable getRootCause (Throwable t) {
+        Throwable rootCause = ExceptionUtils.getRootCause(t);
+        return rootCause != null ? rootCause : t;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifier.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifier.java
new file mode 100644
index 0000000..9cc1243
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifier.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.notification;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Generates a representations of the specified Notifying Object.
+ *
+ * @version $Id$
+ */
+public class Notifier {
+
+    /**
+     * Generate notification information as a response.
+     * The notification is directly written to the OutputStream.
+     * @param  n The <code>Notifying</code> object
+     * @param outputStream The output stream the notification is written to
+     *        This could be <code>null</code>.
+     */
+    public static void notify(Notifying n, OutputStream outputStream, String mimetype) throws IOException {
+        //(NKB) FIXME should use error page templates, one per mime-type
+        // currently uses hardcoded html, should be used only as last resort.
+        notifyHTML(n, outputStream);
+    }
+
+    /**
+     * Generate notification information as html.
+     * The notification is directly written to the OutputStream.
+     * @param  n The <code>Notifying</code> object
+     * @param outputStream The output stream the notification is written to
+     *        This could be <code>null</code>.
+     */
+    private static void notifyHTML(Notifying n, OutputStream outputStream) throws IOException {
+        if (outputStream == null) {
+            return;
+        }
+
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("<html><head><title>").append(n.getTitle()).append("</title>");
+        sb.append("<style><!--");
+        sb.append("body { background-color: white; color: black; font-family: verdana, helvetica, sanf serif;}");
+        sb.append("h1 {color: #336699; margin: 0px 0px 20px 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}");
+        sb.append("p.footer { color: #336699; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }");
+        sb.append("span {color: #336699;}");
+        sb.append("pre {padding-left: 20px;}");
+        sb.append("a:link {font-weight: bold; color: #336699;}");
+        sb.append("a:visited {color: #336699; }");
+        sb.append("a:hover {color: #800000; background-color: #ffff80;}");
+        sb.append("a:active {color: #006666;}");
+        sb.append("--></style>");
+        sb.append("</head><body>");
+        sb.append("<h1>")
+          .append(StringEscapeUtils.escapeXml(n.getTitle())).append("</h1>");
+        sb.append("<p><span>Message:</span> ")
+          .append(StringEscapeUtils.escapeXml(n.getMessage())).append("</p>");
+        sb.append("<p><span>Description:</span> ")
+          .append(StringEscapeUtils.escapeXml(n.getDescription())).append("</p>");
+        sb.append("<p><span>Sender:</span> ")
+          .append(StringEscapeUtils.escapeXml(n.getSender())).append("</p>");
+        sb.append("<p><span>Source:</span> ")
+          .append(StringEscapeUtils.escapeXml(n.getSource())).append("</p>");
+
+        Map extras = n.getExtraDescriptions();
+        Iterator i = extras.keySet().iterator();
+        while (i.hasNext()) {
+            final String key = (String) i.next();
+
+            sb.append("<p><span>")
+              .append(key).append("</span><pre>")
+              .append(StringEscapeUtils.escapeXml(String.valueOf(extras.get(key))))
+              .append("</pre></p>");
+        }
+
+        sb.append("<p class='footer'><a href='http://cocoon.apache.org/'>").append(Constants.COMPLETE_NAME).append("</p>");
+        sb.append("</body></html>");
+
+        outputStream.write(sb.toString().getBytes());
+    }
+
+    /**
+     * Generate notification information in XML format.
+     */
+    public static void notify(Notifying n, ContentHandler ch, String mimetype) throws SAXException {
+        final String PREFIX = Constants.ERROR_NAMESPACE_PREFIX;
+        final String URI = Constants.ERROR_NAMESPACE_URI;
+
+        // Start the document
+        ch.startDocument();
+        ch.startPrefixMapping(PREFIX, URI);
+
+        // Root element.
+        AttributesImpl atts = new AttributesImpl();
+
+        atts.addAttribute(URI, "type", PREFIX + ":type", "CDATA", n.getType());
+        atts.addAttribute(URI, "sender", PREFIX + ":sender", "CDATA", n.getSender());
+        ch.startElement(URI, "notify", PREFIX + ":notify", atts);
+        ch.startElement(URI, "title", PREFIX + ":title", new AttributesImpl());
+        ch.characters(n.getTitle().toCharArray(), 0, n.getTitle().length());
+        ch.endElement(URI, "title", PREFIX + ":title");
+        ch.startElement(URI, "source", PREFIX + ":source", new AttributesImpl());
+        ch.characters(n.getSource().toCharArray(), 0, n.getSource().length());
+        ch.endElement(URI, "source", PREFIX + ":source");
+        ch.startElement(URI, "message", PREFIX + ":message", new AttributesImpl());
+
+        if (n.getMessage() != null) {
+            ch.characters(n.getMessage().toCharArray(), 0, n.getMessage().length());
+        }
+
+        ch.endElement(URI, "message", PREFIX + ":message");
+        ch.startElement(URI, "description", PREFIX + ":description", XMLUtils.EMPTY_ATTRIBUTES);
+        ch.characters(n.getDescription().toCharArray(), 0, n.getDescription().length());
+        ch.endElement(URI, "description", PREFIX + ":description");
+
+        Map extraDescriptions = n.getExtraDescriptions();
+        for (Iterator i = extraDescriptions.entrySet().iterator(); i.hasNext(); ) {
+            final Map.Entry me = (Map.Entry) i.next();
+            String key = (String) me.getKey();
+            String value = String.valueOf(me.getValue());
+            atts = new AttributesImpl();
+
+            atts.addAttribute(URI, "description", PREFIX + ":description", "CDATA", key);
+            ch.startElement(URI, "extra", PREFIX + ":extra", atts);
+            ch.characters(value.toCharArray(), 0, value.length());
+            ch.endElement(URI, "extra", PREFIX + ":extra");
+        }
+
+        // End root element.
+        ch.endElement(URI, "notify", PREFIX + ":notify");
+
+        // End the document.
+        ch.endPrefixMapping(PREFIX);
+        ch.endDocument();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifying.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifying.java
new file mode 100644
index 0000000..d5054a2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/Notifying.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.notification;
+
+import java.util.Map;
+
+/**
+ *  Interface for Objects that can notify something.
+ *
+ * @version $Id$
+ */
+public interface Notifying {
+
+    /*
+     * Proposed types of notifications
+     */
+    String UNKNOWN_NOTIFICATION = "unknown";
+    String DEBUG_NOTIFICATION   = "debug";
+    String INFO_NOTIFICATION    = "info" ;
+    String WARN_NOTIFICATION    = "warn" ;
+    String ERROR_NOTIFICATION   = "error";
+    String FATAL_NOTIFICATION   = "fatal";
+
+    /*
+     * Proposed extra descriptions
+     */
+    String EXTRA_LOCATION   = "location";
+    String EXTRA_LINE       = "line";
+    String EXTRA_COLUMN     = "column" ;
+    String EXTRA_REQUESTURI = "request-uri" ;
+    String EXTRA_CAUSE      = "cause";
+    String EXTRA_STACKTRACE = "stacktrace";
+    String EXTRA_FULLTRACE  = "full exception chain stacktrace";
+
+    /**
+     * Gets the Type of the Notifying object
+     */
+    String getType();
+
+    /**
+     * Gets the Title of the Notifying object
+     */
+    String getTitle();
+
+    /**
+     * Gets the Source of the Notifying object
+     */
+    String getSource();
+
+    /**
+     * Gets the Sender of the Notifying object
+     */
+    String getSender();
+
+    /**
+     * Gets the Message of the Notifying object
+     */
+    String getMessage();
+
+    /**
+     * Gets the Description of the Notifying object
+     */
+    String getDescription();
+
+    /**
+     * Gets the ExtraDescriptions of the Notifying object
+     */
+    Map getExtraDescriptions();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingBuilder.java
new file mode 100644
index 0000000..98af62e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingBuilder.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.notification;
+
+import java.util.Map;
+
+/**
+ *  Generates an Notifying representation of widely used objects.
+ *
+ * @version $Id$
+ */
+public interface NotifyingBuilder {
+
+  /**
+  * The role implemented by a <code>NotifyingBuilder</code>.
+  */
+  String ROLE = NotifyingBuilder.class.getName();
+
+  /** Builds a Notifying object (SimpleNotifyingObject in this case)
+   *  that tries to explain what the Object o can reveal.
+   * @param sender who sent this Object.
+   * @param o the object to use when building the SimpleNotifyingObject
+   * @return the  Notifying Object that was build
+   * @see org.apache.cocoon.components.notification.Notifying
+   */
+  Notifying build(Object sender, Object o);
+
+
+  /** Builds a Notifying object (SimpleNotifyingObject in this case)
+   *  that explains a notification.
+   * @param sender who sent this Object.
+   * @param o the object to use when building the SimpleNotifyingObject
+   * @param type see the Notifying apidocs
+   * @param title see the Notifying apidocs
+   * @param source see the Notifying apidocs
+   * @param message see the Notifying apidocs
+   * @param description see the Notifying apidocs
+   * @param extra see the Notifying apidocs
+   * @return the  Notifying Object that was build
+   * @see org.apache.cocoon.components.notification.Notifying
+   */
+  Notifying build(Object sender, Object o, String type, String title,
+          String source, String message, String description, Map extra);
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingCascadingRuntimeException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingCascadingRuntimeException.java
new file mode 100644
index 0000000..c601e5a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/NotifyingCascadingRuntimeException.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.notification;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+import java.util.Map;
+
+/**
+ * A CascadingRuntimeException that is also Notifying.
+ *
+ * @version $Id$
+ */
+public class NotifyingCascadingRuntimeException
+  extends CascadingRuntimeException
+    implements Notifying{
+
+  /**
+   * The Notifying Object used internally to keep Notifying fields
+   */
+  Notifying n;
+
+  /**
+   * Construct a new <code>NotifyingCascadingRuntimeException</code> instance.
+   */
+  public NotifyingCascadingRuntimeException(String message) {
+    super(message, null);
+    n = new DefaultNotifyingBuilder().build(this, message);
+  }
+
+  /**
+   * Creates a new <code>ProcessingException</code> instance.
+   *
+   * @param ex an <code>Exception</code> value
+   */
+  public NotifyingCascadingRuntimeException(Exception ex) {
+    super(ex.getMessage(), ex);
+    n = new DefaultNotifyingBuilder().build(this, ex);
+  }
+
+  /**
+   * Construct a new <code>ProcessingException</code> that references
+   * a parent Exception.
+   */
+  public NotifyingCascadingRuntimeException(String message, Throwable t) {
+    super(message, t);
+    n = new DefaultNotifyingBuilder().build(this, t);
+  }
+
+  /**
+   *  Gets the Type attribute of the Notifying object
+   */
+  public String getType() {
+    return n.getType();
+  }
+
+  /**
+   *  Gets the Title attribute of the Notifying object
+   */
+  public String getTitle() {
+    return n.getTitle();
+  }
+
+  /**
+   *  Gets the Source attribute of the Notifying object
+   */
+  public String getSource() {
+    return n.getSource();
+  }
+
+  /**
+   *  Gets the Sender attribute of the Notifying object
+   */
+  public String getSender() {
+    return n.getSender();
+  }
+
+  /**
+   *  Gets the Message attribute of the Notifying object
+   */
+  public String getMessage() {
+    return n.getMessage();
+  }
+
+  /**
+   *  Gets the Description attribute of the Notifying object
+   */
+  public String getDescription() {
+    return n.getDescription();
+  }
+
+  /**
+   *  Gets the ExtraDescriptions attribute of the Notifying object
+   */
+  public Map getExtraDescriptions() {
+    return n.getExtraDescriptions();
+  }
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/SimpleNotifyingBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/SimpleNotifyingBean.java
new file mode 100644
index 0000000..51d248c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/notification/SimpleNotifyingBean.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.notification;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *  A simple bean implementation of Notifying.
+ *
+ * @version $Id$
+ */
+public class SimpleNotifyingBean implements Notifying {
+
+    /**
+     * The type of the notification. Examples can be "warning" or "error"
+     */
+    private String type = "unknown";
+
+    /**
+     * The title of the notification.
+     */
+    private String title = "Generic notification";
+
+    /**
+     * The source that generates the notification.
+     */
+    private String source = getClass().getName();
+
+    /**
+     * The sender of the notification.
+     */
+    private String sender = "unknown";
+
+    /**
+     * The notification itself.
+     */
+    private String message = "Message not known.";
+
+    /**
+     * A more detailed description of the notification.
+     */
+    private String description = "";
+
+    /**
+     * A HashMap containing extra notifications
+     */
+    private Map extraDescriptions = new HashMap();
+
+
+    public SimpleNotifyingBean() {
+    }
+
+    public SimpleNotifyingBean(Object sender) {
+        this.sender = sender.getClass().getName();
+    }
+
+    /**
+     * Sets the Type of the SimpleNotifyingBean object
+     *
+     * @param  type  The new Type value
+     */
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * Sets the Title of the SimpleNotifyingBean object
+     *
+     * @param  title  The new Title value
+     */
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * Sets the Source of the SimpleNotifyingBean object
+     *
+     * @param  source  The new Source value
+     */
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    /**
+     * Sets the Message of the SimpleNotifyingBean object
+     *
+     * @param  message  The new Message value
+     */
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * Sets the Description of the SimpleNotifyingBean object
+     *
+     * @param  description  The new Description value
+     */
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * Adds the ExtraDescription to the SimpleNotifyingBean object
+     *
+     * @param  extraDescriptionDescription  The additional ExtraDescription name
+     * @param  extraDescription The additional ExtraDescription value
+     */
+    public void addExtraDescription(String extraDescriptionDescription,
+                                    String extraDescription) {
+        this.extraDescriptions.put(extraDescriptionDescription, extraDescription);
+    }
+
+    /**
+     * Replaces the ExtraDescriptions of the SimpleNotifyingBean object
+     */
+    protected void replaceExtraDescriptions(Map extraDescriptions) {
+        this.extraDescriptions = extraDescriptions;
+    }
+
+    /**
+     * Adds the ExtraDescriptions to the SimpleNotifyingBean object
+     */
+    protected void addExtraDescriptions(Map extraDescriptions) {
+        if (this.extraDescriptions == null) {
+            replaceExtraDescriptions(extraDescriptions);
+        } else {
+            this.extraDescriptions.putAll(extraDescriptions);
+        }
+    }
+
+    /**
+     * Gets the Type of the SimpleNotifyingBean object
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Gets the Title of the SimpleNotifyingBean object
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Gets the Source of the SimpleNotifyingBean object
+     */
+    public String getSource() {
+        return source;
+    }
+
+    /**
+     * Gets the Sender of the SimpleNotifyingBean object
+     */
+    public String getSender() {
+        return sender;
+    }
+
+    /**
+     * Gets the Message of the SimpleNotifyingBean object
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * Gets the Description of the SimpleNotifyingBean object
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * Gets the ExtraDescriptions of the SimpleNotifyingBean object
+     */
+    public Map getExtraDescriptions() {
+        return extraDescriptions;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStore.java
new file mode 100644
index 0000000..b85e9c1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStore.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.persistence;
+
+
+/**
+ * A request data store is a component that manages data that is
+ * linked to the current request.
+ * With the setRequestData() method you can link any object to the
+ * current request. This object can be fetched via getRequestData()
+ * as long as the request is running. This data is not available
+ * in any sub-request (cocoon: protocol calls).
+ * If you want to share data between the main request and any sub-request
+ * than you have to use the setGlobalRequestData etc. methods.
+ * 
+ * This component is a replacement for the request lifecycle and
+ * global request lifecycle components.
+ * 
+ * @version $Id$
+ * @since 2.1.1
+ * @deprecated Use the scoped attributes on the Request object instead.
+ *             This component will be removed with Cocoon 2.3.
+ */
+public interface RequestDataStore {
+        
+    String ROLE = RequestDataStore.class.getName();
+    
+    Object getRequestData(String key);
+
+    void removeRequestData(String key);
+
+    void setRequestData(String key, Object value);
+
+    Object getGlobalRequestData(String key);
+
+    void removeGlobalRequestData(String key);
+
+    void setGlobalRequestData(String key, Object value);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStoreImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStoreImpl.java
new file mode 100644
index 0000000..a308acd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/persistence/RequestDataStoreImpl.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.persistence;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+/**
+ * The default implementation
+ * 
+ * @version $Id$
+ * @since 2.1.1
+ * @deprecated Use the scoped attributes on the Request object instead.
+ *             This component will be removed with Cocoon 2.3.
+ */
+public class RequestDataStoreImpl
+    extends AbstractLogEnabled
+    implements ThreadSafe, RequestDataStore, Contextualizable {
+        
+    protected Context context;
+
+    protected final String requestDataKey = this.getClass().getName() + "/RD";
+    
+    protected final String globalRequestDataKey = this.getClass().getName() + "/GRD";
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#getGlobalRequestData(java.lang.String)
+     */
+    public Object getGlobalRequestData(String key) {
+        Object value = null;
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.globalRequestDataKey);
+        if ( m != null ) {
+            value = m.get( key );
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#getRequestData(java.lang.String)
+     */
+    public Object getRequestData(String key) {
+        Object value = null;
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.requestDataKey + ObjectModelHelper.getRequest(objectModel).hashCode());
+        if ( m != null ) {
+            value = m.get( key );
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#removeGlobalRequestData(java.lang.String)
+     */
+    public void removeGlobalRequestData(String key) {
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.globalRequestDataKey);
+        if ( m != null ) {
+            objectModel.remove( key );
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#removeRequestData(java.lang.String)
+     */
+    public void removeRequestData(String key) {
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.requestDataKey + ObjectModelHelper.getRequest(objectModel).hashCode());
+        if ( m != null ) {
+            objectModel.remove( key );
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#setGlobalRequestData(java.lang.String, java.lang.Object)
+     */
+    public void setGlobalRequestData(String key, Object value) {
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.globalRequestDataKey);
+        if ( m == null ) {
+            m = new HashMap();
+            objectModel.put(this.globalRequestDataKey, m);
+        }
+        m.put(key, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.persistance.RequestDataStore#setRequestData(java.lang.String, java.lang.Object)
+     */
+    public void setRequestData(String key, Object value) {
+        final Map objectModel = ContextHelper.getObjectModel(this.context);
+        Map m = (Map)objectModel.get(this.requestDataKey + ObjectModelHelper.getRequest(objectModel).hashCode());
+        if ( m == null ) {
+            m = new HashMap();
+            objectModel.put(this.requestDataKey + ObjectModelHelper.getRequest(objectModel).hashCode(), m);
+        }
+        m.put(key, value);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java
new file mode 100644
index 0000000..6042949
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/AbstractProcessingPipeline.java
@@ -0,0 +1,900 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ConnectionResetException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.reading.Reader;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.sitemap.SitemapErrorHandler;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.xml.SaxBuffer;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+/**
+ * This is the base for all implementations of a <code>ProcessingPipeline</code>.
+ * It is advisable to inherit from this base class instead of doing a complete
+ * own implementation!
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public abstract class AbstractProcessingPipeline
+        extends AbstractLogEnabled
+        implements ProcessingPipeline, Parameterizable, Recyclable, Serviceable {
+
+    // Generator stuff
+    protected Generator generator;
+    protected Parameters generatorParam;
+    protected String generatorSource;
+
+    // Transformer stuff
+    protected ArrayList transformers = new ArrayList();
+    protected ArrayList transformerParams = new ArrayList();
+    protected ArrayList transformerSources = new ArrayList();
+
+    // Serializer stuff
+    protected Serializer serializer;
+    protected Parameters serializerParam;
+    protected String serializerSource;
+    protected String serializerMimeType;
+
+    // Reader stuff
+    protected Reader reader;
+    protected Parameters readerParam;
+    protected String readerSource;
+    protected String readerMimeType;
+
+    // Error handler stuff
+    private SitemapErrorHandler errorHandler;
+    private Processor.InternalPipelineDescription errorPipeline;
+
+    /** True when pipeline has been prepared. */
+    private boolean prepared;
+
+    /**
+     * This is the last component in the pipeline, either the serializer
+     * or a custom XML consumer in case of internal processing.
+     */
+    protected XMLConsumer lastConsumer;
+
+    /** The component manager set with compose() */
+    protected ServiceManager manager;
+
+    /** The component manager set with compose() and recompose() */
+    protected ServiceManager newManager;
+
+    /** The configuration */
+    protected Parameters configuration;
+
+    /** Configured Expires value */
+    protected long configuredExpires;
+
+    /** Configured Output Buffer Size */
+    protected int configuredOutputBufferSize;
+
+    /** The parameters */
+    protected Parameters parameters;
+
+    /** Expires value */
+    protected long expires;
+
+    /** Output Buffer Size */
+    protected int outputBufferSize;
+
+    /** The current Processor */
+    protected Processor processor;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service (ServiceManager manager)
+    throws ServiceException {
+        this.manager = manager;
+        this.newManager = manager;
+    }
+
+    /**
+     * Set the processor's service manager
+     */
+    public void setProcessorManager (ServiceManager manager) {
+        this.newManager = manager;
+    }
+
+    /**
+     * Parameterizable Interface - Configuration
+     */
+    public void parameterize(Parameters params)
+    throws ParameterException {
+        this.configuration = params;
+        final String expiresValue = params.getParameter("expires", null);
+        if (expiresValue != null) {
+            this.configuredExpires = parseExpires(expiresValue);
+        }
+        this.configuredOutputBufferSize = params.getParameterAsInteger("outputBufferSize", -1);
+    }
+
+    /**
+     * Setup this component
+     */
+    public void setup(Parameters params) {
+        this.parameters = params;
+        final String expiresValue = params.getParameter("expires", null);
+        if (expiresValue != null) {
+            this.expires = parseExpires(expiresValue);
+        } else {
+            this.expires = this.configuredExpires;
+        }
+        this.outputBufferSize = params.getParameterAsInteger("outputBufferSize",
+                                                              this.configuredOutputBufferSize);
+    }
+
+    /**
+     * Informs pipeline we have come across a branch point.
+     * Default behaviour is do nothing.
+     */
+    public void informBranchPoint() {
+        // this can be overwritten in subclasses
+    }
+
+    /**
+     * Get the generator - used for content aggregation
+     */
+    public Generator getGenerator() {
+        return this.generator;
+    }
+
+    /**
+     * Set the generator that will be used as the initial step in the pipeline.
+     * The generator role is given : the actual <code>Generator</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the generator role in the component manager.
+     * @param source the source where to produce XML from, or <code>null</code> if no
+     *        source is given.
+     * @param param the parameters for the generator.
+     * @throws ProcessingException if the generator couldn't be obtained.
+     */
+    public void setGenerator(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException {
+        if (this.generator != null) {
+            throw new ProcessingException ("Generator already set. Cannot set generator '" + role + "'",
+                    getLocation(param));
+        }
+        if (this.reader != null) {
+            throw new ProcessingException ("Reader already set. Cannot set generator '" + role + "'",
+                    getLocation(param));
+        }
+        try {
+            this.generator = (Generator) this.newManager.lookup(Generator.ROLE + '/' + role);
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of generator '" + role + "' failed", ce, getLocation(param));
+        }
+        this.generatorSource = source;
+        this.generatorParam = param;
+    }
+
+    /**
+     * Add a transformer at the end of the pipeline.
+     * The transformer role is given : the actual <code>Transformer</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the transformer role in the component manager.
+     * @param source the source used to setup the transformer (e.g. XSL file), or
+     *        <code>null</code> if no source is given.
+     * @param param the parameters for the transfomer.
+     * @throws ProcessingException if the generator couldn't be obtained.
+     */
+    public void addTransformer(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException {
+        if (this.reader != null) {
+            // Should normally never happen as setting a reader starts pipeline processing
+            throw new ProcessingException ("Reader already set. Cannot add transformer '" + role + "'",
+                    getLocation(param));
+        }
+        if (this.generator == null) {
+            throw new ProcessingException ("Must set a generator before adding transformer '" + role + "'",
+                    getLocation(param));
+        }
+        try {
+            this.transformers.add(this.newManager.lookup(Transformer.ROLE + '/' + role));
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of transformer '"+role+"' failed", ce, getLocation(param));
+        }
+        this.transformerSources.add(source);
+        this.transformerParams.add(param);
+    }
+
+    /**
+     * Set the serializer for this pipeline
+     * @param mimeType Can be null
+     */
+    public void setSerializer(String role, String source, Parameters param, Parameters hintParam, String mimeType)
+    throws ProcessingException {
+        if (this.serializer != null) {
+            // Should normally not happen as adding a serializer starts pipeline processing
+            throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role + "'",
+                    getLocation(param));
+        }
+        if (this.reader != null) {
+            // Should normally never happen as setting a reader starts pipeline processing
+            throw new ProcessingException ("Reader already set. Cannot set serializer '" + role + "'",
+                    getLocation(param));
+        }
+        if (this.generator == null) {
+            throw new ProcessingException ("Must set a generator before setting serializer '" + role + "'",
+                    getLocation(param));
+        }
+
+        try {
+            this.serializer = (Serializer)this.newManager.lookup(Serializer.ROLE + '/' + role);
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of serializer '" + role + "' failed", ce, getLocation(param));
+        }
+        this.serializerSource = source;
+        this.serializerParam = param;
+        this.serializerMimeType = mimeType;
+        this.lastConsumer = this.serializer;
+    }
+
+    /**
+     * Set the reader for this pipeline
+     * @param mimeType Can be null
+     */
+    public void setReader(String role, String source, Parameters param, String mimeType)
+    throws ProcessingException {
+        if (this.reader != null) {
+            // Should normally never happen as setting a reader starts pipeline processing
+            throw new ProcessingException ("Reader already set. Cannot set reader '" + role + "'",
+                    getLocation(param));
+        }
+        if (this.generator != null) {
+            // Should normally never happen as setting a reader starts pipeline processing
+            throw new ProcessingException ("Generator already set. Cannot use reader '" + role + "'",
+                    getLocation(param));
+        }
+
+        try {
+            this.reader = (Reader)this.newManager.lookup(Reader.ROLE + '/' + role);
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of reader '"+role+"' failed", ce, getLocation(param));
+        }
+        this.readerSource = source;
+        this.readerParam = param;
+        this.readerMimeType = mimeType;
+    }
+
+    /**
+     * Sets error handler for this pipeline.
+     * Used for handling errors in the internal pipelines.
+     * @param errorHandler error handler
+     */
+    public void setErrorHandler(SitemapErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    /**
+     * Sanity check
+     * @return true if the pipeline is 'sane', false otherwise.
+     */
+    protected boolean checkPipeline() {
+        if (this.generator == null && this.reader == null) {
+            return false;
+        }
+
+        if (this.generator != null && this.serializer == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Setup pipeline components.
+     */
+    protected void setupPipeline(Environment environment)
+    throws ProcessingException {
+        try {
+            // setup the generator
+            this.generator.setup(
+                this.processor.getSourceResolver(),
+                environment.getObjectModel(),
+                generatorSource,
+                generatorParam
+            );
+
+            Iterator transformerItt = this.transformers.iterator();
+            Iterator transformerSourceItt = this.transformerSources.iterator();
+            Iterator transformerParamItt = this.transformerParams.iterator();
+
+            while (transformerItt.hasNext()) {
+                Transformer trans = (Transformer)transformerItt.next();
+                trans.setup(this.processor.getSourceResolver(),
+                            environment.getObjectModel(),
+                            (String)transformerSourceItt.next(),
+                            (Parameters)transformerParamItt.next()
+                );
+            }
+
+            if (this.serializer instanceof SitemapModelComponent) {
+                ((SitemapModelComponent)this.serializer).setup(
+                    this.processor.getSourceResolver(),
+                    environment.getObjectModel(),
+                    this.serializerSource,
+                    this.serializerParam
+                );
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+    }
+
+    /**
+     * Connect the next component
+     */
+    protected void connect(Environment environment,
+                           XMLProducer producer,
+                           XMLConsumer consumer)
+    throws ProcessingException {
+        // Connect next component.
+        producer.setConsumer(consumer);
+    }
+
+    /**
+     * Connect the XML pipeline.
+     */
+    protected void connectPipeline(Environment environment)
+    throws ProcessingException {
+        XMLProducer prev = this.generator;
+
+        Iterator itt = this.transformers.iterator();
+        while (itt.hasNext()) {
+            Transformer next = (Transformer) itt.next();
+            connect(environment, prev, next);
+            prev = next;
+        }
+
+        // insert the serializer
+        connect(environment, prev, this.lastConsumer);
+    }
+
+    /**
+     * Process the given <code>Environment</code>, producing the output.
+     */
+    public boolean process(Environment environment)
+    throws ProcessingException {
+        if (!this.prepared) {
+            preparePipeline(environment);
+        }
+
+        // See if we need to set an "Expires:" header
+        if (this.expires != 0) {
+            Response res = ObjectModelHelper.getResponse(environment.getObjectModel());
+            res.setDateHeader("Expires", System.currentTimeMillis() + expires);
+            res.setHeader("Cache-Control", "max-age=" + expires/1000 + ", public");
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Setting a new Expires object for this resource");
+            }
+            environment.getObjectModel().put(ObjectModelHelper.EXPIRES_OBJECT,
+                                             new Long(expires + System.currentTimeMillis()));
+        }
+
+        if (this.reader != null) {
+            if (checkIfModified(environment, this.reader.getLastModified())) {
+                return true;
+            }
+
+            return processReader(environment);
+        } else {
+            // If this is an internal request, lastConsumer was reset!
+            if (this.lastConsumer == null) {
+                this.lastConsumer = this.serializer;
+            }
+
+            connectPipeline(environment);
+            return processXMLPipeline(environment);
+        }
+    }
+
+    /**
+     * Prepare the pipeline
+     */
+    protected void preparePipeline(Environment environment)
+    throws ProcessingException {
+        // TODO (CZ) Get the processor set via IoC
+        this.processor = EnvironmentHelper.getCurrentProcessor();
+        if (!checkPipeline()) {
+            throw new ProcessingException("Attempted to process incomplete pipeline.");
+        }
+
+        if (this.prepared) {
+            throw new ProcessingException("Duplicate preparePipeline call caught.");
+        }
+
+        if (this.reader != null) {
+            setupReader(environment);
+        } else {
+            setupPipeline(environment);
+        }
+        this.prepared = true;
+    }
+
+    /**
+     * Prepare an internal processing.
+     * @param environment The current environment.
+     * @throws ProcessingException
+     */
+    public void prepareInternal(Environment environment)
+    throws ProcessingException {
+        this.lastConsumer = null;
+        try {
+            preparePipeline(environment);
+        } catch (ProcessingException e) {
+            prepareInternalErrorHandler(environment, e);
+        }
+    }
+
+    /**
+     * If prepareInternal fails, prepare internal error handler.
+     */
+    protected void prepareInternalErrorHandler(Environment environment, ProcessingException ex)
+    throws ProcessingException {
+        if (this.errorHandler != null) {
+            try {
+                this.errorPipeline = this.errorHandler.prepareErrorPipeline(ex);
+                if (this.errorPipeline != null) {
+                    this.errorPipeline.processingPipeline.prepareInternal(environment);
+                    return;
+                }
+            } catch (ProcessingException e) {
+                // Log the original exception
+                getLogger().error("Failed to process error handler for exception", ex);
+                throw e;
+            } catch (Exception e) {
+                getLogger().error("Failed to process error handler for exception", ex);
+                throw new ProcessingException("Failed to handle exception <" + ex.getMessage() + ">", e);
+            }
+        } else {
+            // propagate exception if we have no error handler
+            throw ex;
+        }
+    }
+
+    /**
+     * @return true if error happened during internal pipeline prepare call.
+     */
+    protected boolean isInternalError() {
+        return this.errorPipeline != null;
+    }
+
+    /**
+     * Process the SAX event pipeline
+     */
+    protected boolean processXMLPipeline(Environment environment)
+    throws ProcessingException {
+
+        setMimeTypeForSerializer(environment);
+        try {
+            if (this.lastConsumer == null) {
+                // internal processing
+                this.generator.generate();
+            } else {
+                if (this.serializer.shouldSetContentLength()) {
+                    // set the output stream
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    this.serializer.setOutputStream(os);
+
+                    // execute the pipeline:
+                    this.generator.generate();
+                    environment.setContentLength(os.size());
+                    os.writeTo(environment.getOutputStream(0));
+                } else {
+                    // set the output stream
+                    this.serializer.setOutputStream(environment.getOutputStream(this.outputBufferSize));
+                    // execute the pipeline:
+                    this.generator.generate();
+                }
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Setup the reader
+     */
+    protected void setupReader(Environment environment)
+    throws ProcessingException {
+        try {
+            this.reader.setup(this.processor.getSourceResolver(),environment.getObjectModel(),readerSource,readerParam);
+
+            // set the expires parameter on the pipeline if the reader is configured with one
+            if (readerParam.isParameter("expires")) {
+	            // should this checking be done somewhere else??
+	            this.expires = readerParam.getParameterAsLong("expires");
+            }
+        } catch (Exception e){
+            handleException(e);
+        }
+    }
+
+    /**
+     * Set the mime-type for a reader
+     * @param environment The current environment
+     */
+    protected void setMimeTypeForReader(Environment environment) {
+        // Set the mime-type
+        // the behaviour has changed from 2.1.x to 2.2 according to bug #10277:
+        // MIME type declared in the sitemap (instance or declaration, in this order)
+        // Ask the Reader for a MIME type:
+        //     A *.doc reader could peek into the file
+        //     and return either text/plain or application/vnd.msword or
+        //     the reader can use MIME type declared in WEB-INF/web.xml or
+        //     by the server.
+        if ( this.readerMimeType != null ) {
+            // there was a mime-type defined on map:read in the sitemap
+            environment.setContentType(this.readerMimeType);
+        } else {
+            final String mimeType = this.reader.getMimeType();
+            if (mimeType != null) {
+                environment.setContentType(mimeType);
+            }
+            // If no mimeType available, leave to to upstream proxy
+            // or browser to deduce content-type from URL extension.
+        }
+    }
+
+    /**
+     * Set the mime-type for a serializer
+     * @param environment The current environment
+     */
+    protected void setMimeTypeForSerializer(Environment environment)
+    throws ProcessingException {
+        if (this.lastConsumer == null) {
+            // internal processing: text/xml
+            environment.setContentType("text/xml");
+        } else {
+            // Set the mime-type
+            // the behaviour has changed from 2.1.x to 2.2 according to bug #10277
+            if (serializerMimeType != null) {
+                // there was a serializer defined in the sitemap
+                environment.setContentType(serializerMimeType);
+            } else {
+                // ask to the component itself
+                String mimeType = this.serializer.getMimeType();
+                if (mimeType != null) {
+                    environment.setContentType (mimeType);
+                } else {
+                    // No mimeType available
+                    String message = "Unable to determine MIME type for " +
+                        environment.getURIPrefix() + "/" + environment.getURI();
+                    throw new ProcessingException(message);
+                }
+            }
+        }
+    }
+
+    protected boolean checkIfModified(Environment environment,
+                                      long lastModified)
+    throws ProcessingException {
+        // has the read resource been modified?
+        if(!environment.isResponseModified(lastModified)) {
+            // environment supports this, so we are finished
+            environment.setResponseIsNotModified();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Process the pipeline using a reader.
+     * @throws ProcessingException if
+     */
+    protected boolean processReader(Environment environment)
+    throws ProcessingException {
+        try {
+            this.setMimeTypeForReader(environment);
+            if (this.reader.shouldSetContentLength()) {
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                this.reader.setOutputStream(os);
+                this.reader.generate();
+                environment.setContentLength(os.size());
+                os.writeTo(environment.getOutputStream(0));
+            } else {
+                this.reader.setOutputStream(environment.getOutputStream(this.outputBufferSize));
+                this.reader.generate();
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+
+        return true;
+    }
+
+    public void recycle() {
+        this.prepared = false;
+
+        // Release reader.
+        if (this.reader != null) {
+            this.newManager.release(this.reader);
+            this.reader = null;
+            this.readerParam = null;
+        }
+
+        if (this.generator != null) {
+            // Release generator.
+            this.newManager.release(this.generator);
+            this.generator = null;
+            this.generatorParam = null;
+        }
+
+        // Release transformers
+        int size = this.transformers.size();
+        for (int i = 0; i < size; i++) {
+            this.newManager.release(this.transformers.get(i));
+        }
+        this.transformers.clear();
+        this.transformerParams.clear();
+        this.transformerSources.clear();
+
+        // Release serializer
+        if (this.serializer != null) {
+            this.newManager.release(this.serializer);
+            this.serializerParam = null;
+        }
+        this.serializer = null;
+        this.parameters = null;
+        this.processor = null;
+        this.lastConsumer = null;
+
+        // Release error handler
+        this.errorHandler = null;
+        if (this.errorPipeline != null) {
+            this.errorPipeline.release();
+            this.errorPipeline = null;
+        }
+    }
+
+    /**
+     * Process the given <code>Environment</code>, but do not use the
+     * serializer. Instead all SAX events are streamed to the XMLConsumer.
+     */
+    public boolean process(Environment environment, XMLConsumer consumer)
+    throws ProcessingException {
+        if (this.reader != null) {
+            throw new ProcessingException("Streaming of an internal pipeline is not possible with a reader.");
+        }
+
+        // Exception happened during setup and was handled
+        if (this.errorPipeline != null) {
+            return this.errorPipeline.processingPipeline.process(environment, consumer);
+        }
+
+        // Have to buffer events if error handler is specified.
+        SaxBuffer buffer = null;
+        this.lastConsumer = this.errorHandler == null? consumer: (buffer = new SaxBuffer());
+        try {
+            connectPipeline(environment);
+            return processXMLPipeline(environment);
+        } catch (ProcessingException e) {
+            buffer = null;
+            return processErrorHandler(environment, e, consumer);
+        } finally {
+            if (buffer != null) {
+                try {
+                    buffer.toSAX(consumer);
+                } catch (SAXException e) {
+                    throw new ProcessingException("Failed to execute pipeline.", e);
+                }
+            }
+        }
+    }
+
+    protected boolean processErrorHandler(Environment environment, ProcessingException e, XMLConsumer consumer)
+    throws ProcessingException {
+        if (this.errorHandler != null) {
+            try {
+                this.errorPipeline = this.errorHandler.prepareErrorPipeline(e);
+                if (this.errorPipeline != null) {
+                    this.errorPipeline.processingPipeline.prepareInternal(environment);
+                    return this.errorPipeline.processingPipeline.process(environment, consumer);
+                }
+            } catch (Exception ignored) {
+                getLogger().debug("Exception in error handler", ignored);
+            }
+        }
+
+        throw e;
+    }
+
+    /**
+     * Return valid validity objects for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return all validity objects.
+     * Otherwise return <code>null</code>
+     */
+    public SourceValidity getValidityForEventPipeline() {
+        return null;
+    }
+
+    /**
+     * Return the key for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return a key.
+     * Otherwise return <code>null</code>
+     */
+    public String getKeyForEventPipeline() {
+        return null;
+    }
+
+
+    /**
+     * Parse the expires parameter
+     */
+    private long parseExpires(String expire) {
+        StringTokenizer tokens = new StringTokenizer(expire);
+
+        // get <base>
+        String current = tokens.nextToken();
+        if (current.equals("modification")) {
+            getLogger().warn("the \"modification\" keyword is not yet" +
+                             " implemented. Assuming \"now\" as the base attribute");
+            current = "now";
+        }
+
+        if (!current.equals("now") && !current.equals("access")) {
+            getLogger().error("bad <base> attribute, Expires header will not be set");
+            return -1;
+        }
+
+        long number = 0;
+        long modifier = 0;
+        long expires = 0;
+
+        while (tokens.hasMoreTokens()) {
+            current = tokens.nextToken();
+
+            // get rid of the optional <plus> keyword
+            if (current.equals("plus")) {
+                current = tokens.nextToken();
+            }
+
+            // We're expecting a sequence of <number> and <modification> here
+            // get <number> first
+            try {
+                number = Long.parseLong(current);
+            } catch (NumberFormatException nfe) {
+                getLogger().error("state violation: a number was expected here");
+                return -1;
+            }
+
+            // now get <modifier>
+            try {
+                current = tokens.nextToken();
+            } catch (NoSuchElementException nsee) {
+                getLogger().error("State violation: expecting a modifier" +
+                                  " but no one found: Expires header will not be set");
+            }
+            if (current.equals("years")) {
+                modifier = 365L * 24L * 60L * 60L * 1000L;
+            } else if (current.equals("months")) {
+                modifier = 30L * 24L * 60L * 60L * 1000L;
+            } else if (current.equals("weeks")) {
+                modifier = 7L * 24L * 60L * 60L * 1000L;
+            } else if (current.equals("days")) {
+                modifier = 24L * 60L * 60L * 1000L;
+            } else if (current.equals("hours")) {
+                modifier = 60L * 60L * 1000L;
+            } else if (current.equals("minutes")) {
+                modifier = 60L * 1000L;
+            } else if (current.equals("seconds")) {
+                modifier = 1000L;
+            } else {
+                getLogger().error("Bad modifier (" + current +
+                                  "): ignoring expires configuration");
+                return -1;
+            }
+            expires += number * modifier;
+        }
+
+        return expires;
+    }
+
+    protected Location getLocation(Parameters param) {
+        Location location = null;
+        if (param instanceof Locatable) {
+            location = ((Locatable)param).getLocation();
+        }
+        if (location == null) {
+            location = Location.UNKNOWN;
+        }
+        return location;
+    }
+
+    /**
+     * Handles exception which can happen during pipeline processing.
+     * If this not a connection reset, then all locations for pipeline components are
+     * added to the exception.
+     * 
+     * @throws ConnectionResetException if connection reset detected
+     * @throws ProcessingException in all other cases
+     */
+    protected void handleException(Exception e) throws ProcessingException {
+        // Check if the client aborted the connection
+        if (e instanceof SocketException) {
+            if (e.getMessage().indexOf("reset") > 0
+                    || e.getMessage().indexOf("aborted") > 0
+                    || e.getMessage().indexOf("connection abort") > 0) {
+                throw new ConnectionResetException("Connection reset by peer", e);
+            }
+        } else if (e instanceof IOException) {
+            // Tomcat5 wraps SocketException into ClientAbortException which extends IOException.
+            if (e.getClass().getName().endsWith("ClientAbortException")) {
+                throw new ConnectionResetException("Connection reset by peer", e);
+            }
+        } else if (e instanceof ConnectionResetException) {
+            // Exception comes up from a deeper pipeline
+            throw (ConnectionResetException)e;
+        }
+
+        // Not a connection reset: add all location information        
+        if (this.reader == null) {
+            // Add all locations in reverse order
+            ArrayList locations = new ArrayList(this.transformers.size() + 2);
+            locations.add(getLocation(this.serializerParam));
+            for (int i = this.transformerParams.size() - 1; i >= 0; i--) {
+                locations.add(getLocation((Parameters)this.transformerParams.get(i)));
+            }
+            locations.add(getLocation(this.generatorParam));
+            
+            throw ProcessingException.throwLocated("Failed to process pipeline", e, locations);
+
+        } else {
+            // Add reader location
+            throw ProcessingException.throwLocated("Failed to process reader", e, getLocation(this.readerParam));
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/ProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/ProcessingPipeline.java
new file mode 100644
index 0000000..e41fb01
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/ProcessingPipeline.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.SitemapErrorHandler;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.xml.XMLConsumer;
+
+import org.apache.excalibur.source.SourceValidity;
+
+/**
+ * A <code>ProcessingPipeline<code> produces the response for a given request.
+ * It is assembled according to the commands in the sitemap and can either
+ * <ul>
+ *  <li>Collect a <code>Reader</code> and let it produce a byte stream,</li>
+ *  <li>Or connect a <code>Generator</code> with zero or more
+ *      <code>Transformer</code>s and a <code>Serializer</code>, and let them
+ *      produce the byte stream. This pipeline uses SAX events for
+ *      communication.
+ *  </li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public interface ProcessingPipeline {
+
+    String ROLE = ProcessingPipeline.class.getName();
+
+    /**
+     * Setup this component.
+     */
+    void setup(Parameters params);
+
+    /**
+     * Set the generator that will be used as the initial step in the pipeline.
+     * The generator role is given : the actual <code>Generator</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the generator role in the component manager.
+     * @param source the source where to produce XML from, or <code>null</code> if no
+     *        source is given.
+     * @param param the parameters for the generator.
+     * @throws ProcessingException if the generator couldn't be obtained.
+     */
+    void setGenerator(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException;
+
+    /**
+     * Get the generator - used for content aggregation
+     */
+    Generator getGenerator();
+
+    /**
+     * Informs pipeline we have come across a branch point
+     */
+    void informBranchPoint();
+
+    /**
+     * Set the <code>ServiceManager</code> where pipeline components have to be searched for.
+     * @param manager the processor's service manager.
+     */
+    void setProcessorManager(ServiceManager manager);
+
+    /**
+     * Add a transformer at the end of the pipeline.
+     * The transformer role is given : the actual <code>Transformer</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the transformer role in the service manager.
+     * @param source the source used to setup the transformer (e.g. XSL file), or
+     *        <code>null</code> if no source is given.
+     * @param param the parameters for the transfomer.
+     * @throws ProcessingException if the generator couldn't be obtained.
+     */
+    void addTransformer(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException;
+
+    /**
+     * Set the serializer for this pipeline
+     * @param mimeType Can be null
+     */
+    void setSerializer(String role, String source, Parameters param, Parameters hintParam, String mimeType)
+    throws ProcessingException;
+
+    /**
+     * Set the reader for this pipeline
+     * @param mimeType Can be null
+     */
+    void setReader(String role, String source, Parameters param, String mimeType)
+    throws ProcessingException;
+
+    /**
+     * Sets error handler for this pipeline.
+     * Used for handling errors in the internal pipelines.
+     */
+    void setErrorHandler(SitemapErrorHandler errorHandler)
+    throws ProcessingException;
+
+    /**
+     * Process the given <code>Environment</code>, producing the output.
+     */
+    boolean process(Environment environment)
+    throws ProcessingException;
+
+    /**
+     * Prepare an internal processing
+     * @param environment          The current environment.
+     * @throws ProcessingException
+     */
+    void prepareInternal(Environment environment)
+    throws ProcessingException;
+
+    /**
+     * Process the given <code>Environment</code>, but do not use the
+     * serializer. Instead the sax events are streamed to the XMLConsumer.
+     * Make sure to call {@link #prepareInternal(Environment)} beforehand.
+     */
+    boolean process(Environment environment, XMLConsumer consumer)
+    throws ProcessingException;
+
+    /**
+     * Return valid validity objects for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return all validity objects.
+     * Otherwise return <code>null</code>
+     */
+    SourceValidity getValidityForEventPipeline();
+
+    /**
+     * Return the key for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return a key.
+     * Otherwise return <code>null</code>
+     */
+    String getKeyForEventPipeline();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java
new file mode 100644
index 0000000..e85b0f2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/VirtualProcessingPipeline.java
@@ -0,0 +1,617 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.sitemap.SitemapErrorHandler;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.xml.SaxBuffer;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+/**
+ * Pipeline used by virtual pipeline components
+ *
+ * @version $Id$
+ */
+public class VirtualProcessingPipeline extends AbstractLogEnabled
+                                       implements ProcessingPipeline, Recyclable, Serviceable {
+
+    // Resolver of the defining sitemap
+    private SourceResolver resolver;
+
+    // Generator stuff
+    protected Generator generator;
+    protected Parameters generatorParam;
+    protected String generatorSource;
+
+    // Transformer stuff
+    protected ArrayList transformers = new ArrayList();
+    protected ArrayList transformerParams = new ArrayList();
+    protected ArrayList transformerSources = new ArrayList();
+
+    // Serializer stuff
+    protected Serializer serializer;
+    protected Parameters serializerParam;
+    protected String serializerSource;
+    protected String serializerMimeType;
+
+    // Error handler stuff
+    private SitemapErrorHandler errorHandler;
+    private Processor.InternalPipelineDescription errorPipeline;
+
+    /**
+     * True when pipeline has been prepared.
+     */
+    private boolean prepared;
+
+    /**
+     * This is the first consumer component in the pipeline, either
+     * the first transformer or the serializer.
+     */
+    protected XMLConsumer firstConsumer;
+
+    /**
+     * This is the last component in the pipeline, either the serializer
+     * or a custom xmlconsumer for the cocoon: protocol etc.
+     */
+    protected XMLConsumer lastConsumer;
+
+    /** The component manager set with compose() */
+    protected ServiceManager manager;
+
+    /** The component manager set with compose() and recompose() */
+    protected ServiceManager newManager;
+
+    /** The current Processor */
+    protected Processor processor;
+
+
+    public VirtualProcessingPipeline(Context context) throws Exception {
+        this.resolver = (EnvironmentHelper) context.get(Constants.CONTEXT_ENV_HELPER);
+    }
+
+    public void service(ServiceManager manager)
+    throws ServiceException {
+        this.manager = manager;
+        this.newManager = manager;
+    }
+
+    /**
+     * Set the processor's service manager
+     */
+    public void setProcessorManager(ServiceManager manager) {
+        this.newManager = manager;
+    }
+
+    /**
+     * Setup this component
+     */
+    public void setup(Parameters params) {
+    }
+
+    /**
+     * Get the generator - used for content aggregation
+     */
+    public Generator getGenerator() {
+        return this.generator;
+    }
+
+    /**
+     * Informs pipeline we have come across a branch point
+     * Default Behaviour is do nothing
+     */
+    public void informBranchPoint() {
+        // this can be overwritten in subclasses
+    }
+
+    /**
+     * Set the generator that will be used as the initial step in the pipeline.
+     * The generator role is given : the actual <code>Generator</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the generator role in the component manager.
+     * @param source the source where to produce XML from, or <code>null</code> if no
+     *        source is given.
+     * @param param the parameters for the generator.
+     * @throws org.apache.cocoon.ProcessingException if the generator couldn't be obtained.
+     */
+    public void setGenerator(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException {
+        if (this.generator != null) {
+            throw new ProcessingException ("Generator already set. Cannot set generator '" + role + "'",
+                getLocation(param));
+        }
+
+        try {
+            this.generator = (Generator) this.newManager.lookup(Generator.ROLE + '/' + role);
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of generator '" + role + "' failed", ce, getLocation(param));
+        }
+
+        this.generatorSource = source;
+        this.generatorParam = param;
+    }
+
+    /**
+     * Add a transformer at the end of the pipeline.
+     * The transformer role is given : the actual <code>Transformer</code> is fetched
+     * from the latest <code>ServiceManager</code>.
+     *
+     * @param role the transformer role in the component manager.
+     * @param source the source used to setup the transformer (e.g. XSL file), or
+     *        <code>null</code> if no source is given.
+     * @param param the parameters for the transfomer.
+     */
+    public void addTransformer(String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException {
+        try {
+            this.transformers.add(this.newManager.lookup(Transformer.ROLE + '/' + role));
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of transformer '"+role+"' failed", ce, getLocation(param));
+        }
+        this.transformerSources.add(source);
+        this.transformerParams.add(param);
+    }
+
+    /**
+     * Set the serializer for this pipeline
+     * @param mimeType Can be null
+     */
+    public void setSerializer(String role, String source, Parameters param, Parameters hintParam, String mimeType)
+    throws ProcessingException {
+        if (this.serializer != null) {
+            // Should normally not happen as adding a serializer starts pipeline processing
+            throw new ProcessingException ("Serializer already set. Cannot set serializer '" + role + "'",
+                    getLocation(param));
+        }
+
+        try {
+            this.serializer = (Serializer)this.newManager.lookup(Serializer.ROLE + '/' + role);
+        } catch (ServiceException ce) {
+            throw ProcessingException.throwLocated("Lookup of serializer '" + role + "' failed", ce, getLocation(param));
+        }
+        this.serializerSource = source;
+        this.serializerParam = param;
+        this.serializerMimeType = mimeType;
+        this.lastConsumer = this.serializer;
+    }
+
+    /**
+     * Sets error handler for this pipeline.
+     * Used for handling errors in the internal pipelines.
+     * @param errorHandler error handler
+     */
+    public void setErrorHandler(SitemapErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    /**
+     * Sanity check
+     * @return true if the pipeline is 'sane', for VPCs all pipelines are sane
+     */
+    protected boolean checkPipeline() {
+        return true;
+    }
+
+    /**
+     * Setup pipeline components.
+     */
+    protected void setupPipeline(Environment environment)
+    throws ProcessingException {
+        try {
+            // SourceResolver resolver = this.processor.getSourceResolver();
+
+            // setup the generator
+            if (this.generator != null) {
+                this.generator.setup(resolver,
+                                     environment.getObjectModel(),
+                                     generatorSource,
+                                     generatorParam);
+            }
+
+            Iterator transformerItt = this.transformers.iterator();
+            Iterator transformerSourceItt = this.transformerSources.iterator();
+            Iterator transformerParamItt = this.transformerParams.iterator();
+
+            while (transformerItt.hasNext()) {
+                Transformer trans = (Transformer)transformerItt.next();
+                trans.setup(resolver,
+                            environment.getObjectModel(),
+                            (String)transformerSourceItt.next(),
+                            (Parameters)transformerParamItt.next()
+                );
+            }
+
+            if (this.serializer != null && this.serializer instanceof SitemapModelComponent) {
+                ((SitemapModelComponent)this.serializer).setup(
+                    resolver,
+                    environment.getObjectModel(),
+                    this.serializerSource,
+                    this.serializerParam
+                );
+            }
+
+        } catch (SAXException e) {
+            throw new ProcessingException("Could not setup pipeline.", e);
+        } catch (IOException e) {
+            throw new ProcessingException("Could not setup pipeline.", e);
+        }
+    }
+
+    /**
+     * Connect the next component
+     */
+    protected void connect(Environment environment,
+                           XMLProducer producer,
+                           XMLConsumer consumer)
+    throws ProcessingException {
+        // Connect next component.
+        producer.setConsumer(consumer);
+    }
+
+    /**
+     * Connect the XML pipeline.
+     */
+    protected void connectPipeline(Environment environment)
+    throws ProcessingException {
+        XMLProducer prev = this.generator;
+
+        Iterator itt = this.transformers.iterator();
+
+        // No generator for VPC transformer and serializer 
+        if (this.generator == null && itt.hasNext()) {
+            this.firstConsumer = (XMLConsumer)(prev = (XMLProducer)itt.next());
+        }
+
+        while (itt.hasNext()) {
+            Transformer next = (Transformer) itt.next();
+            connect(environment, prev, next);
+            prev = next;
+        }
+        
+        // insert the serializer
+        if (prev != null) {
+            connect(environment, prev, this.lastConsumer);
+        } else {
+            this.firstConsumer = this.lastConsumer;
+        }
+    }
+
+    /**
+     * Prepare the pipeline
+     */
+    protected void preparePipeline(Environment environment)
+    throws ProcessingException {
+        // TODO (CZ) Get the processor set via IoC
+        this.processor = EnvironmentHelper.getCurrentProcessor();
+        if (!checkPipeline()) {
+            throw new ProcessingException("Attempted to process incomplete pipeline.");
+        }
+
+        if (this.prepared) {
+            throw new ProcessingException("Duplicate preparePipeline call caught.");
+        }
+
+        setupPipeline(environment);
+        this.prepared = true;
+    }
+
+    /**
+     * Prepare an internal processing
+     * @param environment          The current environment.
+     * @throws org.apache.cocoon.ProcessingException
+     */
+    public void prepareInternal(Environment environment)
+    throws ProcessingException {
+        this.lastConsumer = null;
+        try {
+            preparePipeline(environment);
+        } catch (ProcessingException e) {
+            prepareInternalErrorHandler(environment, e);
+        }
+    }
+
+    /**
+     * If prepareInternal fails, prepare internal error handler.
+     */
+    protected void prepareInternalErrorHandler(Environment environment, ProcessingException ex)
+    throws ProcessingException {
+        if (this.errorHandler != null) {
+            try {
+                this.errorPipeline = this.errorHandler.prepareErrorPipeline(ex);
+                if (this.errorPipeline != null) {
+                    this.errorPipeline.processingPipeline.prepareInternal(environment);
+                    return;
+                }
+            } catch (ProcessingException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new ProcessingException("Failed to handle exception <" + ex + ">", e);
+            }
+        }
+    }
+
+    /**
+     * @return true if error happened during internal pipeline prepare call.
+     */
+    protected boolean isInternalError() {
+        return this.errorPipeline != null;
+    }
+
+    public void setReader(String role, String source, Parameters param, String mimeType) throws ProcessingException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean process(Environment environment) throws ProcessingException {
+        if (!this.prepared) {
+            preparePipeline(environment);
+        }
+
+        // If this is an internal request, lastConsumer was reset!
+        if (this.lastConsumer == null) {
+            this.lastConsumer = this.serializer;
+        }
+        
+        connectPipeline(environment);
+        return processXMLPipeline(environment);
+    }
+
+    /**
+     * Process the given <code>Environment</code>, but do not use the
+     * serializer. Instead the sax events are streamed to the XMLConsumer.
+     */
+    public boolean process(Environment environment, XMLConsumer consumer)
+    throws ProcessingException {
+        // Exception happened during setup and was handled
+        if (this.errorPipeline != null) {
+            return this.errorPipeline.processingPipeline.process(environment, consumer);
+        }
+
+        // Have to buffer events if error handler is specified.
+        SaxBuffer buffer = null;
+        this.lastConsumer = this.errorHandler == null? consumer: (buffer = new SaxBuffer());
+        try {
+            connectPipeline(environment);
+            return processXMLPipeline(environment);
+        } catch (ProcessingException e) {
+            buffer = null;
+            return processErrorHandler(environment, e, consumer);
+        } finally {
+            if (buffer != null) {
+                try {
+                    buffer.toSAX(consumer);
+                } catch (SAXException e) {
+                    throw new ProcessingException("Failed to execute pipeline.", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get the first consumer - used for VPC transformers
+     */
+    public XMLConsumer getXMLConsumer(Environment environment, XMLConsumer consumer)
+        throws ProcessingException {
+        if (!this.prepared) {
+            preparePipeline(environment);
+        }
+
+        this.lastConsumer = consumer;
+        connectPipeline(environment);
+
+        if (this.firstConsumer == null)
+            throw new ProcessingException("A VPC transformer pipeline should not contain a generator.");
+
+        return this.firstConsumer;
+    }
+
+    /**
+     * Get the first consumer - used for VPC serializers
+     */
+    public XMLConsumer getXMLConsumer(Environment environment) throws ProcessingException {
+        if (!this.prepared) {
+            preparePipeline(environment);
+        }
+
+        // If this is an internal request, lastConsumer was reset!
+        if (this.lastConsumer == null) {
+            this.lastConsumer = this.serializer;
+        }
+        
+        connectPipeline(environment);
+
+        if (this.serializer == null) {
+            throw new ProcessingException("A VPC serializer pipeline must contain a serializer.");
+        }
+
+        try {
+            this.serializer.setOutputStream(environment.getOutputStream(0));
+        } catch (Exception e) {
+            throw new ProcessingException("Couldn't set output stream ", e);
+        }
+            
+        if (this.firstConsumer == null)
+            throw new ProcessingException("A VPC serializer pipeline should not contain a generator.");
+
+        return this.firstConsumer;
+    }
+
+    /**
+     * Get the mime-type for the serializer
+     */
+    public String getMimeType() {
+        if (this.lastConsumer == null) {
+            // internal processing: text/xml
+            return "text/xml";
+        } else {
+            // Get the mime-type
+            if (serializerMimeType != null) {
+                // there was a serializer defined in the sitemap
+                return serializerMimeType;
+            } else {
+                // ask to the component itself
+                return this.serializer.getMimeType();
+            }
+        }
+    }
+
+    /**
+     * Test if the serializer wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return this.serializer.shouldSetContentLength();
+    }
+
+    /**
+     * Process the SAX event pipeline
+     */
+    protected boolean processXMLPipeline(Environment environment)
+    throws ProcessingException {
+
+        try {
+            if (this.lastConsumer == null || this.serializer == null) {
+                // internal processing
+                this.generator.generate();
+            } else {
+                if (this.serializer.shouldSetContentLength()) {
+                    // set the output stream
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    this.serializer.setOutputStream(os);
+
+                    // execute the pipeline:
+                    this.generator.generate();
+                    environment.setContentLength(os.size());
+                    os.writeTo(environment.getOutputStream(0));
+                } else {
+                    // set the output stream
+                    this.serializer.setOutputStream(environment.getOutputStream(0));
+                    // execute the pipeline:
+                    this.generator.generate();
+                }
+            }
+        } catch (ProcessingException e) {
+            throw e;
+        } catch (Exception e) {
+            // TODO: Unwrap SAXException ?
+            throw new ProcessingException("Failed to execute pipeline.", e);
+        }
+        return true;
+    }
+
+    public void recycle() {
+        this.prepared = false;
+
+        if (this.generator != null) {
+            // Release generator.
+            this.newManager.release(this.generator);
+            this.generator = null;
+            this.generatorParam = null;
+        }
+
+        // Release transformers
+        int size = this.transformers.size();
+        for (int i = 0; i < size; i++) {
+            this.newManager.release(this.transformers.get(i));
+        }
+        this.transformers.clear();
+        this.transformerParams.clear();
+        this.transformerSources.clear();
+
+        // Release serializer
+        if (this.serializer != null) {
+            this.newManager.release(this.serializer);
+            this.serializerParam = null;
+        }
+        this.serializer = null;
+        this.processor = null;
+        this.lastConsumer = null;
+        this.firstConsumer = null;
+
+        // Release error handler
+        this.errorHandler = null;
+        if (this.errorPipeline != null) {
+            this.errorPipeline.release();
+            this.errorPipeline = null;
+        }
+    }
+
+    protected boolean processErrorHandler(Environment environment, ProcessingException e, XMLConsumer consumer)
+    throws ProcessingException {
+        if (this.errorHandler != null) {
+            try {
+                this.errorPipeline = this.errorHandler.prepareErrorPipeline(e);
+                if (this.errorPipeline != null) {
+                    this.errorPipeline.processingPipeline.prepareInternal(environment);
+                    return this.errorPipeline.processingPipeline.process(environment, consumer);
+                }
+            } catch (Exception ignored) {
+                getLogger().debug("Exception in error handler", ignored);
+            }
+        }
+
+        throw e;
+    }
+
+    /**
+     * Return valid validity objects for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return all validity objects.
+     * Otherwise return <code>null</code>
+     */
+    public SourceValidity getValidityForEventPipeline() {
+        return null;
+    }
+
+    public String getKeyForEventPipeline() {
+        return null;
+    }
+
+    protected Location getLocation(Parameters param) {
+        Location value = null;
+        if (param instanceof Locatable) {
+            value = ((Locatable) param).getLocation();
+        }
+        if (value == null) {
+            value = Location.UNKNOWN;
+        }
+        return value;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java
new file mode 100644
index 0000000..be54e1e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/AbstractCachingProcessingPipeline.java
@@ -0,0 +1,930 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.cocoon.caching.CachingOutputStream;
+import org.apache.cocoon.caching.ComponentCacheKey;
+import org.apache.cocoon.caching.PipelineCacheKey;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.util.HashUtil;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AggregatedValidity;
+import org.apache.excalibur.source.impl.validity.DeferredValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+
+/**
+ * This is the base class for all caching pipeline implementations
+ * that check different pipeline components.
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public abstract class AbstractCachingProcessingPipeline extends BaseCachingProcessingPipeline {
+
+    /** The role name of the generator */
+    protected String generatorRole;
+
+    /** The role names of the transfomrers */
+    protected ArrayList transformerRoles = new ArrayList();
+
+    /** The role name of the serializer */
+    protected String serializerRole;
+
+    /** The role name of the reader */
+    protected String readerRole;
+
+    /** The cached response */
+    protected CachedResponse cachedResponse;
+
+    /** The index indicating the first transformer getting input from the cache */
+    protected int firstProcessedTransformerIndex;
+
+    /** Complete response is cached */
+    protected boolean completeResponseIsCached;
+
+
+    /** This key indicates the response that is fetched from the cache */
+    protected PipelineCacheKey fromCacheKey;
+
+    /** This key indicates the response that will get into the cache */
+    protected PipelineCacheKey toCacheKey;
+
+    /** The source validities used for caching */
+    protected SourceValidity[] toCacheSourceValidities;
+
+    /** The index indicating to the first transformer which is not cacheable */
+    protected int firstNotCacheableTransformerIndex;
+
+    /** Cache complete response */
+    protected boolean cacheCompleteResponse;
+
+    /** Smart caching ? */
+    protected boolean doSmartCaching;
+
+    /** Default setting for smart caching */
+    protected boolean configuredDoSmartCaching;
+
+    /**
+     * Abstract methods defined in subclasses
+     */
+    protected abstract void cacheResults(Environment environment,
+                                         OutputStream os)
+    throws Exception;
+
+    protected abstract ComponentCacheKey newComponentCacheKey(int type,
+                                                              String role,
+                                                              Serializable key);
+
+    protected abstract void connectCachingPipeline(Environment environment)
+    throws ProcessingException;
+
+    /**
+     * Parameterizable Interface - Configuration
+     */
+    public void parameterize(Parameters params)
+    throws ParameterException {
+        super.parameterize(params);
+        this.configuredDoSmartCaching = params.getParameterAsBoolean("smart-caching", true);
+    }
+
+    /**
+     * Setup this component
+     */
+    public void setup(Parameters params) {
+        super.setup(params);
+        this.doSmartCaching = params.getParameterAsBoolean("smart-caching",
+                                                           this.configuredDoSmartCaching);
+    }
+
+    /**
+     * Set the generator.
+     */
+    public void setGenerator (String role, String source, Parameters param,
+                              Parameters hintParam)
+    throws ProcessingException {
+        super.setGenerator(role, source, param, hintParam);
+        this.generatorRole = role;
+    }
+
+    /**
+     * Add a transformer.
+     */
+    public void addTransformer (String role, String source, Parameters param,
+                                Parameters hintParam)
+    throws ProcessingException {
+        super.addTransformer(role, source, param, hintParam);
+        this.transformerRoles.add(role);
+    }
+
+    /**
+     * Set the serializer.
+     */
+    public void setSerializer (String role, String source, Parameters param,
+                               Parameters hintParam, String mimeType)
+    throws ProcessingException {
+        super.setSerializer(role, source, param, hintParam, mimeType);
+        this.serializerRole = role;
+    }
+
+    /**
+     * Set the Reader.
+     */
+    public void setReader (String role, String source, Parameters param,
+                           String mimeType)
+    throws ProcessingException {
+        super.setReader(role, source, param, mimeType);
+        this.readerRole = role;
+    }
+
+    /**
+     * Process the given <code>Environment</code>, producing the output.
+     */
+    protected boolean processXMLPipeline(Environment environment)
+    throws ProcessingException {
+        if (this.toCacheKey == null && this.cachedResponse == null) {
+            return super.processXMLPipeline(environment);
+        }
+
+        if (this.cachedResponse != null && this.completeResponseIsCached) {
+
+            // Allow for 304 (not modified) responses in dynamic content
+            if (checkIfModified(environment, this.cachedResponse.getLastModified())) {
+                return true;
+            }
+
+            // Set mime-type
+            if (this.cachedResponse.getContentType() != null) {
+                environment.setContentType(this.cachedResponse.getContentType());
+            } else {
+                setMimeTypeForSerializer(environment);
+            }
+
+            // Write response out
+            try {
+                final OutputStream outputStream = environment.getOutputStream(0);
+                final byte[] content = this.cachedResponse.getResponse();
+                if (content.length > 0) {
+                    environment.setContentLength(content.length);
+                    outputStream.write(content);
+                }
+            } catch (Exception e) {
+                handleException(e);
+            }
+        } else {
+            setMimeTypeForSerializer(environment);
+            if (getLogger().isDebugEnabled() && this.toCacheKey != null) {
+                getLogger().debug("processXMLPipeline: caching content for further" +
+                                  " requests of '" + environment.getURI() +
+                                  "' using key " + this.toCacheKey);
+            }
+
+            try {
+                OutputStream os = null;
+                if (this.cacheCompleteResponse && this.toCacheKey != null) {
+                    os = new CachingOutputStream(environment.getOutputStream(this.outputBufferSize));
+                }
+
+                if (super.serializer != super.lastConsumer) {
+                    if (os == null) {
+                        os = environment.getOutputStream(this.outputBufferSize);
+                    }
+
+                    // internal processing
+                    if (this.xmlDeserializer != null) {
+                        this.xmlDeserializer.deserialize(this.cachedResponse.getResponse());
+                    } else {
+                        this.generator.generate();
+                    }
+
+                } else {
+                    if (this.serializer.shouldSetContentLength()) {
+                        if (os == null) {
+                            os = environment.getOutputStream(0);
+                        }
+
+                        // Set the output stream
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                        this.serializer.setOutputStream(baos);
+
+                        // Execute the pipeline
+                        if (this.xmlDeserializer != null) {
+                            this.xmlDeserializer.deserialize(this.cachedResponse.getResponse());
+                        } else {
+                            this.generator.generate();
+                        }
+
+                        environment.setContentLength(baos.size());
+                        baos.writeTo(os);
+                    } else {
+                        if (os == null) {
+                            os = environment.getOutputStream(this.outputBufferSize);
+                        }
+
+                        // Set the output stream
+                        this.serializer.setOutputStream(os);
+
+                        // Execute the pipeline
+                        if (this.xmlDeserializer != null) {
+                            this.xmlDeserializer.deserialize(this.cachedResponse.getResponse());
+                        } else {
+                            this.generator.generate();
+                        }
+                    }
+                }
+
+                //
+                // Now that we have processed the pipeline,
+                // we do the actual caching
+                //
+                cacheResults(environment,os);
+
+            } catch (Exception e) {
+                handleException(e);
+            }
+
+            return true;
+        }
+
+        return true;
+    }
+
+    /**
+     * The components of the pipeline are checked if they are Cacheable.
+     */
+    protected void generateCachingKey(Environment environment)
+    throws ProcessingException {
+
+        this.toCacheKey = null;
+
+        this.firstNotCacheableTransformerIndex = 0;
+        this.cacheCompleteResponse = false;
+
+        // first step is to generate the key:
+        // All pipeline components starting with the generator
+        // are tested if they are either a CacheableProcessingComponent
+        // or Cacheable (deprecated). The returned keys are chained together
+        // to build a unique key of the request
+
+        // is the generator cacheable?
+        Serializable key = null;
+        if (super.generator instanceof CacheableProcessingComponent) {
+            key = ((CacheableProcessingComponent)super.generator).getKey();
+        }
+
+        if (key != null) {
+            this.toCacheKey = new PipelineCacheKey();
+            this.toCacheKey.addKey(
+                    this.newComponentCacheKey(
+                            ComponentCacheKey.ComponentType_Generator,
+                            this.generatorRole, key));
+
+            // now testing transformers
+            final int transformerSize = super.transformers.size();
+            boolean continueTest = true;
+
+            while (this.firstNotCacheableTransformerIndex < transformerSize && continueTest) {
+                final Transformer trans =
+                    (Transformer) super.transformers.get(this.firstNotCacheableTransformerIndex);
+                key = null;
+                if (trans instanceof CacheableProcessingComponent) {
+                    key = ((CacheableProcessingComponent)trans).getKey();
+                }
+                if (key != null) {
+                    this.toCacheKey.addKey(
+                            this.newComponentCacheKey(
+                                    ComponentCacheKey.ComponentType_Transformer,
+                                    (String)this.transformerRoles.get(
+                                            this.firstNotCacheableTransformerIndex),
+                                            key));
+
+                    this.firstNotCacheableTransformerIndex++;
+                } else {
+                    continueTest = false;
+                }
+            }
+            // all transformers are cacheable => pipeline is cacheable
+            // test serializer if this is not an internal request
+            if (this.firstNotCacheableTransformerIndex == transformerSize
+                    && super.serializer == this.lastConsumer) {
+
+                key = null;
+                if (super.serializer instanceof CacheableProcessingComponent) {
+                    key = ((CacheableProcessingComponent)this.serializer).getKey();
+                }
+                if (key != null) {
+                    this.toCacheKey.addKey(
+                            this.newComponentCacheKey(
+                                    ComponentCacheKey.ComponentType_Serializer,
+                                    this.serializerRole,
+                                    key));
+                    this.cacheCompleteResponse = true;
+                }
+            }
+        }
+    }
+
+    /**
+     * Generate validity objects for the new response
+     */
+    protected void setupValidities() throws ProcessingException {
+
+        if (this.toCacheKey != null) {
+            // only update validity objects if we cannot use
+            // a cached response or when the cached response does
+            // cache less than now is cacheable
+            if (this.fromCacheKey == null
+                || this.fromCacheKey.size() < this.toCacheKey.size()) {
+
+                this.toCacheSourceValidities =
+                    new SourceValidity[this.toCacheKey.size()];
+
+                int len = this.toCacheSourceValidities.length;
+                int i = 0;
+                while (i < len) {
+                    final SourceValidity validity = getValidityForInternalPipeline(i);
+
+                    if (validity == null) {
+                        if (i > 0
+                            && (this.fromCacheKey == null
+                                    || i > this.fromCacheKey.size())) {
+                            // shorten key
+                            for (int m=i; m < this.toCacheSourceValidities.length; m++) {
+                                this.toCacheKey.removeLastKey();
+                                if (!this.cacheCompleteResponse) {
+                                    this.firstNotCacheableTransformerIndex--;
+                                }
+                                this.cacheCompleteResponse = false;
+                            }
+                            SourceValidity[] copy = new SourceValidity[i];
+                            System.arraycopy(this.toCacheSourceValidities, 0, copy, 0, copy.length);
+                            this.toCacheSourceValidities = copy;
+                            len = this.toCacheSourceValidities.length;
+                        } else {
+                            // caching is not possible!
+                            this.toCacheKey = null;
+                            this.toCacheSourceValidities = null;
+                            this.cacheCompleteResponse = false;
+                            len = 0;
+                        }
+                    } else {
+                        this.toCacheSourceValidities[i] = validity;
+                    }
+                    i++;
+                }
+            } else {
+                // we don't have to cache
+                this.toCacheKey = null;
+                this.cacheCompleteResponse = false;
+            }
+        }
+    }
+
+    /**
+     * Calculate the key that can be used to get something from the cache, and
+     * handle expires properly.
+     */
+    protected void validatePipeline(Environment environment)
+    throws ProcessingException {
+        this.completeResponseIsCached = this.cacheCompleteResponse;
+        this.fromCacheKey = this.toCacheKey.copy();
+        this.firstProcessedTransformerIndex = this.firstNotCacheableTransformerIndex;
+
+        boolean finished = false;
+        while (this.fromCacheKey != null && !finished) {
+            finished = true;
+
+            final CachedResponse response = this.cache.get(this.fromCacheKey);
+
+            // now test validity
+            if (response != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Found cached response for '" + environment.getURI() +
+                                      "' using key: " + this.fromCacheKey);
+                }
+
+                boolean responseIsValid = true;
+                boolean responseIsUsable = true;
+
+                // See if we have an explicit "expires" setting. If so,
+                // and if it's still fresh, we're done.
+                Long responseExpires = response.getExpires();
+
+                if (responseExpires != null) {
+                    if (getLogger().isDebugEnabled()) {
+                       getLogger().debug("Expires time found for " + environment.getURI());
+                    }
+
+                    if (responseExpires.longValue() > System.currentTimeMillis()) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Expires time still fresh for " + environment.getURI() +
+                                              ", ignoring all other cache settings. This entry expires on "+
+                                              new Date(responseExpires.longValue()));
+                        }
+                        this.cachedResponse = response;
+                        return;
+                    } else {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Expires time has expired for " + environment.getURI() +
+                                              ", regenerating content.");
+                        }
+
+                        // If an expires parameter was provided, use it. If this parameter is not available
+                        // it means that the sitemap was modified, and the old expires value is not valid
+                        // anymore.
+                        if (expires != 0) {
+                            if (this.getLogger().isDebugEnabled())
+                                this.getLogger().debug("Refreshing expires informations");
+                            response.setExpires(new Long(expires + System.currentTimeMillis()));
+                        } else {
+                            if (this.getLogger().isDebugEnabled())
+                                this.getLogger().debug("No expires defined anymore for this object, setting it to no expires");
+                            response.setExpires(null);
+                        }
+                    }
+                } else {
+                    // The response had no expires informations. See if it needs to be set (i.e. because the configuration has changed)
+                    if (expires != 0) {
+                        if (this.getLogger().isDebugEnabled())
+                            this.getLogger().debug("Setting a new expires object for this resource");
+                        response.setExpires(new Long(expires + System.currentTimeMillis()));
+                    }
+                }
+
+                SourceValidity[] fromCacheValidityObjects = response.getValidityObjects();
+
+                int i = 0;
+                while (responseIsValid && i < fromCacheValidityObjects.length) {
+                    boolean isValid = false;
+
+                    // BH Check if validities[i] is null, may happen
+                    //    if exception was thrown due to malformed content
+                    SourceValidity validity = fromCacheValidityObjects[i];
+                    int valid = validity == null ? SourceValidity.INVALID : validity.isValid();
+                    if (valid == SourceValidity.UNKNOWN) {
+                        // Don't know if valid, make second test
+                        validity = getValidityForInternalPipeline(i);
+                        if (validity != null) {
+                            valid = fromCacheValidityObjects[i].isValid(validity);
+                            if (valid == SourceValidity.UNKNOWN) {
+                                validity = null;
+                            } else {
+                                isValid = (valid == SourceValidity.VALID);
+                            }
+                        }
+                    } else {
+                        isValid = (valid == SourceValidity.VALID);
+                    }
+
+                    if (!isValid) {
+                        responseIsValid = false;
+                        // update validity
+                        if (validity == null) {
+                            responseIsUsable = false;
+                            if (getLogger().isDebugEnabled()) {
+                                getLogger().debug("validatePipeline: responseIsUsable is false, valid=" +
+                                                  valid + " at index " + i);
+                            }
+                        } else {
+                            if (getLogger().isDebugEnabled()) {
+                                getLogger().debug("validatePipeline: responseIsValid is false due to " +
+                                                  validity);
+                            }
+                        }
+                    } else {
+                        i++;
+                    }
+                }
+
+                if (responseIsValid) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("validatePipeline: using valid cached content for '" +
+                                          environment.getURI() + "'.");
+                    }
+
+                    // we are valid, ok that's it
+                    this.cachedResponse = response;
+                    this.toCacheSourceValidities = fromCacheValidityObjects;
+                } else {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("validatePipeline: cached content is invalid for '" +
+                                          environment.getURI() + "'.");
+                    }
+                    // we are not valid!
+
+                    if (!responseIsUsable) {
+                        // we could not compare, because we got no
+                        // validity object, so shorten pipeline key
+                        if (i > 0) {
+                            int deleteCount = fromCacheValidityObjects.length - i;
+                            if (i > 0 && i <= firstNotCacheableTransformerIndex + 1) {
+                                this.firstNotCacheableTransformerIndex = i-1;
+                            }
+                            for(int x=0; x < deleteCount; x++) {
+                                this.toCacheKey.removeLastKey();
+                            }
+                            finished = false;
+                        } else {
+                            this.toCacheKey = null;
+                        }
+                        this.cacheCompleteResponse = false;
+                    } else {
+                        // the entry is invalid, remove it
+                        this.cache.remove(this.fromCacheKey);
+                    }
+
+                    // try a shorter key
+                    if (i > 0) {
+                        this.fromCacheKey.removeLastKey();
+                        if (!this.completeResponseIsCached) {
+                            this.firstProcessedTransformerIndex--;
+                        }
+                    } else {
+                        this.fromCacheKey = null;
+                    }
+                    finished = false;
+                    this.completeResponseIsCached = false;
+                }
+            } else {
+
+                // no cached response found
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug(
+                        "Cached response not found for '" + environment.getURI() +
+                        "' using key: " +  this.fromCacheKey
+                    );
+                }
+
+                if (!this.doSmartCaching) {
+                    // try a shorter key
+                    if (this.fromCacheKey.size() > 1) {
+                        this.fromCacheKey.removeLastKey();
+                        if (!this.completeResponseIsCached) {
+                            this.firstProcessedTransformerIndex--;
+                        }
+                        finished = false;
+                    } else {
+                        this.fromCacheKey = null;
+                    }
+                } else {
+                    // stop on longest key for smart caching
+                    this.fromCacheKey = null;
+                }
+                this.completeResponseIsCached = false;
+            }
+        }
+
+    }
+
+    /**
+     * Setup the evenet pipeline.
+     * The components of the pipeline are checked if they are
+     * Cacheable.
+     */
+    protected void setupPipeline(Environment environment)
+    throws ProcessingException {
+        super.setupPipeline( environment );
+
+        // generate the key to fill the cache
+        this.generateCachingKey(environment);
+
+        // test the cache for a valid response
+        if (this.toCacheKey != null) {
+            this.validatePipeline(environment);
+        }
+        this.setupValidities();
+    }
+
+    /**
+     * Connect the pipeline.
+     */
+    protected void connectPipeline(Environment   environment)
+    throws ProcessingException {
+        if (this.toCacheKey == null && this.cachedResponse == null) {
+            super.connectPipeline(environment);
+            return;
+        } else if (this.completeResponseIsCached) {
+            // do nothing
+            return;
+        } else {
+            this.connectCachingPipeline(environment);
+        }
+    }
+
+    /** Process the pipeline using a reader.
+     * @throws ProcessingException if an error occurs
+     */
+    protected boolean processReader(Environment  environment)
+    throws ProcessingException {
+        try {
+            boolean usedCache = false;
+            OutputStream outputStream = null;
+            SourceValidity readerValidity = null;
+            PipelineCacheKey pcKey = null;
+
+            // test if reader is cacheable
+            Serializable readerKey = null;
+            if (super.reader instanceof CacheableProcessingComponent) {
+                readerKey = ((CacheableProcessingComponent)super.reader).getKey();
+            }
+
+            if (readerKey != null) {
+                // response is cacheable, build the key
+                pcKey = new PipelineCacheKey();
+                pcKey.addKey(new ComponentCacheKey(ComponentCacheKey.ComponentType_Reader,
+                                                   this.readerRole,
+                                                   readerKey)
+                            );
+
+                // now we have the key to get the cached object
+                CachedResponse cachedObject = this.cache.get(pcKey);
+                if (cachedObject != null) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Found cached response for '" +
+                                          environment.getURI() + "' using key: " + pcKey);
+                    }
+
+                    SourceValidity[] validities = cachedObject.getValidityObjects();
+                    if (validities == null || validities.length != 1) {
+                        // to avoid getting here again and again, we delete it
+                        this.cache.remove(pcKey);
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Cached response for '" + environment.getURI() +
+                                              "' using key: " + pcKey + " is invalid.");
+                        }
+                        this.cachedResponse = null;
+                    } else {
+                        SourceValidity cachedValidity = validities[0];
+                        boolean isValid = false;
+                        int valid = cachedValidity.isValid();
+                        if (valid == SourceValidity.UNKNOWN) {
+                            // get reader validity and compare
+                            readerValidity = ((CacheableProcessingComponent) super.reader).getValidity();
+                            if (readerValidity != null) {
+                                valid = cachedValidity.isValid(readerValidity);
+                                if (valid == SourceValidity.UNKNOWN) {
+                                    readerValidity = null;
+                                } else {
+                                    isValid = (valid == SourceValidity.VALID);
+                                }
+                            }
+                        } else {
+                            isValid = (valid == SourceValidity.VALID);
+                        }
+
+                        if (isValid) {
+                            if (getLogger().isDebugEnabled()) {
+                                getLogger().debug("processReader: using valid cached content for '" +
+                                                  environment.getURI() + "'.");
+                            }
+                            byte[] response = cachedObject.getResponse();
+                            if (response.length > 0) {
+                                usedCache = true;
+                                if (cachedObject.getContentType() != null) {
+                                    environment.setContentType(cachedObject.getContentType());
+                                } else {
+                                    setMimeTypeForReader(environment);
+                                }
+                                outputStream = environment.getOutputStream(0);
+                                environment.setContentLength(response.length);
+                                outputStream.write(response);
+                            }
+                        } else {
+                            if (getLogger().isDebugEnabled()) {
+                                getLogger().debug("processReader: cached content is invalid for '" +
+                                                  environment.getURI() + "'.");
+                            }
+                            // remove invalid cached object
+                            this.cache.remove(pcKey);
+                        }
+                    }
+                }
+            }
+
+            if (!usedCache) {
+                if (pcKey != null) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("processReader: caching content for further requests of '" +
+                                          environment.getURI() + "'.");
+                    }
+
+                    if (readerValidity == null) {
+                        readerValidity = ((CacheableProcessingComponent)super.reader).getValidity();
+                    }
+
+                    if (readerValidity != null) {
+                        outputStream = environment.getOutputStream(this.outputBufferSize);
+                        outputStream = new CachingOutputStream(outputStream);
+                    } else {
+                        pcKey = null;
+                    }
+                }
+
+                setMimeTypeForReader(environment);
+                if (this.reader.shouldSetContentLength()) {
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    this.reader.setOutputStream(os);
+                    this.reader.generate();
+                    environment.setContentLength(os.size());
+                    if (outputStream == null) {
+                        outputStream = environment.getOutputStream(0);
+                    }
+                    os.writeTo(outputStream);
+                } else {
+                    if (outputStream == null) {
+                        outputStream = environment.getOutputStream(this.outputBufferSize);
+                    }
+                    this.reader.setOutputStream(outputStream);
+                    this.reader.generate();
+                }
+
+                // store the response
+                if (pcKey != null) {
+                    final CachedResponse res = new CachedResponse(new SourceValidity[] {readerValidity},
+                            ((CachingOutputStream)outputStream).getContent());
+                    res.setContentType(environment.getContentType());
+                    this.cache.store(pcKey, res);
+                }
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Return valid validity objects for the event pipeline.
+     *
+     * If the event pipeline (the complete pipeline without the
+     * serializer) is cacheable and valid, return all validity objects.
+     *
+     * Otherwise, return <code>null</code>.
+     */
+    public SourceValidity getValidityForEventPipeline() {
+        if (isInternalError()) {
+            return null;
+        }
+
+        if (this.cachedResponse != null) {
+            if (!this.cacheCompleteResponse &&
+                    this.firstNotCacheableTransformerIndex < super.transformers.size()) {
+                // Cache contains only partial pipeline.
+                return null;
+            }
+
+            if (this.toCacheSourceValidities != null) {
+                // This means the pipeline is valid based on the validities
+                // of the individual components
+                final AggregatedValidity validity = new AggregatedValidity();
+                for (int i=0; i < this.toCacheSourceValidities.length; i++) {
+                    validity.add(this.toCacheSourceValidities[i]);
+                }
+
+                return validity;
+            }
+
+            // This means that the pipeline is valid because it has not yet expired
+            return NOPValidity.SHARED_INSTANCE;
+        } else {
+            int vals = 0;
+
+            if (null != this.toCacheKey
+                    && !this.cacheCompleteResponse
+                    && this.firstNotCacheableTransformerIndex == super.transformers.size()) {
+                vals = this.toCacheKey.size();
+            } else if (null != this.fromCacheKey
+                    && !this.completeResponseIsCached
+                    && this.firstProcessedTransformerIndex == super.transformers.size()) {
+                vals = this.fromCacheKey.size();
+            }
+
+            if (vals > 0) {
+                final AggregatedValidity validity = new AggregatedValidity();
+                for (int i = 0; i < vals; i++) {
+                    validity.add(getValidityForInternalPipeline(i));
+                }
+
+                return validity;
+            }
+
+            return null;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.pipeline.ProcessingPipeline#getKeyForEventPipeline()
+     */
+    public String getKeyForEventPipeline() {
+        if (isInternalError()) {
+            return null;
+        }
+
+        if (null != this.toCacheKey
+             && !this.cacheCompleteResponse
+             && this.firstNotCacheableTransformerIndex == super.transformers.size()) {
+             return String.valueOf(HashUtil.hash(this.toCacheKey.toString()));
+        }
+        if (null != this.fromCacheKey
+             && !this.completeResponseIsCached
+             && this.firstProcessedTransformerIndex == super.transformers.size()) {
+            return String.valueOf(HashUtil.hash(this.fromCacheKey.toString()));
+        }
+
+        return null;
+    }
+
+    SourceValidity getValidityForInternalPipeline(int index) {
+        final SourceValidity validity;
+
+        // if debugging try to tell why something is not cacheable
+        final boolean debug = this.getLogger().isDebugEnabled();
+        String msg = null;
+        if(debug) msg = "getValidityForInternalPipeline(" + index + "): ";
+
+        if (index == 0) {
+            // test generator
+            validity = ((CacheableProcessingComponent)super.generator).getValidity();
+            if(debug) msg += "generator: using getValidity";
+        } else if (index <= firstNotCacheableTransformerIndex) {
+            // test transformer
+            final Transformer trans = (Transformer)super.transformers.get(index-1);
+            validity = ((CacheableProcessingComponent)trans).getValidity();
+            if(debug) msg += "transformer: using getValidity";
+        } else {
+            // test serializer
+            validity = ((CacheableProcessingComponent)super.serializer).getValidity();
+            if(debug) msg += "serializer: using getValidity";
+        }
+
+        if(debug) {
+            msg += ", validity==" + validity;
+            this.getLogger().debug(msg);
+        }
+        return validity;
+    }
+
+    /**
+     * Recyclable Interface
+     */
+    public void recycle() {
+
+        this.generatorRole = null;
+        this.transformerRoles.clear();
+        this.serializerRole = null;
+        this.readerRole = null;
+
+        this.fromCacheKey = null;
+        this.cachedResponse = null;
+
+        this.toCacheKey = null;
+        this.toCacheSourceValidities = null;
+
+        super.recycle();
+    }
+}
+
+final class DeferredPipelineValidity implements DeferredValidity {
+
+    private final AbstractCachingProcessingPipeline pipeline;
+    private final int index;
+
+    public DeferredPipelineValidity(AbstractCachingProcessingPipeline pipeline, int index) {
+        this.pipeline = pipeline;
+        this.index = index;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.impl.validity.DeferredValidity#getValidity()
+     */
+    public SourceValidity getValidity() {
+        return pipeline.getValidityForInternalPipeline(this.index);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/BaseCachingProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/BaseCachingProcessingPipeline.java
new file mode 100644
index 0000000..a18e873
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/BaseCachingProcessingPipeline.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.caching.Cache;
+import org.apache.cocoon.components.pipeline.AbstractProcessingPipeline;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+
+/**
+ * This is the base class for all caching pipeline implementations.
+ * The pipeline can be configured with the {@link Cache} to use
+ * by specifying the <code>cache-role</code> parameter.
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public abstract class BaseCachingProcessingPipeline extends AbstractProcessingPipeline
+                                                    implements Disposable {
+
+    /** This is the Cache holding cached responses */
+    protected Cache  cache;
+
+    /** The deserializer */
+    protected XMLByteStreamInterpreter xmlDeserializer;
+
+    /** The serializer */
+    protected XMLByteStreamCompiler xmlSerializer;
+
+    /**
+     * Parameterizable Interface - Configuration
+     */
+    public void parameterize(Parameters params)
+    throws ParameterException {
+        super.parameterize(params);
+
+        String cacheRole = params.getParameter("cache-role", Cache.ROLE);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Using cache " + cacheRole);
+        }
+
+        try {
+            this.cache = (Cache) this.manager.lookup(cacheRole);
+        } catch (ServiceException ce) {
+            throw new ParameterException("Unable to lookup cache: " + cacheRole, ce);
+        }
+    }
+
+    /**
+     * Recyclable Interface
+     */
+    public void recycle() {
+        this.xmlDeserializer = null;
+        this.xmlSerializer = null;
+
+        super.recycle();
+    }
+
+    /**
+     * Disposable Interface
+     */
+    public void dispose() {
+        if (null != this.manager) {
+            this.manager.release(this.cache);
+        }
+        this.cache = null;
+        this.manager = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingPointProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingPointProcessingPipeline.java
new file mode 100644
index 0000000..9c61723
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingPointProcessingPipeline.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.cocoon.caching.CachingOutputStream;
+import org.apache.cocoon.caching.ComponentCacheKey;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+import org.apache.cocoon.components.sax.XMLTeePipe;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+import org.apache.excalibur.source.SourceValidity;
+
+/**
+ * The CachingPointProcessingPipeline
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class CachingPointProcessingPipeline
+    extends AbstractCachingProcessingPipeline {
+
+    protected ArrayList isCachePoint = new ArrayList();
+    protected ArrayList xmlSerializerArray = new ArrayList();
+    protected boolean nextIsCachePoint = false;
+    protected String autoCachingPointSwitch;
+    protected boolean autoCachingPoint = true;
+
+
+   /**
+    * The <code>CachingPointProcessingPipeline</code> is configurable.
+    * The autoCachingPoint algorithm can be switced on/off
+    * in the sitemap.xmap
+    */
+    public void parameterize(Parameters config) throws ParameterException {
+        super.parameterize(config);
+        this.autoCachingPointSwitch = config.getParameter("autoCachingPoint", null);
+
+        if (this.getLogger().isDebugEnabled()) {
+            getLogger().debug("Auto caching-point is set to = '" + this.autoCachingPointSwitch + "'");
+        }
+
+        // Default is that auto caching-point is on
+        if (this.autoCachingPointSwitch == null){
+            this.autoCachingPoint=true;
+            return;
+        }
+
+        if (this.autoCachingPointSwitch.toLowerCase().equals("on")) {
+            this.autoCachingPoint=true;
+        } else {
+            this.autoCachingPoint=false;
+        }
+    }
+
+    /**
+     * Set the generator.
+     */
+    public void setGenerator (String role, String source, Parameters param, Parameters hintParam)
+    throws ProcessingException {
+        super.setGenerator(role, source, param, hintParam);
+
+        // check the hint param for a "caching-point" hint
+        String pipelinehint = null;
+        try {
+            pipelinehint = hintParam.getParameter("caching-point", null);
+
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("generator caching-point pipeline-hint is set to: " + pipelinehint);
+            }
+        } catch (Exception ex) {
+            if (this.getLogger().isWarnEnabled()) {
+                getLogger().warn("caching-point hint Exception, pipeline-hint ignored: " + ex);
+            }
+        }
+
+        // if this generator is manually set to "caching-point" (via pipeline-hint)
+        // then ensure the next component is caching.
+        if ( "true".equals(pipelinehint)) {
+            this.nextIsCachePoint=true;
+        }
+    }
+
+
+    /**
+     * Add a transformer.
+     */
+    public void addTransformer (String role, String source, Parameters param,  Parameters hintParam)
+    throws ProcessingException {
+        super.addTransformer(role, source, param, hintParam);
+
+        // check the hint param for a "caching-point" hint
+        String pipelinehint = null;
+        try {
+            pipelinehint = hintParam.getParameter("caching-point", null);
+
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("transformer caching-point pipeline-hint is set to: " + pipelinehint);
+            }
+        } catch (Exception ex) {
+            if (this.getLogger().isWarnEnabled()) {
+                getLogger().warn("caching-point hint Exception, pipeline-hint ignored: " + ex);
+            }
+        }
+
+        // add caching point flag
+        // default value is false
+        this.isCachePoint.add(new Boolean(this.nextIsCachePoint));
+        this.nextIsCachePoint = false;
+
+        // if this transformer is manually set to "caching-point" (via pipeline-hint)
+        // then ensure the next component is caching.
+        if ( "true".equals(pipelinehint)) {
+            this.nextIsCachePoint=true;
+        }
+    }
+
+
+    /**
+     * Determine if the given branch-point
+     * is a caching-point
+     *
+     * Please Note: this method is used by auto caching-point
+     * and is of no consequence when auto caching-point is switched off
+     */
+    public void informBranchPoint() {
+
+        if (this.generator == null) {
+            return;
+        }
+        if (!this.autoCachingPoint) {
+            return;
+        }
+
+        this.nextIsCachePoint = true;
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Informed Pipeline of branch point");
+        }
+    }
+
+    /**
+     * Cache longest cacheable path plus cache points.
+     */
+    protected void cacheResults(Environment environment, OutputStream os)  throws Exception {
+
+        if (this.toCacheKey != null) {
+            if ( this.cacheCompleteResponse ) {
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Cached: caching complete response; pSisze"
+                                           + this.toCacheKey.size() + " Key " + this.toCacheKey);
+                }
+                CachedResponse response = new CachedResponse(this.toCacheSourceValidities,
+                                          ((CachingOutputStream)os).getContent());
+                response.setContentType(environment.getContentType());
+                this.cache.store(this.toCacheKey.copy(),
+                                 response);
+                //
+                // Scan back along the pipelineCacheKey for
+                // for any cachepoint(s)
+                //
+                this.toCacheKey.removeUntilCachePoint();
+
+                //
+                // adjust the validities object
+                // to reflect the new length of the pipeline cache key.
+                //
+                // REVISIT: Is it enough to simply reduce the length of the validities array?
+                //
+                if (this.toCacheKey.size()>0) {
+                    SourceValidity[] copy = new SourceValidity[this.toCacheKey.size()];
+                    System.arraycopy(this.toCacheSourceValidities, 0,
+                                     copy, 0, copy.length);
+                    this.toCacheSourceValidities = copy;
+                }
+            }
+
+            if (this.toCacheKey.size()>0) {
+                ListIterator itt = this.xmlSerializerArray.listIterator(this.xmlSerializerArray.size());
+                while (itt.hasPrevious()) {
+                    XMLByteStreamCompiler serializer = (XMLByteStreamCompiler) itt.previous();
+                    CachedResponse response = new CachedResponse(this.toCacheSourceValidities,
+                                              (byte[])serializer.getSAXFragment());
+                    this.cache.store(this.toCacheKey.copy(),
+                                     response);
+
+                    if (this.getLogger().isDebugEnabled()) {
+                        this.getLogger().debug("Caching results for the following key: "
+                            + this.toCacheKey);
+                    }
+
+                    //
+                    // Check for further cachepoints
+                    //
+                    toCacheKey.removeUntilCachePoint();
+                    if (this.toCacheKey.size()==0)
+                        // no cachePoint found in key
+                        break;
+
+                    //
+                    // re-calculate validities array
+                    //
+                    SourceValidity[] copy = new SourceValidity[this.toCacheKey.size()];
+                    System.arraycopy(this.toCacheSourceValidities, 0,
+                                     copy, 0, copy.length);
+                    this.toCacheSourceValidities = copy;
+                } //end serializer loop
+
+            }
+        }
+    }
+
+    /**
+     * Create a new ComponentCachekey
+     * ComponentCacheKeys can be flagged as cachepoints
+     */
+    protected ComponentCacheKey newComponentCacheKey(int type, String role,Serializable key) {
+        boolean cachePoint = false;
+
+        if (type == ComponentCacheKey.ComponentType_Transformer) {
+            cachePoint =
+                ((Boolean)this.isCachePoint.get(this.firstNotCacheableTransformerIndex)).booleanValue();
+        } else if (type == ComponentCacheKey.ComponentType_Serializer) {
+            cachePoint = this.nextIsCachePoint;
+        }
+
+        return new ComponentCacheKey(type, role, key, cachePoint);
+    }
+
+
+    /**
+     * Connect the caching point pipeline.
+     */
+    protected void connectCachingPipeline(Environment   environment)
+    throws ProcessingException {
+        XMLByteStreamCompiler localXMLSerializer = null;
+        XMLByteStreamCompiler cachePointXMLSerializer = null;
+        if (!this.cacheCompleteResponse) {
+            this.xmlSerializer = new XMLByteStreamCompiler();
+            localXMLSerializer = this.xmlSerializer;
+        }
+
+        if (this.cachedResponse == null) {
+            XMLProducer prev = super.generator;
+            XMLConsumer next;
+
+            int cacheableTransformerCount = this.firstNotCacheableTransformerIndex;
+            int currentTransformerIndex = 0; //start with the first transformer
+
+            Iterator itt = this.transformers.iterator();
+            while ( itt.hasNext() ) {
+                next = (XMLConsumer) itt.next();
+
+                // if we have cacheable transformers,
+                // check the tranformers for cachepoints
+                if (cacheableTransformerCount > 0) {
+                    if ( (this.isCachePoint.get(currentTransformerIndex) != null)  &&
+                            ((Boolean)this.isCachePoint.get(currentTransformerIndex)).booleanValue()) {
+
+                        cachePointXMLSerializer = new XMLByteStreamCompiler();
+                        next = new XMLTeePipe(next, cachePointXMLSerializer);
+                        this.xmlSerializerArray.add(cachePointXMLSerializer);
+                    }
+                }
+
+
+                // Serializer is not cacheable,
+                // but we  have the longest cacheable key. Do default longest key caching
+                if (localXMLSerializer != null) {
+                    if (cacheableTransformerCount == 0) {
+                        next = new XMLTeePipe(next, localXMLSerializer);
+                        this.xmlSerializerArray.add(localXMLSerializer);
+                        localXMLSerializer = null;
+                    } else {
+                        cacheableTransformerCount--;
+                    }
+                }
+                this.connect(environment, prev, next);
+                prev = (XMLProducer) next;
+
+                currentTransformerIndex++;
+            }
+            next = super.lastConsumer;
+
+
+            // if the serializer is not cacheable, but all the transformers are:
+            // (this is default longest key caching)
+            if (localXMLSerializer != null) {
+                next = new XMLTeePipe(next, localXMLSerializer);
+                this.xmlSerializerArray.add(localXMLSerializer);
+                localXMLSerializer = null;
+            }
+
+            // else if the serializer is cacheable and has cocoon views
+            else if ((currentTransformerIndex == this.firstNotCacheableTransformerIndex) &&
+                    this.nextIsCachePoint) {
+                cachePointXMLSerializer = new XMLByteStreamCompiler();
+                next = new XMLTeePipe(next, cachePointXMLSerializer);
+                this.xmlSerializerArray.add(cachePointXMLSerializer);
+            }
+            this.connect(environment, prev, next);
+
+        } else {
+            // Here the first part of the pipeline has been retrived from cache
+            // we now check if any part of the rest of the pipeline can be cached
+            this.xmlDeserializer = new XMLByteStreamInterpreter();
+            // connect the pipeline:
+            XMLProducer prev = xmlDeserializer;
+            XMLConsumer next;
+            int cacheableTransformerCount = 0;
+            Iterator itt = this.transformers.iterator();
+            while ( itt.hasNext() ) {
+                next = (XMLConsumer) itt.next();
+
+                if (cacheableTransformerCount >= this.firstProcessedTransformerIndex) {
+
+                    // if we have cacheable transformers left,
+                    // then check the tranformers for cachepoints
+                    if (cacheableTransformerCount < this.firstNotCacheableTransformerIndex) {
+                        if ( !(prev instanceof XMLByteStreamInterpreter) &&
+                                (this.isCachePoint.get(cacheableTransformerCount) != null)  &&
+                                ((Boolean)this.isCachePoint.get(cacheableTransformerCount)).booleanValue()) {
+                            cachePointXMLSerializer = new XMLByteStreamCompiler();
+                            next = new XMLTeePipe(next, cachePointXMLSerializer);
+                            this.xmlSerializerArray.add(cachePointXMLSerializer);
+                        }
+                    }
+
+                    // Serializer is not cacheable,
+                    // but we  have the longest cacheable key. Do default longest key caching
+                    if (localXMLSerializer != null && !(prev instanceof XMLByteStreamInterpreter)
+                            && cacheableTransformerCount == this.firstNotCacheableTransformerIndex) {
+                        next = new XMLTeePipe(next, localXMLSerializer);
+                        this.xmlSerializerArray.add(localXMLSerializer);
+                        localXMLSerializer = null;
+                    }
+                    this.connect(environment, prev, next);
+                    prev = (XMLProducer)next;
+                }
+                cacheableTransformerCount++;
+            }
+            next = super.lastConsumer;
+
+            //*all* the transformers are cacheable, but the serializer is not!! this is longest key
+            if (localXMLSerializer != null && !(prev instanceof XMLByteStreamInterpreter)) {
+                next = new XMLTeePipe(next, localXMLSerializer);
+                this.xmlSerializerArray.add(localXMLSerializer);
+                localXMLSerializer = null;
+            } else if (this.nextIsCachePoint && !(prev instanceof XMLByteStreamInterpreter) &&
+                    cacheableTransformerCount == this.firstNotCacheableTransformerIndex) {
+                // else the serializer is cacheable but has views
+                cachePointXMLSerializer = new XMLByteStreamCompiler();
+                next = new XMLTeePipe(next,  cachePointXMLSerializer);
+                this.xmlSerializerArray.add(cachePointXMLSerializer);
+            }
+            this.connect(environment, prev, next);
+        }
+    }
+
+
+    /**
+     * Recyclable Interface
+     */
+    public void recycle() {
+        super.recycle();
+
+        Iterator itt = this.xmlSerializerArray.iterator();
+        while (itt.hasNext()) {
+            this.manager.release(itt.next());
+        }
+
+        this.isCachePoint.clear();
+        this.xmlSerializerArray.clear();
+        this.nextIsCachePoint = false;
+        this.autoCachingPointSwitch=null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingProcessingPipeline.java
new file mode 100644
index 0000000..1cf2ba0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/CachingProcessingPipeline.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.cocoon.caching.CachingOutputStream;
+import org.apache.cocoon.caching.ComponentCacheKey;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+import org.apache.cocoon.components.sax.XMLTeePipe;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+
+/**
+ * The CachingProcessingPipeline
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class CachingProcessingPipeline extends AbstractCachingProcessingPipeline {
+
+    /**
+    * Cache longest cacheable key
+    */
+    protected void cacheResults(Environment environment, OutputStream os)  throws Exception {
+        if (this.toCacheKey != null) {
+            // See if there is an expires object for this resource.
+            Long expiresObj = (Long) environment.getObjectModel().get(ObjectModelHelper.EXPIRES_OBJECT);
+
+            CachedResponse response;
+            if (this.cacheCompleteResponse) {
+                response = new CachedResponse(this.toCacheSourceValidities,
+                                              ((CachingOutputStream) os).getContent(),
+                                              expiresObj);
+                response.setContentType(environment.getContentType());
+            } else {
+                response = new CachedResponse(this.toCacheSourceValidities,
+                                              (byte[]) this.xmlSerializer.getSAXFragment(),
+                                              expiresObj);
+            }
+
+            this.cache.store(this.toCacheKey, response);
+        }
+    }
+
+    /**
+     * Create a new cache key
+     */
+    protected ComponentCacheKey newComponentCacheKey(int type, String role,Serializable key) {
+        return new ComponentCacheKey(type, role, key);
+    }
+
+    /**
+     * Connect the pipeline.
+     */
+    protected void connectCachingPipeline(Environment   environment)
+    throws ProcessingException {
+        XMLByteStreamCompiler localXMLSerializer = null;
+        if (!this.cacheCompleteResponse) {
+            this.xmlSerializer = new XMLByteStreamCompiler();
+            localXMLSerializer = this.xmlSerializer;
+        }
+
+        if (this.cachedResponse == null) {
+            XMLProducer prev = super.generator;
+            XMLConsumer next;
+
+            int cacheableTransformerCount = this.firstNotCacheableTransformerIndex;
+
+            Iterator itt = this.transformers.iterator();
+            while (itt.hasNext()) {
+                next = (XMLConsumer) itt.next();
+                if (localXMLSerializer != null) {
+                    if (cacheableTransformerCount == 0) {
+                        next = new XMLTeePipe(next, localXMLSerializer);
+                        localXMLSerializer = null;
+                    } else {
+                        cacheableTransformerCount--;
+                    }
+                }
+                connect(environment, prev, next);
+                prev = (XMLProducer) next;
+            }
+
+            next = super.lastConsumer;
+            if (localXMLSerializer != null) {
+                next = new XMLTeePipe(next, localXMLSerializer);
+                localXMLSerializer = null;
+            }
+            connect(environment, prev, next);
+        } else {
+            this.xmlDeserializer = new XMLByteStreamInterpreter();
+
+            // connect the pipeline:
+            XMLProducer prev = xmlDeserializer;
+            XMLConsumer next;
+            int cacheableTransformerCount = 0;
+            Iterator itt = this.transformers.iterator();
+            while (itt.hasNext()) {
+                next = (XMLConsumer) itt.next();
+                if (cacheableTransformerCount >= this.firstProcessedTransformerIndex) {
+                    if (localXMLSerializer != null
+                            && cacheableTransformerCount == this.firstNotCacheableTransformerIndex) {
+                        next = new XMLTeePipe(next, localXMLSerializer);
+                        localXMLSerializer = null;
+                    }
+                    connect(environment, prev, next);
+                    prev = (XMLProducer) next;
+                }
+                cacheableTransformerCount++;
+            }
+
+            next = super.lastConsumer;
+            if (localXMLSerializer != null) {
+                next = new XMLTeePipe(next, localXMLSerializer);
+                localXMLSerializer = null;
+            }
+            connect(environment, prev, next);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/ExpiresCachingProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/ExpiresCachingProcessingPipeline.java
new file mode 100644
index 0000000..4dc74cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/ExpiresCachingProcessingPipeline.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.cocoon.caching.CachingOutputStream;
+import org.apache.cocoon.caching.IdentifierCacheKey;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+import org.apache.cocoon.components.sax.XMLTeePipe;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.xml.XMLConsumer;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.ExpiresValidity;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+/**
+ * This pipeline implementation caches the complete content for a defined
+ * period of time (expires).
+ *
+ * <map:pipe name="expires" src="org.apache.cocoon.components.pipeline.impl.ExpiresCachingProcessingPipeline">
+ *   <parameter name="cache-expires" value="180"/> <!-- Expires in secondes -->
+ * </map:pipe>
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class ExpiresCachingProcessingPipeline
+    extends BaseCachingProcessingPipeline {
+
+    /** This key can be used to put a key in the object model */
+    public static final String CACHE_KEY_KEY = ExpiresCachingProcessingPipeline.class.getName() + "/CacheKey";
+
+    /** This key can be used to put an expires information in the object model */
+    public static final String CACHE_EXPIRES_KEY = ExpiresCachingProcessingPipeline.class.getName() + "/Expires";
+
+    /** The source validity */
+    protected SourceValidity cacheValidity;
+
+    /** The key used for caching */
+    protected IdentifierCacheKey cacheKey;
+
+    /** The expires information */
+    protected long cacheExpires;
+
+    /** Default value for expiration */
+    protected long defaultCacheExpires = 3600; // 1 hour
+
+    /** The cached response */
+    protected CachedResponse cachedResponse;
+
+    public void parameterize(Parameters params)
+    throws ParameterException {
+        super.parameterize(params);
+
+        this.defaultCacheExpires = params.getParameterAsLong("cache-expires", this.defaultCacheExpires);
+    }
+
+    /**
+     * Process the given <code>Environment</code>, producing the output.
+     */
+    protected boolean processXMLPipeline(Environment environment)
+    throws ProcessingException {
+        try {
+            if (this.cachedResponse != null) {
+                byte[] content = cachedResponse.getResponse();
+
+                if ( this.serializer == this.lastConsumer ) {
+                    if ( cachedResponse.getContentType() != null ) {
+                        environment.setContentType(cachedResponse.getContentType());
+                    } else {
+                        this.setMimeTypeForSerializer(environment);
+                    }
+                    final OutputStream outputStream = environment.getOutputStream(0);
+                    if (content.length > 0) {
+                        environment.setContentLength(content.length);
+                        outputStream.write(content);
+                    }
+                } else {
+                    this.setMimeTypeForSerializer(environment);
+                    this.xmlDeserializer.setConsumer( this.lastConsumer );
+                    this.xmlDeserializer.deserialize( content );
+                }
+
+            } else {
+
+                // generate new response
+
+                if ( this.cacheExpires == 0 ) {
+                    return super.processXMLPipeline( environment );
+                }
+
+                this.setMimeTypeForSerializer(environment);
+                byte[] cachedData;
+                if ( this.serializer == this.lastConsumer ) {
+
+                    if (this.serializer.shouldSetContentLength()) {
+                        OutputStream os = environment.getOutputStream(this.outputBufferSize);
+
+                        // set the output stream
+                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                        this.serializer.setOutputStream(baos);
+
+                        this.generator.generate();
+
+                        cachedData = baos.toByteArray();
+                        environment.setContentLength(cachedData.length);
+                        os.write(cachedData);
+                    } else {
+                        CachingOutputStream os = new CachingOutputStream( environment.getOutputStream(this.outputBufferSize) );
+                        // set the output stream
+                        this.serializer.setOutputStream( os );
+                        this.generator.generate();
+
+                        cachedData = os.getContent();
+                    }
+
+                } else {
+                    this.generator.generate();
+                    cachedData = (byte[])this.xmlSerializer.getSAXFragment();
+                }
+
+                //
+                // Now that we have processed the pipeline,
+                // we do the actual caching
+                //
+                if (this.cacheValidity != null) {
+                    cachedResponse = new CachedResponse(this.cacheValidity,
+                                                        cachedData);
+                    cachedResponse.setContentType(environment.getContentType());
+                    this.cache.store(this.cacheKey, cachedResponse);
+                }
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Connect the XML pipeline.
+     */
+    protected void connectPipeline(Environment environment)
+    throws ProcessingException {
+        if ( this.lastConsumer != this.serializer ) {
+            // internal
+            if ( this.cachedResponse == null) {
+                // if we cache, we need an xml serializer
+                if ( this.cacheExpires > 0) {
+                    final XMLConsumer old = this.lastConsumer;
+                    this.xmlSerializer = new XMLByteStreamCompiler();
+                    this.lastConsumer = new XMLTeePipe(this.lastConsumer, this.xmlSerializer);
+
+                    super.connectPipeline( environment );
+
+                    this.lastConsumer = old;
+                } else {
+                    super.connectPipeline( environment );
+                }
+            } else {
+                // we use the cache, so we need an xml deserializer
+                this.xmlDeserializer = new XMLByteStreamInterpreter();
+            }
+        } else {
+            // external: we only need to connect if we don't use a cached response
+            if ( this.cachedResponse == null) {
+                super.connectPipeline( environment );
+            }
+        }
+    }
+
+    /**
+     * Prepare the pipeline
+     */
+    protected void preparePipeline(Environment environment)
+    throws ProcessingException {
+        // get the key and the expires info
+        // we must do this before we call super.preparePipeline,
+        // otherwise internal pipelines are instantiated and
+        // get a copy of the object model with our info!
+        final Map objectModel = environment.getObjectModel();
+        String key = (String)objectModel.get(CACHE_KEY_KEY);
+        if ( key == null ) {
+            key = this.parameters.getParameter("cache-key", null);
+            if ( key == null ) {
+                key = environment.getURIPrefix()+environment.getURI();
+            }
+        } else {
+            objectModel.remove(CACHE_KEY_KEY);
+        }
+        String expiresValue = (String)objectModel.get(CACHE_EXPIRES_KEY);
+        if ( expiresValue == null ) {
+            this.cacheExpires = this.parameters.getParameterAsLong("cache-expires", this.defaultCacheExpires);
+        } else {
+            this.cacheExpires = Long.valueOf(expiresValue).longValue();
+            objectModel.remove(CACHE_EXPIRES_KEY);
+        }
+
+        // prepare the pipeline
+        super.preparePipeline( environment );
+
+        // and now prepare the caching information
+        this.cacheKey = new IdentifierCacheKey(key,
+                                           this.serializer == this.lastConsumer);
+        if ( this.cacheExpires > 0) {
+            this.cacheValidity = new ExpiresValidity(this.cacheExpires*1000);
+        }
+        final boolean purge = this.parameters.getParameterAsBoolean("purge-cache", false);
+
+        this.cachedResponse = this.cache.get(this.cacheKey);
+        if ( this.cachedResponse != null ) {
+            final SourceValidity sv = cachedResponse.getValidityObjects()[0];
+            if ( purge
+                 || (this.cacheExpires != -1 && sv.isValid() != SourceValidity.VALID) ) {
+                this.cache.remove( this.cacheKey );
+                this.cachedResponse = null;
+            }
+        }
+        if ( this.cacheExpires > 0
+             && (this.reader != null || this.lastConsumer == this.serializer )) {
+            Response res = ObjectModelHelper.getResponse(environment.getObjectModel());
+            res.setDateHeader("Expires", System.currentTimeMillis() + (this.cacheExpires*1000));
+            res.setHeader("Cache-Control", "max-age=" + this.cacheExpires + ", public");
+        }
+    }
+
+    /**
+     * Return valid validity objects for the event pipeline
+     * If the "event pipeline" (= the complete pipeline without the
+     * serializer) is cacheable and valid, return all validity objects.
+     * Otherwise return <code>null</code>
+     */
+    public SourceValidity getValidityForEventPipeline() {
+        return this.cacheValidity;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.pipeline.ProcessingPipeline#getKeyForEventPipeline()
+     */
+    public String getKeyForEventPipeline() {
+        if (this.cacheKey != null && this.cacheValidity != null) {
+            return this.cacheKey.toString();
+        }
+        return null;
+    }
+
+    /**
+     * Recyclable Interface
+     */
+    public void recycle() {
+        this.cacheKey = null;
+        this.cacheExpires = 0;
+        this.cachedResponse = null;
+        super.recycle();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#processReader(org.apache.cocoon.environment.Environment)
+     */
+    protected boolean processReader(Environment environment)
+    throws ProcessingException {
+        try {
+            if (this.cachedResponse != null) {
+                if ( cachedResponse.getContentType() != null ) {
+                    environment.setContentType(cachedResponse.getContentType());
+                } else {
+                    this.setMimeTypeForReader(environment);
+                }
+
+                final byte[] content = cachedResponse.getResponse();
+                environment.setContentLength(content.length);
+
+                final OutputStream os = environment.getOutputStream(0);
+                os.write(content);
+
+            } else {
+                // generate new response
+
+                if ( this.cacheExpires == 0 ) {
+                    return super.processReader( environment );
+                }
+
+                byte[] cachedData;
+
+                this.setMimeTypeForReader(environment);
+                if (this.reader.shouldSetContentLength()) {
+                    final OutputStream os = environment.getOutputStream(this.outputBufferSize);
+
+                    // set the output stream
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    this.reader.setOutputStream(baos);
+
+                    this.reader.generate();
+
+                    cachedData = baos.toByteArray();
+                    environment.setContentLength(cachedData.length);
+                    os.write(cachedData);
+                } else {
+                    final CachingOutputStream os = new CachingOutputStream( environment.getOutputStream(this.outputBufferSize) );
+                    // set the output stream
+                    this.reader.setOutputStream( os );
+                    this.reader.generate();
+
+                    cachedData = os.getContent();
+                }
+
+                //
+                // Now that we have processed the pipeline,
+                // we do the actual caching
+                //
+                if (this.cacheValidity != null) {
+                    cachedResponse = new CachedResponse(this.cacheValidity,
+                                                        cachedData);
+                    cachedResponse.setContentType(environment.getContentType());
+                    this.cache.store(this.cacheKey, cachedResponse);
+                }
+            }
+        } catch (Exception e) {
+            handleException(e);
+        }
+
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/NonCachingProcessingPipeline.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/NonCachingProcessingPipeline.java
new file mode 100644
index 0000000..ab128a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/pipeline/impl/NonCachingProcessingPipeline.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.pipeline.impl;
+
+import org.apache.cocoon.components.pipeline.AbstractProcessingPipeline;
+
+/**
+ * Thi is the implementation of the non caching processing pipeline
+ *
+ * @version $Id$
+ */
+public class NonCachingProcessingPipeline
+       extends AbstractProcessingPipeline {
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/DefaultResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/DefaultResolver.java
new file mode 100644
index 0000000..d7420df
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/DefaultResolver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.resolver;
+
+import org.apache.excalibur.xml.DefaultEntityResolver;
+
+
+/**
+ * A component that uses catalogs for resolving entities.
+ * This component simply inherits from the excalibur implementation and
+ * adds the context: protocol to each relative uri.
+ *
+ * The catalog is by default loaded from "WEB-INF/entities/catalog".
+ * This can be configured by the "catalog" parameter in the cocoon.xconf:
+ * &lt;entity-resolver&gt;
+ *   &lt;parameter name="catalog" value="mycatalog"/&gt;
+ * &lt;/entity-resolver&gt;
+ * 
+ * @version $Id$
+ * @since 2.1
+ */
+public class DefaultResolver
+  extends DefaultEntityResolver {
+
+    /**
+     * Parse a catalog
+     */
+    protected void parseCatalog(String uri) {
+        // check for relative URIs
+        //   if the URI has ':/' then it's a URI
+        //   if the URI starts with '/ it's an absolute (UNIX) path
+        //   if the URI has a ':' at position 1, it's an absolute windows path
+        // otherwise we have a relative URI, that is resolved relative
+        // to the context
+        if (uri.indexOf(":/") == -1 
+            && !uri.startsWith("/") 
+            && !(uri.length() > 1 && uri.charAt(1) == ':')) {
+                uri = "context://" + uri;
+        }
+        super.parseCatalog( uri );
+    }
+    
+    /**
+     * Default catalog path
+     */
+    protected String defaultCatalog() {
+        return "WEB-INF/entities/catalog";
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/package.html
new file mode 100644
index 0000000..cb50a5e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/resolver/package.html
@@ -0,0 +1,33 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+  <title>Catalog Entity Resolver</title>
+</head>
+<body>
+  <h1>Catalog Entity Resolver</h1>
+  <p>
+    A component that uses entity catalogs for resolving external entities.
+    It sets the entity resolver onto the hook provided by the SAX parser,
+    and then handles the resolveEntity() requests.
+  </p>
+  <p>
+    This implementation uses the XML Entity and URI Resolvers
+    published by Norman Walsh at
+    <a href="http://xml.apache.org/commons/">Apache XML Commons</a>
+  </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/DocumentLocatorException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/DocumentLocatorException.java
new file mode 100644
index 0000000..6dc1cd0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/DocumentLocatorException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.sax;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+public final class DocumentLocatorException extends CascadingRuntimeException
+{
+    public DocumentLocatorException(String message)
+    {
+        super(message, null);
+    }
+
+    public DocumentLocatorException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamCompiler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamCompiler.java
new file mode 100644
index 0000000..1ee08db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamCompiler.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.sax;
+
+import java.util.HashMap;
+
+import org.apache.cocoon.xml.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * This a simple xml compiler which outputs a byte array.
+ * If you want to reuse this instance, make sure to call {@link #recycle()}
+ * inbetween two compilation tasks.
+ *
+ * @version $Id$
+ */
+public final class XMLByteStreamCompiler implements XMLConsumer {
+
+    private HashMap map;
+    private int mapCount;
+
+    /** The buffer for the compile xml byte stream. */
+    private byte buf[];
+
+    /** The number of valid bytes in the buffer. */
+    private int bufCount;
+
+    private int bufCountAverage;
+
+
+    public XMLByteStreamCompiler() {
+        this.map = new HashMap();
+        this.bufCountAverage = 2000;
+        this.initOutput();
+    }
+
+    private void initOutput() {
+        this.mapCount = 0;
+        this.map.clear();
+        this.buf = new byte[bufCountAverage];
+        this.buf[0] = (byte)'C';
+        this.buf[1] = (byte)'X';
+        this.buf[2] = (byte)'M';
+        this.buf[3] = (byte)'L';
+        this.buf[4] = (byte)1;
+        this.buf[5] = (byte)0;
+        this.bufCount = 6;
+    }
+
+    public void recycle() {
+        bufCountAverage = (bufCountAverage + bufCount) / 2;
+        this.initOutput();
+    }
+
+    private static final int START_DOCUMENT         = 0;
+    private static final int END_DOCUMENT           = 1;
+    private static final int START_PREFIX_MAPPING   = 2;
+    private static final int END_PREFIX_MAPPING     = 3;
+    private static final int START_ELEMENT          = 4;
+    private static final int END_ELEMENT            = 5;
+    private static final int CHARACTERS             = 6;
+    private static final int IGNORABLE_WHITESPACE   = 7;
+    private static final int PROCESSING_INSTRUCTION = 8;
+    private static final int COMMENT                = 9;
+    private static final int LOCATOR                = 10;
+    private static final int START_DTD              = 11;
+    private static final int END_DTD                = 12;
+    private static final int START_CDATA            = 13;
+    private static final int END_CDATA              = 14;
+    private static final int SKIPPED_ENTITY         = 15;
+    private static final int START_ENTITY           = 16;
+    private static final int END_ENTITY             = 17;
+
+
+    public Object getSAXFragment() {
+        if (this.bufCount == 6) { // no event arrived yet
+            return null;
+        }
+        byte newbuf[] = new byte[this.bufCount];
+        System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+        return newbuf;
+    }
+
+    public void startDocument() throws SAXException {
+        this.writeEvent(START_DOCUMENT);
+    }
+
+    public void endDocument() throws SAXException {
+        this.writeEvent(END_DOCUMENT);
+    }
+
+    public void startPrefixMapping(java.lang.String prefix, java.lang.String uri) throws SAXException {
+        this.writeEvent(START_PREFIX_MAPPING);
+        this.writeString(prefix);
+        this.writeString(uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+       this.writeEvent(END_PREFIX_MAPPING);
+       this.writeString(prefix);
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+        int length = atts.getLength();
+        this.writeEvent(START_ELEMENT);
+        this.writeAttributes(length);
+        for (int i = 0; i < length; i++) {
+            this.writeString(atts.getURI(i));
+            this.writeString(atts.getLocalName(i));
+            this.writeString(atts.getQName(i));
+            this.writeString(atts.getType(i));
+            this.writeString(atts.getValue(i));
+         }
+         this.writeString((namespaceURI == null ? "" : namespaceURI));
+         this.writeString(localName);
+         this.writeString(qName);
+     }
+
+    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+        this.writeEvent(END_ELEMENT);
+        this.writeString((namespaceURI == null ? "" : namespaceURI));
+        this.writeString(localName);
+        this.writeString(qName);
+    }
+
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        this.writeEvent(CHARACTERS);
+        this.writeChars(ch, start, length);
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+        this.writeEvent(IGNORABLE_WHITESPACE);
+        this.writeChars(ch, start, length);
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        this.writeEvent(PROCESSING_INSTRUCTION);
+        this.writeString(target);
+        this.writeString(data);
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        try {
+            this.writeEvent(LOCATOR);
+            String publicId = locator.getPublicId();
+            String systemId = locator.getSystemId();
+            this.writeString(publicId!=null?publicId:"");
+            this.writeString(systemId!=null?systemId:"");
+            this.write(locator.getLineNumber());
+            this.write(locator.getColumnNumber());
+        } catch (Exception e) {
+             throw new DocumentLocatorException("Error while handling locator", e);
+        }
+    }
+
+    public void skippedEntity(java.lang.String name) throws SAXException {
+        this.writeEvent(SKIPPED_ENTITY);
+        this.writeString(name);
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        this.writeEvent(START_DTD);
+        this.writeString(name);
+        this.writeString(publicId!=null?publicId:"");
+        this.writeString(systemId!=null?systemId:"");
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void endDTD() throws SAXException {
+        this.writeEvent(END_DTD);
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void startEntity(String name) throws SAXException {
+        this.writeEvent(START_ENTITY);
+        this.writeString(name);
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void endEntity(String name) throws SAXException {
+        this.writeEvent(END_ENTITY);
+        this.writeString(name);
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void startCDATA() throws SAXException {
+        this.writeEvent(START_CDATA);
+    }
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void endCDATA() throws SAXException {
+        this.writeEvent(END_CDATA);
+    }
+
+
+    /**
+     * SAX Event Handling: LexicalHandler
+     */
+    public void comment(char ary[], int start, int length) throws SAXException {
+        try {
+            this.writeEvent(COMMENT);
+            this.writeChars(ary, start, length);
+        } catch (Exception e) {
+            throw new SAXException(e);
+        }
+    }
+
+    public final void writeEvent( final int event) {
+        this.write(event);
+    }
+
+    public final void writeAttributes( final int attributes) throws SAXException {
+        if (attributes > 0xFFFF) throw new SAXException("Too many attributes");
+        this.write((attributes >>> 8) & 0xFF);
+        this.write((attributes >>> 0) & 0xFF);
+    }
+
+    public final void writeString( final String str) throws SAXException {
+        Integer index = (Integer) map.get(str);
+        if (index == null) {
+            map.put(str, new Integer(mapCount++));
+            int length = str.length();
+            this.writeChars(str.toCharArray(), 0, length);
+        }
+        else {
+            int i = index.intValue();
+
+            if (i > 0xFFFF) throw new SAXException("Index too large");
+
+            this.write(((i >>> 8) & 0xFF) | 0x80);
+            this.write((i >>> 0) & 0xFF);
+        }
+    }
+
+    public final void writeChars( final char[] ch, final int start, final int length) {
+        int utflen = 0;
+        int c;
+
+        for (int i = 0; i < length; i++) {
+            c = ch[i + start];
+            if ((c >= 0x0001) && (c <= 0x007F)) {
+                utflen++;
+            }
+            else if (c > 0x07FF) {
+                utflen += 3;
+            }
+            else {
+                utflen += 2;
+            }
+        }
+
+        if (utflen >= 0x00007FFF) {
+            assure(bufCount + utflen + 6);
+
+            buf[bufCount++] = (byte)0x7F;
+            buf[bufCount++] = (byte)0xFF;
+
+            buf[bufCount++] = (byte) ((utflen >>> 24) & 0xFF);
+            buf[bufCount++] = (byte) ((utflen >>> 16) & 0xFF);
+            buf[bufCount++] = (byte) ((utflen >>>  8) & 0xFF);
+            buf[bufCount++] = (byte) ((utflen >>>  0) & 0xFF);
+        }
+        else {
+            assure(bufCount + utflen + 2);
+
+            buf[bufCount++] = (byte) ((utflen >>> 8) & 0xFF);
+            buf[bufCount++] = (byte) ((utflen >>> 0) & 0xFF);
+        }
+
+        for (int i = 0; i < length; i++) {
+            c = ch[i + start];
+            if ((c >= 0x0001) && (c <= 0x007F)) {
+                buf[bufCount++] = (byte) c;
+            }
+            else if (c > 0x07FF) {
+                buf[bufCount++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  6) & 0x3F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  0) & 0x3F));
+            }
+            else {
+                buf[bufCount++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  0) & 0x3F));
+            }
+        }
+
+
+/*
+        if (length == 0) return;
+
+        assure( (int) (buf.length + length * utfRatioAverage) );
+
+        int utflentotal = 0;
+
+        bufCount += 2;
+        int bufStart = bufCount;
+
+        for (int i = 0; i < length; i++) {
+            int c = ch[i + start];
+            int l = bufCount-bufStart;
+
+            if (l+3 >= 0x7FFF) {
+                buf[bufStart-2] = (byte) ((l >>> 8) & 0xFF);
+                buf[bufStart-1] = (byte) ((l >>> 0) & 0xFF);
+                utflentotal += l;
+                bufCount += 2;
+                bufStart = bufCount;
+            }
+
+            if ((c >= 0x0001) && (c <= 0x007F)) {
+                assure(bufCount+1);
+                buf[bufCount++] = (byte)c;
+            }
+            else if (c > 0x07FF) {
+                assure(bufCount+3);
+                buf[bufCount++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  6) & 0x3F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  0) & 0x3F));
+            }
+            else {
+                assure(bufCount+2);
+                buf[bufCount++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
+                buf[bufCount++] = (byte) (0x80 | ((c >>  0) & 0x3F));
+            }
+        }
+
+        int l = bufCount-bufStart;
+        buf[bufStart-2] = (byte) ((l >>> 8) & 0xFF);
+        buf[bufStart-1] = (byte) ((l >>> 0) & 0xFF);
+        utflentotal += l;
+
+        utfRatioAverage = (utfRatioAverage + (utflentotal / length) / 2);
+*/
+    }
+
+/*  JH (2003-11-20): seems to be never used
+
+    private void write( final byte[] b ) {
+        int newcount = this.bufCount + b.length;
+        assure(newcount);
+        System.arraycopy(b, 0, this.buf, this.bufCount, b.length);
+        this.bufCount = newcount;
+    }
+*/
+
+    private void write( final int b ) {
+        int newcount = this.bufCount + 1;
+        assure(newcount);
+        this.buf[this.bufCount] = (byte)b;
+        this.bufCount = newcount;
+    }
+
+    private void assure( final int size ) {
+        if (size > this.buf.length) {
+            byte newbuf[] = new byte[Math.max(this.buf.length << 1, size)];
+            System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+            this.buf = newbuf;
+        }
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamFragment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamFragment.java
new file mode 100644
index 0000000..8e6de90
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamFragment.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.sax;
+
+import org.apache.cocoon.xml.AbstractSAXFragment;
+import org.apache.cocoon.xml.EmbeddedXMLPipe;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * An XMLByteStream wrapped by an XMLFragment implementation. This allows to
+ * store SAX events and insert them in an XSP result using &lt;xsp:expr&gt;.
+ *
+ * @version $Id$
+ */
+public class XMLByteStreamFragment extends AbstractSAXFragment {
+
+    /** The XML byte stream */
+    private Object xmlBytes;
+
+    /**
+     * Creates a new <code>XMLByteStreamFragment</code> defined by the given
+     * XML byte stream.
+     *
+     * @param bytes the XML byte stream representing the document fragment
+     */
+    public XMLByteStreamFragment(Object bytes) {
+        this.xmlBytes = bytes;
+    }
+
+    /**
+     * Output the fragment. If the fragment is a document, start/endDocument
+     * events are discarded.
+     */
+    public void toSAX(ContentHandler ch) throws SAXException {
+        // Stream bytes and discard start/endDocument
+        XMLByteStreamInterpreter deserializer = new XMLByteStreamInterpreter();
+        deserializer.setContentHandler(new EmbeddedXMLPipe(ch));
+        deserializer.deserialize(this.xmlBytes);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamInterpreter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamInterpreter.java
new file mode 100644
index 0000000..944839d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLByteStreamInterpreter.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.sax;
+
+import java.util.ArrayList;
+
+import org.apache.cocoon.xml.DefaultLexicalHandler;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * This a simple xml compiler which takes a byte array as input.
+ * If you want to reuse this interpreter make sure to call first {@link #recycle()}
+ * and then set the new consumer for the sax events.
+ *
+ * @version $Id$
+ */
+public final class XMLByteStreamInterpreter implements XMLProducer {
+
+    private static final int START_DOCUMENT         = 0;
+    private static final int END_DOCUMENT           = 1;
+    private static final int START_PREFIX_MAPPING   = 2;
+    private static final int END_PREFIX_MAPPING     = 3;
+    private static final int START_ELEMENT          = 4;
+    private static final int END_ELEMENT            = 5;
+    private static final int CHARACTERS             = 6;
+    private static final int IGNORABLE_WHITESPACE   = 7;
+    private static final int PROCESSING_INSTRUCTION = 8;
+    private static final int COMMENT                = 9;
+    private static final int LOCATOR                = 10;
+    private static final int START_DTD              = 11;
+    private static final int END_DTD                = 12;
+    private static final int START_CDATA            = 13;
+    private static final int END_CDATA              = 14;
+    private static final int SKIPPED_ENTITY         = 15;
+    private static final int START_ENTITY           = 16;
+    private static final int END_ENTITY             = 17;
+
+    private ArrayList list = new ArrayList();
+    private byte[] input;
+    private int currentPos;
+
+    protected static final ContentHandler EMPTY_CONTENT_HANDLER = new DefaultHandler();
+
+    /** The <code>ContentHandler</code> receiving SAX events. */
+    protected ContentHandler contentHandler = EMPTY_CONTENT_HANDLER;
+
+    /** The <code>LexicalHandler</code> receiving SAX events. */
+    protected LexicalHandler lexicalHandler = DefaultLexicalHandler.NULL_HANDLER;
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     * <br>
+     * This method will simply call <code>setContentHandler(consumer)</code>
+     * and <code>setLexicalHandler(consumer)</code>.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        setContentHandler(consumer);
+        setLexicalHandler(consumer);
+    }
+
+    /**
+     * Set the <code>ContentHandler</code> that will receive XML data.
+     * <br>
+     * Subclasses may retrieve this <code>ContentHandler</code> instance
+     * accessing the protected <code>super.contentHandler</code> field.
+     */
+    public void setContentHandler(ContentHandler handler) {
+        this.contentHandler = handler;
+    }
+
+    /**
+     * Set the <code>LexicalHandler</code> that will receive XML data.
+     * <br>
+     * Subclasses may retrieve this <code>LexicalHandler</code> instance
+     * accessing the protected <code>super.lexicalHandler</code> field.
+     */
+    public void setLexicalHandler(LexicalHandler handler) {
+        this.lexicalHandler = handler;
+    }
+
+    public void recycle() {
+        this.contentHandler = EMPTY_CONTENT_HANDLER;
+        this.lexicalHandler = DefaultLexicalHandler.NULL_HANDLER;
+        this.list.clear();
+        this.input = null;
+    }
+
+    public void deserialize(Object saxFragment) throws SAXException {
+        if (!(saxFragment instanceof byte[])) {
+            throw new SAXException("XMLDeserializer needs byte array for deserialization.");
+        }
+        this.list.clear();
+        this.input = (byte[])saxFragment;
+        this.currentPos = 0;
+        this.checkProlog();
+        this.parse();
+    }
+
+    private void parse() throws SAXException {
+        while ( currentPos < input.length) {
+            switch (this.readEvent()) {
+                case START_DOCUMENT:
+                    contentHandler.startDocument();
+                    break;
+                case END_DOCUMENT:
+                    contentHandler.endDocument();
+                    break;
+                case START_PREFIX_MAPPING:
+                    contentHandler.startPrefixMapping(this.readString(), this.readString());
+                    break;
+                case END_PREFIX_MAPPING:
+                    contentHandler.endPrefixMapping(this.readString());
+                    break;
+                case START_ELEMENT:
+                    int attributes = this.readAttributes();
+                    AttributesImpl atts = new AttributesImpl();
+                    for (int i = 0; i < attributes; i++) {
+                        atts.addAttribute(this.readString(), this.readString(), this.readString(), this.readString(), this.readString());
+                    }
+                    contentHandler.startElement(this.readString(), this.readString(), this.readString(), atts);
+                    break;
+                case END_ELEMENT:
+                    contentHandler.endElement(this.readString(), this.readString(), this.readString());
+                    break;
+                case CHARACTERS:
+                    char[] chars = this.readChars();
+                    int len = chars.length;
+                    while (len > 0 && chars[len-1]==0) len--;
+                    if (len > 0) contentHandler.characters(chars, 0, len);
+                    break;
+                case IGNORABLE_WHITESPACE:
+                    char[] spaces = this.readChars();
+                    len = spaces.length;
+                    while (len > 0 && spaces[len-1]==0) len--;
+                    if (len > 0) contentHandler.characters(spaces, 0, len);
+                    break;
+                case PROCESSING_INSTRUCTION:
+                    contentHandler.processingInstruction(this.readString(), this.readString());
+                    break;
+                case COMMENT:
+                    chars = this.readChars();
+                    len = chars.length;
+                    while (len > 0 && chars[len-1]==0) len--;
+                    if (len > 0) lexicalHandler.comment(chars, 0, len);
+                    break;
+                case LOCATOR:
+                    {
+                    String publicId = this.readString();
+                    String systemId = this.readString();
+                    int lineNumber = this.read();
+                    int columnNumber = this.read();
+                    org.xml.sax.helpers.LocatorImpl locator = new org.xml.sax.helpers.LocatorImpl();
+                    locator.setPublicId(publicId);
+                    locator.setSystemId(systemId);
+                    locator.setLineNumber(lineNumber);
+                    locator.setColumnNumber(columnNumber);
+                    contentHandler.setDocumentLocator(locator);
+                    }
+                    break;
+                case START_DTD:
+                    lexicalHandler.startDTD(this.readString(), 
+                                            this.readString(), 
+                                            this.readString());
+                    break;
+                case END_DTD:
+                    lexicalHandler.endDTD();
+                    break;
+                case START_CDATA:
+                    lexicalHandler.startCDATA();
+                    break;
+                case END_CDATA:
+                    lexicalHandler.endCDATA();
+                    break;
+                case SKIPPED_ENTITY:
+                    contentHandler.skippedEntity( this.readString() );
+                    break;
+                case START_ENTITY:
+                    lexicalHandler.startEntity( this.readString() );
+                    break;
+                case END_ENTITY:
+                    lexicalHandler.endEntity( this.readString() );
+                    break;
+                default:
+                    throw new SAXException ("parsing error: event not supported.");
+            }
+        }
+    }
+
+    private void checkProlog() throws SAXException {
+        int valid = 0;
+        if (this.read() == 'C') valid++;
+        if (this.read() == 'X') valid++;
+        if (this.read() == 'M') valid++;
+        if (this.read() == 'L') valid++;
+        if (this.read() == 1) valid++;
+        if (this.read() == 0) valid++;
+        if (valid != 6) throw new SAXException("Unrecognized file format.");
+    }
+
+    protected int readEvent() throws SAXException {
+        return this.read();
+    }
+
+    private int readAttributes() throws SAXException {
+        int ch1 = this.read();
+        int ch2 = this.read();
+        return ((ch1 << 8) + (ch2 << 0));
+    }
+
+    private String readString() throws SAXException {
+        int length = this.readWord();
+        int index = length & 0x00007FFF;
+        if (length >= 0x00008000) {
+            return (String) list.get(index);
+        }
+        else {
+            if (length == 0x00007FFF) {
+                length = this.readLong();
+            }
+            char[] chars = this.readChars(length);
+            int len = chars.length;
+            if (len > 0) {
+                while (chars[len-1]==0) len--;
+            }
+            String str;
+            if (len == 0) {
+                str = "";
+            } else {
+                str = new String(chars, 0, len);
+            }
+            list.add(str);
+            return str;
+        }
+    }
+
+    /**
+     * The returned char array might contain any number of zero bytes
+     * at the end
+     */
+    private char[] readChars() throws SAXException {
+        int length = this.readWord();
+        if (length == 0x00007FFF) {
+            length = this.readLong();
+        }
+        return this.readChars(length);
+    }
+
+    private int read() throws SAXException {
+        if (currentPos >= input.length)
+            throw new SAXException("Reached end of input.");
+        return input[currentPos++] & 0xff;
+    }
+
+    /**
+     * The returned char array might contain any number of zero bytes
+     * at the end
+     */
+    private char[] readChars(int len) throws SAXException {
+        char[] str = new char[len];
+        byte[] bytearr = new byte[len];
+        int c, char2, char3;
+        int count = 0;
+        int i = 0;
+
+        this.readBytes(bytearr);
+
+        while (count < len) {
+            c = bytearr[count] & 0xff;
+            switch (c >> 4) {
+                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+                    // 0xxxxxxx
+                    count++;
+                    str[i++] = (char) c;
+                    break;
+                case 12: case 13:
+                    // 110x xxxx   10xx xxxx
+                    count += 2;
+                    char2 = bytearr[count-1];
+                    str[i++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
+                    break;
+                case 14:
+                    // 1110 xxxx  10xx xxxx  10xx xxxx
+                    count += 3;
+                    char2 = bytearr[count-2];
+                    char3 = bytearr[count-1];
+                    str[i++] = ((char)(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)));
+                    break;
+                default:
+                    // 10xx xxxx,  1111 xxxx
+                    throw new SAXException("UTFDataFormatException");
+            }
+        }
+
+        return str;
+    }
+
+    private void readBytes(byte[] b) throws SAXException {
+        if (this.currentPos + b.length > this.input.length) {
+            // TC:
+            // >= prevents getting the last byte
+            // 0 1 2 3 4   input.length = 5
+            //     |_ currentPos = 2
+            // b.length = 3
+            // 2 + 3 > 5 ok
+            // 2 + 3 >= 5 wrong
+            // why has this worked before?
+            throw new SAXException("End of input reached.");
+        }
+        System.arraycopy(this.input, this.currentPos, b, 0, b.length);
+        this.currentPos += b.length;
+    }
+
+    private int readWord() throws SAXException {
+        int ch1 = this.read();
+        int ch2 = this.read();
+        return ((ch1 << 8) + (ch2 << 0));
+    }
+
+    private int readLong() throws SAXException {
+        int ch1 = this.read();
+        int ch2 = this.read();
+        int ch3 = this.read();
+        int ch4 = this.read();
+        return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLTeePipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLTeePipe.java
new file mode 100644
index 0000000..d40bde3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/sax/XMLTeePipe.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.sax;
+
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLPipe;
+import org.apache.cocoon.xml.XMLProducer;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+
+/**
+ * This is a simple Tee Component.
+ * The incoming events are forwarded to two other components.
+ *
+ * @version $Id$
+ */
+public final class XMLTeePipe
+implements XMLPipe {
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        ((XMLProducer)this.firstConsumer).setConsumer(consumer);
+    }
+
+    private XMLConsumer firstConsumer;
+    private XMLConsumer secondConsumer;
+
+    /**
+     * Create a new XMLTeePipe with two consumers
+     */
+    public XMLTeePipe(XMLConsumer firstPipe,
+                      XMLConsumer secondConsumer) {
+        this.firstConsumer = firstPipe;
+        this.secondConsumer = secondConsumer;
+    }
+
+    public void recycle() {
+        this.firstConsumer = null;
+        this.secondConsumer = null;
+    }
+
+    public void startDocument() throws SAXException {
+        this.firstConsumer.startDocument();
+        this.secondConsumer.startDocument();
+    }
+
+    public void endDocument() throws SAXException {
+        this.firstConsumer.endDocument();
+        this.secondConsumer.endDocument();
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        this.firstConsumer.startPrefixMapping(prefix, uri);
+        this.secondConsumer.startPrefixMapping(prefix, uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        this.firstConsumer.endPrefixMapping(prefix);
+        this.secondConsumer.endPrefixMapping(prefix);
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+    throws SAXException {
+        this.firstConsumer.startElement(namespaceURI, localName, qName, atts);
+        this.secondConsumer.startElement(namespaceURI, localName, qName, atts);
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName)
+    throws SAXException {
+        this.firstConsumer.endElement(namespaceURI, localName, qName);
+        this.secondConsumer.endElement(namespaceURI, localName, qName);
+    }
+
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        this.firstConsumer.characters(ch, start, length);
+        this.secondConsumer.characters(ch, start, length);
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+        this.firstConsumer.ignorableWhitespace(ch, start, length);
+        this.secondConsumer.ignorableWhitespace(ch, start, length);
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        this.firstConsumer.processingInstruction(target, data);
+        this.secondConsumer.processingInstruction(target, data);
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        this.firstConsumer.setDocumentLocator(locator);
+        this.secondConsumer.setDocumentLocator(locator);
+    }
+
+    public void skippedEntity(String name) throws SAXException {
+        this.firstConsumer.skippedEntity(name);
+        this.secondConsumer.skippedEntity(name);
+    }
+
+    public void startDTD(String name, String public_id, String system_id)
+    throws SAXException {
+        this.firstConsumer.startDTD(name, public_id, system_id);
+        this.secondConsumer.startDTD(name, public_id, system_id);
+    }
+
+    public void endDTD() throws SAXException {
+        this.firstConsumer.endDTD();
+        this.secondConsumer.endDTD();
+    }
+
+    public void startEntity(String name) throws SAXException {
+        this.firstConsumer.startEntity(name);
+        this.secondConsumer.startEntity(name);
+    }
+
+    public void endEntity(String name) throws SAXException {
+        this.firstConsumer.endEntity(name);
+        this.secondConsumer.endEntity(name);
+    }
+
+    public void startCDATA() throws SAXException {
+        this.firstConsumer.startCDATA();
+        this.secondConsumer.startCDATA();
+    }
+
+    public void endCDATA() throws SAXException {
+        this.firstConsumer.endCDATA();
+        this.secondConsumer.endCDATA();
+    }
+
+    public void comment(char ary[], int start, int length)
+    throws SAXException {
+        this.firstConsumer.comment(ary, start, length);
+        this.secondConsumer.comment(ary, start, length);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/CocoonSourceResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/CocoonSourceResolver.java
new file mode 100644
index 0000000..006e834
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/CocoonSourceResolver.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.container.ComponentLocatorWrapper;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.ComponentLocator;
+import org.apache.cocoon.sitemap.Sitemap;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.URIAbsolutizer;
+
+/**
+ * This is the default implementation of the {@link SourceResolver} for
+ * Cocoon. The implementation is based on the original source resolver implementation
+ * from the Excalibur project.
+ * @since 2.2
+ * 
+ * @version $Id$
+ */
+public class CocoonSourceResolver 
+extends AbstractLogEnabled
+implements SourceResolver, Contextualizable, Serviceable, Disposable, ThreadSafe {
+
+    /** A (optional) custom source resolver */
+    protected org.apache.excalibur.source.SourceResolver customResolver;
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    /** The base URL */
+    protected URL baseURL;
+
+    /** The core */
+    protected Core core;
+
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize( Context context )
+    throws ContextException {
+        try {
+            if ( context.get( "context-root" ) instanceof URL ) {
+                this.baseURL = (URL)context.get( "context-root" );
+            } else {
+                this.baseURL = ( (File)context.get( "context-root" ) ).toURL();
+            }
+        } catch( ContextException ce ) {
+            // set the base URL to the current directory
+            try {
+                this.baseURL = new File( System.getProperty( "user.dir" ) ).toURL();
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( "SourceResolver: Using base URL: " + this.baseURL );
+                }
+            } catch( MalformedURLException mue ) {
+                throw new ContextException( "Malformed URL for user.dir, and no container.rootDir exists", mue );
+            }
+        } catch( MalformedURLException mue ) {
+            throw new ContextException( "Malformed URL for container.rootDir", mue );
+        }
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String, java.lang.String, java.util.Map)
+     */
+    public Source resolveURI(String location, String baseURI, Map parameters)
+    throws MalformedURLException, IOException, SourceException {
+        if ( baseURI == null ) {
+            final Processor processor = EnvironmentHelper.getCurrentProcessor();
+            if ( processor != null ) {
+                baseURI = processor.getContext();
+            }
+        }
+        if ( this.customResolver != null ) {
+            return this.customResolver.resolveURI(location, baseURI, parameters);
+        }
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "Resolving '" + location + "' with base '" + baseURI + "' in context '" + this.baseURL + "'" );
+        }
+        if( location == null ) {
+            throw new MalformedURLException( "Invalid System ID" );
+        }
+        if( null != baseURI && org.apache.excalibur.source.SourceUtil.indexOfSchemeColon(baseURI) == -1 ) {
+            throw new MalformedURLException( "BaseURI is not valid, it must contain a protocol: " + baseURI );
+        }
+
+        if( baseURI == null ) {
+            baseURI = this.baseURL.toExternalForm();
+        }
+
+        String systemID = location;
+        // special handling for windows file paths
+        if( location.length() > 1 && location.charAt( 1 ) == ':' ) {
+            systemID = "file:/" + location;
+        } else if( location.length() > 2 && location.charAt(0) == '/' && location.charAt(2) == ':' ) {
+            systemID = "file:" + location;
+        }
+
+        // determine protocol (scheme): first try to get the one of the systemID, if that fails, take the one of the baseURI
+        String protocol;
+        int protocolPos = org.apache.excalibur.source.SourceUtil.indexOfSchemeColon(systemID);
+        if( protocolPos != -1 ) {
+            protocol = systemID.substring( 0, protocolPos );
+        } else {
+            protocolPos = org.apache.excalibur.source.SourceUtil.indexOfSchemeColon(baseURI);
+            if( protocolPos != -1 ) {
+                protocol = baseURI.substring( 0, protocolPos );
+            } else {
+                protocol = "*";
+            }
+        }
+
+        final ComponentLocator m = this.getComponentLocator();
+
+        Source source = null;
+        // search for a SourceFactory implementing the protocol
+        SourceFactory factory = null;
+        try {
+            factory = this.getSourceFactory( m, protocol );
+            systemID = this.absolutize( factory, baseURI, systemID );
+            if( getLogger().isDebugEnabled() ) {
+                getLogger().debug( "Resolved to systemID : " + systemID );
+            }
+            source = factory.getSource( systemID, parameters );
+        } catch( final ProcessingException ce ) {
+            // no selector available, use fallback
+        } finally {
+            m.release( factory );
+        }
+
+        if( null == source ) {
+            try {
+                factory = this.getSourceFactory( m, "*");
+                systemID = this.absolutize( factory, baseURI, systemID );
+                if( getLogger().isDebugEnabled() ) {
+                    getLogger().debug( "Resolved to systemID : " + systemID );
+                }
+                source = factory.getSource( systemID, parameters );
+            } catch (ProcessingException se ) {
+                throw new SourceException( "Unable to select source factory for " + systemID, se );
+            } finally {
+                m.release(factory);
+            }
+        }
+
+        return source;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String)
+     */
+    public Source resolveURI(String location)
+    throws MalformedURLException, IOException, SourceException {
+        return this.resolveURI(location, null, null);
+    }
+
+    /** 
+     * Obtain a reference to the SourceResolver with "/Cocoon" hint
+     * 
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        if ( this.manager.hasService(org.apache.excalibur.source.SourceResolver.ROLE+"/Cocoon")) {
+            this.customResolver = (org.apache.excalibur.source.SourceResolver)
+                     this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE+"/Cocoon");
+        }
+        this.core = (Core)this.manager.lookup(Core.ROLE);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release( this.customResolver );
+            this.customResolver = null;
+            this.manager.release(this.core);
+            this.core = null;
+            this.manager = null;
+        }
+    }
+
+    /**
+     * Get the component locator.
+     */
+    protected ComponentLocator getComponentLocator() {
+        ComponentLocator l = null;
+        final Sitemap sitemap = this.core.getCurrentSitemap();
+        if ( sitemap != null ) {
+            l = sitemap.getComponentLocator();
+        }
+        if ( l == null ) {
+            l = new ComponentLocatorWrapper(this.manager);
+        }
+        return l;
+    }
+
+    /**
+     * Get the SourceFactory
+     */
+    protected SourceFactory getSourceFactory(ComponentLocator m, String scheme) 
+    throws ProcessingException {
+        return (SourceFactory)m.getComponent(SourceFactory.ROLE + '/' + scheme);
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#release(org.apache.excalibur.source.Source)
+     */
+    public void release(Source source) {
+        if( source == null ) return;
+
+        if ( this.customResolver != null ) {
+            this.customResolver.release( source );
+        } else {
+            final ComponentLocator m = this.getComponentLocator();
+            
+            // search for a SourceFactory implementing the protocol
+            final String scheme = source.getScheme();
+            SourceFactory factory = null;
+
+            try {
+                factory = this.getSourceFactory(m, scheme);
+                factory.release(source);
+            } catch (ProcessingException se ) {
+                try {
+                    factory = this.getSourceFactory(m, "*");
+                    factory.release(source);
+                } catch (ProcessingException sse ) {
+                    throw new SourceFactoryNotFoundException( "Unable to select source factory for " + source.getURI(), se );
+                }
+            } finally {
+                m.release( factory );
+            }
+        }
+    }
+
+    /**
+     * Makes an absolute URI based on a baseURI and a relative URI.
+     */
+    protected String absolutize( SourceFactory factory, String baseURI, String systemID )  {
+        if( factory instanceof URIAbsolutizer ) {
+            systemID = ((URIAbsolutizer)factory).absolutize(baseURI, systemID);
+        } else {
+            systemID = org.apache.excalibur.source.SourceUtil.absolutize(baseURI, systemID);
+        }
+        return systemID;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceFactoryNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceFactoryNotFoundException.java
new file mode 100644
index 0000000..4a58399
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceFactoryNotFoundException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+public final class SourceFactoryNotFoundException extends CascadingRuntimeException
+{
+    public SourceFactoryNotFoundException(String message)
+    {
+        super(message, null);
+    }
+
+    public SourceFactoryNotFoundException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceUtil.java
new file mode 100644
index 0000000..3b3c863
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/SourceUtil.java
@@ -0,0 +1,835 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceParameters;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.excalibur.xmlizer.XMLizer;
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.REProgram;
+import org.apache.regexp.RESyntaxException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.xml.transform.OutputKeys;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This class contains some utility methods for the source resolving.
+ *
+ * @version $Id$
+ */
+public final class SourceUtil {
+
+    private static REProgram uripattern = null;
+
+    static {
+        try {
+            uripattern = new RECompiler().compile("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
+        } catch (RESyntaxException e) {
+            // Should not happen
+            e.printStackTrace();
+        }
+    }
+
+    /** Avoid instantiation */
+    private SourceUtil() {
+    }
+
+    /**
+     * Generates SAX events from the XMLizable and handle SAXException.
+     *
+     * @param  source    the data
+     */
+    static public void toSAX(XMLizable source,
+                             ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        try {
+            source.toSAX(handler);
+        } catch (SAXException e) {
+            // Unwrap ProcessingException, IOException, and extreme cases of SAXExceptions.
+            // Handle SourceException.
+            // See also handleSAXException
+            final Exception cause = e.getException();
+            if (cause != null) {
+                if (cause instanceof SourceException) {
+                    throw handle((SourceException) cause);
+                }
+                if (cause instanceof ProcessingException) {
+                    throw (ProcessingException) cause;
+                }
+                if (cause instanceof IOException) {
+                    throw (IOException) cause;
+                }
+                if (cause instanceof SAXException) {
+                    throw (SAXException) cause;
+                }
+            }
+
+            // Throw original SAX exception
+            throw e;
+        }
+    }
+
+    /**
+     * Generates SAX events from the given source.
+     *
+     * <p><b>NOTE</b>: If the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually
+     * directly implement the LexicalHandler interface!</p>
+     *
+     * @param  source    the data
+     * @throws ProcessingException if no suitable converter is found
+     */
+    static public void toSAX(Source source,
+                             ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        toSAX(EnvironmentHelper.getSitemapServiceManager(),
+              source, null, handler);
+    }
+
+    /**
+     * Generates SAX events from the given source by using XMLizer.
+     * Current sitemap manager will be used to lookup XMLizer.
+     *
+     * <p><b>NOTE</b>: If the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually
+     * directly implement the LexicalHandler interface!</p>
+     *
+     * @param  source    the data
+     * @throws ProcessingException if no suitable converter is found
+     */
+    static public void toSAX(Source source,
+                             String mimeTypeHint,
+                             ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        toSAX(EnvironmentHelper.getSitemapServiceManager(),
+              source, mimeTypeHint, handler);
+    }
+
+    /**
+     * Generates SAX events from the given source by using XMLizer.
+     *
+     * <p><b>NOTE</b>: If the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually
+     * directly implement the LexicalHandler interface!</p>
+     *
+     * @param  source    the data
+     * @throws ProcessingException if no suitable converter is found
+     */
+    static public void toSAX(ServiceManager manager,
+                             Source source,
+                             String mimeTypeHint,
+                             ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        if (source instanceof XMLizable) {
+            toSAX((XMLizable) source, handler);
+        } else {
+            String mimeType = source.getMimeType();
+            if (null == mimeType) {
+                mimeType = mimeTypeHint;
+            }
+
+            XMLizer xmlizer = null;
+            try {
+                xmlizer = (XMLizer) manager.lookup(XMLizer.ROLE);
+                xmlizer.toSAX(source.getInputStream(),
+                              mimeType,
+                              source.getURI(),
+                              handler);
+            } catch (SourceException e) {
+                throw SourceUtil.handle(e);
+            } catch (ServiceException e) {
+                throw new ProcessingException("Exception during streaming source.", e);
+            } finally {
+                manager.release(xmlizer);
+            }
+        }
+    }
+
+    /**
+     * Generates SAX events from the given source with possible URL rewriting.
+     *
+     * <p><b>NOTE</b>: If the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually
+     * directly implement the LexicalHandler interface!</p>
+     *
+     * @param  source    the data
+     * @throws ProcessingException if no suitable converter is found
+     */
+    static public void toSAX(Source source,
+                             ContentHandler handler,
+                             Parameters typeParameters,
+                             boolean filterDocumentEvent)
+    throws SAXException, IOException, ProcessingException {
+        // Test for url rewriting
+        if (typeParameters != null
+                && typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null) != null) {
+            handler = new URLRewriter(typeParameters, handler);
+        }
+
+        String mimeTypeHint = null;
+        if (typeParameters != null) {
+            mimeTypeHint = typeParameters.getParameter("mime-type", mimeTypeHint);
+        }
+        if (filterDocumentEvent) {
+            IncludeXMLConsumer filter = new IncludeXMLConsumer(handler);
+            toSAX(source, mimeTypeHint, filter);
+        } else {
+            toSAX(source, mimeTypeHint, handler);
+        }
+    }
+
+    /**
+     * Generates character SAX events from the given source.
+     *
+     * @param source The data
+     * @param encoding The character encoding of the data
+     */
+    static public void toCharacters(Source source,
+                                    String encoding,
+                                    ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        try {
+            Reader r = encoding == null?
+                    new InputStreamReader(source.getInputStream()):
+                    new InputStreamReader(source.getInputStream(), encoding);
+
+            int len;
+            char[] chr = new char[4096];
+            try {
+                while ((len = r.read(chr)) > 0) {
+                    handler.characters(chr, 0, len);
+                }
+            } finally {
+                r.close();
+            }
+        } catch (SAXException e) {
+            handleSAXException(source.getURI(), e);
+        }
+    }
+
+    /**
+     * Generates SAX events from the given source by parsing it.
+     *
+     * <p><b>NOTE</b>: If the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually
+     * directly implement the LexicalHandler interface!</p>
+     *
+     * @param  source    the data
+     * @throws ProcessingException if no suitable converter is found
+     */
+    static public void parse(ServiceManager manager,
+                             Source source,
+                             ContentHandler handler)
+    throws SAXException, IOException, ProcessingException {
+        if (source instanceof XMLizable) {
+            toSAX((XMLizable) source, handler);
+        } else {
+            SAXParser parser = null;
+            try {
+                parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+                parser.parse(getInputSource(source), handler);
+            } catch (SourceException e) {
+                throw SourceUtil.handle(e);
+            } catch (ServiceException e) {
+                throw new ProcessingException("Exception during parsing source.", e);
+            } finally {
+                manager.release(parser);
+            }
+        }
+    }
+
+    /**
+     * Generates a DOM from the given source
+     * @param source The data
+     *
+     * @return Created DOM document.
+     *
+     * @throws IOException If a io exception occurs.
+     * @throws ProcessingException if no suitable converter is found
+     * @throws SAXException If a SAX exception occurs.
+     */
+    static public Document toDOM(Source source)
+    throws SAXException, IOException, ProcessingException {
+        DOMBuilder builder = new DOMBuilder();
+
+        toSAX(source, builder);
+
+        Document document = builder.getDocument();
+        if (document == null) {
+            throw new ProcessingException("Could not build DOM for '" +
+                                          source.getURI() + "'");
+        }
+
+        return document;
+    }
+
+    /**
+     * Generates a DOM from the given source
+     * @param source The data
+     *
+     * @return Created DOM document.
+     *
+     * @throws IOException If a io exception occurs.
+     * @throws ProcessingException if no suitable converter is found
+     * @throws SAXException If a SAX exception occurs.
+     */
+    static public Document toDOM(ServiceManager manager, Source source)
+    throws SAXException, IOException, ProcessingException {
+        DOMBuilder builder = new DOMBuilder();
+
+        toSAX(manager, source, null, builder);
+
+        Document document = builder.getDocument();
+        if (document == null) {
+            throw new ProcessingException("Could not build DOM for '" +
+                                          source.getURI() + "'");
+        }
+
+        return document;
+    }
+
+    /**
+     * Generates a DOM from the given source
+     * @param source The data
+     *
+     * @return Created DOM document.
+     *
+     * @throws IOException If a io exception occurs.
+     * @throws ProcessingException if no suitable converter is found
+     * @throws SAXException If a SAX exception occurs.
+     */
+    static public Document toDOM(ServiceManager manager, String mimeTypeHint, Source source)
+    throws SAXException, IOException, ProcessingException {
+        DOMBuilder builder = new DOMBuilder();
+
+        toSAX(manager, source, mimeTypeHint, builder);
+
+        Document document = builder.getDocument();
+        if (document == null) {
+            throw new ProcessingException("Could not build DOM for '" +
+                                          source.getURI() + "'");
+        }
+
+        return document;
+    }
+
+    /**
+     * Make a ProcessingException from a SourceException.
+     * If the exception is a SourceNotFoundException then a
+     * ResourceNotFoundException is thrown.
+     *
+     * @param se Source exception
+     * @return Created processing exception.
+     */
+    static public ProcessingException handle(SourceException se) {
+        if (se instanceof SourceNotFoundException) {
+            return new ResourceNotFoundException("Resource not found.", se);
+        }
+        return new ProcessingException("Exception during source resolving.",
+                                       se);
+    }
+
+    /**
+     * Make a ProcessingException from a SourceException.
+     * If the exception is a SourceNotFoundException then a
+     * ResourceNotFoundException is thrown.
+     *
+     * @param message Additional exception message.
+     * @param se Source exception.
+     * @return Created processing exception.
+     */
+    static public ProcessingException handle(String message,
+                                             SourceException se) {
+        if (se instanceof SourceNotFoundException) {
+            return new ResourceNotFoundException(message, se);
+        }
+        return new ProcessingException(message, se);
+    }
+
+    /**
+     * Handle SAXException catched in Generator's generate method.
+     *
+     * @param source Generator's source
+     * @param e SAXException happened in the generator's generate method.
+     */
+    static public void handleSAXException(String source, SAXException e)
+    throws ProcessingException, IOException, SAXException {
+        final Exception cause = e.getException();
+        if (cause != null) {
+            // Unwrap ProcessingException, IOException, and extreme cases of SAXExceptions.
+            // Handle SourceException.
+            // See also toSax(XMLizable, ContentHandler)
+            if (cause instanceof SourceException) {
+                throw handle((SourceException) cause);
+            }
+            if (cause instanceof ProcessingException) {
+                throw (ProcessingException) cause;
+            }
+            if (cause instanceof IOException) {
+                throw (IOException) cause;
+            }
+            if (cause instanceof SAXException) {
+                throw (SAXException) cause;
+            }
+            throw new ProcessingException("Could not read resource " +
+                                          source, cause);
+        }
+        throw e;
+    }
+
+    /**
+     * Get an InputSource object
+     *
+     * @param source Source.
+     *
+     * @return Input stream of the source.
+     *
+     * @throws IOException If a io exception occurs.
+     * @throws ProcessingException If an exception occurs during
+     *                             processing.
+     */
+    static public InputSource getInputSource(Source source)
+    throws IOException, ProcessingException {
+        try {
+            final InputSource newObject = new InputSource(source.getInputStream());
+
+            newObject.setSystemId(source.getURI());
+            return newObject;
+        } catch (SourceException se) {
+            throw handle(se);
+        }
+    }
+
+    /**
+     * Get a <code>Source</code> object
+     *
+     * @param uri URI of the source.
+     * @param typeParameters Type of Source query.  Currently, only
+     * <code>method</code> parameter (value typically <code>GET</code> or
+     * <code>POST</code>) is recognized.  May be <code>null</code>.
+     * @param resourceParameters Parameters of the source.  May be <code>null</code>
+     * @param resolver Resolver for the source.
+     *
+     * @return The resolved source.
+     *
+     * @throws IOException If a io exception occurs.
+     * @throws SAXException If a SAX exception occurs.
+     * @throws SourceException If the source an exception throws.
+     */
+    static public Source getSource(String uri,
+                                   Parameters typeParameters,
+                                   SourceParameters resourceParameters,
+                                   SourceResolver resolver)
+    throws IOException, SAXException, SourceException {
+
+        // first step: encode parameters which are already appended to the url
+        int queryPos = uri.indexOf('?');
+        if (queryPos != -1) {
+            String queryString = uri.substring(queryPos+1);
+            SourceParameters queries = new SourceParameters(queryString);
+
+            if (queries.hasParameters()) {
+                StringBuffer buffer = new StringBuffer(uri.substring(0, queryPos));
+                char separator = '?';
+
+                Iterator i = queries.getParameterNames();
+                while (i.hasNext()) {
+                    String current = (String) i.next();
+                    Iterator values = queries.getParameterValues(current);
+                    while (values.hasNext()) {
+                        buffer.append(separator)
+                                .append(current)
+                                .append('=')
+                                .append(NetUtils.encode((String) values.next(), "utf-8"));
+                        separator = '&';
+                    }
+                }
+                uri = buffer.toString();
+            }
+        }
+
+        String method = ((typeParameters!=null)
+                         ? typeParameters.getParameter("method", "GET")
+                         : "GET");
+        if (method.equalsIgnoreCase("POST") &&
+                (resourceParameters == null ||
+                !resourceParameters.hasParameters())) {
+            method = "GET";
+        }
+
+        if (uri.startsWith("cocoon:") && resourceParameters != null &&
+                resourceParameters.hasParameters()) {
+            int pos = uri.indexOf(";jsessionid=");
+
+            StringBuffer buf;
+            if (pos == -1) {
+                buf = new StringBuffer(uri);
+            } else {
+                buf = new StringBuffer(uri.substring(0, pos));
+            }
+            buf.append(((uri.indexOf('?') == -1) ? '?' : '&'));
+            buf.append(resourceParameters.getEncodedQueryString());
+            uri = buf.toString();
+        }
+
+        Map resolverParameters = new HashMap();
+        resolverParameters.put(SourceResolver.METHOD, method);
+        if (typeParameters != null) {
+            String encoding = typeParameters.getParameter("encoding",
+                 System.getProperty("file.encoding", "ISO-8859-1"));
+            if (encoding != null && !"".equals(encoding)) {
+                resolverParameters.put(SourceResolver.URI_ENCODING, encoding);
+            }
+        }
+        resolverParameters.put(SourceResolver.URI_PARAMETERS,
+                               resourceParameters);
+
+        return resolver.resolveURI(uri, null, resolverParameters);
+    }
+
+    /**
+     * Write a DOM Fragment to a source.
+     * If the source is a ModifiableSource the interface is used.
+     * If not, the source is invoked with an additional parameter named
+     * "content" containing the XML.
+     * The current sitemap service manager is used to lookup the serializer.
+     *
+     * @param location URI of the Source
+     * @param typeParameters Type of Source query.  Currently, only
+     * <code>method</code> parameter (value typically <code>GET</code> or
+     * <code>POST</code>) is recognized.  May be <code>null</code>.
+     * @param parameters Parameters (e.g. URL params) of the source.
+     * May be <code>null</code>
+     * @param frag DOM fragment to serialize to the Source
+     * @param resolver Resolver for the source.
+     * @param serializerName The serializer to use
+     *
+     * @throws ProcessingException
+     */
+    public static void writeDOM(String location,
+                                Parameters typeParameters,
+                                SourceParameters parameters,
+                                DocumentFragment frag,
+                                SourceResolver resolver,
+                                String serializerName)
+    throws ProcessingException {
+        Source source = null;
+
+        try {
+            source = SourceUtil.getSource(location, typeParameters,
+                                          parameters, resolver);
+            if (source instanceof ModifiableSource) {
+                ModifiableSource ws = (ModifiableSource) source;
+
+                frag.normalize();
+
+                if (null != serializerName) {
+                    ServiceManager manager = EnvironmentHelper.getSitemapServiceManager();
+
+                    ServiceSelector selector = null;
+                    Serializer serializer = null;
+                    OutputStream oStream = null;
+                    try {
+                        selector = (ServiceSelector)manager.lookup(Serializer.ROLE + "Selector");
+                        serializer = (Serializer)selector.select(serializerName);
+                        oStream = ws.getOutputStream();
+                        serializer.setOutputStream(oStream);
+                        serializer.startDocument();
+                        DOMStreamer streamer = new DOMStreamer(serializer);
+                        streamer.stream(frag);
+                        serializer.endDocument();
+                    } catch (ServiceException e) {
+                        throw new ProcessingException("Unable to lookup serializer.", e);
+                    } finally {
+                        if (oStream != null) {
+                            oStream.flush();
+                            try {
+                                oStream.close();
+                            } catch (Exception ignore) {
+                            }
+                        }
+                        if (selector != null) {
+                            selector.release(serializer);
+                            manager.release(selector);
+                        }
+                    }
+                } else {
+                    Properties props = XMLUtils.createPropertiesForXML(false);
+                    props.put(OutputKeys.ENCODING, "ISO-8859-1");
+                    final String content = XMLUtils.serializeNode(frag, props);
+                    OutputStream oStream = ws.getOutputStream();
+
+                    oStream.write(content.getBytes());
+                    oStream.flush();
+                    oStream.close();
+                }
+            } else {
+                String content;
+                if (null != serializerName) {
+                    ServiceManager manager = EnvironmentHelper.getSitemapServiceManager();
+
+                    ServiceSelector selector = null;
+                    Serializer serializer = null;
+                    ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+                    try {
+                        selector = (ServiceSelector)manager.lookup(Serializer.ROLE + "Selector");
+                        serializer = (Serializer)selector.select(serializerName);
+                        serializer.setOutputStream(oStream);
+                        serializer.startDocument();
+                        DOMStreamer streamer = new DOMStreamer(serializer);
+                        streamer.stream(frag);
+                        serializer.endDocument();
+                    } catch (ServiceException e) {
+                        throw new ProcessingException("Unable to lookup serializer.", e);
+                    } finally {
+                        if (oStream != null) {
+                            oStream.flush();
+                            try {
+                                oStream.close();
+                            } catch (Exception ignore) {
+                            }
+                        }
+                        if (selector != null) {
+                            selector.release(serializer);
+                            manager.release(selector);
+                        }
+                    }
+                    content = oStream.toString();
+                } else {
+                    Properties props = XMLUtils.createPropertiesForXML(false);
+                    props.put(OutputKeys.ENCODING, "ISO-8859-1");
+                    content = XMLUtils.serializeNode(frag, props);
+                }
+
+                if (parameters == null) {
+                    parameters = new SourceParameters();
+                } else {
+                    parameters = (SourceParameters) parameters.clone();
+                }
+                parameters.setSingleParameterValue("content", content);
+
+                source = SourceUtil.getSource(location, typeParameters,
+                                              parameters, resolver);
+                SourceUtil.toSAX(source, new DefaultHandler());
+            }
+        } catch (SourceException e) {
+            throw SourceUtil.handle(e);
+        } catch (IOException e) {
+            throw new ProcessingException(e);
+        } catch (SAXException e) {
+            throw new ProcessingException(e);
+        } finally {
+            resolver.release(source);
+        }
+    }
+
+    /**
+     * Read a DOM Fragment from a source
+     *
+     * @param location URI of the Source
+     * @param typeParameters Type of Source query. Currently, only
+     *        <code>method</code> parameter (value typically <code>GET</code> or
+     *        <code>POST</code>) is recognized. May be <code>null</code>.
+     * @param parameters Parameters (e.g. URL params) of the source.
+     *        May be <code>null</code>
+     * @param resolver Resolver for the source.
+     *
+     * @return DOM <code>DocumentFragment</code> constructed from the specified
+     *         source.
+     *
+     * @throws ProcessingException
+     */
+    public static DocumentFragment readDOM(String location,
+                                           Parameters typeParameters,
+                                           SourceParameters parameters,
+                                           SourceResolver resolver)
+    throws ProcessingException {
+
+        Source source = null;
+        try {
+            source = SourceUtil.getSource(location, typeParameters, parameters, resolver);
+            Document doc = SourceUtil.toDOM(source);
+
+            DocumentFragment fragment = doc.createDocumentFragment();
+            fragment.appendChild(doc.getDocumentElement());
+
+            return fragment;
+        } catch (SourceException e) {
+            throw SourceUtil.handle(e);
+        } catch (IOException e) {
+            throw new ProcessingException(e);
+        } catch (SAXException e) {
+            throw new ProcessingException(e);
+        } finally {
+            resolver.release(source);
+        }
+    }
+
+    /**
+     * Return the scheme of a URI. Just as there are many different methods
+     * of access to resources, there are a variety of schemes for identifying
+     * such resources.
+     * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Scheme of the URI.
+     */
+    public static String getScheme(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(2);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+
+    /**
+     * Return the authority of a URI. This authority is
+     * typically defined by an Internet-based server or a scheme-specific
+     * registry of naming authorities
+     * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Scheme of the URI.
+     */
+    public static String getAuthority(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(4);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+
+    /**
+     * Return the path of a URI. The path contains data, specific to the
+     * authority (or the scheme if there is no authority component),
+     * identifying the resource within the scope of that scheme and authority
+     * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Path of the URI.
+     */
+    public static String getPath(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(5);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+
+    /**
+     * Return the path of a URI, if the URI can't contains a authority.
+     * This implementation differ to the RFC 2396.
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Path of the URI.
+     */
+    public static String getPathWithoutAuthority(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(4) + re.getParen(5);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+
+    /**
+     * Return the query of a URI. The query is a string of information to
+     * be interpreted by the resource
+     * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Query of the URI.
+     */
+    public static String getQuery(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(7);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+
+    /**
+     * Return the fragment of a URI. When a URI reference is used to perform
+     * a retrieval action on the identified resource, the optional fragment
+     * identifier, consists of additional reference information to be
+     * interpreted by the user agent after the retrieval action has been
+     * successfully completed
+     * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+     *
+     * @param uri Uniform resource identifier.
+     *
+     * @return Fragment of the URI.
+     */
+    public static String getFragment(String uri) {
+        RE re = new RE(uripattern);
+        if (re.match(uri)) {
+            return re.getParen(9);
+        } else {
+            throw new IllegalArgumentException("'" + uri +
+                                               "' is not a correct URI");
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/URLRewriter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/URLRewriter.java
new file mode 100644
index 0000000..dca58bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/URLRewriter.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.XMLConsumer;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * This is an <code>XMLConsumer</code> which rewrites the stream according
+ * to the configuration. The configuration can have the following
+ * parameters:
+ *
+ * <ul>
+ * <li><code>rewriteURLMode</code>: The mode to rewrite the urls. Currently,
+ *     values <code>none</code> and <code>cocoon</code> are supported.
+ * <li><code>baseURL</code>: The current URL to rewrite.
+ * <li><code>cocoonURL</code>: The url all links are resolved to.
+ * <li><code>urlParameterName</code>: The parameter name to use for
+ *     links (all links are then "cocoonURL?urlParameterName=LINK").
+ * </ul>
+ *
+ * <p>URLRewriter rewrites only href, src, background, and action attributes.
+ *
+ * @version $Id$
+ */
+public final class URLRewriter implements XMLConsumer {
+
+    public static final String PARAMETER_MODE = "rewriteURLMode";
+    public static final String MODE_NONE   = "none";
+    public static final String MODE_COCOON = "cocoon";
+    public static final String PARAMETER_PARAMETER_NAME = "urlParameterName";
+    public static final String PARAMETER_URL  = "baseURL";
+    public static final String PARAMETER_COCOON_URL = "cocoonURL";
+
+    /** The <code>ContentHandler</code> */
+    private ContentHandler contentHandler;
+    /** The <code>LexicalHandler</code> */
+    private LexicalHandler lexicalHandler;
+
+    /**
+     * The mode:
+     *  0: no rewriting
+     *  1: cocoon
+     */
+    private int mode;
+
+    /** The base url */
+    private String baseUrl;
+    /** The cocoon url */
+    private String cocoonUrl;
+
+    /**
+     * Create a new rewriter
+     */
+    public URLRewriter(Parameters configuration,
+                       ContentHandler contentHandler,
+                       LexicalHandler lexicalHandler)
+    throws ProcessingException {
+        try {
+            this.contentHandler = contentHandler;
+            this.lexicalHandler = lexicalHandler;
+            this.mode = 0;
+            if (configuration != null &&
+                    MODE_COCOON.equalsIgnoreCase(configuration.getParameter(PARAMETER_MODE, null))) {
+                this.mode = 1;
+                this.baseUrl = configuration.getParameter(PARAMETER_URL);
+                this.cocoonUrl = configuration.getParameter(PARAMETER_COCOON_URL) +
+                        '?' + configuration.getParameter(PARAMETER_PARAMETER_NAME) + '=';
+            }
+        } catch (org.apache.avalon.framework.parameters.ParameterException local) {
+            throw new ProcessingException("URLRewriter: configuration exception.", local);
+        }
+    }
+
+    /**
+     * Create a new rewriter
+     */
+    public URLRewriter(Parameters configuration,
+                       ContentHandler contentHandler)
+    throws ProcessingException {
+        this(configuration, contentHandler,
+             (contentHandler instanceof LexicalHandler ? (LexicalHandler)contentHandler : null));
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void setDocumentLocator(Locator locator) {
+        contentHandler.setDocumentLocator(locator);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startDocument()
+    throws SAXException {
+        contentHandler.startDocument();
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endDocument()
+    throws SAXException {
+        contentHandler.endDocument();
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        contentHandler.startPrefixMapping(prefix,uri);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        contentHandler.endPrefixMapping(prefix);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startElement(String namespace, String name, String raw,
+                             Attributes attr)
+    throws SAXException {
+        if (this.mode == 1) {
+            String attrname;
+            AttributesImpl newattr = null;
+            String value;
+
+            for(int i = 0; i < attr.getLength(); i++) {
+                attrname = attr.getLocalName(i);
+                if (attrname.equals("href") == true ||
+                        attrname.equals("action") == true) {
+                    if (newattr == null) {
+                        newattr = new AttributesImpl(attr);
+                    }
+                    value = attr.getValue(i);
+                    if (value.indexOf(':') == -1) {
+                        try {
+                            URL baseURL = new URL(new URL(this.baseUrl), value);
+                            value = baseURL.toExternalForm();
+                        } catch (MalformedURLException local) {
+                            value = attr.getValue(i);
+                        }
+                    }
+                    newattr.setValue(i, this.cocoonUrl + value);
+                } else if (attrname.equals("src") == true ||
+                        attrname.equals("background") == true) {
+                    if (newattr == null) {
+                        newattr = new AttributesImpl(attr);
+                    }
+                    value = attr.getValue(i);
+                    if (value.indexOf(':') == -1) {
+                        try {
+                            URL baseURL = new URL(new URL(this.baseUrl), value);
+                            value = baseURL.toExternalForm();
+                        } catch (MalformedURLException local) {
+                            value = attr.getValue(i);
+                        }
+                    }
+                    newattr.setValue(i, value);
+                }
+            }
+            if (newattr != null) {
+                contentHandler.startElement(namespace, name, raw, newattr);
+                return;
+            }
+        }
+        contentHandler.startElement(namespace, name, raw, attr);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endElement(String namespace, String name, String raw)
+    throws SAXException {
+        contentHandler.endElement(namespace, name, raw);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void characters(char ary[], int start, int length)
+    throws SAXException {
+        contentHandler.characters(ary, start, length);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void ignorableWhitespace(char ary[], int start, int length)
+    throws SAXException {
+        contentHandler.ignorableWhitespace(ary, start, length);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        contentHandler.processingInstruction(target, data);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        contentHandler.skippedEntity(name);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startDTD(String name, String public_id, String system_id)
+            throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.startDTD(name, public_id, system_id);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endDTD() throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.endDTD();
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startEntity(String name) throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.startEntity(name);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endEntity(String name) throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.endEntity(name);
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void startCDATA() throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.startCDATA();
+    }
+
+    /**
+     * SAX Event Handling
+     */
+    public void endCDATA() throws SAXException {
+        if (lexicalHandler != null) lexicalHandler.endCDATA();
+    }
+
+
+    /**
+     * SAX Event Handling
+     */
+    public void comment(char ary[], int start, int length)
+    throws SAXException {
+        if (this.lexicalHandler != null) {
+            lexicalHandler.comment(ary, start, length);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/helpers/SourceCredential.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/helpers/SourceCredential.java
new file mode 100644
index 0000000..2b04cef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/helpers/SourceCredential.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.helpers;
+
+/**
+ * This class represents a credential for a given user
+ *
+ * @version $Id$
+ */
+public class SourceCredential {
+
+    private String principal = "guest";
+    private String password = "guest";
+
+    /**
+     * Create a new credential
+     *
+     * @param principal The user name
+     */
+    public SourceCredential(String principal) {
+        this.principal = principal;
+    }
+
+    /**
+     * Create a new credential
+     *
+     * @param principal The user name
+     * @param password Password
+     */
+    public SourceCredential(String principal, String password) {
+        this.principal = principal;
+        this.password  = password;
+    }
+
+    /**
+     * Sets the principal
+     *
+     * @param principal The user name
+     */
+    public void setPrincipal(String principal) {
+        this.principal = principal;
+    }
+
+    /**
+     * Returns the principal
+     * 
+     * @return Principal
+     */
+    public String getPrincipal() {
+        return this.principal;
+    }
+
+    /**
+     * Sets the password
+     *
+     * @param password Password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * Returns the password
+     * 
+     * @return Password
+     */
+    public String getPassword() {
+        return this.password;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSource.java
new file mode 100644
index 0000000..9e41f16
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSource.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.blocks.Block;
+import org.apache.cocoon.blocks.BlockEnvironmentHelper;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.wrapper.EnvironmentWrapper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.impl.AbstractSource;
+
+/**
+ * Implementation of a {@link Source} that gets its content by
+ * invoking the Block. 
+ *
+ * @version $Id$
+ */
+public final class BlockSource
+    extends AbstractSource {
+
+    /** The environment */
+    private final EnvironmentWrapper environment;
+
+    /** The name of the called block */
+    private String blockName;
+
+    /** The current block */
+    private final Block block;
+
+    /**
+     * Construct a new object
+     */
+    public BlockSource(ServiceManager manager,
+                       String         uri,
+                       Map            parameters,
+                       Logger         logger)
+        throws MalformedURLException {
+
+        Environment env = EnvironmentHelper.getCurrentEnvironment();
+        if ( env == null ) {
+            throw new MalformedURLException("The block protocol can not be used outside an environment.");
+        }
+        this.block = BlockEnvironmentHelper.getCurrentBlock();
+        if (this.block == null)
+            throw new MalformedURLException("Must be used in a block context " + this.getURI());
+
+        SitemapSourceInfo info = null;
+        try {
+            info = parseBlockURI(env, uri);
+        } catch (URISyntaxException e) {
+            throw new MalformedURLException("Malformed URI in block source " +
+                                            e.getMessage());
+        }
+        setScheme(info.protocol);
+        setSystemId(info.systemId);
+
+        // create environment...
+        this.environment = new EnvironmentWrapper(env, info, logger);
+
+        // ...and put information passed from the parent request to the internal request
+        if ( null != parameters ) {
+            this.environment.getObjectModel().put(ObjectModelHelper.PARENT_CONTEXT, parameters);
+        } else {
+            this.environment.getObjectModel().remove(ObjectModelHelper.PARENT_CONTEXT);
+        }
+
+        this.environment.setURI(info.prefix, info.uri);
+        this.environment.setAttribute(Block.NAME, this.blockName);
+    }
+
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     */
+    public InputStream getInputStream()
+        throws IOException, SourceException {
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        this.environment.setOutputStream(os);
+
+        try {
+            this.block.process(this.environment);
+            
+            return new ByteArrayInputStream(os.toByteArray());
+
+        } catch (Exception e) {
+            throw new SourceException("Exception during processing of " + this.getURI(), e);
+        } finally {
+            // Unhide wrapped environment output stream
+            this.environment.setOutputStream(null);
+        }
+    }
+
+    /**
+     * Returns true always.
+     * @see org.apache.excalibur.source.Source#exists()
+     */
+    public boolean exists() {
+        return true;
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+    }
+
+    // Parse the block protocol.
+    private SitemapSourceInfo parseBlockURI(Environment env, String blockURI) 
+        throws URISyntaxException {
+
+        SitemapSourceInfo info = new SitemapSourceInfo();
+        // Maybe rawMode should be available for the block protocol.
+        info.rawMode = false;
+
+        URI uri = new URI(blockURI);
+
+        // Can't happen
+        if (!uri.isAbsolute()) {
+            throw new URISyntaxException(blockURI,
+                                         "Only absolute URIs are allowed for the block protocol.");
+        }
+        info.protocol = uri.getScheme();
+
+        String baseURI = env.getURIPrefix();
+        if (baseURI.length() == 0 || !baseURI.startsWith("/"))
+            baseURI = "/" + baseURI;
+
+        uri = this.block.resolveURI(new URI(uri.getSchemeSpecificPart()),
+                                    new URI(null, null, baseURI, null));
+        
+        this.blockName = uri.getScheme();
+        info.uri = uri.getPath();
+        // Sub sitemap URI parsing doesn't like URIs starting with "/"
+        if (info.uri.length() != 0 && info.uri.startsWith("/"))
+            info.uri = info.uri.substring(1);
+        // All URIs, also relative are resolved and processed from the block manager
+        info.processFromRoot = true;
+        info.prefix = "";
+        info.requestURI = info.uri;
+        info.queryString = uri.getQuery();
+        info.view = SitemapSourceInfo.getView(info.queryString, env);
+        
+        // FIXME: This will not be a system global id, as the blockName is block local.
+        String ssp = (new URI(this.blockName, null, uri.getPath(), info.queryString, null)).toString();
+        info.systemId = (new URI(info.protocol, ssp, null)).toString();
+        
+        return info;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSourceFactory.java
new file mode 100644
index 0000000..14edcd7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/BlockSourceFactory.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.URIAbsolutizer;
+import org.apache.excalibur.source.SourceUtil;
+
+/**
+ * This class implements the block: protocol.
+ *
+ *
+ * @version $Id$
+ */
+public final class BlockSourceFactory
+    extends AbstractLogEnabled
+    implements SourceFactory, ThreadSafe, Serviceable, URIAbsolutizer
+{
+    
+    /** The <code>ServiceManager</code> */
+    private ServiceManager manager;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource( String location, Map parameters )
+        throws MalformedURLException, IOException {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Creating source object for " + location );
+        }
+
+        return new BlockSource( this.manager,
+                                location,
+                                parameters,
+                                getLogger());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+     */
+    public void release( Source source ) {
+        if ( null != source ) {
+            if ( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug("Releasing source " + source.getURI());
+            }
+            ((BlockSource)source).recycle();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.URIAbsolutizer#absolutize(java.lang.String, java.lang.String)
+     */
+    public String absolutize(String baseURI, String location) {
+        return SourceUtil.absolutize(baseURI, location, true);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java
new file mode 100644
index 0000000..4de4471
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.environment.Context;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceUtil;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.excalibur.source.URIAbsolutizer;
+
+/**
+ * A factory for the context protocol using the context of the servlet api. 
+ * It builds the source by asking the environment context for the real URL
+ * (see {@link org.apache.cocoon.environment.Context#getResource(String)}) 
+ * and then resolving this real URL.
+ *
+ * @version $Id$
+ */
+public class ContextSourceFactory
+extends AbstractLogEnabled
+implements SourceFactory, 
+            Serviceable, 
+            Contextualizable, 
+            ThreadSafe, 
+            URIAbsolutizer {
+
+    /** The context */
+    protected Context envContext;
+
+    /** The ServiceManager */
+    protected ServiceManager manager;
+
+    /** Http servlet context - if available */
+    protected ServletContext servletContext;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(org.apache.avalon.framework.context.Context context)
+    throws ContextException {
+        this.envContext = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
+        try {
+            this.servletContext = ((ServletConfig) context.get("servlet-config")).getServletContext();
+        } catch (ContextException ignore) {
+            // in other environments (CLI etc.), we don't have a servlet context
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource( String location, Map parameters )
+    throws SourceException, MalformedURLException, IOException {
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "Creating source object for " + location );
+        }
+
+        // Lookup resolver 
+        SourceResolver resolver = null;
+        try {
+            resolver = (SourceResolver)this.manager.lookup( SourceResolver.ROLE );
+
+            // Remove the protocol and the first '/'
+            final int pos = location.indexOf(":/");
+            final String scheme = location.substring(0, pos);
+            final String path = location.substring(pos+1);
+            
+            // fix for #24093, we don't give access to files outside the context:
+            if ( path.indexOf("../") != -1 ) {
+                throw new MalformedURLException("Invalid path ('../' is not allowed) : " + path);
+            }
+            
+            URL u;
+            
+            // Try to get a file first and fall back to a resource URL
+            String actualPath = envContext.getRealPath(path);
+            if (actualPath != null) {
+                u = new File(actualPath).toURL();
+            } else {
+                u = envContext.getResource(path);
+            }
+
+            if (u != null) {
+                Source source = resolver.resolveURI(u.toExternalForm());
+                if ( parameters != null 
+                     && BooleanUtils.toBoolean("force-traversable")
+                     && this.servletContext != null 
+                     && !(source instanceof TraversableSource) ) {
+                    final Set children = this.servletContext.getResourcePaths(path + '/');
+                    if ( children != null ) {
+                        source = new TraversableContextSource(source, children, this, path, scheme);
+                    }
+                }
+                return source;                
+            } 
+            final String message = location + " could not be found. (possible context problem)";
+            this.getLogger().info(message);
+            throw new MalformedURLException(message);
+        } catch (ServiceException se) {
+            throw new SourceException("Unable to lookup source resolver.", se);
+        } finally {
+            this.manager.release( resolver );
+        }
+                
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+     */
+    public void release( Source source ) {
+        // In fact, this method should never be called as this factory
+        // returns a source object from a different factory. So that
+        // factory should release the source
+        if ( null != source ) {
+            if ( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug("Releasing source " + source.getURI());
+            }
+            SourceResolver resolver = null;
+            try {
+                resolver = (SourceResolver)this.manager.lookup( SourceResolver.ROLE );
+                if ( source instanceof TraversableContextSource ) {
+                    resolver.release(((TraversableContextSource)source).wrappedSource);
+                } else {
+                    resolver.release( source );
+                }
+            } catch (ServiceException ingore) {
+                // we ignore this
+            } finally {
+                this.manager.release( resolver );
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.URIAbsolutizer#absolutize(java.lang.String, java.lang.String)
+     */
+    public String absolutize(String baseURI, String location) {
+        return SourceUtil.absolutize(baseURI, location, true);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/DelayedRefreshSourceWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/DelayedRefreshSourceWrapper.java
new file mode 100644
index 0000000..ff15df1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/DelayedRefreshSourceWrapper.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * A wrapper around a <code>Source</code> that reduces the number of calls to
+ * <code>Source.getLastModified()</code> which can be a costly operation.
+ *
+ * @version $Id$
+ */
+public final class DelayedRefreshSourceWrapper
+    implements Source {
+
+    private Source source;
+
+    private long delay;
+
+    private long nextCheckTime = 0;
+
+    private long lastModified = 0;
+
+    /**
+     * Creates a wrapper for a <code>Source</code> which ensures that
+     * <code>Source.getLastModified()</code> won't be called more than once per
+     * <code>delay</code> milliseconds period.
+     *
+     * @param source the wrapped <code>Source</code>
+     * @param delay  the last-modified refresh delay, in milliseconds
+     */
+    public DelayedRefreshSourceWrapper(Source source, long delay) {
+        this.source = source;
+        this.delay = delay;
+    }
+    
+    /**
+     * Get the real source
+     */
+    public Source getSource() {
+        return this.source;
+    }
+    
+    public final InputStream getInputStream()
+    throws SourceException, IOException {
+        return this.source.getInputStream();
+    }
+
+    public final String getURI() {
+        return this.source.getURI();
+    }
+
+    /**
+     *  Get the Validity object. This can either wrap the last modification
+     *  date or the expires information or...
+     *  If it is currently not possible to calculate such an information
+     *  <code>null</code> is returned.
+     */
+    public SourceValidity getValidity() {
+        return this.source.getValidity();
+    }
+
+    /**
+     * Return the protocol identifier.
+     */
+    public String getScheme() {
+        return this.source.getScheme();
+    }
+
+    /**
+     * 
+     * @see org.apache.excalibur.source.Source#exists()
+     */
+    public boolean exists() {
+        return this.source.exists();
+    }
+    
+    /**
+     * Get the last modification time for the wrapped <code>Source</code>. The
+     * age of the returned information is guaranteed to be lower than or equal to
+     * the delay specified in the constructor.
+     * <p>
+     * This method is also thread-safe, even if the underlying Source is not.
+     *
+     * @return the last modification time.
+     */
+    public final long getLastModified() {
+
+        // Do we have to refresh the source ?
+        if (System.currentTimeMillis() >= nextCheckTime) {
+            // Yes
+            this.refresh();
+        }
+        return this.lastModified;
+    }
+
+    /**
+     * Force the refresh of the wrapped <code>Source</code>, even if the refresh period
+     * isn't over, and starts a new period.
+     * <p>
+     * This method is thread-safe, even if the underlying Source is not.
+     */
+    public synchronized final void refresh() {
+
+        this.nextCheckTime = System.currentTimeMillis() + this.delay;
+        // Refresh modifiable sources
+        this.source.refresh();
+
+        // Keep the last modified date
+        this.lastModified = source.getLastModified();
+    }
+
+    public final long getContentLength() {
+        return this.source.getContentLength();
+    }
+
+    /**
+     * The mime-type of the content described by this object.
+     * If the source is not able to determine the mime-type by itself
+     * this can be <code>null</code>.
+     */
+    public String getMimeType() {
+        return this.source.getMimeType();
+    }
+
+    public final void recycle() {
+        if (this.source instanceof Recyclable) {
+            ((Recyclable)this.source).recycle();
+        }
+    }
+
+    /**
+     * Get the value of a parameter.
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public String getParameter(String name) {
+        return null;
+    }
+
+    /**
+     * Get the value of a parameter.
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public long getParameterAsLong(String name) {
+        return 0;
+    }
+
+    /**
+     * Get parameter names
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public Iterator getParameterNames() {
+        return java.util.Collections.EMPTY_LIST.iterator();
+
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySource.java
new file mode 100644
index 0000000..a9ba80d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySource.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A <code>Source</code> that generates completely empty XML document or an
+ * XML document that contains just a root node.
+ *
+ * <p>
+ * The URI syntax is <code>empty:</code> for completely empty XML document
+ * or <code>create-document:root-element</code> for document with root element,
+ * where <code>root-element</code> is the name of the root element to create.
+ *
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class EmptySource implements XMLizable, Source {
+
+    protected String rootElementName;
+    protected String scheme;
+    protected String uri;
+    protected String xmlDocument;
+
+    public EmptySource(String location) {
+        this.uri = location;
+        final int pos = location.indexOf(':');
+        this.scheme = location.substring(0, pos);
+
+        final String rootName = location.substring(pos + 1);
+        if (rootName != null && rootName.trim().length() > 0) {
+            this.rootElementName = rootName.trim();
+            this.xmlDocument = '<' + this.rootElementName + "/>";
+        } else {
+            this.xmlDocument = "";
+        }
+    }
+
+    /**
+     * @see org.apache.excalibur.xml.sax.XMLizable#toSAX(org.xml.sax.ContentHandler)
+     */
+    public void toSAX(ContentHandler handler) throws SAXException {
+        handler.startDocument();
+        if (rootElementName != null) {
+            XMLUtils.createElement(handler, this.rootElementName);
+        }
+        handler.endDocument();
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#exists()
+     */
+    public boolean exists() {
+        return true;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getContentLength()
+     */
+    public long getContentLength() {
+        return this.xmlDocument.length();
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getInputStream()
+     */
+    public InputStream getInputStream() throws IOException, SourceNotFoundException {
+        return new ByteArrayInputStream(this.xmlDocument.getBytes("utf-8"));
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getLastModified()
+     */
+    public long getLastModified() {
+        // this document *never* changes
+        return 1;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getMimeType()
+     */
+    public String getMimeType() {
+        return "text/xml";
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getScheme()
+     */
+    public String getScheme() {
+        return this.scheme;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getURI()
+     */
+    public String getURI() {
+        return this.uri;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getValidity()
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#refresh()
+     */
+    public void refresh() {
+        // nothing to do here
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySourceFactory.java
new file mode 100644
index 0000000..5684236
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/EmptySourceFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+
+/**
+ * A factory for 'empty:' sources (see {@link EmptySource}).
+ *
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class EmptySourceFactory extends AbstractLogEnabled
+                                implements SourceFactory, ThreadSafe {
+
+    /**
+     * Get an {@link EmptySource} object.
+     *
+     * @param location   The URI to resolve - this URI includes the scheme.
+     * @param parameters this is optional and not used here
+     *
+     * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource(String location, Map parameters)
+    throws IOException, MalformedURLException {
+        return new EmptySource(location);
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+     */
+    public void release(Source source) {
+        // Do nothing here
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSource.java
new file mode 100644
index 0000000..9585713
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSource.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.impl.AbstractSource;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+
+import org.apache.commons.jxpath.JXPathContext;
+
+
+/**
+ * A <code>Source</code> that takes its content from a
+ * module.
+ * <p>The URI syntax is
+ * "module:<input-module>:<attribute-name>[#XPath]",
+ * where :
+ * <ul>
+ * <li>an input-module name is used for finding an input-module for reading data from</li>,
+ * <li>"attribute-name" is the name of the attribute found in the module</li>,
+ * <li>"XPath" is an XPath that is aplied on the object in the
+ * attribute, by using JXPath.</li>
+ * </ul>
+ * </p>
+ *
+ */
+public class ModuleSource
+    extends AbstractSource {
+
+    private final static String SCHEME = "module";
+    private String attributeType;
+    private String attributeName;
+    private String xPath;
+    private ServiceManager manager;
+    private Map objectModel;
+    private Logger logger;
+    
+    /**
+     * Create a module source from a 'module:' uri and a the object model.
+     * <p>The uri is of the form "module:attribute-type:attribute-name#xpath</p>
+     */
+    public ModuleSource( Map objectModel, String uri,
+                         ServiceManager manager, Logger logger )
+        throws MalformedURLException {
+
+        this.objectModel = objectModel;
+        this.manager = manager;
+        this.logger = logger;
+
+        setSystemId( uri );
+
+        // Scheme
+        int start = 0;
+        int end = uri.indexOf( ':' );
+        if ( end == -1 )
+            throw new MalformedURLException("Malformed uri for module source (cannot find scheme) : " + uri);
+
+        String scheme = uri.substring( start, end );
+        if ( !SCHEME.equals( scheme ) )
+            throw new MalformedURLException("Malformed uri for a module source : " + uri);
+
+        setScheme( scheme );
+
+        // Attribute type
+        start = end + 1;
+        end = uri.indexOf( ':', start );
+        if ( end == -1 ) {
+            throw new MalformedURLException("Malformed uri for module source (cannot find attribute type) : " + uri);
+        }
+        this.attributeType = uri.substring( start, end );
+
+        // Attribute name
+        start = end + 1;
+        end = uri.indexOf( '#', start );
+
+        if ( end == -1 )
+            end = uri.length();
+
+        if ( end == start )
+            throw new MalformedURLException("Malformed uri for module source (cannot find attribute name) : " + uri);
+
+        this.attributeName = uri.substring( start, end );
+
+        // xpath
+        start = end + 1;
+        this.xPath = start < uri.length() ? uri.substring( start ) : "";
+    }
+    
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     *
+     * @throws IOException if I/O error occured.
+     */
+    public InputStream getInputStream() throws IOException, SourceException {
+        if ( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "Getting InputStream for " + getURI() );
+        }
+
+        Object obj = getInputAttribute( this.attributeType, this.attributeName );
+        if ( obj == null )
+            throw new SourceException( " The attribute: " + this.attributeName +
+                                       " is empty" );
+
+        if ( !(this.xPath.length() == 0 || this.xPath.equals( "/" )) ) {
+            JXPathContext context = JXPathContext.newContext( obj );
+            obj = context.getValue( this.xPath );
+
+            if ( obj == null )
+                throw new SourceException( "the xpath: " + this.xPath +
+                                           " applied on the attribute: " +
+                                           this.attributeName +
+                                           " returns null");
+        }
+
+        if ( obj instanceof InputStream ) {
+            return (InputStream)obj;
+        } else if ( obj instanceof Source ) {
+            return ((Source)obj).getInputStream();
+        } else if ( obj instanceof String ) {
+            return new ByteArrayInputStream( ((String)obj).getBytes() );
+        } else if (obj instanceof byte[]) {
+            return new ByteArrayInputStream((byte[]) obj);
+        } else {
+            throw new SourceException( "The object type: " + obj.getClass() +
+                                       " could not be serialized as a InputStream " + obj );
+        }
+    }
+
+    /**
+     * Does this source actually exist ?
+     *
+     * @return true if the resource exists.
+     *
+     */
+    public boolean exists() {
+        boolean exists = false;
+        try {
+            exists = getInputAttribute( this.attributeType, this.attributeName ) != null;
+        } catch ( SourceException e ) {
+            exists = false;
+        }
+        return exists;
+    }
+
+    private Object getInputAttribute( String inputModuleName, String attributeName )
+        throws  SourceException {
+        Object obj;
+        ServiceSelector selector = null;
+        InputModule inputModule = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup( InputModule.ROLE + "Selector" );
+            inputModule = (InputModule) selector.select( inputModuleName );
+            obj = inputModule.getAttribute( attributeName, null, this.objectModel );
+
+        } catch ( ServiceException e ) {
+            throw new SourceException( "Could not find an InputModule of the type " + 
+                                       inputModuleName , e );
+        } catch ( ConfigurationException e ) {
+            throw new SourceException( "Could not find an attribute: " + attributeName +
+                                       " from the InputModule " + inputModuleName, e );
+        } finally {
+            if ( inputModule != null ) selector.release( inputModule );
+            this.manager.release( selector );
+        }
+
+        return obj;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSourceFactory.java
new file mode 100644
index 0000000..d47247f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ModuleSourceFactory.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+
+import org.apache.cocoon.components.ContextHelper;
+
+/**
+ * A factory for 'module:' sources (see {@link ModuleSource}). 
+ *
+ */
+public class ModuleSourceFactory extends AbstractLogEnabled
+  implements SourceFactory, Serviceable, Contextualizable, ThreadSafe {
+    
+    private ServiceManager manager;
+    private Context context;
+
+    /**
+     * Servicable Interface
+     */
+    public void service( ServiceManager manager ) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Contextualizable, get the object model
+     */
+    public void contextualize( Context context ) throws ContextException {
+        this.context = context;
+    }
+    
+
+    /**
+     * Get a {@link ModuleSource} object.
+     * 
+     * @param location   The URI to resolve - this URI includes the scheme.
+     * @param parameters this is optional and not used here
+     */
+    public Source getSource( String location, Map parameters )
+        throws IOException, MalformedURLException {
+
+        Map objectModel = ContextHelper.getObjectModel( this.context );
+        return new ModuleSource( objectModel, location, this.manager, getLogger() );
+    }
+    
+    /**
+     * Release a {@link Source} object.
+     */
+    public void release( Source source ) {
+        // Do nothing here
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/MultiSourceValidity.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/MultiSourceValidity.java
new file mode 100644
index 0000000..b3f6cb1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/MultiSourceValidity.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AbstractAggregatedValidity;
+
+/**
+ * <p>An aggregated {@link SourceValidity} for multiple sources.</p>
+ *
+ * @version $Id$
+ */
+public class MultiSourceValidity extends AbstractAggregatedValidity
+                                 implements SourceValidity {
+
+    /** <p>When validity expiration is performed.</p> */
+    private long expiry;
+
+    /** <p>The delay from <b>now</b> used to calculate the expiration time.</p> */
+    private long delay;
+
+    /** <p>An ordered list of URIs which should be checked.</p> */
+    private List uris = new ArrayList();
+
+    /** <p>Is this instance is closed (accepts modifications or is validable)? */
+    private boolean isClosed = false;
+
+    /** <p>The {@link SourceResolver} to use (transient not to be serialized). */
+    private transient SourceResolver resolver;
+
+    /**
+     * <p>The delay value indicating to check always.</p>
+     */
+    public static final int CHECK_ALWAYS = -1;
+
+    /**
+     * <p>Create a new {@link MultiSourceValidity} instance.</p>
+     *
+     * <p>If the number of milliseconds is less than <b>zero</b>, or it's sum with
+     * the number of <b>now</b> milliseconds is greater than the biggest long
+     * representable, the expiration date will be set to {@link Long#MAX_VALUE}
+     * milliseconds from the epoch.</p>
+     *
+     * @param resolver the {@link SourceResolver} used to access the sources.
+     * @param delay the number of milliseconds from <b>now</b> defining for how long
+     *              this instance will be valid.
+     */
+    public MultiSourceValidity(SourceResolver resolver, long delay) {
+        /* Calculate the initial expiration time and calculate the delay */
+        this.resolver = resolver;
+        this.expiry = System.currentTimeMillis() + delay;
+        this.delay = delay;
+    }
+
+    /**
+     * <p>Add a {@link Source} to the list of {@link Source}s monitored by this
+     * instance.</p>
+     *
+     * @param src a <b>non-null</b> {@link Source}.
+     */
+    public void addSource(Source src) {
+        if (this.uris != null) {
+            SourceValidity validity = src.getValidity();
+            if (validity == null) {
+                /* The source has no validity: this will be always be invalid. */
+                this.uris = null;
+            } else {
+                /* Add the validity and URI to the list */
+                super.add(validity);
+                this.uris.add(src.getURI());
+            }
+        }
+    }
+
+    /**
+     * <p>Close this instance, or in other words declare that no other sources will
+     * be added to this {@link MultiSourceValidity} and that checkings can be now
+     * performed.</p>
+     */
+    public void close() {
+        this.isClosed = true;
+        this.resolver = null;
+    }
+
+    /**
+     * <p>Check the validity of this {@link SourceValidity} instance.</p>
+     *
+     * @see SourceValidity#isValid()
+     */
+    public int isValid() {
+        if (System.currentTimeMillis() <= expiry) {
+            /* Validity not expired, so, don't even check */
+            return SourceValidity.VALID;
+        }
+
+        /* Re-calculate the expiry time based on the current time */
+        expiry = System.currentTimeMillis() + delay;
+
+        if (uris == null || !isClosed) {
+            /* We have not been closed (yet) or we were forced to be invalid */
+            return SourceValidity.INVALID;
+        } else {
+            /* Compute the status of all the sources listed in this instance */
+            return computeStatus(null);
+        }
+    }
+
+    /**
+     * <p>Check the validity of this instance comparing it with a (recently acquired)
+     * new {@link SourceValidity} object.</p>
+     *
+     * @see SourceValidity#isValid(SourceValidity)
+     */
+    public int isValid(SourceValidity newValidity) {
+        if (uris == null || !isClosed) {
+            /* We have not been closed (yet) or we were forced to be invalid */
+            return SourceValidity.INVALID;
+        }
+
+        /* Perform a simple class check and compute the validity of the sources */
+        if (newValidity instanceof MultiSourceValidity) {
+            return computeStatus(((MultiSourceValidity)newValidity).resolver);
+        } else {
+            /* The supplied validity is not an instance of ourselves, forget it */
+            return SourceValidity.INVALID;
+        }
+    }
+
+    /**
+     * <p>Compute the status of this instance by checking every source.</p>
+     *
+     * @param resolver The {@link SourceResolver} to use to access sources.
+     * @return {@link SourceValidity.VALID}, {@link SourceValidity.INVALID} or
+     *         {@link SourceValidity.UNKNOWN} depending on the status.
+     */
+    private int computeStatus(SourceResolver resolver) {
+        /* Get the validities and analyse them one by one */
+        List validities = super.getValidities();
+        for (int i = 0; i < validities.size(); i++) {
+
+            /* Check the validity status */
+            SourceValidity validity = (SourceValidity) validities.get(i);
+            switch (validity.isValid()) {
+
+                /* The current source is valid: just continue to next source */
+                case SourceValidity.VALID:
+                    break;
+
+                /* The current source is invalid: stop examining */
+                case SourceValidity.INVALID:
+                    return SourceValidity.INVALID;
+
+                /* The source validity is not known: check with the new source */
+                case SourceValidity.UNKNOWN:
+                    /* We have no resolver: definitely don't know */
+                    if (resolver == null) {
+                        return SourceValidity.UNKNOWN;
+                    }
+
+                    /* Check the new source by asking to the resolver */
+                    Source newSrc = null;
+                    int newValidity = SourceValidity.INVALID;
+                    try {
+                        newSrc = resolver.resolveURI((String) this.uris.get(i));
+                        newValidity = validity.isValid(newSrc.getValidity());
+                    } catch(IOException ioe) {
+                        /* Swallow the IOException, but set the new validity */
+                        newValidity = SourceValidity.INVALID;
+                    } finally {
+                        /* Make sure that the source is released */
+                        if (newSrc != null) {
+                            resolver.release(newSrc);
+                        }
+                    }
+
+                    /* If the source is still valid, go to the next one */
+                    if (newValidity == SourceValidity.VALID) {
+                        break;
+                    }
+
+                    /* The source is not valid (or unknown), we invalidate the lot */
+                    return SourceValidity.INVALID;
+
+                /* We got something _really_ odd out tof the validity, dunno. */
+                default:
+                    return SourceValidity.INVALID;
+            }
+        }
+
+        /* All items checked successfully */
+        return SourceValidity.VALID;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSource.java
new file mode 100644
index 0000000..e29f47c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSource.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.SourceNotFoundException;
+
+import org.apache.cocoon.servlet.multipart.Part;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import java.net.MalformedURLException;
+import java.util.Map;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * Implementation of a {@link Source} that gets its content
+ * from a PartOnDisk or PartInMemory held in the Request when
+ * a file is uploaded.
+ *
+ * @version $Id$
+ */
+public class PartSource implements Source
+{
+    /* hold a private ref to the protocol used to call the Source */
+    private String protocol;
+
+    /* hold a private ref to the full uri */
+    private String uri;
+
+    /* hold a private ref to the Part which has been uploaded. */
+    private Part part;
+
+    /**
+     * Builds a PartSource given an URI.
+     * @param uri e.g., upload://formField1
+     * @throws SourceException
+     * @throws MalformedURLException
+     */
+    public PartSource(String uri, Map objectModel) throws MalformedURLException, SourceException
+    {
+        // set the uri for use in getURI()
+        this.uri = uri;
+
+        int position = uri.indexOf(':') + 1;
+        if (position != 0)
+        {
+            // set the protocol for use in getScheme()
+            this.protocol = uri.substring(0, position-1);
+        }
+        else
+        {
+            // if the URI is not correctly formatted then throw an excpetion
+            throw new MalformedURLException("No protocol found for part source in " + uri);
+        }
+
+        // get the request parameter name: the bit after ://
+        String location = uri.substring(position + 2);
+
+        // get the cocoon request from the object model.
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        // try and cast the request object to a Part
+        Object obj = request.get(location);
+        if (obj instanceof Part)
+        {
+             part = (Part) obj;
+        }
+        else
+        {
+             throw new SourceException("Request object " + location + " is not an uploaded Part");
+        }
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getInputStream()
+     */
+    public InputStream getInputStream() throws IOException, SourceNotFoundException
+    {
+        try
+        {
+            return part.getInputStream();
+        }
+        catch (Exception ex)
+        {
+            throw new SourceNotFoundException("The part source can not be found.");
+        }
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getMimeType()
+     */
+    public String getMimeType()
+    {
+        return part.getMimeType();
+    }
+
+    /**
+      * @return true if the resource exists.
+      */
+    public boolean exists()
+    {
+        return part != null;
+    }
+
+    /*
+     * @see org.apache.excalibur.source.Source#getURI()
+     */
+    public String getURI()
+    {
+        return uri;
+    }
+
+    /*
+     * @see org.apache.excalibur.source.Source#getScheme()
+     */
+    public String getScheme()
+    {
+        return this.protocol;
+    }
+
+    /*
+     * Not used, Parts are not cacheable.
+     */
+    public SourceValidity getValidity()
+    {
+        // not sure what happens here.
+        return null;
+    }
+
+    /**
+      * @see org.apache.excalibur.source.Source#refresh()
+      */
+    public void refresh()
+    {
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getContentLength()
+     */
+    public long getContentLength()
+    {
+        return part.getSize();
+    }
+
+    /**
+     * @see org.apache.excalibur.source.Source#getLastModified()
+     */
+    public long getLastModified()
+    {
+        return 0;
+    }
+    
+    public Part getPart() {
+        return this.part;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSourceFactory.java
new file mode 100644
index 0000000..c68f320
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/PartSourceFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+/**
+ * A factory for {@link org.apache.cocoon.servlet.multipart.Part} based sources (see {@link PartSource}).
+ *
+ * @version $Id$
+ */
+public class PartSourceFactory implements SourceFactory, Contextualizable, ThreadSafe
+{
+    Context context;
+    
+    /*
+     * Returns a new {@link PartSource} based on the uri.
+     *
+     * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource(String uri, Map parameters) throws IOException, MalformedURLException
+    {
+        Map objectModel = ContextHelper.getObjectModel(context);
+        return new PartSource(uri, objectModel);
+    }
+
+    /**
+     * Do nothing, {@link PartSource}s don't need to be released.
+     *
+     * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+     */
+    public void release(Source source)
+    {
+        // Nothing to do here
+    }
+
+    /**
+     * Get the objectModel from the Context
+     */
+    public void contextualize(org.apache.avalon.framework.context.Context context)
+    throws ContextException {
+         this.context = context;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSource.java
new file mode 100644
index 0000000..8bb6965
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSource.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.wrapper.EnvironmentWrapper;
+import org.apache.cocoon.environment.wrapper.MutableEnvironmentFacade;
+import org.apache.cocoon.xml.ContentHandlerWrapper;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * Implementation of a {@link Source} that gets its content
+ * by invoking a pipeline.
+ *
+ * @version $Id$
+ */
+public final class SitemapSource
+        extends AbstractLogEnabled
+        implements Source, XMLizable {
+
+    /** The internal event pipeline validities */
+    private SitemapSourceValidity validity;
+
+    /** The system id */
+    private final String systemId;
+
+    /** The system id used for caching */
+    private String systemIdForCaching;
+
+    /** The current ServiceManager */
+    private final ServiceManager manager;
+
+    /** The processor */
+    private final Processor processor;
+
+    /** The pipeline description */
+    private Processor.InternalPipelineDescription pipelineDescription;
+
+    /** The environment */
+    private final MutableEnvironmentFacade environment;
+
+    /** The redirect <code>Source</code> */
+    private Source redirectSource;
+
+    /** The <code>SAXException</code> if unable to get resource */
+    private SAXException exception;
+
+    /** Do I need a refresh ? */
+    private boolean needsRefresh;
+
+    /** Is start processing on the environment called? */
+    private boolean processed;
+
+    /** The used protocol */
+    private final String protocol;
+
+    /** SourceResolver (for the redirect source) */
+    private SourceResolver sourceResolver;
+
+    private String mimeType;
+
+    /**
+     * Construct a new object
+     */
+    public SitemapSource(ServiceManager manager,
+                         String         uri,
+                         Map            parameters,
+                         Logger         logger)
+    throws MalformedURLException {
+
+        Environment env = EnvironmentHelper.getCurrentEnvironment();
+        if ( env == null ) {
+            throw new MalformedURLException("The cocoon protocol can not be used outside an environment.");
+        }
+        this.manager = manager;
+        this.enableLogging(logger);
+
+        SitemapSourceInfo info = SitemapSourceInfo.parseURI(env, uri);
+        this.protocol = info.protocol;
+
+        // does the uri point to this sitemap or to the root sitemap?
+        if (info.processFromRoot) {
+            this.processor = EnvironmentHelper.getCurrentProcessor().getRootProcessor();
+        } else {
+            this.processor = EnvironmentHelper.getCurrentProcessor();
+        }
+
+        // create environment...
+        final EnvironmentWrapper wrapper = new EnvironmentWrapper(env, info, logger);
+
+        // The environment is a facade whose delegate can be changed in case of internal redirects
+        this.environment = new MutableEnvironmentFacade(wrapper);
+
+        // ...and put information passed from the parent request to the internal request
+        if ( null != parameters ) {
+            this.environment.getObjectModel().put(ObjectModelHelper.PARENT_CONTEXT, parameters);
+        } else {
+            this.environment.getObjectModel().remove(ObjectModelHelper.PARENT_CONTEXT);
+        }
+
+        this.systemId = info.systemId;
+
+        // create a new validity holder
+        this.validity = new SitemapSourceValidity();
+
+        // initialize
+        this.init();
+    }
+
+    /**
+     * Return the protocol identifier.
+     */
+    public String getScheme() {
+        return this.protocol;
+    }
+
+    /**
+     * Get the content length of the source or -1 if it
+     * is not possible to determine the length.
+     */
+    public long getContentLength() {
+        return -1;
+    }
+
+    /**
+     * Get the last modification date.
+     * @return The last modification in milliseconds since January 1, 1970 GMT
+     *         or 0 if it is unknown
+     */
+    public long getLastModified() {
+        return 0;
+    }
+
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     */
+    public InputStream getInputStream()
+    throws IOException, SourceException {
+
+        if (this.needsRefresh) {
+            this.refresh();
+        }
+        // VG: Why exception is not thrown in constructor?
+        if (this.exception != null) {
+            throw new SourceException("Cannot get input stream for " + getURI(), this.exception);
+        }
+
+        if (this.redirectSource != null) {
+            return this.redirectSource.getInputStream();
+        }
+
+        try {
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            this.environment.setOutputStream(os);
+            EnvironmentHelper.enterProcessor(this.pipelineDescription.lastProcessor,
+                                            this.manager,
+                                            this.environment);
+            try {
+
+                this.pipelineDescription.processingPipeline.process(this.environment);
+            } finally {
+                EnvironmentHelper.leaveProcessor();
+            }
+
+            return new ByteArrayInputStream(os.toByteArray());
+
+        } catch (ResourceNotFoundException e) {
+            throw new SourceNotFoundException("Exception during processing of " + this.systemId, e);
+        } catch (Exception e) {
+            throw new SourceException("Exception during processing of " + this.systemId, e);
+        } finally {
+            // Unhide wrapped environment output stream
+            this.environment.setOutputStream(null);
+            this.needsRefresh = true;
+        }
+    }
+
+    /**
+     * Returns the unique identifer for this source
+     */
+    public String getURI() {
+        return this.systemIdForCaching;
+    }
+
+    /**
+     * Returns true always.
+     * @see org.apache.excalibur.source.Source#exists()
+     */
+    public boolean exists() {
+        return true;
+    }
+
+    /**
+     * Get the validity object. This wraps validity of the enclosed event
+     * pipeline. If pipeline is not cacheable, <code>null</code> is returned.
+     */
+    public SourceValidity getValidity() {
+        return this.validity.getNestedValidity() == null? null: this.validity;
+    }
+
+    /**
+     * The mime-type of the content described by this object.
+     * If the source is not able to determine the mime-type by itself
+     * this can be null.
+     */
+     public String getMimeType() {
+         return this.mimeType;
+     }
+
+    /**
+     * Refresh this object and update the last modified date
+     * and content length.
+     */
+    public void refresh() {
+        this.reset();
+        this.init();
+    }
+
+    /**
+     * Initialize
+     */
+    protected void init() {
+        this.systemIdForCaching = this.systemId;
+        try {
+            this.environment.startingProcessing();
+            this.processed = true;
+            this.pipelineDescription = this.processor.buildPipeline(this.environment);
+            this.environment.setURI(this.pipelineDescription.prefix, this.pipelineDescription.uri);
+
+            String redirectURL = this.environment.getRedirectURL();
+            if (redirectURL == null) {
+
+                EnvironmentHelper.enterProcessor(this.pipelineDescription.lastProcessor,
+                                                 this.manager,
+                                                 this.environment);
+                try {
+                    this.pipelineDescription.processingPipeline.prepareInternal(this.environment);
+                    this.validity.set(this.pipelineDescription.processingPipeline.getValidityForEventPipeline());
+                    final String eventPipelineKey = this.pipelineDescription.processingPipeline.getKeyForEventPipeline();
+                    this.mimeType = this.environment.getContentType();
+
+                    if (eventPipelineKey != null) {
+                        StringBuffer buffer = new StringBuffer(this.systemId);
+                        if (this.systemId.indexOf('?') == -1) {
+                            buffer.append('?');
+                        } else {
+                            buffer.append('&');
+                        }
+                        buffer.append("pipelinehash=");
+                        buffer.append(eventPipelineKey);
+                        this.systemIdForCaching = buffer.toString();
+                    } else {
+                        this.systemIdForCaching = this.systemId;
+                    }
+                } finally {
+                    EnvironmentHelper.leaveProcessor();
+                }
+            } else {
+                if (redirectURL.indexOf(":") == -1) {
+                    redirectURL = this.protocol + ":/" + redirectURL;
+                }
+                if (this.sourceResolver == null) {
+                    this.sourceResolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+                }
+                this.redirectSource = this.sourceResolver.resolveURI(redirectURL);
+                this.validity.set(this.redirectSource.getValidity());
+                this.mimeType = this.redirectSource.getMimeType();
+            }
+        } catch (SAXException e) {
+            reset();
+            this.exception = e;
+        } catch (Exception e) {
+            reset();
+            this.exception = new SAXException("Could not get sitemap source " + this.systemId, e);
+        }
+        this.needsRefresh = false;
+    }
+
+    /**
+     * Stream content to the content handler
+     */
+    public void toSAX(ContentHandler contentHandler)
+    throws SAXException {
+        if (this.needsRefresh) {
+            this.refresh();
+        }
+        if (this.exception != null) {
+            throw this.exception;
+        }
+        try {
+            if (this.redirectSource != null) {
+                SourceUtil.parse(this.manager, this.redirectSource, contentHandler);
+            } else {
+                XMLConsumer consumer;
+                if (contentHandler instanceof XMLConsumer) {
+                    consumer = (XMLConsumer)contentHandler;
+                } else if (contentHandler instanceof LexicalHandler) {
+                    consumer = new ContentHandlerWrapper(contentHandler, (LexicalHandler)contentHandler);
+                } else {
+                    consumer = new ContentHandlerWrapper(contentHandler);
+                }
+                // We have to add an environment changer
+                // for clean environment stack handling.
+                EnvironmentHelper.enterProcessor(this.pipelineDescription.lastProcessor,
+                                                 this.manager,
+                                                 this.environment);
+                try {
+                    this.pipelineDescription.processingPipeline.process(this.environment,
+                                                                        EnvironmentHelper.createEnvironmentAwareConsumer(consumer));
+                } finally {
+                    EnvironmentHelper.leaveProcessor();
+                }
+            }
+        } catch (SAXException e) {
+            // Preserve original exception
+            throw e;
+        } catch (Exception e) {
+            throw new SAXException("Exception during processing of " + this.systemId, e);
+        } finally {
+            this.needsRefresh = true;
+        }
+    }
+
+    /**
+     * Reset everything
+     */
+    private void reset() {
+        if (this.pipelineDescription != null) {
+            this.pipelineDescription.release();
+            this.pipelineDescription = null;
+        }
+
+        if (this.processed) {
+            this.processed = false;
+            this.environment.finishingProcessing();
+        }
+
+        if (this.redirectSource != null) {
+            this.sourceResolver.release(this.redirectSource);
+            this.redirectSource = null;
+        }
+
+        this.validity.set(null);
+
+        this.environment.reset();
+        this.exception = null;
+        this.needsRefresh = true;
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        this.validity = new SitemapSourceValidity();
+        this.reset();
+        if ( this.sourceResolver != null ) {
+            this.manager.release( this.sourceResolver );
+            this.sourceResolver = null;
+        }
+    }
+
+    /**
+     * Get the value of a parameter.
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public String getParameter(String name) {
+        return null;
+    }
+
+    /**
+     * Get the value of a parameter.
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public long getParameterAsLong(String name) {
+        return 0;
+    }
+
+    /**
+     * Get parameter names
+     * Using this it is possible to get custom information provided by the
+     * source implementation, like an expires date, HTTP headers etc.
+     */
+    public Iterator getParameterNames() {
+        return java.util.Collections.EMPTY_LIST.iterator();
+    }
+
+    /**
+     * A simple SourceValidity protecting callers from resets.
+     */
+    public static final class SitemapSourceValidity implements SourceValidity {
+
+        private SourceValidity validity;
+
+        protected SitemapSourceValidity() {
+            super();
+        }
+
+        protected void set(SourceValidity validity) {
+            this.validity = validity;
+        }
+
+        public int isValid() {
+            return (this.validity != null ?
+                    this.validity.isValid() :
+                    SourceValidity.INVALID);
+        }
+
+        public int isValid(SourceValidity validity) {
+            if (validity instanceof SitemapSourceValidity) {
+                return (this.validity != null ?
+                        this.validity.isValid(((SitemapSourceValidity) validity).getNestedValidity()) :
+                        SourceValidity.INVALID);
+            }
+            return SourceValidity.INVALID;
+        }
+        
+        public SourceValidity getNestedValidity() {
+            return this.validity;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceFactory.java
new file mode 100644
index 0000000..beb3c0a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.URIAbsolutizer;
+import org.apache.excalibur.source.SourceUtil;
+
+/**
+ * This class implements the cocoon: protocol.
+ * It cannot be used like other source factories
+ * as it needs the current <code>Sitemap</code> as input.
+ *
+ * @version $Id$
+ */
+public final class SitemapSourceFactory
+    extends AbstractLogEnabled
+    implements SourceFactory, ThreadSafe, Serviceable, URIAbsolutizer
+{
+    
+    /** The <code>ServiceManager</code> */
+    private ServiceManager manager;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#getSource(java.lang.String, java.util.Map)
+     */
+    public Source getSource( String location, Map parameters )
+        throws MalformedURLException, IOException {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Creating source object for " + location );
+        }
+
+        return new SitemapSource( this.manager,
+                                  location,
+                                  parameters,
+                                  getLogger());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceFactory#release(org.apache.excalibur.source.Source)
+     */
+    public void release( Source source ) {
+        if ( null != source ) {
+            if ( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug("Releasing source " + source.getURI());
+            }
+            ((SitemapSource)source).recycle();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.URIAbsolutizer#absolutize(java.lang.String, java.lang.String)
+     */
+    public String absolutize(String baseURI, String location) {
+        return SourceUtil.absolutize(baseURI, location, true);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceInfo.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceInfo.java
new file mode 100644
index 0000000..758536e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/SitemapSourceInfo.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.net.MalformedURLException;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * This is a helper class for the cocoon protocol.
+ *
+ * @version $Id$
+ */
+public final class SitemapSourceInfo {
+    
+    /**
+     * <ul>
+     * <li><code>true</code> if the sitemap URI uses the <code>raw:</code> subprotocol,
+     * which means that request parameters of the original request are not forwarded,</li>
+     * <li><code>false</code> otherwise.
+     * </ul>
+     */
+    public boolean rawMode;
+    
+    /** The protocol used in the sitemap URI, up to and excluding the colon. */
+    public String protocol;
+    
+    /** The request URI, relative to the context. */
+    public String requestURI;
+    
+    /** The system ID: &lt;protocol&gt;&lt;request-uri&gt;[?&lt;query-string&gt;]. */
+    public String systemId;
+    
+    /** The Cocoon view used in the sitemap URI or <code>null</code> if no view is used.  */
+    public String view;
+    
+    /**
+     * The prefix of the URI in progress for <code>cocoon:/</code> requests,
+     * or an empty string for <code>cocoon://</code> requests.
+     */
+    public String prefix;
+    
+    /** The query string of the sitemap URI. */
+    public String queryString;
+    
+    /** The sitemap URI without protocol identifier and query string. */
+    public String uri;
+
+    /**
+     * Determine the initial processor for the cocoon protocol request.
+     * <ul>
+     * <li><code>true</code> - start in the root sitemap (<code>cocoon://</code>)</li>
+     * <li><code>false</code> - start in the current sitemap (<code>cocoon:/</code>)</li>
+     * </ul>
+     */
+    public boolean processFromRoot;
+
+    public static SitemapSourceInfo parseURI(Environment env, String sitemapURI) 
+    throws MalformedURLException {
+        SitemapSourceInfo info = new SitemapSourceInfo();
+        info.rawMode = false;
+
+        // remove the protocol
+        int position = sitemapURI.indexOf(':') + 1;
+        if (position != 0) {
+            info.protocol = sitemapURI.substring(0, position-1);
+            // check for subprotocol
+            if (sitemapURI.startsWith("raw:", position)) {
+                position += 4;
+                info.rawMode = true;
+            }
+        } else {
+            throw new MalformedURLException("No protocol found for sitemap source in " + sitemapURI);
+        }
+
+        // does the uri point to this sitemap or to the root sitemap?
+        if (sitemapURI.startsWith("//", position)) {
+            position += 2;
+            info.prefix = "";
+            info.processFromRoot = true;
+        } else if (sitemapURI.startsWith("/", position)) {
+            position ++;
+            info.prefix = env.getURIPrefix();
+            info.processFromRoot = false;
+        } else {
+            throw new MalformedURLException("Malformed cocoon URI: " + sitemapURI);
+        }
+
+        // create the queryString (if available)
+        int queryStringPos = sitemapURI.indexOf('?', position);
+        if (queryStringPos != -1) {
+            info.queryString = sitemapURI.substring(queryStringPos + 1);
+            info.uri = sitemapURI.substring(position, queryStringPos);
+        } else if (position > 0) {
+            info.uri = sitemapURI.substring(position);
+        }
+
+        
+        // determine if the queryString specifies a cocoon-view
+        info.view = getView(info.queryString, env);
+
+        // build the request uri which is relative to the context
+        info.requestURI = info.prefix + info.uri;
+
+        // create system ID
+        final StringBuffer buffer = new StringBuffer(info.protocol);
+        buffer.append("://").append(info.requestURI);
+        if (info.queryString != null ) {
+            buffer.append('?').append(info.queryString);
+        }
+        info.systemId = buffer.toString();
+
+        return info;
+    }
+
+    public static String getView(String query, Environment env) {
+        if (query != null) {
+            int index = query.indexOf(Constants.VIEW_PARAM);
+            if (index != -1 
+                    && (index == 0 || query.charAt(index-1) == '&')
+                    && query.length() > index + Constants.VIEW_PARAM.length() 
+                    && query.charAt(index+Constants.VIEW_PARAM.length()) == '=') {
+                
+                String tmp = query.substring(index+Constants.VIEW_PARAM.length()+1);
+                index = tmp.indexOf('&');
+                if (index != -1) {
+                    return tmp.substring(0,index);
+                } else {
+                    return tmp;
+                }
+            } else {
+                return env.getView();
+            }
+        } else {
+            return env.getView();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java
new file mode 100644
index 0000000..d1048d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * @version SVN $Id$
+ */
+public class TraversableContextSource
+implements Source, TraversableSource { 
+
+    final protected Source wrappedSource;
+    final protected Set children;
+    final protected ContextSourceFactory factory;
+    final protected String path;
+    final protected String scheme;
+    
+    public TraversableContextSource(Source source, 
+                                    Set children, 
+                                    ContextSourceFactory factory,
+                                    String path,
+                                    String scheme) {
+        this.wrappedSource = source;
+        this.children = children;
+        this.factory = factory;
+        this.path = path;
+        this.scheme = scheme;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#exists()
+     */
+    public boolean exists() {
+        return this.wrappedSource.exists();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getContentLength()
+     */
+    public long getContentLength() {
+        return this.wrappedSource.getContentLength();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getInputStream()
+     */
+    public InputStream getInputStream() 
+    throws IOException, SourceNotFoundException {
+        return this.wrappedSource.getInputStream();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getLastModified()
+     */
+    public long getLastModified() {
+        return this.wrappedSource.getLastModified();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getMimeType()
+     */
+    public String getMimeType() {
+        return this.wrappedSource.getMimeType();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getScheme()
+     */
+    public String getScheme() {
+        return this.scheme;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getURI()
+     */
+    public String getURI() {
+        return this.wrappedSource.getURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#getValidity()
+     */
+    public SourceValidity getValidity() {
+        return this.wrappedSource.getValidity();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.Source#refresh()
+     */
+    public void refresh() {
+        this.wrappedSource.refresh();
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.TraversableSource#getChild(java.lang.String)
+     */
+    public Source getChild(String name) throws SourceException {
+        final String postfixOne = '/' + name + '/';
+        final String postfixTwo = '/' + name;
+        final Iterator i = this.children.iterator();
+        while ( i.hasNext() ) {
+            String uri = (String)i.next();
+            if ( uri.endsWith(postfixOne ) ){
+                uri = "context:/" + uri;
+                uri = uri.substring(0, uri.length()-1);
+                try {
+                    return this.factory.getSource(uri, null);
+                } catch (IOException ioe) {
+                    throw new SourceException("Unable to get source for: " + uri);
+                }                
+            } else if ( uri.endsWith(postfixTwo) ) {
+                uri = "context:/" + uri;
+                try {
+                    return this.factory.getSource(uri, null);
+                } catch (IOException ioe) {
+                    throw new SourceException("Unable to get source for: " + uri);
+                }                
+            }
+        }
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.TraversableSource#getChildren()
+     */
+    public Collection getChildren() throws SourceException {
+        final List l = new ArrayList();
+        final Iterator i = this.children.iterator();
+        while ( i.hasNext() ) {
+            String uri = (String)i.next();
+            uri = "context:/" + uri;
+            try {
+                l.add(this.factory.getSource(uri, null));
+            } catch (IOException ioe) {
+                final Iterator ci = l.iterator();
+                while ( ci.hasNext() ) {
+                    this.factory.release((Source)ci.next());
+                }
+                throw new SourceException("Unable to get source for: " + uri);
+            }
+        }
+        return l;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.TraversableSource#getName()
+     */
+    public String getName() {
+        final String uri = this.wrappedSource.getURI();
+        return uri.substring(uri.lastIndexOf('/')+1);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.TraversableSource#getParent()
+     */
+    public Source getParent() throws SourceException {
+        String uri = "context:/" + this.path;
+        uri = uri.substring(0, uri.lastIndexOf('/'));
+        try {
+            return this.factory.getSource(uri, null);
+        } catch (IOException ioe) {
+            throw new SourceException("Unable to get source for: " + uri);
+        }                
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.TraversableSource#isCollection()
+     */
+    public boolean isCollection() {
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSource.java
new file mode 100644
index 0000000..d42571f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSource.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.impl.AbstractSource;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.excalibur.xml.sax.XMLizable;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.components.modules.output.OutputModule;
+import org.apache.cocoon.serialization.XMLSerializer;
+import org.apache.cocoon.util.jxpath.DOMFactory;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+
+import org.apache.commons.jxpath.JXPathContext;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * A <code>ModifiableSource</code> that takes its content from a
+ * module.
+ * <p>The URI syntax is
+ * "xmodule:[<input-module>|<output-module>]:attribute-name[#XPath]",
+ * where :
+ * <ul>
+ * <li>an input-module name is used for finding an input-module for reading data from</li>,
+ * <li>an output-module name is used for finding an output-module for writing data to</li>,
+ * <li>"attribute-name" is the name of the attribute found in the module</li>,
+ * <li>"XPath" is an XPath that is aplied on the object in the
+ * attribute, by using JXPath.</li>
+ * </ul>
+ * </p>
+ *
+ */
+public class XModuleSource
+    extends AbstractSource
+    implements ModifiableSource, XMLizable, DOMBuilder.Listener {
+
+    private final static String SCHEME = "xmodule";
+    private String attributeType;
+    private String attributeName;
+    private String xPath;
+    private ServiceManager manager;
+    private Map objectModel;
+    private Logger logger;
+    
+    /**
+     * Create a xmodule source from a 'xmodule:' uri and a the object model.
+     * <p>The uri is of the form "xmodule:/attribute-type/attribute-name/xpath</p>
+     */
+    public XModuleSource( Map objectModel, String uri,
+                          ServiceManager manager, Logger logger )
+        throws MalformedURLException {
+
+        this.objectModel = objectModel;
+        this.manager = manager;
+        this.logger = logger;
+
+        setSystemId( uri );
+
+        // Scheme
+        int start = 0;
+        int end = uri.indexOf( ':' );
+        if ( end == -1 )
+            throw new MalformedURLException("Malformed uri for xmodule source (cannot find scheme) : " + uri);
+
+        String scheme = uri.substring( start, end );
+        if ( !SCHEME.equals( scheme ) )
+            throw new MalformedURLException("Malformed uri for a xmodule source : " + uri);
+
+        setScheme( scheme );
+
+        // Attribute type
+        start = end + 1;
+        end = uri.indexOf( ':', start );
+        if ( end == -1 ) {
+            throw new MalformedURLException("Malformed uri for xmodule source (cannot find attribute type) : " + uri);
+        }
+        this.attributeType = uri.substring( start, end );
+
+        // Attribute name
+        start = end + 1;
+        end = uri.indexOf( '#', start );
+
+        if ( end == -1 )
+            end = uri.length();
+
+        if ( end == start )
+            throw new MalformedURLException("Malformed uri for xmodule source (cannot find attribute name) : " + uri);
+
+        this.attributeName = uri.substring( start, end );
+
+        // xpath
+        start = end + 1;
+        this.xPath = start < uri.length() ? uri.substring( start ) : "";
+    }
+    
+    /**
+     * Implement this method to obtain SAX events.
+     *
+     */
+
+    public void toSAX(ContentHandler handler)
+        throws SAXException {
+
+        Object obj = getInputAttribute( this.attributeType, this.attributeName );
+        if ( obj == null )
+            throw new SAXException( " The attribute: " + this.attributeName +
+                                    " is empty" );
+
+        if ( !(this.xPath.length() == 0 || this.xPath.equals( "/" )) ) {
+            JXPathContext context = JXPathContext.newContext( obj );
+
+            obj = context.getPointer( this.xPath ).getNode();
+
+            if ( obj == null )
+                throw new SAXException( "the xpath: " + this.xPath +
+                                        " applied on the attribute: " +
+                                        this.attributeName +
+                                        " returns null");
+        }
+
+        if ( obj instanceof Document ) {
+            DOMStreamer domStreamer = new DOMStreamer( handler );
+            domStreamer.stream( (Document)obj );
+        } else if ( obj instanceof Node ) {
+            DOMStreamer domStreamer = new DOMStreamer( handler );
+            handler.startDocument();
+            domStreamer.stream( (Node)obj );
+            handler.endDocument();
+        } else if ( obj instanceof XMLizable ) {
+            ((XMLizable)obj).toSAX( handler );
+        } else {
+            throw new SAXException( "The object type: " + obj.getClass() +
+                                    " could not be serialized to XML: " + obj );
+        }
+    }
+
+    /**
+     * Return an <code>InputStream</code> object to read from the source.
+     *
+     * @throws IOException if I/O error occured.
+     */
+    // Stolen from QDoxSource
+    public InputStream getInputStream() throws IOException, SourceException {
+        if ( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "Getting InputStream for " + getURI() );
+        }
+
+        // Serialize the SAX events to the XMLSerializer:
+
+        XMLSerializer serializer = new XMLSerializer();
+        ByteArrayInputStream inputStream = null;
+
+        try {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream( 2048 );
+            serializer.setOutputStream( outputStream );
+            toSAX( serializer );
+            inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
+        } catch ( SAXException se ) {
+            logger.error( "SAX exception!", se );
+            throw new SourceException( "Serializing SAX to a ByteArray failed!", se );
+        }
+
+        return inputStream;
+    }
+
+    /**
+     * Does this source actually exist ?
+     *
+     * @return true if the resource exists.
+     *
+     */
+    public boolean exists() {
+        boolean exists = false;
+        try {
+            exists = getInputAttribute( this.attributeType, this.attributeName ) != null;
+        } catch ( SAXException e ) {
+            exists = false;
+        }
+        return exists;
+    }
+
+    /**
+     * Get an <code>InputStream</code> where raw bytes can be written to.
+     * The signification of these bytes is implementation-dependent and
+     * is not restricted to a serialized XML document.
+     *
+     * @return a stream to write to
+     */ 
+    public OutputStream getOutputStream() throws IOException {
+        return new DOMOutputStream();
+    }
+
+    /**
+     * Delete the source 
+     */
+    public void delete() throws SourceException {
+        if ( !(this.xPath.length() == 0 || this.xPath.equals( "/" )) ) {
+            Object value;
+            try {
+                value = getInputAttribute( this.attributeType, this.attributeName );
+            } catch ( SAXException e ) {
+                throw new SourceException( "delete: ", e );
+            }
+            if ( value == null )
+                throw new SourceException( " The attribute: " + this.attributeName +
+                                           " is empty" );
+
+            JXPathContext context = JXPathContext.newContext( value );
+            context.removeAll( this.xPath );
+        } else {
+            try {
+                setOutputAttribute( this.attributeType, this.attributeName, null );
+            } catch ( SAXException e ) {
+                throw new SourceException( "delete: ", e );
+            }
+        }
+    }
+
+    /**
+     * FIXME
+     * delete is an operator in java script, this method is for
+     * testing puposes in java script only
+     */
+    public void deleteTest() throws SourceException {
+        delete();
+    }
+
+    /**
+     * Can the data sent to an <code>OutputStream</code> returned by
+     * {@link #getOutputStream()} be cancelled ?
+     *
+     * @return true if the stream can be cancelled
+     */
+    public boolean canCancel( OutputStream stream ) { return false; }
+
+    /**
+     * Cancel the data sent to an <code>OutputStream</code> returned by
+     * {@link #getOutputStream()}.
+     * <p>
+     * After cancel, the stream should no more be used.
+     */
+    public void cancel(OutputStream stream) throws IOException {}
+
+    /**
+     * Get a <code>ContentHandler</code> where an XML document can
+     * be written using SAX events.
+     * <p>
+     * Care should be taken that the returned handler can actually
+     * be a {@link org.apache.cocoon.xml.XMLConsumer} supporting also
+     * lexical events such as comments.
+     *
+     * @return a handler for SAX events
+     */
+    public ContentHandler getContentHandler() {
+        return new DOMBuilder( this );
+    }
+
+    public void notify( Document insertDoc ) throws SAXException {
+
+        // handle xpaths, we are only handling inserts, i.e. if there is no
+        // attribute of the given name and type the operation will fail
+        if ( !(this.xPath.length() == 0 || this.xPath.equals( "/" )) ) {
+
+            Object value = getInputAttribute( this.attributeType, this.attributeName );
+            if ( value == null )
+                throw new SAXException( " The attribute: " + this.attributeName +
+                                        " is empty" );
+
+            JXPathContext context = JXPathContext.newContext( value );
+
+            if ( value instanceof Document ) {
+                // If the attribute contains a dom document we
+                // create the elements in the given xpath if
+                // necesary, import the input document and put it
+                // in the place described by the xpath.
+                Document doc = (Document)value;
+                
+                Node importedNode =
+                    doc.importNode( insertDoc.getDocumentElement(), true );
+                
+                context.setLenient( true );
+                context.setFactory( new DOMFactory() );
+                context.createPathAndSetValue( this.xPath, importedNode );
+            } else {
+                // Otherwise just try to put a the input document in
+                // the place pointed to by the xpath
+                context.setValue( this.xPath, insertDoc );
+            }
+                    
+        } else {
+            setOutputAttribute( this.attributeType, this.attributeName, insertDoc );
+        }
+    }
+
+    private class DOMOutputStream extends ByteArrayOutputStream {
+        public void close() throws IOException {
+            SAXParser parser = null;
+            try {
+                parser = (SAXParser)XModuleSource.this.manager.lookup( SAXParser.ROLE );
+
+                parser.parse( new InputSource( new ByteArrayInputStream( super.toByteArray() ) ),
+                              XModuleSource.this.getContentHandler());
+            } catch (Exception e){
+                throw new IOException("Exception during processing of " +
+                                       XModuleSource.super.getURI() +
+                                       e.getMessage());
+            } finally {
+                if (parser != null) XModuleSource.this.manager.release( parser );
+            }
+            super.close();
+        }
+    }
+
+
+    private Object getInputAttribute( String inputModuleName, String attributeName )
+        throws SAXException {
+        Object obj;
+        ServiceSelector selector = null;
+        InputModule inputModule = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup( InputModule.ROLE + "Selector" );
+            inputModule = (InputModule) selector.select( inputModuleName );
+            obj = inputModule.getAttribute( attributeName, null, this.objectModel );
+
+        } catch ( ServiceException e ) {
+            throw new SAXException( "Could not find an InputModule of the type " + 
+                                    inputModuleName , e );
+        } catch ( ConfigurationException e ) {
+            throw new SAXException( "Could not find an attribute: " + attributeName +
+                                    " from the InputModule " + inputModuleName, e );
+        } finally {
+            if ( inputModule != null ) selector.release( inputModule );
+            this.manager.release( selector );
+        }
+
+        return obj;
+    }
+
+    private void setOutputAttribute( String outputModuleName,
+                                     String attributeName, Object value )
+        throws SAXException{
+        ServiceSelector selector = null;
+        OutputModule outputModule = null;
+        try {
+            selector = (ServiceSelector) this.manager.lookup( OutputModule.ROLE + "Selector" );
+            outputModule = (OutputModule) selector.select( outputModuleName );
+            outputModule.setAttribute( null, this.objectModel, attributeName, value );
+            outputModule.commit( null, this.objectModel );
+
+        } catch ( ServiceException e ) {
+            throw new SAXException( "Could not find an OutputModule of the type " + 
+                                    outputModuleName , e );
+        } finally {
+            if ( outputModule != null ) selector.release( outputModule );
+            this.manager.release( selector );
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSourceFactory.java
new file mode 100644
index 0000000..03ccd9a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/XModuleSourceFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceFactory;
+
+import org.apache.cocoon.components.ContextHelper;
+
+/**
+ * A factory for 'xmodule:' sources (see {@link XModuleSource}). 
+ *
+ */
+public class XModuleSourceFactory extends AbstractLogEnabled
+  implements SourceFactory, Serviceable, Contextualizable, ThreadSafe {
+    
+    private ServiceManager manager;
+    private Context context;
+
+    /**
+     * Servicable Interface
+     */
+    public void service( ServiceManager manager ) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Contextualizable, get the object model
+     */
+    public void contextualize( Context context ) throws ContextException {
+        this.context = context;
+    }
+    
+
+    /**
+     * Get a {@link XModuleSource} object.
+     * 
+     * @param location   The URI to resolve - this URI includes the scheme.
+     * @param parameters this is optional and not used here
+     */
+    public Source getSource( String location, Map parameters )
+        throws IOException, MalformedURLException {
+
+        Map objectModel = ContextHelper.getObjectModel( this.context );
+        return new XModuleSource( objectModel, location, this.manager, getLogger() );
+    }
+    
+    /**
+     * Release a {@link Source} object.
+     */
+    public void release( Source source ) {
+        // Do nothing here
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSource.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSource.java
new file mode 100644
index 0000000..d15df65
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSource.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.util.MIMEUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class ZipSource extends AbstractLogEnabled
+                       implements Source {
+
+    private String protocol;
+    private Source archive;
+    private String filePath;
+
+
+    public ZipSource(String protocol, Source archive, String filePath) {
+        this.protocol = protocol;
+        this.archive = archive;
+        this.filePath = filePath;
+    }
+
+    private ZipEntry findEntry(ZipInputStream zipStream)
+    throws IOException {
+        ZipEntry entry;
+        while ((entry = zipStream.getNextEntry()) != null) {
+            if (entry.getName().equals(this.filePath)) {
+                return entry;
+            }
+            zipStream.closeEntry();
+        }
+
+        return null;
+    }
+
+    /* package access */
+    void dispose(SourceResolver resolver) {
+        resolver.release(this.archive);
+        this.archive = null;
+    }
+
+    public boolean exists() {
+        if(!this.archive.exists()) {
+            return false;
+        }
+
+        ZipInputStream zipStream = null;
+        try {
+            zipStream = new ZipInputStream(this.archive.getInputStream());
+            return findEntry(zipStream) != null;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            try {
+                if (zipStream != null) {
+                    zipStream.close();
+                }
+            } catch (IOException e) {
+                getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
+            }
+        }
+    }
+
+    public InputStream getInputStream()
+    throws IOException, SourceNotFoundException {
+
+        ZipInputStream zipStream = new ZipInputStream(this.archive.getInputStream());
+        try {
+            ZipEntry entry = findEntry(zipStream);
+            if (entry == null) {
+                throw new SourceNotFoundException("File " + filePath + " is not found in the archive " +
+                                                  this.archive.getURI());
+            }
+
+            // Now we will extract the document and write it into a byte array
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            byte[] buffer = new byte[8192];
+            int length;
+            while (zipStream.available() > 0) {
+                length = zipStream.read(buffer, 0, 8192);
+                if (length > 0) {
+                    baos.write(buffer, 0, length);
+                }
+            }
+
+            // Return an input stream
+            return new ByteArrayInputStream(baos.toByteArray());
+        } finally {
+            try {
+                zipStream.close();
+            } catch (IOException e) {
+                getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
+            }
+        }
+    }
+
+    public String getURI() {
+        return this.protocol + this.archive.getURI() + "!/" + this.filePath;
+    }
+
+    public String getScheme() {
+        return this.protocol;
+    }
+
+    public SourceValidity getValidity() {
+        return this.archive.getValidity();
+    }
+
+    public void refresh() {
+    }
+
+    public String getMimeType() {
+        String ext = this.filePath.substring(this.filePath.lastIndexOf("."));
+        return MIMEUtils.getMIMEType(ext);
+    }
+
+    public long getContentLength() {
+        ZipInputStream zipStream = null;
+        try {
+            zipStream = new ZipInputStream(this.archive.getInputStream());
+            ZipEntry entry = findEntry(zipStream);
+            if (entry != null) {
+                return entry.getSize();
+            }
+
+        } catch (IOException e) {
+            // Ignored
+        } finally {
+            try {
+                if (zipStream != null) {
+                    zipStream.close();
+                }
+            } catch (IOException e) {
+                getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
+            }
+        }
+
+        return -1;
+    }
+
+    public long getLastModified() {
+        return this.archive.getLastModified();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java
new file mode 100644
index 0000000..73d6308
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceFactory;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * Implementation of a {@link Source} that gets its content from
+ * a ZIP archive.
+ *
+ * <p>
+ * A ZIP source can be obtained using the <code>zip:</code> pseudo-protocol.
+ * The syntax for protocol is
+ * <pre>
+ *   zip:[archive-url]!/[file-path]
+ * </pre>
+ *
+ * Where, <code>archive-url</code> can be any supported Cocoon URL, and
+ * <code>file-path</code> is the path to the file within archive.
+ *
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class ZipSourceFactory extends AbstractLogEnabled
+                              implements SourceFactory, ThreadSafe, Serviceable {
+
+    private ServiceManager manager;
+
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+
+    public Source getSource(String location, Map parameters)
+    throws IOException, MalformedURLException {
+        // Checks URL syntax
+        int protocolEnd = location.indexOf(":");
+        if (protocolEnd == -1) {
+            throw new MalformedURLException("Protocol ':' separator is missing in URL: " + location);
+        }
+
+        int archiveEnd = location.lastIndexOf("!/");
+        if (archiveEnd == -1) {
+            throw new MalformedURLException("File path '!/' separator is missing in URL: " + location);
+        }
+
+        // Get protocol. Protocol is configurable via cocoon.xconf
+        final String protocol = location.substring(0, protocolEnd - 1);
+
+        // Get archive URL
+        final String archiveURL = location.substring(protocolEnd + 1, archiveEnd);
+
+        // Get file path
+        final String filePath = location.substring(archiveEnd + 2);
+
+        // Resolve archive source
+        Source archive;
+        SourceResolver resolver = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            archive = resolver.resolveURI(archiveURL);
+        } catch (ServiceException se) {
+            throw new SourceException("SourceResolver is not available.", se);
+        } finally {
+            this.manager.release(resolver);
+        }
+
+        return new ZipSource(protocol, archive, filePath);
+    }
+
+    public void release(Source source) {
+        SourceResolver resolver = null;
+        try {
+            resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            ((ZipSource) source).dispose(resolver);
+        } catch (ServiceException e) {
+            // Ignored
+            getLogger().error("ServiceException while looking up SourceResolver in release()", e);
+        } finally {
+            this.manager.release(resolver);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/validity/DelayedValidity.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/validity/DelayedValidity.java
new file mode 100644
index 0000000..031be3f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/source/impl/validity/DelayedValidity.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.source.impl.validity;
+
+import org.apache.excalibur.source.SourceValidity;
+
+/**
+ * Delays validity check for a specified interval.
+ *
+ * <p>
+ * This is wrapper validity which can be used to reduce count of
+ * filesystem (or network) accesses just to check the source
+ * validity.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class DelayedValidity implements SourceValidity {
+
+    private long delay;
+    private long expires;
+
+    private SourceValidity delegate;
+
+
+    public DelayedValidity(long delay, SourceValidity validity) {
+        this.delay = delay;
+        this.expires = System.currentTimeMillis() + delay;
+        this.delegate = validity;
+    }
+
+    public int isValid() {
+        final long currentTime = System.currentTimeMillis();
+        if (currentTime <= this.expires) {
+            // The delay has not passed yet - assuming source is valid.
+            return SourceValidity.VALID;
+        }
+
+        // The delay has passed, prepare for the next interval.
+        this.expires = currentTime + this.delay;
+
+        return this.delegate.isValid();
+    }
+
+    public int isValid(SourceValidity newValidity) {
+        // Always delegate
+        return this.delegate.isValid(newValidity);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/default.ccf b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/default.ccf
new file mode 100644
index 0000000..e4c0e3b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/default.ccf
@@ -0,0 +1,44 @@
+# Cache configuration defaults.
+
+# Copyright 1999-2004 The Apache Software Foundation
+#
+# Licensed 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.
+
+
+jcs.default=DC
+jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
+jcs.default.cacheattributes.MaxObjects=100
+jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
+
+# SYSTEM GROUP ID CACHE
+jcs.system.groupIdCache=DC
+jcs.system.groupIdCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
+jcs.system.groupIdCache.cacheattributes.MaxObjects=1000
+jcs.system.groupIdCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
+
+##### AUXILIARY CACHES
+
+# Indexed Disk Cache
+jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
+jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
+#jcs.auxiliary.DC.attributes.DiskPath=
+
+# PRE-DEFINED CACHE REGIONS   
+
+jcs.region.main=DC
+jcs.region.main.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
+jcs.region.main.cacheattributes.MaxObjects=100
+jcs.region.main.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
+jcs.region.main.cacheattributes.UseMemoryShrinker=true
+jcs.region.main.cacheattributes.MaxMemoryIdleTimeSeconds=3600
+jcs.region.main.cacheattributes.ShrinkerIntervalSeconds=60
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/CocoonStoreJanitor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/CocoonStoreJanitor.java
new file mode 100644
index 0000000..7b99c7a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/CocoonStoreJanitor.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.store.impl;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.component.Component;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.components.thread.RunnableManager;
+
+/**
+ * The CocoonStoreJanitor class just subclasses the {@link StoreJanitorImpl} to
+ * overwrite the start method for background thread creation using the Cocoon
+ * {@link RunnableManager}.
+ *
+ * @version $Id$
+ */
+public class CocoonStoreJanitor extends StoreJanitorImpl
+                                implements Parameterizable, Serviceable, Disposable, Component {
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** Name of the thread pool to use. Defaults to 'daemon'. */
+    private String threadPool;
+
+    /** Our {@link ServiceManager} */
+    private ServiceManager serviceManager;
+
+    /** Our {@link RunnableManager} */
+    private RunnableManager runnableManager;
+
+    /** Flags to ignore memory bursts in the startup */
+    private boolean m_firstRun = true;
+
+    /** Flags to ignore memory bursts in the startup */
+    private boolean m_secondRun = false;
+
+    //~ Methods ----------------------------------------------------------------
+
+    public void parameterize(Parameters params) throws ParameterException {
+        super.parameterize(params);
+        this.threadPool = params.getParameter("thread-pool", "daemon");
+    }
+
+    /**
+     * Get the <code>RunnableManager</code>
+     *
+     * @param serviceManager The <code>ServiceManager</code>
+     * @throws ServiceException If RunnableManager is not available
+     */
+    public void service(final ServiceManager serviceManager)
+    throws ServiceException {
+        this.serviceManager = serviceManager;
+        this.runnableManager = (RunnableManager) serviceManager.lookup(RunnableManager.ROLE);
+    }
+
+    /**
+     * Release <code>RunnableManager</code>
+     */
+    public void dispose() {
+        this.serviceManager.release(this.runnableManager);
+        this.runnableManager = null;
+        this.serviceManager = null;
+    }
+
+    /**
+     * The "checker" thread checks if memory is running low in the jvm.
+     */
+    public void run() {
+        // Ignoring memory bursts in the first two invokations
+        if (m_firstRun || m_secondRun) {
+            super.inUse = super.memoryInUse();
+            m_secondRun = m_firstRun;
+            m_firstRun = false;
+        }
+
+        super.checkMemory();
+
+        // Relaunch
+        relaunch(super.interval);
+    }
+
+    /**
+     * Start this instance using a default thread from the
+     * <code>RunnableManager</code>
+     */
+    public void start() {
+        relaunch(0);
+    }
+
+    /**
+     * Does a delayed (re-)start of this instance using a default thread from
+     * the<code>RunnableManager</code> with a delay
+     *
+     * @param delay the delay to apply before next run
+     */
+    private void relaunch(final long delay) {
+        getLogger().debug("(Re-)Start CocoonStoreJanitor");
+        this.runnableManager.execute(this.threadPool, this, delay, 0);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultStore.java
new file mode 100644
index 0000000..fad79ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultStore.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.store.impl;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.excalibur.store.impl.MRUMemoryStore;
+
+/**
+ * Default implementation of Cocoon's store. It's a <code>MRUMemoryStore</code> whose
+ * "<code>use-persistent-cache</code>" parameter defaults to <code>true</code>.
+ * <p>
+ * This default setting allows the store to be an in-memory front-end to the persistent store.
+ * 
+ * @version $Id$
+ */
+public class DefaultStore extends MRUMemoryStore {
+    
+    public void parameterize(Parameters params) throws ParameterException {
+        if (!params.isParameter("use-persistent-cache")) {
+            params.setParameter("use-persistent-cache", "true");
+        }
+        super.parameterize(params);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultTransientStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultTransientStore.java
new file mode 100644
index 0000000..1169c8a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/DefaultTransientStore.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.store.impl;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.excalibur.store.impl.MRUMemoryStore;
+
+/**
+ * Default implementation of Cocoon's transient store. This is a <code>MRUMemoryStore</code>
+ * that cannot be backed by a persistent store (this ensure it is really transient).
+ * 
+ * @version $Id$
+ */
+public class DefaultTransientStore extends MRUMemoryStore {
+    
+    public void parameterize(Parameters params) throws ParameterException {
+        if (params.getParameterAsBoolean("use-persistent-cache", false)) {
+            throw new ParameterException("A transient store cannot be backed by a persistent store.");
+        }
+        super.parameterize(params);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java
new file mode 100644
index 0000000..dd3252a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/EHDefaultStore.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2004, 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.store.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Element;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.IOUtils;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+
+/**
+ * Store implementation based on EHCache.
+ * (http://ehcache.sourceforge.net/)
+ */
+public class EHDefaultStore extends AbstractLogEnabled 
+implements Store, Contextualizable, Serviceable, Parameterizable, Initializable, Disposable, ThreadSafe {
+
+    // ---------------------------------------------------- Constants
+
+    private static final String CONFIG_FILE = "org/apache/cocoon/components/store/impl/ehcache.xml";
+
+    private static int instanceCount = 0;
+
+    // ---------------------------------------------------- Instance variables
+
+    private Cache cache;
+    private CacheManager cacheManager;
+
+    private final String cacheName;
+
+    // configuration options
+    private int maxObjects;
+    private boolean overflowToDisk;
+    private boolean eternal;
+    private long timeToLiveSeconds;
+    private long timeToIdleSeconds;
+
+    /** The service manager */
+    private ServiceManager manager;
+    
+    /** The store janitor */
+    private StoreJanitor storeJanitor;
+
+    private File workDir;
+    private File cacheDir;
+
+    // ---------------------------------------------------- Lifecycle
+
+    public EHDefaultStore() {
+        instanceCount++;
+        this.cacheName = "cocoon-ehcache-" + instanceCount;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.workDir = (File)context.get(Constants.CONTEXT_WORK_DIR);
+        this.cacheDir = (File)context.get(Constants.CONTEXT_CACHE_DIR);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager aManager) throws ServiceException {
+        this.manager = aManager;
+        this.storeJanitor = (StoreJanitor) this.manager.lookup(StoreJanitor.ROLE);
+    }
+
+    /**
+     * Configure the store. The following options can be used:
+     * <ul>
+     *  <li><code>maxobjects</code> (10000) - The maximum number of in-memory objects.</li>
+     *  <li><code>overflow-to-disk</code> (true) - Whether to spool elements to disk after
+     *   maxobjects has been exceeded.</li>
+     * <li><code>eternal</code> (true) - whether or not entries expire. When set to
+     * <code>false</code> the <code>timeToLiveSeconds</code> and
+     * <code>timeToIdleSeconds</code> parameters are used to determine when an
+     * item expires.</li>
+     * <li><code>timeToLiveSeconds</code> (0) - how long an entry may live in the cache
+     * before it is removed. The entry will be removed no matter how frequently it is retrieved.</li>
+     * <li><code>timeToIdleSeconds</code> (0) - the maximum time between retrievals
+     * of an entry. If the entry is not retrieved for this period, it is removed from the
+     * cache.</li>
+     *  <li><code>use-cache-directory</code> (false) - If true the <i>cache-directory</i>
+     *   context entry will be used as the location of the disk store. 
+     *   Within the servlet environment this is set in web.xml.</li>
+     *  <li><code>use-work-directory</code> (false) - If true the <i>work-directory</i>
+     *   context entry will be used as the location of the disk store.
+     *   Within the servlet environment this is set in web.xml.</li>
+     *  <li><code>directory</code> - Specify an alternative location of the disk store.
+     * </ul>
+     * 
+     * <p>
+     * Setting <code>eternal</code> to <code>false</code> but not setting
+     * <code>timeToLiveSeconds</code> and/or <code>timeToIdleSeconds</code>, has the
+     * same effect as setting <code>eternal</code> to <code>true</code>.
+     * </p>
+     * 
+     * <p>
+     * Here is an example to clarify the purpose of the <code>timeToLiveSeconds</code> and
+     * <code>timeToIdleSeconds</code> parameters:
+     * </p>
+     * <ul>
+     *   <li>timeToLiveSeconds = 86400 (1 day)</li>
+     *   <li>timeToIdleSeconds = 10800 (3 hours)</li>
+     * </ul>
+     * 
+     * <p>
+     * With these settings the entry will be removed from the cache after 24 hours. If within
+     * that 24-hour period the entry is not retrieved within 3 hours after the last retrieval, it will
+     * also be removed from the cache.
+     * </p>
+     * 
+     * <p>
+     * By setting <code>timeToLiveSeconds</code> to <code>0</code>, an item can stay in
+     * the cache as long as it is retrieved within <code>timeToIdleSeconds</code> after the
+     * last retrieval.
+     * </p>
+     * 
+     * <p>
+     * By setting <code>timeToIdleSeconds</code> to <code>0</code>, an item will stay in
+     * the cache for exactly <code>timeToLiveSeconds</code>.
+     * </p>
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+
+        this.maxObjects = parameters.getParameterAsInteger("maxobjects", 10000);
+        this.overflowToDisk = parameters.getParameterAsBoolean("overflow-to-disk", true);
+        
+        this.eternal = parameters.getParameterAsBoolean("eternal", true);
+        if (!this.eternal)
+        {
+            this.timeToLiveSeconds = parameters.getParameterAsLong("timeToLiveSeconds", 0L);
+            this.timeToIdleSeconds = parameters.getParameterAsLong("timeToIdleSeconds", 0L);
+        }
+
+        try {
+            if (parameters.getParameterAsBoolean("use-cache-directory", false)) {
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using cache directory: " + cacheDir);
+                }
+                setDirectory(cacheDir);
+            }
+            else if (parameters.getParameterAsBoolean("use-work-directory", false)) {
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using work directory: " + workDir);
+                }
+                setDirectory(workDir);
+            }
+            else if (parameters.getParameter("directory", null) != null) {
+                String dir = parameters.getParameter("directory");
+                dir = IOUtils.getContextFilePath(workDir.getPath(), dir);
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using directory: " + dir);
+                }
+                setDirectory(new File(dir));
+            }
+            else {
+                try {
+                    // Legacy: use working directory by default
+                    setDirectory(workDir);
+                } catch (IOException e) {
+                }
+            }
+        } catch (IOException e) {
+            throw new ParameterException("Unable to set directory", e);
+        }
+
+    }
+
+    /**
+     * Sets the cache directory
+     */
+    private void setDirectory(final File directory) throws IOException  {
+        
+        /* Save directory path prefix */
+        String directoryPath = getFullFilename(directory);
+        directoryPath += File.separator;
+
+        /* If directory doesn't exist, create it anew */
+        if (!directory.exists()) {
+            if (!directory.mkdir()) {
+                throw new IOException("Error creating store directory '" + directoryPath + "': ");
+            }
+        }
+
+        /* Is given file actually a directory? */
+        if (!directory.isDirectory()) {
+            throw new IOException("'" + directoryPath + "' is not a directory");
+        }
+
+        /* Is directory readable and writable? */
+        if (!(directory.canRead() && directory.canWrite())) {
+            throw new IOException("Directory '" + directoryPath + "' is not readable/writable");
+        }
+
+        System.setProperty("java.io.tmpdir", directoryPath);
+    }
+
+    /**
+     * Get the complete filename corresponding to a (typically relative)
+     * <code>File</code>.
+     * This method accounts for the possibility of an error in getting
+     * the filename's <i>canonical</i> path, returning the io/error-safe
+     * <i>absolute</i> form instead
+     *
+     * @param file The file
+     * @return The file's absolute filename
+     */
+    private static String getFullFilename(File file) {
+        try {
+            return file.getCanonicalPath();
+        }
+        catch (Exception e) {
+            return file.getAbsolutePath();
+        }
+    }
+
+    /**
+     * Initialize the CacheManager and created the Cache.
+     */
+    public void initialize() throws Exception {
+        URL configFileURL = Thread.currentThread().getContextClassLoader().getResource(CONFIG_FILE);
+        this.cacheManager = CacheManager.create(configFileURL);
+        this.cache = new Cache(this.cacheName, this.maxObjects, this.overflowToDisk, this.eternal,
+                this.timeToLiveSeconds, this.timeToIdleSeconds, true, 120);
+        this.cacheManager.addCache(this.cache);
+        this.storeJanitor.register(this);
+    }
+    
+    /**
+     * Shutdown the CacheManager.
+     */
+    public void dispose() {
+        if (this.storeJanitor != null) {
+            this.storeJanitor.unregister(this);
+            this.manager.release(this.storeJanitor);
+            this.storeJanitor = null;
+        }
+        this.manager = null;
+        this.cacheManager.shutdown();
+        this.cacheManager = null;
+        this.cache = null;
+    }
+    
+    // ---------------------------------------------------- Store implementation
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public Object get(Object key) {
+        Object value = null;
+        try {
+            final Element element = this.cache.get((Serializable) key);
+            if (element != null) {
+                value = element.getValue();
+            }
+        }
+        catch (CacheException e) {
+            getLogger().error("Failure retrieving object from store", e);
+        }
+        if (getLogger().isDebugEnabled()) {
+            if (value != null) {
+                getLogger().debug("Found key: " + key);
+            } 
+            else {
+                getLogger().debug("NOT Found key: " + key);
+            }
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public void store(Object key, Object value) throws IOException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Store object " + value + " with key "+ key);
+        }
+
+        // without these checks we get cryptic "ClassCastException" messages
+        if(!(key instanceof Serializable)) {
+            throw new IOException("Key of class " + key.getClass().getName() + " is not Serializable");
+        }
+        if(!(value instanceof Serializable)) {
+            throw new IOException("Value of class " + value.getClass().getName() + " is not Serializable");            
+        }
+
+        final Element element = new Element((Serializable) key, (Serializable) value);
+        this.cache.put(element);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public void free() {
+        try {
+            final List keys = this.cache.getKeysNoDuplicateCheck();
+            if (!keys.isEmpty()) {
+            	// TODO find a way to get to the LRU one.
+                final Serializable key = (Serializable) keys.get(0);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Freeing cache");
+                    getLogger().debug("key: " + key);
+                    getLogger().debug("value: " + this.cache.get(key));
+                }
+                if (!this.cache.remove(key)) {
+                    if (getLogger().isInfoEnabled()) {
+                        getLogger().info("Concurrency condition in free()");
+                    }
+                }
+            }
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error in free()", e);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#remove(java.lang.Object)
+     */
+    public void remove(Object key) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Removing item " + key);
+        }
+        this.cache.remove((Serializable) key);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#clear()
+     */
+    public void clear() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Clearing the store");
+        }
+        try {
+            this.cache.removeAll();
+        }
+        catch (IOException e) {
+            getLogger().error("Failure to clearing store", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#containsKey(java.lang.Object)
+     */
+    public boolean containsKey(Object key) {
+        try {
+            return this.cache.get((Serializable) key) != null;
+        }
+        catch (CacheException e) {
+            getLogger().error("Failure retrieving object from store",e);
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#keys()
+     */
+    public Enumeration keys() {
+        List keys = null;
+        try {
+            keys = this.cache.getKeys();
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error while getting cache keys", e);
+            }
+            keys = Collections.EMPTY_LIST;
+        }
+        return Collections.enumeration(keys);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#size()
+     */
+    public int size() {
+        try {
+            return this.cache.getSize();
+        }
+        catch (CacheException e) {
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("Error while getting cache size", e);
+            }
+            return 0;
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/FilesystemStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/FilesystemStore.java
new file mode 100644
index 0000000..07cc5f4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/FilesystemStore.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.store.impl;
+
+import org.apache.excalibur.store.impl.AbstractFilesystemStore;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.IOUtils;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Stores objects on the filesystem: String objects as text files,
+ * all other objects are serialized.
+ *
+ * @version $Id$
+ */
+public final class FilesystemStore
+extends AbstractFilesystemStore
+implements Contextualizable, Parameterizable {
+
+    protected File workDir;
+    protected File cacheDir;
+
+    public void contextualize(final Context context)
+    throws ContextException {
+        this.workDir = (File)context.get(Constants.CONTEXT_WORK_DIR);
+        this.cacheDir = (File)context.get(Constants.CONTEXT_CACHE_DIR);
+    }
+
+    public void parameterize(Parameters params)
+    throws ParameterException {
+        try {
+            if (params.getParameterAsBoolean("use-cache-directory", false)) {
+                if (this.getLogger().isDebugEnabled())
+                    getLogger().debug("Using cache directory: " + cacheDir);
+                setDirectory(cacheDir);
+            } else if (params.getParameterAsBoolean("use-work-directory", false)) {
+                if (this.getLogger().isDebugEnabled())
+                    getLogger().debug("Using work directory: " + workDir);
+                setDirectory(workDir);
+            } else if (params.getParameter("directory", null) != null) {
+                String dir = params.getParameter("directory");
+                dir = IOUtils.getContextFilePath(workDir.getPath(), dir);
+                if (this.getLogger().isDebugEnabled())
+                    getLogger().debug("Using directory: " + dir);
+                setDirectory(new File(dir));
+            } else {
+                try {
+                    // Legacy: use working directory by default
+                    setDirectory(workDir);
+                } catch (IOException e) {
+                    // Legacy: Always was ignored
+                }
+            }
+        } catch (IOException e) {
+            throw new ParameterException("Unable to set directory", e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/JCSDefaultStore.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/JCSDefaultStore.java
new file mode 100644
index 0000000..460c07d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/JCSDefaultStore.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2004,2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.store.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.IOUtils;
+import org.apache.commons.collections.iterators.IteratorEnumeration;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+import org.apache.jcs.access.GroupCacheAccess;
+import org.apache.jcs.access.exception.CacheException;
+import org.apache.jcs.engine.control.CompositeCache;
+import org.apache.jcs.engine.control.CompositeCacheManager;
+import org.apache.jcs.engine.memory.MemoryCache;
+
+
+/**
+ * This is the default store implementation based on JCS
+ * http://jakarta.apache.org/turbine/jcs/BasicJCSConfiguration.html
+ * 
+ * @version $Id$
+ */
+public class JCSDefaultStore 
+    extends AbstractLogEnabled
+    implements Store,
+               Contextualizable,
+               Parameterizable,
+               Initializable,
+               Disposable, 
+               ThreadSafe,
+               Serviceable {
+
+    /** The JCS configuration properties */
+    protected Properties properties;
+    
+    /** The JCS region name */
+    protected String region;
+    
+    /** JCS Cache manager */
+    private CompositeCacheManager cacheManager;
+    
+    /** The Java Cache System object */
+    private JCSCacheAccess jcs;
+
+    /** The location of the JCS default properties file */
+    private static final String DEFAULT_PROPERTIES = "org/apache/cocoon/components/store/default.ccf";
+
+    /** The context containing the work and the cache directory */
+    private Context context;
+
+    /** Service Manager */
+    private ServiceManager manager;
+    
+    /** Store janitor */
+    private StoreJanitor janitor;
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context aContext) throws ContextException {
+        this.context = aContext;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager aManager) throws ServiceException {
+        this.manager = aManager;
+        this.janitor = (StoreJanitor)this.manager.lookup(StoreJanitor.ROLE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void parameterize(Parameters parameters) 
+    throws ParameterException {
+        // TODO describe options
+        this.region = parameters.getParameter("region-name","main");
+        
+        Properties defaults = new Properties();
+        try {
+            String defaultsFile = this.getDefaultPropertiesFile();
+            if (defaultsFile != null) {
+                defaults.load(Thread.currentThread().getContextClassLoader().
+                    getResourceAsStream(defaultsFile));
+            }
+        } catch (IOException e) {
+            throw new ParameterException("Failure loading cache defaults",e);
+        }
+        
+        this.properties = new Properties(defaults);
+        String[] names = parameters.getNames();
+        for (int i = 0; i < names.length; i++) {
+            if (names[i].startsWith("jcs.")) {
+                this.properties.put(names[i], parameters.getParameter(names[i]));
+            }
+        }
+        
+        int maxobjects = parameters.getParameterAsInteger("maxobjects", -1);
+        if (maxobjects != -1) {
+            String key = "jcs.region." + region + ".cacheattributes.MaxObjects";
+            this.properties.setProperty(key, String.valueOf(maxobjects));
+        }
+
+        // get the directory to use
+        try {
+            final File workDir = (File) context.get(Constants.CONTEXT_WORK_DIR);
+            if (parameters.getParameterAsBoolean("use-cache-directory", false)) {
+                final File cacheDir = (File) context.get(Constants.CONTEXT_CACHE_DIR);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using cache directory: " + cacheDir);
+                }
+                setDirectory(cacheDir);
+            } else if (parameters.getParameterAsBoolean("use-work-directory", false)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using work directory: " + workDir);
+                }
+                setDirectory(workDir);
+            } else if (parameters.getParameter("directory", null) != null) {
+                String dir = parameters.getParameter("directory");
+                dir = IOUtils.getContextFilePath(workDir.getPath(), dir);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using directory: " + dir);
+                }
+                setDirectory(new File(dir));
+            } else {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using default directory: " + workDir);
+                }
+                setDirectory(workDir);
+            }
+        } catch (ContextException ce) {
+            throw new ParameterException("Unable to get directory information from context.", ce);
+        } catch (IOException e) {
+            throw new ParameterException("Unable to set directory", e);
+        }
+        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        this.cacheManager = CompositeCacheManager.getUnconfiguredInstance();
+        this.cacheManager.configure(this.properties);
+        this.jcs = new JCSCacheAccess(cacheManager.getCache(region));
+        this.janitor.register(this);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if( this.janitor != null ) {
+            this.janitor.unregister( this );
+        }
+        if ( this.jcs != null ) {
+            this.jcs.dispose();
+            this.jcs = null;
+        }
+        if ( this.cacheManager != null ) {
+            this.cacheManager.release();
+            this.cacheManager = null;            
+        }
+        this.properties = null;
+        if ( this.manager != null ) {
+            this.manager.release( this.janitor );
+            this.janitor = null;
+            this.manager = null;
+        }
+    }
+    
+    protected String getDefaultPropertiesFile() {
+        return DEFAULT_PROPERTIES;
+    }
+    
+    /**
+     * Sets the disk cache location.
+     */
+    private void setDirectory(final File directory)
+    throws IOException {
+
+        /* Does directory exist? */
+        if (!directory.exists()) {
+            /* Create it anew */
+            if (!directory.mkdirs()) {
+                throw new IOException(
+                "Error creating store directory '" + directory.getAbsolutePath() + "'. ");
+            }
+        }
+
+        /* Is given file actually a directory? */
+        if (!directory.isDirectory()) {
+            throw new IOException("'" + directory.getAbsolutePath() + "' is not a directory");
+        }
+
+        /* Is directory readable and writable? */
+        if (!(directory.canRead() && directory.canWrite())) {
+            throw new IOException(
+                "Directory '" + directory.getAbsolutePath() + "' is not readable/writable"
+            );
+        }
+        
+        this.properties.setProperty("jcs.auxiliary.DC.attributes.DiskPath",
+                                    directory.getAbsolutePath());
+    }
+
+    // ---------------------------------------------------- Store implementation
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#get(java.lang.Object)
+     */
+    public Object get(Object key) {
+        Object value = this.jcs.get(key);
+        if (getLogger().isDebugEnabled()) {
+            if (value != null) {
+                getLogger().debug("Found key: " + key);
+            } else {
+                getLogger().debug("NOT Found key: " + key);
+            }
+        }
+        
+        return value;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#store(java.lang.Object, java.lang.Object)
+     */
+    public void store(Object key, Object value)
+    throws IOException {
+        
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Store object " + value + " with key "+ key);
+        }
+        
+        try {
+            this.jcs.put(key, value);
+        } catch (CacheException ce) {
+            getLogger().error("Failure storing object ", ce);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#free()
+     */
+    public void free() {
+        // TODO Find a better way
+        MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache();
+        Object[] keys = memoryCache.getKeyArray();
+        if ( keys != null && keys.length > 0 ) {
+            final Object key = keys[0];
+            try {
+                memoryCache.remove((Serializable)key);
+            } catch (Exception ignore) {                
+            }
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#clear()
+     */
+    public void clear() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Clearing the store");
+        }
+        
+        try {
+            this.jcs.remove();               
+        } catch (CacheException ce) {
+            getLogger().error("Failure clearing store", ce);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#remove(java.lang.Object)
+     */
+    public void remove(Object key) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Removing item " + key);
+        }
+        
+        try {
+           this.jcs.remove(key);
+        } catch (CacheException ce) {
+            getLogger().error("Failure removing object", ce);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#containsKey(java.lang.Object)
+     */
+    public boolean containsKey(Object key) {
+        return this.jcs.get(key) != null;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#keys()
+     */
+    public Enumeration keys() {
+        // TODO Find a better way
+        final MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache();
+        final Object[] keys = memoryCache.getKeyArray();
+        return new IteratorEnumeration(Arrays.asList(keys).iterator());
+        //return new IteratorEnumeration(this.jcs.getGroupKeys("").iterator());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.store.Store#size()
+     */
+    public int size() {
+        // TODO Find a better way
+        MemoryCache memoryCache = this.cacheManager.getCache(region).getMemoryCache();
+        return memoryCache.getSize();
+        //return this.jcs.getSize();
+    }
+    
+
+    private static class JCSCacheAccess extends GroupCacheAccess {
+        private JCSCacheAccess(CompositeCache cacheControl) {
+            super(cacheControl);
+        }
+        
+        /*private int getSize() {
+            return super.cacheControl.getSize();
+        }*/
+        
+        public void dispose() {
+            super.dispose();
+        }
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
new file mode 100644
index 0000000..ff17fb4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  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.cocoon.components.store.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+
+/**
+ * This class is a implentation of a StoreJanitor. Store classes
+ * can register to the StoreJanitor. When memory is too low,
+ * the StoreJanitor frees the registered caches until memory is normal.
+ *
+ * <p>A few parameters can be used:
+ * <UL>
+ *  <LI><B>freememory</B>: How many bytes shall be always free in the JVM (Default: 1mb)</LI>
+ *  <LI><B>heapsize</B>: Maximum possible size of the JVM memory consumption (Default: 64mb)</LI>
+ *  <LI><B>cleanupthreadinterval</B>: How often (sec) shall run the cleanup thread (Default: 10s)</LI>
+ *  <LI><B>adaptivethreadinterval</B> (experimental): Enable adaptive algorithm to determine thread interval
+ *      (Default: false) When true, <code>cleanupthreadinterval</code> defines the maximum cleanup interval.
+ *      Cleanup interval then is determined based on the memory fill rate: the faster memory is filled in,
+ *      and the less free memory is left, the shorter is the cleanup time.</LI>
+ *  <LI><B>threadpriority</B>: priority of the thread (1-10). (Default: 10)</LI>
+ *  <LI><B>percent_to_free</B>: What fraction of the store to free when memory is low (1-100). (Default: 10%)</LI>
+ *  <LI><B>invokegc</B>: Invoke the gc on low memory first (true|false; default: false)</LI>
+ * </UL></p>
+ *
+ * @version $Id$
+ */
+public class StoreJanitorImpl extends AbstractLogEnabled
+                              implements StoreJanitor, Parameterizable, ThreadSafe,
+                                         Initializable, Disposable, 
+                                         Runnable {
+
+    // Note: this class doesn't need to be Startable. This allows the janitor thread to be
+    // lazily created the first time a store registers itsefl
+
+    // Configuration parameters
+    private int minFreeMemory = -1;
+    private int maxHeapSize = -1;
+    private int threadInterval = -1;
+    private int minThreadInterval = 500;
+    private boolean adaptiveThreadInterval;
+    private int priority = -1;
+    private double fraction;
+
+    private Runtime jvm;
+    private ArrayList storelist;
+    private int index = -1;
+
+    /** Should the gc be called on low memory? */
+    protected boolean invokeGC;
+
+    private boolean doRun;
+
+    /**
+     * Amount of memory in use before sleep(). Must be initially set a resonable
+     * value; ie. <code>memoryInUse()</code>
+     */
+    protected long inUse;
+
+    private boolean firstRun = true;
+
+    /** The calculated delay for the next checker run in ms */
+    protected long interval = Long.MAX_VALUE;
+
+    /** Used memory change rate in bytes per second */
+    private long maxRateOfChange = 1;
+
+
+    /**
+     * Parameterize the StoreJanitorImpl.
+     */
+    public void parameterize(Parameters params) throws ParameterException {
+        this.jvm = Runtime.getRuntime();
+        this.minFreeMemory = params.getParameterAsInteger("freememory", 1024 * 1024);
+        this.maxHeapSize = params.getParameterAsInteger("heapsize", 66600000);
+        // Parameter value is in seconds, converted to millis
+        this.threadInterval = params.getParameterAsInteger("cleanupthreadinterval", 10) * 1000;
+        this.adaptiveThreadInterval = params.getParameterAsBoolean("adaptivethreadinterval", false);
+        this.priority = params.getParameterAsInteger("threadpriority", Thread.currentThread().getPriority());
+        int percent = params.getParameterAsInteger("percent_to_free", 10);
+        this.invokeGC = params.getParameterAsBoolean("invokegc", this.invokeGC);
+
+        if (getMinFreeMemory() < 1) {
+            throw new ParameterException("StoreJanitorImpl freememory parameter has to be greater then 1");
+        }
+        if (getMaxHeapSize() < 1) {
+            throw new ParameterException("StoreJanitorImpl heapsize parameter has to be greater then 1");
+        }
+        if (getThreadInterval() < 1) {
+            throw new ParameterException("StoreJanitorImpl cleanupthreadinterval parameter has to be greater then 1");
+        }
+        if (getPriority() < 1 || getPriority() > 10) {
+            throw new ParameterException("StoreJanitorImpl threadpriority has to be between 1 and 10");
+        }
+        if (percent > 100 && percent < 1) {
+            throw new ParameterException("StoreJanitorImpl percent_to_free, has to be between 1 and 100");
+        }
+
+        this.fraction = percent / 100.0D;
+        this.storelist = new ArrayList();
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("minimum free memory=" + getMinFreeMemory());
+            getLogger().debug("heapsize=" + getMaxHeapSize());
+            getLogger().debug("thread interval=" + getThreadInterval());
+            getLogger().debug("adaptivethreadinterval=" + getAdaptiveThreadInterval());
+            getLogger().debug("priority=" + getPriority());
+            getLogger().debug("percent=" + percent);
+            getLogger().debug("invoke gc=" + this.invokeGC);
+        }
+    }
+
+    public void initialize() throws Exception {
+        doStart();
+    }
+
+    private void doStart() throws Exception {
+        this.doRun = true;
+        Thread checker = new Thread(this);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Intializing checker thread");
+        }
+        checker.setPriority(getPriority());
+        checker.setDaemon(true);
+        checker.setName("checker");
+        checker.start();
+    }
+
+    private void doStop() {
+        this.doRun = false;
+    }
+
+    public void dispose() {
+        doStop();
+    }
+
+    /**
+     * The "checker" thread loop.
+     */
+    public void run() {
+        this.inUse = memoryInUse();
+        while (this.doRun) {
+            checkMemory();
+
+            // Sleep
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Sleeping for " + this.interval + "ms");
+            }
+            try {
+                Thread.sleep(this.interval);
+            } catch (InterruptedException ignore) {
+            }
+
+            // Ignore change in memory during the first run (startup)
+            if (this.firstRun) {
+                this.firstRun = false;
+                this.inUse = memoryInUse();
+            }
+        }
+    }
+
+    /**
+     * The "checker" thread checks if memory is running low in the jvm.
+     */
+    protected void checkMemory() {
+        if (getAdaptiveThreadInterval()) {
+            // Monitor the rate of change of heap in use.
+            long change = memoryInUse() - inUse;
+            long rateOfChange = longDiv(change * 1000, interval); // bps.
+            if (maxRateOfChange < rateOfChange) {
+                maxRateOfChange = (maxRateOfChange + rateOfChange) / 2;
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Waking after " + interval + "ms, in use change "
+                                  + change + "b to " + memoryInUse() + "b, rate "
+                                  + rateOfChange + "b/sec, max rate " + maxRateOfChange + "b/sec");
+            }
+        }
+
+        // Amount of memory used is greater than heapsize
+        if (memoryLow()) {
+            if (this.invokeGC) {
+                freePhysicalMemory();
+            }
+
+            synchronized (this) {
+                if (!this.invokeGC
+                        || (memoryLow() && getStoreList().size() > 0)) {
+
+                    freeMemory();
+                    setIndex(getIndex() + 1);
+                }
+            }
+        }
+
+        if (getAdaptiveThreadInterval()) {
+            // Calculate sleep interval based on the change rate and free memory left
+            interval = minTimeToFill(maxRateOfChange) * 1000 / 2;
+            if (interval > this.threadInterval) {
+                interval = this.threadInterval;
+            } else if (interval < this.minThreadInterval) {
+                interval = this.minThreadInterval;
+            }
+            inUse = memoryInUse();
+        } else {
+            interval = this.threadInterval;
+        }
+    }
+
+    /**
+     * Method to check if memory is running low in the JVM.
+     *
+     * @return true if memory is low
+     */
+    private boolean memoryLow() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("JVM Memory total: " + getJVM().totalMemory()
+                              + ", free: " + getJVM().freeMemory());
+        }
+
+        if ((getJVM().totalMemory() >= getMaxHeapSize())
+                && (getJVM().freeMemory() < getMinFreeMemory())) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Memory is low!");
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Calculate the JVM memory in use now.
+     *
+     * @return memory in use.
+     */
+    protected long memoryInUse() {
+        return jvm.totalMemory() - jvm.freeMemory();
+    }
+
+    /**
+     * Calculate amount of time needed to fill all free memory with given
+     * fill rate.
+     *
+     * @param rate memory fill rate in time per bytes
+     * @return amount of time to fill all the memory with given fill rate
+     */
+    private long minTimeToFill(long rate) {
+        return longDiv(jvm.freeMemory(), rate);
+    }
+
+    private long longDiv(long top, long bottom) {
+        try {
+            return top / bottom;
+        } catch (Exception e) {
+            return top > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
+        }
+    }
+
+    /**
+     * This method register the stores
+     *
+     * @param store the store to be registered
+     */
+    public synchronized void register(Store store) {
+        getStoreList().add(store);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Registered store instance " + store + ". Stores now: "
+                              + getStoreList().size());
+        }
+    }
+
+    /**
+     * This method unregister the stores
+     *
+     * @param store the store to be unregistered
+     */
+    public synchronized void unregister(Store store) {
+        getStoreList().remove(store);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Unregistered store instance " + store + ". Stores now: "
+                              + getStoreList().size());
+        }
+    }
+
+    /**
+     * This method return a java.util.Iterator of every registered stores
+     *
+     * <i>The iterators returned is fail-fast: if list is structurally
+     * modified at any time after the iterator is created, in any way, the
+     * iterator will throw a ConcurrentModificationException.  Thus, in the
+     * face of concurrent modification, the iterator fails quickly and
+     * cleanly, rather than risking arbitrary, non-deterministic behavior at
+     * an undetermined time in the future.</i>
+     *
+     * @return a java.util.Iterator
+     */
+    public Iterator iterator() {
+        return getStoreList().iterator();
+    }
+
+    /**
+     * Round Robin alghorithm for freeing the registered caches.
+     */
+    private void freeMemory() {
+        // TODO: Alternative to RR might be to free same fraction from every storage.
+        try {
+            // Determine the store.
+            if (getIndex() < getStoreList().size()) {
+                if (getIndex() == -1) {
+                    setIndex(0);
+                }
+            } else {
+                // Store list changed (one or more store has been removed).
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Restarting from the beginning");
+                }
+                setIndex(0);
+            }
+
+            // Delete proportionate elements out of the store as configured.
+            Store store = (Store)getStoreList().get(getIndex());
+            int limit = calcToFree(store);
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Freeing " + limit + " items from store #" + getIndex());
+            }
+
+            for (int i = 0; i < limit; i++) {
+                try {
+                    store.free();
+                } catch (OutOfMemoryError e) {
+                    getLogger().error("OutOfMemoryError in freeMemory()");
+                }
+            }
+        } catch (Exception e) {
+            getLogger().error("Error in freeMemory()", e);
+        } catch (OutOfMemoryError e) {
+            getLogger().error("OutOfMemoryError in freeMemory()");
+        }
+    }
+
+    /**
+     * This method claculates the number of Elements to be freememory
+     * out of the Cache.
+     *
+     * @param store the Store which was selected as victim
+     * @return number of elements to be removed!
+     */
+    private int calcToFree(Store store) {
+        int cnt = store.size();
+        if (cnt < 0) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Unknown size of the store: " + store);
+            }
+            return 0;
+        }
+
+        final int res = (int) (cnt * fraction);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Calculating size for store " + store + " with size " + cnt + ": " + res);
+        }
+        return res;
+    }
+
+    /**
+     * This method forces the garbage collector
+     */
+    private void freePhysicalMemory() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Invoking GC. Memory total: "
+                              + getJVM().totalMemory() + ", free: "
+                              + getJVM().freeMemory());
+        }
+
+        getJVM().runFinalization();
+        getJVM().gc();
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("GC complete. Memory total: "
+                              + getJVM().totalMemory() + ", free: "
+                              + getJVM().freeMemory());
+        }
+    }
+
+
+    private int getMinFreeMemory() {
+        return this.minFreeMemory;
+    }
+
+    private int getMaxHeapSize() {
+        return this.maxHeapSize;
+    }
+
+    private int getPriority() {
+        return this.priority;
+    }
+
+    private int getThreadInterval() {
+        return this.threadInterval;
+    }
+
+    private boolean getAdaptiveThreadInterval() {
+        return this.adaptiveThreadInterval;
+    }
+
+    private Runtime getJVM() {
+        return this.jvm;
+    }
+
+    private ArrayList getStoreList() {
+        return this.storelist;
+    }
+
+    private void setIndex(int _index) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Setting index=" + _index);
+        }
+        this.index = _index;
+    }
+
+    private int getIndex() {
+        return this.index;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/ehcache.xml b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/ehcache.xml
new file mode 100644
index 0000000..6ea5abc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/store/impl/ehcache.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<ehcache>

+

+    <!-- Sets the path to the directory where cache .data files are created.

+

+         If the path is a Java System Property it is replaced by

+         its value in the running VM.

+

+         The following properties are translated:

+         user.home - User's home directory

+         user.dir - User's current working directory

+         java.io.tmpdir - Default temp file path -->

+    <diskStore path="java.io.tmpdir"/>

+

+    <!--Default Cache configuration. These will be applied to caches programmatically created through

+        the CacheManager.

+

+        The following attributes are required:

+

+        maxElementsInMemory            - Sets the maximum number of objects that will be created in memory

+        eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the

+                                         element is never expired.

+        overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache

+                                         has reached the maxInMemory limit.

+

+        The following attributes are optional:

+        timeToIdleSeconds              - Sets the time to idle for an element before it expires.

+                                         i.e. The maximum amount of time between accesses before an element expires

+                                         Is only used if the element is not eternal.

+                                         Optional attribute. A value of 0 means that an Element can idle for infinity.

+                                         The default value is 0.

+        timeToLiveSeconds              - Sets the time to live for an element before it expires.

+                                         i.e. The maximum time between creation time and when an element expires.

+                                         Is only used if the element is not eternal.

+                                         Optional attribute. A value of 0 means that and Element can live for infinity.

+                                         The default value is 0.

+        diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.

+                                         The default value is false.

+        diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value

+                                         is 120 seconds.

+        -->

+

+    <defaultCache

+        maxElementsInMemory="10000"

+        eternal="true"

+        timeToIdleSeconds="0"

+        timeToLiveSeconds="0"

+        overflowToDisk="true"

+        diskPersistent="true"

+        diskExpiryThreadIntervalSeconds="120"

+        />

+

+</ehcache>

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/BoundedQueue.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/BoundedQueue.java
new file mode 100644
index 0000000..334c352
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/BoundedQueue.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * Efficient array-based bounded buffer class. Adapted from CPJ, chapter 8,
+ * which describes design.
+ * 
+ * <p>
+ * [<a
+ * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html">
+ * Introduction to this package. </a>]
+ * </p>
+ * 
+ * <p></p>
+ */
+public class BoundedQueue
+    extends EDU.oswego.cs.dl.util.concurrent.BoundedBuffer
+    implements Queue {
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Create a buffer with the current default capacity.
+     */
+    public BoundedQueue() {
+        super();
+    }
+
+    /**
+     * Create a BoundedQueue with the given capacity.
+     *
+     * @param capacity The capacity
+     *
+     * @exception IllegalArgumentException if capacity less or equal to zero
+     */
+    public BoundedQueue( int capacity )
+    throws IllegalArgumentException {
+        super( capacity );
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return current size of queue.
+     */
+    public int getQueueSize() {
+        return usedSlots_;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java
new file mode 100644
index 0000000..8445470
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ChannelWrapper.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import EDU.oswego.cs.dl.util.concurrent.Channel;
+
+/**
+ * Wrapper around a Channel implementation for constructor convenience
+ *
+ * @version $Id$
+ */
+public class ChannelWrapper
+    implements Channel {
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** The wrapped Channel */
+    private Channel channel;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param channel DOCUMENT ME!
+     */
+    public void setChannel( final Channel channel ) {
+        this.channel = channel;
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Puttable#offer(java.lang.Object,
+     *      long)
+     */
+    public boolean offer( final Object obj,
+                          final long timeout )
+    throws InterruptedException {
+        return channel.offer( obj, timeout );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Channel#peek()
+     */
+    public Object peek() {
+        return channel.peek();
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Takable#poll(long)
+     */
+    public Object poll( final long timeout )
+    throws InterruptedException {
+        return channel.poll( timeout );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Puttable#put(java.lang.Object)
+     */
+    public void put( final Object obj )
+    throws InterruptedException {
+        channel.put( obj );
+    }
+
+    /**
+     * @see EDU.oswego.cs.dl.util.concurrent.Takable#take()
+     */
+    public Object take()  throws InterruptedException {
+        return channel.take();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java
new file mode 100644
index 0000000..ae8ef6b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultRunnableManager.java
@@ -0,0 +1,772 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * The DefaultRunnableManager implements the {@link RunnableManager} interface
+ * and is responsible to create {@link ThreadPool}s and run {@link Runnable}s
+ * in them as background commands.
+ *
+ * <p>
+ * The configuration of the <code>DefaultRunnableManager</code>:
+ * <pre>
+ *   &lt;thread-factory&gt;org.apache.cocoon.components.thread.DefaultThreadFactory&lt;/thread-factory&gt;
+ *   &lt;thread-pools&gt;
+ *     &lt;thread-pool&gt;
+ *       &lt;name&gt;default&lt;/name&gt;
+ *       &lt;priority&gt;NORM&lt;/priority&gt;
+ *       &lt;daemon&gt;false&lt;/daemon&gt;
+ *       &lt;queue-size&gt;-1&lt;/queue-size&gt;
+ *       &lt;max-pool-size&gt;-1&lt;/max-pool-size&gt;
+ *       &lt;min-pool-size&gt;2&lt;/min-pool-size&gt;
+ *       &lt;keep-alive-time-ms&gt;20000&lt;/keep-alive-time-ms&gt;
+ *       &lt;block-policy&gt;RUN&lt;/block-policy&gt;
+ *       &lt;shutdown-graceful&gt;false&lt;/shutdown-graceful&gt;
+ *       &lt;shutdown-wait-time-ms&gt;-1&lt;/shutdown-wait-time-ms&gt;
+ *     &lt;/thread-pool&gt;
+ *   &lt;/thread-pools&gt;
+ * </pre>
+ * </p>
+ *
+ * <p>
+ * Have a look at
+ * http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html,
+ * {@link EDU.oswego.cs.dl.util.concurrent.PooledExecutor} or the cocoon.xconf
+ * file for more information.
+ * </p>
+ *
+ * @version $Id$
+ */
+public class DefaultRunnableManager
+    extends AbstractLogEnabled
+    implements RunnableManager,
+               Configurable,
+               Disposable,
+               Startable,
+               Runnable,
+               ThreadSafe {
+    
+    //~ Static fields/initializers ---------------------------------------------
+
+    /** The default {@link ThreadFactory} */
+    public static final String DEFAULT_THREAD_FACTORY =
+        DefaultThreadFactory.class.getName();
+
+    /** The default queue size */
+    public static final int DEFAULT_QUEUE_SIZE = -1;
+
+    /** The default maximum pool size */
+    public static final int DEFAULT_MAX_POOL_SIZE = 5;
+
+    /** The default minimum pool size */
+    public static final int DEFAULT_MIN_POOL_SIZE = 5;
+
+    /** The default thread priority */
+    public static final String DEFAULT_THREAD_PRIORITY = "NORM";
+
+    /** The default daemon mode */
+    public static final boolean DEFAULT_DAEMON_MODE = false;
+
+    /** The default keep alive time */
+    public static final long DEFAULT_KEEP_ALIVE_TIME = 60000L;
+
+    /** The default way to shutdown gracefully */
+    public static final boolean DEFAULT_SHUTDOWN_GRACEFUL = false;
+
+    /** The default shutdown waittime time */
+    public static final int DEFAULT_SHUTDOWN_WAIT_TIME = -1;
+
+    /** The default shutdown waittime time */
+    public static final String DEFAULT_THREADPOOL_NAME = "default";
+
+    //~ Instance fields --------------------------------------------------------
+
+    /**
+     * Sorted set of <code>ExecutionInfo</code> instances, based on their next
+     * execution time.
+     */
+    protected SortedSet commandStack = new TreeSet();
+
+    /** The managed thread pools */
+    final Map pools = new HashMap();
+
+    /** The configured default ThreadFactory class instance */
+    private Class defaultThreadFactoryClass;
+
+    /** Keep us running? */
+    private boolean keepRunning = false;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure( final Configuration config )
+    throws ConfigurationException {
+        final String defaultThreadFactoryName =
+            config.getChild( "thread-factory" ).getValue( DEFAULT_THREAD_FACTORY );
+
+        try {
+            defaultThreadFactoryClass =
+                Thread.currentThread().getContextClassLoader().loadClass( defaultThreadFactoryName );
+        } catch( final Exception ex ) {
+            throw new ConfigurationException( "Cannot create instance of default thread factory " +
+                                              defaultThreadFactoryName, ex );
+        }
+
+        final Configuration [] threadpools =
+            config.getChild( "thread-pools" ).getChildren( "thread-pool" );
+
+        for( int i = 0; i < threadpools.length; i++ ) {
+            final DefaultThreadPool pool = configThreadPool( threadpools[ i ] );
+        }
+
+        // Check if a "default" pool has been created
+        final ThreadPool defaultThreadPool =
+            (ThreadPool)pools.get( DEFAULT_THREADPOOL_NAME );
+
+        if( null == defaultThreadPool ) {
+            createPool( DEFAULT_THREADPOOL_NAME, DEFAULT_QUEUE_SIZE,
+                        DEFAULT_MAX_POOL_SIZE, DEFAULT_MIN_POOL_SIZE,
+                        getPriority( DEFAULT_THREAD_PRIORITY ),
+                        DEFAULT_DAEMON_MODE, DEFAULT_KEEP_ALIVE_TIME,
+                        DefaultThreadPool.POLICY_DEFAULT,
+                        DEFAULT_SHUTDOWN_GRACEFUL, DEFAULT_SHUTDOWN_WAIT_TIME );
+        }
+    }
+
+    /**
+     * Create a shared ThreadPool
+     *
+     * @param name The name of the thread pool
+     * @param queueSize The size of the queue
+     * @param maxPoolSize The maximum number of threads
+     * @param minPoolSize The maximum number of threads
+     * @param priority The priority of threads created by this pool. This is
+     *        one of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link Thread#MAX_PRIORITY}
+     * @param isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @param keepAliveTime How long should a thread be alive for new work to
+     *        be done before it is GCed
+     * @param blockPolicy What's the blocking policy is resources are exhausted
+     * @param shutdownGraceful Should we wait for the queue to finish all
+     *        pending commands?
+     * @param shutdownWaitTime After what time a normal shutdown should take
+     *        into account if a graceful shutdown has not come to an end
+     *
+     * @throws IllegalArgumentException If the pool already exists
+     */
+    public void createPool( final String name,
+                            final int queueSize,
+                            final int maxPoolSize,
+                            final int minPoolSize,
+                            final int priority,
+                            final boolean isDaemon,
+                            final long keepAliveTime,
+                            final String blockPolicy,
+                            final boolean shutdownGraceful,
+                            final int shutdownWaitTime ) {
+        if( null != pools.get( name ) ) {
+            throw new IllegalArgumentException( "ThreadPool \"" + name +
+                                                "\" already exists" );
+        }
+
+        createPool( new DefaultThreadPool(  ), name, queueSize, maxPoolSize,
+                    minPoolSize, priority, isDaemon, keepAliveTime,
+                    blockPolicy, shutdownGraceful, shutdownWaitTime );
+    }
+
+    /**
+     * Create a private ThreadPool
+     *
+     * @param queueSize The size of the queue
+     * @param maxPoolSize The maximum number of threads
+     * @param minPoolSize The maximum number of threads
+     * @param priority The priority of threads created by this pool. This is
+     *        one of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link Thread#MAX_PRIORITY}
+     * @param isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @param keepAliveTime How long should a thread be alive for new work to
+     *        be done before it is GCed
+     * @param blockPolicy What's the blocking policy is resources are exhausted
+     * @param shutdownGraceful Should we wait for the queue to finish all
+     *        pending commands?
+     * @param shutdownWaitTime After what time a normal shutdown should take
+     *        into account if a graceful shutdown has not come to an end
+     *
+     * @return A newly created <code>ThreadPool</code>
+     */
+    public ThreadPool createPool( final int queueSize,
+                                  final int maxPoolSize,
+                                  final int minPoolSize,
+                                  final int priority,
+                                  final boolean isDaemon,
+                                  final long keepAliveTime,
+                                  final String blockPolicy,
+                                  final boolean shutdownGraceful,
+                                  final int shutdownWaitTime ) {
+        final DefaultThreadPool pool = new DefaultThreadPool();
+        final String name = "anon-" + pool.hashCode(  );
+
+        return createPool( pool, name, queueSize, maxPoolSize, minPoolSize,
+                           priority, isDaemon, keepAliveTime, blockPolicy,
+                           shutdownGraceful, shutdownWaitTime );
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Disposing all thread pools" );
+        }
+
+        for( final Iterator i = pools.keySet().iterator(); i.hasNext(); ) {
+            final String poolName = (String)i.next();
+            final DefaultThreadPool pool =
+                (DefaultThreadPool)pools.get( poolName );
+
+            if( getLogger().isDebugEnabled(  ) ) {
+                getLogger().debug( "Disposing thread pool " +
+                                     pool.getName() );
+            }
+
+            pool.shutdown();
+
+            if( getLogger().isDebugEnabled(  ) ) {
+                getLogger().debug( "Thread pool " + pool.getName() +
+                                     " disposed" );
+            }
+        }
+
+        try {
+            pools.clear();
+        } catch( final Throwable t ) {
+            getLogger().error( "Cannot dispose", t );
+        }
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link Runnable} to execute
+     * @param delay the delay befor first run
+     * @param interval The interval for repeated runs
+     *
+     * @throws IllegalArgumentException DOCUMENT ME!
+     */
+    public void execute( final String threadPoolName,
+                         final Runnable command,
+                         final long delay,
+                         long interval ) {
+        if( delay < 0 ) {
+            throw new IllegalArgumentException( "delay < 0" );
+        }
+
+        if( interval < 0 ) {
+            throw new IllegalArgumentException( "interval < 0" );
+        }
+
+        ThreadPool pool = (ThreadPool)pools.get( threadPoolName );
+
+        if( null == pool ) {
+            getLogger().warn( "ThreadPool \"" + threadPoolName +
+                              "\" is not known. Will use ThreadPool \"" +
+                              DEFAULT_THREADPOOL_NAME + "\"" );
+            pool = (ThreadPool)pools.get( DEFAULT_THREADPOOL_NAME );
+        }
+
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Command entered: " + command.toString() +
+                               ", pool=" + pool.getName() + ", delay=" +
+                               delay + ", interval=" + interval );
+        }
+
+        new ExecutionInfo( pool, command, delay, interval, getLogger() );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link Runnable} to execute
+     * @param delay the delay befor first run
+     * @param interval The interval for repeated runs
+     */
+    public void execute( final Runnable command,
+                         final long delay,
+                         final long interval ) {
+        execute( DEFAULT_THREADPOOL_NAME, command, delay, interval );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link Runnable} to execute
+     * @param delay the delay befor first run
+     */
+    public void execute( final Runnable command,
+                         final long delay ) {
+        execute( DEFAULT_THREADPOOL_NAME, command, delay, 0 );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param command The {@link Runnable} to execute
+     */
+    public void execute( final Runnable command ) {
+        execute( DEFAULT_THREADPOOL_NAME, command, 0, 0 );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link Runnable} to execute
+     * @param delay the delay befor first run
+     */
+    public void execute( final String threadPoolName,
+                         final Runnable command,
+                         final long delay ) {
+        execute( threadPoolName, command, delay, 0 );
+    }
+
+    /**
+     * Run a {@link Runnable} in the background using a {@link ThreadPool}
+     *
+     * @param threadPoolName The thread pool name to be used
+     * @param command The {@link Runnable} to execute
+     */
+    public void execute( final String threadPoolName,
+                         final Runnable command ) {
+        execute( threadPoolName, command, 0, 0 );
+    }
+
+    /**
+     * Remove a <code>Runnable</code> from the command stack
+     *
+     * @param command The <code>Runnable</code> to be removed
+     */
+    public void remove( Runnable command ) {
+        synchronized( commandStack ) {
+            for( final Iterator i = commandStack.iterator(); i.hasNext(); ) {
+                final ExecutionInfo info = (ExecutionInfo)i.next();
+
+                if( info.m_command == command ) {
+                    i.remove();
+                    commandStack.notifyAll();
+
+                    return;
+                }
+            }
+        }
+
+        getLogger().warn( "Could not find command " + command +
+                          " for removal" );
+    }
+
+    /**
+     * The heart of the command manager
+     */
+    public void run()
+    {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Entering loop" );
+        }
+
+        while( keepRunning ) {
+            synchronized( commandStack ) {
+                try {
+                    if( commandStack.size(  ) > 0 ) {
+                        final ExecutionInfo info =
+                            (ExecutionInfo)commandStack.first();
+                        final long delay =
+                            info.m_nextRun - System.currentTimeMillis( );
+
+                        if( delay > 0 ) {
+                            commandStack.wait( delay );
+                        }
+                    } else {
+                        if( getLogger().isDebugEnabled() ) {
+                            getLogger().debug( "No commands available. Will just wait for one" );
+                        }
+
+                        commandStack.wait();
+                    }
+                } catch( final InterruptedException ie ) {
+                    if( getLogger().isDebugEnabled() ) {
+                        getLogger().debug( "I've been interrupted" );
+                    }
+                }
+
+                if( keepRunning ) {
+                    if( commandStack.size() > 0 ) {
+                        final ExecutionInfo info =
+                            (ExecutionInfo)commandStack.first();
+                        final long delay =
+                            info.m_nextRun - System.currentTimeMillis();
+
+                        if( delay < 0 ) {
+                            info.execute();
+                        }
+                    }
+                }
+            }
+        }
+
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Exiting loop" );
+        }
+    }
+    
+    /**
+     * Start the managing thread
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    public void start() throws Exception {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Starting the heart" );
+        }
+
+        keepRunning = true;
+        ( (ThreadPool) pools.get( DEFAULT_THREADPOOL_NAME ) ).execute( this );
+    }
+
+    /**
+     * Stop the managing thread
+     */
+    public void stop( ) {
+        keepRunning = false;
+
+        synchronized( commandStack ) {
+            commandStack.notifyAll();
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param priority The priority to set as string value.
+     *
+     * @return The priority as int value.
+     */
+    private int getPriority( final String priority ) {
+        if( "MIN".equalsIgnoreCase( priority ) ) {
+            return Thread.MIN_PRIORITY;
+        } else if( "NORM".equalsIgnoreCase( priority ) ) {
+            return Thread.NORM_PRIORITY;
+        } else if( "MAX".equalsIgnoreCase( priority ) ) {
+            return Thread.MAX_PRIORITY;
+        } else {
+            getLogger().warn( "Unknown thread priority \"" + priority +
+                              "\". Set to \"NORM\"." );
+
+            return Thread.NORM_PRIORITY;
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param config DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     *
+     * @throws ConfigurationException DOCUMENT ME!
+     */
+    private DefaultThreadPool configThreadPool( final Configuration config )
+    throws ConfigurationException {
+        final String name = config.getChild( "name" ).getValue();
+        final int queueSize =
+            config.getChild( "queue-size" ).getValueAsInteger( DEFAULT_QUEUE_SIZE );
+        final int maxPoolSize =
+            config.getChild( "max-pool-size" ).getValueAsInteger( DEFAULT_MAX_POOL_SIZE );
+        int minPoolSize =
+            config.getChild( "min-pool-size" ).getValueAsInteger( DEFAULT_MIN_POOL_SIZE );
+
+        // make sure we have enough threads for the default thread pool as we
+        // need one for ourself
+        if( DEFAULT_THREADPOOL_NAME.equals( name ) &&
+            ( ( minPoolSize > 0 ) && ( minPoolSize < DEFAULT_MIN_POOL_SIZE ) ) ) {
+            minPoolSize = DEFAULT_MIN_POOL_SIZE;
+        }
+
+        final String priority =
+            config.getChild( "priority" ).getValue( DEFAULT_THREAD_PRIORITY );
+        final boolean isDaemon =
+            config.getChild( "daemon" ).getValueAsBoolean( DEFAULT_DAEMON_MODE );
+        final long keepAliveTime =
+            config.getChild( "keep-alive-time-ms" ).getValueAsLong( DEFAULT_KEEP_ALIVE_TIME );
+        final String blockPolicy =
+            config.getChild( "block-policy" ).getValue( DefaultThreadPool.POLICY_DEFAULT );
+        final boolean shutdownGraceful =
+            config.getChild( "shutdown-graceful" ).getValueAsBoolean( DEFAULT_SHUTDOWN_GRACEFUL );
+        final int shutdownWaitTime =
+            config.getChild( "shutdown-wait-time-ms" ).getValueAsInteger( DEFAULT_SHUTDOWN_WAIT_TIME );
+
+        return createPool( new DefaultThreadPool(), name, queueSize,
+                           maxPoolSize, minPoolSize, getPriority( priority ),
+                           isDaemon, keepAliveTime, blockPolicy,
+                           shutdownGraceful, shutdownWaitTime );
+    }
+
+    /**
+     * Create a ThreadPool
+     *
+     * @param pool DOCUMENT ME!
+     * @param name DOCUMENT ME!
+     * @param queueSize The size of the queue
+     * @param maxPoolSize The maximum number of threads
+     * @param minPoolSize The maximum number of threads
+     * @param priority The priority of threads created by this pool. This is
+     *        one of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link Thread#MAX_PRIORITY}
+     * @param isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @param keepAliveTime How long should a thread be alive for new work to
+     *        be done before it is GCed
+     * @param blockPolicy What's the blocking policy is resources are exhausted
+     * @param shutdownGraceful Should we wait for the queue to finish all
+     *        pending commands?
+     * @param shutdownWaitTime After what time a normal shutdown should take
+     *        into account if a graceful shutdown has not come to an end
+     *
+     * @return A newly created <code>ThreadPool</code>
+     */
+    private DefaultThreadPool createPool( final DefaultThreadPool pool,
+                                          final String name,
+                                          final int queueSize,
+                                          final int maxPoolSize,
+                                          final int minPoolSize,
+                                          final int priority,
+                                          final boolean isDaemon,
+                                          final long keepAliveTime,
+                                          final String blockPolicy,
+                                          final boolean shutdownGraceful,
+                                          final int shutdownWaitTime ) {
+        pool.enableLogging( getLogger().getChildLogger( name ) );
+        pool.setName( name );
+
+        ThreadFactory factory = null;
+        try {
+            factory =
+                (ThreadFactory)defaultThreadFactoryClass.newInstance(  );
+        } catch( final Exception ex ) {
+            getLogger().warn( "Cannot instantiate a ThreadFactory from class " +
+                              defaultThreadFactoryClass.getName() +
+                              ". Will use a " +
+                              DefaultThreadFactory.class.getName(), ex );
+            factory = new DefaultThreadFactory(  );
+        }
+
+        factory.setPriority( priority );
+        factory.setDaemon( isDaemon );
+        pool.setThreadFactory( factory );
+        pool.setQueue( queueSize );
+        pool.setMaximumPoolSize( ( maxPoolSize < 0 ) ? Integer.MAX_VALUE
+                                 : maxPoolSize );
+
+        if( minPoolSize < 1 ) {
+            getLogger().warn( "min-pool-size < 1 for pool \"" +
+                              name + "\". Set to 1" );
+        }
+
+        pool.setMinimumPoolSize( ( minPoolSize < 1 ) ? 1 : minPoolSize );
+
+        if( keepAliveTime < 0 ) {
+            getLogger().warn( "keep-alive-time-ms < 0 for pool \"" +
+                              name + "\". Set to 1000" );
+        }
+
+        pool.setKeepAliveTime( ( keepAliveTime < 0 ) ? 1000 : keepAliveTime );
+        pool.setBlockPolicy( blockPolicy );
+        pool.setShutdownGraceful( shutdownGraceful );
+        pool.setShutdownWaitTimeMs( shutdownWaitTime );
+
+        synchronized( pools ) {
+            pools.put( name, pool );
+        }
+
+        printPoolInfo( pool );
+        return pool;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param pool DOCUMENT ME!
+     */
+    private void printPoolInfo( final DefaultThreadPool pool ) {
+        if( getLogger().isInfoEnabled() ) {
+            if( pool.isQueued() ) {
+                final StringBuffer msg = new StringBuffer();
+                msg.append( "ThreadPool named \"" ).append( pool.getName() );
+                msg.append( "\" created with maximum queue-size=" );
+                msg.append( pool.getMaxQueueSize(  ) );
+                msg.append( ",max-pool-size=" ).append( pool.getMaximumPoolSize() );
+                msg.append( ",min-pool-size=" ).append( pool.getMinimumPoolSize() );
+                msg.append( ",priority=" ).append( pool.getPriority() );
+                msg.append( ",isDaemon=" ).append( ( (ThreadFactory)pool.getThreadFactory() ).isDaemon() );
+                msg.append( ",keep-alive-time-ms=" ).append( pool.getKeepAliveTime() );
+                msg.append( ",block-policy=\"" ).append( pool.getBlockPolicy() );
+                msg.append( "\",shutdown-wait-time-ms=" ).append( pool.getShutdownWaitTimeMs() );
+                getLogger().info( msg.toString() );
+            } else {
+                final StringBuffer msg = new StringBuffer();
+                msg.append( "ThreadPool named \"" ).append( pool.getName() );
+                msg.append( "\" created with no queue,max-pool-size=" ).append( pool.getMaximumPoolSize() );
+                msg.append( ",min-pool-size=" ).append( pool.getMinimumPoolSize() );
+                msg.append( ",priority=" ).append( pool.getPriority() );
+                msg.append( ",isDaemon=" ).append( ( (ThreadFactory)pool.getThreadFactory() ).isDaemon() );
+                msg.append( ",keep-alive-time-ms=" ).append( pool.getKeepAliveTime() );
+                msg.append( ",block-policy=" ).append( pool.getBlockPolicy(  ) );
+                msg.append( ",shutdown-wait-time-ms=" ).append( pool.getShutdownWaitTimeMs() );
+                getLogger().info( msg.toString() );
+            }
+        }
+    }
+
+    //~ Inner Classes ----------------------------------------------------------
+
+    /**
+     * The $classType$ class ...
+     *
+     * @version $Id$
+     */
+    private class ExecutionInfo implements Comparable {
+        //~ Instance fields ----------------------------------------------------
+
+        /** Our logger */
+        final Logger m_logger;
+
+        /** DOCUMENT ME! */
+        final Runnable m_command;
+
+        /** DOCUMENT ME! */
+        final ThreadPool m_pool;
+
+        /** DOCUMENT ME! */
+        final long m_delay;
+
+        /** DOCUMENT ME! */
+        final long m_interval;
+
+        /** DOCUMENT ME! */
+        long m_nextRun = 0;
+
+        //~ Constructors -------------------------------------------------------
+
+        /**
+         * Creates a new ExecutionInfo object.
+         *
+         * @param pool DOCUMENT ME!
+         * @param command DOCUMENT ME!
+         * @param delay DOCUMENT ME!
+         * @param interval DOCUMENT ME!
+         * @param logger DOCUMENT ME!
+         */
+        ExecutionInfo( final ThreadPool pool,
+                       final Runnable command,
+                       final long delay,
+                       final long interval,
+                       final Logger logger ) {
+            m_pool = pool;
+            m_command = command;
+            m_delay = delay;
+            m_interval = interval;
+            m_logger = logger;
+            m_nextRun = System.currentTimeMillis() + delay;
+
+            synchronized( commandStack )
+            {
+                commandStack.add( this );
+                commandStack.notifyAll();
+            }
+            Thread.yield(); // Give others a chance to run
+        }
+
+        //~ Methods ------------------------------------------------------------
+
+        /**
+         * DOCUMENT ME!
+         *
+         * @param other DOCUMENT ME!
+         *
+         * @return DOCUMENT ME!
+         */
+        public int compareTo( final Object other ) {
+            final ExecutionInfo otherInfo = (ExecutionInfo)other;
+            int diff = (int)( m_nextRun - otherInfo.m_nextRun );
+            if (diff == 0) {
+                if (this == other) {
+                    // Same object, return 0.
+                    return 0;
+                } else {
+                    // NOT the same object, MUST return non-0 value.
+                    return System.identityHashCode(this) - System.identityHashCode(other);
+                }
+            }
+            return diff;
+        }
+
+        /**
+         * DOCUMENT ME!
+         */
+        void execute() {
+            if( m_logger.isDebugEnabled() ) {
+                m_logger.debug( "Executing command " + m_command + " in pool \"" +
+                                 m_pool.getName() + "\", schedule with interval=" + m_interval );
+            }
+
+            synchronized( commandStack ) {
+                commandStack.remove( this );
+                if( m_interval > 0 ) {
+                    m_nextRun = System.currentTimeMillis() + m_interval;
+                    commandStack.add( this );
+                }
+            }
+
+            try {
+                m_pool.execute( m_command );
+            } catch( final InterruptedException ie ) {
+                if( m_logger.isDebugEnabled() ) {
+                    m_logger.debug( "Interrupted executing command + " + m_command );
+                }
+            } catch( final Throwable t ) {
+                m_logger.error( "Exception executing command " + m_command, t );
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java
new file mode 100644
index 0000000..19d569d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadFactory.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * This class is responsible to create new Thread instances to run a command.
+ *
+ * @version $Id$
+ */
+public class DefaultThreadFactory
+    implements ThreadFactory, EDU.oswego.cs.dl.util.concurrent.ThreadFactory {
+    //~ Instance fields --------------------------------------------------------
+
+    /** The daemon mode */
+    private boolean m_isDaemon = false;
+
+    /** The priority of newly created Threads */
+    private int m_priority = Thread.NORM_PRIORITY;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Set the isDaemon property
+     *
+     * @param isDaemon Whether or not new <code>Thread</code> should run as
+     *        daemons.
+     */
+    public void setDaemon( boolean isDaemon ) {
+        m_isDaemon = isDaemon;
+    }
+
+    /**
+     * Get the isDaemon property
+     *
+     * @return Whether or not new <code>Thread</code> will run as daemons.
+     */
+    public boolean isDaemon() {
+        return m_isDaemon;
+    }
+
+    /**
+     * Set the priority newly created <code>Thread</code>s should have
+     *
+     * @param priority One of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    public void setPriority( final int priority ) {
+        if( ( Thread.MAX_PRIORITY == priority ) ||
+            ( Thread.MIN_PRIORITY == priority ) ||
+            ( Thread.NORM_PRIORITY == priority ) ) {
+            m_priority = priority;
+        }
+    }
+
+    /**
+     * Get the priority newly created <code>Thread</code>s will have
+     *
+     * @return One of {@link Thread#MIN_PRIORITY}, {@link
+     *         Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    public int getPriority() {
+        return m_priority;
+    }
+
+    /**
+     * Create a new Thread for Runnable
+     *
+     * @param command The {@link Runnable}
+     *
+     * @return A new Thread instance
+     */
+    public Thread newThread( final Runnable command ) {
+        final Thread thread = new Thread( command );
+        thread.setPriority( m_priority );
+        thread.setDaemon( m_isDaemon );
+
+        return thread;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java
new file mode 100644
index 0000000..321a41c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/DefaultThreadPool.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
+import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
+
+
+/**
+ * The DefaultThreadPool class implements the {@link ThreadPool} interface.
+ * Instances of this class are made by the {@link RunnableManager} passing a
+ * configuration into the <code>configure</code> method.
+ *
+ * @version $Id$
+ */
+public class DefaultThreadPool
+    extends PooledExecutor
+    implements ThreadPool, LogEnabled {
+
+    //~ Static fields/initializers ---------------------------------------------
+
+    /** Default ThreadPool block policy */
+    public static final String POLICY_DEFAULT = POLICY_RUN;
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** Wrapps a channel */
+    private ChannelWrapper m_channelWrapper;
+
+    /** Our logger */
+    private Logger m_logger;
+
+    /** The Queue */
+    private Queue m_queue;
+
+    /** The blocking policy */
+    private String m_blockPolicy;
+
+    /** The name of this thread pool */
+    private String m_name;
+
+    /** Should we wait for running jobs to terminate on shutdown ? */
+    private boolean m_shutdownGraceful;
+
+    /** The maximum queue size */
+    private int m_queueSize;
+
+    /** How long to wait for running jobs to terminate on disposition */
+    private int m_shutdownWaitTimeMs;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Create a new pool.
+     */
+    DefaultThreadPool() {
+        this( new ChannelWrapper() );
+    }
+
+    /**
+     * Create a new pool.
+     *
+     * @param channel DOCUMENT ME!
+     */
+    private DefaultThreadPool( final ChannelWrapper channel ) {
+        super( channel );
+        m_channelWrapper = channel;
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return Returns the blockPolicy.
+     */
+    public String getBlockPolicy() {
+        return m_blockPolicy;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return maximum size of the queue (0 if isQueued() == false)
+     *
+     * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+     */
+    public int getMaxQueueSize() {
+        return ( ( m_queueSize < 0 ) ? Integer.MAX_VALUE : m_queueSize );
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return size of queue (0 if isQueued() == false)
+     *
+     * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+     */
+    public int getMaximumQueueSize() {
+        return m_queueSize;
+    }
+
+    /**
+     * @see org.apache.cocoon.components.thread.ThreadPool#getName()
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Get hte priority used to create Threads
+     *
+     * @return {@link Thread#MIN_PRIORITY}, {@link Thread#NORM_PRIORITY}, or
+     *         {@link Thread#MAX_PRIORITY}
+     */
+    public int getPriority() {
+        return ((ThreadFactory)super.getThreadFactory()).getPriority();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return current size of the queue (0 if isQueued() == false)
+     *
+     * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+     */
+    public int getQueueSize() {
+        return m_queue.getQueueSize();
+    }
+
+    /**
+     * Whether this DefaultThreadPool has a queue
+     *
+     * @return Returns the m_isQueued.
+     *
+     * @see org.apache.cocoon.components.thread.ThreadPool#isQueued()
+     */
+    public boolean isQueued() {
+        return m_queueSize != 0;
+    }
+
+    /**
+     * Set the logger
+     *
+     * @param logger
+     *
+     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+     */
+    public void enableLogging( Logger logger ) {
+        m_logger = logger;
+    }
+
+    /**
+     * Execute a command
+     *
+     * @param command The {@link Runnable} to execute
+     *
+     * @throws InterruptedException In case of interruption
+     */
+    public void execute( Runnable command ) throws InterruptedException {
+        if( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Executing Command: " + command.toString() +
+                                 ",pool=" + getName() );
+        }
+
+        super.execute( command );
+    }
+
+    /**
+     * @see org.apache.cocoon.components.thread.ThreadPool#shutdown()
+     */
+    public void shutdown() {
+        if( m_shutdownGraceful ) {
+            shutdownAfterProcessingCurrentlyQueuedTasks();
+        } else {
+            shutdownNow();
+        }
+
+        try {
+            if( getShutdownWaitTimeMs() > 0 ) {
+                if( ! awaitTerminationAfterShutdown( getShutdownWaitTimeMs()) ) {
+                    getLogger().warn( "running commands have not terminated within " +
+                                      getShutdownWaitTimeMs() +
+                                      "ms. Will shut them down by interruption" );
+                    interruptAll();
+                    shutdownNow();
+                }
+            }
+
+            awaitTerminationAfterShutdown();
+        } catch( final InterruptedException ie ) {
+            getLogger().error( "cannot shutdown ThreadPool", ie );
+        }
+    }
+
+    /**
+     * Set the blocking policy
+     *
+     * @param blockPolicy The blocking policy value
+     */
+    void setBlockPolicy( final String blockPolicy ) {
+        m_blockPolicy = blockPolicy;
+
+        if( POLICY_ABORT.equalsIgnoreCase( blockPolicy ) ) {
+            abortWhenBlocked(  );
+        } else if( POLICY_DISCARD.equalsIgnoreCase( blockPolicy ) ) {
+            discardWhenBlocked(  );
+        } else if( POLICY_DISCARD_OLDEST.equalsIgnoreCase( blockPolicy ) ) {
+            discardOldestWhenBlocked();
+        } else if( POLICY_RUN.equalsIgnoreCase( blockPolicy ) ) {
+            runWhenBlocked();
+        } else if( POLICY_WAIT.equalsIgnoreCase( blockPolicy ) ) {
+            waitWhenBlocked();
+        } else {
+            final StringBuffer msg = new StringBuffer();
+            msg.append( "WARNING: Unknown block-policy configuration \"" )
+               .append( blockPolicy );
+            msg.append( "\". Should be one of \"" ).append( POLICY_ABORT );
+            msg.append( "\",\"" ).append( POLICY_DISCARD );
+            msg.append( "\",\"" ).append( POLICY_DISCARD_OLDEST );
+            msg.append( "\",\"" ).append( POLICY_RUN );
+            msg.append( "\",\"" ).append( POLICY_WAIT );
+            msg.append( "\". Will use \"" ).append( POLICY_DEFAULT ).append( "\"" );
+            getLogger().warn( msg.toString() );
+            setBlockPolicy( POLICY_DEFAULT );
+        }
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param name The name to set.
+     */
+    void setName( String name ) {
+        m_name = name;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param queueSize DOCUMENT ME!
+     */
+    void setQueue( final int queueSize ) {
+        if( queueSize != 0 ) {
+            if( queueSize > 0 ) {
+                m_queue = new BoundedQueue( queueSize );
+            } else {
+                m_queue = new LinkedQueue(  );
+            }
+        } else {
+            m_queue = new SynchronousChannel(  );
+        }
+
+        m_queueSize = queueSize;
+        m_channelWrapper.setChannel( m_queue );
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param shutdownGraceful The shutdownGraceful to set.
+     */
+    void setShutdownGraceful( boolean shutdownGraceful ) {
+        m_shutdownGraceful = shutdownGraceful;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return Returns the shutdownGraceful.
+     */
+    boolean isShutdownGraceful() {
+        return m_shutdownGraceful;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param shutdownWaitTimeMs The shutdownWaitTimeMs to set.
+     */
+    void setShutdownWaitTimeMs( int shutdownWaitTimeMs ) {
+        m_shutdownWaitTimeMs = shutdownWaitTimeMs;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return Returns the shutdownWaitTimeMs.
+     */
+    int getShutdownWaitTimeMs() {
+        return m_shutdownWaitTimeMs;
+    }
+
+    /**
+     * Get our <code>Logger</code>
+     *
+     * @return our <code>Logger</code>
+     */
+    private Logger getLogger() {
+        return m_logger;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/LinkedQueue.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/LinkedQueue.java
new file mode 100644
index 0000000..f05980d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/LinkedQueue.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * A linked list based channel implementation. The algorithm avoids contention
+ * between puts and takes when the queue is not empty. Normally a put and a
+ * take can proceed simultaneously. (Although it does not allow multiple
+ * concurrent puts or takes.) This class tends to perform more efficently than
+ * other Queue implementations in producer/consumer applications.
+ * 
+ * <p>
+ * [<a
+ * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html">
+ * Introduction to this package. </a>]
+ * </p>
+ */
+public class LinkedQueue
+    extends EDU.oswego.cs.dl.util.concurrent.LinkedQueue
+    implements Queue {
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see org.apache.cocoon.components.thread.Queue#getQueueSize()
+     */
+    public int getQueueSize() {
+        return -1;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/Queue.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/Queue.java
new file mode 100644
index 0000000..e22a743
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/Queue.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * Extension to add queue size reporting
+ *
+ * @version $Id$
+ *
+ * @see EDU.oswego.cs.dl.util.concurrent.Channel
+ */
+public interface Queue
+    extends EDU.oswego.cs.dl.util.concurrent.Channel {
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * get the current queue size
+     *
+     * @return current size of queue. If the size of the queue is not
+     *         maintained by an implementation -1 should be returned.
+     */
+    int getQueueSize();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/RunnableManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/RunnableManager.java
new file mode 100644
index 0000000..14c07ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/RunnableManager.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * The RunnableManager interface describes the functionality of an
+ * implementation running commands in the background.
+ *
+ * @version $Id$
+ */
+public interface RunnableManager {
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** The role name */
+    String ROLE = RunnableManager.class.getName();
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Create a shared ThreadPool with a specific {@link ThreadFactory}
+     *
+     * @param name The name of the thread pool
+     * @param queueSize The size of the queue
+     * @param maxPoolSize The maximum number of threads
+     * @param minPoolSize The maximum number of threads
+     * @param priority The priority of threads created by this pool. This is
+     *        one of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link Thread#MAX_PRIORITY}
+     * @param isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @param keepAliveTime How long should a thread be alive for new work to
+     *        be done before it is GCed
+     * @param blockPolicy What's the blocking policy is resources are exhausted
+     * @param shutdownGraceful Should we wait for the queue to finish all
+     *        pending commands?
+     * @param shutdownWaitTime After what time a normal shutdown should take
+     *        into account if a graceful shutdown has not come to an end
+     */
+    void createPool( String name,
+                     int queueSize,
+                     int maxPoolSize,
+                     int minPoolSize,
+                     int priority,
+                     final boolean isDaemon,
+                     long keepAliveTime,
+                     String blockPolicy,
+                     boolean shutdownGraceful,
+                     int shutdownWaitTime );
+
+    /**
+     * Create a private ThreadPool with a specific {@link ThreadFactory}
+     *
+     * @param queueSize The size of the queue
+     * @param maxPoolSize The maximum number of threads
+     * @param minPoolSize The maximum number of threads
+     * @param priority The priority of threads created by this pool. This is
+     *        one of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, or {@link Thread#MAX_PRIORITY}
+     * @param isDaemon Whether or not thread from the pool should run in daemon
+     *        mode
+     * @param keepAliveTime How long should a thread be alive for new work to
+     *        be done before it is GCed
+     * @param blockPolicy What's the blocking policy is resources are exhausted
+     * @param shutdownGraceful Should we wait for the queue to finish all
+     *        pending commands?
+     * @param shutdownWaitTime After what time a normal shutdown should take
+     *        into account if a graceful shutdown has not come to an end
+     *
+     * @return The newly created <code>ThreadPool</code>
+     */
+    ThreadPool createPool( int queueSize,
+                           int maxPoolSize,
+                           int minPoolSize,
+                           int priority,
+                           final boolean isDaemon,
+                           long keepAliveTime,
+                           String blockPolicy,
+                           boolean shutdownGraceful,
+                           int shutdownWaitTime );
+
+    /**
+     * Immediate Execution of a runnable in the background
+     *
+     * @param command The command to execute
+     */
+    void execute( Runnable command );
+
+    /**
+     * Immediate Execution of a runnable in the background
+     *
+     * @param command The command to execute
+     * @param delay The delay before first run
+     */
+    void execute( Runnable command,
+                  long delay );
+
+    /**
+     * Immediate Execution of a runnable in the background
+     *
+     * @param command The command to execute
+     * @param delay The delay before first run
+     * @param interval The interval of repeated runs
+     */
+    void execute( Runnable command,
+                  long delay,
+                  long interval );
+
+    /**
+     * Immediate Execution of a runnable in the background
+     *
+     * @param threadPoolName The thread pool to use
+     * @param command The command to execute
+     */
+    void execute( String threadPoolName,
+                  Runnable command );
+
+    /**
+     * Immediate Execution of a runnable in the background
+     *
+     * @param threadPoolName The thread pool to use
+     * @param command The command to execute
+     * @param delay The delay before first run
+     */
+    void execute( String threadPoolName,
+                  Runnable command,
+                  long delay );
+
+    /**
+     * Delayed and repeated Execution of a runnable in the background
+     *
+     * @param threadPoolName The thread pool to use
+     * @param command The command to execute
+     * @param delay The delay before first run
+     * @param interval The interval of repeated runs
+     */
+    void execute( String threadPoolName,
+                  Runnable command,
+                  long delay,
+                  long interval );
+
+    /**
+     * Remove a {@link Runnable} from the execution stack
+     *
+     * @param command The command to be removed
+     */
+    void remove( Runnable command );
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java
new file mode 100644
index 0000000..1c6271c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/SynchronousChannel.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
+import EDU.oswego.cs.dl.util.concurrent.Rendezvous;
+
+/**
+ * A rendezvous channel, similar to those used in CSP and Ada.  Each put must
+ * wait for a take, and vice versa.  Synchronous channels are well suited for
+ * handoff designs, in which an object running in one thread must synch up
+ * with an object running in another thread in order to hand it some
+ * information, event, or task.
+ * 
+ * <p>
+ * If you only need threads to synch up without exchanging information,
+ * consider using a Barrier. If you need bidirectional exchanges, consider
+ * using a Rendezvous.
+ * </p>
+ * 
+ * <p></p>
+ * 
+ * <p>
+ * [<a
+ * href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html">
+ * Introduction to this package. </a>]
+ * </p>
+ *
+ * @see CyclicBarrier
+ * @see Rendezvous
+ */
+public class SynchronousChannel
+    extends EDU.oswego.cs.dl.util.concurrent.SynchronousChannel
+    implements Queue {
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see org.apache.cocoon.components.thread.Queue#getQueueSize()
+     */
+    public int getQueueSize(){
+        return 0;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadFactory.java
new file mode 100644
index 0000000..48cc4cd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * The ThreadFactory interface describes the responability of Factories
+ * creating Thread for {@link ThreadPool}s of the {@link RunnableManager}
+ *
+ * @version $Id$
+ */
+public interface ThreadFactory
+    extends EDU.oswego.cs.dl.util.concurrent.ThreadFactory {
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Set the daemon mode of created <code>Thread</code>s should have
+     *
+     * @param isDaemon Whether new {@link Thread}s should run as daemons.
+     */
+    void setDaemon( boolean isDaemon );
+
+    /**
+     * Get the daemon mode created <code>Thread</code>s will have
+     *
+     * @return Whether new {@link Thread}s should run as daemons.
+     */
+    boolean isDaemon();
+
+    /**
+     * Set the priority newly created <code>Thread</code>s should have
+     *
+     * @param priority One of {@link Thread#MIN_PRIORITY}, {@link
+     *        Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    void setPriority( int priority );
+
+    /**
+     * Get the priority newly created <code>Thread</code>s will have
+     *
+     * @return One of {@link Thread#MIN_PRIORITY}, {@link
+     *         Thread#NORM_PRIORITY}, {@link Thread#MAX_PRIORITY}
+     */
+    int getPriority();
+
+    /**
+     * Create a new Thread for a {@link Runnable} command
+     *
+     * @param command The <code>Runnable</code>
+     *
+     * @return new <code>Thread</code>
+     */
+    Thread newThread( Runnable command );
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadPool.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadPool.java
new file mode 100644
index 0000000..7897ead
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/thread/ThreadPool.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+/**
+ * The ThreadPool interface gives access to methods needed to inspect and use
+ * of  a pool of threads
+ *
+ * @version $Id$
+ */
+public interface ThreadPool {
+
+    //~ Instance fields --------------------------------------------------------
+
+    /** ThreadPool block policy ABORT */
+    String POLICY_ABORT = "ABORT";
+
+    /** ThreadPool block policy DISCARD */
+    String POLICY_DISCARD = "DISCARD";
+
+    /** ThreadPool block policy DISCARD-OLDEST */
+    String POLICY_DISCARD_OLDEST = "DISCARDOLDEST";
+
+    /** ThreadPool block policy RUN */
+    String POLICY_RUN = "RUN";
+
+    /** ThreadPool block policy WAIT */
+    String POLICY_WAIT = "WAIT";
+
+    /** The Role name */
+    String ROLE = ThreadPool.class.getName();
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * The blocking policy used
+     *
+     * @return DOCUMENT ME!
+     */
+    String getBlockPolicy();
+
+    /**
+     * How long will a thread in this pool be idle before it is allowed to be
+     * garbage collected
+     *
+     * @return maximum idle time
+     */
+    long getKeepAliveTime();
+
+    /**
+     * How many threads are in this pool at maximum
+     *
+     * @return maximum size of pool
+     */
+    int getMaximumPoolSize();
+
+    /**
+     * Maximum size of the queue
+     *
+     * @return current size of queue
+     */
+    int getMaximumQueueSize();
+
+    /**
+     * How many threads are in this pool at minimum
+     *
+     * @return minimum size of pool
+     */
+    int getMinimumPoolSize();
+
+    /**
+     * The Name of this thread pool
+     *
+     * @return The name
+     */
+    String getName();
+
+    /**
+     * How many threads are currently in this pool
+     *
+     * @return current size of pool
+     */
+    int getPoolSize();
+
+    /**
+     * Get the thread priority used by this pool
+     *
+     * @return current size of queue
+     */
+    int getPriority();
+
+    /**
+     * Current size of the queue.
+     *
+     * @return current size of queue. If the size of the queue is not
+     *         maintained by an implementation -1 should be returned.
+     */
+    int getQueueSize();
+
+    /**
+     * Whether this ThreadPool has a queue
+     *
+     * @return Returns true if this ThreadPool has a queue
+     */
+    boolean isQueued();
+
+    /**
+     * Returns true if a shutDown method has succeeded in terminating all
+     * threads
+     *
+     * @return Whether a shutDown method has succeeded in terminating all
+     *         threads
+     */
+    boolean isTerminatedAfterShutdown();
+
+    /**
+     * Execute a command using this pool
+     *
+     * @param command a {@link Runnable} to execute
+     *
+     * @throws InterruptedException In case of interruption
+     */
+    void execute( Runnable command )
+    throws InterruptedException;
+
+    /**
+     * Terminates all threads possibly awaiting processing all elements
+     * currently in queue.
+     */
+    void shutdown();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNode.java
new file mode 100644
index 0000000..ead386b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNode.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.cocoon.environment.Environment;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public abstract class AbstractParentProcessingNode extends AbstractProcessingNode {
+
+    public AbstractParentProcessingNode(String type) {
+        super(type);
+    }
+
+    public AbstractParentProcessingNode() {
+        this(null);
+    }
+
+    /**
+     * Invoke all nodes of a node array in order, until one succeeds.
+     *
+     * @param currentMap the <code>Map<code> of parameters produced by this node,
+     *            which is added to <code>listOfMap</code>.
+     */
+    protected final boolean invokeNodes(ProcessingNode[] nodes,
+                                        Environment env,
+                                        InvokeContext context,
+                                        String currentName,
+                                        Map currentMap)
+    throws Exception {
+
+        currentMap = this.executor.pushVariables(this, env.getObjectModel(), currentName, currentMap);
+        context.pushMap(currentName,currentMap);
+
+        try {
+            for (int i = 0; i < nodes.length; i++) {
+                if (nodes[i].invoke(env, context)) {
+                    // Success
+                    return true;
+                }
+            }
+        } finally {
+            this.executor.popVariables(this, env.getObjectModel());
+            // No success
+            context.popMap();
+        }
+        return false;
+    }
+
+    /**
+     * Invoke all nodes of a node array in order, until one succeeds.
+     */
+    protected final boolean invokeNodes (ProcessingNode[] nodes,
+                                         Environment env,
+                                         InvokeContext context)
+    throws Exception {
+
+        for (int i = 0; i < nodes.length; i++) {
+            if (nodes[i].invoke(env, context)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNodeBuilder.java
new file mode 100644
index 0000000..300bc37
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractParentProcessingNodeBuilder.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Base class for parent <code>ProcessingNodeBuilders</code>, providing services for parsing
+ * children nodes.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractParentProcessingNodeBuilder extends AbstractProcessingNodeBuilder
+                                                          implements Configurable {
+
+    protected Collection allowedChildren;
+
+    protected Collection forbiddenChildren;
+
+    protected Collection ignoredChildren;
+
+    /**
+     * Configure the sets of allowed, forbidden and ignored children nodes.
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        this.allowedChildren   = getStringCollection(config.getChild("allowed-children"));
+        this.forbiddenChildren = getStringCollection(config.getChild("forbidden-children"));
+        this.ignoredChildren   = getStringCollection(config.getChild("ignored-children"));
+    }
+
+    /**
+     * Checks if a child element and is allowed, and if not throws a <code>ConfigurationException</code>.
+     *
+     * @param child the child configuration to check.
+     * @return <code>true</code> if this child should be considered or <code>false</code>
+     *         if it should be ignored.
+     * @throws ConfigurationException if this child isn't allowed.
+     */
+    protected boolean isChild(Configuration child) throws ConfigurationException {
+
+        checkNamespace(child);
+
+        String name = child.getName();
+
+        // Is this a parameter of a parameterizable node builder ?
+        if (isParameter(child)) {
+            return false;
+        }
+
+        // Is this element to be ignored ?
+        if (ignoredChildren != null && ignoredChildren.contains(name)) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Element '" + name + "' is ignored for building children of element '" +
+                                  child.getName() + "'");
+            }
+
+            return false;
+        }
+
+        // Is it allowed ?
+        if ( (allowedChildren != null && !allowedChildren.contains(name)) ||
+             (forbiddenChildren != null && forbiddenChildren.contains(name)) ) {
+            String msg = "Element '" + name + "' is not allowed at " + child.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        return true;
+    }
+
+    protected boolean isParameter(Configuration config) throws ConfigurationException {
+        final String name = config.getName();
+        if (name.equals("parameter")) {
+            if (this.hasParameters()) {
+                return true;
+            }
+            String msg = "Element '" + name + "' has no parameters at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+        return false;
+    }
+
+    /**
+     * Create the <code>ProcessingNode</code>s for the children of a given node.
+     * Child nodes are controlled to be actually allowed in this node.
+     */
+    protected List buildChildNodesList(Configuration config) throws Exception {
+
+        Configuration[] children = config.getChildren();
+        List result = new ArrayList();
+
+        for (int i = 0; i < children.length; i++) {
+
+            Configuration child = children[i];
+            try {
+                 if (isChild(child)) {
+                    // OK : get a builder.
+                    ProcessingNodeBuilder childBuilder = this.treeBuilder.createNodeBuilder(child);
+                    result.add(childBuilder.buildNode(child));
+                }
+
+            } catch(ConfigurationException ce) {
+                throw ce;
+            } catch(Exception e) {
+                String msg = "Error while creating node '" + child.getName() + "' at " + child.getLocation();
+                throw new ConfigurationException(msg, e);
+            }
+        }
+
+        return result;
+    }
+
+    protected ProcessingNode[] buildChildNodes(Configuration config) throws Exception {
+        return toNodeArray(buildChildNodesList(config));
+    }
+
+    /**
+     * Convenience function that converts a <code>List</code> of <code>ProcessingNode</code>s
+     * to an array.
+     */
+    public static ProcessingNode[] toNodeArray(List list) {
+        return (ProcessingNode[])list.toArray(new ProcessingNode[list.size()]);
+    }
+
+    /**
+     * Splits the value of a Configuration in a Collection of Strings. Splitting
+     * occurs at space characters (incl. line breaks) and comma.
+     *
+     * @return a collection of Strings, or null if <code>config</code> has no value.
+     */
+    private Collection getStringCollection(Configuration config) {
+        String s = config.getValue(null);
+
+        return (s == null) ? null : Arrays.asList(StringUtils.split(s, ", \t\n\r"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java
new file mode 100644
index 0000000..9c86af9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNode.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.sitemap.ExecutionContext;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.util.location.Location;
+
+/**
+ *
+ * @version $Id$
+ */
+public abstract class AbstractProcessingNode 
+    extends AbstractLogEnabled 
+    implements ProcessingNode, ExecutionContext {
+
+    protected Location location = Location.UNKNOWN;
+
+    /** The type of the component */
+    protected String componentName;
+    
+    /** The sitemap executor */
+    protected SitemapExecutor executor;
+    
+    public AbstractProcessingNode(String type) {
+        this.componentName = type;
+    }
+    
+    public AbstractProcessingNode() {
+        this(null);
+    }
+
+    /**
+     * Get the location of this node.
+     */
+    public Location getLocation() {
+        return this.location;
+    }
+
+    /**
+     * Set the location of this node.
+     */
+    public void setLocation(Location location) {
+        this.location = location;
+    }
+    
+    /**
+     * Set the sitemap executor
+     */
+    public void setSitemapExecutor(SitemapExecutor executor) {
+        this.executor = executor;
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.sitemap.ExecutionContext#getType()
+     */
+    public String getType() {
+        return this.componentName;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java
new file mode 100644
index 0000000..fd4ea0f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AbstractProcessingNodeBuilder.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ *
+ * @version $Id$
+ */
+public abstract class AbstractProcessingNodeBuilder extends AbstractLogEnabled
+                                                    implements ProcessingNodeBuilder {
+
+    protected TreeBuilder treeBuilder;
+
+    protected ServiceManager manager;
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder#setBuilder(org.apache.cocoon.components.treeprocessor.TreeBuilder)
+     */
+    public void setBuilder(TreeBuilder treeBuilder) {
+        this.treeBuilder = treeBuilder;
+        this.manager = treeBuilder.getBuiltProcessorManager();
+    }
+
+    /**
+     * Does this node accept parameters ? Default is true : if a builder that doesn't
+     * have parameters doesn't override this method, erroneous parameters will be silently
+     * ignored.
+     */
+    protected boolean hasParameters() {
+        return true;
+    }
+
+    /**
+     * Check if the namespace URI of the given configuraition is the same as the
+     * one given by the builder.
+     */
+    protected void checkNamespace(Configuration config) throws ConfigurationException {
+        if (!this.treeBuilder.getNamespace().equals(config.getNamespace())) {
+            String msg = "Invalid namespace '" + config.getNamespace() + "' at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AnnotationsFilter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AnnotationsFilter.java
new file mode 100644
index 0000000..e363f9a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/AnnotationsFilter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/** Filter out annotations in the sitemap
+ *  (bugzilla 25352)
+ * @version $Id$
+ */
+class AnnotationsFilter implements ContentHandler {
+    public static final String ANNOTATIONS_NAMESPACE = "http://apache.org/cocoon/sitemap/annotations/1.0";
+
+    private ContentHandler delegate;
+
+    private int nestingLevel;
+
+    private boolean isOutsideAnnotation()
+    {
+        return nestingLevel == 0;
+    }
+
+    public AnnotationsFilter(ContentHandler delegate) {
+        this.delegate = delegate;
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        delegate.setDocumentLocator(locator);
+    }
+
+    public void startDocument() throws SAXException {
+        delegate.startDocument();
+    }
+
+    public void endDocument() throws SAXException {
+        delegate.endDocument();
+    }
+
+    public void startPrefixMapping(String prefix, String namespaceURI) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.startPrefixMapping(prefix, namespaceURI);
+        }
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.endPrefixMapping(prefix);
+        }
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException {
+        if (namespaceURI !=  null && namespaceURI.equals(ANNOTATIONS_NAMESPACE)) {
+            nestingLevel++;
+        }
+        if (isOutsideAnnotation()) {
+            delegate.startElement(namespaceURI, localName, qName, attributes);
+        }
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.endElement(namespaceURI, localName, qName);
+        }
+        if (namespaceURI !=  null && namespaceURI.equals(ANNOTATIONS_NAMESPACE)) {
+            nestingLevel--;
+        }
+    }
+
+    public void characters(char[] ch, int start, int len) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.characters(ch, start, len);
+        }
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int len) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.ignorableWhitespace(ch, start, len);
+        }
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.processingInstruction(target, data);
+        }
+    }
+
+    public void skippedEntity(String name) throws SAXException {
+        if (isOutsideAnnotation()) {
+            delegate.skippedEntity(name);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNode.java
new file mode 100644
index 0000000..f3ad31d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNode.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * A generic container node that just invokes its children.
+ *
+ * @version $Id$
+ */
+public final class CategoryNode extends AbstractParentProcessingNode {
+
+    public CategoryNode(String type) {
+        super(type);
+    }
+    
+    /** The name of this category */
+    private String categoryName;
+
+    /** The Map of named nodes in this category */
+    private Map nodes;
+
+    public void setCategory(String categoryName, Map nodes) {
+        this.categoryName = categoryName;
+        this.nodes = (nodes != null) ? nodes : new HashMap(0);
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context) throws Exception {
+        String msg = "Cannot invoke " + this.categoryName + " at " + getLocation();
+        throw new ProcessingException(msg);
+    }
+
+    public final ProcessingNode getNodeByName(String name) throws Exception {
+        ProcessingNode node = (ProcessingNode)nodes.get(name);
+        if (node == null) {
+            String msg = "Unknown " + this.categoryName + " named '" + name + "' at " + getLocation();
+            throw new ProcessingException(msg);
+        }
+
+        return node;
+    }
+
+    public final boolean invokeByName(String name, Environment env, InvokeContext context)
+      throws Exception {
+
+        return getNodeByName(name).invoke(env, context);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNodeBuilder.java
new file mode 100644
index 0000000..86d5c23
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/CategoryNodeBuilder.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * Builds a generic container node.
+ *
+ * @version $Id$
+ */
+public class CategoryNodeBuilder extends AbstractParentProcessingNodeBuilder
+  implements Configurable, ThreadSafe {
+
+    // Prefix used for registering as a TreeBuilder attribute
+    private static String PREFIX = CategoryNodeBuilder.class.getName() + "/";
+
+    protected String name;
+
+    /**
+     * The category name is the value of the "category-name" child, or if not
+     * present, the name of the configuration element.
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        super.configure(config);
+        this.name = config.getChild("category-name").getValue(config.getAttribute("name"));
+    }
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        CategoryNode node = new CategoryNode(null);
+        this.treeBuilder.setupNode(node, config);
+
+        // Get all children and associate them to their name
+        Map category = new HashMap();
+
+        List children = buildChildNodesList(config);
+        Iterator iter = children.iterator();
+        while(iter.hasNext()) {
+            NamedProcessingNode child = (NamedProcessingNode)iter.next();
+            category.put(child.getName(), child);
+        }
+
+        node.setCategory(this.name, category);
+
+        // Register node to allow lookup by other nodes
+        if ( !this.treeBuilder.registerNode(PREFIX + this.name, node) ) {
+            throw new ConfigurationException("Only one <map:" + this.name +
+                    "> is allowed in a sitemap. Another one is declared at " +
+                    config.getLocation());
+        }
+
+        return node;
+    }
+
+    public static CategoryNode getCategoryNode(TreeBuilder builder, String categoryName) {
+        return (CategoryNode)builder.getRegisteredNode(PREFIX + categoryName);
+    }
+
+    public static ProcessingNode getNamedNode(TreeBuilder builder, String categoryName, String nodeName)
+      throws Exception {
+        CategoryNode category = getCategoryNode(builder, categoryName);
+
+        return category.getNodeByName(nodeName);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
new file mode 100644
index 0000000..139a1e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ConcreteTreeProcessor.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.source.impl.SitemapSourceInfo;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ForwardRedirector;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.internal.ForwardEnvironmentWrapper;
+import org.apache.cocoon.environment.wrapper.MutableEnvironmentFacade;
+import org.apache.cocoon.sitemap.ComponentLocator;
+import org.apache.cocoon.sitemap.EnterSitemapEvent;
+import org.apache.cocoon.sitemap.EnterSitemapEventListener;
+import org.apache.cocoon.sitemap.ExecutionContext;
+import org.apache.cocoon.sitemap.LeaveSitemapEvent;
+import org.apache.cocoon.sitemap.LeaveSitemapEventListener;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.sitemap.SitemapListener;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.commons.jci.listeners.NotificationListener;
+
+/**
+ * The concrete implementation of {@link Processor}, containing the evaluation tree and associated
+ * data such as component manager.
+ *
+ * @version $Id$
+ */
+public class ConcreteTreeProcessor extends AbstractLogEnabled
+                                   implements Processor, Disposable, ExecutionContext, NotificationListener {
+
+    /** Our ServiceManager */
+    private ServiceManager manager;
+
+    /** Our class loader */
+    private ClassLoader classloader;
+
+    /** The processor that wraps us */
+    private TreeProcessor wrappingProcessor;
+
+    /** Processing nodes that need to be disposed with this processor */
+    private List disposableNodes;
+
+    /** Root node of the processing tree */
+    private ProcessingNode rootNode;
+
+    private Configuration componentConfigurations;
+
+    /** Number of simultaneous uses of this processor (either by concurrent request or by internal requests) */
+    private int requestCount;
+
+    /** The sitemap executor */
+    private SitemapExecutor sitemapExecutor;
+
+    /** Optional application container */
+    private ComponentLocator applicationContainer;
+
+    /** Optional event listeners for the enter sitemap event */
+    private List enterSitemapEventListeners = new ArrayList();
+
+    /** Optional event listeners for the leave sitemap event */
+    private List leaveSitemapEventListeners = new ArrayList();
+
+    /** Needs a reload? */
+    protected volatile boolean needsReload = false;
+    
+    /** Processor attributes */
+    protected Map processorAttributes = new HashMap();
+
+    /** no listeners by default */ 
+    private Map classpathListeners = Collections.EMPTY_MAP;
+    
+    /**
+     * Builds a concrete processig, given the wrapping processor
+     */
+    public ConcreteTreeProcessor(TreeProcessor wrappingProcessor,
+                                 SitemapExecutor sitemapExecutor) {
+        // Store our wrapping processor
+        this.wrappingProcessor = wrappingProcessor;
+
+        // Get the sitemap executor - we use the same executor for each sitemap
+        this.sitemapExecutor = sitemapExecutor;        
+    }
+
+    public void handleNotification() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug(this + " got notified that a reload is required");
+        }
+        needsReload = true;
+    }
+    
+    public void setClasspathListeners(Map classpathListeners) {
+        this.classpathListeners = classpathListeners;
+    }
+    
+    public Map getClasspathListeners() {
+        return this.classpathListeners;
+    }    
+    
+    /** Set the processor data, result of the treebuilder job */
+    public void setProcessorData(ServiceManager manager, 
+                                 ClassLoader classloader, 
+                                 ProcessingNode rootNode, 
+                                 List disposableNodes,
+                                 ComponentLocator componentLocator,
+                                 List enterSitemapEventListeners,
+                                 List leaveSitemapEventListeners) {
+        if (this.rootNode != null) {
+            throw new IllegalStateException("setProcessorData() can only be called once");
+        }
+
+        this.manager = manager;
+        this.classloader = classloader;
+        this.rootNode = rootNode;
+        this.disposableNodes = disposableNodes;
+        this.enterSitemapEventListeners = enterSitemapEventListeners;
+        this.leaveSitemapEventListeners = leaveSitemapEventListeners;
+        this.applicationContainer = componentLocator;
+    }
+
+    /** Set the sitemap component configurations (called as part of the tree building process) */
+    public void setComponentConfigurations(Configuration componentConfigurations) {
+        this.componentConfigurations = componentConfigurations;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getComponentConfigurations()
+     */
+    public Configuration[] getComponentConfigurations() {
+        if (this.componentConfigurations == null) {
+            if (this.wrappingProcessor.parent != null) {
+                return this.wrappingProcessor.parent.getComponentConfigurations();
+            }
+            return null;
+        }
+        if (this.wrappingProcessor.parent == null) {
+            return new Configuration[]{this.componentConfigurations};
+        }
+        final Configuration[] parentArray = this.wrappingProcessor.parent.getComponentConfigurations();
+        if ( parentArray != null ) {
+            final Configuration[] newArray = new Configuration[parentArray.length + 1];
+            System.arraycopy(parentArray, 0, newArray, 1, parentArray.length);
+            newArray[0] = this.componentConfigurations;
+            return newArray;
+        }
+        return new Configuration[] {this.componentConfigurations};
+    }
+
+    /**
+     * Mark this processor as needing to be disposed. Actual call to {@link #dispose()} will occur when
+     * all request processings on this processor will be terminated.
+     */
+    public void markForDisposal() {
+        // Decrement the request count (negative number means dispose)
+        synchronized(this) {
+            this.requestCount--;
+        }
+
+        if (this.requestCount < 0) {
+            // No more users : dispose right now
+            dispose();
+        }
+    }
+
+    boolean isReloadNeeded() {
+        return needsReload;
+    }
+    
+    public TreeProcessor getWrappingProcessor() {
+        return this.wrappingProcessor;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getRootProcessor()
+     */
+    public Processor getRootProcessor() {
+        return this.wrappingProcessor.getRootProcessor();
+    }
+
+    /**
+     * Process the given <code>Environment</code> producing the output.
+     * @return If the processing is successfull <code>true</code> is returned.
+     *         If not match is found in the sitemap <code>false</code>
+     *         is returned.
+     * @throws org.apache.cocoon.ResourceNotFoundException If a sitemap component tries
+     *                                   to access a resource which can not
+     *                                   be found, e.g. the generator
+     *         ConnectionResetException  If the connection was reset
+     */
+    public boolean process(Environment environment) throws Exception {
+        InvokeContext context = new InvokeContext();
+        context.enableLogging(getLogger());
+        try {
+            return process(environment, context);
+        } finally {
+            context.dispose();
+        }
+    }
+
+    /**
+     * Process the given <code>Environment</code> to assemble
+     * a <code>ProcessingPipeline</code>.
+     * @since 2.1
+     */
+    public InternalPipelineDescription buildPipeline(Environment environment)
+    throws Exception {
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+        try {
+            if (process(environment, context)) {
+                return context.getInternalPipelineDescription(environment);
+            }
+            return null;
+        } finally {
+            context.dispose();
+        }
+    }
+
+    /**
+     * Do the actual processing, be it producing the response or just building the pipeline
+     * @param environment
+     * @param context
+     * @return true if the pipeline was successfully built, false otherwise.
+     * @throws Exception
+     */
+    protected boolean process(Environment environment, InvokeContext context)
+    throws Exception {
+
+        // Increment the concurrent requests count
+        synchronized (this) {
+            requestCount++;
+        }
+
+        Thread currentThread = Thread.currentThread();
+        ClassLoader oldClassLoader = currentThread.getContextClassLoader();
+        currentThread.setContextClassLoader(this.classloader);
+
+        try {
+            // invoke listeners
+            // only invoke if pipeline is not internally
+            if ( !context.isBuildingPipelineOnly() && this.enterSitemapEventListeners.size() > 0 ) {
+                final EnterSitemapEvent enterEvent = new EnterSitemapEvent(this, environment);
+                final Iterator enterSEI = this.enterSitemapEventListeners.iterator();
+                while ( enterSEI.hasNext() ) {
+                    final TreeBuilder.EventComponent current = (TreeBuilder.EventComponent)enterSEI.next();
+                    ((EnterSitemapEventListener)current.component).enteredSitemap(enterEvent);
+                }
+            }
+
+            this.sitemapExecutor.enterSitemap(this, environment.getObjectModel(), this.wrappingProcessor.source.getURI());
+            // and now process
+            EnvironmentHelper.enterProcessor(this, this.manager, environment);
+            final Redirector oldRedirector = context.getRedirector();
+
+            // Build a redirector
+            TreeProcessorRedirector redirector = new TreeProcessorRedirector(environment, context);
+            setupLogger(redirector);
+            context.setRedirector(redirector);
+            context.service(this.manager);
+            context.setLastProcessor(this);
+
+            try {
+                final boolean success = this.rootNode.invoke(environment, context);
+                return success;
+            } finally {
+                EnvironmentHelper.leaveProcessor();
+                // Restore old redirector
+                context.setRedirector(oldRedirector);
+            }
+
+        } finally {
+            this.sitemapExecutor.leaveSitemap(this, environment.getObjectModel());
+            // invoke listeners
+            // only invoke if pipeline is not internally
+            if ( !context.isBuildingPipelineOnly() && this.leaveSitemapEventListeners.size() > 0 ) {
+                final LeaveSitemapEvent leaveEvent = new LeaveSitemapEvent(this, environment);
+                final Iterator leaveSEI = this.leaveSitemapEventListeners.iterator();
+                while ( leaveSEI.hasNext() ) {
+                    final TreeBuilder.EventComponent current = (TreeBuilder.EventComponent)leaveSEI.next();
+                    ((LeaveSitemapEventListener)current.component).leftSitemap(leaveEvent);
+                }
+            }
+
+            // Restore classloader
+            currentThread.setContextClassLoader(oldClassLoader);
+
+            // Decrement the concurrent request count
+            synchronized (this) {
+                requestCount--;
+            }
+
+            if (requestCount < 0) {
+                // Marked for disposal and no more concurrent requests.
+                dispose();
+            }
+        }
+    }
+
+    protected boolean handleCocoonRedirect(String uri, Environment environment, InvokeContext context)
+    throws Exception {
+        // Build an environment wrapper
+        // If the current env is a facade, change the delegate and continue processing the facade, since
+        // we may have other redirects that will in turn also change the facade delegate
+
+        MutableEnvironmentFacade facade = environment instanceof MutableEnvironmentFacade ?
+            ((MutableEnvironmentFacade)environment) : null;
+
+        if (facade != null) {
+            // Consider the facade delegate (the real environment)
+            environment = facade.getDelegate();
+        }
+
+        // test if this is a call from flow
+        boolean isRedirect = (environment.getObjectModel().remove("cocoon:forward") == null);
+        final SitemapSourceInfo info = SitemapSourceInfo.parseURI(environment, uri);
+        Environment newEnv = new ForwardEnvironmentWrapper(environment, info, getLogger());
+        if (isRedirect) {
+            ((ForwardEnvironmentWrapper) newEnv).setInternalRedirect(true);
+        }
+
+        if (facade != null) {
+            // Change the facade delegate
+            facade.setDelegate((ForwardEnvironmentWrapper)newEnv);
+            newEnv = facade;
+        }
+
+        // Get the processor that should process this request
+        ConcreteTreeProcessor processor;
+        if (newEnv.getURIPrefix().equals("")) {
+            processor = ((TreeProcessor)getRootProcessor()).concreteProcessor;
+        } else {
+            processor = this;
+        }
+
+        // Process the redirect
+        // No more reset since with TreeProcessorRedirector, we need to pop values from the redirect location
+        // context.reset();
+        // The following is a fix for bug #26854 and #26571
+        final boolean result = processor.process(newEnv, context);
+        if (facade != null) {
+            newEnv = facade.getDelegate();
+        }
+        if (((ForwardEnvironmentWrapper) newEnv).getRedirectURL() != null) {
+            environment.redirect(((ForwardEnvironmentWrapper) newEnv).getRedirectURL(), false, false);
+        }
+        return result;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.disposableNodes != null) {
+            // we must dispose the nodes in reverse order
+            // otherwise selector nodes are freed before the components node
+            for (int i = this.disposableNodes.size() - 1; i > -1; i--) {
+                ((Disposable) disposableNodes.get(i)).dispose();
+            }
+            this.disposableNodes = null;
+        }
+
+        // Ensure it won't be used anymore
+        this.rootNode = null;
+        this.sitemapExecutor = null;
+
+        // dispose listeners
+        this.disposeListeners(this.enterSitemapEventListeners);
+        this.disposeListeners(this.leaveSitemapEventListeners);
+
+        // dispose component locator - if it is a SitemapListener it is already disposed!
+        if ( !(this.applicationContainer instanceof SitemapListener) ) {
+            ContainerUtil.dispose(this.applicationContainer);
+        }
+        this.applicationContainer = null;
+    }
+
+    protected void disposeListeners(List l) {
+        Iterator i = l.iterator();
+        while ( i.hasNext() ) {
+            final TreeBuilder.EventComponent current = (TreeBuilder.EventComponent)i.next();
+            if ( current.releaseUsingManager ) {
+                this.manager.release(current.component);
+            } else {
+                ContainerUtil.dispose(current.component);
+            }
+        }
+        l.clear();        
+    }
+
+    private class TreeProcessorRedirector extends ForwardRedirector {
+        private InvokeContext context;
+
+        public TreeProcessorRedirector(Environment env, InvokeContext context) {
+            super(env);
+            this.context = context;
+        }
+
+        protected void cocoonRedirect(String uri) throws IOException, ProcessingException {
+            try {
+                ConcreteTreeProcessor.this.handleCocoonRedirect(uri, this.env, this.context);
+            } catch (IOException e) {
+                throw e;
+            } catch (ProcessingException e) {
+                throw e;
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new ProcessingException(e);
+            }
+        }
+    }
+
+    public SourceResolver getSourceResolver() {
+        return wrappingProcessor.getSourceResolver();
+    }
+
+    public String getContext() {
+        return wrappingProcessor.getContext();
+    }
+    /**
+     * Return the sitemap executor
+     */
+    public SitemapExecutor getSitemapExecutor() {
+        return this.sitemapExecutor;
+    }
+
+    public ServiceManager getServiceManager() {
+        return this.manager;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.processorAttributes.get(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.processorAttributes.remove(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.processorAttributes.put(name, value);
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ExecutionContext#getLocation()
+     */
+    public Location getLocation() {
+        return new LocationImpl("[sitemap]", this.wrappingProcessor.source.getURI());
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ExecutionContext#getType()
+     */
+    public String getType() {
+        return "sitemap";
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNode.java
new file mode 100644
index 0000000..aa69afb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNode.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * A generic container node that just invokes its children.
+ *
+ * @version $Id$
+ */
+public class ContainerNode extends SimpleParentProcessingNode {
+
+    public ContainerNode(String type) {
+        super(type);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context) throws Exception {
+
+        return invokeNodes(this.children, env, context);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNodeBuilder.java
new file mode 100644
index 0000000..2a6c08f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ContainerNodeBuilder.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * Builds a generic container node.
+ *
+ * @version $Id$
+ */
+public class ContainerNodeBuilder extends AbstractParentProcessingNodeBuilder implements ThreadSafe {
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        ContainerNode node = new ContainerNode(null);
+        setupNode(node, config);
+
+        return node;
+    }
+
+    protected void setupNode(ContainerNode node, Configuration config)throws Exception {
+
+        this.treeBuilder.setupNode(node, config);
+
+        ProcessingNode[] children = buildChildNodes(config);
+        if (children.length == 0) {
+            String msg = "There must be at least one child at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        node.setChildren(children);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
new file mode 100644
index 0000000..bfb2321
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/DefaultTreeBuilder.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.AbstractConfiguration;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.core.container.StandaloneServiceSelector;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.sitemap.ComponentLocator;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.cocoon.util.location.LocationUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ *
+ * @version $Id$
+ */
+public class DefaultTreeBuilder
+        extends AbstractLogEnabled
+        implements TreeBuilder, Contextualizable, Serviceable,
+                   Recyclable, Disposable {
+
+    protected Map attributes = new HashMap();
+
+    //----- lifecycle-related objects ------
+
+    /**
+     * This component's avalon context
+     */
+    private Context context;
+
+    /**
+     * This component's service manager
+     */
+    private ServiceManager manager;
+
+    // -------------------------------------
+
+    /**
+     * The tree processor that we are building.
+     */
+    protected ConcreteTreeProcessor processor;
+
+    /**
+     * The namespace of configuration for the processor that we are building.
+     */
+    protected String itsNamespace;
+
+    /**
+     * The context for the processor that we are building
+     * It is created by {@link #createContext(Configuration)}.
+     */
+    private Context itsContext;
+
+    /**
+     * The service manager for the processor that we are building.
+     * It is created by {@link #createServiceManager(ClassLoader, Context, Configuration)}.
+     */
+    private ServiceManager itsManager;
+    
+    /**
+     * The classloader for the processor that we are building.
+     * It is created by {@link #createServiceManager(ClassLoader, Context, Configuration)}.
+     */
+    protected ClassLoader itsClassLoader;
+
+    /**
+     * Helper object which sets up components in the context
+     * of the processor that we are building.
+     */
+    private LifecycleHelper itsLifecycle;
+
+    /**
+     * Selector for ProcessingNodeBuilders which is set up
+     * in the context of the processor that we are building.
+     */
+    private ServiceSelector itsBuilders;
+
+    /**
+     * The sitemap component information grabbed while building itsMaanger
+     */
+    protected ProcessorComponentInfo itsComponentInfo;
+
+    /** Optional application container */
+    protected ComponentLocator applicationContainer;
+
+    /** Optional event listeners for the enter sitemap event */
+    protected List enterSitemapEventListeners = new ArrayList();
+
+    /** Optional event listeners for the leave sitemap event */
+    protected List leaveSitemapEventListeners = new ArrayList();
+
+    // -------------------------------------
+
+    /**
+     * Component processor of the parent manager
+     * (can be null for the root sitemap)
+     */
+    protected ServiceManager parentProcessorManager;
+
+
+    /** Nodes gone through setupNode() that implement Initializable */
+    private List initializableNodes = new ArrayList();
+
+    /** Nodes gone through setupNode() that implement Disposable */
+    private List disposableNodes = new ArrayList();
+
+    /** NodeBuilders created by createNodeBuilder() that implement LinkedProcessingNodeBuilder */
+    private List linkedBuilders = new ArrayList();
+
+    /** Are we in a state that allows to get registered nodes ? */
+    private boolean canGetNode = false;
+
+    /** Nodes registered using registerNode() */
+    private Map registeredNodes = new HashMap();
+
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Get the location of the treebuilder config file. Can be overridden for other versions.
+     * @return The location of the treebuilder config file
+     */
+    protected String getBuilderConfigURL() {
+        return "resource://org/apache/cocoon/components/treeprocessor/sitemap-language.xml";
+    }
+
+    public void setParentProcessorManager(ServiceManager manager) {
+        this.parentProcessorManager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.attributes.put(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    /**
+     * Create a context that will be used for all <code>Contextualizable</code>
+     * <code>ProcessingNodeBuilder</code>s and <code>ProcessingNode</code>s.
+     *
+     * <p>The default here is to simply return the context set in
+     * <code>contextualize()</code>, i.e. the context set by the calling
+     * <code>TreeProcessor</code>.
+     *
+     * <p>Subclasses can redefine this method to create a context local to
+     * a tree, such as for sitemap's &lt;map:components&gt;.
+     *
+     * @return a context
+     */
+    protected Context createContext(Configuration tree)
+    throws Exception {
+        return this.context;
+    }
+
+    protected ClassLoader createClassLoader(Configuration tree) throws Exception {
+        // Useless method as it's redefined in SitemapLanguage
+        // which is the only used incarnation.
+        return Thread.currentThread().getContextClassLoader();        
+    }
+    
+    /**
+     * Create a service manager that will be used for all <code>Serviceable</code>
+     * <code>ProcessingNodeBuilder</code>s and <code>ProcessingNode</code>s.
+     *
+     * <p>The default here is to simply return the manager set in
+     * <code>compose()</code>, i.e. the component manager set by the calling
+     * <code>TreeProcessor</code>.
+     *
+     * <p>Subclasses can redefine this method to create a service manager local to
+     * a tree, such as for sitemap's &lt;map:components&gt;.
+     *
+     * @return a component manager
+     */
+    protected ServiceManager createServiceManager(ClassLoader classloader, Context context, Configuration tree)
+    throws Exception {
+        return this.manager;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#setProcessor(ConcreteTreeProcessor)
+     */
+    public void setProcessor(ConcreteTreeProcessor processor) {
+        this.processor = processor;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getProcessor()
+     */
+    public ConcreteTreeProcessor getProcessor() {
+        return this.processor;
+    }
+    
+    public ServiceManager getBuiltProcessorManager() {
+        return this.itsManager;
+    }
+
+    public ClassLoader getBuiltProcessorClassLoader() {
+        return this.itsClassLoader;
+    }
+
+    /**
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getComponentLocator()
+     */
+    public ComponentLocator getComponentLocator() {
+        // Useless method as it's redefined in SitemapLanguage
+        return this.applicationContainer;
+    }
+
+    /**
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getEnterSitemapEventListeners()
+     */
+    public List getEnterSitemapEventListeners() {
+        // we make a copy here, so we can clear(recylce) the list after the
+        // sitemap is build
+        return (List)((ArrayList)this.enterSitemapEventListeners).clone();
+    }
+
+    /**
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#getLeaveSitemapEventListeners()
+     */
+    public List getLeaveSitemapEventListeners() {
+        // we make a copy here, so we can clear(recylce) the list after the
+        // sitemap is build
+        return (List)((ArrayList)this.leaveSitemapEventListeners).clone();
+    }
+
+    /**
+     * @see org.apache.cocoon.components.treeprocessor.TreeBuilder#registerNode(java.lang.String, org.apache.cocoon.components.treeprocessor.ProcessingNode)
+     */
+    public boolean registerNode(String name, ProcessingNode node) {
+        if ( this.registeredNodes.containsKey(name) ) {
+            return false;
+        }
+        this.registeredNodes.put(name, node);
+        return true;
+    }
+
+    public ProcessingNode getRegisteredNode(String name) {
+        if (this.canGetNode) {
+            return (ProcessingNode)this.registeredNodes.get(name);
+        }
+        throw new IllegalArgumentException("Categories are only available during buildNode()");
+    }
+
+    public ProcessingNodeBuilder createNodeBuilder(Configuration config) throws Exception {
+        // FIXME : check namespace
+        String nodeName = config.getName();
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Creating node builder for " + nodeName);
+        }
+
+        ProcessingNodeBuilder builder;
+        try {
+            builder = (ProcessingNodeBuilder) this.itsBuilders.select(nodeName);
+        } catch (ServiceException ce) {
+            // Is it because this element is unknown ?
+            if (this.itsBuilders.isSelectable(nodeName)) {
+                // No : rethrow
+                throw ce;
+            }
+            // Throw a more meaningful exception
+            String msg = "Unknown element '" + nodeName + "' at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        builder.setBuilder(this);
+
+        if (builder instanceof LinkedProcessingNodeBuilder) {
+            this.linkedBuilders.add(builder);
+        }
+
+        return builder;
+    }
+
+    /**
+     * Create the tree once component manager and node builders have been set up.
+     * Can be overriden by subclasses to perform pre/post tree creation operations.
+     */
+    protected ProcessingNode createTree(Configuration tree) throws Exception {
+        // Create a node builder from the top-level element
+        ProcessingNodeBuilder rootBuilder = createNodeBuilder(tree);
+
+        // Build the whole tree (with an empty buildModel)
+        return rootBuilder.buildNode(tree);
+    }
+
+    /**
+     * Resolve links : call <code>linkNode()</code> on all
+     * <code>LinkedProcessingNodeBuilder</code>s.
+     * Can be overriden by subclasses to perform pre/post resolution operations.
+     */
+    protected void linkNodes() throws Exception {
+        // Resolve links
+        Iterator iter = this.linkedBuilders.iterator();
+        while(iter.hasNext()) {
+            ((LinkedProcessingNodeBuilder)iter.next()).linkNode();
+        }
+    }
+
+    /**
+     * Get the namespace URI that builders should use to find their nodes.
+     */
+    public String getNamespace() {
+        return this.itsNamespace;
+    }
+
+    /**
+     * Build a processing tree from a <code>Configuration</code>.
+     */
+    public ProcessingNode build(Configuration tree) throws Exception {
+        // The namespace used in the whole sitemap is the one of the root element
+        this.itsNamespace = tree.getNamespace();
+
+        Configuration componentConfig = tree.getChild("components", false);
+
+        if (componentConfig == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Sitemap has no components definition at " + tree.getLocation());
+            }
+            componentConfig = new DefaultConfiguration("", "");
+        }
+
+        // Context and manager and classloader for the sitemap we build
+        this.itsContext = createContext(tree);
+//        this.itsClassLoader = createClassLoader(componentConfig);
+//        
+//        Thread currentThread = Thread.currentThread();
+        //ClassLoader oldClassLoader = currentThread.getContextClassLoader();
+//        currentThread.setContextClassLoader(this.itsClassLoader);
+        this.itsClassLoader = Thread.currentThread().getContextClassLoader();
+
+        this.itsManager = createServiceManager(this.itsClassLoader, this.itsContext, componentConfig);
+        this.itsComponentInfo = (ProcessorComponentInfo)this.itsManager.lookup(ProcessorComponentInfo.ROLE);
+
+        // Create a helper object to setup components
+        this.itsLifecycle = new LifecycleHelper(getLogger(),
+                                             this.itsContext,
+                                             this.itsManager,
+                                             null /* configuration */);
+
+        // Create & initialize the NodeBuilder selector.
+        {
+            StandaloneServiceSelector selector = new StandaloneServiceSelector() {
+                protected String getComponentInstanceName() {
+                    return "node";
+                }
+
+                protected String getClassAttributeName() {
+                    return "builder";
+                }
+            };
+            // Load the builder config file
+            SourceResolver resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+            String url = getBuilderConfigURL();
+            Configuration config;
+            try {
+                Source src = resolver.resolveURI(url);
+                try {
+                    SAXConfigurationHandler handler = new SAXConfigurationHandler();
+                    SourceUtil.toSAX(this.manager, src, null, handler);
+                    config = handler.getConfiguration();
+                } finally {
+                    resolver.release(src);
+                }
+            } catch (Exception e) {
+                throw new ConfigurationException("Could not load TreeBuilder configuration from " + url, e);
+            } finally {
+                this.manager.release(resolver);
+            }
+            LifecycleHelper.setupComponent(selector,
+                                           getLogger(),
+                                           this.itsContext,
+                                           this.itsManager,
+                                           config.getChild("nodes", false),
+                                           true);
+            this.itsBuilders = selector;
+        }
+
+        // Calls to getRegisteredNode() are forbidden
+        this.canGetNode = false;
+
+        // Collect all disposable variable resolvers
+        VariableResolverFactory.setDisposableCollector(this.disposableNodes);
+
+        ProcessingNode result = createTree(tree);
+
+        // Calls to getRegisteredNode() are now allowed
+        this.canGetNode = true;
+
+        linkNodes();
+
+        // Initialize all Initializable nodes
+        Iterator iter = this.initializableNodes.iterator();
+        while(iter.hasNext()) {
+            ((Initializable)iter.next()).initialize();
+        }
+
+        // And that's all !
+        return result;
+    }
+
+    /**
+     * Return the list of <code>ProcessingNodes</code> part of this tree that are
+     * <code>Disposable</code>. Care should be taken to properly dispose them before
+     * trashing the processing tree.
+     */
+    public List getDisposableNodes() {
+        return this.disposableNodes;
+    }
+
+    /**
+     * Setup a <code>ProcessingNode</code> by setting its location, calling all
+     * the lifecycle interfaces it implements and giving it the parameter map if
+     * it's a <code>ParameterizableNode</code>.
+     * <p>
+     * As a convenience, the node is returned by this method to allow constructs
+     * like <code>return treeBuilder.setupNode(new MyNode(), config)</code>.
+     */
+    public ProcessingNode setupNode(ProcessingNode node, Configuration config)
+      throws Exception {
+        Location location = getLocation(config);
+        if (node instanceof AbstractProcessingNode) {
+            ((AbstractProcessingNode)node).setLocation(location);
+            ((AbstractProcessingNode)node).setSitemapExecutor(this.processor.getSitemapExecutor());
+        }
+
+        this.itsLifecycle.setupComponent(node, false);
+
+        if (node instanceof ParameterizableProcessingNode) {
+            Map params = getParameters(config, location);
+            ((ParameterizableProcessingNode)node).setParameters(params);
+        }
+
+        if (node instanceof Initializable) {
+            this.initializableNodes.add(node);
+        }
+
+        if (node instanceof Disposable) {
+            this.disposableNodes.add(node);
+        }
+
+        return node;
+    }
+
+    protected LocationImpl getLocation(Configuration config) {
+        String prefix = "";
+
+        if (config instanceof AbstractConfiguration) {
+            //FIXME: AbstractConfiguration has a _protected_ getPrefix() method.
+            // So make some reasonable guess on the prefix until it becomes public
+            String namespace = null;
+            try {
+                namespace = ((AbstractConfiguration)config).getNamespace();
+            } catch (ConfigurationException e) {
+                // ignore
+            }
+            if ("http://apache.org/cocoon/sitemap/1.0".equals(namespace)) {
+                prefix="map";
+            }
+        }
+        
+        StringBuffer desc = new StringBuffer().append('<');
+        if (prefix.length() > 0) {
+            desc.append(prefix).append(':').append(config.getName());
+        } else {
+            desc.append(config.getName());
+        }
+        String type = config.getAttribute("type", null);
+        if (type != null) {
+            desc.append(" type=\"").append(type).append('"');
+        }
+        desc.append('>');
+        
+        Location rawLoc = LocationUtils.getLocation(config);
+        return new LocationImpl(desc.toString(), rawLoc.getURI(), rawLoc.getLineNumber(), rawLoc.getColumnNumber());
+    }
+
+    /**
+     * Get &lt;xxx:parameter&gt; elements as a <code>Map</code> of </code>ListOfMapResolver</code>s,
+     * that can be turned into parameters using <code>ListOfMapResolver.buildParameters()</code>.
+     *
+     * @return the Map of ListOfMapResolver, or <code>null</code> if there are no parameters.
+     */
+    protected Map getParameters(Configuration config, Location location) throws ConfigurationException {
+
+        Configuration[] children = config.getChildren("parameter");
+
+        if (children.length == 0) {
+            // Parameters are only the component's location
+            // TODO Optimize this
+            return new SitemapParameters.LocatedHashMap(location, 0);
+        }
+
+        Map params = new SitemapParameters.LocatedHashMap(location, children.length+1);
+        for (int i = 0; i < children.length; i++) {
+            Configuration child = children[i];
+            if (true) { // FIXME : check namespace
+                String name = child.getAttribute("name");
+                String value = child.getAttribute("value");
+                try {
+                    params.put(resolve(name), resolve(value));
+                } catch(PatternException pe) {
+                    String msg = "Invalid pattern '" + value + "' at " + child.getLocation();
+                    throw new ConfigurationException(msg, pe);
+                }
+            }
+        }
+
+        return params;
+    }
+
+    /**
+     * Get the type for a statement : it returns the 'type' attribute if present,
+     * and otherwhise the default type defined for this role in the components declarations.
+     *
+     * @throws ConfigurationException if the type could not be found.
+     */
+    public String getTypeForStatement(Configuration statement, String role) throws ConfigurationException {
+
+        // Get the component type for the statement
+        String type = statement.getAttribute("type", null);
+        if (type == null) {
+            type = this.itsComponentInfo.getDefaultType(role);
+        }
+
+        if (type == null) {
+            throw new ConfigurationException("No default type exists for 'map:" + statement.getName() +
+                "' at " + statement.getLocation()
+            );
+        }
+
+        // Check that this type actually exists
+        ServiceSelector selector = null;
+        try {
+            selector = (ServiceSelector) this.itsManager.lookup(role + "Selector");
+        } catch (ServiceException e) {
+            throw new ConfigurationException("Cannot get service selector for 'map:" +
+                                             statement.getName() + "' at " + statement.getLocation(),
+                                             e);
+        }
+
+        if (!selector.isSelectable(type)) {
+            throw new ConfigurationException("Type '" + type + "' does not exist for 'map:" +
+                                             statement.getName() + "' at " + statement.getLocation());
+        }
+
+        this.itsManager.release(selector);
+
+        return type;
+    }
+
+    /**
+     * Resolve expression using its manager
+     */
+    protected VariableResolver resolve (String expression)
+    throws PatternException {
+        return VariableResolverFactory.getResolver(expression, this.itsManager);
+    }
+
+    public void recycle() {
+        // Reset all data created during the build
+        this.attributes.clear();
+        this.canGetNode = false;
+        this.disposableNodes = new ArrayList(); // Must not be cleared as it's used for processor disposal
+        this.initializableNodes.clear();
+        this.linkedBuilders.clear();
+        this.parentProcessorManager = null; // Set in setParentProcessorManager()
+        this.processor = null;          // Set in setProcessor()
+
+        this.itsNamespace = null;       // Set in build()
+        LifecycleHelper.dispose(this.itsBuilders);
+        this.itsBuilders = null;        // Set in build()
+        this.itsLifecycle = null;       // Set in build()
+        this.itsManager = null;         // Set in build()
+        this.itsContext = null;         // Set in build()
+
+        this.registeredNodes.clear();
+        this.initializableNodes.clear();
+        this.linkedBuilders.clear();
+        this.canGetNode = false;
+        this.registeredNodes.clear();
+
+        VariableResolverFactory.setDisposableCollector(null);
+        this.applicationContainer = null;
+        this.enterSitemapEventListeners.clear();
+        this.leaveSitemapEventListeners.clear();
+    }
+
+    public void dispose() {
+        // Don't dispose manager or roles: they are used by the built tree
+        // and thus must live longer than the builder.
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java
new file mode 100644
index 0000000..14530b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/InvokeContext.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.sitemap.SitemapErrorHandler;
+
+/**
+ * The invocation context of <code>ProcessingNode</code>s.
+ *
+ * <p>This class serves two purposes:
+ * <ul>
+ *   <li>Avoid explicit enumeration of all needed parameters in
+ *       {@link ProcessingNode#invoke(org.apache.cocoon.environment.Environment, InvokeContext)},
+ *       thus allowing easier addition of new parameters,</li>
+ *   <li>Hold pipelines, and provide "just in time" lookup for them.</li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class InvokeContext extends AbstractLogEnabled
+                           implements Serviceable, Disposable {
+
+    private List mapStack = new ArrayList();
+    private HashMap nameToMap = new HashMap();
+    private HashMap mapToName = new HashMap();
+
+    /** True if building pipeline only, not processing it. */
+    private boolean isBuildingPipelineOnly;
+
+    /** The redirector */
+    protected Redirector redirector;
+
+
+    /** The current component manager, as set by the last call to compose() or recompose() */
+    private ServiceManager currentManager;
+
+    /** The component manager that was used to get the pipelines */
+    private ServiceManager pipelinesManager;
+
+    /** The name of the processing pipeline component */
+    protected String processingPipelineName;
+
+    /** The parameters for the processing pipeline */
+    protected Parameters processingPipelineParameters;
+
+    /** The object model used to resolve processingPipelineParameters */
+    protected Map processingPipelineObjectModel;
+
+    /** The Selector for the processing pipeline */
+    protected ServiceSelector pipelineSelector;
+
+    /** The ProcessingPipeline used */
+    protected ProcessingPipeline processingPipeline;
+
+    /** The internal pipeline description */
+    protected Processor.InternalPipelineDescription internalPipelineDescription;
+
+    /** The error handler for the pipeline. */
+    protected SitemapErrorHandler errorHandler;
+
+    /** The last processor */
+    protected Processor lastProcessor;
+
+    /**
+     * Create an <code>InvokeContext</code> without existing pipelines. This also means
+     * the current request is external.
+     */
+    public InvokeContext() {
+        this.isBuildingPipelineOnly = false;
+    }
+
+    /**
+     * Determines if the Pipeline been set for this context
+     */
+    public boolean pipelineIsSet() {
+	    return (this.processingPipeline != null);
+    }
+
+    /**
+     * Create an <code>InvokeContext</code>
+     */
+    public InvokeContext(boolean isBuildingPipelineOnly) {
+        this.isBuildingPipelineOnly = isBuildingPipelineOnly;
+    }
+
+    /**
+     * Serviceable interface
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.currentManager = manager;
+        if (this.processingPipeline != null) {
+            this.processingPipeline.setProcessorManager(manager);
+        }
+    }
+
+    /**
+     * Informs the context about a new pipeline section
+     */
+    public void inform(String     pipelineName,
+                       Parameters parameters,
+                       Map        objectModel) {
+        this.processingPipelineName = pipelineName;
+        this.processingPipelineParameters = parameters;
+        this.processingPipelineObjectModel = objectModel;
+    }
+    
+    public Parameters getPipelineParameters() {
+        return this.processingPipelineParameters;
+    }
+    
+    public String getPipelineType() {
+        return this.processingPipelineName;
+    }
+
+    /**
+     * Get the current <code>ProcessingPipeline</code>
+     */
+    public ProcessingPipeline getProcessingPipeline()
+    throws Exception {
+        if (this.processingPipeline == null) {
+            // Keep current manager for proper release
+            this.pipelinesManager = this.currentManager;
+
+            this.pipelineSelector = (ServiceSelector)this.pipelinesManager.lookup(ProcessingPipeline.ROLE+"Selector");
+            this.processingPipeline = (ProcessingPipeline)this.pipelineSelector.select(this.processingPipelineName);
+            this.processingPipeline.setProcessorManager(this.currentManager);
+
+            this.processingPipeline.setup(this.processingPipelineParameters);
+            this.processingPipeline.setErrorHandler(this.errorHandler);
+        }
+        return this.processingPipeline;
+    }
+
+    /**
+     * Set the processing pipeline for sub-sitemaps
+     */
+    public void setInternalPipelineDescription(Processor.InternalPipelineDescription desc) {
+        this.processingPipeline = desc.processingPipeline;
+        this.pipelinesManager = desc.pipelineManager;
+        this.lastProcessor = desc.lastProcessor;
+        this.pipelineSelector = desc.pipelineSelector;
+        this.internalPipelineDescription = new Processor.InternalPipelineDescription(
+                this.processingPipeline, this.pipelineSelector, this.pipelinesManager);
+        this.internalPipelineDescription.lastProcessor = this.lastProcessor;
+        this.internalPipelineDescription.prefix = desc.prefix;
+        this.internalPipelineDescription.uri = desc.uri;
+    }
+
+    /**
+     * Get the pipeline description
+     */
+    public Processor.InternalPipelineDescription getInternalPipelineDescription(Environment env) {
+        if ( this.internalPipelineDescription == null ) {
+            this.internalPipelineDescription = new Processor.InternalPipelineDescription(
+                    this.processingPipeline, this.pipelineSelector, this.pipelinesManager);
+            this.internalPipelineDescription.lastProcessor = this.lastProcessor;
+            this.internalPipelineDescription.prefix = env.getURIPrefix();
+            this.internalPipelineDescription.uri = env.getURI();
+        }
+        return this.internalPipelineDescription;
+    }
+
+    /**
+     * Set the last processor
+     */
+    public void setLastProcessor(Processor p) {
+        this.lastProcessor = p;
+    }
+
+    /**
+     * Are we building a pipeline (and not executing it) ?
+     */
+    public final boolean isBuildingPipelineOnly() {
+        return this.isBuildingPipelineOnly;
+    }
+
+    /**
+     * Get the current Map stack used to resolve expressions.
+     */
+    public final List getMapStack() {
+        return this.mapStack;
+    }
+
+    /**
+     * Get the result Map by anchor name
+     */
+    public final Map getMapByAnchor(String anchor) {
+        return (Map) this.nameToMap.get(anchor);
+    }
+
+    /**
+     * Push a Map on top of the current Map stack.
+     */
+    public final void pushMap(String anchorName, Map map) {
+        this.mapStack.add(map);
+
+        if (getLogger().isDebugEnabled()) {
+            dumpParameters();
+        }
+
+        if (anchorName != null) {
+            if (!this.nameToMap.containsKey(anchorName)) {
+                this.nameToMap.put(anchorName,map);
+                this.mapToName.put(map,anchorName);
+            } else {
+                if (getLogger().isErrorEnabled()) {
+                    getLogger().error("name [" + anchorName + "] clashes");
+                }
+            }
+        }
+    }
+
+    /**
+     * Dumps all sitemap parameters to log
+     */
+    protected void dumpParameters() {
+        if (!this.mapStack.isEmpty()) {
+            StringBuffer sb = new StringBuffer();
+
+            sb.append("\nCurrent Sitemap Parameters:\n");
+            String path = "";
+
+            for (int i = this.mapStack.size() - 1; i >= 0; i--) {
+                Map map = (Map) this.mapStack.get(i);
+                sb.append("LEVEL ").append(i+1);
+                if (this.mapToName.containsKey(map)) {
+                    sb.append(" is named '").append(String.valueOf(this.mapToName.get(map))).append("'");
+                }
+                sb.append("\n");
+
+                for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
+                    final Map.Entry me = (Map.Entry)iter.next();
+                    final Object key = me.getKey();
+                    sb.append("PARAM: '").append(path).append(key).append("' ");
+                    sb.append("VALUE: '").append(map.get(key)).append("'\n");
+                }
+
+                path = "../" + path;
+            }
+
+            getLogger().debug(sb.toString());
+        }
+    }
+
+    /**
+     * Pop the topmost element of the current Map stack.
+     */
+    public final void popMap() {
+        Object map = this.mapStack.remove(this.mapStack.size() - 1);
+        Object name = this.mapToName.get(map);
+        this.mapToName.remove(map);
+        this.nameToMap.remove(name);
+    }
+
+    /**
+     * Set the redirector to be used by nodes that need it.
+     *
+     * @param redirector the redirector
+     */
+    public void setRedirector(Redirector redirector) {
+        this.redirector = redirector;
+    }
+
+    /**
+     * Get the redirector to be used by nodes that need it.
+     *
+     * @return the redirector
+     */
+    public Redirector getRedirector() {
+        return this.redirector;
+    }
+
+    /**
+     * Release the pipelines, if any, if they were looked up by this context.
+     */
+    public void dispose() {
+        if (this.internalPipelineDescription == null && this.pipelinesManager != null) {
+            if (this.pipelineSelector != null) {
+                this.pipelineSelector.release(this.processingPipeline);
+                this.processingPipeline = null;
+                this.pipelinesManager.release(this.pipelineSelector);
+                this.pipelineSelector = null;
+            }
+            this.pipelinesManager = null;
+
+            this.processingPipelineName = null;
+            this.processingPipelineParameters = null;
+            this.processingPipelineObjectModel = null;
+        }
+    }
+
+    /**
+     * Set the error handler for the pipeline.
+     */
+    public void setErrorHandler(SitemapErrorHandler handler) {
+        this.errorHandler = handler;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/LinkedProcessingNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/LinkedProcessingNodeBuilder.java
new file mode 100644
index 0000000..8344665
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/LinkedProcessingNodeBuilder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+/**
+ * A <code>ProcessingNode</code> builder that links its node to
+ * other nodes in the hierarchy. This allows to turn the node tree
+ * into a directed graph.
+ *
+ * @version $Id$
+ */
+public interface LinkedProcessingNodeBuilder extends ProcessingNodeBuilder {
+
+    /**
+     * Resolve the links needed by the node built by this builder.
+     */
+    void linkNode() throws Exception;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNode.java
new file mode 100644
index 0000000..8587e1d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNode.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+/**
+ * A named container node that just invokes its children.
+ *
+ * @version $Id$
+ */
+public class NamedContainerNode extends ContainerNode implements NamedProcessingNode {
+
+    private String name;
+
+    public NamedContainerNode(String name) {
+        super(name);
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNodeBuilder.java
new file mode 100644
index 0000000..98b6967
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedContainerNodeBuilder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+/**
+ * Builds a generic named container node.
+ *
+ * @version $Id$
+ */
+public class NamedContainerNodeBuilder extends ContainerNodeBuilder implements Configurable {
+
+    protected String nameAttr;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        super.configure(config);
+        this.nameAttr = config.getChild("name-attribute").getValue("name");
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        NamedContainerNode node = new NamedContainerNode(config.getAttribute(this.nameAttr));
+        this.setupNode(node, config);
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedProcessingNode.java
new file mode 100644
index 0000000..820eb93
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NamedProcessingNode.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+/**
+ * A <code>ProcessingNode</code> that has a name. This is primarily used by
+ * <code>CategoryNode</code> to access its children.
+ *
+ * @version $Id$
+ */
+public interface NamedProcessingNode extends ProcessingNode {
+
+    String getName();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNode.java
new file mode 100644
index 0000000..6b9243e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNode.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * A no-op node to stub not yet implemented features.
+ *
+ * @version $Id$
+ */
+public class NullNode extends AbstractProcessingNode {
+
+    public NullNode() {
+        super(null);
+    }
+    
+    public final boolean invoke(Environment env, InvokeContext context) throws Exception {
+
+        getLogger().warn("Invoke on NullNode at " + getLocation());
+        return false;
+
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNodeBuilder.java
new file mode 100644
index 0000000..57d51dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/NullNodeBuilder.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ *
+ * @version $Id$
+ */
+public class NullNodeBuilder extends AbstractProcessingNodeBuilder {
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        return this.treeBuilder.setupNode(new NullNode(), config);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ParameterizableProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ParameterizableProcessingNode.java
new file mode 100644
index 0000000..7e13405
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ParameterizableProcessingNode.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.Map;
+
+/**
+ * A <code>ProcessingNode</code> that has parameters.
+ *
+ * @version $Id$
+ */
+public interface ParameterizableProcessingNode extends ProcessingNode {
+
+    /**
+     * Set the parameters of this node as a <code>Map</code> of <code>VariableResolver</code>s
+     * that will be resolved at process-time.
+     */
+    void setParameters(Map parameterMap);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/PipelineEventComponentProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/PipelineEventComponentProcessingNode.java
new file mode 100644
index 0000000..0bcc464
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/PipelineEventComponentProcessingNode.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public abstract class PipelineEventComponentProcessingNode extends AbstractProcessingNode {
+
+    protected Map views;
+    protected Map pipelineHints;
+
+    public PipelineEventComponentProcessingNode() {
+        super(null);
+    }
+
+    public void setViews(Map views) {
+        this.views = views;
+    }
+
+    // Set any pipeline-hint parameters
+    public void setPipelineHints(Map parameterMap) {
+        this.pipelineHints = parameterMap;
+    }
+
+    public boolean hasViews() {
+        return this.views != null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java
new file mode 100644
index 0000000..18ef0b4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface ProcessingNode extends ThreadSafe, Locatable {
+
+    /**
+     * Process environment.
+     */
+    boolean invoke(Environment env, InvokeContext context) throws Exception;
+
+    /**
+     * Get the location of this node.
+     */
+    Location getLocation();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNodeBuilder.java
new file mode 100644
index 0000000..2021d2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessingNodeBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+/**
+ * A <code>ProcessingNode</code> builder.
+ * <p>
+ * Lifecycle information : a <code>TreeBuilder</code> can be recycled
+ * and used to build several <code>Processor</code>s, each one defining
+ * a different <code>ServiceManager</code>.
+ * <p>
+ *
+ * @version $Id$
+ */
+public interface ProcessingNodeBuilder {
+
+    /**
+     * Set the builder for which we are building.
+     */
+    void setBuilder(TreeBuilder builder);
+
+    /**
+     * Build the {@link ProcessingNode} and its children from the given
+     * <code>Configuration</code>, and optionnaly register it in the tree builder
+     * for lookup by other <code>LinkedProcessingNodeBuilder</code>s.
+     */
+    ProcessingNode buildNode(Configuration config) throws Exception;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java
new file mode 100644
index 0000000..b23f015
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/ProcessorComponentInfo.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.core.container.DefaultServiceSelector;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.reading.Reader;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.transformation.Transformer;
+
+/**
+ * Holds informations defined in &lt;map:components&gt; such as default hint, labels and mime-types
+ * that are needed when building a processor and to manage inheritance when building child processors.
+ * <p>
+ * In previous versions of the sitemap engine, these informations where store in specialized
+ * extensions of ComponentSelector (<code>SitemapComponentSelector</code> and
+ * <code>OutputComponentSelector</code>), which led to a strong dependency on the chosen component
+ * container implementation. This is now a regular component that also "listens" to modifications
+ * of the service manager when it is built.
+ * 
+ * @version $Id$
+ */
+public class ProcessorComponentInfo {
+    
+    public static final String ROLE = ProcessorComponentInfo.class.getName();
+    
+    private static final String GENERATOR_PREFIX = Generator.ROLE + "/";
+    private static final String TRANSFORMER_PREFIX = Transformer.ROLE + "/";
+    private static final String SERIALIZER_PREFIX = Serializer.ROLE + "/";
+    private static final String READER_PREFIX = Reader.ROLE + "/";
+    private static final String PIPELINE_PREFIX = ProcessingPipeline.ROLE + "/";
+    
+    private static final Set DEFAULT_ROLES = new HashSet(Arrays.asList(new String[] {
+            Generator.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Transformer.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Serializer.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Reader.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            ProcessingPipeline.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Matcher.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Selector.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT,
+            Action.ROLE + "/" + DefaultServiceSelector.DEFAULT_HINT
+    }));
+    
+    /** Component info for the parent processor */
+    ProcessorComponentInfo parent;
+    
+    /** Lock that prevents further modification */
+    private boolean locked = false;
+    
+    /**
+     * Component-related data (see methods below for key names). We use a single Map
+     * to reduce memory usage, as each kind of data has a limited number of entries.
+     */
+    private Map data;
+    
+    public ProcessorComponentInfo(ProcessorComponentInfo parent) {
+        this.parent = parent;
+    }
+    
+    /**
+     * Grabs on the fly the sitemap-related information on generators, transformers,
+     * serializers and readers when they're declared in the <code>ServiceManager</code>.
+     * <p>
+     * This method is triggered when a component is added on a <code>CocoonServiceManager</code>.
+     * 
+     * @param role the component's role
+     * @param clazz the component's class
+     * @param config the component's configuration
+     */
+    public void componentAdded(String role, String clazz, Configuration config) {
+        if (role.startsWith(GENERATOR_PREFIX)) {
+            setupLabelAndPipelineHint(role, config);
+
+        } else if (role.startsWith(TRANSFORMER_PREFIX)) {
+            setupLabelAndPipelineHint(role, config);
+
+        } else if (role.startsWith(SERIALIZER_PREFIX)) {
+            setupLabelAndPipelineHint(role, config);
+            setupMimeType(role, config);
+
+        } else if (role.startsWith(READER_PREFIX)) {
+            setupMimeType(role, config);
+        }
+    }
+    
+    /**
+     * Prepares the configuration for pooled sitemap components:
+     * Per default pooled components are proxied - we override this
+     * for generators, transformers, serializers, readers and pipes
+     * @param role the component's role
+     * @param clazz the component's class
+     * @param config the component's configuration
+     */
+    public void prepareConfig(String role, String clazz, Configuration config) {
+        if (role.startsWith(GENERATOR_PREFIX)
+            || role.startsWith(TRANSFORMER_PREFIX)
+            || role.startsWith(SERIALIZER_PREFIX)
+            || role.startsWith(READER_PREFIX)
+            || role.startsWith(PIPELINE_PREFIX)) {
+            
+            ((DefaultConfiguration)config).setAttribute("model", ComponentInfo.TYPE_NON_THREAD_SAFE_POOLED);
+        }
+    }
+
+    public void roleAliased(String existingRole, String newRole) {
+        if (DEFAULT_ROLES.contains(newRole)) {
+            // A default role for a sitemap component has been added
+            int pos = existingRole.indexOf('/');
+            String role = existingRole.substring(0, pos);
+            String hint = existingRole.substring(pos+1);
+            
+            this.setDefaultType(role, hint);
+        }
+    }
+    
+    private void setupLabelAndPipelineHint(String role, Configuration config) {
+
+        // Labels
+        String label = config.getAttribute("label", null);
+        if (label != null) {
+            StringTokenizer st = new StringTokenizer(label, " ,", false);
+            String[] labels = new String[st.countTokens()];
+            for (int tokenIdx = 0; tokenIdx < labels.length; tokenIdx++) {
+                labels[tokenIdx] = st.nextToken();
+            }
+            setLabels(role, labels);
+        } else {
+            // Set no labels, overriding those defined in the parent sitemap, if any
+            setLabels(role, null);
+        }
+
+        // Pipeline hints
+        String pipelineHint = config.getAttribute("hint", null);
+        setPipelineHint(role, pipelineHint);
+    }
+
+    private void setupMimeType(String role, Configuration config) {
+        setMimeType(role, config.getAttribute("mime-type", null));
+    }
+
+    /** Store some data, creating the storage map if needed */
+    private void setData(String key, Object value) {
+        if (locked) throw new IllegalStateException("ProcessorComponentInfo is locked");
+        if (this.data == null) this.data = new HashMap();
+        this.data.put(key, value);
+    }
+    
+    /** Get some data, asking the parent if needed */
+    private Object getData(String key) {
+        // Need to check containsKey as the default hint may be unspecified (i.e. no "default" attribute)
+        if (this.data != null && this.data.containsKey(key)) {
+            return this.data.get(key);
+        } else if (this.parent != null) {
+            // Ask parent
+            return this.parent.getData(key);
+        } else {
+            return null;
+        }
+    }
+    
+    /**
+     * Lock this component info object at the end of processor building to prevent
+     * any further changes.
+     */
+    public void lock() {
+        this.locked = true;
+    }
+    
+    private void setDefaultType(String role, String hint) {
+        setData("defaultType/" + role, hint);
+    }
+    
+    public String getDefaultType(String role) {
+        return (String)getData("defaultType/" + role);
+    }
+    
+    private void setPipelineHint(String role, String hint) {
+        setData("pipelineHint/" + role, hint);
+    }
+    
+    public String getPipelineHint(String role, String type) {
+        return (String)getData("pipelineHint/" + role + "/" + type);
+    }
+    
+    private void setMimeType(String role, String mimeType) {
+        setData("mimeType/" + role, mimeType);
+    }
+    
+    public String getMimeType(String role, String type) {
+        return (String)getData("mimeType/" + role + "/" + type);
+    }
+    
+    private void setLabels(String role, String[] labels) {
+        setData("labels/" + role, labels);
+    }
+    
+    public String[] getLabels(String role, String type) {
+        return (String[])getData("labels/" + role + "/" + type);
+    }
+    
+    public boolean hasLabel(String role, String type, String label) {
+        String[] labels = this.getLabels(role, type);
+        if (labels != null) {
+            for (int i = 0; i < labels.length; i++) {
+                if (labels[i].equals(label))
+                    return true;
+            }
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleParentProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleParentProcessingNode.java
new file mode 100644
index 0000000..4a08a5b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleParentProcessingNode.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * @version $Id$
+ */
+public abstract class SimpleParentProcessingNode extends AbstractParentProcessingNode {
+
+    /** The childrens of this matcher */
+    protected ProcessingNode[] children;
+
+    public SimpleParentProcessingNode(String type) {
+        super(type);
+    }
+    
+    public void setChildren(ProcessingNode[] children) {
+        this.children = children;
+    }
+
+    /**
+     * Boolean method with returns true if this Node has children
+     * and false otherwise.
+     *
+     * @return boolean true if has children.
+     */
+    public boolean hasChildren() {
+        return this.children != null && this.children.length > 0;
+    }
+
+    /**
+     * Define common invoke behavior here
+     */
+    public boolean invoke(Environment env, InvokeContext context) throws Exception {
+        // Inform the pipeline (if available) that we have come across
+        // a possible branch point
+        if (context.pipelineIsSet() && hasChildren()) {
+            context.getProcessingPipeline().informBranchPoint();
+        }
+
+        // processing not yet complete, so return false
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleSelectorProcessingNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleSelectorProcessingNode.java
new file mode 100644
index 0000000..9c7e926
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/SimpleSelectorProcessingNode.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * Base class for processing nodes that are based on a component in a Selector (act, match, select, etc).
+ *
+ * @version $Id$
+ */
+public abstract class SimpleSelectorProcessingNode extends SimpleParentProcessingNode
+    implements Serviceable, Disposable {
+
+    private String selectorRole;
+    
+    /** ServiceManager */
+    private ServiceManager manager;
+    
+    /** Selector where to get components from */
+    private ServiceSelector selector;
+    
+    /** The underlying component, if it's threadsafe. Null otherwise */
+    private Object threadSafeComponent;
+
+    public SimpleSelectorProcessingNode(String selectorRole, String componentType) {
+        super(componentType);
+        this.selectorRole = selectorRole;
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.selector = (ServiceSelector)manager.lookup(selectorRole);
+        
+        // Pre-lookup the associated component, and cache it if it's threadsafe
+        Object component = this.selector.select(this.getType());
+        if (component instanceof ThreadSafe) {
+            this.threadSafeComponent = component;
+        } else {
+            this.selector.release(component);
+        }
+    }
+    
+    /**
+     * Get the component to be used by this node. That component may be cached for faster
+     * execution if it's ThreadSafe. In any case, a call to {@link #releaseComponent(Object)} must
+     * be done to release the component if needed.
+     * 
+     * @return the component to use
+     * @throws ServiceException if component lookup fails
+     */
+    protected Object getComponent() throws ServiceException {
+        if (this.threadSafeComponent != null) {
+            return this.threadSafeComponent;
+        }
+        return this.selector.select(this.componentName);
+    }
+    
+    /**
+     * Release the component used by this node (does nothing if it's the cached
+     * ThreadSafe component)
+     * 
+     * @param obj the component
+     */
+    protected void releaseComponent(Object obj) {
+        if (obj != this.threadSafeComponent) {
+            this.selector.release(obj);
+        }
+    }
+    
+    public void dispose() {
+        this.selector.release(this.threadSafeComponent);
+        this.manager.release(this.selector);
+        this.selector = null;
+        this.manager = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java
new file mode 100644
index 0000000..30c8994
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeBuilder.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.sitemap.ComponentLocator;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface TreeBuilder {
+
+    String ROLE = TreeBuilder.class.getName();
+
+    public static class EventComponent {
+        
+        public final Object component;
+        public final boolean releaseUsingManager;
+        
+        public EventComponent(Object c, boolean releaseUsingManager) {
+            this.component = c;
+            this.releaseUsingManager = releaseUsingManager;
+        }
+    }
+
+    void setParentProcessorManager(ServiceManager manager);
+    
+    ServiceManager getBuiltProcessorManager();
+    
+    ClassLoader getBuiltProcessorClassLoader();
+
+    ConcreteTreeProcessor getProcessor();
+
+    void setProcessor(ConcreteTreeProcessor processor);
+
+    /**
+     * Register a <code>ProcessingNode</code> under a given name.
+     * For example, <code>ResourceNodeBuilder</code> stores here the <code>ProcessingNode</code>s
+     * it produces for use by sitemap pipelines. This allows to turn the tree into a graph.
+     * If a node with the name is already registed, the process fails!
+     * @return If the node could be registered, <code>true</code> is returned; otherwise false.
+     */
+    boolean registerNode(String name, ProcessingNode node);
+
+    /**
+     * @throws IllegalStateException
+     */
+    ProcessingNode getRegisteredNode(String name);
+
+    ProcessingNodeBuilder createNodeBuilder(Configuration config) throws Exception;
+
+    /**
+     * Get the namespace URI that builders should use to find their nodes.
+     */
+    String getNamespace();
+
+    /**
+     * Build a processing tree from a <code>Configuration</code> object holding the sitemap program.
+     */
+    ProcessingNode build(Configuration config) throws Exception;
+
+    /**
+     * Return the list of <code>ProcessingNodes</code> part of this tree that are
+     * <code>Disposable</code>. Care should be taken to properly dispose them before
+     * trashing the processing tree.
+     */
+    List getDisposableNodes();
+
+    /**
+     * Setup a <code>ProcessingNode</code> by setting its location, calling all
+     * the lifecycle interfaces it implements and giving it the parameter map if
+     * it's a <code>ParameterizableNode</code>.
+     * <p>
+     * As a convenience, the node is returned by this method to allow constructs
+     * like <code>return treeBuilder.setupNode(new MyNode(), config)</code>.
+     */
+    ProcessingNode setupNode(ProcessingNode node, Configuration config) throws Exception;
+
+
+    /**
+     * Get the type for a statement : it returns the 'type' attribute if present,
+     * and otherwhise the default hint for the <code>ServiceSelector</code> identified by
+     * the role <code>role</code>.
+     *
+     * @param statement the statement
+     * @param role the component's role (warn: not the selector's role)
+     *
+     * @throws ConfigurationException if the default type could not be found.
+     */
+    String getTypeForStatement(Configuration statement, String role) throws ConfigurationException;
+
+    /**
+     * Add an attribute. Useful to transmit information between distant (in the tree) node builders
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     * Get the value of an attribute.
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Return the sitemap component locator - if available.
+     */
+    ComponentLocator getComponentLocator();
+
+    /**
+     * Return all event listers that are registered for the
+     * {@link org.apache.cocoon.sitemap.EnterSitemapEvent}.
+     * @return A list of {@link EventComponent}s.
+     */
+    List getEnterSitemapEventListeners();
+    
+    /**
+     * Return all event listers that are registered for the
+     * {@link org.apache.cocoon.sitemap.LeaveSitemapEvent}.
+     * @return A list of {@link EventComponent}s.
+     */
+    List getLeaveSitemapEventListeners();
+    
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
new file mode 100644
index 0000000..c6bcf2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/TreeProcessor.java
@@ -0,0 +1,816 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.NamespacedSAXConfigurationHandler;
+import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.classloader.ClassLoaderFactory;
+import org.apache.cocoon.components.classloader.ReloadingClassLoaderFactory;
+import org.apache.cocoon.components.fam.SitemapMonitor;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper;
+import org.apache.cocoon.components.treeprocessor.sitemap.FlowNode;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.sitemap.impl.DefaultExecutor;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.compilers.eclipse.EclipseJavaCompiler;
+import org.apache.commons.jci.listeners.CompilingListener;
+import org.apache.commons.jci.listeners.FileChangeListener;
+import org.apache.commons.jci.listeners.NotifyingListener;
+import org.apache.commons.jci.listeners.ReloadingListener;
+import org.apache.commons.jci.listeners.ResourceStoringListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.TransactionalResourceStore;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.regexp.RE;
+import org.xml.sax.SAXException;
+
+/**
+ * Interpreted tree-traversal implementation of a pipeline assembly language.
+ *
+ * @version $Id$
+ */
+public class TreeProcessor extends AbstractLogEnabled
+                           implements ThreadSafe, Processor, Serviceable,
+                                      Configurable, Contextualizable,
+                                      Disposable, Initializable {
+
+    private static final String XCONF_URL =
+        "resource://org/apache/cocoon/components/treeprocessor/sitemap-language.xml";
+
+    /** The parent TreeProcessor, if any */
+    protected TreeProcessor parent;
+
+    /** The context */
+    protected Context context;
+
+    /**
+     * The component manager given by the upper level
+     * (root manager or parent concrete processor)
+     */
+    protected ServiceManager manager;
+
+    /** The core object. */
+    protected Core core;
+
+    /** Last modification time */
+    protected long lastModified = 0;
+
+    /** The source of the tree definition */
+    protected DelayedRefreshSourceWrapper source;
+
+    /** Delay for <code>sourceLastModified</code>. */
+    protected long lastModifiedDelay;
+
+    /** Check for reload? */
+    protected boolean checkReload;
+    
+    protected SitemapMonitor fam;
+    
+    /** The source resolver */
+    protected SourceResolver resolver;
+
+    /** The environment helper */
+    private EnvironmentHelper environmentHelper;
+
+    /** The actual sitemap executor */
+    private SitemapExecutor sitemapExecutor;
+
+    /** Indicates whether this is our component or not */
+    private boolean releaseSitemapExecutor;
+
+    /** The actual processor */
+    protected ConcreteTreeProcessor concreteProcessor;
+
+    /** The tree builder configuration */
+    private Configuration treeBuilderConfiguration;
+
+    /**
+     * Create a TreeProcessor.
+     */
+    public TreeProcessor() {
+        this.checkReload = true;
+        this.lastModifiedDelay = 1000;
+    }
+
+    /**
+     * Create a child processor for a given language
+     */
+    protected TreeProcessor(TreeProcessor parent,
+                            DelayedRefreshSourceWrapper sitemapSource,
+                            boolean checkReload,
+                            String prefix)
+    throws Exception {
+        this.parent = parent;
+        enableLogging(parent.getLogger());
+
+        // Copy all that can be copied from the parent
+        this.context = parent.context;
+        this.source = sitemapSource;
+        this.treeBuilderConfiguration = parent.treeBuilderConfiguration;
+        this.checkReload = checkReload;
+        this.lastModifiedDelay = parent.lastModifiedDelay;
+
+        this.manager = parent.concreteProcessor.getServiceManager();
+
+        this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+        this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
+        this.core = (Core) this.manager.lookup(Core.ROLE);
+        this.environmentHelper = new EnvironmentHelper(parent.environmentHelper);
+        // Setup environment helper
+        ContainerUtil.enableLogging(this.environmentHelper, this.getLogger());
+        ContainerUtil.service(this.environmentHelper, this.manager);
+        this.environmentHelper.changeContext(sitemapSource, prefix);
+        this.sitemapExecutor = parent.sitemapExecutor;
+    }
+
+    /**
+     * Create a new child of this processor (used for mounting submaps).
+     *
+     * @return a new child processor.
+     */
+    public TreeProcessor createChildProcessor(String src,
+                                              boolean checkReload,
+                                              String  prefix)
+    throws Exception {
+        DelayedRefreshSourceWrapper delayedSource = new DelayedRefreshSourceWrapper(
+                this.resolver.resolveURI(src), this.lastModifiedDelay);
+        return new TreeProcessor(this, delayedSource, checkReload, prefix);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+        this.fam = (SitemapMonitor) this.manager.lookup(SitemapMonitor.ROLE);
+        this.core = (Core) this.manager.lookup(Core.ROLE);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        // setup the environment helper
+        if (this.environmentHelper == null) {
+            this.environmentHelper = new EnvironmentHelper(
+                    (URL) this.context.get(ContextHelper.CONTEXT_ROOT_URL));
+        }
+        ContainerUtil.enableLogging(this.environmentHelper, getLogger());
+        ContainerUtil.service(this.environmentHelper, this.manager);
+
+        // Create sitemap executor
+        if (this.parent == null) {
+            if (this.manager.hasService(SitemapExecutor.ROLE)) {
+                this.sitemapExecutor = (SitemapExecutor) this.manager.lookup(SitemapExecutor.ROLE);
+                this.releaseSitemapExecutor = true;
+            } else {
+                this.sitemapExecutor = new DefaultExecutor();
+            }
+        } else {
+            this.sitemapExecutor = this.parent.sitemapExecutor;
+        }
+    }
+
+    /**
+     * Configure the tree processor:
+     * &lt;processor file="{Location of the sitemap}"
+     *               check-reload="{true|false}"
+     *               config="{Location of sitemap tree processor config}&gt;
+     *   &lt;reload delay="10"/&gt;
+     * &lt;/processor&gt;
+     *
+     * Only the file attribute is required; everything else is optional.
+     *
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config)
+    throws ConfigurationException {
+
+        this.checkReload = config.getAttributeAsBoolean("check-reload",
+                             this.core.getSettings().isReloadingEnabled("sitemap"));
+
+        // Obtain the configuration file, or use the XCONF_URL if none
+        // is defined
+        String xconfURL = config.getAttribute("config", XCONF_URL);
+
+        // Reload check delay. Default is 1 second.
+        this.lastModifiedDelay = config.getChild("reload").getAttributeAsLong("delay", this.core.getSettings().getReloadDelay("sitemap"));
+
+        String fileName = config.getAttribute("file", "sitemap.xmap");
+        
+        try {
+            this.source = new DelayedRefreshSourceWrapper(this.resolver.resolveURI(fileName), lastModifiedDelay);
+        } catch (Exception e) {
+            throw new ConfigurationException("Cannot resolve " + fileName, e);
+        }
+
+        // Read the builtin languages definition file
+        try {
+            Source source = this.resolver.resolveURI(xconfURL);
+            try {
+                SAXConfigurationHandler handler = new SAXConfigurationHandler();
+                SourceUtil.toSAX(this.manager, source, null, handler);
+                this.treeBuilderConfiguration = handler.getConfiguration();
+            } finally {
+                this.resolver.release(source);
+            }
+        } catch (Exception e) {
+            String msg = "Error while reading " + xconfURL + ": " + e.getMessage();
+            throw new ConfigurationException(msg, e);
+        }
+    }
+
+    /**
+     * Process the given <code>Environment</code> producing the output.
+     * @return If the processing is successfull <code>true</code> is returned.
+     *         If not match is found in the sitemap <code>false</code>
+     *         is returned.
+     * @throws org.apache.cocoon.ResourceNotFoundException If a sitemap component tries
+     *                                   to access a resource which can not
+     *                                   be found, e.g. the generator
+     *         ConnectionResetException  If the connection was reset
+     */
+    public boolean process(Environment environment) throws Exception {
+        // Get the concrete processor and delegate it the job
+        setupConcreteProcessor(environment);
+        return this.concreteProcessor.process(environment);
+    }
+
+
+    /**
+     * Process the given <code>Environment</code> to assemble
+     * a <code>ProcessingPipeline</code>.
+     * @since 2.1
+     */
+    public InternalPipelineDescription buildPipeline(Environment environment)
+    throws Exception {
+        // Get the concrete processor and delegate it the job
+        setupConcreteProcessor(environment);
+        return this.concreteProcessor.buildPipeline(environment);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getRootProcessor()
+     */
+    public Processor getRootProcessor() {
+        TreeProcessor result = this;
+        while (result.parent != null) {
+            result = result.parent;
+        }
+
+        return result;
+    }
+
+//    /**
+//     * Set the sitemap component configurations
+//     */
+//    public void setComponentConfigurations(Configuration componentConfigurations) {
+//        this.concreteProcessor.setComponentConfigurations(componentConfigurations);
+//    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getComponentConfigurations()
+     */
+    public Configuration[] getComponentConfigurations() {
+        return this.concreteProcessor.getComponentConfigurations();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getContext()
+     */
+    public String getContext() {
+        return this.environmentHelper.getContext();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getEnvironmentHelper()
+     */
+    public org.apache.cocoon.environment.SourceResolver getSourceResolver() {
+        return this.environmentHelper;
+    }
+
+    /**
+     * The current environment helper used by the MountNode
+     * @return EnvironmentHelper
+     */
+    public EnvironmentHelper getEnvironmentHelper() {
+        return this.environmentHelper;
+    }
+
+    /**
+     * Get the tree builder role from the sitemap program (as a configuration object).
+     * This method should report very any problem very clearly, as it is the entry point of any
+     * Cocoon application.
+     *
+     * @param sitemapProgram the sitemap
+     * @return the treebuilder role
+     * @throws ConfigurationException if a suitable role could not be found
+     */
+    private TreeBuilder getTreeBuilder(Configuration sitemapProgram) throws ConfigurationException {
+        String ns = sitemapProgram.getNamespace();
+
+        RE re = new RE("http://apache.org/cocoon/sitemap/(\\d\\.\\d)");
+        if (!re.match(ns)) {
+            throw new ConfigurationException("Unknown sitemap namespace (" + ns + ") at " +
+                    this.source.getURI());
+        }
+
+        String version = re.getParen(1);
+        String result = TreeBuilder.ROLE + "/sitemap-" + version;
+
+        try {
+            return (TreeBuilder) this.manager.lookup(result);
+        } catch (Exception e) {
+            throw new ConfigurationException("This version of Cocoon does not handle sitemap version " +
+                                             version + " at " + this.source.getURI(), e);
+        }
+    }
+
+    /**
+     * Sets up the concrete processor, building or rebuilding it if necessary.
+     */
+    private void setupConcreteProcessor(Environment env) throws Exception {
+
+        if (this.parent == null) {
+            // Ensure root sitemap uses the correct context, even if not located in the webapp context
+            this.environmentHelper.changeContext(this.source, "");
+        }
+
+        if (this.concreteProcessor == null || this.concreteProcessor.isReloadNeeded() ||
+                (this.checkReload && this.source.getLastModified() != this.lastModified)) {
+            buildConcreteProcessor(env);
+        }
+    }
+    
+    private JavaCompiler createJavaCompiler(final Configuration config) {
+        // FIXME: extract compiler and compiler configuration from config
+        return new EclipseJavaCompiler();
+    }
+    
+    private ResourceStore createResourceStore(final Configuration storeConfig) throws Exception {
+        final String className = storeConfig.getAttribute("class","org.apache.commons.jci.stores.MemoryResourceStore");
+        final ResourceStore store = (ResourceStore) Class.forName(className).newInstance();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("storing resources in " + store.getClass().getName());
+        }
+        return store;
+    }
+    
+    private FilesystemAlterationListener createCompilingListener(
+            final Configuration dirConfig
+            ) throws Exception {
+        Source src = null;
+        
+        try {
+            src = resolver.resolveURI(dirConfig.getAttribute("src"));
+            final File repository = new File(src.getURI().substring(5));
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("monitoring src dir " + dirConfig.getAttribute("src"));
+            }
+
+            return new CompilingListener(
+                repository,
+                createJavaCompiler(dirConfig.getChild("compiler")),
+                new TransactionalResourceStore(createResourceStore(dirConfig.getChild("store")))
+              );
+        } finally {
+            resolver.release(src);
+        }
+    }
+
+    private FilesystemAlterationListener createReloadingListener(final Configuration dirConfig) 
+        throws Exception {
+        
+        Source src = null;
+        
+        try {
+            src = resolver.resolveURI(dirConfig.getAttribute("src"));
+            final File repository = new File(src.getURI().substring(5));
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("monitoring class dir " + dirConfig.getAttribute("src"));
+            }
+
+            return new ReloadingListener(
+                repository,
+                createResourceStore(dirConfig.getChild("store"))
+                );
+        } finally {
+            resolver.release(src);
+        }
+    }
+
+    private FilesystemAlterationListener createFileChangeListener(
+            final Configuration dirConfig
+            ) throws Exception {
+        Source src = null;
+        
+        try {
+            src = resolver.resolveURI(dirConfig.getAttribute("src"));
+            final File repository = new File(src.getURI().substring(5));
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("monitoring lib dir " + dirConfig.getAttribute("src"));
+            }
+
+            return new FileChangeListener(repository);
+        } finally {
+            resolver.release(src);
+        }
+    }
+
+    
+    private boolean containsListener(Map map, String src, Class clazz) {
+        FilesystemAlterationListener listener = (FilesystemAlterationListener) map.get(src);
+        if (listener == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("no previous listener for " + src);
+            }
+            return false;
+        }
+        if (!listener.getClass().equals(clazz)) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("previous listener was of a different type");
+            }
+            return false;
+        }
+        
+        return true;
+    }
+    
+    private Map createClasspathListeners(Map oldListeners, Configuration classpathConfig) throws Exception {
+
+        final Configuration[] classDirConfigs = classpathConfig.getChildren("class-dir");        
+        final Configuration[] srcDirConfigs = classpathConfig.getChildren("src-dir");        
+        final Configuration[] libDirConfigs = classpathConfig.getChildren("lib-dir");    
+
+        Map newListeners = new HashMap();
+        
+        for (int i = 0; i < classDirConfigs.length; i++) {
+            final Configuration dirConfig = classDirConfigs[i];
+            final String src = dirConfig.getAttribute("src");
+            if (containsListener(oldListeners, src, ReloadingListener.class)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("keeping ReloadingListener for " + src);
+                }
+                newListeners.put(src, oldListeners.get(src));
+                oldListeners.remove(src);
+            } else {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("new ReloadingListener for " + src);
+                }
+                newListeners.put(src, createReloadingListener(dirConfig));
+            }
+        }
+
+        for (int i = 0; i < srcDirConfigs.length; i++) {
+            final Configuration dirConfig = srcDirConfigs[i];
+            final String src = dirConfig.getAttribute("src");
+            if (containsListener(oldListeners, src, CompilingListener.class)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("keeping CompilingListener for " + src);
+                }
+                newListeners.put(src, oldListeners.get(src));
+                oldListeners.remove(src);
+            } else {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("new CompilingListener for " + src);
+                }
+                newListeners.put(src, createCompilingListener(dirConfig));
+            }
+        }
+
+        for (int i = 0; i < libDirConfigs.length; i++) {
+            final Configuration dirConfig = libDirConfigs[i];
+            final String src = dirConfig.getAttribute("src");
+            if (containsListener(oldListeners, src, FileChangeListener.class)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("keeping FileChangeListener for " + src);
+                }
+                newListeners.put(src, oldListeners.get(src));
+                oldListeners.remove(src);
+            } else {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("new FileChangeListener for " + src);
+                }
+                newListeners.put(src, createFileChangeListener(dirConfig));
+            }
+        }
+             
+        return newListeners;
+    }
+    
+    protected ClassLoader createClassLoader(Configuration classpathConfig)
+    throws Exception {
+        String factoryRole = classpathConfig.getAttribute("factory-role", ClassLoaderFactory.ROLE + "/ReloadingClassLoaderFactory");
+        // Create a new classloader
+        ClassLoaderFactory clFactory = (ClassLoaderFactory)this.manager.lookup(factoryRole);
+        try {
+            return clFactory.createClassLoader(
+                    Thread.currentThread().getContextClassLoader(),
+                    classpathConfig
+            );
+        } finally {
+            this.manager.release(clFactory);
+        }
+    }
+
+    
+    private Configuration createSitemapProgram(Source source) throws ProcessingException, SAXException, IOException {
+        NamespacedSAXConfigurationHandler handler = new NamespacedSAXConfigurationHandler();
+        AnnotationsFilter annotationsFilter = new AnnotationsFilter(handler);
+        SourceUtil.toSAX(source, annotationsFilter);
+        return handler.getConfiguration();        
+    }
+    
+    private void subscribeListeners(Map listerens, ConcreteTreeProcessor processor) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("setting up listeners " + listerens);
+        }
+        for (final Iterator it = listerens.values().iterator(); it.hasNext();) {
+            final NotifyingListener newListener = (NotifyingListener) it.next();
+            
+            newListener.setNotificationListener(processor);
+            
+            fam.subscribe(newListener);
+        }        
+    }
+
+    private void unsubscribeListeners(Map listerens) {
+        if (listerens != null && listerens.size() > 0) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("unsubscribing " + listerens + " from fam");
+            }
+            for (final Iterator it = listerens.values().iterator(); it.hasNext();) {
+                final FilesystemAlterationListener oldListener = (FilesystemAlterationListener) it.next();
+                fam.unsubscribe(oldListener);
+            }
+        }        
+    }
+    
+    private void waitForInitialCompilation(Map listeners) throws Exception {
+        if (listeners.size() > 0) {
+            // wait for the new ones to complete for the first time                
+            for (final Iterator it = listeners.values().iterator(); it.hasNext();) {
+                final NotifyingListener newListener = (NotifyingListener) it.next();
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("waiting for initial compilation");
+                }
+                newListener.waitForFirstCheck();
+            }
+        }        
+    }
+    
+    private void provideClasses(Map listeners, ClassLoader classloader) {
+        for (final Iterator it = listeners.values().iterator(); it.hasNext();) {
+            final NotifyingListener newListener = (NotifyingListener) it.next();
+
+            if (newListener instanceof ResourceStoringListener) {
+                ResourceStoringListener l = (ResourceStoringListener)newListener;
+                if (classloader instanceof ReloadingClassLoaderFactory.DefaultClassLoader) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("adding store " + l.getStore() + " to classloader");
+                    }
+                    ReloadingClassLoaderFactory.DefaultClassLoader cl = (ReloadingClassLoaderFactory.DefaultClassLoader) classloader;
+                    cl.addResourceStore(l.getStore());
+                }
+            }                
+        }        
+    }
+
+    
+    /**
+     * Build the concrete processor (i.e. loads the sitemap). Should be called
+     * only by setupProcessor();
+     */
+    private synchronized void buildConcreteProcessor(Environment env) throws Exception {
+
+        // Now that we entered the synchronized area, recheck what's already
+        // been checked in process().
+        if (this.concreteProcessor != null && source.getLastModified() == this.lastModified && !this.concreteProcessor.isReloadNeeded()) {
+            // Nothing changed
+            return;
+        }
+
+        long startTime = System.currentTimeMillis();
+        long newLastModified;
+        ConcreteTreeProcessor newProcessor;
+        ConcreteTreeProcessor oldProcessor = this.concreteProcessor;
+        Map oldListeners = Collections.EMPTY_MAP;
+        Map newListeners = Collections.EMPTY_MAP;
+                
+        if (oldProcessor != null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("found a previous ConcreteTreeProcessor");
+            }            
+            oldListeners = oldProcessor.getClasspathListeners();                    
+        } else {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("first version of the ConcreteTreeProcessor");
+            }            
+        }
+        
+        // Dispose the old processor, if any
+        if (oldProcessor != null) {
+            oldProcessor.markForDisposal();
+        }
+
+
+        // We have to do a call to enterProcessor() here as during building
+        // of the tree, components (e.g. actions) are already instantiated
+        // (ThreadSafe ones mostly).
+        // If these components try to access the current processor or the
+        // current service manager they must get this one - which is currently
+        // in the process of initialization.
+        EnvironmentHelper.enterProcessor(this, this.manager, env);
+
+        try {
+
+            Configuration sitemapProgram = createSitemapProgram(this.source);
+            newLastModified = this.source.getLastModified();
+
+            newProcessor = createConcreteTreeProcessor();
+
+            // setup sitemap specific classloader
+            // (RP) Should we really support sitemap specific classloader when the global 
+            //      BlocksClassloader is in place?
+            Configuration classpathConfig = sitemapProgram.getChild("components").getChild("classpath", false);
+            if (classpathConfig != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("ConcreteTreeProcessor has a special classpath");
+                }
+                
+                // create a reloading classloader and make it the context classloader
+                ClassLoader classloader = createClassLoader(classpathConfig);
+                Thread.currentThread().setContextClassLoader(classloader);
+                
+                // create the listeners for all classpath entries (lib, classes, src)
+                newListeners = createClasspathListeners(oldListeners, classpathConfig);
+                
+                // store the listeners in the the concreteTreeProcessor instance
+                newProcessor.setClasspathListeners(newListeners);
+                
+                // subscribe all listeners to filesystem altering monitor (FAM)
+                subscribeListeners(newListeners, newProcessor);
+                
+                // use the information about the listeners to create the classpath
+                provideClasses(newListeners, classloader);
+            }
+
+            unsubscribeListeners(oldListeners);
+            
+            waitForInitialCompilation(newListeners);
+            
+
+            // Get the treebuilder that can handle this version of the sitemap.
+            TreeBuilder treeBuilder = getTreeBuilder(sitemapProgram);
+            try {
+                treeBuilder.setProcessor(newProcessor);
+                treeBuilder.setParentProcessorManager(this.manager);
+
+                ProcessingNode root = treeBuilder.build(sitemapProgram);
+                newProcessor.setProcessorData(
+                        treeBuilder.getBuiltProcessorManager(),
+                        treeBuilder.getBuiltProcessorClassLoader(),
+                        root,
+                        treeBuilder.getDisposableNodes(),
+                        treeBuilder.getComponentLocator(),
+                        treeBuilder.getEnterSitemapEventListeners(),
+                        treeBuilder.getLeaveSitemapEventListeners());
+                
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("ConcreteTreeProcessor ready");
+                }
+
+                // Get the actual interpreter
+                FlowNode flowNode = (FlowNode)treeBuilder.getRegisteredNode("flow");
+                if ( flowNode != null ) {
+                    final Interpreter interpreter = flowNode.getInterpreter();
+                    newProcessor.setAttribute(Interpreter.ROLE, interpreter);
+                }
+                
+            } finally {
+                this.manager.release(treeBuilder);
+            }
+        } finally {
+            EnvironmentHelper.leaveProcessor();
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            double time = (System.currentTimeMillis() - startTime) / 1000.0;
+            getLogger().debug("TreeProcessor built in " + time + " secs from " + source.getURI());
+        }
+
+        // Switch to the new processor (ensure it's never temporarily null)
+        this.concreteProcessor = newProcessor;
+        this.lastModified = newLastModified;
+    }
+
+    private ConcreteTreeProcessor createConcreteTreeProcessor() {
+        ConcreteTreeProcessor newProcessor = new ConcreteTreeProcessor(this, this.sitemapExecutor);
+        setupLogger(newProcessor);
+        return newProcessor;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        // Dispose the concrete processor. No need to check for existing requests, as there
+        // are none when a TreeProcessor is disposed.
+        ContainerUtil.dispose(this.concreteProcessor);
+        this.concreteProcessor = null;
+
+        if (this.releaseSitemapExecutor) {
+            this.manager.release(this.sitemapExecutor);
+            this.sitemapExecutor = null;
+        }
+
+        if (this.manager != null) {
+            if (this.source != null) {
+                this.resolver.release(this.source.getSource());
+                this.source = null;
+            }
+            this.manager.release(this.fam);
+            this.manager.release(this.resolver);
+            this.manager.release(this.core);
+            this.resolver = null;
+            this.manager = null;
+            this.core = null;
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.concreteProcessor.getAttribute(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return this.concreteProcessor.removeAttribute(name);
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.concreteProcessor.setAttribute(name, value);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/package.html
new file mode 100644
index 0000000..05892e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/package.html
@@ -0,0 +1,25 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+ <title>Tree Processor</title>
+</head>
+<body>
+ <h1>Evaluation tree based implementation of the <code>Processor</code> interface</h1>
+ <p>
+ </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap-language.xml b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap-language.xml
new file mode 100644
index 0000000..2af9ebe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap-language.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!DOCTYPE sitemap-language [
+  <!ELEMENT sitemap-language (nodes)>
+  <!ELEMENT nodes (node+)>
+  <!ELEMENT node (allowed-children*, ignored-children*, forbidden-children*)>
+  <!ATTLIST node
+    name CDATA #REQUIRED
+    builder CDATA #REQUIRED
+  >
+  <!ELEMENT allowed-children (#PCDATA)>
+  <!ELEMENT ignored-children (#PCDATA)>
+  <!ELEMENT forbidden-children (#PCDATA)>
+]>
+
+<!--+
+    | The sitemap language.
+    | $Id$
+    +-->
+<sitemap-language>
+
+    <!-- node definitions for the sitemap language -->
+    <nodes>
+      <!-- A node has the following attributes :
+           - name : the node name, given as a local name in the language namespace (no prefix)
+           - builder : the class name of the ProcessingNodeBuilder for this node
+           
+           The contents of a node definition is the configuration of Configurable
+           ProcessingNodeBuilders.
+        -->
+      
+      <!-- Sitemap root node -->
+      <node name="sitemap" builder="org.apache.cocoon.components.treeprocessor.sitemap.SitemapNodeBuilder">
+        <allowed-children>components, views, action-sets, resources, flow, pipelines</allowed-children>
+      </node>
+
+      <node name="components" builder="org.apache.cocoon.components.treeprocessor.sitemap.ComponentsNodeBuilder"/>
+
+      <node name="generators" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCsNodeBuilder"/>
+
+      <node name="generator" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCNodeBuilder">
+        <ignored-children>source</ignored-children>
+      </node>
+
+      <node name="transformers" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCsNodeBuilder"/>
+
+      <node name="transformer" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCNodeBuilder">
+        <ignored-children>source</ignored-children>
+      </node>
+
+      <node name="serializers" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCsNodeBuilder"/>
+
+      <node name="serializer" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCNodeBuilder">
+        <ignored-children>source</ignored-children>
+      </node>
+
+      <node name="readers" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCsNodeBuilder"/>
+
+      <node name="reader" builder="org.apache.cocoon.components.treeprocessor.sitemap.VPCNodeBuilder">
+        <ignored-children>source</ignored-children>
+      </node>
+
+      <node name="views" builder="org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder">
+        <allowed-children>view</allowed-children>
+      </node>
+
+      <node name="view" builder="org.apache.cocoon.components.treeprocessor.sitemap.ViewNodeBuilder"/>
+
+      <node name="action-sets" builder="org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder">
+        <allowed-children>action-set</allowed-children>
+      </node>
+
+      <node name="action-set" builder="org.apache.cocoon.components.treeprocessor.sitemap.ActionSetNodeBuilder"/>
+
+      <node name="resources" builder="org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder">
+        <allowed-children>resource</allowed-children>
+      </node>
+
+      <node name="resource" builder="org.apache.cocoon.components.treeprocessor.NamedContainerNodeBuilder"/>
+
+      <node name="flow" builder="org.apache.cocoon.components.treeprocessor.sitemap.FlowNodeBuilder">
+        <allowed-children>script</allowed-children>
+      </node>
+
+      <node name="script" builder="org.apache.cocoon.components.treeprocessor.sitemap.ScriptNodeBuilder"/>
+
+      <node name="pipelines" builder="org.apache.cocoon.components.treeprocessor.sitemap.PipelinesNodeBuilder">
+        <allowed-children>pipeline, handle-errors</allowed-children>
+        <ignored-children>component-configurations</ignored-children>
+      </node>
+
+      <node name="pipeline" builder="org.apache.cocoon.components.treeprocessor.sitemap.PipelineNodeBuilder">
+        <forbidden-children>sitemap, components, pipeline</forbidden-children>
+      </node>
+
+      <node name="match" builder="org.apache.cocoon.components.treeprocessor.sitemap.MatchNodeBuilder">
+        <forbidden-children>sitemap, components, pipeline, handle-errors</forbidden-children>
+      </node>
+
+      <node name="select" builder="org.apache.cocoon.components.treeprocessor.sitemap.SelectNodeBuilder">
+        <forbidden-children>sitemap, components, pipeline, handle-errors</forbidden-children>
+      </node>
+
+      <node name="act" builder="org.apache.cocoon.components.treeprocessor.sitemap.ActNodeBuilder">
+        <forbidden-children>sitemap, components, pipeline, handle-errors</forbidden-children>
+      </node>
+
+      <node name="redirect-to" builder="org.apache.cocoon.components.treeprocessor.sitemap.RedirectToNodeBuilder"/>
+
+      <node name="call" builder="org.apache.cocoon.components.treeprocessor.sitemap.CallNodeBuilder"/>
+
+      <node name="mount" builder="org.apache.cocoon.components.treeprocessor.sitemap.MountNodeBuilder"/>
+
+      <node name="read" builder="org.apache.cocoon.components.treeprocessor.sitemap.ReadNodeBuilder"/>
+
+      <node name="aggregate" builder="org.apache.cocoon.components.treeprocessor.sitemap.AggregateNodeBuilder"/>
+
+      <node name="generate" builder="org.apache.cocoon.components.treeprocessor.sitemap.GenerateNodeBuilder"/>
+
+      <node name="transform" builder="org.apache.cocoon.components.treeprocessor.sitemap.TransformNodeBuilder"/>
+
+      <node name="serialize" builder="org.apache.cocoon.components.treeprocessor.sitemap.SerializeNodeBuilder"/>
+
+      <node name="handle-errors" builder="org.apache.cocoon.components.treeprocessor.sitemap.HandleErrorsNodeBuilder"/>
+
+    </nodes>
+
+    <!--+
+        | You can add specific nodes for a specific sitemap version, using
+        | &lt;nodes-{version}&gt;
+        +-->
+
+</sitemap-language>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActNodeBuilder.java
new file mode 100644
index 0000000..e77166e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActNodeBuilder.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.CategoryNode;
+import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ActNodeBuilder extends AbstractParentProcessingNodeBuilder
+                            implements LinkedProcessingNodeBuilder {
+
+    private ActSetNode  actSetNode;
+    private String      actSetName;
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        
+        boolean inActionSet = this.treeBuilder.getAttribute(ActionSetNodeBuilder.IN_ACTION_SET) != null;
+
+        // Is it an action-set call ?
+        this.actSetName = config.getAttribute("set", null);
+        if (actSetName == null) {
+            
+            if (inActionSet) {
+                // Check that children are only parameters or actions
+                Configuration children[] = config.getChildren();
+                for (int i = 0; i < children.length; i++) {
+                    String name = children[i].getName();
+                    if (!"act".equals(name) && !"parameter".equals(name)) {
+                        throw new ConfigurationException("An action set can only contain actions and not '" 
+                            + name + "' at " + children[i].getLocation());
+                    }
+                }
+            }
+
+            String name = config.getAttribute("name", null);
+            String source = config.getAttribute("src", null);
+            String type = this.treeBuilder.getTypeForStatement(config, Action.ROLE);
+
+            ActTypeNode actTypeNode = new ActTypeNode(
+                type,
+                VariableResolverFactory.getResolver(source, this.manager),
+                name,
+                inActionSet
+            );
+            this.treeBuilder.setupNode(actTypeNode, config);
+
+            actTypeNode.setChildren(buildChildNodes(config));
+
+            return actTypeNode;
+
+        }
+
+        if (inActionSet) {
+            throw new ConfigurationException("Cannot call an action set from an action set at " + config.getLocation());
+        }
+
+        // Action set call
+        if (config.getAttribute("src", null) != null) {
+            getLogger().warn("The 'src' attribute is ignored for action-set call at " + config.getLocation());
+        }
+        this.actSetNode = new ActSetNode();
+        this.treeBuilder.setupNode(this.actSetNode, config);
+
+        this.actSetNode.setChildren(buildChildNodes(config));
+
+        return this.actSetNode;
+    }
+
+    public void linkNode() throws Exception {
+
+        if (this.actSetNode != null) {
+            // Link action-set call to the action set
+            CategoryNode actionSets = CategoryNodeBuilder.getCategoryNode(this.treeBuilder, "action-sets");
+
+            if (actionSets == null)
+                throw new ConfigurationException("This sitemap contains no action sets. Cannot call at " + actSetNode.getLocation());
+
+            ActionSetNode actionSetNode = (ActionSetNode)actionSets.getNodeByName(this.actSetName);
+
+            this.actSetNode.setActionSet(actionSetNode);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActSetNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActSetNode.java
new file mode 100644
index 0000000..ae7dbed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActSetNode.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleParentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+
+import java.util.Map;
+
+/**
+ * Handles &lt;map:act type="..."&gt; (action-sets calls are handled by {@link ActSetNode}).
+ *
+ * @version $Id$
+ */
+public class ActSetNode extends SimpleParentProcessingNode
+  implements ParameterizableProcessingNode {
+
+    /** The parameters of this node */
+    private Map parameters;
+
+    /** The action set to call */
+    private ActionSetNode actionSet;
+
+    public ActSetNode() {
+        super(null);
+    }
+    
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setActionSet(ActionSetNode actionSet) {
+        this.actionSet = actionSet;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+      throws Exception {
+
+        // Perform any common invoke functionality 
+        super.invoke(env, context);
+
+        Parameters resolvedParams = VariableResolver.buildParameters(
+            this.parameters,
+            context,
+            env.getObjectModel()
+        );
+
+        Map result = this.actionSet.call(env, context, resolvedParams);
+
+        if (context.getRedirector().hasRedirected()) {
+            return true;
+
+        } else if (result == null) {
+            return false;
+
+        } else if (this.children == null) {
+            return true;
+
+        } else {
+            return this.invokeNodes(this.children, env, context, null, result);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActTypeNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActTypeNode.java
new file mode 100644
index 0000000..6592fe7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActTypeNode.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ * Handles &lt;map:act type="..."&gt; (action-sets calls are handled by {@link ActSetNode}).
+ *
+ * @version $Id$
+ */
+public class ActTypeNode extends SimpleSelectorProcessingNode
+  implements ParameterizableProcessingNode {
+
+    /** The parameters of this node */
+    private Map parameters;
+
+    /** The 'src' attribute */
+    protected VariableResolver source;
+
+    /** The 'name' for the variable anchor */
+    protected String name;
+
+    protected boolean inActionSet;
+
+    public ActTypeNode(String type, 
+                       VariableResolver source, 
+                       String name,
+                       boolean inActionSet)  {
+        super(Action.ROLE + "Selector", type);
+        this.source = source;
+        this.name = name;
+        this.inActionSet = inActionSet;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+          throws Exception {
+
+        // Perform any common invoke functionality 
+        super.invoke(env, context);
+
+        // Prepare data needed by the action
+        Map objectModel = env.getObjectModel();
+        Redirector redirector = context.getRedirector();
+        SourceResolver resolver = EnvironmentHelper.getCurrentProcessor().getSourceResolver();
+        String resolvedSource = source.resolve(context, objectModel);
+        Parameters resolvedParams =
+            VariableResolver.buildParameters(this.parameters,
+                    context, objectModel);
+
+        Map actionResult;
+
+        // If in action set, merge parameters
+        if (inActionSet) {
+            Parameters callerParams =
+                (Parameters)env.getAttribute(ActionSetNode.CALLER_PARAMETERS);
+            if (resolvedParams == Parameters.EMPTY_PARAMETERS) {
+                // Just swap
+                resolvedParams = callerParams;
+            } else if (callerParams != Parameters.EMPTY_PARAMETERS) {
+                // Build new Parameters object, the both we hare are read-only!
+                Parameters newParams = new Parameters();
+                // And merge both
+                newParams.merge(resolvedParams);
+                newParams.merge(callerParams);
+                resolvedParams = newParams;
+            }
+        }
+
+        Action action = (Action)getComponent();
+        try {
+            actionResult = this.executor.invokeAction(this,
+                                             objectModel, 
+                                             action, 
+                                             redirector, 
+                                             resolver, 
+                                             resolvedSource, 
+                                             resolvedParams);
+        } finally {
+            releaseComponent(action);
+        }
+
+        if (redirector.hasRedirected()) {
+            return true;
+        }
+
+        if (actionResult != null) {
+            // Action succeeded : process children if there are some, with the action result
+            if (this.children != null) {
+                boolean result = this.invokeNodes(this.children, env, context, name, actionResult);
+
+                if (inActionSet) {
+                    // Merge child action results, if any
+                    Map childMap = (Map)env.getAttribute(ActionSetNode.ACTION_RESULTS);
+                    if (childMap != null) {
+                        Map newResults = new HashMap(childMap);
+                        newResults.putAll(actionResult);
+                        env.setAttribute(ActionSetNode.ACTION_RESULTS, newResults);
+                    } else {
+                        // No previous results
+                        env.setAttribute(ActionSetNode.ACTION_RESULTS, actionResult);
+                    }
+                }
+                return result;
+            }// else {
+               // return false; // Return false to continue sitemap invocation
+            //}
+        }// else {
+            return false;   // Action failed
+        //}
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNode.java
new file mode 100644
index 0000000..225f9d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNode.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.NamedProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ActionSetNode extends AbstractProcessingNode
+  implements NamedProcessingNode {
+      
+    public static final String CALLER_PARAMETERS = ActionSetNode.class.getName() + "/CallerParameters";
+    public static final String ACTION_RESULTS = ActionSetNode.class.getName() + "/ActionResults";
+
+    /** The action nodes */
+    private ProcessingNode[] nodes;
+
+    /** The 'action' attribute for each action */
+    private String[] actionNames;
+
+    public ActionSetNode(
+      String name, ProcessingNode[] nodes, String[] actionNames) {
+        super(name);
+        this.nodes = nodes;
+        this.actionNames = actionNames;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+      throws Exception {
+	
+        // Perform any common invoke functionalty 
+        // super.invoke(env, context);
+        String msg = "An action-set cannot be invoked, at " + this.getLocation();
+        throw new UnsupportedOperationException(msg);
+    }
+
+    /**
+     * Call the actions composing the action-set and return the combined result of
+     * these actions.
+     */
+    public final Map call(Environment env, InvokeContext context, Parameters params) throws Exception {
+
+        String cocoonAction = env.getAction();
+
+        // Store the parameters from the caller into the environment so that they can be merged with
+        // each action's parameters.
+        
+
+        Map result = null;
+
+        // Call each action that either has no cocoonAction, or whose cocoonAction equals
+        // the one from the environment.
+        env.setAttribute(CALLER_PARAMETERS, params);
+
+        for (int i = 0; i < nodes.length; i++) {
+
+
+            String actionName = actionNames[i];
+            if (actionName == null || actionName.equals(cocoonAction)) {
+                
+                this.nodes[i].invoke(env, context);
+                
+                // Get action results. They're passed back through the environment since action-sets
+                // "violate" the tree hierarchy (the returned Map is visible outside of the node)
+                Map actionResult = (Map)env.getAttribute(ACTION_RESULTS);
+                // Don't forget to clear it
+                env.removeAttribute(ACTION_RESULTS);
+                
+                if (actionResult != null) {
+                    // Merge the result in the global result, creating it if necessary.
+                    if (result == null) {
+                        result = new HashMap(actionResult);
+                    } else {
+                        result.putAll(actionResult);
+                    }
+                }
+                
+            } // if (actionName...
+        } // for (int i...
+
+        return result;
+    }
+
+    /**
+     * Implementation of <code>NamedProcessingNode</code>.
+     */
+
+    public String getName() {
+        return this.componentName;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNodeBuilder.java
new file mode 100644
index 0000000..cde8fc3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ActionSetNodeBuilder.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ActionSetNodeBuilder extends AbstractParentProcessingNodeBuilder implements ThreadSafe {
+    
+    /** The TreeBuilder attribute indicating that an ActionSet is being built */
+    public static final String IN_ACTION_SET = ActionSetNodeBuilder.class.getName() + "/inActionSet";
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String actionSetName = config.getAttribute("name");
+
+        Configuration[] childrenConfig = config.getChildren();
+        // Inform other builders that we're in an action-set
+        this.treeBuilder.setAttribute(IN_ACTION_SET, Boolean.TRUE);
+        
+        // Get the child actions
+        ProcessingNode[] nodes = this.buildChildNodes(config);
+        
+        // And get their names
+        String[] actions = new String[nodes.length];
+        for (int i = 0; i < childrenConfig.length; i++) {
+            Configuration childConfig = childrenConfig[i];
+            String name = childConfig.getName();
+
+            if ("act".equals(name)) {
+                actions[i] = childConfig.getAttribute("action", null);
+            } else {
+                // Unknown element
+                String msg = "Unknown element " + name + " in action-set at " + childConfig.getLocation();
+                throw new ConfigurationException(msg);
+            }            
+        }
+
+        ActionSetNode node = new ActionSetNode(actionSetName, nodes, actions);
+        this.treeBuilder.setupNode(node, config);
+
+        // Inform other builders that we're no more in an action-set
+        this.treeBuilder.setAttribute(IN_ACTION_SET, null);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNode.java
new file mode 100644
index 0000000..6b74819
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNode.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.ContentAggregator;
+
+import java.util.Map;
+
+/**
+ * Aggregate sitemap node.
+ *
+ * <h3>View handling in aggregation</h3>
+ * <ul>
+ * <li>map:aggregate can have a label, but doesn't match view from-position="first" like generators
+ * </li>
+ * <li>each map:part can have a label
+ * </li>
+ * <li>if at least one of the parts has a label matching the current view, only parts matching
+ *     this view are added. Otherwise, all parts are added.
+ * </li>
+ * </ul>
+ * For more info on aggregation and views, see the mail archive
+ * <a href="http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=100525751417953">here</a> or
+ * <a href="http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=100517130418424">here</a>.
+ *
+ * @version $Id$
+ */
+public class AggregateNode extends AbstractProcessingNode {
+
+    private VariableResolver element;
+    private VariableResolver nsURI;
+    private VariableResolver nsPrefix;
+
+    /** All parts */
+    private Part[] allParts;
+
+    /** Pre-filtered Part[] for views that have a matching label in any of the parts */
+    private Map viewParts;
+
+    /** View nodes to jump to */
+    private Map viewNodes;
+
+    public AggregateNode(VariableResolver element, VariableResolver nsURI, VariableResolver nsPrefix) {
+        super(null);
+        this.element = element;
+        this.nsURI = nsURI;
+        this.nsPrefix = nsPrefix;
+    }
+
+    public void setParts(Part[] allParts, Map viewParts) {
+        this.allParts = allParts;
+        this.viewParts = viewParts;
+    }
+
+    public void setViewNodes(Map viewNodes) {
+        this.viewNodes = viewNodes;
+    }
+
+    public boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+        final boolean infoEnabled = getLogger().isInfoEnabled();
+
+        Map objectModel = env.getObjectModel();
+
+        // Setup aggregator
+        ProcessingPipeline processingPipeline = context.getProcessingPipeline();
+        processingPipeline.setGenerator("<aggregator>", null, Parameters.EMPTY_PARAMETERS, Parameters.EMPTY_PARAMETERS);
+
+        ContentAggregator aggregator = (ContentAggregator) processingPipeline.getGenerator();
+        aggregator.setRootElement(this.element.resolve(context, objectModel),
+                                  this.nsURI.resolve(context, objectModel),
+                                  this.nsPrefix.resolve(context, objectModel));
+
+        // Get actual parts, potentially filtered by the view
+        Part[] actualParts;
+
+        String cocoonView = env.getView();
+        if (cocoonView == null) {
+            // Keep all parts
+            actualParts = this.allParts;
+
+        } else {
+            // Are there some parts that match this view ?
+            actualParts = (Part[])this.viewParts.get(cocoonView);
+
+            // If not, keep all parts
+            if (actualParts == null) {
+                actualParts = this.allParts;
+            }
+        }
+
+        // Add parts
+        for (int i = 0; i < actualParts.length; i++) {
+            Part part = actualParts[i];
+            if (part != null) {
+                aggregator.addPart(
+                    part.source.resolve(context, objectModel),
+                    part.element.resolve(context, objectModel),
+                    part.nsURI.resolve(context, objectModel),
+                    part.stripRoot.resolve(context, objectModel),
+                    part.nsPrefix.resolve(context, objectModel)
+                );
+            }
+        }
+
+        // Bug #7196 : Some parts matched the view: jump to that view
+        if (actualParts != this.allParts) {
+            ProcessingNode viewNode = (ProcessingNode)this.viewNodes.get(cocoonView);
+            if (viewNode != null) {
+                if (infoEnabled) {
+                    getLogger().info("Jumping to view '" + cocoonView + "' from aggregate part at " + this.getLocation());
+                }
+                return viewNode.invoke(env, context);
+            }
+        }
+
+        // Check aggregate-level view
+        if (cocoonView != null && this.viewNodes != null) {
+            ProcessingNode viewNode = (ProcessingNode)this.viewNodes.get(cocoonView);
+            if (viewNode != null) {
+                if (infoEnabled) {
+                    getLogger().info("Jumping to view '" + cocoonView + "' from aggregate at " + this.getLocation());
+                }
+                return viewNode.invoke(env, context);
+            }
+        }
+
+        // Return false to continue sitemap invocation
+        return false;
+    }
+
+    public static class Part {
+        protected VariableResolver source;
+        protected VariableResolver element;
+        protected VariableResolver nsURI;
+        protected VariableResolver nsPrefix;
+        protected VariableResolver stripRoot;
+
+        public Part(VariableResolver source,
+                    VariableResolver element,
+                    VariableResolver nsURI,
+                    VariableResolver nsPrefix,
+                    VariableResolver stripRoot) {
+            this.source = source;
+            this.element = element;
+            this.nsURI = nsURI;
+            this.nsPrefix = nsPrefix;
+            this.stripRoot = stripRoot;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNodeBuilder.java
new file mode 100644
index 0000000..fabb493
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/AggregateNodeBuilder.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+
+/**
+ * @version $Id$
+ */
+public class AggregateNodeBuilder extends AbstractProcessingNodeBuilder
+                                  implements LinkedProcessingNodeBuilder {
+
+    /** The views for the aggregate element */
+    private Collection views;
+
+    /** The built node */
+    private AggregateNode node;
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        // Get root node data
+        this.node = new AggregateNode(
+            VariableResolverFactory.getResolver(config.getAttribute("element"), this.manager),
+            VariableResolverFactory.getResolver(config.getAttribute("ns", ""), this.manager),
+            VariableResolverFactory.getResolver(config.getAttribute("prefix", ""), this.manager)
+        );
+        this.treeBuilder.setupNode(this.node, config);
+
+        this.views = ((SitemapLanguage)this.treeBuilder).getViewsForStatement("", "", config);
+
+        // Bug #7196 : ensure this.views is never null (see continuation of fix below)
+        if (this.views == null) {
+            this.views = new HashSet();
+        }
+
+        // The sitemap builder
+        SitemapLanguage sitemap = (SitemapLanguage)this.treeBuilder;
+
+        // All parts of the aggregate
+        List allParts = new ArrayList();
+
+        // For each view that a part matches, the list of all parts that match it
+        Map viewParts = new HashMap();
+
+        Configuration[] childConfigs = config.getChildren();
+        for (int i = 0; i < childConfigs.length; i++) {
+            Configuration childConfig = childConfigs[i];
+
+            if (!"part".equals(childConfig.getName())) {
+                String msg = "Unknown element '" + childConfig.getName() + " in aggregate ' at " +
+                    childConfig.getLocation();
+                throw new ConfigurationException(msg);
+            }
+
+            checkNamespace(childConfig);
+
+            AggregateNode.Part currentPart = new AggregateNode.Part(
+                VariableResolverFactory.getResolver(childConfig.getAttribute("src"), this.manager),
+                VariableResolverFactory.getResolver(childConfig.getAttribute("element", ""), this.manager),
+                VariableResolverFactory.getResolver(childConfig.getAttribute("ns", ""), this.manager),
+                VariableResolverFactory.getResolver(childConfig.getAttribute("prefix", ""), this.manager),
+                VariableResolverFactory.getResolver(childConfig.getAttribute("strip-root", "false"), this.manager)
+            );
+
+            allParts.add(currentPart);
+
+            // Get the views for this part
+            Collection viewsForPart = sitemap.getViewsForStatement("", "", childConfig);
+
+            // Associate this part to all the views it belongs to
+            if (viewsForPart != null) {
+
+                // Bug #7196 : add part view to aggregate views
+                this.views.addAll(viewsForPart);
+
+                Iterator iter = viewsForPart.iterator();
+                while(iter.hasNext()) {
+                    String currentView = (String)iter.next();
+
+                    // Get collection of parts for current view
+                    Collection currentViewParts = (Collection)viewParts.get(currentView);
+                    if (currentViewParts == null) {
+                        // None for now : create the collection
+                        currentViewParts = new ArrayList();
+                        viewParts.put(currentView, currentViewParts);
+                    }
+
+                    // Add the current part to the parts list of the view
+                    currentViewParts.add(currentPart);
+                }
+            }
+        }
+
+        if (allParts.size() == 0) {
+            String msg = "There must be at least one part in map:aggregate at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        // Now convert all Collections to Array for faster traversal
+        AggregateNode.Part[] allPartsArray = (AggregateNode.Part[])allParts.toArray(
+            new AggregateNode.Part[allParts.size()]);
+
+        Iterator iter = viewParts.entrySet().iterator();
+        while(iter.hasNext()) {
+            Map.Entry entry = (Map.Entry)iter.next();
+
+            // Get collection of parts for this entry
+            Collection coll = (Collection)entry.getValue();
+
+            // Convert to array and replace the entry value
+            entry.setValue(
+                coll.toArray(new AggregateNode.Part[coll.size()])
+            );
+        }
+
+        node.setParts(allPartsArray, viewParts);
+
+        return node;
+
+    }
+
+    public void linkNode() throws Exception {
+
+        // Give the AggregateNode a Node for each view
+        SitemapLanguage sitemap = (SitemapLanguage)this.treeBuilder;
+
+        this.node.setViewNodes(sitemap.getViewNodes(this.views));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
new file mode 100644
index 0000000..c3cf52e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallFunctionNode.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Redirector;
+
+/**
+ * Node handler for calling functions and resuming continuations in
+ * the control flow layer.
+ *
+ * @since March 13, 2002
+ * @version $Id$
+ */
+public class CallFunctionNode extends AbstractProcessingNode implements ParameterizableProcessingNode {
+
+    protected Map parameters;
+    protected VariableResolver functionName;
+    protected VariableResolver continuationId;
+    protected String[] argumentNames;
+    protected Interpreter interpreter;
+
+    public CallFunctionNode(VariableResolver functionName, VariableResolver continuationId, String[] argumentNames) {
+        super(null);
+        this.functionName = functionName;
+        this.continuationId = continuationId;
+        this.argumentNames = argumentNames;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode#setParameters(java.util.Map)
+     */
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setInterpreter(Interpreter interp) throws Exception {
+        this.interpreter = interp;
+    }
+
+    public boolean invoke(Environment env, InvokeContext context) throws Exception {
+
+        Map objectModel = env.getObjectModel();
+
+        // Resolve parameters
+        Parameters params = VariableResolver.buildParameters(this.parameters, context, objectModel);
+
+        // Build the list of positional arguments
+        //TODO (SW): Deprecate this in the future.
+        // It has be found to be bad practice to pass sitemap parameters
+        // as function arguments, as these are name-value pairs in the sitemap
+        // and positional arguments in the flowscript. If the user doesn't respect
+        // the argument order, this leads to difficult to solve bugs.
+        List args;
+        if (argumentNames.length != 0) {
+            args = new ArrayList(argumentNames.length);
+            for (int i = 0; i < argumentNames.length; i++) {
+                String name = argumentNames[i];
+                args.add(new Interpreter.Argument(name, params.getParameter(name)));
+            }
+        } else {
+            args = Collections.EMPTY_LIST;
+        }
+
+        // Need redirector in any case
+        Redirector redirector = context.getRedirector();
+
+        // If the continuation id is not null, it takes precedence over
+        // the function call, so we invoke it here.
+        String continuation = continuationId.resolve(context, env.getObjectModel());
+        if (continuation != null && continuation.length() > 0) {
+            try {
+                interpreter.handleContinuation(continuation, args, redirector);
+            } catch(Exception e) {
+                throw ProcessingException.throwLocated("Sitemap: error calling continuation", e, getLocation());
+            }
+            if (!redirector.hasRedirected()) {
+                throw new ProcessingException("Sitemap: <map:call continuation> did not send a response", getLocation());
+            }
+            return true;
+        }
+
+        // We don't have a continuation id passed in <map:call>, so invoke
+        // the specified function
+        String name = functionName.resolve(context, objectModel);
+        if (name != null && name.length() > 0) {
+            try {
+                interpreter.callFunction(name, args, redirector);
+            } catch(Exception e) {
+                throw ProcessingException.throwLocated("Sitemap: error calling function '" + name + "'", e, getLocation());
+            }
+            if (!redirector.hasRedirected()) {
+                throw new ProcessingException("Sitemap: <map:call function> did not send a response", getLocation());
+            }
+            return true;
+        }
+
+        // Found neither continuation nor function to call
+        throw new ProcessingException("Sitemap: no function nor continuation given in <map:call function>", getLocation());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNode.java
new file mode 100644
index 0000000..9494cea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNode.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.CategoryNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ *
+ * @version $Id$
+ */
+public class CallNode extends AbstractProcessingNode
+    implements ParameterizableProcessingNode {
+
+    /** The parameters of this node */
+    private Map parameters;
+
+    /** The 'resource' attribute */
+    private VariableResolver resourceName;
+
+    /** The category node */
+    private CategoryNode resources;
+
+    public CallNode() {
+        super(null);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode#setParameters(java.util.Map)
+     */
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setResource(CategoryNode resources, VariableResolver resourceName) throws Exception {
+        this.resourceName = resourceName;
+        this.resources = resources;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+      throws Exception {
+
+        Map objectModel = env.getObjectModel();
+        // Resolve parameters, but push them only once the resource name has been
+        // resolved, otherwise it adds an unwanted nesting level
+        Map params = VariableResolver.buildMap(this.parameters, context, objectModel);
+
+        // Resolved resource name
+        String name = this.resourceName.resolve(context, objectModel);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Calling resource " + name);
+        }
+        
+        // and only now push the parameters
+        params = this.executor.pushVariables(this, objectModel, null, params);
+        context.pushMap(null,params);
+        
+        try {
+            return this.resources.invokeByName(name, env, context);
+        } finally {
+            this.executor.popVariables(this, objectModel);
+            context.popMap();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNodeBuilder.java
new file mode 100644
index 0000000..0f5b186
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/CallNodeBuilder.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.CategoryNode;
+import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+
+/**
+ *
+ * @version $Id$
+ */
+public class CallNodeBuilder extends AbstractProcessingNodeBuilder
+                             implements LinkedProcessingNodeBuilder {
+
+    protected ProcessingNode node;
+
+    protected String resourceName;
+
+    protected String functionName;
+
+    protected String continuationId;
+
+    public ProcessingNode buildNode(Configuration config)
+    throws Exception {
+        resourceName = config.getAttribute("resource", null);
+        functionName = config.getAttribute("function", null);
+        continuationId = config.getAttribute("continuation", null);
+
+        if (resourceName == null) {
+            // Building a CallFunction node
+            if (functionName == null && continuationId == null) {
+                throw new ConfigurationException(
+                    "<map:call> must have either a 'resource', 'function' or 'continuation' attribute, at "
+                    + config.getLocation()
+                );
+            }
+
+            // Build the ordered list of parameter names
+            // FIXME(SW): remove this in the future (see comment in FlowNode)
+            List argumentNames = new ArrayList();
+            Configuration[] params = config.getChildren("parameter");
+            for (int i = 0; i < params.length; i++) {
+                argumentNames.add(params[i].getAttribute("name"));
+            }
+
+            node = new CallFunctionNode(VariableResolverFactory.getResolver(
+                functionName, this.manager),
+                VariableResolverFactory.getResolver(continuationId, this.manager),
+                (String[]) argumentNames.toArray(new String[argumentNames.size()])
+            );
+
+        } else {
+            // Building a Call(Resource)Node
+            if (functionName != null || continuationId != null) {
+                throw new ConfigurationException(
+                    "<map:call> cannot have both a 'resource' and a 'function' or 'continuation' attribute, at "
+                    + config.getLocation());
+            }
+            node = new CallNode();
+        }
+
+        this.treeBuilder.setupNode(this.node, config);
+        if (node instanceof Configurable) {
+            ((Configurable) this.node).configure(config);
+        }
+
+        return this.node;
+    }
+
+    public void linkNode() throws Exception {
+        if (resourceName != null) {
+            // We have a <map:call resource="..."/>
+            CategoryNode resources = CategoryNodeBuilder.getCategoryNode(treeBuilder, "resources");
+
+            if (resources == null)
+                throw new ConfigurationException(
+                    "This sitemap contains no resources. Cannot call at " + node.getLocation());
+
+            ((CallNode) this.node).setResource(
+                resources,
+                VariableResolverFactory.getResolver(this.resourceName, this.manager)
+            );
+        } else {
+            // We have a <map:call> with either "function" or
+            // "continuation", or both specified
+
+            // Check to see if a flow has been defined in this sitemap
+            FlowNode flow = (FlowNode) treeBuilder.getRegisteredNode("flow");
+            if (flow == null) {
+                throw new ConfigurationException(
+                    "This sitemap contains no control flows defined, cannot call at "
+                    + node.getLocation()
+                    + ". Define a control flow using <map:flow>, with embedded <map:script> elements.");
+            }
+
+            // Get the Interpreter instance and set it up in the
+            // CallFunctionNode function
+            Interpreter interpreter = flow.getInterpreter();
+            ((CallFunctionNode) node).setInterpreter(interpreter);
+        }
+    }
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsNodeBuilder.java
new file mode 100644
index 0000000..72ede8c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsNodeBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
+
+/**
+ * Handles &lt;map:components&gt;. It doesn't actually create a <code>ProcessingNode</code>.
+ *
+ * @version $Id$
+ */
+public class ComponentsNodeBuilder extends AbstractProcessingNodeBuilder {
+
+    private static String[] VPCTypes =
+    {"generators", "transformers", "serializers", "readers"};
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        // Handle the VPCs
+        for (int i = 0; i < VPCTypes.length; i++) {
+            Configuration child = config.getChild(VPCTypes[i], false);
+            if (child != null) {
+                ProcessingNodeBuilder childBuilder =
+                    this.treeBuilder.createNodeBuilder(child);
+                childBuilder.buildNode(child);
+            }
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
new file mode 100644
index 0000000..969371c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ComponentsSelector.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.core.container.DefaultServiceSelector;
+import org.apache.cocoon.generation.GeneratorFactory;
+import org.apache.cocoon.serialization.SerializerFactory;
+import org.apache.cocoon.transformation.TransformerFactory;
+
+/**
+ * Component selector for sitemap components.
+ *
+ * @version $Id$
+ */
+public class ComponentsSelector extends DefaultServiceSelector {
+
+    private static final int UNKNOWN     = -1;
+    private static final int GENERATOR   = 0;
+    private static final int TRANSFORMER = 1;
+    private static final int SERIALIZER  = 2;
+
+    /** Configuration element names, used to find the role */
+    private static final String[] CONFIG_NAMES = {
+        "generators",
+        "transformers",
+        "serializers",
+        "readers",
+        "matchers",
+        "selectors",
+        "actions",
+        "pipes"
+    };
+
+    /** Names of children elements, according to role */
+    private static final String[] COMPONENT_NAMES = {
+        "generator",
+        "transformer",
+        "serializer",
+        "reader",
+        "matcher",
+        "selector",
+        "action",
+        "pipe"
+    };
+
+    /** The role as an integer */
+    private int roleId;
+
+    /**
+     * Return the component instance name according to the selector role
+     * (e.g. "action" for "org.apache.cocoon.acting.Action").
+     */
+    protected String getComponentInstanceName() {
+        return COMPONENT_NAMES[this.roleId];
+    }
+
+    /**
+     * Get the attribute for class names. This is "src" for known roles, and
+     * "class" (the default) for other roles.
+     */
+    protected String getClassAttributeName() {
+        return "src";
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        // Who are we ?
+        final String configName = config.getName();
+        this.roleId = UNKNOWN; // unknown
+        for (int i = 0; i < CONFIG_NAMES.length; i++) {
+            if (CONFIG_NAMES[i].equals(configName)) {
+                this.roleId = i;
+                break;
+            }
+        }
+        
+        if (this.roleId == UNKNOWN) {
+            throw new ConfigurationException("ComponentsSelector is reserved for sitemap components. Illegal use at " +
+                    config.getLocation());
+        }
+
+        super.configure(config);
+    }
+
+    /**
+     * Override parent to implement support for {@link GeneratorFactory},
+     * {@link TransformerFactory}, and {@link SerializerFactory}.
+     */
+    public Object select(Object hint) throws ServiceException {
+        final Object component = super.select(hint);
+
+        switch (this.roleId) {
+            case GENERATOR:
+                if (component instanceof GeneratorFactory) {
+                    return ((GeneratorFactory)component).getInstance();
+                }
+                break;
+            case TRANSFORMER:
+                if (component instanceof TransformerFactory) {
+                    return ((TransformerFactory)component).getInstance();
+                }
+                break;
+            case SERIALIZER:
+                if (component instanceof SerializerFactory) {
+                    return ((SerializerFactory)component).getInstance();
+                }
+                break;
+        }
+
+        return component;
+    }
+
+    /**
+     * Override parent to implement support for {@link GeneratorFactory},
+     * {@link TransformerFactory}, and {@link SerializerFactory}.
+     */
+    public void release(Object component) {
+
+        // If component is an Instance returned by Factory, get the Factory.
+        switch (this.roleId) {
+            case GENERATOR:
+                if (component instanceof GeneratorFactory.Instance) {
+                    // Dispose component, if needed
+                    ContainerUtil.dispose(component);
+                    component = ((GeneratorFactory.Instance)component).getFactory();
+                }
+                break;
+            case TRANSFORMER:
+                if (component instanceof TransformerFactory.Instance) {
+                    // Dispose component, if needed
+                    ContainerUtil.dispose(component);
+                    component = ((TransformerFactory.Instance)component).getFactory();
+                }
+                break;
+            case SERIALIZER:
+                if (component instanceof SerializerFactory.Instance) {
+                    // Dispose component, if needed
+                    ContainerUtil.dispose(component);
+                    component = ((SerializerFactory.Instance)component).getFactory();
+                }
+                break;
+        }
+
+        super.release(component);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java
new file mode 100644
index 0000000..47a4291
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ErrorHandlerHelper.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.notification.Notifying;
+import org.apache.cocoon.components.notification.NotifyingBuilder;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Helps to call error handlers from PipelineNode and PipelinesNode.
+ *
+ * @version $Id$
+ */
+public class ErrorHandlerHelper extends AbstractLogEnabled
+                                implements Serviceable {
+
+    private ServiceManager manager;
+
+    /**
+     * Logger for handled errors
+     */
+    protected Logger handledErrorsLogger;
+
+    /**
+     * Error handling node for the ResourceNotFoundException
+     * (deprecated)
+     */
+    private HandleErrorsNode error404;
+
+    /**
+     * Error handling node for all other exceptions
+     */
+    private HandleErrorsNode error500;
+
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.handledErrorsLogger = logger.getChildLogger("handled-errors");
+    }
+
+    /**
+     * The component manager is used to create notifying builders.
+     */
+    public void service(ServiceManager manager) {
+        this.manager = manager;
+    }
+
+    void set404Handler(ProcessingNode node) {
+        this.error404 = (HandleErrorsNode) node;
+    }
+
+    void set500Handler(ProcessingNode node) {
+        this.error500 = (HandleErrorsNode) node;
+    }
+
+    /**
+     * @return true if has no error handler nodes set
+     */
+    public boolean isEmpty() {
+        return this.error404 == null && this.error500 == null;
+    }
+
+    public boolean isInternal() {
+        return this.error500 != null && this.error500.isInternal();
+    }
+
+    public boolean isExternal() {
+        return this.error500 != null && this.error500.isExternal();
+    }
+
+    /**
+     * Handle error.
+     */
+    public boolean invokeErrorHandler(Exception ex,
+                                      Environment env,
+                                      InvokeContext context)
+    throws Exception {
+        final Processor.InternalPipelineDescription desc = prepareErrorHandler(ex, env, context);
+        if ( desc != null ) {
+            desc.release();
+            return true;
+        }
+        return  false;
+    }
+
+    /**
+     * Prepare error handler for the internal pipeline error handling.
+     *
+     * <p>If building pipeline only, error handling pipeline will be
+     * built and returned. If building and executing pipeline,
+     * error handling pipeline will be built and executed.</p>
+     */
+    public Processor.InternalPipelineDescription prepareErrorHandler(Exception ex,
+                                                                     Environment env,
+                                                                     InvokeContext context)
+    throws Exception {
+        boolean internal = !env.isExternal() && !env.isInternalRedirect();
+
+        if (internal && !isInternal()) {
+            // Propagate exception on internal request: No internal handler.
+            throw ex;
+        } else if (!internal && !isExternal()) {
+            // Propagate exception on external request: No external handler.
+            throw ex;
+        } else if (!internal && error404 != null && ex instanceof ResourceNotFoundException) {
+            // Invoke 404-specific handler: Only on external requests. Deprecated.
+            return prepareErrorHandler(error404, ex, env, context);
+        } else if (error500 != null) {
+            // Invoke global handler
+            return prepareErrorHandler(error500, ex, env, context);
+        }
+
+        // Exception was not handled in this error handler, propagate.
+        throw ex;
+    }
+
+    /**
+     * Handle error using specified error handler processing node.
+     */
+    public boolean invokeErrorHandler(ProcessingNode node,
+                                      Exception ex,
+                                      Environment env,
+                                      InvokeContext context)
+    throws Exception {
+        final Processor.InternalPipelineDescription desc = prepareErrorHandler(node, ex, env, context);
+        if ( desc != null ) {
+            desc.release();
+            return true;
+        }
+        return  false;
+    }
+
+    /**
+     * Prepare (or execute) error handler using specified error handler
+     * processing node.
+     *
+     * <p>If building pipeline only, error handling pipeline will be
+     * built and returned. If building and executing pipeline,
+     * error handling pipeline will be built and executed.</p>
+     */
+    private Processor.InternalPipelineDescription prepareErrorHandler(ProcessingNode node,
+                                                                      Exception ex,
+                                                                      Environment env,
+                                                                      InvokeContext context)
+    throws Exception {
+        if (ex instanceof ResourceNotFoundException) {
+            this.handledErrorsLogger.error(ex.getMessage());
+        } else {
+            this.handledErrorsLogger.error(ex.getMessage(), ex);
+        }
+
+        try {
+            prepare(context, env, ex);
+
+            // Create error context
+            InvokeContext errorContext = new InvokeContext(context.isBuildingPipelineOnly());
+            errorContext.enableLogging(getLogger());
+            errorContext.setRedirector(context.getRedirector());
+            errorContext.service(this.manager);
+            errorContext.inform(context.getPipelineType(), context.getPipelineParameters(), env.getObjectModel());
+            try {
+                // Process error handling node
+                if (node.invoke(env, errorContext)) {
+                    // Exception was handled.
+                    return errorContext.getInternalPipelineDescription(env);
+                }
+            } finally {
+                errorContext.dispose();
+            }
+        } catch (Exception e) {
+            getLogger().error("An exception occured while handling errors at " + node.getLocation(), e);
+            // Rethrow it: It will either be handled by the parent sitemap or by the environment (e.g. Cocoon servlet)
+            throw e;
+        }
+
+        // Exception was not handled in this error handler, propagate.
+        throw ex;
+    }
+
+    /**
+     * Build notifying object
+     */
+    private void prepare(InvokeContext context, Environment env, Exception ex)
+    throws IOException, ServiceException {
+        Map objectModel = env.getObjectModel();
+        if (objectModel.get(Constants.NOTIFYING_OBJECT) == null) {
+            // error has not been processed by another handler before
+
+            // Try to reset the response to avoid mixing already produced output
+            // and error page.
+            if (!context.isBuildingPipelineOnly()) {
+                env.tryResetResponse();
+            }
+
+            // Create a Notifying
+            NotifyingBuilder notifyingBuilder = (NotifyingBuilder) this.manager.lookup(NotifyingBuilder.ROLE);
+            Notifying currentNotifying = null;
+            try {
+                currentNotifying = notifyingBuilder.build(this, ex);
+            } finally {
+                this.manager.release(notifyingBuilder);
+            }
+
+            // Add it to the object model
+            objectModel.put(Constants.NOTIFYING_OBJECT, currentNotifying);
+
+            // Also add the exception
+            objectModel.put(ObjectModelHelper.THROWABLE_OBJECT, ex);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java
new file mode 100644
index 0000000..713c803
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNode.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Handler for &lt;map:flow&gt; element in the sitemap.
+ *
+ * @since September 13, 2002
+ * @version $Id$
+ */
+public class FlowNode extends AbstractProcessingNode
+                      implements Serviceable, Disposable {
+
+    private ServiceManager manager;
+    private String language;
+    private Interpreter interpreter;
+    private ServiceSelector interpreterSelector;
+
+    public FlowNode(String language) {
+        this.language = language;
+    }
+
+    /**
+     * Lookup an flow {@link org.apache.cocoon.components.flow.Interpreter}
+     * instance to hold the scripts defined within the <code>&lt;map:flow&gt;</code>
+     * in the sitemap.
+     *
+     * @param manager a <code>ServiceManager</code> value
+     * @exception ServiceException if no flow interpreter could be obtained
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+
+        try {
+            this.interpreterSelector = (ServiceSelector) manager.lookup(Interpreter.ROLE + "Selector");
+            // Obtain the Interpreter instance for this language
+            this.interpreter = (Interpreter) this.interpreterSelector.select(language);
+            // Set interpreter ID as URI of the flow node (full sitemap file path)
+            this.interpreter.setInterpreterID(this.location.getURI());
+        } catch (ServiceException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new ServiceException(language,
+                                       "FlowNode: Couldn't obtain a flow interpreter for '" + language +
+                                       "' at " + getLocation(), e);
+        }
+    }
+
+    /**
+     * This method should never be called by the TreeProcessor, since a
+     * <code>&lt;map:flow&gt;</code> element should not be in an
+     * "executable" sitemap node.
+     *
+     * @param env an <code>Environment</code> value
+     * @param context an <code>InvokeContext</code> value
+     * @return a <code>boolean</code> value
+     * @exception Exception if an error occurs
+     */
+    public boolean invoke(Environment env, InvokeContext context) throws Exception {
+        return true;
+    }
+
+    public Interpreter getInterpreter() {
+        return interpreter;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            if (this.interpreterSelector != null) {
+                this.interpreterSelector.release(this.interpreter);
+                this.interpreter = null;
+
+                this.manager.release(this.interpreterSelector);
+                this.interpreterSelector = null;
+            }
+            this.manager = null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNodeBuilder.java
new file mode 100644
index 0000000..7d7d565
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/FlowNodeBuilder.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+/**
+ * Builder of a {@link FlowNode} instance, corresponding to a
+ * <code>&lt;map:flow&gt;</code> element in the sitemap.
+ *
+ * @since September 13, 2002
+ * @version $Id$
+ */
+public class FlowNodeBuilder extends AbstractParentProcessingNodeBuilder {
+
+    public ProcessingNode buildNode(Configuration config)
+    throws Exception {
+        String language = config.getAttribute("language", "javascript");
+        FlowNode node = new FlowNode(language);
+
+        if ( !this.treeBuilder.registerNode("flow", node) ) {
+            throw new ConfigurationException("Only one <map:flow> is allowed in a sitemap. Another one is declared at " +
+                    config.getLocation());
+        }
+        this.treeBuilder.setupNode(node, config);
+
+        buildChildNodesList(config);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNode.java
new file mode 100644
index 0000000..7fdf85c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNode.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.PipelineEventComponentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+/**
+ *
+ * @version $Id$
+ */
+public class GenerateNode extends PipelineEventComponentProcessingNode implements ParameterizableProcessingNode {
+
+    private String generatorName;
+
+    private VariableResolver source;
+
+    private Map parameters;
+
+
+    public GenerateNode(String name, VariableResolver source) {
+        this.generatorName = name;
+        this.source = source;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+        final Map objectModel = env.getObjectModel();
+        
+        SitemapExecutor.PipelineComponentDescription desc = new SitemapExecutor.PipelineComponentDescription();
+        desc.type = this.generatorName;
+        desc.source = source.resolve(context, objectModel);
+        desc.parameters = VariableResolver.buildParameters(this.parameters, context, objectModel);
+        desc.hintParameters = this.pipelineHints == null
+                ? Parameters.EMPTY_PARAMETERS
+                : VariableResolver.buildParameters(this.pipelineHints, context, objectModel);
+        
+        desc = this.executor.addGenerator(this, objectModel, desc);
+        
+        context.getProcessingPipeline().setGenerator(
+            desc.type,
+            desc.source,
+            desc.parameters,
+            desc.hintParameters
+        );
+
+
+        // Check view
+        if (this.views != null) {
+	 
+            //inform the pipeline that we have a branch point
+            context.getProcessingPipeline().informBranchPoint();
+
+            String cocoonView = env.getView();
+            if (cocoonView != null) {
+
+                // Get view node
+                ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
+
+                if (viewNode != null) {
+                    if (getLogger().isInfoEnabled()) {
+                        getLogger().info("Jumping to view " + cocoonView + " from generator at " + this.getLocation());
+                    }
+                    return viewNode.invoke(env, context);
+                }
+            }
+        }
+
+        // Return false to continue sitemap invocation
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNodeBuilder.java
new file mode 100644
index 0000000..37f3c60
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/GenerateNodeBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.generation.Generator;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public class GenerateNodeBuilder extends AbstractProcessingNodeBuilder
+  implements LinkedProcessingNodeBuilder {
+
+    private GenerateNode node;
+
+    private Collection views;
+    private Map  pipelineHints;
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String type = this.treeBuilder.getTypeForStatement(config, Generator.ROLE);
+
+        this.views = ((SitemapLanguage)this.treeBuilder).getViewsForStatement(Generator.ROLE, type, config);
+        this.pipelineHints = ((SitemapLanguage)this.treeBuilder).getHintsForStatement(Generator.ROLE, type, config);
+
+        this.node = new GenerateNode(
+            type,
+            VariableResolverFactory.getResolver(config.getAttribute("src", null), this.manager)
+        );
+        this.node.setPipelineHints(this.pipelineHints);
+        return this.treeBuilder.setupNode(this.node, config);
+    }
+
+    public void linkNode() throws Exception {
+        this.node.setViews(
+            ((SitemapLanguage)this.treeBuilder).getViewNodes(this.views)
+        );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNode.java
new file mode 100644
index 0000000..9df21c8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNode.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.environment.Environment;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * Handles &lt;map:handle-errors&gt;
+ *
+ * @version $Id$
+ */
+public final class HandleErrorsNode extends AbstractParentProcessingNode {
+
+    private ProcessingNode[] children;
+    private int statusCode;
+    private boolean internal;
+    private boolean external;
+
+    /**
+     * @param statusCode Value of the type attribute: 404 (deprecated), 500 (deprecated), or -1 (no attribute present).
+     * @param scope Value of the error handler scope attribute: external, internal, always.
+     */
+    public HandleErrorsNode(int statusCode, String scope)
+    throws ConfigurationException {
+        this.statusCode = statusCode;
+        if ("internal".equals(scope)) {
+            this.internal = true;
+        } else if ("external".equals(scope)) {
+            this.external = true;
+        } else if ("always".equals(scope)) {
+            this.internal = true;
+            this.external = true;
+        } else {
+            throw new ConfigurationException("Unrecognized value of when attribute on <handle-errors> at " +
+                                             getLocation());
+        }
+    }
+
+    public int getStatusCode() {
+        return this.statusCode;
+    }
+
+    public boolean isInternal() {
+        return this.internal;
+    }
+
+    public boolean isExternal() {
+        return this.external;
+    }
+
+    public void setChildren(ProcessingNode[] nodes) {
+        this.children = nodes;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+        if (getLogger().isInfoEnabled()) {
+            getLogger().info("Processing handle-errors at " + getLocation());
+        }
+
+		if (statusCode == -1) {
+            // No 'type' attribute : new Cocoon 2.1 behaviour, no implicit generator
+            try {
+                return invokeNodes(this.children, env, context);
+
+            } catch (ProcessingException e) {
+                // Handle the various cases related to the transition from implicit generators in handle-errors to
+                // explicit ones, in order to provide meaningful messages that will ease the migration
+                if (e.getMessage().indexOf("Must set a generator before adding") != -1) {
+
+                    env.getObjectModel().remove(Constants.NOTIFYING_OBJECT);
+                    throw new ProcessingException(
+                        "Incomplete pipeline: 'handle-error' without a 'type' must include a generator, at " +
+                        getLocation() + SystemUtils.LINE_SEPARATOR +
+                        "Either add a generator (preferred) or a type='500' attribute (deprecated) on 'handle-errors'");
+                }
+
+                // Rethrow the exception
+                throw e;
+            }
+		}
+	    // A 'type' attribute is present : add the implicit generator
+        context.getProcessingPipeline().setGenerator("<notifier>", "", Parameters.EMPTY_PARAMETERS, Parameters.EMPTY_PARAMETERS);
+
+        try {
+            return invokeNodes(this.children, env, context);
+        } catch (ProcessingException e) {
+            if (e.getMessage().indexOf("Generator already set") != -1){
+
+                env.getObjectModel().remove(Constants.NOTIFYING_OBJECT);
+                throw new ProcessingException(
+                        "Error: 'handle-error' with a 'type' attribute has an implicit generator, at " +
+                        getLocation() + SystemUtils.LINE_SEPARATOR +
+                        "Please remove the 'type' attribute on 'handle-error'");
+            }
+            // Rethrow the exception
+            throw e;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNodeBuilder.java
new file mode 100644
index 0000000..3f3b3b0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/HandleErrorsNodeBuilder.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+/**
+ * Builds a &lt;map:handle-errors&gt;
+ *
+ * @version $Id$
+ */
+public class HandleErrorsNodeBuilder extends AbstractParentProcessingNodeBuilder
+                                     implements ThreadSafe {
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        HandleErrorsNode node = new HandleErrorsNode(config.getAttributeAsInteger("type", -1),
+                                                     config.getAttribute("when", "external"));
+        this.treeBuilder.setupNode(node, config);
+
+        // Set a flag that will prevent redirects
+        ((SitemapLanguage) this.treeBuilder).setBuildingErrorHandler(true);
+        try {
+            // Get all children
+            node.setChildren(buildChildNodes(config));
+        } finally {
+            // And clear the flag
+            ((SitemapLanguage) this.treeBuilder).setBuildingErrorHandler(false);
+        }
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNode.java
new file mode 100644
index 0000000..0377745
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNode.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.matching.Matcher;
+
+/**
+ *
+ * @version $Id$
+ */
+public class MatchNode extends SimpleSelectorProcessingNode
+        implements ParameterizableProcessingNode {
+
+    /** The 'pattern' attribute */
+    private VariableResolver pattern;
+
+    /** The 'name' for the variable anchor */
+    private String name;
+
+    private Map parameters;
+
+    public MatchNode(String type, VariableResolver pattern, String name) {
+        super(Matcher.ROLE + "Selector", type);
+        this.pattern = pattern;
+        this.name = name;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+      throws Exception {
+	
+        // Perform any common invoke functionality 
+        super.invoke(env, context);
+
+        Map objectModel = env.getObjectModel();
+
+        String resolvedPattern = pattern.resolve(context, objectModel);
+        Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel);
+
+        Map result = null;
+
+        Matcher matcher = (Matcher)getComponent();
+        try {
+            result = this.executor.invokeMatcher(this, 
+                    objectModel, 
+                    matcher, 
+                    resolvedPattern, 
+                    resolvedParams);
+        } finally {
+            releaseComponent(matcher);
+        }
+
+        if (result != null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Matcher '" + this.componentName + "' matched pattern '" + this.pattern +
+                    "' at " + this.getLocation());
+            }
+
+            // Invoke children with the matcher results
+            return this.invokeNodes(children, env, context, name, result);
+        }
+        // Matcher failed
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNodeBuilder.java
new file mode 100644
index 0000000..930bf5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MatchNodeBuilder.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.matching.PreparableMatcher;
+
+/**
+ *
+ * @version $Id$
+ */
+public class MatchNodeBuilder extends AbstractParentProcessingNodeBuilder
+  implements ThreadSafe {
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String pattern = config.getAttribute("pattern", null);
+        String name = config.getAttribute("name", null);
+
+        String type = this.treeBuilder.getTypeForStatement(config, Matcher.ROLE);
+
+        // Get the type and class for this matcher
+        ServiceSelector selector = (ServiceSelector)this.manager.lookup(Matcher.ROLE + "Selector");
+
+        Class clazz = null;
+        try {
+            // Find matcher class
+            Matcher matcher = (Matcher)selector.select(type);
+            clazz = matcher.getClass();
+            selector.release(matcher);
+        } finally {
+            this.manager.release(selector);
+        }
+
+        // PreparableMatcher are only prepared if pattern doesn't need request-time resolution.
+        boolean preparable =
+            PreparableMatcher.class.isAssignableFrom(clazz) &&
+            !VariableResolverFactory.needsResolve(pattern);
+
+        // Instanciate appropriate node
+        SimpleSelectorProcessingNode node;
+        VariableResolver patternResolver = VariableResolverFactory.getResolver(pattern, this.manager);
+
+        if (preparable) {
+            node = new PreparableMatchNode(type, VariableResolverFactory.unescape(pattern),name);
+        } else {
+            node = new MatchNode(type, patternResolver,name);
+        }
+
+        this.treeBuilder.setupNode(node, config);
+
+        // Get all children
+        ProcessingNode[] children = buildChildNodes(config);
+
+        node.setChildren(children);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
new file mode 100644
index 0000000..a28e218
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNode.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.TreeProcessor;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.commons.lang.BooleanUtils;
+
+/**
+ *
+ * @version $Id$
+ */
+public class MountNode extends AbstractProcessingNode
+                       implements Disposable {
+
+    /** The key to get the pass_through value from the Environment*/
+    public final static String COCOON_PASS_THROUGH = "COCOON_PASS_THROUGH";
+
+
+    /** The 'uri-prefix' attribute */
+    private final VariableResolver prefix;
+
+    /** The 'src' attribute */
+    private final VariableResolver source;
+
+    /** Processors for sources */
+    private Map processors = new HashMap();
+
+    /** The processor for this node */
+    private final TreeProcessor parentProcessor;
+
+    /** The value of the 'check-reload' attribute */
+    private final boolean checkReload;
+
+    /** The value of the 'pass-through' attribute */
+    private final Boolean passThrough;
+
+    public MountNode(VariableResolver prefix,
+                     VariableResolver source,
+                     TreeProcessor parentProcessor,
+                     boolean checkReload,
+                     boolean passThrough) {
+        this.prefix = prefix;
+        this.source = source;
+        this.parentProcessor = parentProcessor;
+        this.checkReload = checkReload;
+        this.passThrough = BooleanUtils.toBooleanObject(passThrough);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+        final Map objectModel = env.getObjectModel();
+
+        String resolvedSource = this.source.resolve(context, objectModel);
+        String resolvedPrefix = this.prefix.resolve(context, objectModel);
+
+        if (resolvedSource.length() == 0) {
+            throw new ProcessingException("Source of mount statement is empty");
+        }
+        // Handle directory mounts
+        if (resolvedSource.charAt(resolvedSource.length() - 1) == '/') {
+            resolvedSource = resolvedSource + "sitemap.xmap";
+        }
+
+        TreeProcessor processor = getProcessor(resolvedSource, resolvedPrefix);
+
+        // Save context
+        String oldPrefix = env.getURIPrefix();
+        String oldURI    = env.getURI();
+        Object oldPassThrough = env.getAttribute(COCOON_PASS_THROUGH);
+        env.setAttribute(COCOON_PASS_THROUGH, this.passThrough);
+
+        try {
+            processor.getEnvironmentHelper().changeContext(env);
+
+            if (context.isBuildingPipelineOnly()) {
+                // Propagate pipelines
+                Processor.InternalPipelineDescription pp = processor.buildPipeline(env);
+                if (pp != null) {
+                    context.setInternalPipelineDescription(pp);
+                    return true;
+                }
+                return false;
+            }
+            // Processor will create its own pipelines
+            return processor.process(env);
+        } catch(Exception e) {
+            // Wrap with our location
+            throw ProcessingException.throwLocated("Sitemap: error when calling sub-sitemap", e, getLocation());
+
+        } finally {
+            // Restore context
+            env.setURI(oldPrefix, oldURI);
+            if (oldPassThrough != null) {
+                env.setAttribute(COCOON_PASS_THROUGH, oldPassThrough);
+            } else {
+                env.removeAttribute(COCOON_PASS_THROUGH);
+            }
+
+            // Turning recomposing as a test, according to:
+            // http://marc.theaimsgroup.com/?t=106802211400005&r=1&w=2
+            // Recompose pipelines which may have been recomposed by subsitemap
+            // context.recompose(this.manager);
+        }
+    }
+
+    private synchronized TreeProcessor getProcessor(String source, String prefix)
+    throws Exception {
+
+        TreeProcessor processor = (TreeProcessor) processors.get(source);
+        if (processor == null) {
+
+            processor = this.parentProcessor.createChildProcessor(source, this.checkReload, prefix);
+
+            // Associate to the original source
+            processors.put(source, processor);
+        }
+
+        return processor;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        Iterator i = this.processors.values().iterator();
+        while (i.hasNext()) {
+            ((TreeProcessor) i.next()).dispose();
+        }
+        this.processors.clear();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNodeBuilder.java
new file mode 100644
index 0000000..ad8701c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/MountNodeBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.core.Core;
+
+/**
+ *
+ * @version $Id$
+ */
+public class MountNodeBuilder
+    extends AbstractProcessingNodeBuilder
+    implements ThreadSafe {
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        final Core core = (Core)manager.lookup(Core.ROLE);
+        MountNode node = new MountNode(
+            VariableResolverFactory.getResolver(config.getAttribute("uri-prefix"), manager),
+            VariableResolverFactory.getResolver(config.getAttribute("src"), manager),
+            this.treeBuilder.getProcessor().getWrappingProcessor(),
+            config.getAttributeAsBoolean("check-reload", core.getSettings().isReloadingEnabled("sitemap")),
+            config.getAttributeAsBoolean("pass-through", false)
+        );
+  
+        return (this.treeBuilder.setupNode(node, config));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNode.java
new file mode 100644
index 0000000..47b97fb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNode.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ConnectionResetException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.SitemapErrorHandler;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+import java.util.Map;
+
+/**
+ * Handles &lt;map:pipeline&gt;
+ *
+ * @version $Id$
+ */
+public class PipelineNode extends AbstractParentProcessingNode
+                          implements Serviceable, ParameterizableProcessingNode {
+
+    // TODO: handle a 'fail-hard' environment attribute
+    //       can be useful to stop off-line generation when there's an error
+
+    private ProcessingNode[] children;
+
+    private ErrorHandlerHelper errorHandlerHelper;
+
+    private boolean internalOnly;
+
+    /** Is it the last <pipeline> in the enclosing <pipelines> ? */
+    private boolean isLast;
+
+    /** The component name of the processing pipeline */
+    protected String processingPipeline;
+
+    /** Optional sitemap parameters */
+    protected Map parameters;
+
+    /**
+     * A constructor to receive the optional expires parameter
+     * and optional parameters for the processing pipeline
+     */
+    public PipelineNode(String name) {
+        this.processingPipeline = name;
+        this.errorHandlerHelper = new ErrorHandlerHelper();
+    }
+
+    /**
+     * The component manager is used to create error pipelines
+     */
+    public void service(ServiceManager manager) {
+        this.errorHandlerHelper.service(manager);
+    }
+
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.errorHandlerHelper.enableLogging(logger);
+    }
+
+    public void setChildren(ProcessingNode[] nodes) {
+        this.children = nodes;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setLast(boolean isLast) {
+        this.isLast = isLast;
+    }
+
+    public void set404Handler(ProcessingNode node) {
+        this.errorHandlerHelper.set404Handler(node);
+    }
+
+    public void set500Handler(ProcessingNode node) {
+        this.errorHandlerHelper.set500Handler(node);
+    }
+
+    public void setInternalOnly(boolean internalOnly) {
+        this.internalOnly = internalOnly;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+        boolean passThrough;
+        Object passThroughRaw = env.getAttribute(MountNode.COCOON_PASS_THROUGH);
+        if (passThroughRaw == null) {
+            // Use default value
+            passThrough = false;
+        } else {
+            passThrough = ((Boolean) passThroughRaw).booleanValue();
+        }
+
+        // Always fail on external request if pipeline is internal only.
+        if (this.internalOnly && env.isExternal()) {
+            if (!this.isLast || passThrough) {
+                return false;
+            }
+
+            // Do not use internal-only pipeline error handler for external requests.
+            throw new ResourceNotFoundException("No pipeline matched request: " +
+                                                env.getURIPrefix() + env.getURI());
+        }
+
+        Parameters params = VariableResolver.buildParameters(this.parameters,
+                context,
+                env.getObjectModel());
+
+        SitemapExecutor.PipelineComponentDescription desc = new SitemapExecutor.PipelineComponentDescription();
+        desc.type = this.processingPipeline;
+        desc.parameters = params;
+
+        desc = this.executor.enteringPipeline(this, env.getObjectModel(), desc);
+        context.inform(desc.type, desc.parameters, env.getObjectModel());
+
+        try {
+            if (this.errorHandlerHelper.isInternal()) {
+                // Set internal error handler in the pipeline
+                context.setErrorHandler(
+                        new SitemapErrorHandler(this.errorHandlerHelper, env, context));
+            } else {
+                // Reset internal error handler (previous pipeline might had set it) 
+                context.setErrorHandler(null);
+            }
+
+            if (invokeNodes(children, env, context)) {
+                return true;
+            } else if (!this.isLast || passThrough) {
+                return false;
+            }
+
+            throw new ResourceNotFoundException("No pipeline matched request: " +
+                                                env.getURIPrefix() + env.getURI());
+
+        } catch (ConnectionResetException e) {
+            // Will be reported by CocoonServlet, rethrowing
+            throw e;
+        } catch (Exception e) {
+            // Invoke error handler
+            return this.errorHandlerHelper.invokeErrorHandler(e, env, context);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNodeBuilder.java
new file mode 100644
index 0000000..25e694a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelineNodeBuilder.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
+
+/**
+ * Builds a &lt;map:pipeline&gt;
+ *
+ * @version $Id$
+ */
+public class PipelineNodeBuilder extends AbstractParentProcessingNodeBuilder
+                                 implements ThreadSafe {
+
+    /** This builder can have parameters -- return <code>true</code> */
+    protected boolean hasParameters() {
+        return true;
+    }
+
+    public ProcessingNode buildNode(Configuration config)
+    throws Exception {
+        String type = this.treeBuilder.getTypeForStatement(config, ProcessingPipeline.ROLE);
+        PipelineNode node = new PipelineNode(type);
+
+        this.treeBuilder.setupNode(node, config);
+        node.setInternalOnly(config.getAttributeAsBoolean("internal-only", false));
+
+        // Main (with no "type" attribute) error handler: new in Cocoon 2.1, must have a generator
+        ProcessingNode mainHandler = null;
+
+        // 404 & 500 error handlers as in Cocoon 2.0.x, have an implicit generator
+        ProcessingNode error404Handler = null;
+        ProcessingNode error500Handler = null;
+
+        Configuration[] childConfigs = config.getChildren();
+        List children = new ArrayList();
+        for (int i = 0; i < childConfigs.length; i++) {
+            Configuration childConfig = childConfigs[i];
+            if (isChild(childConfig)) {
+
+                ProcessingNodeBuilder builder = this.treeBuilder.createNodeBuilder(childConfig);
+                if (builder instanceof HandleErrorsNodeBuilder) {
+                    // Error handler : check type
+                    HandleErrorsNode handler = (HandleErrorsNode)builder.buildNode(childConfig);
+                    int status = handler.getStatusCode();
+
+                    switch(status) {
+                        case -1: // main handler (needs generator)
+                            if (mainHandler != null) {
+                                throw new ConfigurationException("Duplicate <handle-errors> at " + handler.getLocation());
+                            } else if (error500Handler != null || error404Handler != null) {
+                                throw new ConfigurationException("Cannot mix <handle-errors> with and without 'type' attribute at " +
+                                                                 handler.getLocation());
+                            } else {
+                                mainHandler = handler;
+                            }
+                            break;
+
+                        case 404:
+                            if (error404Handler != null) {
+                                throw new ConfigurationException("Duplicate <handle-errors type='404' at " + handler.getLocation());
+                            } else if(mainHandler != null) {
+                                throw new ConfigurationException("Cannot mix <handle-errors> with and without 'type' attribute at " +
+                                                                 handler.getLocation());
+                            } else {
+                                error404Handler = handler;
+                            }
+                            break;
+
+                        case 500:
+                            if (error500Handler != null) {
+                                throw new ConfigurationException("Duplicate <handle-errors type='500' at " + handler.getLocation());
+                            } else if (mainHandler != null) {
+                                throw new ConfigurationException("Cannot mix <handle-errors> with and without 'type' attribute at " +
+                                                                 handler.getLocation());
+                            } else {
+                                error500Handler = handler;
+                            }
+                            break;
+
+                        default:
+                            throw new ConfigurationException("Unknown handle-errors type (" + type + ") at " + handler.getLocation());
+                    }
+                } else {
+                    // Regular builder
+                    children.add(builder.buildNode(childConfig));
+                }
+            }
+        }
+
+        node.setChildren(toNodeArray(children));
+        node.set404Handler(error404Handler);
+        // Set either main or error500 handler as only one can exist
+        node.set500Handler(error500Handler == null ? mainHandler : error500Handler);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNode.java
new file mode 100644
index 0000000..976b6b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNode.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ConnectionResetException;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleParentProcessingNode;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Handles &lt;map:pipelines&gt;
+ *
+ * @version $Id$
+ */
+public final class PipelinesNode extends SimpleParentProcessingNode
+                                 implements Serviceable, Disposable {
+
+    private ServiceManager manager;
+
+    private ErrorHandlerHelper errorHandlerHelper;
+
+    /**
+     * Constructor
+     */
+    public PipelinesNode() {
+        super(null);
+        this.errorHandlerHelper = new ErrorHandlerHelper();
+    }
+
+    /**
+     * Keep the component manager used everywhere in the tree so that we can
+     * cleanly dispose it.
+     */
+    public void service(ServiceManager manager) {
+        this.manager = manager;
+        this.errorHandlerHelper.service(manager);
+    }
+
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.errorHandlerHelper.enableLogging(logger);
+    }
+
+    public void setErrorHandler(ProcessingNode node) {
+        this.errorHandlerHelper.set500Handler(node);
+    }
+
+    public void setChildren(ProcessingNode[] nodes) {
+        // Mark the last pipeline so that it can throw a ResourceNotFoundException
+        ((PipelineNode) nodes[nodes.length - 1]).setLast(true);
+        super.setChildren(nodes);
+    }
+
+    /**
+     * Process the environment. Also adds a <code>SourceResolver</code>
+     * and a <code>Redirector</code> in the object model. The previous resolver and
+     * redirector, if any, are restored before return.
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+        // Perform any common invoke functionality
+        super.invoke(env, context);
+
+        // Recompose context (and pipelines) to the local component manager
+        context.service(this.manager);
+
+        try {
+            // FIXME: Is there any useful information that can be passed as top-level parameters,
+            //        such as the URI of the mount point ?
+
+            return invokeNodes(this.children, env, context);
+
+        } catch (ConnectionResetException e) {
+            // Will be reported by CocoonServlet, rethrowing
+            throw e;
+        } catch (Exception ex) {
+            // Invoke pipelines handler
+            return this.errorHandlerHelper.invokeErrorHandler(ex, env, context);
+        }
+    }
+
+    /**
+     * Dispose the component manager.
+     */
+    public void dispose() {
+        if (this.manager instanceof Disposable) {
+            ((Disposable) this.manager).dispose();
+        }
+        this.manager = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNodeBuilder.java
new file mode 100644
index 0000000..5022e9c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PipelinesNodeBuilder.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.treeprocessor.ContainerNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builds a &lt;map:pipelines&gt;
+ *
+ * @version $Id$
+ */
+public class PipelinesNodeBuilder extends ContainerNodeBuilder implements ThreadSafe {
+
+    public ProcessingNode buildNode(Configuration config)
+    throws Exception {
+        // Check for component configurations
+        Configuration child = config.getChild("component-configurations", false);
+        if (child != null) {
+            checkNamespace(child);
+            this.treeBuilder.getProcessor().setComponentConfigurations(child);
+        }
+
+        PipelinesNode node = new PipelinesNode();
+        this.treeBuilder.setupNode(node, config);
+
+        Configuration[] childConfigs = config.getChildren();
+        List children = new ArrayList();
+        HandleErrorsNode handler = null;
+
+        for (int i = 0; i < childConfigs.length; i++) {
+            Configuration childConfig = childConfigs[i];
+            if (isChild(childConfig)) {
+
+                ProcessingNodeBuilder builder = this.treeBuilder.createNodeBuilder(childConfig);
+                if (builder instanceof HandleErrorsNodeBuilder) {
+                    handler = (HandleErrorsNode)builder.buildNode(childConfig);
+                } else {
+                    // Regular builder
+                    children.add(builder.buildNode(childConfig));
+                }
+            }
+        }
+
+        if (children.size() == 0) {
+            String msg = "There must be at least one pipeline at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        node.setChildren(toNodeArray(children));
+        node.setErrorHandler(handler);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PreparableMatchNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PreparableMatchNode.java
new file mode 100644
index 0000000..f90cc15
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/PreparableMatchNode.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.matching.PreparableMatcher;
+import org.apache.cocoon.sitemap.PatternException;
+
+/**
+ *
+ * @version $Id$
+ */
+public class PreparableMatchNode extends SimpleSelectorProcessingNode
+    implements ParameterizableProcessingNode, Initializable {
+
+    /** The 'pattern' attribute */
+    private String pattern;
+
+    /** The 'name' for the variable anchor */
+    private String name;
+
+    private Object preparedPattern;
+
+    private Map parameters;
+
+    public PreparableMatchNode(String type, String pattern, String name) {
+        super(Matcher.ROLE + "Selector", type);
+        this.pattern = pattern;
+        this.name = name;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode#setParameters(java.util.Map)
+     */
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+
+        // Prepare the pattern
+        PreparableMatcher matcher = (PreparableMatcher)getComponent();
+
+        try {
+            this.preparedPattern = matcher.preparePattern(this.pattern);
+        } catch(PatternException pe) {
+            String msg = "Invalid pattern '" + this.pattern + "' for matcher at " + this.getLocation();
+            throw new ConfigurationException(msg, pe);
+        } finally {
+            releaseComponent(matcher);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+      	// Perform any common invoke functionality
+      	super.invoke(env, context);
+
+        Map objectModel = env.getObjectModel();
+        Parameters resolvedParams = VariableResolver.buildParameters(
+            this.parameters, context, objectModel
+        );
+
+        Map result = null;
+
+        PreparableMatcher matcher = (PreparableMatcher)getComponent();
+        try {
+            result = this.executor.invokePreparableMatcher(this,
+                                                           objectModel,
+                                                           matcher,
+                                                           this.pattern,
+                                                           preparedPattern,
+                                                           resolvedParams);
+        } finally {
+            releaseComponent(matcher);
+        }
+
+        if (result != null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Matcher '" + this.componentName + "' matched prepared pattern '" +
+                                  this.pattern + "' at " + this.getLocation());
+            }
+
+            // Invoke children with the matcher results
+            return this.invokeNodes(children, env, context, name, result);
+
+        }
+        // Matcher failed
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNode.java
new file mode 100644
index 0000000..906d931
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNode.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ReadNode extends AbstractProcessingNode implements ParameterizableProcessingNode {
+
+    private String readerName;
+
+    private VariableResolver source;
+
+    private VariableResolver mimeType;
+
+    private int statusCode;
+
+    private Map parameters;
+
+    /**
+     * Build a <code>SerializerNode</code> having a name, a mime-type and a status code (HTTP codes).
+     *
+     * @param name the name of the serializer to use.
+     * @param mimeType the mime-type, or <code>null</code> not specified.
+     * @param statusCode the HTTP response status code, or <code>-1</code> if not specified.
+     */
+    public ReadNode(String name, VariableResolver source, VariableResolver mimeType, int statusCode) {
+        this.readerName = name;
+        this.source = source;
+        this.mimeType = mimeType;
+        this.statusCode = statusCode;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env,  InvokeContext context)
+    throws Exception {
+
+        final Map objectModel = env.getObjectModel();
+
+        final ProcessingPipeline pipeline = context.getProcessingPipeline();
+
+        SitemapExecutor.PipelineComponentDescription desc = new SitemapExecutor.PipelineComponentDescription();
+        desc.type = this.readerName;
+        desc.source = source.resolve(context, objectModel);
+        desc.parameters = VariableResolver.buildParameters(this.parameters, context, objectModel);
+        desc.mimeType = this.mimeType.resolve(context, objectModel);
+        
+        desc = this.executor.addReader(this, objectModel, desc);
+
+        pipeline.setReader(
+            desc.type,
+            desc.source,
+            desc.parameters,
+            desc.mimeType
+        );
+
+        // Set status code if there is one
+        if (this.statusCode >= 0) {
+            env.setStatus(this.statusCode);
+        }
+
+        if (! context.isBuildingPipelineOnly()) {
+            // Process pipeline
+            return pipeline.process(env);
+
+        }
+        // Return true : pipeline is finished.
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java
new file mode 100644
index 0000000..6828530
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ReadNodeBuilder.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.reading.Reader;
+
+/**
+ *
+ * @version $Id$
+ */
+public class ReadNodeBuilder extends AbstractProcessingNodeBuilder implements ThreadSafe {
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String type = this.treeBuilder.getTypeForStatement(config, Reader.ROLE);
+        
+        String mimeType = config.getAttribute("mime-type", null);
+        if (mimeType == null) {
+            mimeType = ((SitemapLanguage)this.treeBuilder).getMimeType(Reader.ROLE, type);
+        }
+
+        ReadNode node = new ReadNode(
+            type,
+            VariableResolverFactory.getResolver(config.getAttribute("src", null), this.manager),
+            VariableResolverFactory.getResolver(mimeType, this.manager),
+            config.getAttributeAsInteger("status-code", -1)
+        );
+
+        return this.treeBuilder.setupNode(node, config);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToNodeBuilder.java
new file mode 100644
index 0000000..614d1dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToNodeBuilder.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.CategoryNode;
+import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public class RedirectToNodeBuilder extends AbstractProcessingNodeBuilder
+  implements LinkedProcessingNodeBuilder {
+
+    private CallNode callNode;
+    private String resourceName;
+
+    /** This builder has no parameters -- return <code>false</code> */
+    protected boolean hasParameters() {
+        return false;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        
+		if (((SitemapLanguage)this.treeBuilder).isBuildingErrorHandler()) {
+			throw new ConfigurationException("'map:redirect' is forbidden inside a 'map:handle-errors', at "
+			+ config.getLocation());
+		}
+		
+        // Is it a redirect to resource ?
+        this.resourceName = config.getAttribute("resource", null);
+        if (this.resourceName != null) {
+            
+            getLogger().warn("Redirect to resource is deprecated. Use map:call instead at " +
+                config.getLocation());
+
+            this.callNode = new CallNode();
+            this.treeBuilder.setupNode(this.callNode, config);
+
+            String target = config.getAttribute("target", null);
+            if (target != null) {
+                Map params = new HashMap(1);
+                params.put("target", VariableResolverFactory.getResolver(target, this.manager));
+                this.callNode.setParameters(params);
+            }
+            return this.callNode;
+            
+        }
+        ProcessingNode URINode = new RedirectToURINode(
+            VariableResolverFactory.getResolver(config.getAttribute("uri"), this.manager),
+            config.getAttributeAsBoolean("session", false),
+            config.getAttributeAsBoolean("global", false),
+            config.getAttributeAsBoolean("permanent", false)
+        );
+        return this.treeBuilder.setupNode(URINode, config);
+    }
+
+    public void linkNode() throws Exception {
+
+        if (this.callNode != null) {
+            CategoryNode resources = CategoryNodeBuilder.getCategoryNode(this.treeBuilder, "resources");
+
+            if (resources == null) {
+                String msg = "This sitemap contains no resources. Cannot redirect at " +
+                    this.callNode.getLocation();
+                throw new ConfigurationException(msg);
+            }
+
+            this.callNode.setResource(
+                resources,
+                VariableResolverFactory.getResolver(this.resourceName, this.manager)
+            );
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToURINode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToURINode.java
new file mode 100644
index 0000000..c10b9bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/RedirectToURINode.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.PermanentRedirector;
+
+/**
+ *
+ * @version $Id$
+ */
+public class RedirectToURINode extends AbstractProcessingNode {
+
+    // TODO: It can implement ParameterizableProcessingNode to pass redirect parameters
+    //       Those parameters will be URL-encoded and appended to the redirect URI
+    
+    /** The 'uri' attribute */
+    private VariableResolver uri;
+
+    private boolean createSession;
+
+    private boolean global;
+
+    private boolean permanent;
+
+    public RedirectToURINode(VariableResolver uri, 
+                             boolean createSession, 
+                             boolean global, 
+                             boolean permanent ) {
+        this.global = global;
+        this.uri = uri;
+        this.createSession = createSession;
+        this.permanent = permanent;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+      throws Exception {
+        String resolvedURI = uri.resolve(context, env.getObjectModel());
+
+        if (getLogger().isInfoEnabled()) {
+            getLogger().info("Redirecting to '" + resolvedURI + "' at " + this.getLocation());
+        }
+
+        resolvedURI = this.executor.redirectTo(this,
+                                               env.getObjectModel(),
+                                               resolvedURI,
+                                               this.createSession,
+                                               this.global,
+                                               this.permanent);
+        final Redirector redirector = context.getRedirector();
+
+        if( this.global ) {
+            redirector.globalRedirect(this.createSession, resolvedURI);
+        } else if (this.permanent && redirector instanceof PermanentRedirector) {
+            ((PermanentRedirector)redirector).permanentRedirect(this.createSession, resolvedURI);
+        } else {
+            redirector.redirect(this.createSession, resolvedURI);
+        }
+
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNode.java
new file mode 100644
index 0000000..b73bd8d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNode.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.cocoon.components.flow.AbstractInterpreter;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNode;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Handler for &lt;map:script&gt; elements in the sitemap. It registers the 
+ *
+ * @since March 13, 2002
+ * @version $Id$
+ */
+public class ScriptNode extends AbstractProcessingNode
+{
+  String source;
+
+  public ScriptNode(String source)
+  {
+    this.source = source;
+  }
+  
+  /**
+   * This method should never be called by the TreeProcessor, since a
+   * <map:script> element should not be in an "executable" sitemap
+   * node.
+   *
+   * @param env an <code>Environment</code> value
+   * @param context an <code>InvokeContext</code> value
+   * @return a <code>boolean</code> value
+   * @exception Exception if an error occurs
+   */
+  public boolean invoke(Environment env, InvokeContext context)
+    throws Exception
+  {
+    return true;
+  }
+
+  public void registerScriptWithInterpreter(Interpreter interpreter)
+  {
+    if (interpreter instanceof AbstractInterpreter)
+      ((AbstractInterpreter)interpreter).register(source);
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNodeBuilder.java
new file mode 100644
index 0000000..e4a0ed5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ScriptNodeBuilder.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.flow.Interpreter;
+
+/**
+ * Builder class for creating a {@link ScriptNode} instance
+ * corresponding to a &lt;map:script&gt; element in the sitemap.
+ *
+ * @since March 13, 2002
+ * @version $Id$
+ */
+public class ScriptNodeBuilder
+  extends AbstractProcessingNodeBuilder
+  implements LinkedProcessingNodeBuilder
+{
+  protected ScriptNode node;
+
+  public ProcessingNode buildNode(Configuration config)
+    throws Exception
+  {
+    String source = config.getAttribute("src");
+
+    this.node = new ScriptNode(source);
+    this.treeBuilder.setupNode(this.node, config);
+
+    return this.node;
+  }
+
+  /**
+   * Call the built node to register the script it contains with the
+   * flow interpreter.
+   */
+  public void linkNode()
+    throws Exception
+  {
+    FlowNode flowNode = (FlowNode)this.treeBuilder.getRegisteredNode("flow");
+    Interpreter interpreter = flowNode.getInterpreter();
+
+    this.node.registerScriptWithInterpreter(interpreter);
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNode.java
new file mode 100644
index 0000000..3eed828
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNode.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.selection.Selector;
+
+/**
+ *
+ * @version $Id$
+ */
+public class SelectNode extends SimpleSelectorProcessingNode
+    implements ParameterizableProcessingNode {
+
+    /** The parameters of this node */
+    private Map parameters;
+
+    private ProcessingNode[][] whenNodes;
+
+    private VariableResolver[] whenTests;
+
+    private ProcessingNode[] otherwhiseNodes;
+
+    public SelectNode(String name) {
+        super(Selector.ROLE + "Selector", name);
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setCases(ProcessingNode[][] whenNodes, VariableResolver[] whenTests, ProcessingNode[] otherwhiseNodes) {
+        this.whenNodes = whenNodes;
+        this.whenTests = whenTests;
+        this.otherwhiseNodes = otherwhiseNodes;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+      	// Perform any common invoke functionality 
+        super.invoke(env, context);
+
+        // Prepare data needed by the action
+        final Map objectModel = env.getObjectModel();
+        final Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel);
+
+        final Selector selector = (Selector)getComponent();
+        try {
+
+            for (int i = 0; i < this.whenTests.length; i++) {
+                if ( this.executor.invokeSelector(this, objectModel,
+                        selector,
+                        whenTests[i].resolve(context, objectModel),
+                        resolvedParams)) {
+                    return invokeNodes(this.whenNodes[i], env, context);
+                }
+            }
+
+            if (this.otherwhiseNodes != null) {
+                return invokeNodes(this.otherwhiseNodes, env, context);
+            }
+
+            return false;
+        } finally {
+            releaseComponent(selector);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNodeBuilder.java
new file mode 100644
index 0000000..2ea2bd4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SelectNodeBuilder.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.selection.SwitchSelector;
+
+/**
+ *
+ * @version $Id$
+ */
+public class SelectNodeBuilder extends AbstractParentProcessingNodeBuilder {
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String type = this.treeBuilder.getTypeForStatement(config, Selector.ROLE);
+
+        // Lists of ProcessingNode[] and test resolvers for each "when"
+        List whenChildren = new ArrayList();
+        List whenTests = new ArrayList();
+
+        // Nodes for otherwise (if any)
+        ProcessingNode[] otherwiseNodes = null;
+
+        Configuration[] childrenConfig = config.getChildren();
+        for (int i = 0; i < childrenConfig.length; i++) {
+
+            Configuration childConfig = childrenConfig[i];
+            String name = childConfig.getName();
+
+            if ("when".equals(name)) {
+
+                checkNamespace(childConfig);
+                whenTests.add(
+                    VariableResolverFactory.getResolver(childConfig.getAttribute("test"), this.manager)
+                );
+                whenChildren.add(buildChildNodes(childConfig));
+
+            } else if ("otherwise".equals(name)) {
+
+                checkNamespace(childConfig);
+                if (otherwiseNodes != null) {
+                    String msg = "Duplicate " + name + " (only one is allowed) at " + childConfig.getLocation();
+                    getLogger().error(msg);
+                    throw new ConfigurationException(msg);
+                }
+
+                otherwiseNodes = buildChildNodes(childConfig);
+
+            } else if (isParameter(childConfig)) {
+                // ignore it. It is handled automatically in setupNode()
+
+            } else {
+                // Unknown element
+                String msg = "Unknown element '" + name + "' in select at " + childConfig.getLocation();
+                throw new ConfigurationException(msg);
+            }
+        }
+
+        ProcessingNode[][] whenChildrenNodes = (ProcessingNode[][])whenChildren.toArray(new ProcessingNode[0][0]);
+        VariableResolver[] whenResolvers = (VariableResolver[])whenTests.toArray(new VariableResolver[whenTests.size()]);
+
+        // Get the type and class for this selector
+        ServiceSelector compSelector = (ServiceSelector)this.manager.lookup(Selector.ROLE + "Selector");
+
+        Class clazz = null;
+        try {
+            // Find selector class
+            Selector selector = (Selector)compSelector.select(type);
+            try {
+                clazz = selector.getClass();
+            } finally {
+                compSelector.release(selector);
+            }
+        } finally {
+            this.manager.release(compSelector);
+        }
+
+        if (SwitchSelector.class.isAssignableFrom(clazz)) {
+            SwitchSelectNode node = new SwitchSelectNode(type);
+            this.treeBuilder.setupNode(node, config);
+            node.setCases(whenChildrenNodes, whenResolvers, otherwiseNodes);
+            return node;
+        }
+        SelectNode node = new SelectNode(type);
+        this.treeBuilder.setupNode(node, config);
+        node.setCases(whenChildrenNodes, whenResolvers, otherwiseNodes);
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
new file mode 100644
index 0000000..8f5b2aa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNode.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.PipelineEventComponentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+/**
+ *
+ * @version $Id$
+ */
+public class SerializeNode extends PipelineEventComponentProcessingNode implements ParameterizableProcessingNode {
+
+    private String serializerName;
+
+    private VariableResolver source;
+
+    private VariableResolver mimeType;
+
+    private int statusCode;
+
+    private Map parameters;
+
+
+    /**
+     * Build a <code>SerializerNode</code> having a name, a mime-type and a status code (HTTP codes).
+     *
+     * @param name the name of the serializer to use.
+     * @param mimeType the mime-type, or <code>null</code> not specified.
+     * @param statusCode the HTTP response status code, or <code>-1</code> if not specified.
+     */
+    public SerializeNode(String name,
+                         VariableResolver source, 
+                         VariableResolver mimeType, 
+                         int statusCode) {
+        this.serializerName = name;
+        this.source = source;
+        this.mimeType = mimeType;
+        this.statusCode = statusCode;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+        // Check view
+        if (this.views != null) {
+	   
+            //inform the pipeline that we have a branch point
+            context.getProcessingPipeline().informBranchPoint();
+
+            String cocoonView = env.getView();
+            if (cocoonView != null) {
+
+                // Get view node
+                ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
+
+                if (viewNode != null) {
+                    if (getLogger().isInfoEnabled()) {
+                        getLogger().info("Jumping to view " + cocoonView + " from serializer at " + this.getLocation());
+                    }
+                    return viewNode.invoke(env, context);
+                }
+            }
+        }
+        
+        final Map objectModel = env.getObjectModel();
+        final ProcessingPipeline pipeline = context.getProcessingPipeline();
+
+        // Perform link translation if requested
+        if (objectModel.containsKey(Constants.LINK_OBJECT)) {
+            pipeline.addTransformer("<translator>", null, Parameters.EMPTY_PARAMETERS, Parameters.EMPTY_PARAMETERS);
+        }
+        
+        if (objectModel.containsKey(Constants.LINK_COLLECTION_OBJECT) && env.isExternal()) {
+            pipeline.addTransformer("<gatherer>", null, Parameters.EMPTY_PARAMETERS, Parameters.EMPTY_PARAMETERS);
+        }
+
+        SitemapExecutor.PipelineComponentDescription desc = new SitemapExecutor.PipelineComponentDescription();
+        desc.type = this.serializerName;
+        desc.source = source.resolve(context, objectModel);
+        desc.parameters = VariableResolver.buildParameters(this.parameters, context, objectModel);
+        desc.hintParameters = this.pipelineHints == null
+                ? Parameters.EMPTY_PARAMETERS
+                : VariableResolver.buildParameters(this.pipelineHints, context, objectModel);
+        desc.mimeType = this.mimeType.resolve(context, objectModel);
+
+        // inform executor
+        desc = this.executor.addSerializer(this, objectModel, desc);
+        
+        pipeline.setSerializer(
+                desc.type,
+                desc.source,
+                desc.parameters,
+                desc.hintParameters,
+                desc.mimeType
+        );
+
+        // Set status code if there is one
+        if (this.statusCode >= 0) {
+            env.setStatus(this.statusCode);
+        }
+
+        if (! context.isBuildingPipelineOnly()) {
+            // Process pipeline
+            return pipeline.process(env);
+        }
+        // Return true : pipeline is finished.
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java
new file mode 100644
index 0000000..924d7c3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SerializeNodeBuilder.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.serialization.Serializer;
+
+/**
+ *
+ * @version $Id$
+ */
+public class SerializeNodeBuilder extends AbstractProcessingNodeBuilder
+  implements LinkedProcessingNodeBuilder {
+
+    private SerializeNode node;
+
+    private Collection views;
+    private Map  pipelineHints;
+
+    /** Serializers can have parameters -- return <code>true</code> */
+    protected boolean hasParameters() {
+        return true;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String type = this.treeBuilder.getTypeForStatement(config, Serializer.ROLE);
+        
+        SitemapLanguage sitemapBuilder = (SitemapLanguage)this.treeBuilder;
+
+        String mimeType = config.getAttribute("mime-type", null);
+        if (mimeType == null) {
+            mimeType = sitemapBuilder.getMimeType(Serializer.ROLE, type);
+        }
+
+        this.views = sitemapBuilder.getViewsForStatement(Serializer.ROLE, type, config);
+        this.pipelineHints = sitemapBuilder.getHintsForStatement(Serializer.ROLE, type, config);
+
+        this.node = new SerializeNode(
+            type,
+            VariableResolverFactory.getResolver(config.getAttribute("src", null), this.manager),
+            VariableResolverFactory.getResolver(mimeType, this.manager),
+            config.getAttributeAsInteger("status-code", -1)
+        );
+        this.node.setPipelineHints(this.pipelineHints);
+        return this.treeBuilder.setupNode(node, config);
+    }
+
+    public void linkNode() throws Exception {
+        this.node.setViews(
+            ((SitemapLanguage)this.treeBuilder).getViewNodes(this.views)
+        );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
new file mode 100644
index 0000000..1a4c6bc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapLanguage.java
@@ -0,0 +1,524 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.LifecycleHelper;
+import org.apache.cocoon.components.container.CocoonServiceManager;
+import org.apache.cocoon.components.treeprocessor.CategoryNode;
+import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder;
+import org.apache.cocoon.components.treeprocessor.TreeBuilder;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.sitemap.ComponentLocator;
+import org.apache.cocoon.sitemap.EnterSitemapEventListener;
+import org.apache.cocoon.sitemap.LeaveSitemapEventListener;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapListener;
+import org.apache.cocoon.sitemap.impl.ComponentManager;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.StringUtils;
+import org.apache.regexp.RE;
+
+/**
+ * The tree builder for the sitemap language.
+ *
+ * @version $Id$
+ */
+public class SitemapLanguage extends DefaultTreeBuilder {
+
+    // Regexp's for splitting expressions
+    private static final String COMMA_SPLIT_REGEXP = "[\\s]*,[\\s]*";
+    private static final String EQUALS_SPLIT_REGEXP = "[\\s]*=[\\s]*";
+
+//    protected ClassLoader createClassLoader(Configuration config)
+//    throws Exception {
+//        ClassLoader newClassLoader;
+//        Configuration classpathConfig = config.getChild("classpath", false);
+//        if (classpathConfig == null) {
+//            return Thread.currentThread().getContextClassLoader();
+//        }
+//        
+//        String factoryRole = config.getAttribute("factory-role", ClassLoaderFactory.ROLE + "/ReloadingClassLoaderFactory");
+//        // Create a new classloader
+//        ClassLoaderFactory clFactory = (ClassLoaderFactory)this.parentProcessorManager.lookup(factoryRole);
+//        try {
+//            return clFactory.createClassLoader(
+//                    Thread.currentThread().getContextClassLoader(),
+//                    classpathConfig
+//            );
+//        } finally {
+//            this.parentProcessorManager.release(clFactory);
+//        }
+//    }
+    
+    /**
+     * Build a component manager with the contents of the &lt;map:components&gt; element of
+     * the tree.
+     */
+    protected ServiceManager createServiceManager(ClassLoader classloader, Context context, Configuration config)
+    throws Exception {
+
+        // Create the classloader, if needed.
+        ServiceManager newManager;
+        
+        newManager = new CocoonServiceManager(this.parentProcessorManager, classloader);
+
+        // Go through the component lifecycle
+        ContainerUtil.enableLogging(newManager, this.getLogger());
+        ContainerUtil.contextualize(newManager, context);
+        // before we pass the configuration we have to strip the
+        // additional configuration parts, like classpath etc. as these
+        // are not configurations for the service manager
+        final DefaultConfiguration c = new DefaultConfiguration(config.getName(), 
+                                                                config.getLocation(),
+                                                                config.getNamespace(),
+                                                                "");
+        c.addAll(config);
+        c.removeChild(config.getChild("application-container"));
+        c.removeChild(config.getChild("classpath"));
+        c.removeChild(config.getChild("listeners"));
+
+        ContainerUtil.configure(newManager, c);
+        ContainerUtil.initialize(newManager);
+
+        Logger sitemapLogger = ((CocoonServiceManager)newManager).getServiceManagerLogger();
+        // check for an application specific container
+        final Configuration appContainer = config.getChild("application-container", false);
+        if ( appContainer != null ) {
+            final String clazzName = appContainer.getAttribute("class");
+
+            final ComponentLocator cl = (ComponentLocator)ClassUtils.newInstance(clazzName); 
+            // Go through the component lifecycle
+            LifecycleHelper.setupComponent(cl, sitemapLogger, context, newManager, appContainer);
+
+            this.applicationContainer = cl;
+
+            newManager = new ComponentManager(newManager, cl);
+        }
+
+        // and finally the listeners
+        if ( this.applicationContainer instanceof SitemapListener ) {
+            this.addListener(new TreeBuilder.EventComponent(this.applicationContainer, false));
+        }
+
+        final Configuration listenersWrapper = config.getChild("listeners", false);
+        if ( listenersWrapper != null ) {
+            final Configuration[] listeners = listenersWrapper.getChildren("listener");                
+            for(int i = 0; i < listeners.length; i++) {
+                final Configuration current = listeners[i];
+                final TreeBuilder.EventComponent listener = this.createListener(newManager, sitemapLogger, context, current);
+                if ( !(listener.component instanceof SitemapListener) ) {
+                    throw new ConfigurationException("Listener must implement the SitemapListener interface.");
+                }
+                this.addListener(listener);
+            }
+        }
+
+        return newManager;
+    }
+
+    /**
+     * Create a listener
+     */
+    protected TreeBuilder.EventComponent createListener(ServiceManager manager,
+                                                        Logger sitemapLogger,
+                                                        Context context,
+                                                        Configuration config) 
+    throws Exception {
+        // role or class?
+        final String role = config.getAttribute("role", null);
+        if ( role != null ) {
+            return new TreeBuilder.EventComponent(manager.lookup(role), true);
+        }
+        final String className = config.getAttribute("class");
+        final Object component = ClassUtils.newInstance(className);
+
+        LifecycleHelper.setupComponent(component, sitemapLogger, context, manager, config);
+
+        return new TreeBuilder.EventComponent(component, false);
+    }
+
+    /**
+     * Add a listener
+     */
+    protected void addListener(TreeBuilder.EventComponent listener) {
+        if ( listener.component instanceof EnterSitemapEventListener ) {
+            this.enterSitemapEventListeners.add(listener);
+        } else if ( listener.component instanceof LeaveSitemapEventListener ) {
+            this.leaveSitemapEventListeners.add(listener);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.components.treeprocessor.DefaultTreeBuilder#createContext(org.apache.avalon.framework.configuration.Configuration)
+     */
+    protected Context createContext(Configuration tree) throws Exception {
+        // Create sub-context for this sitemap
+        DefaultContext newContext = new DefaultContext(super.createContext(tree));
+        Environment env = EnvironmentHelper.getCurrentEnvironment();
+        newContext.put(Constants.CONTEXT_ENV_URI, env.getURI());
+        newContext.put(Constants.CONTEXT_ENV_PREFIX, env.getURIPrefix());
+        // FIXME How to get rid of EnvironmentHelper?
+        newContext.put(Constants.CONTEXT_ENV_HELPER, getProcessor().getWrappingProcessor().getEnvironmentHelper());
+
+        return newContext;
+    }
+
+    //---- Views management
+
+    /** Collection of view names for each label */
+    private Map labelViews = new HashMap();
+
+    /** The views CategoryNode */
+    private CategoryNode viewsNode;
+
+    /** Are we currently building a view ? */
+    private boolean isBuildingView = false;
+
+    /** Are we currently building a view ? */
+    private boolean isBuildingErrorHandler = false;
+
+    /**
+     * Pseudo-label for views <code>from-position="first"</code> (i.e. generator).
+     */
+    public static final String FIRST_POS_LABEL = "!first!";
+
+    /**
+     * Pseudo-label for views <code>from-position="last"</code> (i.e. serializer).
+     */
+    public static final String LAST_POS_LABEL = "!last!";
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        super.recycle();
+
+        // Go back to initial state
+        this.labelViews.clear();
+        this.viewsNode = null;
+        this.isBuildingView = false;
+        this.isBuildingErrorHandler = false;
+    }
+
+    /**
+     * Set to <code>true</code> while building the internals of a &lt;map:view&gt;
+     */
+    public void setBuildingView(boolean building) {
+        this.isBuildingView = building;
+    }
+
+    /**
+     * Are we currently building a view ?
+     */
+    public boolean isBuildingView() {
+        return this.isBuildingView;
+    }
+
+    /**
+     * Set to <code>true</code> while building the internals of a &lt;map:handle-errors&gt;
+     */
+    public void setBuildingErrorHandler(boolean building) {
+        this.isBuildingErrorHandler = building;
+    }
+
+    /**
+     * Are we currently building an error handler ?
+     */
+    public boolean isBuildingErrorHandler() {
+        return this.isBuildingErrorHandler;
+    }
+
+    /**
+     * Add a view for a label. This is used to register all views that start from
+     * a given label.
+     *
+     * @param label the label (or pseudo-label) for the view
+     * @param view the view name
+     */
+    public void addViewForLabel(String label, String view) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("views:addViewForLabel(" + label + ", " + view + ")");
+        }
+        Set views = (Set)this.labelViews.get(label);
+        if (views == null) {
+            views = new HashSet();
+            this.labelViews.put(label, views);
+        }
+
+        views.add(view);
+    }
+
+    /**
+     * Get the names of views for a given statement. If the cocoon view exists in the returned
+     * collection, the statement can directly branch to the view-handling node.
+     *
+     * @param role the component role (e.g. <code>Generator.ROLE</code>)
+     * @param hint the component hint, i.e. the 'type' attribute
+     * @param statement the sitemap statement
+     * @return the view names for this statement
+     */
+    public Collection getViewsForStatement(String role, String hint, Configuration statement) throws Exception {
+
+        String statementLabels = statement.getAttribute("label", null);
+
+        if (this.isBuildingView) {
+            // Labels are forbidden inside view definition
+            if (statementLabels != null) {
+                String msg = "Cannot put a 'label' attribute inside view definition at " + statement.getLocation();
+                throw new ConfigurationException(msg);
+            }
+
+            // We are currently building a view. Don't recurse !
+            return null;
+        }
+
+        // Compute the views attached to this component
+        Set views = null;
+
+        // Build the set for all labels for this statement
+        Set labels = new HashSet();
+
+        // 1 - labels defined on the component
+        if (role != null && role.length() > 0) {
+            String[] compLabels = this.itsComponentInfo.getLabels(role, hint);
+            if (compLabels != null) {
+                for (int i = 0; i < compLabels.length; i++) {
+                    labels.add(compLabels[i]);
+                }
+            }
+        }
+
+        // 2 - labels defined on this statement
+        if (statementLabels != null) {
+            labels.addAll(splitLabels(statementLabels));
+        }
+
+        // 3 - pseudo-label depending on the role
+        if (Generator.ROLE.equals(role)) {
+            labels.add("!first!");
+        } else if (Serializer.ROLE.equals(role)) {
+            labels.add("!last!");
+        }
+
+        // Build the set of views attached to these labels
+        views = new HashSet();
+
+        // Iterate on all labels for this statement
+        Iterator labelIter = labels.iterator();
+        while(labelIter.hasNext()) {
+
+            // Iterate on all views for this labek
+            Collection coll = (Collection)this.labelViews.get(labelIter.next());
+            if (coll != null) {
+                Iterator viewIter = coll.iterator();
+                while(viewIter.hasNext()) {
+                    String viewName = (String)viewIter.next();
+
+                    views.add(viewName);
+                }
+            }
+        }
+
+        // Don't keep empty result
+        if (views.size() == 0) {
+            views = null;
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug(statement.getName() + " has no views at " + statement.getLocation());
+            }
+        } else {
+            if (getLogger().isDebugEnabled()) {
+                // Dump matching views
+                StringBuffer buf = new StringBuffer(statement.getName() + " will match views [");
+                Iterator iter = views.iterator();
+                while(iter.hasNext()) {
+                    buf.append(iter.next()).append(" ");
+                }
+                buf.append("] at ").append(statement.getLocation());
+
+                getLogger().debug(buf.toString());
+            }
+        }
+
+        return views;
+    }
+
+    /**
+     * Before linking nodes, lookup the view category node used in {@link #getViewNodes(Collection)}.
+     */
+    protected void linkNodes() throws Exception {
+        // Get the views category node
+        this.viewsNode = CategoryNodeBuilder.getCategoryNode(this, "views");
+
+        super.linkNodes();
+    }
+
+    /**
+     * Get the {view name, view node} map for a collection of view names.
+     * This allows to resolve view nodes at build time, thus avoiding runtime lookup.
+     *
+     * @param viewNames the view names
+     * @return association of names to views
+     */
+    public Map getViewNodes(Collection viewNames) throws Exception {
+        if (viewNames == null || viewNames.size() == 0) {
+            return null;
+        }
+
+        if (this.viewsNode == null) {
+            return null;
+        }
+
+        Map result = new HashMap();
+
+        Iterator iter = viewNames.iterator();
+        while(iter.hasNext()) {
+            String viewName = (String)iter.next();
+            result.put(viewName, viewsNode.getNodeByName(viewName));
+        }
+
+        return result;
+    }
+
+    /**
+     * Extract pipeline-hints from the given statement (if any exist)
+     *
+     * @param role the component role (e.g. <code>Generator.ROLE</code>)
+     * @param hint the component hint, i.e. the 'type' attribute
+     * @param statement the sitemap statement
+     * @return the hint params <code>Map</code> for this statement, or null
+     *         if none exist
+     */
+    public Map getHintsForStatement(String role, String hint, Configuration statement) throws Exception {
+        // This method implemets the hintParam Syntax as follows:
+        //     A hints attribute has one or more comma separated hints
+        //     hints-attr :: hint [ ',' hint ]*
+        //     A hint is a name and an optional (string) value
+        //     If there is no value, it is considered as boolean string "true"
+        //     hint :: literal [ '=' litteral ]
+        //     literal :: <a character string where the chars ',' and '=' are not permitted>
+        //
+        //  A ConfigurationException is thrown if there is a problem "parsing"
+        //  the hint.
+
+        String statementHintParams = statement.getAttribute("pipeline-hints", null);
+        String componentHintParams = null;
+        String hintParams = null;
+
+        // firstly, determine if any pipeline-hints are defined at the component level
+        // if so, inherit these pipeline-hints (these hints can be overriden by local pipeline-hints)
+        componentHintParams = this.itsComponentInfo.getPipelineHint(role, hint);
+
+        if (componentHintParams != null) {
+            hintParams = componentHintParams;
+
+            if (statementHintParams != null) {
+                hintParams = hintParams + "," + statementHintParams;
+            }
+        } else {
+            hintParams = statementHintParams;
+        }
+
+        // if there are no pipeline-hints defined then
+        // it makes no sense to continue so, return null
+        if (hintParams == null) {
+            return null;
+        }
+
+        Map params = new HashMap();
+
+        RE commaSplit = new RE(COMMA_SPLIT_REGEXP);
+        RE equalsSplit = new RE(EQUALS_SPLIT_REGEXP);
+
+        String[]  expressions = commaSplit.split(hintParams.trim());
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("pipeline-hints: (aggregate-hint) " + hintParams);
+        }
+
+        for (int i=0; i<expressions.length;i++) {
+            String [] nameValuePair = equalsSplit.split(expressions[i]);
+
+            try {
+                if (nameValuePair.length < 2) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("pipeline-hints: (name) " + nameValuePair[0]
+                                       + "\npipeline-hints: (value) [implicit] true");
+                    }
+
+                    params.put(resolve(nameValuePair[0]), resolve("true"));
+                } else {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("pipeline-hints: (name) " + nameValuePair[0]
+                                          + "\npipeline-hints: (value) " + nameValuePair[1]);
+                    }
+
+                    params.put(resolve(nameValuePair[0]), resolve(nameValuePair[1]));
+                }
+            } catch(PatternException pe) {
+                String msg = "Invalid pattern '" + hintParams + "' at " + statement.getLocation();
+                getLogger().error(msg, pe);
+                throw new ConfigurationException(msg, pe);
+            }
+        }
+
+        return params;
+    }
+    
+    /**
+     * Get the mime-type for a component (either a serializer or a reader)
+     *
+     * @param role the component role (e.g. <code>Serializer.ROLE</code>)
+     * @param hint the component hint, i.e. the 'type' attribute
+     * @return the mime-type, or <code>null</code> if none was set
+     */
+    public String getMimeType(String role, String hint) {
+        return this.itsComponentInfo.getMimeType(role, hint);
+    }
+
+    /**
+     * Split a list of space/comma separated labels into a Collection
+     *
+     * @return the collection of labels (may be empty, nut never null)
+     */
+    private static final Collection splitLabels(String labels) {
+        if (labels == null) {
+            return Collections.EMPTY_SET;
+        }
+        return Arrays.asList(StringUtils.split(labels, ", \t\n\r"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapNodeBuilder.java
new file mode 100644
index 0000000..bb38d13
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SitemapNodeBuilder.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
+
+/**
+ * Builds all nodes below the top-level &lt;sitemap&gt; element, and returns the
+ * &lt;pipelines&gt; node. There is no node for &gt;sitemap&lt; since no processing
+ * occurs at this level.
+ *
+ * @version $Id$
+ */
+public class SitemapNodeBuilder extends AbstractParentProcessingNodeBuilder implements ThreadSafe {
+    
+    // Name of children that have to be built in a particular order.
+    // For example, views have to be built before resources and both before pipelines.
+    private static final String[] orderedNames = { "components", "views", "resources" };
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        
+        // Start by explicitely ordered children
+        for (int i = 0; i < orderedNames.length; i++) {
+            Configuration childConfig = config.getChild(orderedNames[i], false);
+            if (childConfig != null) {
+                ProcessingNodeBuilder builder = this.treeBuilder.createNodeBuilder(childConfig);
+                // Don't build them since "pipelines" is not present in this list
+                builder.buildNode(childConfig);
+            }
+        }
+        
+        ProcessingNode pipelines = null;
+
+        // Now build all those that have no particular order
+        Configuration[] childConfigs = config.getChildren();
+        
+        loop: for (int i = 0; i < childConfigs.length; i++) {
+            
+            Configuration childConfig = childConfigs[i];
+            if (isChild(childConfig)) {
+                // Is it in the ordered list ?
+                for (int j = 0; j < orderedNames.length; j++) {
+                    if (orderedNames[j].equals(childConfig.getName())) {
+                        // yep : already built above
+                        continue loop;
+                    }
+                }
+                
+                ProcessingNodeBuilder builder = this.treeBuilder.createNodeBuilder(childConfig);
+                ProcessingNode node = builder.buildNode(childConfig);
+                if (node instanceof PipelinesNode) {
+                    if (pipelines != null) {
+                        String msg = "Only one 'pipelines' is allowed, at " + childConfig.getLocation();
+                        throw new ConfigurationException(msg);
+                    }
+                    pipelines = node;
+                }
+            }
+        }
+
+        if (pipelines == null) {
+            String msg = "Invalid sitemap : there must be a 'pipelines' at " + config.getLocation();
+            throw new ConfigurationException(msg);
+        }
+
+        return pipelines;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SwitchSelectNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SwitchSelectNode.java
new file mode 100644
index 0000000..79f75da
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/SwitchSelectNode.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.selection.SwitchSelector;
+
+/**
+ *
+ * @version $Id$
+ */
+public class SwitchSelectNode extends SimpleSelectorProcessingNode
+    implements ParameterizableProcessingNode {
+
+    /** The parameters of this node */
+    private Map parameters;
+
+    private ProcessingNode[][] whenNodes;
+
+    private VariableResolver[] whenTests;
+
+    private ProcessingNode[] otherwhiseNodes;
+
+    public SwitchSelectNode(String name) {
+        super(Selector.ROLE + "Selector", name);
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+    public void setCases(ProcessingNode[][] whenNodes, VariableResolver[] whenTests, ProcessingNode[] otherwhiseNodes) {
+        this.whenNodes = whenNodes;
+        this.whenTests = whenTests;
+        this.otherwhiseNodes = otherwhiseNodes;
+    }
+
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+	
+      	// Perform any common invoke functionality 
+        super.invoke(env, context);
+
+        // Prepare data needed by the action
+        final Map objectModel = env.getObjectModel();
+        Parameters resolvedParams = VariableResolver.buildParameters(this.parameters, context, objectModel);
+
+        SwitchSelector switchSelector = (SwitchSelector)getComponent();
+
+        Object ctx = switchSelector.getSelectorContext(objectModel, resolvedParams);
+       
+        try {
+            for (int i = 0; i < this.whenTests.length; i++) {
+                if (this.executor.invokeSwitchSelector(this, 
+                        objectModel, 
+                        switchSelector, 
+                        whenTests[i].resolve(context, objectModel), 
+                        resolvedParams, 
+                        ctx)) {
+                    return invokeNodes(this.whenNodes[i], env, context);
+                }
+            }
+
+            if (this.otherwhiseNodes != null) {
+                return invokeNodes(this.otherwhiseNodes, env, context);
+            }
+
+            return false;
+        } finally {
+            releaseComponent(switchSelector);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNode.java
new file mode 100644
index 0000000..b887d4d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNode.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.pipeline.ProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ParameterizableProcessingNode;
+import org.apache.cocoon.components.treeprocessor.PipelineEventComponentProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public class TransformNode extends PipelineEventComponentProcessingNode implements ParameterizableProcessingNode {
+
+    private String transformerName;
+
+    private VariableResolver source;
+
+    private Map parameters;
+
+
+    public TransformNode(String name, VariableResolver source) {
+        this.transformerName = name;
+        this.source = source;
+    }
+
+    public void setParameters(Map parameterMap) {
+        this.parameters = parameterMap;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.components.treeprocessor.ProcessingNode#invoke(org.apache.cocoon.environment.Environment, org.apache.cocoon.components.treeprocessor.InvokeContext)
+     */
+    public final boolean invoke(Environment env, InvokeContext context)
+    throws Exception {
+
+        final Map objectModel = env.getObjectModel();
+
+        final ProcessingPipeline pipeline = context.getProcessingPipeline();
+        
+        SitemapExecutor.PipelineComponentDescription desc = new SitemapExecutor.PipelineComponentDescription();
+        desc.type = this.transformerName;
+        desc.source = source.resolve(context, objectModel);
+        desc.parameters = VariableResolver.buildParameters(this.parameters, context, objectModel);
+        desc.hintParameters = this.pipelineHints == null
+                ? Parameters.EMPTY_PARAMETERS
+                : VariableResolver.buildParameters(this.pipelineHints, context, objectModel);
+
+        // inform executor
+        desc = this.executor.addTransformer(this, objectModel, desc);
+
+        pipeline.addTransformer(
+            desc.type,
+            desc.source,
+            desc.parameters,
+            desc.hintParameters
+        );
+
+        // Check view
+        if (this.views != null) {
+	   
+            //inform the pipeline that we have a branch point
+            pipeline.informBranchPoint();
+	    
+            String cocoonView = env.getView();
+            if (cocoonView != null) {
+
+                // Get view node
+                ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
+
+                if (viewNode != null) {
+                    if (getLogger().isInfoEnabled()) {
+                        getLogger().info("Jumping to view " + cocoonView + " from transformer at " + this.getLocation());
+                    }
+                    return viewNode.invoke(env, context);
+                }
+            }
+        }
+
+        // Return false to contine sitemap invocation
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNodeBuilder.java
new file mode 100644
index 0000000..f51f4b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/TransformNodeBuilder.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.transformation.Transformer;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public class TransformNodeBuilder extends AbstractProcessingNodeBuilder
+  implements LinkedProcessingNodeBuilder {
+
+    private TransformNode node;
+
+    private Collection views;
+    private Map  pipelineHints;
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        String type = this.treeBuilder.getTypeForStatement(config, Transformer.ROLE);
+
+        this.views = ((SitemapLanguage)this.treeBuilder).getViewsForStatement(Transformer.ROLE, type, config);
+        this.pipelineHints = ((SitemapLanguage)this.treeBuilder).getHintsForStatement(Transformer.ROLE, type, config);
+
+        this.node = new TransformNode(
+            type,
+            VariableResolverFactory.getResolver(config.getAttribute("src", null), this.manager)
+        );
+
+        this.node.setPipelineHints(this.pipelineHints);
+        return this.treeBuilder.setupNode(node, config);
+    }
+
+    public void linkNode() throws Exception {
+        this.node.setViews(
+            ((SitemapLanguage)this.treeBuilder).getViewNodes(this.views)
+        );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNode.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNode.java
new file mode 100644
index 0000000..f28fa3e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.Set;
+
+import org.apache.cocoon.components.treeprocessor.NamedContainerNode;
+
+/**
+ * A VPC node that just invokes its children and store what parameters are sources.
+ *
+ * @version $Id$
+ */
+public class VPCNode extends NamedContainerNode {
+
+    Set sourceSet;
+
+    public VPCNode(String name, Set sourceSet) {
+        super(name);
+        this.sourceSet = sourceSet;
+    }
+
+    public Set getSources() {
+        return this.sourceSet;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNodeBuilder.java
new file mode 100644
index 0000000..6a30d45
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCNodeBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import java.util.HashSet;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.components.treeprocessor.NamedContainerNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+/**
+ * Handles a virtual sitemap component.
+ *
+ * @version $Id$
+ */
+public class VPCNodeBuilder extends NamedContainerNodeBuilder
+    implements Contextualizable {
+
+    private DefaultContext context;
+
+    // FIXME: The class is thread safe, will that work with Contextualizable?
+    public void contextualize(Context context) throws ContextException {
+        this.context = (DefaultContext) context;
+    }
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+        String type = config.getName();
+        String name = config.getAttribute(this.nameAttr);
+
+        // Find out which parameters that should be handled as sources
+        // and put the info in the context.
+        Configuration[] sources = config.getChildren("source");
+        HashSet sourceSet = new HashSet();
+        for (int j = 0; j < sources.length; j++)
+            sourceSet.add(sources[j].getAttribute("param"));
+        
+        VPCNode node = new VPCNode(name, sourceSet);
+        this.setupNode(node, config);
+
+        // Stuff this node into the context of current Sitemap so that
+        // VirtualPipelineComponent can find it. 
+        //
+        this.context.put(Constants.CONTEXT_VPC_PREFIX + type + "-" + name, node);
+
+        return node;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCsNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCsNodeBuilder.java
new file mode 100644
index 0000000..9ed1f7e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/VPCsNodeBuilder.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+
+import org.apache.cocoon.components.treeprocessor.ContainerNode;
+import org.apache.cocoon.components.treeprocessor.ContainerNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.generation.VirtualPipelineGenerator;
+import org.apache.cocoon.reading.VirtualPipelineReader;
+import org.apache.cocoon.serialization.VirtualPipelineSerializer;
+import org.apache.cocoon.transformation.VirtualPipelineTransformer;
+
+/**
+ * Handles a set of virtual sitemap components.
+ *
+ * @version $Id$
+ */
+public class VPCsNodeBuilder extends ContainerNodeBuilder {
+
+    /**
+     * Checks if a child element is a VPC, and if not throws a <code>ConfigurationException</code>.
+     *
+     * @param child the child configuration to check.
+     * @return <code>true</code> if this child should be considered or <code>false</code>
+     *         if it should be ignored.
+     * @throws ConfigurationException if this child isn't allowed.
+     */
+    protected boolean isChild(Configuration child) throws ConfigurationException {
+
+        checkNamespace(child);
+
+        String clazz = child.getAttribute("src");
+        return VirtualPipelineGenerator.class.getName().equals(clazz)
+            || VirtualPipelineSerializer.class.getName().equals(clazz)
+            || VirtualPipelineTransformer.class.getName().equals(clazz)
+            || VirtualPipelineReader.class.getName().equals(clazz);
+    }
+
+    protected void setupNode(ContainerNode node, Configuration config)throws Exception {
+
+        this.treeBuilder.setupNode(node, config);
+
+        ProcessingNode[] children = buildChildNodes(config);
+
+        node.setChildren(children);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ViewNodeBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ViewNodeBuilder.java
new file mode 100644
index 0000000..327162c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/ViewNodeBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.sitemap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.treeprocessor.NamedContainerNodeBuilder;
+import org.apache.cocoon.components.treeprocessor.NamedProcessingNode;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+
+/**
+ * Builds a &lt;map:view&gt;
+ *
+ * @version $Id$
+ */
+public class ViewNodeBuilder extends NamedContainerNodeBuilder implements ThreadSafe {
+
+    public ProcessingNode buildNode(Configuration config) throws Exception {
+
+        // Get the label or position (pseudo-label) of this view.
+        String label = config.getAttribute("from-label", null);
+
+        if (label == null) {
+            String position = config.getAttribute("from-position");
+            if ("first".equals(position)) {
+                label = SitemapLanguage.FIRST_POS_LABEL;
+            } else if ("last".equals(position)) {
+                label = SitemapLanguage.LAST_POS_LABEL;
+            } else {
+                String msg = "Bad value for 'from-position' at " + config.getLocation();
+                throw new ConfigurationException(msg);
+            }
+        }
+
+        SitemapLanguage sitemapBuilder = (SitemapLanguage)this.treeBuilder;
+
+        // Indicate to child builders that we're in a view (they won't perform view branching)
+        sitemapBuilder.setBuildingView(true);
+
+        // Build children
+        NamedProcessingNode result = (NamedProcessingNode)super.buildNode(config);
+
+        sitemapBuilder.addViewForLabel(label, result.getName());
+
+        // Clear the flag
+        sitemapBuilder.setBuildingView(false);
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/package.html
new file mode 100644
index 0000000..21ff165
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/sitemap/package.html
@@ -0,0 +1,25 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+ <title>Implemention of the Sitemap language</title>
+</head>
+<body>
+ <h1>Implemention of the Sitemap language</h1>
+ <p>
+ </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/NOPVariableResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/NOPVariableResolver.java
new file mode 100644
index 0000000..f405a88
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/NOPVariableResolver.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+
+import java.util.Map;
+
+/**
+ * No-op implementation of {@link VariableResolver} for constant expressions
+ *
+ * @version $Id$
+ */
+public class NOPVariableResolver extends VariableResolver {
+
+    private String expression = null;
+
+    public NOPVariableResolver(String expression) {
+        super(expression);
+        if (expression != null) {
+            this.expression = VariableResolverFactory.unescape(expression);
+        }
+    }
+
+    public final String resolve(InvokeContext context, Map objectModel) {
+        return this.expression;
+    }
+    
+    public final void release() {
+        // Nothing to do
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolver.java
new file mode 100644
index 0000000..5d0d52c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolver.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * Prepared implementation of {@link VariableResolver} for fast evaluation.
+ *
+ * @version $Id$
+ */
+final public class PreparedVariableResolver extends VariableResolver implements Disposable {
+
+    private ServiceManager manager;
+    protected List tokens;
+    protected boolean needsMapStack;
+
+    private static final int OPEN = -2;
+    private static final int CLOSE = -3;
+    private static final int COLON = -4;
+    private static final int TEXT = -5;
+    private static final int EXPR = -7;
+    private static final int SITEMAP_VAR = -9;
+    private static final int THREADSAFE_MODULE = -10;
+    private static final int STATEFUL_MODULE = -11;
+    private static final int ROOT_SITEMAP_VARIABLE = 0;
+    private static final int ANCHOR_VAR = -1;
+
+    protected static Token COLON_TOKEN = new Token(COLON);
+    protected static Token OPEN_TOKEN = new Token(OPEN);
+    protected static Token CLOSE_TOKEN = new Token(CLOSE);
+    protected static Token EMPTY_TOKEN = new Token(EXPR);
+
+    public PreparedVariableResolver(String expr, ServiceManager manager) throws PatternException {
+        super(expr);
+        this.manager = manager;
+        this.tokens = new ArrayList();
+
+        VariableExpressionTokenizer.tokenize(expr, new VariableExpressionTokenizer.TokenReciever() {
+            public void addToken(int type, String value) throws PatternException {
+                switch (type) {
+                    case VariableExpressionTokenizer.TokenReciever.COLON:
+                        tokens.add(COLON_TOKEN);
+                        break;
+                    case VariableExpressionTokenizer.TokenReciever.OPEN:
+                        tokens.add(OPEN_TOKEN);
+                        break;
+                    case VariableExpressionTokenizer.TokenReciever.CLOSE:
+                        tokens.add(CLOSE_TOKEN);
+                        break;
+                    case VariableExpressionTokenizer.TokenReciever.TEXT:
+                        tokens.add(new Token(value));
+                        break;
+                    case VariableExpressionTokenizer.TokenReciever.MODULE:
+                        Token token;
+                        if (value.equals("sitemap")) {
+                            // Explicit prefix for sitemap variable
+                            needsMapStack = true;
+                            token = new Token(SITEMAP_VAR);
+                        } else if (value.startsWith("#")) {
+                            // anchor syntax refering to a name result level
+                            needsMapStack = true;
+                            token = new Token(ANCHOR_VAR, value.substring(1));
+                        } else {
+                            // Module used
+                            token = getNewModuleToken(value);
+                        }
+                        tokens.add(token);
+                        break;
+                    case VariableExpressionTokenizer.TokenReciever.VARIABLE:
+                        needsMapStack = true;
+                        tokens.add(getNewVariableToken(value));
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Unknown token type: " + type);
+                }
+            }
+        });
+    }
+
+    protected Token getNewVariableToken(String variable) {
+        if (variable.startsWith("/")) {
+            return new Token(ROOT_SITEMAP_VARIABLE, variable.substring(1));
+        }
+        // Find level
+        int level = 1; // Start at 1 since it will be substracted from list.size()
+        int pos = 0;
+        while (variable.startsWith("../", pos)) {
+            level++;
+            pos += "../".length();
+        }
+        return new Token(level, variable.substring(pos));
+    }
+
+
+    protected Token getNewModuleToken(String moduleName) throws PatternException {
+        // Get the module
+        InputModule module;
+        try {
+            module = (InputModule) this.manager.lookup(InputModule.ROLE + '/' + moduleName);
+        } catch (ServiceException e) {
+            throw new PatternException("Cannot get module named '" + moduleName +
+                                       "' in expression '" + this.originalExpr + "'", e);
+        }
+
+        Token token;
+        // Is this module threadsafe ?
+        if (module instanceof ThreadSafe) {
+            token = new Token(THREADSAFE_MODULE, module);
+        } else {
+            // Stateful module : release it and get a new one each time
+            this.manager.release(module);
+            token = new Token(STATEFUL_MODULE, moduleName);
+        }
+        return token;
+    }
+
+    public final String resolve(InvokeContext context, Map objectModel) throws PatternException {
+        List mapStack = null; // get the stack only when necessary - lazy inside the loop
+        int stackSize = 0;
+
+        if (needsMapStack) {
+            if (context == null) {
+                throw new PatternException("Need an invoke context to resolve " + this);
+            }
+            mapStack = context.getMapStack();
+            stackSize = mapStack.size();
+        }
+
+        Stack stack = new Stack();
+
+        for (Iterator i = tokens.iterator(); i.hasNext();) {
+            Token token = (Token) i.next();
+            Token last;
+            switch (token.getType()){
+                case TEXT:
+                    if (stack.empty()) {
+                        stack.push(new Token(EXPR, token.getStringValue()));
+                    } else {
+                        last = (Token)stack.peek();
+                        if (last.hasType(EXPR)) {
+                            last.merge(token);
+                        } else {
+                            stack.push(new Token(EXPR, token.getStringValue()));
+                        }
+                    }
+                    break;
+                case CLOSE:
+                    Token expr = (Token)stack.pop();
+                    Token lastButOne = (Token)stack.pop();
+                    Token result;
+                    if (expr.hasType(COLON)) { // i.e. nothing was specified after the colon
+                        stack.pop(); // Pop the OPEN
+                        result = processModule(lastButOne, EMPTY_TOKEN, objectModel, context, mapStack, stackSize);
+                    } else if (lastButOne.hasType(COLON)) {
+                        Token module = (Token)stack.pop();
+                        stack.pop(); // Pop the OPEN
+                        result = processModule(module, expr, objectModel, context, mapStack, stackSize);
+                    } else {
+                        result = processVariable(expr, mapStack, stackSize);
+                    }
+                    if (stack.empty()) {
+                        stack.push(result);
+                    } else {
+                        last = (Token)stack.peek();
+                        if (last.hasType(EXPR)) {
+                            last.merge(result);
+                        } else {
+                            stack.push(result);
+                        }
+                    }
+                    break;
+                case OPEN:
+                case COLON:
+                case ANCHOR_VAR:
+                case THREADSAFE_MODULE:
+                case STATEFUL_MODULE:
+                case ROOT_SITEMAP_VARIABLE:
+                default: {
+                    stack.push(token);
+                    break;
+                }
+            }
+        }
+        if (stack.size() !=1) {
+            throw new PatternException("Evaluation error in expression: " + originalExpr);
+        }
+        return ((Token)stack.pop()).getStringValue();
+    }
+
+    private Token processModule(Token module, Token expr, Map objectModel, InvokeContext context, List mapStack, int stackSize) throws PatternException {
+        int type = module.getType();
+
+        if (type == ANCHOR_VAR) {
+            Map levelResult = context.getMapByAnchor(module.getStringValue());
+
+            if (levelResult == null) {
+              throw new PatternException("Error while evaluating '" + this.originalExpr +
+                "' : no anchor '" + String.valueOf(module.getStringValue()) + "' found in context");
+            }
+
+            Object result = levelResult.get(expr.getStringValue());
+            return new Token(EXPR, result==null ? "" : result.toString());
+        } else if (type == THREADSAFE_MODULE) {
+            try {
+                InputModule im = module.getModule();
+                Object result = im.getAttribute(expr.getStringValue(), null, objectModel);
+                return new Token(EXPR, result==null ? "" : result.toString());
+
+            } catch(ConfigurationException confEx) {
+                throw new PatternException("Cannot get variable '" + expr.getStringValue() +
+                    "' in expression '" + this.originalExpr + "'", confEx);
+            }
+
+        } else if (type == STATEFUL_MODULE) {
+            InputModule im = null;
+            String moduleName = module.getStringValue();
+            try {
+                im = (InputModule) this.manager.lookup(InputModule.ROLE + '/' + moduleName);
+
+                Object result = im.getAttribute(expr.getStringValue(), null, objectModel);
+                return new Token(EXPR, result==null ? "" : result.toString());
+
+            } catch(ServiceException e) {
+                throw new PatternException("Cannot get module '" + moduleName +
+                                           "' in expression '" + this.originalExpr + "'", e);
+
+            } catch(ConfigurationException confEx) {
+                throw new PatternException("Cannot get variable '" + expr.getStringValue() +
+                    "' in expression '" + this.originalExpr + "'", confEx);
+
+            } finally {
+                this.manager.release(im);
+            }
+        } else if (type == SITEMAP_VAR) {
+            // Prefixed sitemap variable must be parsed at runtime
+            String variable = expr.getStringValue();
+            Token token;
+            if (variable.startsWith("/")) {
+                token = new Token(ROOT_SITEMAP_VARIABLE, variable.substring(1));
+            } else {
+                // Find level
+                int level = 1; // Start at 1 since it will be substracted from list.size()
+                int pos = 0;
+                while (variable.startsWith("../", pos)) {
+                    level++;
+                    pos += "../".length();
+                }
+                token = new Token(level, variable.substring(pos));
+            }
+            return processVariable(token, mapStack, stackSize);
+        } else {
+            throw new PatternException("Unknown token type: " + expr.getType());
+        }
+    }
+
+    private Token processVariable(Token expr, List mapStack, int stackSize) throws PatternException {
+        int type = expr.getType();
+        String value = expr.getStringValue();
+        if (type == ROOT_SITEMAP_VARIABLE) {
+            Object result = ((Map)mapStack.get(0)).get(value);
+            return new Token(EXPR, result==null ? "" : result.toString());
+        }
+        // relative sitemap variable
+        if (type > stackSize) {
+            throw new PatternException("Error while evaluating '" + this.originalExpr +
+                "' : not so many levels");
+        }
+
+        Object result = ((Map)mapStack.get(stackSize - type)).get(value);
+        return new Token(EXPR, result==null ? "" : result.toString());
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public final void dispose() {
+        if (this.manager != null) {
+            for (Iterator i = tokens.iterator(); i.hasNext();) {
+                Token token = (Token)i.next();
+                if (token.hasType(THREADSAFE_MODULE)) {
+                    InputModule im = token.getModule();
+                    this.manager.release(im);
+                }
+            }
+            this.tokens.clear();
+            this.manager = null;
+        }
+    }
+
+    private static final class Token {
+
+        private Object value;
+        private int type;
+
+        public Token(int type) {
+            if (type==EXPR) {
+                this.value="";
+            } else {
+                this.value = null;
+            }
+            this.type = type;
+        }
+
+        public Token(int type, String value) {
+            this.value = value;
+            this.type = type;
+        }
+
+        public Token(int type, InputModule module) {
+            this.value = module;
+            this.type = type;
+        }
+
+        public Token(String value) {
+            this.type = TEXT;
+            this.value = value;
+        }
+
+        public int getType() {
+          return type;
+        }
+
+        public String getStringValue() {
+            if (value instanceof String) {
+                return (String)this.value;
+            }
+            return null;
+        }
+
+        public boolean hasType(int type){
+            return this.type == type;
+        }
+
+        public boolean equals(Object o) {
+            if (o instanceof Token) {
+                return ((Token)o).hasType(this.type);
+            }
+            return false;
+        }
+
+        public void merge(Token newToken) {
+            this.value = this.value + newToken.getStringValue();
+        }
+
+        public InputModule getModule() {
+            if (value instanceof InputModule) {
+                return (InputModule)value;
+            }
+            return null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableExpressionTokenizer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableExpressionTokenizer.java
new file mode 100644
index 0000000..2946754
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableExpressionTokenizer.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import org.apache.cocoon.sitemap.PatternException;
+
+/**
+ * Parses "Text {module:{module:attribute}} more text {variable}" types of
+ * expressions. Supports escaping of braces with '\' character, and nested
+ * expressions.
+ *
+ * @version $Id$
+ */
+public final class VariableExpressionTokenizer {
+
+    /**
+     * Callback for tokenizer
+     */
+    public interface TokenReciever {
+        int OPEN = -2;
+        int CLOSE = -3;
+        int COLON = -4;
+        int TEXT = -5;
+        int MODULE = -6;
+        int VARIABLE = -8;
+
+        /**
+         * Reports parsed tokens.
+         */
+        void addToken(int type, String value) throws PatternException;
+    }
+
+    /**
+     * Tokenizes specified expression. Passes tokens to the
+     * reciever.
+     *
+     * @throws PatternException if expression is not valid
+     */
+    public static void tokenize(String expression, TokenReciever reciever) throws PatternException {
+
+        int lastTokenType = 0;
+
+        int openCount = 0;
+        int closeCount = 0;
+
+        int pos = 0;
+        int i;
+        boolean escape = false;
+
+        for (i = 0; i < expression.length(); i++) {
+            final char c = expression.charAt(i);
+
+            if (escape) {
+                escape = false;
+            } else if (c == '\\' && i < expression.length()) {
+                char nextChar = expression.charAt(i + 1);
+                if (nextChar == '{' || nextChar == '}') {
+                    expression = expression.substring(0, i) + expression.substring(i + 1);
+                    escape = true;
+                    i--;
+                }
+            } else if (c == '{') {
+                if (i > pos) {
+                    reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
+                }
+
+                openCount++;
+                reciever.addToken(lastTokenType = TokenReciever.OPEN, null);
+
+                int colonPos = indexOf(expression, ':', i);
+                int closePos = indexOf(expression, '}', i);
+                int openPos = indexOf(expression, '{', i);
+
+                if (openPos < colonPos && openPos < closePos) {
+                    throw new PatternException("Invalid '{' at position " + i +
+                                               " in expression \"" + expression + "\"");
+                }
+
+                if (colonPos < closePos) {
+                    // we've found a module
+                    String module = expression.substring(i + 1, colonPos);
+                    reciever.addToken(lastTokenType = TokenReciever.MODULE, module);
+                    i = colonPos - 1;
+                } else {
+                    // Unprefixed name: variable
+                    reciever.addToken(lastTokenType = TokenReciever.VARIABLE, expression.substring(i + 1, closePos));
+                    i = closePos - 1;
+                }
+
+                pos = i + 1;
+            } else if (c == '}') {
+                if (i > 0 && expression.charAt(i - 1) == '\\') {
+                    continue;
+                }
+                if (i > pos) {
+                    reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
+                }
+
+                closeCount++;
+                reciever.addToken(lastTokenType = TokenReciever.CLOSE, null);
+
+                pos = i + 1;
+            } else if (c == ':') {
+                if (lastTokenType != TokenReciever.MODULE || i != pos) {
+                    // this colon isn't part of a module reference
+                    continue;
+                }
+
+                reciever.addToken(lastTokenType = TokenReciever.COLON, null);
+                pos = i + 1;
+            }
+        }
+
+        if (i > pos) {
+            reciever.addToken(lastTokenType = TokenReciever.TEXT, expression.substring(pos, i));
+        }
+
+        if (openCount != closeCount) {
+            throw new PatternException("Mismatching braces in expression \"" + expression + "\"");
+        }
+    }
+
+    private static int indexOf(String expression, char chr, int pos) {
+        int location;
+        return (location = expression.indexOf(chr, pos + 1)) != -1? location : expression.length();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java
new file mode 100644
index 0000000..c67ba50
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolver.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
+/**
+ * Utility class for handling {...} pattern substitutions in sitemap statements.
+ *
+ * @version $Id$
+ */
+public abstract class VariableResolver {
+
+    public static final Map EMPTY_MAP = Collections.unmodifiableMap(new java.util.HashMap(0));
+
+    protected final String originalExpr;
+    
+    protected VariableResolver(String expr) {
+        this.originalExpr = expr;
+    }
+
+    public final String toString() {
+        return this.originalExpr;
+    }
+
+    /**
+     * Compare two VariableResolvers
+     */
+    public boolean equals(Object object) {
+        if (object instanceof VariableResolver) {
+            VariableResolver other = (VariableResolver)object;
+            return (this.originalExpr == null && other.originalExpr == null) ||
+                   (this.originalExpr.equals(other.originalExpr));
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * generate HashCode
+     * needed to determine uniqueness within hashtables
+     */
+    public int hashCode() {
+        return this.originalExpr == null ? 0 : this.originalExpr.hashCode();
+    }
+
+    /**
+     * Resolve all {...} patterns using the values given in the object model.
+     */
+    public String resolve(Map objectModel) throws PatternException {
+        return resolve(null, objectModel);
+    }
+
+    /**
+     * Resolve all {...} patterns using the values given in the list of maps and the object model.
+     */
+    public abstract String resolve(InvokeContext context, Map objectModel) throws PatternException;
+
+    /**
+     * Build a <code>Parameters</code> object from a Map of named <code>VariableResolver</code>s and
+     * a list of Maps used for resolution.
+     *
+     * @return a fully resolved <code>Parameters</code>.
+     */
+    public static Parameters buildParameters(Map expressions, InvokeContext context, Map objectModel) throws PatternException {
+        Location location;
+        if (expressions instanceof Locatable) {
+            location = ((Locatable)expressions).getLocation();
+        } else {
+            location = Location.UNKNOWN;
+        }
+        
+        if ((expressions == null || expressions.size() == 0) && location.equals(Location.UNKNOWN)) {
+            return Parameters.EMPTY_PARAMETERS;
+        }
+
+        SitemapParameters result = new SitemapParameters(location);
+
+        Iterator iter = expressions.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry)iter.next();
+            result.setParameter(
+                ((VariableResolver)entry.getKey()).resolve(context, objectModel),
+                ((VariableResolver)entry.getValue()).resolve(context, objectModel)
+            );
+        }
+
+        return result;
+    }
+
+    /**
+     * Build a <code>Map</code> from a Map of named <code>ListOfMapResolver</code>s and
+     * a list of Maps used for resolution.
+     *
+     * @return a fully resolved <code>Map</code>.
+     */
+    public static Map buildMap(Map expressions, InvokeContext context, Map objectModel) throws PatternException {
+        int size;
+        if (expressions == null || (size = expressions.size()) == 0) {
+            return EMPTY_MAP;
+        }
+
+        Map result;
+        if ( expressions instanceof Locatable ) {
+            result = new SitemapParameters.LocatedHashMap(((Locatable)expressions).getLocation(), size);   
+        } else {
+            result = new HashMap(size);
+        }
+
+        Iterator iter = expressions.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry)iter.next();
+            result.put(
+                ((VariableResolver)entry.getKey()).resolve(context, objectModel),
+                ((VariableResolver)entry.getValue()).resolve(context, objectModel)
+            );
+        }
+
+        return result;
+    }
+
+//    /**
+//     * Release a <code>Map</code> of expressions.
+//     */
+//    public static void release(Map expressions) {
+//        Iterator iter = expressions.entrySet().iterator();
+//        while (iter.hasNext()) {
+//            Map.Entry entry = (Map.Entry)iter.next();
+//            ((VariableResolver)entry.getKey()).release();
+//            ((VariableResolver)entry.getValue()).release();
+//        }
+//    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolverFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolverFactory.java
new file mode 100644
index 0000000..66a3ea8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/treeprocessor/variables/VariableResolverFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.List;
+
+/**
+ *
+ * @version $Id$
+ */
+public class VariableResolverFactory {
+
+    private static ThreadLocal disposableCollector = new ThreadLocal();
+
+    /**
+     * Set the thread-local list where all created resolvers that need to be
+     * disposed will be collected.
+     * <p>
+     * The purpose of collecting resolvers is to avoid manual release (or lack thereof)
+     * that requires most <code>ProcessingNodes</code> to implement <code>Disposable</code>.
+     */
+    public static void setDisposableCollector(List collector) {
+        disposableCollector.set(collector);
+    }
+
+    /**
+     * Does an expression need resolving (i.e. contain {...} patterns) ?
+     */
+    public static boolean needsResolve(String expression) {
+        if (expression == null || expression.length() == 0) {
+            return false;
+        }
+
+        // Is the first char a '{' ?
+        if (expression.charAt(0) == '{') {
+            return true;
+        }
+
+        if (expression.length() < 2) {
+            return false;
+        }
+
+        // Is there any unescaped '{' ?
+        int pos = 1;
+        while ( (pos = expression.indexOf('{', pos)) != -1) {
+            // Found a '{' : is it escaped ?
+            if (expression.charAt(pos - 1) != '\\') {
+                // No : need to resolve
+                return true;
+            }
+            pos++;
+        }
+        // Nothing found...
+        return false;
+    }
+
+    /**
+     * Unescape an expression that doesn't need to be resolved, but may contain
+     * escaped '{' characters.
+     *
+     * @param expression the expression to unescape.
+     * @return the unescaped result, or <code>expression</code> if unescaping isn't necessary.
+     */
+    public static String unescape(String expression) {
+        // Does it need escaping ?
+        if (expression == null || expression.indexOf("\\{") == -1) {
+            return expression;
+        }
+
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < expression.length(); i++) {
+            char ch = expression.charAt(i);
+            if (ch != '\\' || i >= (expression.length() - 1) || expression.charAt(i+1) != '{') {
+                buf.append(ch);
+            }
+        }
+
+        return buf.toString();
+    }
+
+    /**
+     * Get a resolver for a given expression. Chooses the most efficient implementation
+     * depending on <code>expression</code>.
+     */
+    public static VariableResolver getResolver(String expression, ServiceManager manager) throws PatternException {
+        if (needsResolve(expression)) {
+            VariableResolver resolver = new PreparedVariableResolver(expression, manager);
+            List collector = (List)disposableCollector.get();
+            if (collector != null)
+                collector.add(resolver);
+
+            return resolver;
+
+        }
+        return new NOPVariableResolver(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ElementPathPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ElementPathPart.java
new file mode 100644
index 0000000..2a32cc9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ElementPathPart.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.ProcessingException;
+
+import java.util.StringTokenizer;
+import java.util.ArrayList;
+import java.io.IOException;
+
+/**
+ * A custom XPointer scheme that allows to include the content of a specific element without
+ * building a DOM. The element must be specified using an absolute path reference such as
+ * <tt>/html/body</tt>. Namespace prefixes within these element names are supported.
+ *
+ * <p>This xpointer scheme will always be succesful (thus any further xpointer parts will
+ * never be executed).
+ *
+ * <p>The scheme name for this XPointer scheme is 'elementpath' and its namespace is
+ * http://apache.org/cocoon/xpointer.
+ *
+ * <p>See the samples for a usage example.
+ */
+public class ElementPathPart implements PointerPart {
+    private String expression;
+
+    public ElementPathPart(String expression) {
+        this.expression = expression;
+    }
+
+    public boolean process(XPointerContext xpointerContext) throws SAXException {
+        PathInclusionPipe pipe = new PathInclusionPipe(expression, xpointerContext);
+        pipe.setConsumer(xpointerContext.getXmlConsumer());
+        try {
+            SourceUtil.toSAX(xpointerContext.getSource(), pipe);
+        } catch (IOException e) {
+            throw new SAXException("Exception while trying to XInclude data: " + e.getMessage(), e);
+        } catch (ProcessingException e) {
+            throw new SAXException("Exception while trying to XInclude data: " + e.getMessage(), e);
+        }
+        return true;
+    }
+
+    public static class PathInclusionPipe extends AbstractXMLPipe {
+        /** The QNames that must be matched before inclusion can start. */
+        private QName[] elementPath;
+        /** The current element nesting level. */
+        private int level;
+        /** Should we currently be including? */
+        private boolean include;
+        /** The element nesting level since we started inclusion, used to know when to stop inclusion. */
+        private int includeLevel;
+
+        /** The element nesting level that should currently be matched. */
+        private int levelToMatch;
+        private boolean done;
+
+        public PathInclusionPipe(String expression, XPointerContext xpointerContext) throws SAXException {
+            // parse the expression to an array of QName objects
+            ArrayList path = new ArrayList();
+            StringTokenizer tokenizer = new StringTokenizer(expression, "/");
+            while (tokenizer.hasMoreTokens()) {
+                String token = tokenizer.nextToken();
+                try {
+                    path.add(QName.parse(token, xpointerContext));
+                } catch (SAXException e) {
+                    throw new SAXException("Error in element path xpointer expression \"" + expression + "\": " + e.getMessage());
+                }
+            }
+            if (path.size() < 1)
+                throw new SAXException("Invalid element path xpointer expression \"" + expression + "\".");
+
+            this.elementPath = (QName[])path.toArray(new QName[0]);
+            this.level = -1;
+            this.include = false;
+            this.levelToMatch = 0;
+            this.done = false;
+        }
+
+        public void startElement(String namespaceURI, String localName, String raw, Attributes a)
+                throws SAXException {
+            level++;
+
+            if (include) {
+                super.startElement(namespaceURI, localName, raw, a);
+                return;
+            }
+
+            if (!done && level == levelToMatch && elementPath[level].matches(namespaceURI, localName)) {
+                levelToMatch++;
+                if (levelToMatch == elementPath.length) {
+                    include = true;
+                    done = true;
+                    includeLevel = level;
+                }
+            }
+        }
+
+        public void endElement(String uri, String loc, String raw)
+                throws SAXException {
+            if (include && level == includeLevel)
+                include = false;
+
+            if (include)
+                super.endElement(uri, loc, raw);
+
+            level--;
+        }
+
+        public void setDocumentLocator(Locator locator) {
+            if (include)
+                super.setDocumentLocator(locator);
+        }
+
+        public void startDocument()
+                throws SAXException {
+            if (include)
+                super.startDocument();
+        }
+
+        public void endDocument()
+                throws SAXException {
+            if (include)
+                super.endDocument();
+        }
+
+        public void startPrefixMapping(String prefix, String uri)
+                throws SAXException {
+            // let namespace prefix alway through
+            super.startPrefixMapping(prefix, uri);
+        }
+
+        public void endPrefixMapping(String prefix)
+                throws SAXException {
+            // let namespace prefix alway through
+            super.endPrefixMapping(prefix);
+        }
+
+        public void characters(char c[], int start, int len)
+                throws SAXException {
+            if (include)
+                super.characters(c, start, len);
+        }
+
+        public void ignorableWhitespace(char c[], int start, int len)
+                throws SAXException {
+            if (include)
+                super.ignorableWhitespace(c, start, len);
+        }
+
+        public void processingInstruction(String target, String data)
+                throws SAXException {
+            if (include)
+                super.processingInstruction(target, data);
+        }
+
+        public void skippedEntity(String name)
+                throws SAXException {
+            if (include)
+                super.skippedEntity(name);
+        }
+
+        public void startDTD(String name, String publicId, String systemId)
+                throws SAXException {
+            if (include)
+                super.startDTD(name, publicId, systemId);
+        }
+
+        public void endDTD()
+                throws SAXException {
+            if (include)
+                super.endDTD();
+        }
+
+        public void startEntity(String name)
+                throws SAXException {
+            if (include)
+                super.startEntity(name);
+        }
+
+        public void endEntity(String name)
+                throws SAXException {
+            if (include)
+                super.endEntity(name);
+        }
+
+        public void startCDATA()
+                throws SAXException {
+            if (include)
+                super.startCDATA();
+        }
+
+        public void endCDATA()
+                throws SAXException {
+            if (include)
+                super.endCDATA();
+        }
+
+        public void comment(char ch[], int start, int len)
+                throws SAXException {
+            if (include)
+                super.comment(ch, start, len);
+        }
+
+        public static class QName {
+            private String namespaceURI;
+            private String localName;
+
+            public QName(String namespaceURI, String localName) {
+                this.namespaceURI = namespaceURI;
+                this.localName = localName;
+            }
+
+            public static QName parse(String qName, XPointerContext xpointerContext) throws SAXException {
+                int pos = qName.indexOf(':');
+                if (pos > 0) {
+                    String prefix = qName.substring(0, pos);
+                    String localName = qName.substring(pos + 1);
+                    String namespaceURI = xpointerContext.prefixToNamespace(prefix);
+                    if (namespaceURI == null)
+                        throw new SAXException("Namespace prefix \"" + prefix + "\" not declared.");
+                    return new QName(prefix, localName);
+                }
+                return new QName("", qName);
+            }
+
+            public String getNamespaceURI() {
+                return namespaceURI;
+            }
+
+            public String getLocalName() {
+                return localName;
+            }
+
+            public boolean matches(String namespaceURI, String localName) {
+                return this.localName.equals(localName) && this.namespaceURI.equals(namespaceURI);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/PointerPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/PointerPart.java
new file mode 100644
index 0000000..bee1432
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/PointerPart.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.xml.sax.SAXException;
+import org.apache.cocoon.ResourceNotFoundException;
+
+/**
+ * Interface to be implemented by pointer parts (xpointer schemes).
+ */
+public interface PointerPart {
+    /**
+     * If this pointer part successfully identifies any subresources, it should
+     * stream them to the XMLConsumer available from the XPointerContext and return true.
+     * Otherwise this method should return false.
+     */
+    public boolean process(XPointerContext xpointerContext) throws SAXException, ResourceNotFoundException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ShorthandPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ShorthandPart.java
new file mode 100644
index 0000000..f019587
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/ShorthandPart.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/**
+ * Implements support for shorthand XPointers (= id-based lookup). We treat them here as if they
+ * were a pointerpart too.
+ *
+ * <p>Note that although this is implemented here, this feature depends on the presence of a DTD,
+ * and a validating parser. Currently, this means its unuseable within Cocoon.
+ */
+public class ShorthandPart implements PointerPart {
+    private String shorthand;
+
+    public ShorthandPart(String shorthand) {
+        this.shorthand = shorthand;
+    }
+
+    public boolean process(XPointerContext xpointerContext) throws SAXException, ResourceNotFoundException {
+        Document document = xpointerContext.getDocument();
+        Element element = document.getElementById(shorthand);
+        if (element != null) {
+            DOMStreamer streamer = new DOMStreamer();
+            streamer.setConsumer(xpointerContext.getXmlConsumer());
+            streamer.stream(element);
+            return true;
+        } else {
+            if (xpointerContext.getLogger().isDebugEnabled())
+                xpointerContext.getLogger().debug("XPointer: found no element with id " + shorthand + " in document " + xpointerContext.getSource().getURI());
+        }
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/UnsupportedPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/UnsupportedPart.java
new file mode 100644
index 0000000..0da04d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/UnsupportedPart.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.xml.sax.SAXException;
+
+public class UnsupportedPart implements PointerPart {
+    private String schemeName;
+
+    public UnsupportedPart(String schemeName) {
+        this.schemeName = schemeName;
+    }
+
+    public boolean process(XPointerContext xpointerContext) throws SAXException {
+        throw new SAXException("Scheme " + schemeName + " not supported by this XPointer implementation, as used in the fragment identifier " + xpointerContext.getXPointer());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointer.java
new file mode 100644
index 0000000..47350c9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.xml.sax.SAXException;
+import org.apache.cocoon.ResourceNotFoundException;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+/**
+ * Represents a fragment identifier conforming to the XML Pointer Language Framework.
+ * See also the specification at <a href="http://www.w3.org/TR/2003/REC-xptr-framework-20030325">
+ * http://www.w3.org/TR/2003/REC-xptr-framework-20030325</a>.
+ *
+ * <p>To create an instance of this class, call
+ * {@link org.apache.cocoon.components.xpointer.parser.XPointerFrameworkParser#parse(String)}.
+ */
+public class XPointer {
+    private List pointerParts = new LinkedList();
+
+    public void addPart(PointerPart part) {
+        pointerParts.add(part);
+    }
+
+    public void process(XPointerContext context) throws SAXException, ResourceNotFoundException {
+        Iterator pointerPartsIt = pointerParts.iterator();
+        while (pointerPartsIt.hasNext()) {
+            PointerPart part = (PointerPart)pointerPartsIt.next();
+            part.process(context);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerContext.java
new file mode 100644
index 0000000..ffdfd3e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerContext.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.w3c.dom.Document;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.xml.xpath.PrefixResolver;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.xml.sax.SAXException;
+
+import java.util.HashMap;
+
+/**
+ * A context object used during the evaluating of XPointers.
+ */
+public class XPointerContext implements PrefixResolver {
+    private Source source;
+    private Document document;
+    private XMLConsumer xmlConsumer;
+    private Logger logger;
+    private String xpointer;
+    private HashMap prefixes = new HashMap();
+    private ServiceManager manager;
+
+    /**
+     * Constructs an XPointerContext object.
+     *
+     * @param xpointer the original fragment identifier string, used for debugging purposes
+     * @param source the source into which the xpointer points
+     * @param xmlConsumer the consumer to which the result of the xpointer evaluation should be send
+     */
+    public XPointerContext(String xpointer, Source source, XMLConsumer xmlConsumer, Logger logger, ServiceManager manager) {
+        this.source = source;
+        this.xmlConsumer = xmlConsumer;
+        this.logger = logger;
+        this.manager = manager;
+        this.xpointer = xpointer;
+
+        prefixes.put("xml", "http://www.w3.org/XML/1998/namespace");
+    }
+
+    public Document getDocument() throws SAXException, ResourceNotFoundException {
+        if (document == null) {
+            try {
+                document = SourceUtil.toDOM(source);
+            } catch (ResourceNotFoundException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new SAXException("Error during XPointer evaluation while trying to load " + source.getURI(), e);
+            }
+        }
+        return document;
+    }
+
+    public Source getSource() {
+        return source;
+    }
+
+    public XMLConsumer getXmlConsumer() {
+        return xmlConsumer;
+    }
+
+    public Logger getLogger() {
+        return logger;
+    }
+
+    public String getXPointer() {
+        return xpointer;
+    }
+
+    public ServiceManager getServiceManager() {
+        return manager;
+    }
+
+    public void addPrefix(String prefix, String namespace) throws SAXException {
+        // according to the xmlns() scheme spec, these should not result to any change in namespace context
+        if (prefix.equalsIgnoreCase("xml"))
+            return;
+        else if (prefix.equals("xmlns"))
+            return;
+        else if (namespace.equals("http://www.w3.org/XML/1998/namespace"))
+            return;
+        else if (namespace.equals("http://www.w3.org/2000/xmlns/"))
+            return;
+
+        prefixes.put(prefix, namespace);
+    }
+
+    public String prefixToNamespace(String prefix) {
+        return (String)prefixes.get(prefix);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerPart.java
new file mode 100644
index 0000000..ce912a2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XPointerPart.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * Partly implementation of the xpointer() scheme. Only the XPath subset of xpointer is supported.
+ */
+public class XPointerPart implements PointerPart {
+    private String expression;
+
+    public XPointerPart(String expression) {
+        this.expression = expression;
+    }
+
+    public boolean process(XPointerContext xpointerContext) throws SAXException, ResourceNotFoundException {
+        Document document = xpointerContext.getDocument();
+        ServiceManager manager = xpointerContext.getServiceManager();
+        XPathProcessor xpathProcessor = null;
+        try {
+            try {
+                xpathProcessor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
+            } catch (Exception e) {
+                throw new SAXException("XPointerPart: error looking up XPathProcessor.", e);
+            }
+            NodeList nodeList = xpathProcessor.selectNodeList(document, expression, xpointerContext);
+            if (nodeList.getLength() > 0) {
+                XMLConsumer consumer = xpointerContext.getXmlConsumer();
+                LocatorImpl locator = new LocatorImpl();
+                locator.setSystemId(xpointerContext.getSource().getURI());
+                consumer.setDocumentLocator(locator);
+                for (int i = 0; i < nodeList.getLength(); i++) {
+                    DOMStreamer streamer = new DOMStreamer();
+                    streamer.setConsumer(consumer);
+                    streamer.stream(nodeList.item(i));
+                }
+                return true;
+            } else {
+                if (xpointerContext.getLogger().isDebugEnabled())
+                    xpointerContext.getLogger().debug("XPointer: expression \"" + expression + "\" gave no results.");
+                return false;
+            }
+        } finally {
+            if (xpathProcessor != null)
+                manager.release(xpathProcessor);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XmlnsPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XmlnsPart.java
new file mode 100644
index 0000000..002c02b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/XmlnsPart.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Implements support for the XPointer xmlns() Scheme.
+ * See also <a href="http://www.w3.org/TR/xptr-xmlns/">http://www.w3.org/TR/xptr-xmlns/</a>.
+ */
+public class XmlnsPart implements PointerPart {
+    private String prefix;
+    private String namespace;
+
+    /**
+     * Creates an XmlnsPart.
+     */
+    public XmlnsPart(String prefix, String namespace) {
+        this.prefix = prefix;
+        this.namespace = namespace;
+    }
+
+    public boolean process(XPointerContext xpointerContext) throws SAXException {
+        xpointerContext.addPrefix(prefix, namespace);
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/ParseException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/ParseException.java
new file mode 100644
index 0000000..7efa61f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/ParseException.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+    /**
+     * This constructor is used by the method "generateParseException"
+     * in the generated parser.  Calling this constructor generates
+     * a new object of this type with the fields "currentToken",
+     * "expectedTokenSequences", and "tokenImage" set.  The boolean
+     * flag "specialConstructor" is also set to true to indicate that
+     * this constructor was used to create this object.
+     * This constructor calls its super class with the empty string
+     * to force the "toString" method of parent class "Throwable" to
+     * print the error message in the form:
+     *     ParseException: <result of getMessage>
+     */
+    public ParseException(
+        Token currentTokenVal,
+        int[][] expectedTokenSequencesVal,
+        String[] tokenImageVal) {
+        super("");
+        specialConstructor = true;
+        currentToken = currentTokenVal;
+        expectedTokenSequences = expectedTokenSequencesVal;
+        tokenImage = tokenImageVal;
+    }
+
+    /**
+     * The following constructors are for use by you for whatever
+     * purpose you can think of.  Constructing the exception in this
+     * manner makes the exception behave in the normal way - i.e., as
+     * documented in the class "Throwable".  The fields "errorToken",
+     * "expectedTokenSequences", and "tokenImage" do not contain
+     * relevant information.  The JavaCC generated code does not use
+     * these constructors.
+     */
+
+    public ParseException() {
+        super();
+        specialConstructor = false;
+    }
+
+    public ParseException(String message) {
+        super(message);
+        specialConstructor = false;
+    }
+
+    /**
+     * This variable determines which constructor was used to create
+     * this object and thereby affects the semantics of the
+     * "getMessage" method (see below).
+     */
+    protected boolean specialConstructor;
+
+    /**
+     * This is the last token that has been consumed successfully.  If
+     * this object has been created due to a parse error, the token
+     * followng this token will (therefore) be the first error token.
+     */
+    public Token currentToken;
+
+    /**
+     * Each entry in this array is an array of integers.  Each array
+     * of integers represents a sequence of tokens (by their ordinal
+     * values) that is expected at this point of the parse.
+     */
+    public int[][] expectedTokenSequences;
+
+    /**
+     * This is a reference to the "tokenImage" array of the generated
+     * parser within which the parse error occurred.  This array is
+     * defined in the generated ...Constants interface.
+     */
+    public String[] tokenImage;
+
+    /**
+     * This method has the standard behavior when this object has been
+     * created using the standard constructors.  Otherwise, it uses
+     * "currentToken" and "expectedTokenSequences" to generate a parse
+     * error message and returns it.  If this object has been created
+     * due to a parse error, and you do not catch it (it gets thrown
+     * from the parser), then this method is called during the printing
+     * of the final stack trace, and hence the correct error message
+     * gets displayed.
+     */
+    public String getMessage() {
+        if (!specialConstructor) {
+            return super.getMessage();
+        }
+        String expected = "";
+        int maxSize = 0;
+        for (int i = 0; i < expectedTokenSequences.length; i++) {
+            if (maxSize < expectedTokenSequences[i].length) {
+                maxSize = expectedTokenSequences[i].length;
+            }
+            for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+                expected += tokenImage[expectedTokenSequences[i][j]] + " ";
+            }
+            if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1]
+                != 0) {
+                expected += "...";
+            }
+            expected += eol + "    ";
+        }
+        String retval = "Encountered \"";
+        Token tok = currentToken.next;
+        for (int i = 0; i < maxSize; i++) {
+            if (i != 0)
+                retval += " ";
+            if (tok.kind == 0) {
+                retval += tokenImage[0];
+                break;
+            }
+            retval += add_escapes(tok.image);
+            tok = tok.next;
+        }
+        retval += "\" at line "
+            + currentToken.next.beginLine
+            + ", column "
+            + currentToken.next.beginColumn;
+        retval += "." + eol;
+        if (expectedTokenSequences.length == 1) {
+            retval += "Was expecting:" + eol + "    ";
+        } else {
+            retval += "Was expecting one of:" + eol + "    ";
+        }
+        retval += expected;
+        return retval;
+    }
+
+    /**
+     * The end of line string for this machine.
+     */
+    protected String eol = System.getProperty("line.separator", "\n");
+
+    /**
+     * Used to convert raw characters to their escaped version
+     * when these raw version cannot be used as part of an ASCII
+     * string literal.
+     */
+    protected String add_escapes(String str) {
+        StringBuffer retval = new StringBuffer();
+        char ch;
+        for (int i = 0; i < str.length(); i++) {
+            switch (str.charAt(i)) {
+                case 0 :
+                    continue;
+                case '\b' :
+                    retval.append("\\b");
+                    continue;
+                case '\t' :
+                    retval.append("\\t");
+                    continue;
+                case '\n' :
+                    retval.append("\\n");
+                    continue;
+                case '\f' :
+                    retval.append("\\f");
+                    continue;
+                case '\r' :
+                    retval.append("\\r");
+                    continue;
+                case '\"' :
+                    retval.append("\\\"");
+                    continue;
+                case '\'' :
+                    retval.append("\\\'");
+                    continue;
+                case '\\' :
+                    retval.append("\\\\");
+                    continue;
+                default :
+                    if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                        String s = "0000" + Integer.toString(ch, 16);
+                        retval.append(
+                            "\\u" + s.substring(s.length() - 4, s.length()));
+                    } else {
+                        retval.append(ch);
+                    }
+                    continue;
+            }
+        }
+        return retval.toString();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/SimpleCharStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/SimpleCharStream.java
new file mode 100644
index 0000000..59f613c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/SimpleCharStream.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream {
+    public static final boolean staticFlag = false;
+    int bufsize;
+    int available;
+    int tokenBegin;
+    public int bufpos = -1;
+    protected int bufline[];
+    protected int bufcolumn[];
+
+    protected int column = 0;
+    protected int line = 1;
+
+    protected boolean prevCharIsCR = false;
+    protected boolean prevCharIsLF = false;
+
+    protected java.io.Reader inputStream;
+
+    protected char[] buffer;
+    protected int maxNextCharInd = 0;
+    protected int inBuf = 0;
+
+    protected void ExpandBuff(boolean wrapAround) {
+        char[] newbuffer = new char[bufsize + 2048];
+        int newbufline[] = new int[bufsize + 2048];
+        int newbufcolumn[] = new int[bufsize + 2048];
+
+        try {
+            if (wrapAround) {
+                System.arraycopy(
+                    buffer,
+                    tokenBegin,
+                    newbuffer,
+                    0,
+                    bufsize - tokenBegin);
+                System.arraycopy(
+                    buffer,
+                    0,
+                    newbuffer,
+                    bufsize - tokenBegin,
+                    bufpos);
+                buffer = newbuffer;
+
+                System.arraycopy(
+                    bufline,
+                    tokenBegin,
+                    newbufline,
+                    0,
+                    bufsize - tokenBegin);
+                System.arraycopy(
+                    bufline,
+                    0,
+                    newbufline,
+                    bufsize - tokenBegin,
+                    bufpos);
+                bufline = newbufline;
+
+                System.arraycopy(
+                    bufcolumn,
+                    tokenBegin,
+                    newbufcolumn,
+                    0,
+                    bufsize - tokenBegin);
+                System.arraycopy(
+                    bufcolumn,
+                    0,
+                    newbufcolumn,
+                    bufsize - tokenBegin,
+                    bufpos);
+                bufcolumn = newbufcolumn;
+
+                maxNextCharInd = (bufpos += (bufsize - tokenBegin));
+            } else {
+                System.arraycopy(
+                    buffer,
+                    tokenBegin,
+                    newbuffer,
+                    0,
+                    bufsize - tokenBegin);
+                buffer = newbuffer;
+
+                System.arraycopy(
+                    bufline,
+                    tokenBegin,
+                    newbufline,
+                    0,
+                    bufsize - tokenBegin);
+                bufline = newbufline;
+
+                System.arraycopy(
+                    bufcolumn,
+                    tokenBegin,
+                    newbufcolumn,
+                    0,
+                    bufsize - tokenBegin);
+                bufcolumn = newbufcolumn;
+
+                maxNextCharInd = (bufpos -= tokenBegin);
+            }
+        } catch (Throwable t) {
+            throw new Error(t.getMessage());
+        }
+
+        bufsize += 2048;
+        available = bufsize;
+        tokenBegin = 0;
+    }
+
+    protected void FillBuff() throws java.io.IOException {
+        if (maxNextCharInd == available) {
+            if (available == bufsize) {
+                if (tokenBegin > 2048) {
+                    bufpos = maxNextCharInd = 0;
+                    available = tokenBegin;
+                } else if (tokenBegin < 0)
+                    bufpos = maxNextCharInd = 0;
+                else
+                    ExpandBuff(false);
+            } else if (available > tokenBegin)
+                available = bufsize;
+            else if ((tokenBegin - available) < 2048)
+                ExpandBuff(true);
+            else
+                available = tokenBegin;
+        }
+
+        int i;
+        try {
+            if ((i =
+                inputStream.read(
+                    buffer,
+                    maxNextCharInd,
+                    available - maxNextCharInd))
+                == -1) {
+                inputStream.close();
+                throw new java.io.IOException();
+            } else
+                maxNextCharInd += i;
+            return;
+        } catch (java.io.IOException e) {
+            --bufpos;
+            backup(0);
+            if (tokenBegin == -1)
+                tokenBegin = bufpos;
+            throw e;
+        }
+    }
+
+    public char BeginToken() throws java.io.IOException {
+        tokenBegin = -1;
+        char c = readChar();
+        tokenBegin = bufpos;
+
+        return c;
+    }
+
+    protected void UpdateLineColumn(char c) {
+        column++;
+
+        if (prevCharIsLF) {
+            prevCharIsLF = false;
+            line += (column = 1);
+        } else if (prevCharIsCR) {
+            prevCharIsCR = false;
+            if (c == '\n') {
+                prevCharIsLF = true;
+            } else
+                line += (column = 1);
+        }
+
+        switch (c) {
+            case '\r' :
+                prevCharIsCR = true;
+                break;
+            case '\n' :
+                prevCharIsLF = true;
+                break;
+            case '\t' :
+                column--;
+                column += (8 - (column & 07));
+                break;
+            default :
+                break;
+        }
+
+        bufline[bufpos] = line;
+        bufcolumn[bufpos] = column;
+    }
+
+    public char readChar() throws java.io.IOException {
+        if (inBuf > 0) {
+            --inBuf;
+
+            if (++bufpos == bufsize)
+                bufpos = 0;
+
+            return buffer[bufpos];
+        }
+
+        if (++bufpos >= maxNextCharInd)
+            FillBuff();
+
+        char c = buffer[bufpos];
+
+        UpdateLineColumn(c);
+        return (c);
+    }
+
+    public int getEndColumn() {
+        return bufcolumn[bufpos];
+    }
+
+    public int getEndLine() {
+        return bufline[bufpos];
+    }
+
+    public int getBeginColumn() {
+        return bufcolumn[tokenBegin];
+    }
+
+    public int getBeginLine() {
+        return bufline[tokenBegin];
+    }
+
+    public void backup(int amount) {
+
+        inBuf += amount;
+        if ((bufpos -= amount) < 0)
+            bufpos += bufsize;
+    }
+
+    public SimpleCharStream(
+        java.io.Reader dstream,
+        int startline,
+        int startcolumn,
+        int buffersize) {
+        inputStream = dstream;
+        line = startline;
+        column = startcolumn - 1;
+
+        available = bufsize = buffersize;
+        buffer = new char[buffersize];
+        bufline = new int[buffersize];
+        bufcolumn = new int[buffersize];
+    }
+
+    public SimpleCharStream(
+        java.io.Reader dstream,
+        int startline,
+        int startcolumn) {
+        this(dstream, startline, startcolumn, 4096);
+    }
+
+    public SimpleCharStream(java.io.Reader dstream) {
+        this(dstream, 1, 1, 4096);
+    }
+    public void ReInit(
+        java.io.Reader dstream,
+        int startline,
+        int startcolumn,
+        int buffersize) {
+        inputStream = dstream;
+        line = startline;
+        column = startcolumn - 1;
+
+        if (buffer == null || buffersize != buffer.length) {
+            available = bufsize = buffersize;
+            buffer = new char[buffersize];
+            bufline = new int[buffersize];
+            bufcolumn = new int[buffersize];
+        }
+        prevCharIsLF = prevCharIsCR = false;
+        tokenBegin = inBuf = maxNextCharInd = 0;
+        bufpos = -1;
+    }
+
+    public void ReInit(
+        java.io.Reader dstream,
+        int startline,
+        int startcolumn) {
+        ReInit(dstream, startline, startcolumn, 4096);
+    }
+
+    public void ReInit(java.io.Reader dstream) {
+        ReInit(dstream, 1, 1, 4096);
+    }
+    public SimpleCharStream(
+        java.io.InputStream dstream,
+        int startline,
+        int startcolumn,
+        int buffersize) {
+        this(
+            new java.io.InputStreamReader(dstream),
+            startline,
+            startcolumn,
+            buffersize);
+    }
+
+    public SimpleCharStream(
+        java.io.InputStream dstream,
+        int startline,
+        int startcolumn) {
+        this(dstream, startline, startcolumn, 4096);
+    }
+
+    public SimpleCharStream(java.io.InputStream dstream) {
+        this(dstream, 1, 1, 4096);
+    }
+
+    public void ReInit(
+        java.io.InputStream dstream,
+        int startline,
+        int startcolumn,
+        int buffersize) {
+        ReInit(
+            new java.io.InputStreamReader(dstream),
+            startline,
+            startcolumn,
+            buffersize);
+    }
+
+    public void ReInit(java.io.InputStream dstream) {
+        ReInit(dstream, 1, 1, 4096);
+    }
+    public void ReInit(
+        java.io.InputStream dstream,
+        int startline,
+        int startcolumn) {
+        ReInit(dstream, startline, startcolumn, 4096);
+    }
+    public String GetImage() {
+        if (bufpos >= tokenBegin)
+            return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+        else
+            return new String(buffer, tokenBegin, bufsize - tokenBegin)
+                + new String(buffer, 0, bufpos + 1);
+    }
+
+    public char[] GetSuffix(int len) {
+        char[] ret = new char[len];
+
+        if ((bufpos + 1) >= len)
+            System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+        else {
+            System.arraycopy(
+                buffer,
+                bufsize - (len - bufpos - 1),
+                ret,
+                0,
+                len - bufpos - 1);
+            System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+        }
+
+        return ret;
+    }
+
+    public void Done() {
+        buffer = null;
+        bufline = null;
+        bufcolumn = null;
+    }
+
+    /**
+     * Method to adjust line and column numbers for the start of a token.<BR>
+     */
+    public void adjustBeginLineColumn(int newLine, int newCol) {
+        int start = tokenBegin;
+        int len;
+
+        if (bufpos >= tokenBegin) {
+            len = bufpos - tokenBegin + inBuf + 1;
+        } else {
+            len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+        }
+
+        int i = 0, j = 0, k = 0;
+        int nextColDiff = 0, columnDiff = 0;
+
+        while (i < len && bufline[j =
+            start % bufsize] == bufline[k = ++start % bufsize]) {
+            bufline[j] = newLine;
+            nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+            bufcolumn[j] = newCol + columnDiff;
+            columnDiff = nextColDiff;
+            i++;
+        }
+
+        if (i < len) {
+            bufline[j] = newLine++;
+            bufcolumn[j] = newCol + columnDiff;
+
+            while (i++ < len) {
+                if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+                    bufline[j] = newLine++;
+                else
+                    bufline[j] = newLine;
+            }
+        }
+
+        line = bufline[j];
+        column = bufcolumn[j];
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/Token.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/Token.java
new file mode 100644
index 0000000..fd40932
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/Token.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+
+    /**
+     * An integer that describes the kind of this token.  This numbering
+     * system is determined by JavaCCParser, and a table of these numbers is
+     * stored in the file ...Constants.java.
+     */
+    public int kind;
+
+    /**
+     * beginLine and beginColumn describe the position of the first character
+     * of this token; endLine and endColumn describe the position of the
+     * last character of this token.
+     */
+    public int beginLine, beginColumn, endLine, endColumn;
+
+    /**
+     * The string image of the token.
+     */
+    public String image;
+
+    /**
+     * A reference to the next regular (non-special) token from the input
+     * stream.  If this is the last token from the input stream, or if the
+     * token manager has not read tokens beyond this one, this field is
+     * set to null.  This is true only if this token is also a regular
+     * token.  Otherwise, see below for a description of the contents of
+     * this field.
+     */
+    public Token next;
+
+    /**
+     * This field is used to access special tokens that occur prior to this
+     * token, but after the immediately preceding regular (non-special) token.
+     * If there are no such special tokens, this field is set to null.
+     * When there are more than one such special token, this field refers
+     * to the last of these special tokens, which in turn refers to the next
+     * previous special token through its specialToken field, and so on
+     * until the first special token (whose specialToken field is null).
+     * The next fields of special tokens refer to other special tokens that
+     * immediately follow it (without an intervening regular token).  If there
+     * is no such token, this field is null.
+     */
+    public Token specialToken;
+
+    /**
+     * Returns the image.
+     */
+    public String toString() {
+        return image;
+    }
+
+    /**
+     * Returns a new Token object, by default. However, if you want, you
+     * can create and return subclass objects based on the value of ofKind.
+     * Simply add the cases to the switch for all those special cases.
+     * For example, if you have a subclass of Token called IDToken that
+     * you want to create if ofKind is ID, simlpy add something like :
+     *
+     *    case MyParserConstants.ID : return new IDToken();
+     *
+     * to the following switch statement. Then you can cast matchedToken
+     * variable to the appropriate type and use it in your lexical actions.
+     */
+    public static final Token newToken(int ofKind) {
+        switch (ofKind) {
+            default :
+                return new Token();
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/TokenMgrError.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/TokenMgrError.java
new file mode 100644
index 0000000..1f08c1a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/TokenMgrError.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+public class TokenMgrError extends Error {
+    /*
+     * Ordinals for various reasons why an Error of this type can be thrown.
+     */
+
+    /**
+     * Lexical error occured.
+     */
+    static final int LEXICAL_ERROR = 0;
+
+    /**
+     * An attempt wass made to create a second instance of a static token manager.
+     */
+    static final int STATIC_LEXER_ERROR = 1;
+
+    /**
+     * Tried to change to an invalid lexical state.
+     */
+    static final int INVALID_LEXICAL_STATE = 2;
+
+    /**
+     * Detected (and bailed out of) an infinite loop in the token manager.
+     */
+    static final int LOOP_DETECTED = 3;
+
+    /**
+     * Indicates the reason why the exception is thrown. It will have
+     * one of the above 4 values.
+     */
+    int errorCode;
+
+    /**
+     * Replaces unprintable characters by their espaced (or unicode escaped)
+     * equivalents in the given string
+     */
+    protected static final String addEscapes(String str) {
+        StringBuffer retval = new StringBuffer();
+        char ch;
+        for (int i = 0; i < str.length(); i++) {
+            switch (str.charAt(i)) {
+                case 0 :
+                    continue;
+                case '\b' :
+                    retval.append("\\b");
+                    continue;
+                case '\t' :
+                    retval.append("\\t");
+                    continue;
+                case '\n' :
+                    retval.append("\\n");
+                    continue;
+                case '\f' :
+                    retval.append("\\f");
+                    continue;
+                case '\r' :
+                    retval.append("\\r");
+                    continue;
+                case '\"' :
+                    retval.append("\\\"");
+                    continue;
+                case '\'' :
+                    retval.append("\\\'");
+                    continue;
+                case '\\' :
+                    retval.append("\\\\");
+                    continue;
+                default :
+                    if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                        String s = "0000" + Integer.toString(ch, 16);
+                        retval.append(
+                            "\\u" + s.substring(s.length() - 4, s.length()));
+                    } else {
+                        retval.append(ch);
+                    }
+                    continue;
+            }
+        }
+        return retval.toString();
+    }
+
+    /**
+     * Returns a detailed message for the Error when it is thrown by the
+     * token manager to indicate a lexical error.
+     * Parameters : 
+     *    EOFSeen     : indicates if EOF caused the lexicl error
+     *    curLexState : lexical state in which this error occured
+     *    errorLine   : line number when the error occured
+     *    errorColumn : column number when the error occured
+     *    errorAfter  : prefix that was seen before this error occured
+     *    curchar     : the offending character
+     * Note: You can customize the lexical error message by modifying this method.
+     */
+    protected static String LexicalError(
+        boolean EOFSeen,
+        int lexState,
+        int errorLine,
+        int errorColumn,
+        String errorAfter,
+        char curChar) {
+        return (
+            "Lexical error at line "
+                + errorLine
+                + ", column "
+                + errorColumn
+                + ".  Encountered: "
+                + (EOFSeen
+                    ? "<EOF> "
+                    : ("\"" + addEscapes(String.valueOf(curChar)) + "\"")
+                        + " ("
+                        + (int) curChar
+                        + "), ")
+                + "after : \""
+                + addEscapes(errorAfter)
+                + "\"");
+    }
+
+    /**
+     * You can also modify the body of this method to customize your error messages.
+     * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+     * of end-users concern, so you can return something like : 
+     *
+     *     "Internal Error : Please file a bug report .... "
+     *
+     * from this method for such cases in the release version of your parser.
+     */
+    public String getMessage() {
+        return super.getMessage();
+    }
+
+    /*
+     * Constructors of various flavors follow.
+     */
+
+    public TokenMgrError() {
+    }
+
+    public TokenMgrError(String message, int reason) {
+        super(message);
+        errorCode = reason;
+    }
+
+    public TokenMgrError(
+        boolean EOFSeen,
+        int lexState,
+        int errorLine,
+        int errorColumn,
+        String errorAfter,
+        char curChar,
+        int reason) {
+        this(
+            LexicalError(
+                EOFSeen,
+                lexState,
+                errorLine,
+                errorColumn,
+                errorAfter,
+                curChar),
+            reason);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParser.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParser.java
new file mode 100644
index 0000000..342f73d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParser.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+import java.util.HashMap;
+
+import org.apache.cocoon.components.xpointer.ElementPathPart;
+import org.apache.cocoon.components.xpointer.ShorthandPart;
+import org.apache.cocoon.components.xpointer.UnsupportedPart;
+import org.apache.cocoon.components.xpointer.XPointer;
+import org.apache.cocoon.components.xpointer.XPointerPart;
+import org.apache.cocoon.components.xpointer.XmlnsPart;
+
+public class XPointerFrameworkParser
+    implements XPointerFrameworkParserConstants {
+    private XPointer xpointer = new XPointer();
+    private HashMap namespaces = new HashMap();
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("will parse this: " + args[0]);
+        XPointerFrameworkParser xfp =
+            new XPointerFrameworkParser(new java.io.StringReader(args[0]));
+        xfp.pointer();
+    }
+
+    public static XPointer parse(String xpointer) throws ParseException {
+        XPointerFrameworkParser xfp =
+            new XPointerFrameworkParser(new java.io.StringReader(xpointer));
+        try {
+            xfp.pointer();
+        } catch (TokenMgrError e) {
+            // Rethrow TokenMgrErrors as ParseExceptions, because errors aren't caught by Cocoon,
+            // and mistyping in a xpointer isn't such a grave error
+            throw new ParseException(e.getMessage());
+        }
+        return xfp.getXPointer();
+    }
+
+    public XPointer getXPointer() {
+        return xpointer;
+    }
+
+    private String unescape(String data) throws ParseException {
+        StringBuffer result = new StringBuffer(data.length());
+        boolean inCircumflex = false;
+        for (int i = 0; i < data.length(); i++) {
+            char c = data.charAt(i);
+            if (inCircumflex) {
+                switch (c) {
+                    case '^' :
+                    case '(' :
+                    case ')' :
+                        result.append(c);
+                        inCircumflex = false;
+                        break;
+                    default :
+                        throw new ParseException(
+                            "Incorrect use of circumflex character at position "
+                                + i
+                                + " in the string "
+                                + data);
+                }
+            } else if (c == '^') {
+                inCircumflex = true;
+            } else {
+                result.append(c);
+            }
+        }
+        return result.toString();
+    }
+
+    final public void pointer() throws ParseException {
+        if (jj_2_1(2)) {
+            schemeBased();
+        } else {
+            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+                case NCName :
+                    shortHand();
+                    break;
+                default :
+                    jj_la1[0] = jj_gen;
+                    jj_consume_token(-1);
+                    throw new ParseException();
+            }
+        }
+    }
+
+    final public void shortHand() throws ParseException {
+        Token x;
+        x = jj_consume_token(NCName);
+        xpointer.addPart(new ShorthandPart(x.image));
+    }
+
+    final public void schemeBased() throws ParseException {
+        pointerPart();
+        label_1 : while (true) {
+            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+                case NCName :
+                case WS :
+                case QName :
+                    break;
+                default :
+                    jj_la1[1] = jj_gen;
+                    break label_1;
+            }
+            label_2 : while (true) {
+                switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+                    case WS :
+                        break;
+                    default :
+                        jj_la1[2] = jj_gen;
+                        break label_2;
+                }
+                jj_consume_token(WS);
+            }
+            pointerPart();
+        }
+    }
+
+    final public void pointerPart() throws ParseException {
+        Token x;
+        String schemeName;
+        String schemeData;
+        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+            case NCName :
+                x = jj_consume_token(NCName);
+                break;
+            case QName :
+                x = jj_consume_token(QName);
+                break;
+            default :
+                jj_la1[3] = jj_gen;
+                jj_consume_token(-1);
+                throw new ParseException();
+        }
+        jj_consume_token(LBRACE);
+        // when going inside the scheme data, swith to a different lexical state
+        token_source.SwitchTo(IN_SCHEME);
+
+        // store the scheme name
+        schemeName = x.image;
+        schemeData = schemeData();
+        jj_consume_token(RBRACE);
+        // when going outside the scheme data, swith back to the default lexical state
+        token_source.SwitchTo(DEFAULT);
+
+        // parse schemeName in prefix and localName
+        String schemeNamespace = null, schemeLocalName = null;
+        int colonPos = schemeName.indexOf(':');
+        if (colonPos != -1) {
+            String schemePrefix = schemeName.substring(0, colonPos);
+            schemeNamespace = (String) namespaces.get(schemePrefix);
+            schemeLocalName = schemeName.substring(colonPos + 1);
+        } else {
+            schemeLocalName = schemeName;
+        }
+
+        // add the pointer part
+        if (schemeNamespace == null && schemeLocalName.equals("xmlns")) {
+            int eqPos = schemeData.indexOf("=");
+            if (eqPos == -1) {
+                if (true)
+                    throw new ParseException("xmlns scheme data should contain an equals sign");
+            }
+
+            // Note: the trimming below is not entirely correct, since space is only allowed left
+            // and right of the equal sign, but not at the beginning and end of the schemeData
+            String prefix = schemeData.substring(0, eqPos).trim();
+            String namespace =
+                schemeData.substring(eqPos + 1, schemeData.length()).trim();
+            xpointer.addPart(new XmlnsPart(prefix, namespace));
+            namespaces.put(prefix, namespace);
+        } else if (
+            schemeNamespace == null && schemeLocalName.equals("xpointer")) {
+            xpointer.addPart(new XPointerPart(schemeData));
+        } else if (
+            "http://apache.org/cocoon/xpointer".equals(schemeNamespace)
+                && schemeLocalName.equals("elementpath")) {
+            xpointer.addPart(new ElementPathPart(schemeData));
+        } else {
+            xpointer.addPart(new UnsupportedPart(schemeName));
+        }
+    }
+
+    final public String schemeData() throws ParseException {
+        String temp;
+        StringBuffer schemeData = new StringBuffer();
+        label_3 : while (true) {
+            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+                case LBRACE :
+                case CIRC_LBRACE :
+                case CIRC_RBRACE :
+                case DOUBLE_CIRC :
+                case NormalChar :
+                    break;
+                default :
+                    jj_la1[4] = jj_gen;
+                    break label_3;
+            }
+            temp = escapedData();
+            schemeData.append(temp);
+        }
+        {
+            if (true)
+                return unescape(schemeData.toString());
+        }
+        throw new Error("Missing return statement in function");
+    }
+
+    final public String escapedData() throws ParseException {
+        Token x;
+        String temp;
+        StringBuffer data = new StringBuffer();
+        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+            case NormalChar :
+                x = jj_consume_token(NormalChar);
+                data.append(x.image);
+                break;
+            case CIRC_LBRACE :
+                x = jj_consume_token(CIRC_LBRACE);
+                data.append(x.image);
+                break;
+            case CIRC_RBRACE :
+                x = jj_consume_token(CIRC_RBRACE);
+                data.append(x.image);
+                break;
+            case DOUBLE_CIRC :
+                x = jj_consume_token(DOUBLE_CIRC);
+                data.append(x.image);
+                break;
+            case LBRACE :
+                x = jj_consume_token(LBRACE);
+                data.append(x.image);
+                temp = schemeData();
+                data.append(temp);
+                x = jj_consume_token(RBRACE);
+                data.append(x.image);
+                break;
+            default :
+                jj_la1[5] = jj_gen;
+                jj_consume_token(-1);
+                throw new ParseException();
+        }
+        {
+            if (true)
+                return data.toString();
+        }
+        throw new Error("Missing return statement in function");
+    }
+
+    final private boolean jj_2_1(int xla) {
+        jj_la = xla;
+        jj_lastpos = jj_scanpos = token;
+        boolean retval = !jj_3_1();
+        jj_save(0, xla);
+        return retval;
+    }
+
+    final private boolean jj_3R_6() {
+        if (jj_scan_token(NCName))
+            return true;
+        if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        return false;
+    }
+
+    final private boolean jj_3R_4() {
+        if (jj_3R_5())
+            return true;
+        if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        return false;
+    }
+
+    final private boolean jj_3R_5() {
+        Token xsp;
+        xsp = jj_scanpos;
+        if (jj_3R_6()) {
+            jj_scanpos = xsp;
+            if (jj_3R_7())
+                return true;
+            if (jj_la == 0 && jj_scanpos == jj_lastpos)
+                return false;
+        } else if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        if (jj_scan_token(LBRACE))
+            return true;
+        if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        return false;
+    }
+
+    final private boolean jj_3R_7() {
+        if (jj_scan_token(QName))
+            return true;
+        if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        return false;
+    }
+
+    final private boolean jj_3_1() {
+        if (jj_3R_4())
+            return true;
+        if (jj_la == 0 && jj_scanpos == jj_lastpos)
+            return false;
+        return false;
+    }
+
+    public XPointerFrameworkParserTokenManager token_source;
+    SimpleCharStream jj_input_stream;
+    public Token token, jj_nt;
+    private int jj_ntk;
+    private Token jj_scanpos, jj_lastpos;
+    private int jj_la;
+    public boolean lookingAhead = false;
+    private int jj_gen;
+    final private int[] jj_la1 = new int[6];
+    static private int[] jj_la1_0;
+    static {
+        jj_la1_0();
+    }
+    private static void jj_la1_0() {
+        jj_la1_0 = new int[] { 0x80, 0x380, 0x100, 0x280, 0xf400, 0xf400, };
+    }
+    final private JJCalls[] jj_2_rtns = new JJCalls[1];
+    private boolean jj_rescan = false;
+    private int jj_gc = 0;
+
+    public XPointerFrameworkParser(java.io.InputStream stream) {
+        jj_input_stream = new SimpleCharStream(stream, 1, 1);
+        token_source = new XPointerFrameworkParserTokenManager(jj_input_stream);
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    public void ReInit(java.io.InputStream stream) {
+        jj_input_stream.ReInit(stream, 1, 1);
+        token_source.ReInit(jj_input_stream);
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    public XPointerFrameworkParser(java.io.Reader stream) {
+        jj_input_stream = new SimpleCharStream(stream, 1, 1);
+        token_source = new XPointerFrameworkParserTokenManager(jj_input_stream);
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    public void ReInit(java.io.Reader stream) {
+        jj_input_stream.ReInit(stream, 1, 1);
+        token_source.ReInit(jj_input_stream);
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    public XPointerFrameworkParser(XPointerFrameworkParserTokenManager tm) {
+        token_source = tm;
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    public void ReInit(XPointerFrameworkParserTokenManager tm) {
+        token_source = tm;
+        token = new Token();
+        jj_ntk = -1;
+        jj_gen = 0;
+        for (int i = 0; i < 6; i++)
+            jj_la1[i] = -1;
+        for (int i = 0; i < jj_2_rtns.length; i++)
+            jj_2_rtns[i] = new JJCalls();
+    }
+
+    final private Token jj_consume_token(int kind) throws ParseException {
+        Token oldToken;
+        if ((oldToken = token).next != null)
+            token = token.next;
+        else
+            token = token.next = token_source.getNextToken();
+        jj_ntk = -1;
+        if (token.kind == kind) {
+            jj_gen++;
+            if (++jj_gc > 100) {
+                jj_gc = 0;
+                for (int i = 0; i < jj_2_rtns.length; i++) {
+                    JJCalls c = jj_2_rtns[i];
+                    while (c != null) {
+                        if (c.gen < jj_gen)
+                            c.first = null;
+                        c = c.next;
+                    }
+                }
+            }
+            return token;
+        }
+        token = oldToken;
+        jj_kind = kind;
+        throw generateParseException();
+    }
+
+    final private boolean jj_scan_token(int kind) {
+        if (jj_scanpos == jj_lastpos) {
+            jj_la--;
+            if (jj_scanpos.next == null) {
+                jj_lastpos =
+                    jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+            } else {
+                jj_lastpos = jj_scanpos = jj_scanpos.next;
+            }
+        } else {
+            jj_scanpos = jj_scanpos.next;
+        }
+        if (jj_rescan) {
+            int i = 0;
+            Token tok = token;
+            while (tok != null && tok != jj_scanpos) {
+                i++;
+                tok = tok.next;
+            }
+            if (tok != null)
+                jj_add_error_token(kind, i);
+        }
+        return (jj_scanpos.kind != kind);
+    }
+
+    final public Token getNextToken() {
+        if (token.next != null)
+            token = token.next;
+        else
+            token = token.next = token_source.getNextToken();
+        jj_ntk = -1;
+        jj_gen++;
+        return token;
+    }
+
+    final public Token getToken(int index) {
+        Token t = lookingAhead ? jj_scanpos : token;
+        for (int i = 0; i < index; i++) {
+            if (t.next != null)
+                t = t.next;
+            else
+                t = t.next = token_source.getNextToken();
+        }
+        return t;
+    }
+
+    final private int jj_ntk() {
+        if ((jj_nt = token.next) == null)
+            return (jj_ntk = (token.next = token_source.getNextToken()).kind);
+        else
+            return (jj_ntk = jj_nt.kind);
+    }
+
+    private java.util.Vector jj_expentries = new java.util.Vector();
+    private int[] jj_expentry;
+    private int jj_kind = -1;
+    private int[] jj_lasttokens = new int[100];
+    private int jj_endpos;
+
+    private void jj_add_error_token(int kind, int pos) {
+        if (pos >= 100)
+            return;
+        if (pos == jj_endpos + 1) {
+            jj_lasttokens[jj_endpos++] = kind;
+        } else if (jj_endpos != 0) {
+            jj_expentry = new int[jj_endpos];
+            for (int i = 0; i < jj_endpos; i++) {
+                jj_expentry[i] = jj_lasttokens[i];
+            }
+            boolean exists = false;
+            for (java.util.Enumeration enumeration = jj_expentries.elements();
+                enumeration.hasMoreElements();
+                ) {
+                int[] oldentry = (int[]) (enumeration.nextElement());
+                if (oldentry.length == jj_expentry.length) {
+                    exists = true;
+                    for (int i = 0; i < jj_expentry.length; i++) {
+                        if (oldentry[i] != jj_expentry[i]) {
+                            exists = false;
+                            break;
+                        }
+                    }
+                    if (exists)
+                        break;
+                }
+            }
+            if (!exists)
+                jj_expentries.addElement(jj_expentry);
+            if (pos != 0)
+                jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+        }
+    }
+
+    public ParseException generateParseException() {
+        jj_expentries.removeAllElements();
+        boolean[] la1tokens = new boolean[16];
+        for (int i = 0; i < 16; i++) {
+            la1tokens[i] = false;
+        }
+        if (jj_kind >= 0) {
+            la1tokens[jj_kind] = true;
+            jj_kind = -1;
+        }
+        for (int i = 0; i < 6; i++) {
+            if (jj_la1[i] == jj_gen) {
+                for (int j = 0; j < 32; j++) {
+                    if ((jj_la1_0[i] & (1 << j)) != 0) {
+                        la1tokens[j] = true;
+                    }
+                }
+            }
+        }
+        for (int i = 0; i < 16; i++) {
+            if (la1tokens[i]) {
+                jj_expentry = new int[1];
+                jj_expentry[0] = i;
+                jj_expentries.addElement(jj_expentry);
+            }
+        }
+        jj_endpos = 0;
+        jj_rescan_token();
+        jj_add_error_token(0, 0);
+        int[][] exptokseq = new int[jj_expentries.size()][];
+        for (int i = 0; i < jj_expentries.size(); i++) {
+            exptokseq[i] = (int[]) jj_expentries.elementAt(i);
+        }
+        return new ParseException(token, exptokseq, tokenImage);
+    }
+
+    final public void enable_tracing() {
+    }
+
+    final public void disable_tracing() {
+    }
+
+    final private void jj_rescan_token() {
+        jj_rescan = true;
+        for (int i = 0; i < 1; i++) {
+            JJCalls p = jj_2_rtns[i];
+            do {
+                if (p.gen > jj_gen) {
+                    jj_la = p.arg;
+                    jj_lastpos = jj_scanpos = p.first;
+                    switch (i) {
+                        case 0 :
+                            jj_3_1();
+                            break;
+                    }
+                }
+                p = p.next;
+            } while (p != null);
+        }
+        jj_rescan = false;
+    }
+
+    final private void jj_save(int index, int xla) {
+        JJCalls p = jj_2_rtns[index];
+        while (p.gen > jj_gen) {
+            if (p.next == null) {
+                p = p.next = new JJCalls();
+                break;
+            }
+            p = p.next;
+        }
+        p.gen = jj_gen + xla - jj_la;
+        p.first = token;
+        p.arg = xla;
+    }
+
+    static final class JJCalls {
+        int gen;
+        Token first;
+        int arg;
+        JJCalls next;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserConstants.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserConstants.java
new file mode 100644
index 0000000..bd28d6a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+public interface XPointerFrameworkParserConstants {
+
+  int EOF = 0;
+  int Letter = 1;
+  int BaseChar = 2;
+  int Ideographic = 3;
+  int CombiningChar = 4;
+  int UnicodeDigit = 5;
+  int Extender = 6;
+  int NCName = 7;
+  int WS = 8;
+  int QName = 9;
+  int LBRACE = 10;
+  int RBRACE = 11;
+  int CIRC_LBRACE = 12;
+  int CIRC_RBRACE = 13;
+  int DOUBLE_CIRC = 14;
+  int NormalChar = 15;
+
+  int DEFAULT = 0;
+  int IN_SCHEME = 1;
+
+  String[] tokenImage = {
+    "<EOF>",
+    "<Letter>",
+    "<BaseChar>",
+    "<Ideographic>",
+    "<CombiningChar>",
+    "<UnicodeDigit>",
+    "<Extender>",
+    "<NCName>",
+    "<WS>",
+    "<QName>",
+    "\"(\"",
+    "\")\"",
+    "\"^(\"",
+    "\"^)\"",
+    "\"^^\"",
+    "<NormalChar>",
+  };
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserTokenManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserTokenManager.java
new file mode 100644
index 0000000..3166bdf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/XPointerFrameworkParserTokenManager.java
@@ -0,0 +1,747 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.xpointer.parser;
+
+public class XPointerFrameworkParserTokenManager
+    implements XPointerFrameworkParserConstants {
+    public java.io.PrintStream debugStream = System.out;
+    public void setDebugStream(java.io.PrintStream ds) {
+        debugStream = ds;
+    }
+    private final int jjStopAtPos(int pos, int kind) {
+        jjmatchedKind = kind;
+        jjmatchedPos = pos;
+        return pos + 1;
+    }
+    private final int jjMoveStringLiteralDfa0_0() {
+        switch (curChar) {
+            case 40 :
+                return jjStopAtPos(0, 10);
+            case 41 :
+                return jjStopAtPos(0, 11);
+            default :
+                return jjMoveNfa_0(0, 0);
+        }
+    }
+    private final void jjCheckNAdd(int state) {
+        if (jjrounds[state] != jjround) {
+            jjstateSet[jjnewStateCnt++] = state;
+            jjrounds[state] = jjround;
+        }
+    }
+    private final void jjAddStates(int start, int end) {
+        do {
+            jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+        } while (start++ != end);
+    }
+    private final void jjCheckNAddTwoStates(int state1, int state2) {
+        jjCheckNAdd(state1);
+        jjCheckNAdd(state2);
+    }
+    private final void jjCheckNAddStates(int start, int end) {
+        do {
+            jjCheckNAdd(jjnextStates[start]);
+        } while (start++ != end);
+    }
+    static final long[] jjbitVec0 =
+        { 0x0L, 0xffffffffffffc000L, 0xfffff0007fffffffL, 0x7fffffL };
+    static final long[] jjbitVec2 = { 0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL };
+    static final long[] jjbitVec3 =
+        {
+            0x7ff3ffffffffffffL,
+            0x7ffffffffffffdfeL,
+            0xffffffffffffffffL,
+            0xfc31ffffffffe00fL };
+    static final long[] jjbitVec4 =
+        { 0xffffffL, 0xffffffffffff0000L, 0xf80001ffffffffffL, 0x3L };
+    static final long[] jjbitVec5 =
+        { 0x0L, 0x0L, 0xfffffffbffffd740L, 0xffffd547f7fffL };
+    static final long[] jjbitVec6 =
+        {
+            0xffffffffffffdffeL,
+            0xffffffffdffeffffL,
+            0xffffffffffff0003L,
+            0x33fcfffffff199fL };
+    static final long[] jjbitVec7 =
+        { 0xfffe000000000000L, 0xfffffffe027fffffL, 0x7fL, 0x707ffffff0000L };
+    static final long[] jjbitVec8 =
+        {
+            0x7fffffe00000000L,
+            0xfffe0000000007feL,
+            0x7cffffffffffffffL,
+            0x60002f7fffL };
+    static final long[] jjbitVec9 =
+        {
+            0x23ffffffffffffe0L,
+            0x3ff000000L,
+            0x3c5fdfffff99fe0L,
+            0x30003b0000000L };
+    static final long[] jjbitVec10 =
+        {
+            0x36dfdfffff987e0L,
+            0x1c00005e000000L,
+            0x23edfdfffffbafe0L,
+            0x100000000L };
+    static final long[] jjbitVec11 =
+        { 0x23cdfdfffff99fe0L, 0x3b0000000L, 0x3bfc718d63dc7e0L, 0x0L };
+    static final long[] jjbitVec12 =
+        { 0x3effdfffffddfe0L, 0x300000000L, 0x3effdfffffddfe0L, 0x340000000L };
+    static final long[] jjbitVec13 =
+        { 0x3fffdfffffddfe0L, 0x300000000L, 0x0L, 0x0L };
+    static final long[] jjbitVec14 =
+        { 0xd7ffffffffffeL, 0x3fL, 0x200d6caefef02596L, 0x1fL };
+    static final long[] jjbitVec15 = { 0x0L, 0x3fffffffeffL, 0x0L, 0x0L };
+    static final long[] jjbitVec16 =
+        { 0x0L, 0x0L, 0xffffffff00000000L, 0x7fffffffff003fL };
+    static final long[] jjbitVec17 =
+        {
+            0x500000000007daedL,
+            0x2c62ab82315001L,
+            0xf580c90040000000L,
+            0x201080000000007L };
+    static final long[] jjbitVec18 =
+        {
+            0xffffffffffffffffL,
+            0xffffffffffffffffL,
+            0xffffffff0fffffffL,
+            0x3ffffffffffffffL };
+    static final long[] jjbitVec19 =
+        {
+            0xffffffff3f3fffffL,
+            0x3fffffffaaff3f3fL,
+            0x5fdfffffffffffffL,
+            0x1fdc1fff0fcf1fdcL };
+    static final long[] jjbitVec20 = { 0x4c4000000000L, 0x0L, 0x7L, 0x0L };
+    static final long[] jjbitVec21 =
+        {
+            0x3fe00000080L,
+            0xfffffffffffffffeL,
+            0xfffffffe001fffffL,
+            0x7ffffffffffffffL };
+    static final long[] jjbitVec22 = { 0x1fffffffffe0L, 0x0L, 0x0L, 0x0L };
+    static final long[] jjbitVec23 =
+        { 0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffL, 0x0L };
+    static final long[] jjbitVec24 =
+        { 0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffL, 0x0L };
+    static final long[] jjbitVec25 =
+        { 0x0L, 0x0L, 0x80000000000000L, 0xff7fffffff7fffffL };
+    static final long[] jjbitVec26 =
+        { 0xffffffL, 0xffffffffffff0000L, 0xf80001ffffffffffL, 0x30003L };
+    static final long[] jjbitVec27 =
+        {
+            0xffffffffffffffffL,
+            0x30000003fL,
+            0xfffffffbffffd7c0L,
+            0xffffd547f7fffL };
+    static final long[] jjbitVec28 =
+        {
+            0xffffffffffffdffeL,
+            0xffffffffdffeffffL,
+            0xffffffffffff007bL,
+            0x33fcfffffff199fL };
+    static final long[] jjbitVec29 =
+        {
+            0xfffe000000000000L,
+            0xfffffffe027fffffL,
+            0xbbfffffbfffe007fL,
+            0x707ffffff0016L };
+    static final long[] jjbitVec30 =
+        {
+            0x7fffffe00000000L,
+            0xffff03ff0007ffffL,
+            0x7cffffffffffffffL,
+            0x3ff3dffffef7fffL };
+    static final long[] jjbitVec31 =
+        {
+            0xf3ffffffffffffeeL,
+            0xffcfff1e3fffL,
+            0xd3c5fdfffff99feeL,
+            0x3ffcfb080399fL };
+    static final long[] jjbitVec32 =
+        {
+            0xd36dfdfffff987e4L,
+            0x1fffc05e003987L,
+            0xf3edfdfffffbafeeL,
+            0xffc100003bbfL };
+    static final long[] jjbitVec33 =
+        {
+            0xf3cdfdfffff99feeL,
+            0xffc3b0c0398fL,
+            0xc3bfc718d63dc7ecL,
+            0xff8000803dc7L };
+    static final long[] jjbitVec34 =
+        {
+            0xc3effdfffffddfeeL,
+            0xffc300603ddfL,
+            0xc3effdfffffddfecL,
+            0xffc340603ddfL };
+    static final long[] jjbitVec35 =
+        { 0xc3fffdfffffddfecL, 0xffc300803dcfL, 0x0L, 0x0L };
+    static final long[] jjbitVec36 =
+        { 0x7ff7ffffffffffeL, 0x3ff7fffL, 0x3bff6caefef02596L, 0x3ff3f5fL };
+    static final long[] jjbitVec37 =
+        { 0xc2a003ff03000000L, 0xfffe03fffffffeffL, 0x2fe3ffffebf0fdfL, 0x0L };
+    static final long[] jjbitVec38 = { 0x0L, 0x0L, 0x0L, 0x21fff0000L };
+    static final long[] jjbitVec39 =
+        {
+            0x3efffe000000a0L,
+            0xfffffffffffffffeL,
+            0xfffffffe661fffffL,
+            0x77ffffffffffffffL };
+    private final int jjMoveNfa_0(int startState, int curPos) {
+        int startsAt = 0;
+        jjnewStateCnt = 7;
+        int i = 1;
+        jjstateSet[0] = startState;
+        int kind = 0x7fffffff;
+        for (;;) {
+            if (++jjround == 0x7fffffff)
+                ReInitRounds();
+            if (curChar < 64) {
+                long l = 1L << curChar;
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if ((0x100002600L & l) != 0L)
+                                kind = 8;
+                            break;
+                        case 2 :
+                            if ((0x3ff600000000000L & l) == 0L)
+                                break;
+                            if (kind > 7)
+                                kind = 7;
+                            jjstateSet[jjnewStateCnt++] = 2;
+                            break;
+                        case 3 :
+                            if ((0x3ff600000000000L & l) != 0L)
+                                jjAddStates(0, 1);
+                            break;
+                        case 4 :
+                            if (curChar == 58)
+                                jjstateSet[jjnewStateCnt++] = 5;
+                            break;
+                        case 6 :
+                            if ((0x3ff600000000000L & l) == 0L)
+                                break;
+                            if (kind > 9)
+                                kind = 9;
+                            jjstateSet[jjnewStateCnt++] = 6;
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            } else if (curChar < 128) {
+                long l = 1L << (curChar & 077);
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if ((0x7fffffe87fffffeL & l) == 0L)
+                                break;
+                            if (kind > 7)
+                                kind = 7;
+                            jjCheckNAddStates(2, 5);
+                            break;
+                        case 2 :
+                            if ((0x7fffffe87fffffeL & l) == 0L)
+                                break;
+                            if (kind > 7)
+                                kind = 7;
+                            jjCheckNAdd(2);
+                            break;
+                        case 3 :
+                            if ((0x7fffffe87fffffeL & l) != 0L)
+                                jjCheckNAddTwoStates(3, 4);
+                            break;
+                        case 5 :
+                        case 6 :
+                            if ((0x7fffffe87fffffeL & l) == 0L)
+                                break;
+                            if (kind > 9)
+                                kind = 9;
+                            jjCheckNAdd(6);
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            } else {
+                int hiByte = (curChar >> 8);
+                int i1 = hiByte >> 6;
+                long l1 = 1L << (hiByte & 077);
+                int i2 = (curChar & 0xff) >> 6;
+                long l2 = 1L << (curChar & 077);
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                                break;
+                            if (kind > 7)
+                                kind = 7;
+                            jjCheckNAddStates(2, 5);
+                            break;
+                        case 2 :
+                            if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                                break;
+                            if (kind > 7)
+                                kind = 7;
+                            jjCheckNAdd(2);
+                            break;
+                        case 3 :
+                            if (jjCanMove_1(hiByte, i1, i2, l1, l2))
+                                jjCheckNAddTwoStates(3, 4);
+                            break;
+                        case 5 :
+                            if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                                break;
+                            if (kind > 9)
+                                kind = 9;
+                            jjCheckNAdd(6);
+                            break;
+                        case 6 :
+                            if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                                break;
+                            if (kind > 9)
+                                kind = 9;
+                            jjCheckNAdd(6);
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            }
+            if (kind != 0x7fffffff) {
+                jjmatchedKind = kind;
+                jjmatchedPos = curPos;
+                kind = 0x7fffffff;
+            }
+            ++curPos;
+            if ((i = jjnewStateCnt)
+                == (startsAt = 7 - (jjnewStateCnt = startsAt)))
+                return curPos;
+            try {
+                curChar = input_stream.readChar();
+            } catch (java.io.IOException e) {
+                return curPos;
+            }
+        }
+    }
+    private final int jjStopStringLiteralDfa_1(int pos, long active0) {
+        switch (pos) {
+            default :
+                return -1;
+        }
+    }
+    private final int jjStartNfa_1(int pos, long active0) {
+        return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
+    }
+
+    private final int jjMoveStringLiteralDfa0_1() {
+        switch (curChar) {
+            case 40 :
+                return jjStopAtPos(0, 10);
+            case 41 :
+                return jjStopAtPos(0, 11);
+            case 94 :
+                return jjMoveStringLiteralDfa1_1(0x7000L);
+            default :
+                return jjMoveNfa_1(0, 0);
+        }
+    }
+    private final int jjMoveStringLiteralDfa1_1(long active0) {
+        try {
+            curChar = input_stream.readChar();
+        } catch (java.io.IOException e) {
+            jjStopStringLiteralDfa_1(0, active0);
+            return 1;
+        }
+        switch (curChar) {
+            case 40 :
+                if ((active0 & 0x1000L) != 0L)
+                    return jjStopAtPos(1, 12);
+                break;
+            case 41 :
+                if ((active0 & 0x2000L) != 0L)
+                    return jjStopAtPos(1, 13);
+                break;
+            case 94 :
+                if ((active0 & 0x4000L) != 0L)
+                    return jjStopAtPos(1, 14);
+                break;
+            default :
+                break;
+        }
+        return jjStartNfa_1(0, active0);
+    }
+    static final long[] jjbitVec40 =
+        {
+            0xfffffffffffffffeL,
+            0xffffffffffffffffL,
+            0xffffffffffffffffL,
+            0xffffffffffffffffL };
+    static final long[] jjbitVec41 =
+        { 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL };
+    private final int jjMoveNfa_1(int startState, int curPos) {
+        int startsAt = 0;
+        jjnewStateCnt = 1;
+        int i = 1;
+        jjstateSet[0] = startState;
+        int kind = 0x7fffffff;
+        for (;;) {
+            if (++jjround == 0x7fffffff)
+                ReInitRounds();
+            if (curChar < 64) {
+                long l = 1L << curChar;
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if ((0xfffffcffffffffffL & l) != 0L)
+                                kind = 15;
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            } else if (curChar < 128) {
+                long l = 1L << (curChar & 077);
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if ((0xffffffffbfffffffL & l) != 0L)
+                                kind = 15;
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            } else {
+                int hiByte = (curChar >> 8);
+                int i1 = hiByte >> 6;
+                long l1 = 1L << (hiByte & 077);
+                int i2 = (curChar & 0xff) >> 6;
+                long l2 = 1L << (curChar & 077);
+                do {
+                    switch (jjstateSet[--i]) {
+                        case 0 :
+                            if (jjCanMove_2(hiByte, i1, i2, l1, l2)
+                                && kind > 15)
+                                kind = 15;
+                            break;
+                        default :
+                            break;
+                    }
+                } while (i != startsAt);
+            }
+            if (kind != 0x7fffffff) {
+                jjmatchedKind = kind;
+                jjmatchedPos = curPos;
+                kind = 0x7fffffff;
+            }
+            ++curPos;
+            if ((i = jjnewStateCnt)
+                == (startsAt = 1 - (jjnewStateCnt = startsAt)))
+                return curPos;
+            try {
+                curChar = input_stream.readChar();
+            } catch (java.io.IOException e) {
+                return curPos;
+            }
+        }
+    }
+    static final int[] jjnextStates = { 3, 4, 2, 3, 4, 6, };
+    private static final boolean jjCanMove_0(
+        int hiByte,
+        int i1,
+        int i2,
+        long l1,
+        long l2) {
+        switch (hiByte) {
+            case 0 :
+                return ((jjbitVec2[i2] & l2) != 0L);
+            case 1 :
+                return ((jjbitVec3[i2] & l2) != 0L);
+            case 2 :
+                return ((jjbitVec4[i2] & l2) != 0L);
+            case 3 :
+                return ((jjbitVec5[i2] & l2) != 0L);
+            case 4 :
+                return ((jjbitVec6[i2] & l2) != 0L);
+            case 5 :
+                return ((jjbitVec7[i2] & l2) != 0L);
+            case 6 :
+                return ((jjbitVec8[i2] & l2) != 0L);
+            case 9 :
+                return ((jjbitVec9[i2] & l2) != 0L);
+            case 10 :
+                return ((jjbitVec10[i2] & l2) != 0L);
+            case 11 :
+                return ((jjbitVec11[i2] & l2) != 0L);
+            case 12 :
+                return ((jjbitVec12[i2] & l2) != 0L);
+            case 13 :
+                return ((jjbitVec13[i2] & l2) != 0L);
+            case 14 :
+                return ((jjbitVec14[i2] & l2) != 0L);
+            case 15 :
+                return ((jjbitVec15[i2] & l2) != 0L);
+            case 16 :
+                return ((jjbitVec16[i2] & l2) != 0L);
+            case 17 :
+                return ((jjbitVec17[i2] & l2) != 0L);
+            case 30 :
+                return ((jjbitVec18[i2] & l2) != 0L);
+            case 31 :
+                return ((jjbitVec19[i2] & l2) != 0L);
+            case 33 :
+                return ((jjbitVec20[i2] & l2) != 0L);
+            case 48 :
+                return ((jjbitVec21[i2] & l2) != 0L);
+            case 49 :
+                return ((jjbitVec22[i2] & l2) != 0L);
+            case 159 :
+                return ((jjbitVec23[i2] & l2) != 0L);
+            case 215 :
+                return ((jjbitVec24[i2] & l2) != 0L);
+            default :
+                if ((jjbitVec0[i1] & l1) != 0L)
+                    return true;
+                return false;
+        }
+    }
+    private static final boolean jjCanMove_1(
+        int hiByte,
+        int i1,
+        int i2,
+        long l1,
+        long l2) {
+        switch (hiByte) {
+            case 0 :
+                return ((jjbitVec25[i2] & l2) != 0L);
+            case 1 :
+                return ((jjbitVec3[i2] & l2) != 0L);
+            case 2 :
+                return ((jjbitVec26[i2] & l2) != 0L);
+            case 3 :
+                return ((jjbitVec27[i2] & l2) != 0L);
+            case 4 :
+                return ((jjbitVec28[i2] & l2) != 0L);
+            case 5 :
+                return ((jjbitVec29[i2] & l2) != 0L);
+            case 6 :
+                return ((jjbitVec30[i2] & l2) != 0L);
+            case 9 :
+                return ((jjbitVec31[i2] & l2) != 0L);
+            case 10 :
+                return ((jjbitVec32[i2] & l2) != 0L);
+            case 11 :
+                return ((jjbitVec33[i2] & l2) != 0L);
+            case 12 :
+                return ((jjbitVec34[i2] & l2) != 0L);
+            case 13 :
+                return ((jjbitVec35[i2] & l2) != 0L);
+            case 14 :
+                return ((jjbitVec36[i2] & l2) != 0L);
+            case 15 :
+                return ((jjbitVec37[i2] & l2) != 0L);
+            case 16 :
+                return ((jjbitVec16[i2] & l2) != 0L);
+            case 17 :
+                return ((jjbitVec17[i2] & l2) != 0L);
+            case 30 :
+                return ((jjbitVec18[i2] & l2) != 0L);
+            case 31 :
+                return ((jjbitVec19[i2] & l2) != 0L);
+            case 32 :
+                return ((jjbitVec38[i2] & l2) != 0L);
+            case 33 :
+                return ((jjbitVec20[i2] & l2) != 0L);
+            case 48 :
+                return ((jjbitVec39[i2] & l2) != 0L);
+            case 49 :
+                return ((jjbitVec22[i2] & l2) != 0L);
+            case 159 :
+                return ((jjbitVec23[i2] & l2) != 0L);
+            case 215 :
+                return ((jjbitVec24[i2] & l2) != 0L);
+            default :
+                if ((jjbitVec0[i1] & l1) != 0L)
+                    return true;
+                return false;
+        }
+    }
+    private static final boolean jjCanMove_2(
+        int hiByte,
+        int i1,
+        int i2,
+        long l1,
+        long l2) {
+        switch (hiByte) {
+            case 0 :
+                return ((jjbitVec41[i2] & l2) != 0L);
+            default :
+                if ((jjbitVec40[i1] & l1) != 0L)
+                    return true;
+                return false;
+        }
+    }
+    public static final String[] jjstrLiteralImages =
+        {
+            "",
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            null,
+            "\50",
+            "\51",
+            "\136\50",
+            "\136\51",
+            "\136\136",
+            null,
+            };
+    public static final String[] lexStateNames = { "DEFAULT", "IN_SCHEME", };
+    public static final int[] jjnewLexState =
+        { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, };
+    protected SimpleCharStream input_stream;
+    private final int[] jjrounds = new int[7];
+    private final int[] jjstateSet = new int[14];
+    protected char curChar;
+    public XPointerFrameworkParserTokenManager(SimpleCharStream stream) {
+        if (SimpleCharStream.staticFlag)
+            throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+        input_stream = stream;
+    }
+    public XPointerFrameworkParserTokenManager(
+        SimpleCharStream stream,
+        int lexState) {
+        this(stream);
+        SwitchTo(lexState);
+    }
+    public void ReInit(SimpleCharStream stream) {
+        jjmatchedPos = jjnewStateCnt = 0;
+        curLexState = defaultLexState;
+        input_stream = stream;
+        ReInitRounds();
+    }
+    private final void ReInitRounds() {
+        int i;
+        jjround = 0x80000001;
+        for (i = 7; i-- > 0;)
+            jjrounds[i] = 0x80000000;
+    }
+    public void ReInit(SimpleCharStream stream, int lexState) {
+        ReInit(stream);
+        SwitchTo(lexState);
+    }
+    public void SwitchTo(int lexState) {
+        if (lexState >= 2 || lexState < 0)
+            throw new TokenMgrError(
+                "Error: Ignoring invalid lexical state : "
+                    + lexState
+                    + ". State unchanged.",
+                TokenMgrError.INVALID_LEXICAL_STATE);
+        else
+            curLexState = lexState;
+    }
+
+    protected Token jjFillToken() {
+        Token t = Token.newToken(jjmatchedKind);
+        t.kind = jjmatchedKind;
+        String im = jjstrLiteralImages[jjmatchedKind];
+        t.image = (im == null) ? input_stream.GetImage() : im;
+        t.beginLine = input_stream.getBeginLine();
+        t.beginColumn = input_stream.getBeginColumn();
+        t.endLine = input_stream.getEndLine();
+        t.endColumn = input_stream.getEndColumn();
+        return t;
+    }
+
+    int curLexState = 0;
+    int defaultLexState = 0;
+    int jjnewStateCnt;
+    int jjround;
+    int jjmatchedPos;
+    int jjmatchedKind;
+
+    public Token getNextToken() {
+        Token matchedToken;
+        int curPos = 0;
+
+        for (;;) {
+            try {
+                curChar = input_stream.BeginToken();
+            } catch (java.io.IOException e) {
+                jjmatchedKind = 0;
+                matchedToken = jjFillToken();
+                return matchedToken;
+            }
+
+            switch (curLexState) {
+                case 0 :
+                    jjmatchedKind = 0x7fffffff;
+                    jjmatchedPos = 0;
+                    curPos = jjMoveStringLiteralDfa0_0();
+                    break;
+                case 1 :
+                    jjmatchedKind = 0x7fffffff;
+                    jjmatchedPos = 0;
+                    curPos = jjMoveStringLiteralDfa0_1();
+                    break;
+            }
+            if (jjmatchedKind != 0x7fffffff) {
+                if (jjmatchedPos + 1 < curPos)
+                    input_stream.backup(curPos - jjmatchedPos - 1);
+                matchedToken = jjFillToken();
+                if (jjnewLexState[jjmatchedKind] != -1)
+                    curLexState = jjnewLexState[jjmatchedKind];
+                return matchedToken;
+            }
+            int error_line = input_stream.getEndLine();
+            int error_column = input_stream.getEndColumn();
+            String error_after = null;
+            boolean EOFSeen = false;
+            try {
+                input_stream.readChar();
+                input_stream.backup(1);
+            } catch (java.io.IOException e1) {
+                EOFSeen = true;
+                error_after = curPos <= 1 ? "" : input_stream.GetImage();
+                if (curChar == '\n' || curChar == '\r') {
+                    error_line++;
+                    error_column = 0;
+                } else
+                    error_column++;
+            }
+            if (!EOFSeen) {
+                input_stream.backup(1);
+                error_after = curPos <= 1 ? "" : input_stream.GetImage();
+            }
+            throw new TokenMgrError(
+                EOFSeen,
+                curLexState,
+                error_line,
+                error_column,
+                error_after,
+                curChar,
+                TokenMgrError.LEXICAL_ERROR);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/xpointer-fw.jj b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/xpointer-fw.jj
new file mode 100644
index 0000000..a5c6e2e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xpointer/parser/xpointer-fw.jj
@@ -0,0 +1,304 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+/*
+   Parser for the XPointer Framework Syntax, see the specification at:
+   http://www.w3.org/TR/2003/REC-xptr-framework-20030325/
+
+   Some of the token definitions (for recognizing NCName's) were copied from
+   the JXPath parser from Jakarta Commons (to save some typing), written by
+   Ingo Macherius, Gerald Huck <{macherius, huck}@gmd.de> and Dmitri Plotnikov.
+*/
+
+options {
+  STATIC = false;
+}
+
+PARSER_BEGIN(XPointerFrameworkParser)
+
+  package org.apache.cocoon.components.xpointer.parser;
+
+  import org.apache.cocoon.components.xpointer.*;
+  import java.util.HashMap;
+
+  public class XPointerFrameworkParser {
+    private XPointer xpointer = new XPointer();
+    private HashMap namespaces = new HashMap();
+
+    public static void main(String [] args) throws Exception {
+      System.out.println("will parse this: " + args[0]);
+      XPointerFrameworkParser xfp = new XPointerFrameworkParser(new java.io.StringReader(args[0]));
+      xfp.pointer();
+    }
+
+    public static XPointer parse(String xpointer) throws ParseException {
+      XPointerFrameworkParser xfp = new XPointerFrameworkParser(new java.io.StringReader(xpointer));
+      xfp.pointer();
+      return xfp.getXPointer();
+    }
+
+    public XPointer getXPointer() {
+      return xpointer;
+    }
+
+    private String unescape(String data) throws ParseException {
+      StringBuffer result = new StringBuffer(data.length());
+      boolean inCircumflex = false;
+      for (int i = 0; i < data.length(); i++) {
+        char c = data.charAt(i);
+        if (inCircumflex) {
+          switch (c) {
+            case '^':
+            case '(':
+            case ')':
+              result.append(c);
+              inCircumflex = false;
+              break;
+            default:
+              throw new ParseException("Incorrect use of circumflex character at position " + i + " in the string " + data);
+          }
+        } else if (c == '^') {
+          inCircumflex = true;
+        } else {
+          result.append(c);
+        }
+      }
+      return result.toString();
+    }
+  }
+
+PARSER_END(XPointerFrameworkParser)
+
+TOKEN :
+{
+  <#Letter : <BaseChar> | <Ideographic> >
+| <#BaseChar :
+        (
+        ["\u0041"-"\u005A"] | ["\u0061"-"\u007A"] | ["\u00C0"-"\u00D6"] | ["\u00D8"-"\u00F6"] |
+        ["\u00F8"-"\u00FF"] | ["\u0100"-"\u0131"] | ["\u0134"-"\u013E"] | ["\u0141"-"\u0148"] |
+        ["\u014A"-"\u017E"] | ["\u0180"-"\u01C3"] | ["\u01CD"-"\u01F0"] | ["\u01F4"-"\u01F5"] |
+        ["\u01FA"-"\u0217"] | ["\u0250"-"\u02A8"] | ["\u02BB"-"\u02C1"] | "\u0386" | ["\u0388"-"\u038A"] |
+        "\u038C" | ["\u038E"-"\u03A1"] | ["\u03A3"-"\u03CE"] | ["\u03D0"-"\u03D6"] | "\u03DA" |
+        "\u03DC" |  "\u03DE" | "\u03E0" | ["\u03E2"-"\u03F3"] | ["\u0401"-"\u040C"] | ["\u040E"-"\u044F"] |
+        ["\u0451"-"\u045C"] | ["\u045E"-"\u0481"] | ["\u0490"-"\u04C4"] | ["\u04C7"-"\u04C8"] |
+        ["\u04CB"-"\u04CC"] | ["\u04D0"-"\u04EB"] | ["\u04EE"-"\u04F5"] | ["\u04F8"-"\u04F9"] |
+        ["\u0531"-"\u0556"] | "\u0559" | ["\u0561"-"\u0586"] | ["\u05D0"-"\u05EA"] | ["\u05F0"-"\u05F2"] |
+        ["\u0621"-"\u063A"] | ["\u0641"-"\u064A"] | ["\u0671"-"\u06B7"] | ["\u06BA"-"\u06BE"] |
+        ["\u06C0"-"\u06CE"] | ["\u06D0"-"\u06D3"] | "\u06D5" | ["\u06E5"-"\u06E6"] | ["\u0905"-"\u0939"] |
+        "\u093D" | ["\u0958"-"\u0961"] | ["\u0985"-"\u098C"] | ["\u098F"-"\u0990"] | ["\u0993"-"\u09A8"] |
+        ["\u09AA"-"\u09B0"] | "\u09B2" | ["\u09B6"-"\u09B9"] | ["\u09DC"-"\u09DD"] | ["\u09DF"-"\u09E1"] |
+        ["\u09F0"-"\u09F1"] | ["\u0A05"-"\u0A0A"] | ["\u0A0F"-"\u0A10"] | ["\u0A13"-"\u0A28"] |
+        ["\u0A2A"-"\u0A30"] | ["\u0A32"-"\u0A33"] | ["\u0A35"-"\u0A36"] | ["\u0A38"-"\u0A39"] |
+        ["\u0A59"-"\u0A5C"] | "\u0A5E" | ["\u0A72"-"\u0A74"] | ["\u0A85"-"\u0A8B"] | "\u0A8D" |
+        ["\u0A8F"-"\u0A91"] | ["\u0A93"-"\u0AA8"] | ["\u0AAA"-"\u0AB0"] | ["\u0AB2"-"\u0AB3"] |
+        ["\u0AB5"-"\u0AB9"] | "\u0ABD" | "\u0AE0" |  ["\u0B05"-"\u0B0C"] | ["\u0B0F"-"\u0B10"] |
+        ["\u0B13"-"\u0B28"] | ["\u0B2A"-"\u0B30"] | ["\u0B32"-"\u0B33"] | ["\u0B36"-"\u0B39"] |
+        "\u0B3D" | ["\u0B5C"-"\u0B5D"] | ["\u0B5F"-"\u0B61"] | ["\u0B85"-"\u0B8A"] |  ["\u0B8E"-"\u0B90"] |
+        ["\u0B92"-"\u0B95"] |  ["\u0B99"-"\u0B9A"] | "\u0B9C" | ["\u0B9E"-"\u0B9F"] | ["\u0BA3"-"\u0BA4"] |
+        ["\u0BA8"-"\u0BAA"] | ["\u0BAE"-"\u0BB5"] | ["\u0BB7"-"\u0BB9"] | ["\u0C05"-"\u0C0C"] |
+        ["\u0C0E"-"\u0C10"] | ["\u0C12"-"\u0C28"] | ["\u0C2A"-"\u0C33"] | ["\u0C35"-"\u0C39"] |
+        ["\u0C60"-"\u0C61"] | ["\u0C85"-"\u0C8C"] | ["\u0C8E"-"\u0C90"] | ["\u0C92"-"\u0CA8"] |
+        ["\u0CAA"-"\u0CB3"] | ["\u0CB5"-"\u0CB9"] | "\u0CDE" | ["\u0CE0"-"\u0CE1"] | ["\u0D05"-"\u0D0C"] |
+        ["\u0D0E"-"\u0D10"] | ["\u0D12"-"\u0D28"] | ["\u0D2A"-"\u0D39"] | ["\u0D60"-"\u0D61"] |
+        ["\u0E01"-"\u0E2E"] | "\u0E30" | ["\u0E32"-"\u0E33"] | ["\u0E40"-"\u0E45"] | ["\u0E81"-"\u0E82"] |
+        "\u0E84" | ["\u0E87"-"\u0E88"] | "\u0E8A" | "\u0E8D" | ["\u0E94"-"\u0E97"] | ["\u0E99"-"\u0E9F"] |
+        ["\u0EA1"-"\u0EA3"] | "\u0EA5" | "\u0EA7" | ["\u0EAA"-"\u0EAB"] | ["\u0EAD"-"\u0EAE"] | "\u0EB0" |
+        ["\u0EB2"-"\u0EB3"] | "\u0EBD" | ["\u0EC0"-"\u0EC4"] | ["\u0F40"-"\u0F47"] | ["\u0F49"-"\u0F69"] |
+        ["\u10A0"-"\u10C5"] | ["\u10D0"-"\u10F6"] | "\u1100" | ["\u1102"-"\u1103"] | ["\u1105"-"\u1107"] |
+        "\u1109" | ["\u110B"-"\u110C"] | ["\u110E"-"\u1112"] | "\u113C" | "\u113E" | "\u1140" | "\u114C" |
+        "\u114E" | "\u1150" | ["\u1154"-"\u1155"] | "\u1159" | ["\u115F"-"\u1161"] | "\u1163" | "\u1165" |
+        "\u1167" | "\u1169" | ["\u116D"-"\u116E"] | ["\u1172"-"\u1173"] | "\u1175" | "\u119E" | "\u11A8" |
+        "\u11AB" | ["\u11AE"-"\u11AF"] | ["\u11B7"-"\u11B8"] | "\u11BA" |  ["\u11BC"-"\u11C2"] | "\u11EB" |
+        "\u11F0" | "\u11F9" | ["\u1E00"-"\u1E9B"] | ["\u1EA0"-"\u1EF9"] | ["\u1F00"-"\u1F15"] |
+        ["\u1F18"-"\u1F1D"] |
+        ["\u1F20"-"\u1F45"] | ["\u1F48"-"\u1F4D"] | ["\u1F50"-"\u1F57"] | "\u1F59" | "\u1F5B" | "\u1F5D" |
+        ["\u1F5F"-"\u1F7D"] | ["\u1F80"-"\u1FB4"] | ["\u1FB6"-"\u1FBC"] | "\u1FBE" |  ["\u1FC2"-"\u1FC4"] |
+        ["\u1FC6"-"\u1FCC"] | ["\u1FD0"-"\u1FD3"] | ["\u1FD6"-"\u1FDB"] | ["\u1FE0"-"\u1FEC"] |
+        ["\u1FF2"-"\u1FF4"] | ["\u1FF6"-"\u1FFC"] | "\u2126" | ["\u212A"-"\u212B"] | "\u212E" |
+        ["\u2180"-"\u2182"] | ["\u3041"-"\u3094"] | ["\u30A1"-"\u30FA"] | ["\u3105"-"\u312C"] |
+        ["\uAC00"-"\uD7A3"]
+        ) >
+| <#Ideographic : (["\u4E00"-"\u9FA5"] | "\u3007" | ["\u3021"-"\u3029"]) >
+| <#CombiningChar :
+        (
+        ["\u0300"-"\u0345"]    |    ["\u0360"-"\u0361"]     |    ["\u0483"-"\u0486"]    |    ["\u0591"-"\u05A1"] |
+        ["\u05A3"-"\u05B9"]    |    ["\u05BB"-"\u05BD"]        |    "\u05BF"             |    ["\u05C1"-"\u05C2"] |
+        "\u05C4"             | ["\u064B"-"\u0652"] | "\u0670"             | ["\u06D6"-"\u06DC"] |
+        ["\u06DD"-"\u06DF"] | ["\u06E0"-"\u06E4"] | ["\u06E7"-"\u06E8"] | ["\u06EA"-"\u06ED"] |
+        ["\u0901"-"\u0903"] | "\u093C"    |["\u093E"-"\u094C"] | "\u094D" | ["\u0951"-"\u0954"] |
+        ["\u0962"-"\u0963"] | ["\u0981"-"\u0983"] | "\u09BC" | "\u09BE" | "\u09BF" | ["\u09C0"-"\u09C4"] |
+        ["\u09C7"-"\u09C8"] | ["\u09CB"-"\u09CD"] | "\u09D7" | ["\u09E2"-"\u09E3"] | "\u0A02" | "\u0A3C" |
+        "\u0A3E" | "\u0A3F" | ["\u0A40"-"\u0A42"] |
+        ["\u0A47"-"\u0A48"] | ["\u0A4B"-"\u0A4D"] | ["\u0A70"-"\u0A71"] | ["\u0A81"-"\u0A83"] | "\u0ABC" |
+        ["\u0ABE"-"\u0AC5"] | ["\u0AC7"-"\u0AC9"] | ["\u0ACB"-"\u0ACD"] | ["\u0B01"-"\u0B03"] | "\u0B3C" |
+        ["\u0B3E"-"\u0B43"] | ["\u0B47"-"\u0B48"] | ["\u0B4B"-"\u0B4D"] | ["\u0B56"-"\u0B57"] |
+        ["\u0B82"-"\u0B83"] | ["\u0BBE"-"\u0BC2"] | ["\u0BC6"-"\u0BC8"] | ["\u0BCA"-"\u0BCD"] | "\u0BD7" |
+        ["\u0C01"-"\u0C03"] | ["\u0C3E"-"\u0C44"] | ["\u0C46"-"\u0C48"] | ["\u0C4A"-"\u0C4D"] |
+        ["\u0C55"-"\u0C56"] | ["\u0C82"-"\u0C83"] | ["\u0CBE"-"\u0CC4"] | ["\u0CC6"-"\u0CC8"] |
+        ["\u0CCA"-"\u0CCD"] | ["\u0CD5"-"\u0CD6"] | ["\u0D02"-"\u0D03"] | ["\u0D3E"-"\u0D43"] |
+        ["\u0D46"-"\u0D48"] | ["\u0D4A"-"\u0D4D"] | "\u0D57" | "\u0E31" | ["\u0E34"-"\u0E3A"] |
+        ["\u0E47"-"\u0E4E"] | "\u0EB1" | ["\u0EB4"-"\u0EB9"] | ["\u0EBB"-"\u0EBC"] | ["\u0EC8"-"\u0ECD"] |
+        ["\u0F18"-"\u0F19"] | "\u0F35" | "\u0F37" | "\u0F39" | "\u0F3E" | "\u0F3F" | ["\u0F71"-"\u0F84"] |
+        ["\u0F86"-"\u0F8B"] | ["\u0F90"-"\u0F95"] | "\u0F97" | ["\u0F99"-"\u0FAD"] | ["\u0FB1"-"\u0FB7"] |
+        "\u0FB9" | ["\u20D0"-"\u20DC"] | "\u20E1" | ["\u302A"-"\u302F"] | "\u3099" | "\u309A"
+        )
+    >
+| <#UnicodeDigit :
+        ["\u0030"-"\u0039"] | ["\u0660"-"\u0669"] | ["\u06F0"-"\u06F9"] | ["\u0966"-"\u096F"] |
+        ["\u09E6"-"\u09EF"] | ["\u0A66"-"\u0A6F"] | ["\u0AE6"-"\u0AEF"] | ["\u0B66"-"\u0B6F"] |
+        ["\u0BE7"-"\u0BEF"] | ["\u0C66"-"\u0C6F"] | ["\u0CE6"-"\u0CEF"] | ["\u0D66"-"\u0D6F"] |
+        ["\u0E50"-"\u0E59"] | ["\u0ED0"-"\u0ED9"] | ["\u0F20"-"\u0F29"]
+    >
+| <#Extender :
+        "\u00B7" | "\u02D0" | "\u02D1" | "\u0387" | "\u0640" | "\u0E46" | "\u0EC6" |
+        "\u3005" | ["\u3031"-"\u3035"] | ["\u309D"-"\u309E"] | ["\u30FC"-"\u30FE"]
+    >
+| <NCName : (<Letter> | ["_"]) (<Letter> | <UnicodeDigit> | [".","-","_"] | <CombiningChar> | <Extender>)* >
+| <WS: ["\t", "\r", "\n", " "] >
+| <QName : (<NCName> ":")? <NCName> >
+}
+
+<DEFAULT, IN_SCHEME>
+TOKEN :
+{
+  <LBRACE: "(" >
+| <RBRACE: ")" >
+}
+
+<IN_SCHEME>
+TOKEN :
+{
+  <CIRC_LBRACE: "^(" >
+| <CIRC_RBRACE: "^)" >
+| <DOUBLE_CIRC: "^^" >
+| <NormalChar: ~["(", ")", "^"] >
+}
+
+void pointer():
+{
+}
+{
+  LOOKAHEAD(2) schemeBased() | shortHand()
+}
+
+void shortHand():
+{
+  Token x;
+}
+{
+  x = <NCName>
+  {
+    xpointer.addPart(new ShorthandPart(x.image));
+  }
+}
+
+void schemeBased():
+{
+}
+{
+  pointerPart() ( (<WS>)* pointerPart() )*
+}
+
+void pointerPart():
+{
+  Token x;
+  String schemeName;
+  String schemeData;
+}
+{
+  (x = <NCName> | x = <QName>)
+    <LBRACE>
+    {
+      // when going inside the scheme data, swith to a different lexical state
+      token_source.SwitchTo(IN_SCHEME);
+
+      // store the scheme name
+      schemeName = x.image;
+    }
+  schemeData = schemeData()
+    <RBRACE>
+    {
+      // when going outside the scheme data, swith back to the default lexical state
+      token_source.SwitchTo(DEFAULT);
+
+      // parse schemeName in prefix and localName
+      String schemeNamespace = null, schemeLocalName = null;
+      int colonPos = schemeName.indexOf(':');
+      if (colonPos != -1) {
+         String schemePrefix = schemeName.substring(0, colonPos);
+         schemeNamespace = (String)namespaces.get(schemePrefix);
+         schemeLocalName = schemeName.substring(colonPos + 1);
+       } else {
+         schemeLocalName = schemeName;
+       }
+
+
+      // add the pointer part
+      if (schemeNamespace == null && schemeLocalName.equals("xmlns")) {
+        int eqPos = schemeData.indexOf("=");
+        if (eqPos == -1)
+          throw new ParseException("xmlns scheme data should contain an equals sign");
+
+        // Note: the trimming below is not entirely correct, since space is only allowed left
+        // and right of the equal sign, but not at the beginning and end of the schemeData
+        String prefix = schemeData.substring(0, eqPos).trim();
+        String namespace = schemeData.substring(eqPos + 1, schemeData.length()).trim();
+        xpointer.addPart(new XmlnsPart(prefix, namespace));
+        namespaces.put(prefix, namespace);
+      } else if (schemeNamespace == null && schemeLocalName.equals("xpointer")) {
+        xpointer.addPart(new XPointerPart(schemeData));
+      } else if ("http://apache.org/cocoon/xpointer".equals(schemeNamespace) && schemeLocalName.equals("elementpath")) {
+        xpointer.addPart(new ElementPathPart(schemeData));
+      } else {
+        xpointer.addPart(new UnsupportedPart(schemeName));
+      }
+    }
+}
+
+String schemeData():
+{
+  String temp;
+  StringBuffer schemeData = new StringBuffer();
+}
+{
+  (
+   ( temp = escapedData() { schemeData.append(temp); } )*
+  )
+  {
+    return unescape(schemeData.toString());
+  }
+}
+
+String escapedData():
+{
+  Token x;
+  String temp;
+  StringBuffer data = new StringBuffer();
+}
+{
+  // The reason for not making a token out of this all is that tokens cannot contain recursive definitions
+  (
+   x = <NormalChar> { data.append(x.image); }
+   | x = <CIRC_LBRACE> { data.append(x.image); }
+   | x = <CIRC_RBRACE> { data.append(x.image); }
+   | x = <DOUBLE_CIRC> { data.append(x.image); }
+   | x = <LBRACE> { data.append(x.image); }
+     temp = schemeData() { data.append(temp); }
+     x = <RBRACE> { data.append(x.image); }
+  )
+  {
+    return data.toString();
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxErrorListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxErrorListener.java
new file mode 100644
index 0000000..718f7b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxErrorListener.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.xslt;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.TransformerException;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationUtils;
+
+/**
+ * A smart error listener for <code>javax.xml.tranform</code> that does its best to provide
+ * useful error messages.
+ * 
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class TraxErrorListener implements ErrorListener{
+
+    private Logger logger;
+    private String uri;
+    
+    /** The exception we had from warning() */
+    private TransformerException warningEx;
+    
+    /** The exception we had from error() or fatalError() */
+    private TransformerException exception;
+
+    public TraxErrorListener(Logger logger, String uri) {
+        this.logger = logger;
+        this.uri = uri;
+    }
+
+    /**
+     * Get the exception that was catched by this listener, if any.
+     * 
+     * @return the exception
+     */
+    public Throwable getThrowable() {
+        if (exception == null) {
+            return null;
+        }
+        
+        Location loc = LocationUtils.getLocation(exception);
+        if (LocationUtils.isKnown(loc)) {
+            // Has a location: don't loose this precious information!
+            return exception;
+        }
+        
+        // No location: if it's just a wrapper, consider only the wrapped exception
+        if (exception.getCause() != null) {
+            return exception.getCause();
+        }
+        
+        // That's the actual exception!
+        return exception;
+    }
+
+    public void warning(TransformerException ex) throws TransformerException {
+        // TODO: We may want here to allow some special formatting of the messages, such as
+        // "DEBUG:A debug message" or "INFO:Transforming <foo> in mode 'bar'" to use the different
+        // log levels. This can include also deprecation logs for system-defined stylesheets
+        // using "DEPRECATED:WARN:Styling 'foo' is replaced by 'bar'".    
+
+        if (logger.isWarnEnabled()) {
+            Location loc = LocationUtils.getLocation(ex);
+            logger.warn(ex.getMessage() + " at "+ loc == null ? uri : loc.toString());
+        }
+        // Keep the warning (see below)
+        warningEx = ex;
+    }
+
+    public void error(TransformerException ex) throws TransformerException {
+
+        // If we had a warning previoulsy, and the current exception has no cause, then use the warning.
+        // This is how Xalan behaves on <xsl:message terminate="yes">: it first issues a warning with all
+        // the useful information, then a useless "stylesheed directed termination" error.
+        if (warningEx != null && ex.getCause() == null) {
+            ex = warningEx;
+        }
+        warningEx = null;
+
+        // Keep the exception for later use.
+        exception = ex;
+        // and rethrow it
+        throw ex;
+    }
+
+    public void fatalError(TransformerException ex) throws TransformerException {
+        if (warningEx != null && ex.getCause() == null) {
+            ex = warningEx;
+        }
+        warningEx = null;
+
+        exception = ex;
+        throw ex;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxProcessor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxProcessor.java
new file mode 100644
index 0000000..065d877
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/components/xslt/TraxProcessor.java
@@ -0,0 +1,638 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.components.xslt;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TemplatesHandler;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AggregatedValidity;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.excalibur.xml.xslt.XSLTProcessor;
+import org.apache.excalibur.xml.xslt.XSLTProcessorException;
+import org.apache.excalibur.xmlizer.XMLizer;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLFilter;
+
+/**
+ * Adaptation of Excalibur's XSLTProcessor implementation to allow for better
+ * error reporting.
+ * 
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class TraxProcessor extends AbstractLogEnabled implements XSLTProcessor, Serviceable, Initializable, Disposable, Parameterizable,
+        Recyclable, URIResolver {
+    /** The store service instance */
+    protected Store m_store;
+
+    /** The configured transformer factory to use */
+    protected String m_transformerFactory;
+
+    /** The trax TransformerFactory this component uses */
+    protected SAXTransformerFactory m_factory;
+
+    /** The default TransformerFactory used by this component */
+    protected SAXTransformerFactory m_defaultFactory;
+
+    /** Is the store turned on? (default is off) */
+    protected boolean m_useStore;
+
+    /** Is incremental processing turned on? (default for Xalan: no) */
+    protected boolean m_incrementalProcessing;
+
+    /** Resolver used to resolve XSLT document() calls, imports and includes */
+    protected SourceResolver m_resolver;
+
+    /** Check included stylesheets */
+    protected boolean m_checkIncludes;
+
+    /** Map of pairs of System ID's / validities of the included stylesheets */
+    protected Map m_includesMap = new HashMap();
+
+    protected XMLizer m_xmlizer;
+
+    /** The ServiceManager */
+    protected ServiceManager m_manager;
+
+    /**
+     * Compose. Try to get the store
+     * 
+     * @avalon.service interface="XMLizer"
+     * @avalon.service interface="SourceResolver"
+     * @avalon.service interface="Store/TransientStore" optional="true"
+     */
+    public void service(final ServiceManager manager) throws ServiceException {
+        m_manager = manager;
+        m_xmlizer = (XMLizer) m_manager.lookup(XMLizer.ROLE);
+        m_resolver = (SourceResolver) m_manager.lookup(SourceResolver.ROLE);
+
+        if (m_manager.hasService(Store.TRANSIENT_STORE)) {
+            m_store = (Store) m_manager.lookup(Store.TRANSIENT_STORE);
+        }
+    }
+
+    /**
+     * Initialize
+     */
+    public void initialize() throws Exception {
+        m_factory = getTransformerFactory(m_transformerFactory);
+        m_defaultFactory = m_factory;
+    }
+
+    /**
+     * Disposable
+     */
+    public void dispose() {
+        if (null != m_manager) {
+            m_manager.release(m_store);
+            m_manager.release(m_resolver);
+            m_manager.release(m_xmlizer);
+            m_manager = null;
+        }
+        m_xmlizer = null;
+        m_store = null;
+        m_resolver = null;
+    }
+
+    /**
+     * Configure the component
+     */
+    public void parameterize(final Parameters params) throws ParameterException {
+        m_useStore = params.getParameterAsBoolean("use-store", this.m_useStore);
+        m_incrementalProcessing = params.getParameterAsBoolean("incremental-processing", this.m_incrementalProcessing);
+        m_transformerFactory = params.getParameter("transformer-factory", null);
+        m_checkIncludes = params.getParameterAsBoolean("check-includes", true);
+        if (!m_useStore) {
+            // release the store, if we don't need it anymore
+            m_manager.release(m_store);
+            m_store = null;
+        } else if (null == m_store) {
+            final String message = "XSLTProcessor: use-store is set to true, " + "but unable to aquire the Store.";
+            throw new ParameterException(message);
+        }
+    }
+
+    /**
+     * Set the transformer factory used by this component
+     */
+    public void setTransformerFactory(final String classname) {
+        m_factory = getTransformerFactory(classname);
+    }
+
+    /**
+     * @see org.apache.excalibur.xml.xslt.XSLTProcessor#getTransformerHandler(org.apache.excalibur.source.Source)
+     */
+    public TransformerHandler getTransformerHandler(final Source stylesheet) throws XSLTProcessorException {
+        return getTransformerHandler(stylesheet, null);
+    }
+
+    /**
+     * @see org.apache.excalibur.xml.xslt.XSLTProcessor#getTransformerHandler(org.apache.excalibur.source.Source,
+     *      org.xml.sax.XMLFilter)
+     */
+    public TransformerHandler getTransformerHandler(final Source stylesheet, final XMLFilter filter) throws XSLTProcessorException {
+        final XSLTProcessor.TransformerHandlerAndValidity validity = getTransformerHandlerAndValidity(stylesheet, filter);
+        return validity.getTransfomerHandler();
+    }
+
+    public TransformerHandlerAndValidity getTransformerHandlerAndValidity(final Source stylesheet) throws XSLTProcessorException {
+        return getTransformerHandlerAndValidity(stylesheet, null);
+    }
+
+    public TransformerHandlerAndValidity getTransformerHandlerAndValidity(Source stylesheet, XMLFilter filter) throws XSLTProcessorException {
+
+        final String id = stylesheet.getURI();
+        TransformerHandlerAndValidity handlerAndValidity;
+
+        try {
+            handlerAndValidity = getTemplates(stylesheet, id);
+            if (handlerAndValidity != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Reusing Templates for " + id);
+                }
+                return handlerAndValidity;
+            }
+        } catch(Exception e) {
+            throw new XSLTProcessorException("Error retrieving template", e);
+        }
+        
+        TraxErrorListener errorListener = new TraxErrorListener(getLogger(), stylesheet.getURI());
+        try{
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Creating new Templates for " + id);
+            }
+
+            m_factory.setErrorListener(errorListener);
+
+            // Create a Templates ContentHandler to handle parsing of the
+            // stylesheet.
+            TemplatesHandler templatesHandler = m_factory.newTemplatesHandler();
+
+            // Set the system ID for the template handler since some
+            // TrAX implementations (XSLTC) rely on this in order to obtain
+            // a meaningful identifier for the Templates instances.
+            templatesHandler.setSystemId(id);
+            if (filter != null) {
+                filter.setContentHandler(templatesHandler);
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Source = " + stylesheet + ", templatesHandler = " + templatesHandler);
+            }
+
+            // Initialize List for included validities
+            SourceValidity validity = stylesheet.getValidity();
+            if (validity != null && m_checkIncludes) {
+                m_includesMap.put(id, new ArrayList());
+            }
+
+            try {
+                // Process the stylesheet.
+                sourceToSAX(stylesheet, filter != null ? (ContentHandler) filter : (ContentHandler) templatesHandler);
+
+                // Get the Templates object (generated during the parsing of
+                // the stylesheet) from the TemplatesHandler.
+                final Templates template = templatesHandler.getTemplates();
+
+                if (null == template) {
+                    throw new XSLTProcessorException("Unable to create templates for stylesheet: " + stylesheet.getURI());
+                }
+
+                putTemplates(template, stylesheet, id);
+
+                // Create transformer handler
+                final TransformerHandler handler = m_factory.newTransformerHandler(template);
+                handler.getTransformer().setErrorListener(new TraxErrorListener(getLogger(), stylesheet.getURI()));
+                handler.getTransformer().setURIResolver(this);
+
+                // Create aggregated validity
+                AggregatedValidity aggregated = null;
+                if (validity != null && m_checkIncludes) {
+                    List includes = (List) m_includesMap.get(id);
+                    if (includes != null) {
+                        aggregated = new AggregatedValidity();
+                        aggregated.add(validity);
+                        for (int i = includes.size() - 1; i >= 0; i--) {
+                            aggregated.add((SourceValidity) ((Object[]) includes.get(i))[1]);
+                        }
+                        validity = aggregated;
+                    }
+                }
+
+                // Create result
+                handlerAndValidity = new MyTransformerHandlerAndValidity(handler, validity);
+            } finally {
+                if (m_checkIncludes)
+                    m_includesMap.remove(id);
+            }
+
+            return handlerAndValidity;
+        } catch (Exception e) {
+            Throwable realEx = errorListener.getThrowable();
+            if (realEx == null) realEx = e;
+            
+            if (realEx instanceof RuntimeException) {
+                throw (RuntimeException)realEx;
+            }
+            
+            if (realEx instanceof XSLTProcessorException) {
+                throw (XSLTProcessorException)realEx;
+            }
+            
+            throw new XSLTProcessorException("Exception when creating Transformer from " + stylesheet.getURI(), realEx);
+        }
+    }
+
+    private void sourceToSAX(Source source, ContentHandler handler) throws SAXException, IOException, SourceException {
+        if (source instanceof XMLizable) {
+            ((XMLizable) source).toSAX(handler);
+        } else {
+            final InputStream inputStream = source.getInputStream();
+            final String mimeType = source.getMimeType();
+            final String systemId = source.getURI();
+            m_xmlizer.toSAX(inputStream, mimeType, systemId, handler);
+        }
+    }
+
+    public void transform(final Source source, final Source stylesheet, final Parameters params, final Result result) throws XSLTProcessorException {
+        try {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug(
+                        "Transform source = " + source + ", stylesheet = " + stylesheet + ", parameters = " + params + ", result = " + result);
+            }
+            final TransformerHandler handler = getTransformerHandler(stylesheet);
+            if (params != null) {
+                final Transformer transformer = handler.getTransformer();
+                transformer.clearParameters();
+                String[] names = params.getNames();
+                for (int i = names.length - 1; i >= 0; i--) {
+                    transformer.setParameter(names[i], params.getParameter(names[i]));
+                }
+            }
+
+            handler.setResult(result);
+            sourceToSAX(source, handler);
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Transform done");
+            }
+        } catch (SAXException e) {
+            // Unwrapping the exception will "remove" the real cause with
+            // never Xalan versions and makes the exception message unusable
+            final String message = "Error in running Transformation";
+            throw new XSLTProcessorException(message, e);
+            /*
+             * if( e.getException() == null ) { final String message = "Error in
+             * running Transformation"; throw new XSLTProcessorException(
+             * message, e ); } else { final String message = "Got SAXException.
+             * Rethrowing cause exception."; getLogger().debug( message, e );
+             * throw new XSLTProcessorException( "Error in running
+             * Transformation", e.getException() ); }
+             */
+        } catch (Exception e) {
+            final String message = "Error in running Transformation";
+            throw new XSLTProcessorException(message, e);
+        }
+    }
+
+    /**
+     * Get the TransformerFactory associated with the given classname. If the
+     * class can't be found or the given class doesn't implement the required
+     * interface, the default factory is returned.
+     */
+    private SAXTransformerFactory getTransformerFactory(String factoryName) {
+        SAXTransformerFactory _factory;
+
+        if (null == factoryName) {
+            _factory = (SAXTransformerFactory) TransformerFactory.newInstance();
+        } else {
+            try {
+                ClassLoader loader = Thread.currentThread().getContextClassLoader();
+                if (loader == null) {
+                    loader = getClass().getClassLoader();
+                }
+                _factory = (SAXTransformerFactory) loader.loadClass(factoryName).newInstance();
+            } catch (ClassNotFoundException cnfe) {
+                getLogger().error("Cannot find the requested TrAX factory '" + factoryName + "'. Using default TrAX Transformer Factory instead.");
+                if (m_factory != null)
+                    return m_factory;
+                _factory = (SAXTransformerFactory) TransformerFactory.newInstance();
+            } catch (ClassCastException cce) {
+                getLogger().error(
+                        "The indicated class '" + factoryName
+                                + "' is not a TrAX Transformer Factory. Using default TrAX Transformer Factory instead.");
+                if (m_factory != null)
+                    return m_factory;
+                _factory = (SAXTransformerFactory) TransformerFactory.newInstance();
+            } catch (Exception e) {
+                getLogger().error(
+                        "Error found loading the requested TrAX Transformer Factory '" + factoryName
+                                + "'. Using default TrAX Transformer Factory instead.");
+                if (m_factory != null)
+                    return m_factory;
+                _factory = (SAXTransformerFactory) TransformerFactory.newInstance();
+            }
+        }
+
+        _factory.setErrorListener(new TraxErrorListener(getLogger(), null));
+        _factory.setURIResolver(this);
+
+        // FIXME (SM): implementation-specific parameter passing should be
+        // made more extensible.
+        if (_factory.getClass().getName().equals("org.apache.xalan.processor.TransformerFactoryImpl")) {
+            _factory.setAttribute("http://xml.apache.org/xalan/features/incremental", Boolean.valueOf(m_incrementalProcessing));
+        }
+
+        return _factory;
+    }
+
+    private TransformerHandlerAndValidity getTemplates(Source stylesheet, String id) throws IOException, TransformerException {
+        if (!m_useStore) {
+            return null;
+        }
+
+        // we must augment the template ID with the factory classname since one
+        // transformer implementation cannot handle the instances of a
+        // template created by another one.
+        String key = "XSLTTemplate: " + id + '(' + m_factory.getClass().getName() + ')';
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("getTemplates: stylesheet " + id);
+        }
+
+        SourceValidity newValidity = stylesheet.getValidity();
+
+        // Only stylesheets with validity are stored
+        if (newValidity == null) {
+            // Remove an old template
+            m_store.remove(key);
+            return null;
+        }
+
+        // Stored is an array of the templates and the caching time and list of
+        // includes
+        Object[] templateAndValidityAndIncludes = (Object[]) m_store.get(key);
+        if (templateAndValidityAndIncludes == null) {
+            // Templates not found in cache
+            return null;
+        }
+
+        // Check template modification time
+        SourceValidity storedValidity = (SourceValidity) templateAndValidityAndIncludes[1];
+        int valid = storedValidity.isValid();
+        boolean isValid;
+        if (valid == 0) {
+            valid = storedValidity.isValid(newValidity);
+            isValid = (valid == 1);
+        } else {
+            isValid = (valid == 1);
+        }
+        if (!isValid) {
+            m_store.remove(key);
+            return null;
+        }
+
+        // Check includes
+        if (m_checkIncludes) {
+            AggregatedValidity aggregated = null;
+            List includes = (List) templateAndValidityAndIncludes[2];
+            if (includes != null) {
+                aggregated = new AggregatedValidity();
+                aggregated.add(storedValidity);
+
+                for (int i = includes.size() - 1; i >= 0; i--) {
+                    // Every include stored as pair of source ID and validity
+                    Object[] pair = (Object[]) includes.get(i);
+                    storedValidity = (SourceValidity) pair[1];
+                    aggregated.add(storedValidity);
+
+                    valid = storedValidity.isValid();
+                    isValid = false;
+                    if (valid == 0) {
+                        Source includedSource = null;
+                        try {
+                            includedSource = m_resolver.resolveURI((String) pair[0]);
+                            SourceValidity included = includedSource.getValidity();
+                            if (included != null) {
+                                valid = storedValidity.isValid(included);
+                                isValid = (valid == 1);
+                            }
+                        } finally {
+                            m_resolver.release(includedSource);
+                        }
+                    } else {
+                        isValid = (valid == 1);
+                    }
+                    if (!isValid) {
+                        m_store.remove(key);
+                        return null;
+                    }
+                }
+                storedValidity = aggregated;
+            }
+        }
+
+        TransformerHandler handler = m_factory.newTransformerHandler((Templates) templateAndValidityAndIncludes[0]);
+        handler.getTransformer().setErrorListener(new TraxErrorListener(getLogger(), stylesheet.getURI()));
+        handler.getTransformer().setURIResolver(this);
+        return new MyTransformerHandlerAndValidity(handler, storedValidity);
+    }
+
+    private void putTemplates(Templates templates, Source stylesheet, String id) throws IOException {
+        if (!m_useStore)
+            return;
+
+        // we must augment the template ID with the factory classname since one
+        // transformer implementation cannot handle the instances of a
+        // template created by another one.
+        String key = "XSLTTemplate: " + id + '(' + m_factory.getClass().getName() + ')';
+
+        // only stylesheets with a last modification date are stored
+        SourceValidity validity = stylesheet.getValidity();
+        if (null != validity) {
+            // Stored is an array of the template and the current time
+            Object[] templateAndValidityAndIncludes = new Object[3];
+            templateAndValidityAndIncludes[0] = templates;
+            templateAndValidityAndIncludes[1] = validity;
+            if (m_checkIncludes) {
+                templateAndValidityAndIncludes[2] = m_includesMap.get(id);
+            }
+            m_store.store(key, templateAndValidityAndIncludes);
+        }
+    }
+
+    /**
+     * Called by the processor when it encounters an xsl:include, xsl:import, or
+     * document() function.
+     * 
+     * @param href
+     *            An href attribute, which may be relative or absolute.
+     * @param base
+     *            The base URI in effect when the href attribute was
+     *            encountered.
+     * 
+     * @return A Source object, or null if the href cannot be resolved, and the
+     *         processor should try to resolve the URI itself.
+     * 
+     * @throws TransformerException
+     *             if an error occurs when trying to resolve the URI.
+     */
+    public javax.xml.transform.Source resolve(String href, String base) throws TransformerException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("resolve(href = " + href + ", base = " + base + "); resolver = " + m_resolver);
+        }
+
+        Source xslSource = null;
+        try {
+            if (base == null || href.indexOf(":") > 1) {
+                // Null base - href must be an absolute URL
+                xslSource = m_resolver.resolveURI(href);
+            } else if (href.length() == 0) {
+                // Empty href resolves to base
+                xslSource = m_resolver.resolveURI(base);
+            } else {
+                // is the base a file or a real m_url
+                if (!base.startsWith("file:")) {
+                    int lastPathElementPos = base.lastIndexOf('/');
+                    if (lastPathElementPos == -1) {
+                        // this should never occur as the base should
+                        // always be protocol:/....
+                        return null; // we can't resolve this
+                    } else {
+                        xslSource = m_resolver.resolveURI(base.substring(0, lastPathElementPos) + "/" + href);
+                    }
+                } else {
+                    File parent = new File(base.substring(5));
+                    File parent2 = new File(parent.getParentFile(), href);
+                    xslSource = m_resolver.resolveURI(parent2.toURL().toExternalForm());
+                }
+            }
+
+            InputSource is = getInputSource(xslSource);
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("xslSource = " + xslSource + ", system id = " + xslSource.getURI());
+            }
+
+            if (m_checkIncludes) {
+                // Populate included validities
+                List includes = (List) m_includesMap.get(base);
+                if (includes != null) {
+                    SourceValidity included = xslSource.getValidity();
+                    if (included != null) {
+                        includes.add(new Object[] { xslSource.getURI(), xslSource.getValidity() });
+                    } else {
+                        // One of the included stylesheets is not cacheable
+                        m_includesMap.remove(base);
+                    }
+                }
+            }
+
+            return new StreamSource(is.getByteStream(), is.getSystemId());
+        } catch (SourceException e) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Failed to resolve " + href + "(base = " + base + "), return null", e);
+            }
+
+            // CZ: To obtain the same behaviour as when the resource is
+            // transformed by the XSLT Transformer we should return null here.
+            return null;
+        } catch (java.net.MalformedURLException mue) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Failed to resolve " + href + "(base = " + base + "), return null", mue);
+            }
+
+            return null;
+        } catch (IOException ioe) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Failed to resolve " + href + "(base = " + base + "), return null", ioe);
+            }
+
+            return null;
+        } finally {
+            m_resolver.release(xslSource);
+        }
+    }
+
+    /**
+     * Return a new <code>InputSource</code> object that uses the
+     * <code>InputStream</code> and the system ID of the <code>Source</code>
+     * object.
+     * 
+     * @throws IOException
+     *             if I/O error occured.
+     */
+    private static InputSource getInputSource(final Source source) throws IOException, SourceException {
+        final InputSource newObject = new InputSource(source.getInputStream());
+        newObject.setSystemId(source.getURI());
+        return newObject;
+    }
+
+    /**
+     * Recycle the component
+     */
+    public void recycle() {
+        m_includesMap.clear();
+        // restore default factory
+        if (m_factory != m_defaultFactory) {
+            m_factory = m_defaultFactory;
+        }
+    }
+
+    /**
+     * Subclass to allow for instanciation, as for some unknown reason the
+     * constructor is protected....
+     */
+    public static class MyTransformerHandlerAndValidity extends TransformerHandlerAndValidity {
+
+        protected MyTransformerHandlerAndValidity(TransformerHandler handler, SourceValidity validity) {
+            super(handler, validity);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/configuration/ConfigurationBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/configuration/ConfigurationBuilder.java
new file mode 100644
index 0000000..3bdeffa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/configuration/ConfigurationBuilder.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation
+ * 
+ * Licensed 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.cocoon.configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Iterator;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.util.PropertyHelper;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.NamespaceSupport;
+
+/**
+ * A ConfigurationBuilder builds {@link Configuration}s from XML,
+ * via a SAX2 compliant parser.
+ *
+ * <p>
+ * The mapping from XML namespaces to {@link Configuration} namespaces is pretty
+ * straightforward, with one caveat: attribute namespaces are (deliberately) not
+ * supported. Enabling namespace processing has the following effects:</p>
+ * <ul>
+ *  <li>Attributes starting with <code>xmlns:</code> are interpreted as
+ *  declaring a prefix:namespaceURI mapping, and won't result in the creation of
+ *  <code>xmlns</code>-prefixed attributes in the <code>Configuration</code>.
+ *  </li>
+ *  <li>
+ *  Prefixed XML elements, like <tt>&lt;doc:title xmlns:doc="http://foo.com"&gt;,</tt>
+ *  will result in a <code>Configuration</code> with <code>{@link
+ *  Configuration#getName getName()}.equals("title")</code> and <code>{@link
+ *  Configuration#getNamespace getNamespace()}.equals("http://foo.com")</code>.
+ *  </li>
+ * </ul>
+ * <p>
+ * Whitespace handling. Since mixed content is not allowed in the
+ * configurations, whitespace is completely discarded in non-leaf nodes.
+ * For the leaf nodes the default behavior is to trim the space
+ * surrounding the value. This can be changed by specifying
+ * <code>xml:space</code> attribute with value of <code>preserve</code>
+ * in that case the whitespace is left intact.
+ * </p>
+ *
+ * @version $Id$
+ */
+public class ConfigurationBuilder
+    extends DefaultHandler
+    implements ErrorHandler {
+    
+    private XMLReader parser;
+    
+    /**
+     * Likely number of nested configuration items. If more is
+     * encountered the lists will grow automatically.
+     */
+    private static final int EXPECTED_DEPTH = 4;
+    private final ArrayList elements = new ArrayList( EXPECTED_DEPTH );
+    private final ArrayList prefixes = new ArrayList( EXPECTED_DEPTH );
+    private final ArrayList values = new ArrayList( EXPECTED_DEPTH );
+    
+    /**
+     * Contains true at index n if space in the configuration with
+     * depth n is to be preserved.
+     */
+    private final BitSet preserveSpace = new BitSet();
+    private Configuration configuration;
+    private Locator locator;
+    private final NamespaceSupport namespaceSupport = new NamespaceSupport();
+    private final Settings settings;
+    
+    /**
+     * Create a Configuration Builder
+     */
+    public ConfigurationBuilder(Settings s) {
+        this.settings = s;
+        try {
+            final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+
+            saxParserFactory.setNamespaceAware( true );
+
+            final SAXParser saxParser = saxParserFactory.newSAXParser();
+
+            this.parser = saxParser.getXMLReader();
+
+            this.parser.setContentHandler( this );
+            this.parser.setErrorHandler( this );
+        } catch( final Exception se ) {
+            throw new Error( "Unable to setup SAX parser" + se );
+        }
+    }
+
+    /**
+     * Build a configuration object using an InputStream.
+     * @param inputStream an <code>InputStream</code> value
+     * @return a <code>Configuration</code> object
+     * @throws SAXException if a parsing error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    public Configuration build( final InputStream inputStream )
+    throws SAXException, IOException {
+        return this.build( new InputSource( inputStream ) );
+    }
+
+    /**
+     * Build a configuration object using an InputStream;
+     * supplying a systemId to make messages about all
+     * kinds of errors more meaningfull.
+     * @param inputStream an <code>InputStream</code> value
+     * @param systemId the systemId to set on the intermediate sax
+     *         inputSource
+     * @return a <code>Configuration</code> object
+     * @throws SAXException if a parsing error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    public Configuration build( final InputStream inputStream, 
+                                final String systemId )
+    throws SAXException, IOException {
+        final InputSource inputSource = new InputSource( inputStream );
+        inputSource.setSystemId( systemId );
+        return this.build( inputSource );
+    }
+
+    /**
+     * Build a configuration object using an URI
+     * @param uri a <code>String</code> value
+     * @return a <code>Configuration</code> object
+     * @throws SAXException if a parsing error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    public Configuration build( final String uri )
+    throws SAXException, IOException {
+        return this.build( new InputSource( uri ) );
+    }
+
+    /**
+     * Build a configuration object using an XML InputSource object
+     * @param input an <code>InputSource</code> value
+     * @return a <code>Configuration</code> object
+     * @throws SAXException if a parsing error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    public Configuration build( final InputSource input )
+    throws SAXException, IOException {
+        synchronized( this ) {
+            this.clear();
+            this.parser.parse( input );
+            return this.configuration;
+        }
+    }
+
+    /**
+     * Sets the <code>EntityResolver</code> to 
+     * be used by parser. Useful when dealing with xml
+     * files that reference external entities.
+     * 
+     * @param resolver implementation of <code>EntityResolver</code>
+     */
+    public void setEntityResolver( final EntityResolver resolver ) {
+        this.parser.setEntityResolver( resolver );
+    }
+
+    /**
+     * Clears all data from this configuration handler.
+     */
+    protected void clear() {
+        this.elements.clear();
+        Iterator i = this.prefixes.iterator();
+        while( i.hasNext() ) {
+            ( (ArrayList)i.next() ).clear();
+        }
+        this.prefixes.clear();
+        this.values.clear();
+        this.locator = null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
+     */
+    public void setDocumentLocator( final Locator locator ) {
+        this.locator = locator;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument()
+    throws SAXException {
+        this.namespaceSupport.reset();
+        super.startDocument();
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument()
+    throws SAXException {
+        super.endDocument();
+        this.namespaceSupport.reset();
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+     */
+    public void characters( final char[] ch, int start, int end )
+    throws SAXException {
+        // it is possible to play micro-optimization here by doing
+        // manual trimming and thus preserve some precious bits
+        // of memory, but it's really not important enough to justify
+        // resulting code complexity
+        final int depth = this.values.size() - 1;
+        final StringBuffer valueBuffer = (StringBuffer)this.values.get( depth );
+        valueBuffer.append( ch, start, end );
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endElement( final String namespaceURI,
+                            final String localName,
+                            final String rawName )
+    throws SAXException {
+        final int depth = this.elements.size() - 1;
+        final DefaultConfiguration finishedConfiguration =
+        (DefaultConfiguration)this.elements.remove( depth );
+        final String accumulatedValue =
+        ( (StringBuffer)this.values.remove( depth ) ).toString();
+        final ArrayList prefixes = (ArrayList)this.prefixes.remove( depth );
+
+        final Iterator i = prefixes.iterator();
+        while( i.hasNext() ) {
+            endPrefixMapping( (String)i.next() );
+        }
+        prefixes.clear();
+
+        if( finishedConfiguration.getChildren().length == 0 ) {
+            // leaf node
+            String finishedValue;
+            if( this.preserveSpace.get( depth ) ) {
+                finishedValue = accumulatedValue;
+            } else if( accumulatedValue.length() == 0 ) {
+                finishedValue = null;
+            } else {
+                finishedValue = accumulatedValue.trim();
+            }
+            finishedConfiguration.setValue( PropertyHelper.replace(finishedValue, this.settings) );
+        } else {
+            final String trimmedValue = accumulatedValue.trim();
+            if( trimmedValue.length() > 0 ) {
+                throw new SAXException( "Not allowed to define mixed content in the " 
+                        + "element " + finishedConfiguration.getName() + " at "
+                        + finishedConfiguration.getLocation() );
+            }
+        }
+
+        if( depth == 0 ) {
+            this.configuration = finishedConfiguration;
+        }
+        this.namespaceSupport.popContext();
+    }
+
+    /**
+     * Create a new <code>DefaultConfiguration</code> with the specified
+     * local name, namespace, and location.
+     *
+     * @param localName a <code>String</code> value
+     * @param namespaceURI a <code>String</code> value
+     * @param location a <code>String</code> value
+     * @return a <code>DefaultConfiguration</code> value
+     */
+    protected DefaultConfiguration createConfiguration( final String localName,
+                                                        final String namespaceURI,
+                                                        final String location ) {
+        String prefix = this.namespaceSupport.getPrefix( namespaceURI );
+        if( prefix == null ) {
+            prefix = "";
+        }
+        return new DefaultConfiguration( localName, location, namespaceURI, prefix );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startElement( final String namespaceURI,
+                              final String localName,
+                              final String rawName,
+                              final Attributes attributes )
+    throws SAXException {
+        this.namespaceSupport.pushContext();
+        final DefaultConfiguration configuration =
+            createConfiguration( localName, namespaceURI, getLocationString() );
+        // depth of new configuration (not decrementing here, configuration
+        // is to be added)
+        final int depth = this.elements.size();
+        boolean preserveSpace = false; // top level element trims space by default
+
+        if( depth > 0 ) {
+            final DefaultConfiguration parent =
+                (DefaultConfiguration)this.elements.get( depth - 1 );
+            parent.addChild( configuration );
+            // inherits parent's space preservation policy
+            preserveSpace = this.preserveSpace.get( depth - 1 );
+        }
+
+        this.elements.add( configuration );
+        this.values.add( new StringBuffer() );
+
+        final ArrayList prefixes = new ArrayList();
+        AttributesImpl componentAttr = new AttributesImpl();
+
+        for( int i = 0; i < attributes.getLength(); i++ ) {
+            if( attributes.getQName( i ).startsWith( "xmlns" ) ) {
+                prefixes.add( attributes.getLocalName( i ) );
+                this.startPrefixMapping( attributes.getLocalName( i ),
+                                         attributes.getValue( i ) );
+            } else if( attributes.getQName( i ).equals( "xml:space" ) ) {
+                preserveSpace = attributes.getValue( i ).equals( "preserve" );
+            } else {
+                componentAttr.addAttribute( attributes.getURI( i ),
+                                            attributes.getLocalName( i ),
+                                            attributes.getQName( i ),
+                                            attributes.getType( i ),
+                                            attributes.getValue( i ) );
+            }
+        }
+
+        if( preserveSpace ) {
+            this.preserveSpace.set( depth );
+        } else {
+            this.preserveSpace.clear( depth );
+        }
+
+        this.prefixes.add( prefixes );
+
+        final int attributesSize = componentAttr.getLength();
+
+        for( int i = 0; i < attributesSize; i++ ) {
+            final String name = componentAttr.getQName( i );
+            final String value = componentAttr.getValue( i );
+            configuration.setAttribute( name, PropertyHelper.replace(value, this.settings) );
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+     */
+    public void error( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+     */
+    public void warning( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+     */
+    public void fatalError( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /**
+     * Returns a string showing the current system ID, line number and column number.
+     *
+     * @return a <code>String</code> value
+     */
+    private String getLocationString() {
+        if( this.locator == null ) {
+            return "Unknown";
+        } 
+        final int columnNumber = this.locator.getColumnNumber();
+        return this.locator.getSystemId() + ":"
+            + this.locator.getLineNumber()
+            + ( columnNumber >= 0 ? ( ":" + columnNumber ) : "" );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
+     */
+    public void startPrefixMapping( String prefix, String uri )
+    throws SAXException {
+        this.namespaceSupport.declarePrefix( prefix, uri );
+        super.startPrefixMapping( prefix, uri );
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BaseSettings.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BaseSettings.java
new file mode 100644
index 0000000..3cc2e05
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BaseSettings.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.core;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The settings (configuration) for the Cocoon core are described through the {@link BaseSettings}
+ * interface and the {@link DynamicSettings} interface.
+ * Whereas the settings of the {@link BaseSettings} object can't be changed at runtime,
+ * the settings of the {@link DynamicSettings} object are mutable. Use the {@link Core} instance
+ * to update the settings.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public interface BaseSettings {
+
+    /** Default value for {@link #isManageExceptions()}. */
+    boolean MANAGE_EXCEPTIONS = true;
+
+    /** Name of the property specifying a custom user properties file. */
+    String PROPERTY_USER_SETTINGS = "org.apache.cocoon.settings";
+
+    /** Name of the property specifying the running mode. */
+    String PROPERTY_RUNNING_MODE = "org.apache.cocoon.mode";
+
+    /** The default running mode. */
+    String DEFAULT_RUNNING_MODE = "dev";
+
+    /**
+     * This parameter allows to set system properties
+     */
+    String KEY_FORCE_PROPERTIES = "system.properties";
+
+    /** This parameter specifies the class for the root processor */
+    String KEY_PROCESSOR_CLASS = "processor";
+    
+    /** The default root processor */
+    String DEFAULT_PROCESSOR_CLASS = "org.apache.cocoon.Cocoon";
+    
+    /**
+     * This parameter points to the main configuration file for Cocoon.
+     * Note that the path is specified in absolute notation but it will be
+     * resolved relative to the application context path.
+     */
+    String KEY_CONFIGURATION = "configuration";
+
+    /**
+     * This parameter indicates the configuration file of the LogKit management
+     */
+    String KEY_LOGGING_CONFIGURATION = "logging.configuration";
+
+    /**
+     * This parameter indicates the log level to use throughout startup of the
+     * system. As soon as the logkit.xconf the setting of the logkit.xconf
+     * configuration is used instead! Only for startup and if the logkit.xconf is
+     * not readable/available this log level is of importance.
+     */
+    String KEY_LOGGING_BOOTSTRAP_LOGLEVEL = "logging.bootstrap.loglevel";
+
+    /**
+     * This parameter switches the logging system from LogKit to Log4J for Cocoon.
+     * Log4J has to be configured already.
+     */
+    String KEY_LOGGING_MANAGER_CLASS = "logging.manager.class";
+
+    /**
+     * This parameter is used to list classes that should be loaded at
+     * initialization time of the servlet. For example, JDBC Drivers used need to
+     * be named here. Additional entries may be inserted here during build
+     * depending on your build properties.
+     */
+    String KEY_LOAD_CLASSES = "classloader.load.classes";
+
+    /**
+     * This parameter allows to specify additional directories or jars
+     * which Cocoon should put into it's own classpath.
+     * Note that absolute pathes are taken as such but relative pathes
+     * are rooted at the context root of the Cocoon servlet.
+     */
+    String KEY_EXTRA_CLASSPATHS = "extra.classpaths";
+
+    /**
+     * This parameter allows you to select the parent service manager.
+     * The class will be instantiated via the constructor that takes a single
+     * String as a parameter. That String will be equal to the text after the '/'.
+     *
+     * Cocoon honors the LogEnabled, Initializable and Disposable interfaces for
+     * this class, if it implements them.
+     */
+    String KEY_PARENT_SERVICE_MANAGER = "parentservicemanager";
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * configuration used by the environment.
+     */
+    String KEY_LOGGING_ENVIRONMENT_LOGGER = "logging.category.environment";
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * management configuration for the Cocoon engine.
+     * This logger is used for all components described in the cocoon.xconf
+     * and sitemap.xmap file not having specified a logger with the
+     * logger="..." attribute in the component configuration file.
+     */
+    String KEY_LOGGING_COCOON_LOGGER = "logging.category.cocoon";
+
+    /**
+     * This parameter allows to specify where Cocoon should put uploaded files.
+     * The path specified can be either absolute or relative to the context
+     * path of the servlet. On windows platform, absolute directory must start
+     * with volume: C:\Path\To\Upload\Directory.
+     */
+    String KEY_UPLOADS_DIRECTORY = "uploads.directory";
+
+    /**
+     * This parameter allows to specify where Cocoon should create its page
+     * and other objects cache. The path specified can be either absolute or
+     * relative to the context path of the servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Cache\Directory.
+     */
+    String KEY_CACHE_DIRECTORY = "cache.directory";
+
+    /**
+     * This parameter allows to specify where Cocoon should put it's
+     * working files. The path specified is either absolute or relative
+     * to the context path of the Cocoon servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Work\Directory.
+     */
+    String KEY_WORK_DIRECTORY = "work.directory";
+
+    /**
+     * If true or not set, this class will try to catch and handle all Cocoon exceptions.
+     * If false, it will rethrow them to the servlet container.
+     */
+    String KEY_MANAGE_EXCEPTIONS = "manageexceptions";
+
+    /**
+     * Set form encoding. This will be the character set used to decode request
+     * parameters. If not set the ISO-8859-1 encoding will be assumed.
+    */
+    String KEY_FORM_ENCODING = "formencoding";
+
+    /**
+     * If this value is specified, it will be interpreted as a log level and
+     * all logging categories will be set to this level regardless of their
+     * definition in the logging configuration.
+     */
+    String KEY_LOGGING_OVERRIDE_LOGLEVEL = "override.loglevel";
+
+    /**
+     * This key allows to add own {@link PropertyProvider}s.
+     */
+    String KEY_PROPERTY_PROVIDER = "property.provider";
+
+    /**
+     * @return Returns the class for the root processor
+     * @see #KEY_PROCESSOR_CLASS
+     */
+    String getProcessorClassName();
+    
+    /**
+     * @return Returns the configuration.
+     * @see #KEY_CONFIGURATION
+     */
+    String getConfiguration();
+
+    /**
+     * @return Returns the extraClasspaths.
+     * @see #KEY_EXTRA_CLASSPATHS
+     */
+    List getExtraClasspaths();
+
+    /**
+     * @return Returns the forceProperties.
+     * @see #KEY_FORCE_PROPERTIES
+     */
+    Map getForceProperties();
+
+    /**
+     * @return Returns the loadClasses.
+     * @see #KEY_LOAD_CLASSES
+     */
+    List getLoadClasses();
+
+    /**
+     * @return Returns the loggerManagerClassName.
+     * @see #KEY_LOGGING_MANAGER_CLASS
+     */
+    String getLoggerManagerClassName();
+
+    /**
+     * @return Returns the loggingConfiguration.
+     * @see #KEY_LOGGING_CONFIGURATION
+     */
+    String getLoggingConfiguration();
+
+    /**
+     * @return Returns the logLevel.
+     * @see #KEY_LOGGING_BOOTSTRAP_LOGLEVEL
+     */
+    String getBootstrapLogLevel();
+
+    /**
+     * @return Returns the parentServiceManagerClassName.
+     * @see #KEY_PARENT_SERVICE_MANAGER
+     */
+    String getParentServiceManagerClassName();
+
+    /**
+     * @return Returns the uploadDirectory.
+     * @see #KEY_UPLOADS_DIRECTORY
+     */
+    String getUploadDirectory();
+
+    /**
+     * @return Returns the workDirectory.
+     * @see #KEY_WORK_DIRECTORY
+     */
+    String getWorkDirectory();
+
+    /**
+     * @return Returns the logger for the environment.
+     * @see #KEY_LOGGING_ENVIRONMENT_LOGGER
+     */
+    String getEnvironmentLogger();
+
+    /**
+     * @return Returns the overrideLogLevel.
+     * @see #KEY_LOGGING_OVERRIDE_LOGLEVEL
+     */
+    String getOverrideLogLevel();
+
+    /**
+     * @return Returns the formEncoding.
+     * @see #KEY_FORM_ENCODING
+     */
+    String getFormEncoding();
+
+    /**
+     * @return Returns the manageExceptions.
+     * @see #KEY_MANAGE_EXCEPTIONS
+     */
+    boolean isManageExceptions();
+
+    /**
+     * @return Returns the cacheDirectory.
+     * @see #KEY_CACHE_DIRECTORY
+     */
+    String getCacheDirectory();
+
+    /**
+     * @return Returns the cocoonLogger.
+     * @see #KEY_LOGGING_COCOON_LOGGER
+     */
+    String getCocoonLogger();
+
+    /**
+     * The creation time of the current Cocoon instance.
+     */
+    long getCreationTime();
+
+    /**
+     * @return All property providers.
+     * @see #KEY_PROPERTY_PROVIDER
+     */
+    List getPropertyProviders();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BootstrapEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BootstrapEnvironment.java
new file mode 100644
index 0000000..2354865
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/BootstrapEnvironment.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+
+/**
+ * The BootstrapEnvironment is the connection between the real environment
+ * (servlet, cli etc.) and the Cocoon core. The core uses this object to
+ * access information from the real environment and to pass several objects
+ * back.
+ * A BootstrapEnvironment can be used to create a new Cocoon system using
+ * the {@link CoreUtil}.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public interface BootstrapEnvironment {
+
+    /**
+     * Convenience class to define some constants for log levels.
+     * @see BootstrapEnvironment#getBootstrapLogger(LogLevel)
+     */
+    public static final class LogLevel {
+
+        public static final LogLevel DEBUG = new LogLevel( "DEBUG", 0 );
+        public static final LogLevel INFO = new LogLevel( "INFO", 1 );
+        public static final LogLevel WARN = new LogLevel( "WARN", 2 );
+        public static final LogLevel ERROR = new LogLevel( "ERROR", 3 );
+        public static final LogLevel FATAL_ERROR = new LogLevel( "FATAL_ERROR", 4 );
+        public static final LogLevel DISABLED = new LogLevel( "NONE", 5 );
+
+        public static LogLevel getLogLevelForName(final String name) {
+            if( DEBUG.getName().equals( name ) ) {
+                return DEBUG;
+            } else if( INFO.getName().equals( name ) ) {
+                return INFO;
+            } else if( WARN.getName().equals( name ) ) {
+                return WARN;
+            } else if( ERROR.getName().equals( name ) ) {
+                return ERROR;
+            } else if( FATAL_ERROR.getName().equals( name ) ) {
+                return FATAL_ERROR;
+            } else if( DISABLED.getName().equals( name ) ) {
+                return DISABLED;
+            } else {
+                return DEBUG;
+            }
+        }    
+
+        private final String name;
+        private final int level;
+
+        public LogLevel(String name, int level) {
+            this.name = name;
+            this.level = level;
+        }
+
+        public int getLevel() {
+            return this.level;
+        }
+
+        public String getName() {
+            return this.name;
+        }
+    }
+
+    /**
+     * Get the bootstrap logger.
+     * @param logLevel The log level to use according to the {@link Logger} interface.
+     */
+    Logger getBootstrapLogger(LogLevel logLevel);
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     */
+    void log(String message);
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     * @param error   An error.
+     */
+    void log(String message, Throwable error);
+
+    /**
+     * Pass the root logger back to the environment. As soon as the
+     * logging system is set up, this method is called.
+     * @param rootLogger The root logger.
+     */
+    void setLogger(Logger rootLogger);
+
+    /**
+     * This callback can be used by the environment to add environment specific
+     * settings. For example the servlet environment parsed the web.xml and adjusts
+     * the settings based on the parameters.
+     * @param settings The settings for Cocoon.
+     */
+    void configure(MutableSettings settings);
+
+    /**
+     * This callback can be used by the environment to add environment specific
+     * information for the logging system.
+     * @param context The context passed to the logging system.
+     */
+    void configureLoggingContext(DefaultContext context);
+
+    /**
+     * This callback can be used by the environment to add environment specific
+     * information.
+     * @param context The context passed to all Avalon based components that are context aware.
+     */
+    void configure(DefaultContext context);
+
+    /**
+     * Create the context object of the environment.
+     * @return The context object.
+     */
+    org.apache.cocoon.environment.Context getEnvironmentContext();
+
+    /**
+     * Returns the URL to the application context.
+     */
+    String getContextURL();
+
+    /**
+     * Returns a file to the application context.
+     * @return A file pointing to the context or null if the context is not
+     *         writeable.
+     */
+    File getContextForWriting();
+
+    /**
+     * Set the ConfigFile for the Cocoon object.
+     *
+     * @param configFileName The file location for the cocoon.xconf
+     *
+     * @throws Exception
+     */
+    URL getConfigFile(String configFileName)
+    throws Exception;
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Core.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Core.java
new file mode 100644
index 0000000..0e172ac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Core.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.core.container.ComponentLocatorWrapper;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.ComponentLocator;
+import org.apache.cocoon.sitemap.Sitemap;
+import org.apache.commons.lang.NotImplementedException;
+
+/**
+ * This is the core Cocoon component.
+ * It can be looked up to get access to various information about the
+ * current installation.
+ *
+ * The core of Cocoon is a singleton object that is created on startup.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class Core {
+
+    /** The key to lookup the component. */
+    public static String ROLE = Core.class.getName();
+
+    /**
+     * The cleanup threads that are invoked after the processing of a
+     * request is finished.
+     */
+    private static final ThreadLocal cleanup = new ThreadLocal();
+
+    /** The component context. */
+    private final Context context;
+
+    private final Settings settings;
+
+    /**
+     * Constructor
+     * The core object is created by the {@link CoreUtil} class. Never construct
+     * a core object yourself (apart from testing of course)!
+     * @param s The settings
+     * @param c The context
+     */
+    public Core(Settings s, Context c) {
+        this.settings = s;
+        this.context = c;
+    }
+
+    /**
+     * Add a cleanup task.
+     * A cleanup task is run after a request is processed.
+     * @param task The task to run.
+     */
+    public static void addCleanupTask(CleanupTask task) {
+        List l = (List)cleanup.get();
+        if ( l == null ) {
+            l = new ArrayList();
+            cleanup.set(l);
+        }
+        l.add(task);
+    }
+
+    /**
+     * Invoke all registered cleanup tasks for the current process.
+     * This method should not be called directly!
+     */
+    public static void cleanup() {
+        List l = (List)cleanup.get();
+        if ( l != null ) {
+            final Iterator i = l.iterator();
+            while ( i.hasNext() ) {
+                final CleanupTask t = (CleanupTask)i.next();
+                t.invoke();
+            }
+            l.clear();
+            cleanup.set(null);
+        }
+    }
+
+    /**
+     * The interface for the cleanup task.
+     * A cleanup task can be run after a request has been processed.
+     */
+    public static interface CleanupTask {
+
+        /**
+         * Start the cleanup.
+         * This method should never raise any exception!
+         */
+        void invoke();
+    }
+
+    /**
+     * Return the settings.
+     */
+    public Settings getSettings() {
+        return this.settings;
+    }
+
+    /**
+     * Update the dynamic settings at runtime.
+     * @param dynSettings
+     */
+    public void update(DynamicSettings dynSettings) {
+        throw new NotImplementedException("The update method is not implemented yet.");
+    }
+
+    /**
+     * Return the environment context object.
+     * @return The environment context.
+     */
+    public org.apache.cocoon.environment.Context getEnvironmentContext() {
+        try {
+            return (org.apache.cocoon.environment.Context)this.context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
+        } catch (ContextException ce) {
+            throw new CoreResourceNotFoundException("Unable to get the environment object from the context.", ce);
+        }
+    }
+
+    /**
+     * Return the Avalon context.
+     * @return The Avalon context.
+     */
+    public Context getContext() {
+        return this.context;
+    }
+
+    /**
+     * Return the current object model
+     * @return The object model.
+     */
+    public Map getCurrentObjectModel() {
+        return ContextHelper.getObjectModel(this.context);
+    }
+
+    /**
+     * Return the work directory.
+     */
+    public File getWorkDirectory() {
+        try {
+            return (File)this.context.get(Constants.CONTEXT_WORK_DIR);
+        } catch (ContextException ce) {
+            throw new CoreResourceNotFoundException("Unable to get the working directory from the context.", ce);
+        }        
+    }
+
+    /**
+     * Return the upload directory.
+     */
+    public File getUploadDirectory() {
+        try {
+            return (File)this.context.get(Constants.CONTEXT_UPLOAD_DIR);
+        } catch (ContextException ce) {
+            throw new CoreResourceNotFoundException("Unable to get the upload directory from the context.", ce);
+        }        
+    }
+
+    /**
+     * Return the cache directory.
+     */
+    public File getCacheDirectory() {
+        try {
+            return (File)this.context.get(Constants.CONTEXT_CACHE_DIR);
+        } catch (ContextException ce) {
+            throw new CoreResourceNotFoundException("Unable to get the cache directory from the context.", ce);
+        }        
+    }
+
+    /**
+     * Return the current sitemap.
+     * @return The current sitemap or null if no request is currently processed
+     */
+    public Sitemap getCurrentSitemap() {
+        Processor p = EnvironmentHelper.getCurrentProcessor();
+        if ( p != null ) {
+            return SITEMAP;            
+        }
+        return null;
+    }
+
+    private final static Sitemap SITEMAP = new SitemapImpl();
+
+    public final static class SitemapImpl implements Sitemap {
+
+        /**
+         * @see org.apache.cocoon.sitemap.Sitemap#getComponentLocator()
+         */
+        public ComponentLocator getComponentLocator() {
+            final ServiceManager m = EnvironmentHelper.getSitemapServiceManager();
+            ComponentLocator l = null;
+            if ( m != null ) {
+                if ( !(m instanceof ComponentLocator) ) {
+                    l = new ComponentLocatorWrapper(m);
+                } else {
+                    l = (ComponentLocator)m;
+                }
+            }
+            return l;
+        }
+
+        /**
+         * @see org.apache.cocoon.sitemap.Sitemap#getProcessor()
+         */
+        public Processor getProcessor() {
+            return EnvironmentHelper.getCurrentProcessor();
+        }
+
+        /**
+         * @see org.apache.cocoon.sitemap.Sitemap#getInterpreter(java.lang.String)
+         */
+        public Interpreter getInterpreter(String language) {
+            // TODO We ignore the language for now
+            return (Interpreter)this.getProcessor().getAttribute(Interpreter.ROLE);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreException.java
new file mode 100644
index 0000000..7d01c09
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public class CoreException extends CascadingRuntimeException {
+
+    public CoreException(String message) {
+        super(message, null);
+    }
+
+    public CoreException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreFatalException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreFatalException.java
new file mode 100644
index 0000000..d831369
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreFatalException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public final class CoreFatalException extends CoreException {
+
+    public CoreFatalException(String message) {
+        super(message, null);
+    }
+
+    public CoreFatalException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreInitializationException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreInitializationException.java
new file mode 100644
index 0000000..38eb618
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreInitializationException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public final class CoreInitializationException extends CoreException {
+
+    public CoreInitializationException(String message) {
+        super(message, null);
+    }
+
+    public CoreInitializationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreResourceNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreResourceNotFoundException.java
new file mode 100644
index 0000000..94ed189
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreResourceNotFoundException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public final class CoreResourceNotFoundException extends CoreException {
+
+    public CoreResourceNotFoundException(String message) {
+        super(message, null);
+    }
+
+    public CoreResourceNotFoundException(String message, Throwable cause){
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreUtil.java
new file mode 100644
index 0000000..df4e1f0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/CoreUtil.java
@@ -0,0 +1,1052 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.avalon.excalibur.logger.Log4JConfLoggerManager;
+import org.apache.avalon.excalibur.logger.LoggerManageable;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Modifiable;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.container.ComponentContext;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.container.SingleComponentServiceManager;
+import org.apache.cocoon.core.logging.CocoonLogKitLoggerManager;
+import org.apache.cocoon.core.logging.PerRequestLoggerManager;
+import org.apache.cocoon.core.logging.SettingsContext;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.StringUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * This is an utility class to create a new Cocoon instance.
+ * 
+ * TODO - Remove dependencies to LogKit and Log4J
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class CoreUtil {
+
+    /** Parameter map for the context protocol */
+    protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /** The callback to the real environment. */
+    protected final BootstrapEnvironment env;
+
+    /** "legacy" support: create an avalon context. */
+    protected final DefaultContext appContext = new ComponentContext();
+
+    /** The settings. */
+    protected MutableSettings settings;
+
+    /** The parent service manager. */
+    protected ServiceManager parentManager;
+
+    /** The root logger. */
+    protected Logger log;
+
+    /** The logger manager. */
+    protected LoggerManager loggerManager;
+
+    /** The Root processor instance */
+    protected Processor processor;
+
+    /** Is this a per request logger manager */
+    protected boolean isPerRequestLoggerManager = false;
+    
+    protected ClassLoader classloader;
+
+    /**
+     * Setup a new instance.
+     * @param environment The hook back to the environment.
+     * @throws Exception
+     */
+    public CoreUtil(BootstrapEnvironment environment)
+    throws Exception {
+        this.env = environment;
+        this.init();
+        this.createClassloader();        
+    }
+
+    protected void init()
+    throws Exception {
+        // first let's set up the appContext with some values to make
+        // the simple source resolver work
+
+        // add root url
+        try {
+            appContext.put(ContextHelper.CONTEXT_ROOT_URL,
+                           new URL(this.env.getContextURL()));
+        } catch (MalformedURLException ignore) {
+            // we simply ignore this
+        }
+
+        // add environment context
+        this.appContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT,
+                            this.env.getEnvironmentContext());
+
+        // now add environment specific information
+        this.env.configure(appContext);
+
+        // create settings
+        this.settings = this.createSettings();
+
+        // first init the work-directory for the logger.
+        // this is required if we are running inside a war file!
+        final String workDirParam = this.settings.getWorkDirectory();
+        File workDir;
+        if (workDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                // No context path : consider work-directory as absolute
+                workDir = new File(workDirParam);
+            } else {
+                // Context path exists : is work-directory absolute ?
+                File workDirParamFile = new File(workDirParam);
+                if (workDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    workDir = workDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    workDir = new File(this.env.getContextForWriting(), workDirParam);
+                }
+            }
+        } else {
+            workDir = new File("cocoon-files");
+        }
+        workDir.mkdirs();
+        this.appContext.put(Constants.CONTEXT_WORK_DIR, workDir);
+        this.settings.setWorkDirectory(workDir.getAbsolutePath());
+
+        // Init logger
+        this.initLogger();
+        this.env.setLogger(this.log);
+
+        // Output some debug info
+        if (this.log.isDebugEnabled()) {
+            this.log.debug("Context URL: " + this.env.getContextURL());
+            this.log.debug("Writeable Context: " + this.env.getContextForWriting());
+            if (workDirParam != null) {
+                this.log.debug("Using work-directory " + workDir);
+            } else {
+                this.log.debug("Using default work-directory " + workDir);
+            }
+        }
+
+        final String uploadDirParam = this.settings.getUploadDirectory();
+        File uploadDir;
+        if (uploadDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                uploadDir = new File(uploadDirParam);
+            } else {
+                // Context path exists : is upload-directory absolute ?
+                File uploadDirParamFile = new File(uploadDirParam);
+                if (uploadDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    uploadDir = uploadDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    uploadDir = new File(this.env.getContextForWriting(), uploadDirParam);
+                }
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using upload-directory " + uploadDir);
+            }
+        } else {
+            uploadDir = new File(workDir, "upload-dir" + File.separator);
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using default upload-directory " + uploadDir);
+            }
+        }
+        uploadDir.mkdirs();
+        appContext.put(Constants.CONTEXT_UPLOAD_DIR, uploadDir);
+        this.settings.setUploadDirectory(uploadDir.getAbsolutePath());
+
+        String cacheDirParam = this.settings.getCacheDirectory();
+        File cacheDir;
+        if (cacheDirParam != null) {
+            if (this.env.getContextForWriting() == null) {
+                cacheDir = new File(cacheDirParam);
+            } else {
+                // Context path exists : is cache-directory absolute ?
+                File cacheDirParamFile = new File(cacheDirParam);
+                if (cacheDirParamFile.isAbsolute()) {
+                    // Yes : keep it as is
+                    cacheDir = cacheDirParamFile;
+                } else {
+                    // No : consider it relative to context path
+                    cacheDir = new File(this.env.getContextForWriting(), cacheDirParam);
+                }
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Using cache-directory " + cacheDir);
+            }
+        } else {
+            cacheDir = new File(workDir, "cache-dir" + File.separator);
+            File parent = cacheDir.getParentFile();
+            if (parent != null) {
+                parent.mkdirs();
+            }
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("cache-directory was not set - defaulting to " + cacheDir);
+            }
+        }
+        cacheDir.mkdirs();
+        appContext.put(Constants.CONTEXT_CACHE_DIR, cacheDir);
+        this.settings.setCacheDirectory(cacheDir.getAbsolutePath());
+
+        // update configuration
+        final URL u = this.env.getConfigFile(this.settings.getConfiguration());
+        this.settings.setConfiguration(u.toExternalForm());
+        this.appContext.put(Constants.CONTEXT_CONFIG_URL, u);
+
+        // set encoding
+        this.appContext.put(Constants.CONTEXT_DEFAULT_ENCODING, settings.getFormEncoding());
+
+        // set class loader
+        this.appContext.put(Constants.CONTEXT_CLASS_LOADER, this.classloader);
+
+        // create the Core object
+        final Core core = this.createCore();
+
+        // create parent service manager
+        this.parentManager = this.getParentServiceManager(core);
+
+        // settings can't be changed anymore
+        settings.makeReadOnly();
+
+        // put the core into the context - this is for internal use only
+        // The Cocoon container fetches the Core object using the context.
+        this.appContext.put(Core.ROLE, core);
+    }
+
+    public Core getCore() {
+        try {
+            return (Core)this.parentManager.lookup(Core.ROLE);
+        } catch (ServiceException neverIgnore) {
+            // this should never happen!
+            throw new CoreFatalException("Fatal exception: no Cocoon core available.", neverIgnore);
+        }
+    }
+
+    /**
+     * Create a new core instance.
+     * This method can be overwritten in sub classes.
+     * @return A new core object.
+     */
+    protected Core createCore() {
+        final Core c = new Core(this.settings, this.appContext);
+        return c;
+    }
+
+    /**
+     * Return the settings object.
+     */
+    public Settings getSettings() {
+        return this.settings;
+    }
+
+    /**
+     * Instatiates the parent service manager, as specified in the
+     * parent-service-manager init parameter.
+     *
+     * If none is specified, the method returns <code>null</code>.
+     *
+     * @return the parent service manager, or <code>null</code>.
+     */
+    protected ServiceManager getParentServiceManager(Core core) {
+        String parentServiceManagerClass = this.settings.getParentServiceManagerClassName();
+        String parentServiceManagerInitParam = null;
+        if (parentServiceManagerClass != null) {
+            int dividerPos = parentServiceManagerClass.indexOf('/');
+            if (dividerPos != -1) {
+                parentServiceManagerInitParam = parentServiceManagerInitParam.substring(dividerPos + 1);
+                parentServiceManagerClass = parentServiceManagerClass.substring(0, dividerPos);
+            }
+        }
+
+        ServiceManager parentServiceManager = null;
+        if (parentServiceManagerClass != null) {
+            try {
+                Class pcm = ClassUtils.loadClass(parentServiceManagerClass);
+                Constructor pcmc = pcm.getConstructor(new Class[]{String.class});
+                parentServiceManager = (ServiceManager) pcmc.newInstance(new Object[]{parentServiceManagerInitParam});
+
+                ContainerUtil.enableLogging(parentServiceManager, this.log);
+                ContainerUtil.contextualize(parentServiceManager, this.appContext);
+                ContainerUtil.initialize(parentServiceManager);
+            } catch (Exception e) {
+                if (this.log.isErrorEnabled()) {
+                    this.log.error("Could not initialize parent component manager.", e);
+                }
+            }
+        }
+        return new SingleComponentServiceManager(parentServiceManager, core, Core.ROLE);
+    }
+
+    /**
+     * Get the settings for Cocoon.
+     * This method reads several property files and merges the result. If there
+     * is more than one definition for a property, the last one wins.
+     * The property files are read in the following order:
+     * 1) context://WEB-INF/properties/*.properties
+     *    Default values for the core and each block - the order in which the files are read is not guaranteed.
+     * 2) context://WEB-INF/properties/[RUNNING_MODE]/*.properties
+     *    Default values for the running mode - the order in which the files are read is not guaranteed.
+     * 3) Property providers (ToBeDocumented)
+     * 4) The environment (CLI, Servlet etc.) adds own properties (e.g. from web.xml)
+     * 5) Additional property file specified by the "org.apache.cocoon.settings" system property or
+     *    if the property is not found, the file ".cocoon/settings.properties" is tried to be read from
+     *    the user directory.
+     * 6) System properties
+     *
+     * @return A new Settings object
+     */
+    protected MutableSettings createSettings() {
+        // get the running mode
+        final String mode = System.getProperty(Settings.PROPERTY_RUNNING_MODE, Settings.DEFAULT_RUNNING_MODE);
+        this.env.log("Running in mode: " + mode);
+
+        // create an empty settings objects
+        final MutableSettings s = new MutableSettings();
+
+        // we need our own resolver
+        final SourceResolver resolver = this.createSourceResolver(new LoggerWrapper(this.env));
+
+        // now read all properties from the properties directory
+        this.readProperties("context://WEB-INF/properties", s, resolver);
+        // read all properties from the mode dependent directory
+        this.readProperties("context://WEB-INF/properties/" + mode, s, resolver);
+
+        // Next look for custom property providers
+        Iterator i = s.getPropertyProviders().iterator();
+        while ( i.hasNext() ) {
+            final String className = (String)i.next();
+            try {
+                PropertyProvider provider = (PropertyProvider)ClassUtils.newInstance(className);
+                s.fill(provider.getProperties());
+            } catch (Exception ignore) {
+                env.log("Unable to get property provider for class " + className, ignore);
+                env.log("Continuing initialization.");            
+            }
+        }
+        // fill from the environment configuration, like web.xml etc.
+        env.configure(s);
+
+        // read additional properties file
+        String additionalPropertyFile = s.getProperty(Settings.PROPERTY_USER_SETTINGS, 
+                                                      System.getProperty(Settings.PROPERTY_USER_SETTINGS));
+        // if there is no property defining the addition file, we try it in the home directory
+        if ( additionalPropertyFile == null ) {
+            additionalPropertyFile = System.getProperty("user.home") + File.separator + ".cocoon/settings.properties";
+            final File testFile = new File(additionalPropertyFile);
+            if ( !testFile.exists() ) {
+                additionalPropertyFile = null;
+            }
+        }
+        if ( additionalPropertyFile != null ) {
+            env.log("Reading user settings from '" + additionalPropertyFile + "'");
+            final Properties p = new Properties();
+            try {
+                FileInputStream fis = new FileInputStream(additionalPropertyFile);
+                p.load(fis);
+                fis.close();
+            } catch (IOException ignore) {
+                env.log("Unable to read '" + additionalPropertyFile + "'.", ignore);
+                env.log("Continuing initialization.");
+            }
+        }
+        // now overwrite with system properties
+        s.fill(System.getProperties());
+
+        return s;
+    }
+
+    /**
+     * Read all property files from the given directory and apply them to the settings.
+     */
+    protected void readProperties(String directoryName,
+                                  MutableSettings s,
+                                  SourceResolver resolver) {
+        Source directory = null;
+        try {
+            directory = resolver.resolveURI(directoryName, null, CONTEXT_PARAMETERS);
+            if (directory.exists() && directory instanceof TraversableSource) {
+                final Iterator c = ((TraversableSource) directory).getChildren().iterator();
+                while (c.hasNext()) {
+                    final Source src = (Source) c.next();
+                    if ( src.getURI().endsWith(".properties") ) {
+                        final InputStream propsIS = src.getInputStream();
+                        env.log("Reading settings from '" + src.getURI() + "'.");
+                        final Properties p = new Properties();
+                        p.load(propsIS);
+                        propsIS.close();
+                        s.fill(p);
+                    }
+                }
+            }
+        } catch (IOException ignore) {
+            env.log("Unable to read from directory 'WEB-INF/properties'.", ignore);
+            env.log("Continuing initialization.");            
+        } finally {
+            resolver.release(directory);
+        }
+    }
+
+    /**
+     * Initialize the current request.
+     * This method can be used to initialize anything required for processing
+     * the request. For example, if the logger manager is a {@link PerRequestLoggerManager}
+     * than this manager is invoked to initialize the logging context for the request.
+     * This method returns a handle that should be used to clean up everything
+     * when the request is finished by calling {@link #cleanUpRequest(Object)}.
+     */
+    public Object initializeRequest(Environment env) {
+        if ( this.isPerRequestLoggerManager ) {
+            return ((PerRequestLoggerManager)this.loggerManager).initializePerRequestLoggingContext(env);
+        }
+        return null;   
+    }
+
+    /**
+     * Cleanup everything initialized during the request processing in
+     * {@link #initializeRequest(Environment)}.
+     */
+    public void cleanUpRequest(Object handle) {
+        if ( handle != null && this.isPerRequestLoggerManager) {
+            ((PerRequestLoggerManager)this.loggerManager).cleanPerRequestLoggingContext(handle);
+        }
+    }
+
+    /**
+     * Create a simple source resolver.
+     */
+    protected SourceResolver createSourceResolver(Logger logger) {
+        // Create our own resolver
+        final SimpleSourceResolver resolver = new SimpleSourceResolver();
+        resolver.enableLogging(logger);
+        try {
+            resolver.contextualize(this.appContext);
+        } catch (ContextException ce) {
+            throw new CoreInitializationException(
+                    "Cannot setup source resolver.", ce);
+        }
+        return resolver;        
+    }
+
+    protected void initLogger() {
+        String logLevel = settings.getBootstrapLogLevel();
+        if (logLevel == null) {
+            logLevel = "INFO";
+        }
+
+        String accesslogger = settings.getEnvironmentLogger();
+        if (accesslogger == null) {
+            accesslogger = "cocoon";
+        }
+
+        // create bootstrap logger
+        final BootstrapEnvironment.LogLevel level = BootstrapEnvironment.LogLevel.getLogLevelForName(logLevel);
+        final Logger bootstrapLogger = this.env.getBootstrapLogger(level);
+
+        // Create our own resolver
+        final SourceResolver resolver = this.createSourceResolver(bootstrapLogger);
+
+        // create an own service manager for the logger manager
+        final ServiceManager loggerManagerServiceManager = new SingleComponentServiceManager(
+                 null, resolver, SourceResolver.ROLE);
+
+        // create an own context for the logger manager
+        final DefaultContext subcontext = new SettingsContext(this.appContext, this.settings);
+        subcontext.put("context-work", new File(this.settings.getWorkDirectory()));
+        if (this.env.getContextForWriting() == null) {
+            File logSCDir = new File(this.settings.getWorkDirectory(), "log");
+            logSCDir.mkdirs();
+            subcontext.put("context-root", logSCDir.toString());
+        } else {
+            subcontext.put("context-root", this.env.getContextForWriting().toString());
+        }
+        this.env.configureLoggingContext(subcontext);
+
+        String loggerManagerClass = settings.getLoggerManagerClassName();
+
+        // the log4j support requires currently that the log4j system is already
+        // configured elsewhere
+
+        final LoggerManager loggerManager = this.newLoggerManager(loggerManagerClass);
+        ContainerUtil.enableLogging(loggerManager, bootstrapLogger);
+
+        try {
+            ContainerUtil.contextualize(loggerManager, subcontext);
+            ContainerUtil.service(loggerManager, loggerManagerServiceManager);
+
+            this.loggerManager = loggerManager;
+
+            if (loggerManager instanceof Configurable) {
+                //Configure the logkit management
+                String logkitConfig = settings.getLoggingConfiguration();
+
+                if ( logkitConfig != null ) {
+                    Source source = null;
+                    try {
+                        source = resolver.resolveURI(logkitConfig);
+                        final ConfigurationBuilder builder = new ConfigurationBuilder(
+                                settings);
+                        final Configuration conf = builder.build(source.getInputStream());
+                        final DefaultConfiguration categories = (DefaultConfiguration) conf
+                                .getChild("categories");
+                        final DefaultConfiguration targets = (DefaultConfiguration) conf
+                                .getChild("targets");
+                        final DefaultConfiguration factories = (DefaultConfiguration) conf
+                                .getChild("factories");
+    
+                        // now process includes
+                        final Configuration[] children = conf
+                                .getChildren("include");
+                        for (int i = 0; i < children.length; i++) {
+                            String directoryURI = children[i].getAttribute("dir");
+                            final String pattern = children[i].getAttribute(
+                                    "pattern", null);
+                            int[] parsedPattern = null;
+                            if (pattern != null) {
+                                parsedPattern = WildcardHelper
+                                        .compilePattern(pattern);
+                            }
+                            Source directory = null;
+                            try {
+                                directory = resolver.resolveURI(directoryURI,
+                                        source.getURI(), CONTEXT_PARAMETERS);
+                                if (directory instanceof TraversableSource) {
+                                    final Iterator c = ((TraversableSource) directory)
+                                            .getChildren().iterator();
+                                    while (c.hasNext()) {
+                                        final Source s = (Source) c.next();
+                                        if (parsedPattern == null
+                                                || this.match(s.getURI(),
+                                                        parsedPattern)) {
+                                            final Configuration includeConf = builder
+                                                    .build(s.getInputStream());
+                                            // add targets and categories
+                                            categories.addAllChildren(includeConf
+                                                    .getChild("categories"));
+                                            targets.addAllChildren(includeConf
+                                                    .getChild("targets"));
+                                            factories.addAllChildren(includeConf
+                                                    .getChild("factories"));
+                                        }
+                                    }
+                                } else {
+                                    throw new ConfigurationException(
+                                            "Include.dir must point to a directory, '"
+                                                    + directory.getURI()
+                                                    + "' is not a directory.'");
+                                }
+                            } catch (IOException ioe) {
+                                throw new ConfigurationException(
+                                        "Unable to read configurations from "
+                                                + directoryURI);
+                            } finally {
+                                resolver.release(directory);
+                            }
+    
+                            // finally remove include
+                            ((DefaultConfiguration) conf).removeChild(children[i]);
+                        }
+                        // override log level?
+                        if (settings.getOverrideLogLevel() != null) {
+                            this.overrideLogLevel(conf.getChild("categories"),
+                                    settings.getOverrideLogLevel());
+                        }
+                        ContainerUtil.configure(loggerManager, conf);
+                    } finally {
+                        resolver.release(source);
+                    }
+                }
+            }
+            ContainerUtil.initialize(loggerManager);
+        } catch (Exception e) {
+            bootstrapLogger.error(
+                    "Could not set up Cocoon Logger, will use screen instead",
+                    e);
+        }
+
+        this.log = this.loggerManager.getLoggerForCategory(accesslogger);
+    }
+
+    /**
+     * Create a new logger manager.
+     * @param loggerManagerClass The class name or one of the allowed shortcuts.
+     * @return A new logger manager.
+     */
+    private LoggerManager newLoggerManager(String loggerManagerClass) {
+        if ("LogKit".equalsIgnoreCase(loggerManagerClass) || loggerManagerClass == null) {
+            loggerManagerClass = CocoonLogKitLoggerManager.class.getName();
+        } else if ("LOG4J".equalsIgnoreCase(loggerManagerClass)) {
+            loggerManagerClass = Log4JConfLoggerManager.class.getName();
+        }
+        try {
+            Class clazz = Class.forName(loggerManagerClass);
+            if ( PerRequestLoggerManager.class.isAssignableFrom(clazz) ) {
+                this.isPerRequestLoggerManager = true;
+            }
+            return (LoggerManager) clazz.newInstance();
+        } catch (Exception e) {
+            this.isPerRequestLoggerManager = true;
+            return new CocoonLogKitLoggerManager();
+        }
+    }
+
+    protected void overrideLogLevel(Configuration root, String value) {
+        Configuration[] c = root.getChildren("category");
+        for(int i=0;i<c.length;i++) {
+            ((DefaultConfiguration)c[i]).setAttribute("log-level", value);
+            this.overrideLogLevel(c[i], value);
+        }
+    }
+
+    private boolean match(String uri, int[] parsedPattern ) {
+        int pos = uri.lastIndexOf('/');
+        if ( pos != -1 ) {
+            uri = uri.substring(pos+1);
+        }
+        return WildcardHelper.match(null, uri, parsedPattern);
+    }
+
+    /**
+     * Create the classloader that inlcudes all the [block]/BLOCK-INF/classes directories. 
+     * @throws Exception
+     */
+    protected void createClassloader() throws Exception {
+        // get the wiring
+        final SourceResolver resolver = this.createSourceResolver(this.log);    
+        Source wiringSource = null;
+        final Configuration wiring;
+        try {
+            wiringSource = resolver.resolveURI(Constants.WIRING);
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            wiring = builder.build( wiringSource.getInputStream() );            
+        } catch(org.apache.excalibur.source.SourceNotFoundException snfe) {
+            throw new WiringNotFoundException("wiring.xml not found in the root directory of your Cocoon application.");
+        } finally {
+            resolver.release(wiringSource);
+        }
+        
+        // get all wired blocks and add their classed directory to the classloader
+        List urlList = new ArrayList();        
+        Configuration[] blocks = wiring.getChildren("block");
+        for(int i = 0; i < blocks.length; i++) {
+            String location = blocks[i].getAttribute("location");
+            if(this.log.isDebugEnabled()) {
+                this.log.debug("Found block " + blocks[i].getAttribute("id") + " at " + location);
+            }
+            Source classesDir = null;
+            try {
+               classesDir = resolver.resolveURI(location + "/" + Constants.BLOCK_META_DIR + "/classes");
+               if(classesDir.exists()) {
+                   String classesDirURI = classesDir.getURI();
+                   urlList.add(new URL(classesDirURI));
+                   if(this.log.isDebugEnabled()) {
+                       this.log.debug("added " + classesDir.getURI());
+                   }
+               }               
+            } finally {
+                resolver.release(classesDir);
+            }
+        }
+    
+        // setup the classloader using the current classloader as parent
+        ClassLoader parentClassloader = Thread.currentThread().getContextClassLoader();
+        URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);        
+        URLClassLoader classloader = new URLClassLoader(urls, parentClassloader);
+        Thread.currentThread().setContextClassLoader(classloader);
+        this.classloader = Thread.currentThread().getContextClassLoader();
+    }
+
+    /**
+     * Creates the Cocoon object and handles exception handling.
+     */
+    public synchronized Cocoon createCocoon()
+    throws Exception {        
+        this.createProcessor();
+        return (Cocoon)this.processor;
+    }
+
+    /**
+     * Gets the current cocoon object.
+     * Reload cocoon if configuration changed or we are reloading.
+     * Ensure that the correct classloader is set.
+     */
+    public Cocoon getCocoon(final String pathInfo, final String reloadParam)
+    throws Exception {
+        this.getProcessor(pathInfo, reloadParam);
+        return (Cocoon)this.processor;
+    }
+
+    /**
+     * Creates the root processor object and handles exception handling.
+     */
+    public synchronized Processor createProcessor()
+    throws Exception {
+
+        this.updateEnvironment();
+        this.forceLoad();
+        this.forceProperty();
+
+        try {
+            if (this.log.isInfoEnabled()) {
+                this.log.info("Reloading from: " + this.settings.getConfiguration());
+            }
+            Processor p = (Processor)ClassUtils.newInstance(this.settings.getProcessorClassName());
+            ContainerUtil.enableLogging(p, getCocoonLogger());
+            if (p instanceof LoggerManageable) {
+                ((LoggerManageable)p).setLoggerManager(this.loggerManager);
+            }
+            ContainerUtil.contextualize(p, this.appContext);
+
+            // create the Core object
+            final Core core = this.createCore();
+            this.parentManager = this.getParentServiceManager(core);
+            ContainerUtil.service(p, this.parentManager);
+
+            ContainerUtil.initialize(p);
+            this.settings.setCreationTime(System.currentTimeMillis());
+            this.processor = p;
+        } catch (Exception e) {
+            this.log.error("Exception reloading root processor.", e);
+            this.disposeProcessor();
+            throw e;
+        }
+        return this.processor;
+    }
+
+    /**
+     * Gets the current root processor object.
+     * Reload the root processor if configuration changed or we are reloading.
+     * Ensure that the correct classloader is set.
+     */
+    public Processor getProcessor(final String pathInfo, final String reloadParam)
+    throws Exception {
+        
+        // set the blocks classloader for this thread
+        Thread.currentThread().setContextClassLoader(this.classloader);        
+        
+        if (this.settings.isReloadingEnabled("config")) {
+            boolean reload = false;
+
+            if (this.processor != null) {
+                if (this.processor instanceof Modifiable && ((Modifiable)this.processor).modifiedSince(this.settings.getCreationTime())) {
+                    if (this.log.isInfoEnabled()) {
+                        this.log.info("Configuration changed reload attempt");
+                    }
+                    reload = true;
+                } else if (pathInfo == null && reloadParam != null) {
+                    if (this.log.isInfoEnabled()) {
+                        this.log.info("Forced reload attempt");
+                    }
+                    reload = true;
+                }
+            } else if (pathInfo == null && reloadParam != null) {
+                if (this.log.isInfoEnabled()) {
+                    this.log.info("Invalid configurations reload");
+                }
+                reload = true;
+            }
+
+            if (reload) {
+                this.init();
+                this.createProcessor();
+            }
+        }
+        return this.processor;
+    }
+
+    /**
+     * Destroy root processor
+     */
+    protected final void disposeProcessor() {
+        if (this.processor != null) {
+            if (this.log.isDebugEnabled()) {
+                this.log.debug("Disposing root processor");
+            }
+            ContainerUtil.dispose(this.processor);
+            this.processor = null;
+        }
+        ContainerUtil.dispose(this.parentManager);
+        this.parentManager = null;
+    }
+
+    protected Logger getCocoonLogger() {
+        final String rootlogger = this.settings.getCocoonLogger();
+        if (rootlogger != null) {
+            return this.loggerManager.getLoggerForCategory(rootlogger);
+        }
+        return this.log;
+    }
+
+    /**
+     * Handle the <code>load-class</code> parameter. This overcomes
+     * limits in many classpath issues. One of the more notorious
+     * ones is a bug in WebSphere that does not load the URL handler
+     * for the <code>classloader://</code> protocol. In order to
+     * overcome that bug, set <code>load-class</code> parameter to
+     * the <code>com.ibm.servlet.classloader.Handler</code> value.
+     *
+     * <p>If you need to load more than one class, then separate each
+     * entry with whitespace, a comma, or a semi-colon. Cocoon will
+     * strip any whitespace from the entry.</p>
+     */
+    protected void forceLoad() {
+        final Iterator i = this.settings.getLoadClasses().iterator();
+        while (i.hasNext()) {
+            final String fqcn = (String)i.next();
+            try {
+                if (this.log.isDebugEnabled()) {
+                    this.log.debug("Loading: " + fqcn);
+                }
+                ClassUtils.loadClass(fqcn).newInstance();
+            } catch (Exception e) {
+                if (this.log.isWarnEnabled()) {
+                    this.log.warn("Could not load class: " + fqcn, e);
+                }
+                // Do not throw an exception, because it is not a fatal error.
+            }
+        }
+    }
+
+    /**
+     * Handle the "force-property" parameter.
+     *
+     * If you need to force more than one property to load, then
+     * separate each entry with whitespace, a comma, or a semi-colon.
+     * Cocoon will strip any whitespace from the entry.
+     */
+    protected void forceProperty() {
+        if (this.settings.getForceProperties().size() > 0) {
+            final Iterator i = this.settings.getForceProperties().entrySet().iterator();
+            while (i.hasNext()) {
+                final Map.Entry current = (Map.Entry)i.next();
+                try {
+                    if (this.log.isDebugEnabled()) {
+                        this.log.debug("Setting: " + current.getKey() + "=" + current.getValue());
+                    }
+                    System.setProperty(current.getKey().toString(), current.getValue().toString());
+                } catch (Exception e) {
+                    if (this.log.isWarnEnabled()) {
+                        this.log.warn("Could not set property: " + current.getKey(), e);
+                    }
+                    // Do not throw an exception, because it is not a fatal error.
+                }
+            }
+        }
+    }
+
+    /**
+     * Method to update the environment before Cocoon instances are created.
+     *
+     * This is also useful if you wish to customize any of the 'protected'
+     * variables from this class before a Cocoon instance is built in a derivative
+     * of this class (eg. Cocoon Context).
+     */
+    protected void updateEnvironment() throws Exception {
+//        // concatenate the class path and the extra class path
+//        String classPath = this.env.getClassPath(this.settings);
+//        StringBuffer buffer = new StringBuffer();
+//        if ( classPath != null && classPath.length() > 0 ) {
+//            buffer.append(classPath);
+//        }
+//        classPath = this.getExtraClassPath();
+//        if ( classPath != null && classPath.length() > 0 ) {
+//            if ( buffer.length() > 0 ) {
+//                buffer.append(File.pathSeparatorChar);
+//            }
+//            buffer.append(classPath);
+//        }
+        // FIXME - for now we just set an empty string as this information is looked up
+        //         by other components
+        this.appContext.put(Constants.CONTEXT_CLASSPATH, "");
+    }
+
+    /**
+     * Dispose the root processor when environment is destroyed
+     */
+    public void destroy() {
+        this.disposeProcessor();
+    }
+
+    /**
+     * Retreives the "extra-classpath" attribute, that needs to be
+     * added to the class path.
+     */
+    protected String getExtraClassPath() {
+        if (this.settings.getExtraClasspaths().size() > 0) {
+            StringBuffer sb = new StringBuffer();
+            final Iterator iter = this.settings.getExtraClasspaths().iterator();
+            int i = 0;
+            while (iter.hasNext()) {
+                String s = (String)iter.next();
+                if (i++ > 0) {
+                    sb.append(File.pathSeparatorChar);
+                }
+                if ((s.charAt(0) == File.separatorChar) ||
+                        (s.charAt(1) == ':')) {
+                    if (this.log.isDebugEnabled()) {
+                        this.log.debug("extraClassPath is absolute: " + s);
+                    }
+                    sb.append(s);
+
+                } else {
+                    if (s.indexOf("${") != -1) {
+                        String path = StringUtils.replaceToken(s);
+                        sb.append(path);
+                        if (this.log.isDebugEnabled()) {
+                            this.log.debug("extraClassPath is not absolute replacing using token: [" + s + "] : " + path);
+                        }
+                    } else {
+                        String path = null;
+                        if (this.env.getContextForWriting() != null) {
+                            path = this.env.getContextForWriting() + s;
+                            if (this.log.isDebugEnabled()) {
+                                this.log.debug("extraClassPath is not absolute pre-pending context path: " + path);
+                            }
+                        } else {
+                            path = this.settings.getWorkDirectory() + s;
+                            if (this.log.isDebugEnabled()) {
+                                this.log.debug("extraClassPath is not absolute pre-pending work-directory: " + path);
+                            }
+                        }
+                        sb.append(path);
+                    }
+                }
+            }
+            return sb.toString();
+        }
+        return "";
+    }
+
+    protected static final class LoggerWrapper implements Logger {
+        private final BootstrapEnvironment env;
+
+        public LoggerWrapper(BootstrapEnvironment env) {
+            this.env = env;
+        }
+
+        protected void text(String arg0, Throwable arg1) {
+            if ( arg1 != null ) {
+                this.env.log(arg0, arg1);
+            } else {
+                this.env.log(arg0);
+            }
+        }
+
+        public void debug(String arg0, Throwable arg1) {
+            // we ignore debug
+        }
+
+        public void debug(String arg0) {
+            // we ignore debug
+        }
+
+        public void error(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void error(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public void fatalError(String arg0, Throwable arg1) {
+            this.text(arg0, arg1);
+        }
+
+        public void fatalError(String arg0) {
+            this.text(arg0, null);
+        }
+
+        public Logger getChildLogger(String arg0) {
+            return this;
+        }
+
+        public void info(String arg0, Throwable arg1) {
+            // we ignore info
+        }
+
+        public void info(String arg0) {
+            // we ignore info
+        }
+
+        public boolean isDebugEnabled() {
+            return false;
+        }
+
+        public boolean isErrorEnabled() {
+            return true;
+        }
+
+        public boolean isFatalErrorEnabled() {
+            return true;
+        }
+
+        public boolean isInfoEnabled() {
+            return false;
+        }
+
+        public boolean isWarnEnabled() {
+            return false;
+        }
+
+        public void warn(String arg0, Throwable arg1) {
+            // we ignore warn
+        }
+
+        public void warn(String arg0) {
+            // we ignore warn
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/DynamicSettings.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/DynamicSettings.java
new file mode 100644
index 0000000..2b1c20d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/DynamicSettings.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.core;
+
+/**
+ * The settings (configuration) for the Cocoon core are described through the {@link BaseSettings}
+ * interface and the {@link DynamicSettings} interface.
+ * Whereas the settings of the {@link BaseSettings} object can't be changed at runtime,
+ * the settings of the {@link DynamicSettings} object are mutable. Use the {@link Core} instance
+ * to update the settings.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public interface DynamicSettings {
+
+    /**
+     * Default value for {@link #isReloadingEnabled(String)} parameter (false).
+     */
+    boolean RELOADING_ENABLED_DEFAULT = false;
+
+    /**
+     * Default value for {@link #isEnableUploads()} parameter (false).
+     */
+    boolean ENABLE_UPLOADS = false;
+    boolean SAVE_UPLOADS_TO_DISK = true;
+    int MAX_UPLOAD_SIZE = 10000000; // 10Mb
+
+    boolean SHOW_TIME = false;
+    boolean HIDE_SHOW_TIME = false;
+
+    /**
+     * Default value for {@link #isShowVersion()} parameter (true).
+     */
+    boolean SHOW_COCOON_VERSION = true;
+
+    /**
+     * Allow reinstantiating (reloading) of the cocoon instance. If this is
+     * set to "yes" or "true", a new cocoon instance can be created using
+     * the request parameter "cocoon-reload". It also enables that Cocoon is
+     * reloaded when cocoon.xconf changes. Default is no for security reasons.
+     */
+    String KEY_RELOADING = "reloading";
+
+    /**
+     * Causes all files in multipart requests to be processed.
+     * Default is false for security reasons.
+     */
+    String KEY_UPLOADS_ENABLE = "uploads.enable";
+
+    /**
+     * Causes all files in multipart requests to be saved to upload-dir.
+     * Default is true for security reasons.
+     */
+    String KEY_UPLOADS_AUTOSAVE = "uploads.autosave";
+
+    /**
+     * Specify handling of name conflicts when saving uploaded files to disk.
+     * Acceptable values are deny, allow, rename (default). Files are renamed
+     * x_filename where x is an integer value incremented to make the new
+     * filename unique.
+     */
+    String KEY_UPLOADS_OVERWRITE = "uploads.overwrite";
+
+    /**
+     * Specify maximum allowed size of the upload. Defaults to 10 Mb.
+     */
+    String KEY_UPLOADS_MAXSIZE = "uploads.maxsize";
+
+    /**
+     * Allow adding processing time to the response
+     */
+    String KEY_SHOWTIME = "showtime";
+
+    /**
+     * If true, processing time will be added as an HTML comment
+     */
+    String KEY_HIDE_SHOWTIME = "hideshowtime";
+
+    /**
+     * If true, the X-Cocoon-Version response header will be included.
+     */
+    String KEY_SHOW_VERSION = "show-version";
+
+    /**
+     * Delay between reload checks for the configuration
+     */
+    String KEY_RELOAD_DELAY = "reload-delay";
+
+    /**
+     * Lazy mode for component loading
+     */
+    String KEY_LAZY_MODE = "core.LazyMode";
+
+    /**
+     * @return Returns the hideShowTime.
+     * @see #KEY_HIDE_SHOWTIME
+     */
+    boolean isHideShowTime();
+
+    /**
+     * @return Returns the showCocoonVersion.
+     * @see #KEY_SHOW_VERSION
+     */
+    boolean isShowVersion();
+
+    /**
+     * This method can be used by components to query if they are
+     * configured to check for reloading.
+     * @param type The type of the component that wants to check for reload.
+     * @return Returns if reloading is enabled for this component.
+     * @see #KEY_RELOADING
+     */
+    boolean isReloadingEnabled(String type);
+
+    /**
+     * This method can be used by components to get the configured
+     * delay period inbetween checks.
+     * @param type The type of the component that wants to check for reload.
+     * @return Returns the delay inbetween checks in milliseconds.
+     * @see #KEY_RELOAD_DELAY
+     */
+    long getReloadDelay(String type);
+
+    /**
+     * @return Returns the autosaveUploads.
+     * @see #KEY_UPLOADS_AUTOSAVE
+     */
+    boolean isAutosaveUploads();
+
+    /**
+     * @return Returns the enableUploads.
+     * @see #KEY_UPLOADS_ENABLE
+     */
+    boolean isEnableUploads();
+
+    /**
+     * @return Returns the maxUploadSize.
+     * @see #KEY_UPLOADS_MAXSIZE
+     */
+    int getMaxUploadSize();
+
+    /**
+     * @return Returns the overwriteUploads.
+     * @see #KEY_UPLOADS_OVERWRITE
+     */
+    String getOverwriteUploads();
+
+    /**
+     * @return Returns the showTime.
+     * @see #KEY_SHOWTIME
+     */
+    boolean isShowTime();
+
+    /**
+     * @return Returns the lazyMode.
+     * @see #KEY_LAZY_MODE
+     */
+    boolean isLazyMode();
+
+    boolean isAllowOverwrite();
+
+    boolean isSilentlyRename();
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/MutableSettings.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/MutableSettings.java
new file mode 100644
index 0000000..f14188a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/MutableSettings.java
@@ -0,0 +1,999 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.math.NumberUtils;
+
+/**
+ * This object holds the global configuration of Cocoon.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class MutableSettings implements Settings {
+
+    /** Are we still mutable? */
+    protected boolean readOnly = false;
+
+    /** Prefix for properties */
+    protected static final String KEYPREFIX = "org.apache.cocoon.";
+
+    /**
+     * The list of properties used to configure Cocoon
+     */
+    protected List properties = new ArrayList();
+
+    /**
+     * This parameter allows to set system properties
+     */
+    protected Map forceProperties = new HashMap();
+
+    /**
+     * This parameter indicates what class to use for the root processor.
+     */
+    protected String processorClassName = DEFAULT_PROCESSOR_CLASS;
+    
+    /**
+     * This parameter points to the main configuration file for Cocoon.
+     * Note that the path is specified in absolute notation but it will be
+     * resolved relative to the application context path.
+     */
+    protected String configuration;
+
+    /**
+     * This parameter indicates the configuration file of the LogKit management
+     */
+    protected String loggingConfiguration;
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * configuration used by the environment.
+     */
+    protected String environmentLogger;
+
+    /**
+     * This parameter indicates the category id of the logger from the LogKit
+     * management configuration for the Cocoon engine.
+     * This logger is used for all components described in the cocoon.xconf
+     * and sitemap.xmap file not having specified a logger with the
+     * logger="..." attribute in the component configuration file.
+     */
+    protected String cocoonLogger;
+
+    /**
+     * This parameter indicates the log level to use throughout startup of the
+     * system. As soon as the logkit.xconf the setting of the logkit.xconf
+     * configuration is used instead! Only for startup and if the logkit.xconf is
+     * not readable/available this log level is of importance.
+     */
+    protected String bootstrapLogLevel;
+
+    /**
+     * This parameter switches the logging system from LogKit to Log4J for Cocoon.
+     */
+    protected String loggerManagerClassName;
+
+    /**
+     * Allow reinstantiating (reloading) of the cocoon instance. If this is
+     * set to "yes" or "true", a new cocoon instance can be created using
+     * the request parameter "cocoon-reload". It also enables that Cocoon is
+     * reloaded when cocoon.xconf changes. Default is no for security reasons.
+     */
+    protected boolean reloadingEnabled = RELOADING_ENABLED_DEFAULT;
+
+    /**
+     * This parameter is used to list classes that should be loaded at
+     * initialization time of the servlet. For example, JDBC Drivers used need to
+     * be named here. Additional entries may be inserted here during build
+     * depending on your build properties.
+     */
+    protected List loadClasses = new ArrayList();
+
+    /**
+     * Causes all files in multipart requests to be processed.
+     * Default is false for security reasons.
+     */
+    protected boolean enableUploads = ENABLE_UPLOADS;
+
+    /**
+     * This parameter allows to specify where Cocoon should put uploaded files.
+     * The path specified can be either absolute or relative to the context
+     * path of the servlet. On windows platform, absolute directory must start
+     * with volume: C:\Path\To\Upload\Directory.
+     */
+    protected String uploadDirectory;
+
+    /**
+     * Causes all files in multipart requests to be saved to upload-dir.
+     * Default is true for security reasons.
+     */
+    protected boolean autosaveUploads = SAVE_UPLOADS_TO_DISK;
+
+    /**
+     * Specify handling of name conflicts when saving uploaded files to disk.
+     * Acceptable values are deny, allow, rename (default). Files are renamed
+     * x_filename where x is an integer value incremented to make the new
+     * filename unique.
+     */
+    protected String overwriteUploads;
+
+    /**
+     * Specify maximum allowed size of the upload. Defaults to 10 Mb.
+     */
+    protected int maxUploadSize = MAX_UPLOAD_SIZE;
+
+    /**
+     * This parameter allows to specify where Cocoon should create its page
+     * and other objects cache. The path specified can be either absolute or
+     * relative to the context path of the servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Cache\Directory.
+     */
+    protected String cacheDirectory;
+
+    /**
+     * This parameter allows to specify where Cocoon should put it's
+     * working files. The path specified is either absolute or relative
+     * to the context path of the Cocoon servlet. On windows platform,
+     * absolute directory must start with volume: C:\Path\To\Work\Directory.
+     */
+    protected String workDirectory;
+
+    /**
+     * This parameter allows to specify additional directories or jars
+     * which Cocoon should put into it's own classpath.
+     * Note that absolute pathes are taken as such but relative pathes
+     * are rooted at the context root of the Cocoon servlet.
+     */
+    protected List extraClasspaths = new ArrayList();
+
+    /**
+     * This parameter allows you to select the parent service manager.
+     * The class will be instantiated via the constructor that takes a single
+     * String as a parameter. That String will be equal to the text after the '/'.
+     *
+     * Cocoon honors the LogEnabled, Initializable and Disposable interfaces for
+     * this class, if it implements them.
+     */
+    protected String parentServiceManagerClassName;
+
+    /**
+     * Allow adding processing time to the response
+     */
+    protected boolean showTime = SHOW_TIME;
+
+    /**
+     * If true, processing time will be added as an HTML comment
+     */
+    protected boolean hideShowTime = HIDE_SHOW_TIME;
+
+    /**
+     * If true, the X-Cocoon-Version response header will be included.
+     */
+    protected boolean showCocoonVersion = SHOW_COCOON_VERSION;
+
+    /**
+     * If true or not set, this class will try to catch and handle all Cocoon exceptions.
+     * If false, it will rethrow them to the servlet container.
+     */
+    protected boolean manageExceptions = MANAGE_EXCEPTIONS;
+
+    /**
+     * Set form encoding. This will be the character set used to decode request
+     * parameters. If not set the ISO-8859-1 encoding will be assumed.
+    */
+    protected String formEncoding;
+
+    /**
+     * If this value is specified, it will be interpreted as a log level and
+     * all logging categories will be set to this level regardless of their
+     * definition in the logging configuration.
+     */
+    protected String overrideLogLevel;
+
+    /**
+     * Delay between reload checks for the configuration.
+     */
+    protected long configurationReloadDelay = 1000;
+
+    /**
+     * Lazy mode for component loading
+     */
+    protected boolean lazyMode = false;
+
+    /** The time the cocoon instance was created. */
+    protected long creationTime;
+
+    /** The property providers. */
+    protected List propertyProviders = new ArrayList();
+
+    /**
+     * Create a new settings object
+     */
+    public MutableSettings() {
+        // nothing to do
+    }
+
+    /**
+     * Fill from a properties object
+     */
+    public void fill(Properties props) {
+        this.checkWriteable();
+        if ( props != null ) {
+            final Iterator i = props.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry current = (Map.Entry)i.next();
+                String key = current.getKey().toString();
+                if ( key.startsWith(KEYPREFIX) ) {
+                    key = key.substring(KEYPREFIX.length());
+                    final String value = current.getValue().toString();
+
+                    if ( key.equals(KEY_PROCESSOR_CLASS) ) {
+                        this.processorClassName = value;
+                    } else if ( key.equals(KEY_CONFIGURATION) ) {
+                        this.configuration = value;
+                    } else if ( key.equals(KEY_RELOAD_DELAY) ) {
+                        this.configurationReloadDelay = NumberUtils.toLong(value);
+                    } else if ( key.equals(KEY_LOGGING_CONFIGURATION) ) {
+                        this.loggingConfiguration = value;
+                    } else if ( key.equals(KEY_LOGGING_ENVIRONMENT_LOGGER) ) {
+                        this.environmentLogger = value;
+                    } else if ( key.equals(KEY_LOGGING_COCOON_LOGGER) ) {
+                        this.cocoonLogger = value;
+                    } else if ( key.equals(KEY_LOGGING_BOOTSTRAP_LOGLEVEL) ) {
+                        this.bootstrapLogLevel = value;
+                    } else if ( key.equals(KEY_LOGGING_MANAGER_CLASS) ) {
+                        this.loggerManagerClassName = value;
+                    } else if ( key.equals(KEY_RELOADING) ) {
+                        this.reloadingEnabled = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_ENABLE) ) {
+                        this.enableUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_DIRECTORY) ) {
+                        this.uploadDirectory = value;
+                    } else if ( key.equals(KEY_UPLOADS_AUTOSAVE) ) {
+                        this.autosaveUploads = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_UPLOADS_OVERWRITE) ) {
+                        this.overwriteUploads = value;
+                    } else if ( key.equals(KEY_UPLOADS_MAXSIZE) ) {
+                        this.maxUploadSize = NumberUtils.toInt(value);
+                    } else if ( key.equals(KEY_CACHE_DIRECTORY) ) {
+                        this.cacheDirectory = value;
+                    } else if ( key.equals(KEY_WORK_DIRECTORY) ) {
+                        this.workDirectory = value;
+                    } else if ( key.equals(KEY_PARENT_SERVICE_MANAGER) ) {
+                        this.parentServiceManagerClassName = value;
+                    } else if ( key.equals(KEY_SHOWTIME) ) {
+                        this.showTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_HIDE_SHOWTIME) ) {
+                        this.hideShowTime = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_SHOW_VERSION) ) {
+                        this.showCocoonVersion = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_MANAGE_EXCEPTIONS) ) {
+                        this.manageExceptions = BooleanUtils.toBoolean(value);
+                    } else if ( key.equals(KEY_FORM_ENCODING) ) {
+                        this.formEncoding = value;
+                    } else if ( key.equals(KEY_LOGGING_OVERRIDE_LOGLEVEL) ) {
+                        this.overrideLogLevel = value;
+                    } else if ( key.equals(KEY_LAZY_MODE) ) {
+                        this.lazyMode = BooleanUtils.toBoolean(value);
+                    } else if ( key.startsWith(KEY_LOAD_CLASSES) ) {
+                        this.addToLoadClasses(value);
+                    } else if ( key.startsWith(KEY_EXTRA_CLASSPATHS) ) {
+                        this.addToExtraClasspaths(value);
+                    } else if ( key.startsWith(KEY_PROPERTY_PROVIDER) ) {
+                        this.addToPropertyProviders(value);
+                    } else if ( key.startsWith(KEY_FORCE_PROPERTIES) ) {
+                        key = key.substring(KEY_FORCE_PROPERTIES.length() + 1);
+                        this.addToForceProperties(key, value);
+                    }
+                }
+            }
+            this.properties.add(props);
+        }
+    }
+
+    /**
+     * @return Returns the hideShowTime.
+     */
+    public boolean isHideShowTime() {
+        return this.hideShowTime;
+    }
+
+    /**
+     * @return Returns the allowReload.
+     */
+    public boolean isReloadingEnabled(String type) {
+        boolean result = this.reloadingEnabled;
+        if ( type != null ) {
+            String o = this.getProperty(KEYPREFIX + KEY_RELOADING + '.' + type);
+            if ( o != null ) {
+                result = BooleanUtils.toBoolean(o);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * @return Returns the autosaveUploads.
+     */
+    public boolean isAutosaveUploads() {
+        return this.autosaveUploads;
+    }
+
+    /**
+     * @return Returns the cacheDirectory.
+     */
+    public String getCacheDirectory() {
+        return this.cacheDirectory;
+    }
+
+    /**
+     * @return Returns the cocoonLogger.
+     */
+    public String getCocoonLogger() {
+        return this.cocoonLogger;
+    }
+
+    /**
+     * @return Returns the processorClassName.
+     */
+    public String getProcessorClassName() {
+        return this.processorClassName;
+    }
+
+    /**
+     * @return Returns the configuration.
+     */
+    public String getConfiguration() {
+        return this.configuration;
+    }
+
+    /**
+     * @return Returns the enableUploads.
+     */
+    public boolean isEnableUploads() {
+        return this.enableUploads;
+    }
+
+    /**
+     * @return Returns the extraClasspaths.
+     */
+    public List getExtraClasspaths() {
+        return this.extraClasspaths;
+    }
+
+    /**
+     * @return Returns the forceProperties.
+     */
+    public Map getForceProperties() {
+        return this.forceProperties;
+    }
+
+    /**
+     * @return Returns the formEncoding.
+     */
+    public String getFormEncoding() {
+        return this.formEncoding;
+    }
+
+    /**
+     * @return Returns the loadClasses.
+     */
+    public List getLoadClasses() {
+        return this.loadClasses;
+    }
+
+    /**
+     * @return Returns the loggerClassName.
+     */
+    public String getLoggerManagerClassName() {
+        return this.loggerManagerClassName;
+    }
+
+    /**
+     * @return Returns the loggingConfiguration.
+     */
+    public String getLoggingConfiguration() {
+        return this.loggingConfiguration;
+    }
+
+    /**
+     * @return Returns the logLevel.
+     */
+    public String getBootstrapLogLevel() {
+        return this.bootstrapLogLevel;
+    }
+
+    /**
+     * @return Returns the manageExceptions.
+     */
+    public boolean isManageExceptions() {
+        return this.manageExceptions;
+    }
+
+    /**
+     * @return Returns the maxUploadSize.
+     */
+    public int getMaxUploadSize() {
+        return this.maxUploadSize;
+    }
+
+    /**
+     * @return Returns the overwriteUploads.
+     */
+    public String getOverwriteUploads() {
+        return this.overwriteUploads;
+    }
+
+    /**
+     * @return Returns the parentServiceManagerClassName.
+     */
+    public String getParentServiceManagerClassName() {
+        return this.parentServiceManagerClassName;
+    }
+
+    /**
+     * @return Returns the showTime.
+     */
+    public boolean isShowTime() {
+        return this.showTime;
+    }
+
+    /**
+     * @return Returns the showCocoonVersion flag.
+     */
+    public boolean isShowVersion() {
+        return this.showCocoonVersion;
+    }
+
+    /**
+     * @return Returns the uploadDirectory.
+     */
+    public String getUploadDirectory() {
+        return this.uploadDirectory;
+    }
+
+    /**
+     * @return Returns the workDirectory.
+     */
+    public String getWorkDirectory() {
+        return this.workDirectory;
+    }
+
+    /**
+     * @return Returns the accessLogger.
+     */
+    public String getEnvironmentLogger() {
+        return this.environmentLogger;
+    }
+
+    /**
+     * @return Returns the overrideLogLevel.
+     */
+    public String getOverrideLogLevel() {
+        return this.overrideLogLevel;
+    }
+
+    public boolean isAllowOverwrite() {
+        if ("deny".equalsIgnoreCase(this.overwriteUploads)) {
+            return false;
+        } else if ("allow".equalsIgnoreCase(this.overwriteUploads)) {
+            return true;
+        } else {
+            // either rename is specified or unsupported value - default to rename.
+            return false;
+        }
+    }
+
+    public boolean isSilentlyRename() {
+        if ("deny".equalsIgnoreCase(this.overwriteUploads)) {
+            return false;
+        } else if ("allow".equalsIgnoreCase(this.overwriteUploads)) {
+            return false; // ignored in this case
+        } else {
+            // either rename is specified or unsupported value - default to rename.
+            return true;
+        }
+    }
+
+    /**
+     * @return Returns the configurationReloadDelay.
+     */
+    public long getReloadDelay(String type) {
+        long value = this.configurationReloadDelay;
+        if ( type != null ) {
+            String o = this.getProperty(KEYPREFIX + KEY_RELOAD_DELAY + '.' + type);
+            if ( o != null ) {
+                value = NumberUtils.toLong(o);
+            }
+        }
+        return value;
+    }
+
+    /**
+     * @return Returns the lazyMode.
+     */
+    public boolean isLazyMode() {
+        return this.lazyMode;
+    }
+
+    public String getProperty(String name) {
+        return this.getProperty(name, null);
+    }
+
+    public String getProperty(String key, String defaultValue) {
+        if ( key == null ) {
+            return defaultValue;
+        }
+        String value = null;
+        if ( key.startsWith(KEYPREFIX) ) {
+            final String sKey = key.substring(KEYPREFIX.length());
+            if ( sKey.equals(KEY_PROCESSOR_CLASS) ) {
+                value = this.processorClassName;
+            } else if ( sKey.equals(KEY_CONFIGURATION) ) {
+                value = this.configuration;
+            } else if ( sKey.equals(KEY_RELOAD_DELAY) ) {
+                value = String.valueOf(this.configurationReloadDelay);
+            } else if ( sKey.equals(KEY_LOGGING_CONFIGURATION) ) {
+                value = this.loggingConfiguration;
+            } else if ( sKey.equals(KEY_LOGGING_ENVIRONMENT_LOGGER) ) {
+                value = this.environmentLogger;
+            } else if ( sKey.equals(KEY_LOGGING_COCOON_LOGGER) ) {
+                value = this.cocoonLogger;
+            } else if ( sKey.equals(KEY_LOGGING_BOOTSTRAP_LOGLEVEL) ) {
+                value = this.bootstrapLogLevel;
+            } else if ( sKey.equals(KEY_LOGGING_MANAGER_CLASS) ) {
+                value = this.loggerManagerClassName;
+            } else if ( sKey.equals(KEY_RELOADING) ) {
+                value = String.valueOf(this.reloadingEnabled);
+            } else if ( sKey.equals(KEY_UPLOADS_ENABLE) ) {
+                value = String.valueOf(this.enableUploads);
+            } else if ( sKey.equals(KEY_UPLOADS_DIRECTORY) ) {
+                value = this.uploadDirectory = value;
+            } else if ( sKey.equals(KEY_UPLOADS_AUTOSAVE) ) {
+                value = String.valueOf(this.autosaveUploads);
+            } else if ( sKey.equals(KEY_UPLOADS_OVERWRITE) ) {
+                value = this.overwriteUploads;
+            } else if ( sKey.equals(KEY_UPLOADS_MAXSIZE) ) {
+                value = String.valueOf(this.maxUploadSize);
+            } else if ( sKey.equals(KEY_CACHE_DIRECTORY) ) {
+                value = this.cacheDirectory;
+            } else if ( sKey.equals(KEY_WORK_DIRECTORY) ) {
+                value = this.workDirectory;
+            } else if ( sKey.equals(KEY_PARENT_SERVICE_MANAGER) ) {
+                value = this.parentServiceManagerClassName;
+            } else if ( sKey.equals(KEY_SHOWTIME) ) {
+                value = String.valueOf(this.showTime);
+            } else if ( sKey.equals(KEY_HIDE_SHOWTIME) ) {
+                value = String.valueOf(this.hideShowTime);
+            } else if ( sKey.equals(KEY_MANAGE_EXCEPTIONS) ) {
+                value = String.valueOf(this.manageExceptions);
+            } else if ( sKey.equals(KEY_FORM_ENCODING) ) {
+                value = this.formEncoding;
+            } else if ( sKey.equals(KEY_LOGGING_OVERRIDE_LOGLEVEL) ) {
+                value = this.overrideLogLevel;
+            } else if ( sKey.equals(KEY_LAZY_MODE) ) {
+                value = String.valueOf(this.lazyMode);
+            } else if ( key.equals(KEY_LOAD_CLASSES) ) {
+                value = this.toString(this.loadClasses);
+            } else if ( key.equals(KEY_EXTRA_CLASSPATHS) ) {
+                this.toString(this.extraClasspaths);
+            } else if ( key.equals(KEY_FORCE_PROPERTIES) ) {
+                this.toString(this.forceProperties);
+            } else if ( key.equals(KEY_PROPERTY_PROVIDER) ) {
+                this.toString(this.propertyProviders);
+            }
+        }
+
+        // Iterate in reverse order, as most specific property sources are added last
+        for (int i = this.properties.size() - 1; i >= 0 && value == null; i--) {
+            final Properties p = (Properties)this.properties.get(i);
+            value = p.getProperty(key);
+        }
+
+        if ( value == null ) {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "Settings:\n" +
+          "Running mode : " + this.getProperty(PROPERTY_RUNNING_MODE, DEFAULT_RUNNING_MODE) + '\n' +
+          KEY_PROCESSOR_CLASS + " : " + this.processorClassName + '\n' +
+          KEY_CONFIGURATION + " : " + this.configuration + '\n' +
+          KEY_RELOAD_DELAY + " : " + this.configurationReloadDelay + '\n' +
+          KEY_RELOADING + " : " + this.reloadingEnabled + '\n' +
+          KEY_EXTRA_CLASSPATHS + " : " + this.toString(this.extraClasspaths) + '\n' +
+          KEY_LOAD_CLASSES + " : " + this.toString(this.loadClasses) + '\n' +
+          KEY_FORCE_PROPERTIES + " : " + this.toString(this.forceProperties) + '\n' +
+          KEY_LOGGING_CONFIGURATION + " : " + this.loggingConfiguration + '\n' +
+          KEY_LOGGING_ENVIRONMENT_LOGGER + " : " + this.environmentLogger + '\n' +
+          KEY_LOGGING_BOOTSTRAP_LOGLEVEL + " : " + this.bootstrapLogLevel + '\n' +
+          KEY_LOGGING_COCOON_LOGGER + " : " + this.cocoonLogger + '\n' +
+          KEY_LOGGING_MANAGER_CLASS + " : " + this.loggerManagerClassName + '\n' +
+          KEY_LOGGING_OVERRIDE_LOGLEVEL + " : " + this.overrideLogLevel + '\n' +
+          KEY_MANAGE_EXCEPTIONS + " : " + this.manageExceptions + '\n' +
+          KEY_PARENT_SERVICE_MANAGER + " : " + this.parentServiceManagerClassName + '\n' +
+          KEY_UPLOADS_DIRECTORY + " : " + this.uploadDirectory + '\n' +
+          KEY_UPLOADS_AUTOSAVE + " : " + this.autosaveUploads + '\n' +
+          KEY_UPLOADS_ENABLE + " : " + this.enableUploads + '\n' +
+          KEY_UPLOADS_MAXSIZE + " : " + this.maxUploadSize + '\n' +
+          KEY_UPLOADS_OVERWRITE + " : " + this.overwriteUploads + '\n' +
+          KEY_CACHE_DIRECTORY + " : " + this.cacheDirectory + '\n' +
+          KEY_WORK_DIRECTORY + " : " + this.workDirectory + '\n' +
+          KEY_FORM_ENCODING + " : " + this.formEncoding + '\n' +
+          KEY_SHOWTIME + " : " + this.showTime + '\n' +
+          KEY_HIDE_SHOWTIME + " : " + this.hideShowTime + '\n' +
+          KEY_SHOW_VERSION + " : " + this.showCocoonVersion + '\n' +
+          KEY_LAZY_MODE + " : " + this.lazyMode + '\n';
+    }
+
+    /**
+     * Helper method to make a string out of a list of objects.
+     */
+    protected String toString(List a) {
+        final StringBuffer buffer = new StringBuffer();
+        final Iterator i = a.iterator();
+        boolean first = true;
+        while ( i.hasNext() ) {
+            if ( first ) {
+                first = false;
+            } else {
+                buffer.append(", ");
+            }
+            buffer.append(i.next());
+        }
+        return buffer.toString();        
+    }
+
+    /**
+     * Helper method to make a string out of a map of objects.
+     */
+    protected String toString(Map a) {
+        final StringBuffer buffer = new StringBuffer("{");
+        final Iterator i = a.entrySet().iterator();
+        boolean first = true;
+        while ( i.hasNext() ) {
+            if ( first ) {
+                first = false;
+            } else {
+                buffer.append(", ");
+            }
+            final Map.Entry current = (Map.Entry)i.next();
+            buffer.append(current.getKey());
+            buffer.append("=");
+            buffer.append(current.getValue());
+        }
+        buffer.append("}");
+        return buffer.toString();        
+    }
+
+    /**
+     * @param hideShowTime The hideShowTime to set.
+     */
+    public void setHideShowTime(boolean hideShowTime) {
+        this.checkWriteable();
+        this.hideShowTime = hideShowTime;
+    }
+
+    /**
+     * @param allowReload The allowReload to set.
+     */
+    public void setReloadingEnabled(boolean allowReload) {
+        this.checkWriteable();
+        this.reloadingEnabled = allowReload;
+    }
+
+    /**
+     * @param autosaveUploads The autosaveUploads to set.
+     */
+    public void setAutosaveUploads(boolean autosaveUploads) {
+        this.checkWriteable();
+        this.autosaveUploads = autosaveUploads;
+    }
+
+    /**
+     * @param cacheDirectory The cacheDirectory to set.
+     */
+    public void setCacheDirectory(String cacheDirectory) {
+        this.checkWriteable();
+        this.cacheDirectory = cacheDirectory;
+    }
+
+    /**
+     * @param processorClassName The processorClassName to set.
+     */
+    public void setProcessorClassName(String processorClassName) {
+        this.checkWriteable();
+        this.processorClassName = processorClassName;
+    }
+
+    /**
+     * @param cocoonLogger The cocoonLogger to set.
+     */
+    public void setCocoonLogger(String cocoonLogger) {
+        this.checkWriteable();
+        this.cocoonLogger = cocoonLogger;
+    }
+
+    /**
+     * @param configuration The configuration to set.
+     */
+    public void setConfiguration(String configuration) {
+        this.checkWriteable();
+        this.configuration = configuration;
+    }
+
+    /**
+     * @param enableUploads The enableUploads to set.
+     */
+    public void setEnableUploads(boolean enableUploads) {
+        this.checkWriteable();
+        this.enableUploads = enableUploads;
+    }
+
+    /**
+     * @param extraClasspath The extraClasspaths to set.
+     */
+    public void addToExtraClasspaths(String extraClasspath) {
+        this.checkWriteable();
+        this.extraClasspaths.add(extraClasspath);
+    }
+
+    /**
+     * @param key The forceProperties to set.
+     * @param value The forceProperties value to set.
+     */
+    public void addToForceProperties(String key, String value) {
+        this.checkWriteable();
+        this.forceProperties.put(key, value);
+    }
+
+    /**
+     * @param formEncoding The formEncoding to set.
+     */
+    public void setFormEncoding(String formEncoding) {
+        this.checkWriteable();
+        this.formEncoding = formEncoding;
+    }
+
+    /**
+     * @param className The loadClasses to set.
+     */
+    public void addToLoadClasses(String className) {
+        this.checkWriteable();
+        this.loadClasses.add(className);
+    }
+
+    /**
+     * @param loggerClassName The loggerClassName to set.
+     */
+    public void setLoggerManagerClassName(String loggerClassName) {
+        this.checkWriteable();
+        this.loggerManagerClassName = loggerClassName;
+    }
+
+    /**
+     * @param loggingConfiguration The loggingConfiguration to set.
+     */
+    public void setLoggingConfiguration(String loggingConfiguration) {
+        this.checkWriteable();
+        this.loggingConfiguration = loggingConfiguration;
+    }
+
+    /**
+     * @param logLevel The logLevel to set.
+     */
+    public void setBootstrapLogLevel(String logLevel) {
+        this.checkWriteable();
+        this.bootstrapLogLevel = logLevel;
+    }
+
+    /**
+     * @param manageExceptions The manageExceptions to set.
+     */
+    public void setManageExceptions(boolean manageExceptions) {
+        this.checkWriteable();
+        this.manageExceptions = manageExceptions;
+    }
+
+    /**
+     * @param maxUploadSize The maxUploadSize to set.
+     */
+    public void setMaxUploadSize(int maxUploadSize) {
+        this.checkWriteable();
+        this.maxUploadSize = maxUploadSize;
+    }
+
+    /**
+     * @param overwriteUploads The overwriteUploads to set.
+     */
+    public void setOverwriteUploads(String overwriteUploads) {
+        this.checkWriteable();
+        this.overwriteUploads = overwriteUploads;
+    }
+    
+    /**
+     * @param parentServiceManagerClassName The parentServiceManagerClassName to set.
+     */
+    public void setParentServiceManagerClassName(
+            String parentServiceManagerClassName) {
+        this.checkWriteable();
+        this.parentServiceManagerClassName = parentServiceManagerClassName;
+    }
+
+    /**
+     * @param showTime The showTime to set.
+     */
+    public void setShowTime(boolean showTime) {
+        this.checkWriteable();
+        this.showTime = showTime;
+    }
+
+    /**
+     * @param showCocoonVersion The showCocoonVersion flag to set.
+     */
+    public void setShowCocoonVersion(boolean showCocoonVersion) {
+        this.checkWriteable();
+        this.showCocoonVersion = showCocoonVersion;
+    }
+
+    /**
+     * @param uploadDirectory The uploadDirectory to set.
+     */
+    public void setUploadDirectory(String uploadDirectory) {
+        this.checkWriteable();
+        this.uploadDirectory = uploadDirectory;
+    }
+
+    /**
+     * @param workDirectory The workDirectory to set.
+     */
+    public void setWorkDirectory(String workDirectory) {
+        this.checkWriteable();
+        this.workDirectory = workDirectory;
+    }
+
+    /**
+     * @param logger The logger for the environment.
+     */
+    public void setEnvironmentLogger(String logger) {
+        this.checkWriteable();
+        this.environmentLogger = logger;
+    }
+
+    /**
+     * @param overrideLogLevel The overrideLogLevel to set.
+     */
+    public void setOverrideLogLevel(String overrideLogLevel) {
+        this.checkWriteable();
+        this.overrideLogLevel = overrideLogLevel;
+    }
+
+    /**
+     * @param configurationReloadDelay The configurationReloadDelay to set.
+     */
+    public void setConfigurationReloadDelay(long configurationReloadDelay) {
+        this.checkWriteable();
+        this.configurationReloadDelay = configurationReloadDelay;
+    }
+
+    /**
+     * @param lazyMode The lazyMode to set.
+     */
+    public void setLazyMode(boolean lazyMode) {
+        this.checkWriteable();
+        this.lazyMode = lazyMode;
+    }
+
+    /**
+     * Mark this object as read-only.
+     */
+    public void makeReadOnly() {
+        this.readOnly = false;
+    }
+
+    /**
+     * check if this configuration is writeable.
+     *
+     * @throws IllegalStateException if this setting is read-only
+     */
+    protected final void checkWriteable()
+    throws IllegalStateException {
+        if( this.readOnly ) {
+            throw new IllegalStateException
+                ( "Settings is read only and can not be modified anymore." );
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BaseSettings#getCreationTime()
+     */
+    public long getCreationTime() {
+        return this.creationTime;
+    }
+
+    /**
+     * Set the creation time of the current cocoon instance.
+     */
+    public void setCreationTime(long value) {
+        // Don't check read only here as this will change if Cocoon
+        // is reloaded while the settings remain the same.
+        this.creationTime = value;
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BaseSettings#getPropertyProviders()
+     */
+    public List getPropertyProviders() {
+        return this.propertyProviders;
+    }
+
+    /**
+     * Add a property provider.
+     */
+    public void addToPropertyProviders(String className) {
+        this.checkWriteable();
+        this.propertyProviders.add(className);
+    }
+
+    /**
+     * @see org.apache.cocoon.core.Settings#getProperties(java.lang.String)
+     */
+    public List getProperties(String keyPrefix) {
+        final List props = new ArrayList();
+        for(int i=0; i < this.properties.size(); i++) {
+            final Properties p = (Properties)this.properties.get(i);
+            final Iterator kI = p.keySet().iterator();
+            while ( kI.hasNext() ) {
+                final String name = (String)kI.next();
+                if ( name.startsWith(keyPrefix) && !props.contains(name) ) {
+                    props.add(name);
+                }
+            }
+        }
+        return props;
+    }
+    
+    /**
+     * @see org.apache.cocoon.core.Settings#getProperties()
+     */
+    public List getProperties() {
+        final List props = new ArrayList();
+        for(int i=0; i < this.properties.size(); i++) {
+            final Properties p = (Properties)this.properties.get(i);
+            final Iterator kI = p.keySet().iterator();
+            while ( kI.hasNext() ) {
+                final String name = (String)kI.next();
+                if (!props.contains(name) ) {
+                    props.add(name);
+                }
+            }
+        }
+        return props;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/PropertyProvider.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/PropertyProvider.java
new file mode 100644
index 0000000..6b8ecf0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/PropertyProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core;
+
+import java.util.Properties;
+
+/**
+ * This is an interface for custom components delivering properties to
+ * configure Cocoon.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public interface PropertyProvider {
+
+    Properties getProperties();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Settings.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Settings.java
new file mode 100644
index 0000000..26b35fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/Settings.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.core;
+
+import java.util.List;
+
+/**
+ * This object holds the global configuration of Cocoon.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public interface Settings extends BaseSettings, DynamicSettings {
+
+    /**
+     * Get the value of a property.
+     * @param key The name of the property.
+     * @return The value of the property or null.
+     */
+    String getProperty(String key);
+
+    /**
+     * Get the value of a property.
+     * @param key The name of the property.
+     * @param defaultValue The value returned if the property is not available.
+     * @return The value of the property or if the property cannot
+     *         be found the default value.
+     */
+    String getProperty(String key, String defaultValue);
+
+    /**
+     * Return all available properties starting with the prefix.
+     * @param keyPrefix The prefix each property name must have.
+     * @return A list of property names (including the prefix) or
+     *         an empty list.
+     */
+    List getProperties(String keyPrefix);
+    
+    /**
+     * Return all available properties
+     * @return A list of all property names or an empty list.
+     */
+    List getProperties();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/WiringNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/WiringNotFoundException.java
new file mode 100644
index 0000000..adfd8dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/WiringNotFoundException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core;
+
+/**
+ * Throw this exception in the case that the wiring.xml is not found.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class WiringNotFoundException extends RuntimeException {
+
+    public WiringNotFoundException(String message) {
+        super(message);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentEnvironment.java
new file mode 100644
index 0000000..d24ebf0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentEnvironment.java
@@ -0,0 +1,98 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.io.InputStream;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.util.JMXUtils;
+
+/**
+ * The component enviromnent contains all objects necessary to create
+ * a new component; it's just a "container" of objects.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class ComponentEnvironment {
+
+    public final ServiceManager serviceManager;
+    public final Context context;
+    public final Logger logger;
+    public final RoleManager roleManager;
+    public final LoggerManager loggerManager;
+    private final ClassLoader classLoader;
+    private Core core;
+
+    public ComponentEnvironment(ClassLoader classLoader, Logger logger, RoleManager roleManager, LoggerManager loggerManager,
+            Context context, ServiceManager serviceManager) {
+
+        // Find a class loader
+        if (classLoader == null) {
+            classLoader = Thread.currentThread().getContextClassLoader();
+            if (classLoader == null) {
+                classLoader = this.getClass().getClassLoader();
+            }            
+        }
+
+        this.classLoader = classLoader;
+        this.logger = logger;
+        this.roleManager = roleManager;
+        this.loggerManager = loggerManager;
+        this.context = context;
+        this.serviceManager = serviceManager;
+        // FIXME - we should ensure that the context is never null!
+        if ( this.context != null ) {
+            try {
+                this.core = (Core)this.context.get(Core.ROLE);
+            } catch (ContextException ignore) {
+                // this can never happen
+            }
+        }
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+        return this.classLoader.loadClass(name);
+    }
+    
+    public ComponentInfo loadComponentInfo(String name) 
+    throws Exception {
+        final StringBuffer bu = new StringBuffer(name);
+        bu.append(".xconf");
+        ComponentInfo ci = null;
+        final InputStream is = this.classLoader.getResourceAsStream(bu.toString());
+        if ( is != null ) {
+            final Settings settings = (this.core == null ? null : this.core.getSettings());
+            final ConfigurationBuilder cb = new ConfigurationBuilder(settings);
+            final Configuration conf = cb.build(is);
+            ci = new ComponentInfo();
+            ci.fill(conf);
+            ci.setJmxDomain(JMXUtils.findJmxDomain(ci.getJmxDomain(), serviceManager));
+            ci.setJmxName(JMXUtils.findJmxName(ci.getJmxName(), ci.getServiceClassName()));
+        }
+        return ci;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentFactory.java
new file mode 100644
index 0000000..7cb38c4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentFactory.java
@@ -0,0 +1,214 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.lang.reflect.Method;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.Core;
+
+/**
+ * Factory for Avalon based components.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class ComponentFactory {
+    
+    protected final ComponentInfo serviceInfo;
+    
+    protected final ComponentEnvironment environment;
+    
+    /**
+     * The component's logger, which may be different from the environment's logger
+     */
+    protected final Logger componentLogger;
+    
+    /** The parameters for this component
+     */
+    protected final Parameters parameters;
+    
+    protected final Class serviceClass;
+    protected final Method initMethod;
+    protected final Method destroyMethod;
+    protected final Method poolInMethod;
+    protected final Method poolOutMethod;
+    protected Method configureSettingsMethod;
+    protected Core core;
+
+    /**
+     * Construct a new component factory for the specified component.
+     *
+     * @param environment Describes the environment for the component.
+     * @param info Describes the configuration/settings for the component.
+     *
+     */
+    public ComponentFactory( final ComponentEnvironment environment,
+                             final ComponentInfo info) 
+    throws Exception {
+        // FIXME - we should ensure that the context is never null!
+        if ( environment.context != null ) {
+            try {
+                this.core = (Core)environment.context.get(Core.ROLE);
+            } catch (ContextException ignore) {
+                // this can never happen
+            }
+        }
+        this.environment = environment;
+        this.serviceInfo = info;
+        
+        // this is our default logger:
+        Logger actualLogger = this.environment.logger;
+        final String category = this.serviceInfo.getLoggerCategory();
+        if ( category != null ) {
+            // If the handler is created "manually" (e.g. XSP engine), loggerManager can be null
+            if( this.environment.loggerManager != null ) {
+                actualLogger = this.environment.loggerManager.getLoggerForCategory(category);
+            }
+        }
+        this.componentLogger = actualLogger;
+        
+        this.serviceClass = this.environment.loadClass(this.serviceInfo.getServiceClassName());
+        if ( Parameterizable.class.isAssignableFrom(this.serviceClass) ) {
+            this.parameters = Parameters.fromConfiguration( this.serviceInfo.getConfiguration() );            
+        } else {
+            this.parameters = null;
+        }
+        if ( this.serviceInfo.getDestroyMethodName() != null ) {
+            this.destroyMethod = this.serviceClass.getMethod(this.serviceInfo.getDestroyMethodName(), null);
+        } else {
+            this.destroyMethod = null;
+        }
+        if ( this.serviceInfo.getInitMethodName() != null ) {
+            this.initMethod = this.serviceClass.getMethod(this.serviceInfo.getInitMethodName(), null);
+        } else {
+            this.initMethod = null;
+        }
+        if ( this.serviceInfo.getPoolInMethodName() != null ) {
+            this.poolInMethod = this.serviceClass.getMethod(this.serviceInfo.getPoolInMethodName(), null);
+        } else {
+            this.poolInMethod = null;
+        }
+        if ( this.serviceInfo.getPoolOutMethodName() != null ) {
+            this.poolOutMethod = this.serviceClass.getMethod(this.serviceInfo.getPoolOutMethodName(), null);
+        } else {
+            this.poolOutMethod = null;
+        }
+        try {
+            this.configureSettingsMethod = this.serviceClass.getMethod("configure", new Class[] {Core.class});
+        } catch (Throwable ignore) {
+            // we have to catch throwable here, as the above test can
+            // result in NoClassDefFound exceptions etc.
+            this.configureSettingsMethod = null;
+        }
+    }
+    
+    /**
+     * Create a new instance
+     */
+    public final Object newInstance()
+    throws Exception {
+        final Object component = this.serviceClass.newInstance();
+
+        setupInstance(component);
+        return component;
+    }
+    
+    /**
+     * Invoke the various lifecycle interfaces to setup a newly created component
+     * @param component
+     * @throws Exception
+     */
+    protected void setupInstance(Object component) throws Exception {
+        if( this.environment.logger.isDebugEnabled() ) {
+            this.environment.logger.debug( "ComponentFactory creating new instance of " +
+                    this.serviceClass.getName() + "." );
+        }
+
+        ContainerUtil.enableLogging(component, this.componentLogger);
+        ContainerUtil.contextualize( component, this.environment.context );
+        ContainerUtil.service( component, this.environment.serviceManager );
+        if ( this.configureSettingsMethod != null && this.core != null) {
+            this.configureSettingsMethod.invoke( component, new Object[] {this.core});
+        }
+        ContainerUtil.configure( component, this.serviceInfo.getConfiguration() );
+
+        if( component instanceof Parameterizable ) {
+            ContainerUtil.parameterize( component, this.parameters );
+        }
+
+        ContainerUtil.initialize( component );
+
+        if ( this.initMethod != null ) {
+            this.initMethod.invoke(component, null);
+        }
+
+        ContainerUtil.start( component );
+    }
+
+    public Class getCreatedClass() {
+        return this.serviceClass;
+    }
+
+    /**
+     * Destroy an instance
+     */
+    public void decommission( final Object component )
+    throws Exception {
+        if( this.environment.logger.isDebugEnabled() ) {
+            this.environment.logger.debug( "ComponentFactory decommissioning instance of " +
+                    this.serviceClass.getName() + "." );
+        }
+
+        ContainerUtil.stop( component );
+        ContainerUtil.dispose( component );
+
+        if ( this.destroyMethod != null ) {
+            this.destroyMethod.invoke(component, null);
+        }
+    }
+
+    /**
+     * Handle service specific methods for getting it out of the pool
+     */
+    public void exitingPool( final Object component )
+    throws Exception {
+        if ( this.poolOutMethod != null ) {
+            this.poolOutMethod.invoke(component, null);
+        }         
+    }
+
+    /**
+     * Handle service specific methods for putting it into the pool
+     */
+    public void enteringPool( final Object component )
+    throws Exception {
+        // Handle Recyclable objects
+        if( component instanceof Recyclable ) {
+            ( (Recyclable)component ).recycle();
+        }
+        if ( this.poolInMethod != null ) {
+            this.poolInMethod.invoke(component, null);
+        }         
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java
new file mode 100644
index 0000000..e61ce14
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ComponentLocatorWrapper.java
@@ -0,0 +1,65 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.ComponentLocator;
+
+/**
+ * Wrapper for a service manager.
+ *
+ * @version Id: ComponentLocatorWrapper.java 179038 2005-05-30 08:19:24Z cziegeler $
+ * @since 2.2
+ */
+final public class ComponentLocatorWrapper
+implements ComponentLocator {
+
+    protected final ServiceManager manager;
+
+    public ComponentLocatorWrapper(ServiceManager m) {
+        this.manager = m;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#hasComponent(java.lang.String)
+     */
+    public boolean hasComponent(String key) {
+        return this.manager.hasService(key);
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#getComponent(java.lang.String)
+     */
+    public Object getComponent(String key) 
+    throws ProcessingException {
+        try {
+            return this.manager.lookup(key);
+        } catch (ServiceException se) {
+            throw new ProcessingException("Unable to lookup component for key: " + key, se);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        this.manager.release(component);
+    }
+
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/CoreServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/CoreServiceManager.java
new file mode 100644
index 0000000..dfe8220
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/CoreServiceManager.java
@@ -0,0 +1,940 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.Preloadable;
+import org.apache.cocoon.configuration.ConfigurationBuilder;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.CoreResourceNotFoundException;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.core.container.handler.AbstractComponentHandler;
+import org.apache.cocoon.core.container.handler.AliasComponentHandler;
+import org.apache.cocoon.core.container.handler.ComponentHandler;
+import org.apache.cocoon.core.container.handler.InstanceComponentHandler;
+import org.apache.cocoon.core.container.handler.LazyHandler;
+import org.apache.cocoon.core.source.SimpleSourceResolver;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.sitemap.impl.ComponentManager;
+import org.apache.cocoon.util.JMXUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.TraversableSource;
+
+/**
+ * Default service manager for Cocoon's components.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class CoreServiceManager
+        extends AbstractLogEnabled
+        implements Contextualizable, ThreadSafe, Disposable, Initializable, ServiceManager, Configurable {
+
+    /** The attribute containing the JMX domain name */
+    public static final String JMX_DOMAIN_ATTR_NAME = "jmx-domain";
+
+    /** The attribute containing the JMX domain name */
+    public static final String JMX_NAME_ATTR_NAME = "jmx-name";
+
+    /** The attribute containing the JMX domain name */
+    public static final String JMX_DEFAULT_DOMAIN_NAME = "Cocoon";
+    
+    /**
+     * An empty configuration object, that can be used when no configuration is known but one
+     * is needed.
+     */
+    public static final Configuration EMPTY_CONFIGURATION = new DefaultConfiguration("-", "unknown location");
+
+    /** Parameter map for the context protocol */
+    protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE);
+
+    /** The application context for components */
+    protected Context context;
+
+    /** Static component mapping handlers. */
+    protected final Map componentMapping = Collections.synchronizedMap(new HashMap());
+
+    /** Used to map roles to ComponentHandlers. */
+    protected final Map componentHandlers = Collections.synchronizedMap(new HashMap());
+
+    /** Is the Manager disposed or not? */
+    protected boolean disposed;
+
+    /** Is the Manager initialized? */
+    protected boolean initialized;
+
+    /** RoleInfos. */
+    protected RoleManager roleManager;
+
+    /** LoggerManager. */
+    protected LoggerManager loggerManager;
+
+    protected ComponentEnvironment componentEnv;
+
+    /** The settings */
+    private Settings settings;
+
+    /** The location where this manager is defined */
+    protected String location;
+
+    /** The parent ServiceManager */
+    protected ServiceManager parentManager;
+
+    /** The classloader to get classes from */
+    protected ClassLoader classloader;
+
+    /** The resolver used to resolve includes. It is lazily loaded in {@link #setupSourceResolver()}. */
+    private SourceResolver cachedSourceResolver;
+
+    private String jmxDefaultDomain = null;
+    
+    /** Create the ServiceManager with a parent ServiceManager */
+    public CoreServiceManager( final ServiceManager parent ) {
+        this(parent, null);
+    }
+
+    /** Create the ServiceManager with a parent ServiceManager and a ClassLoader */
+    public CoreServiceManager( final ServiceManager parent, final ClassLoader classloader ) {
+        this.parentManager = parent;
+        this.classloader = classloader;
+
+        RoleManager parentRoleManager = null;
+        // FIXME - We should change this to a cleaner way!
+        ServiceManager coreServicemanager = parent;
+        if ( parent instanceof ComponentManager ) {
+            coreServicemanager = ((ComponentManager)parent).getServiceManager();
+        }
+        // get role manager and logger manager
+        if ( coreServicemanager instanceof CoreServiceManager ) {
+            parentRoleManager = ((CoreServiceManager)coreServicemanager).roleManager;
+            this.loggerManager = ((CoreServiceManager)coreServicemanager).loggerManager;
+        }
+
+        // Always create a role manager, it can be filled several times either through
+        // the root "roles" attribute or through loading of includes
+        this.roleManager = new RoleManager(parentRoleManager);
+    }
+
+    //=============================================================================================
+    // Avalon lifecycle
+    //=============================================================================================
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+     */
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.roleManager.enableLogging(logger);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize( final Context context ) 
+    throws ContextException {
+        this.context = context;
+        this.settings = ((Core)context.get(Core.ROLE)).getSettings();
+    }
+
+    /**
+     * Configure the LoggerManager.
+     */
+    public void setLoggerManager( final LoggerManager manager ) {
+        this.loggerManager = manager;
+    }
+
+    public void setRoleManager (RoleManager rm) {
+        if (rm != null) {
+            // Override the one eventually got in the parent (see constructor)
+            // FIXME - Why do we wrap the role manager?
+            this.roleManager = new RoleManager(rm);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        // It's possible to define a logger on a per sitemap/service manager base.
+        // This is the default logger for all components defined with this sitemap/manager.
+        if ( configuration.getAttribute("logger", null) != null ) {
+            this.enableLogging(this.loggerManager.getLoggerForCategory(configuration.getAttribute("logger")));
+        }
+        this.componentEnv = new ComponentEnvironment(this.classloader, getLogger(), this.roleManager, this.loggerManager, this.context, this);
+
+        // Setup location
+        this.location = configuration.getLocation();
+
+        // Find the current URI
+        String currentURI;
+        int pos = this.location.lastIndexOf(':');
+        if (pos == -1) {
+            // No available location: start at the context
+            currentURI = "context://";
+        } else {
+            pos = this.location.lastIndexOf(':', pos);
+            currentURI = this.location.substring(0, pos-1);
+        }
+
+        // find possible JMX domain name
+        this.jmxDefaultDomain = configuration.getAttribute(JMX_DOMAIN_ATTR_NAME, null);
+
+        try {
+            // and load configuration with a empty list of loaded configurations
+            parseConfiguration(configuration, currentURI, new HashSet());
+        } finally {
+            // Release any source resolver that may have been created to load includes
+            releaseCachedSourceResolver();
+        }
+    }
+
+    /**
+     * @return The default JMX domain name
+     */
+    public String getJmxDefaultDomain() {
+        if (this.jmxDefaultDomain == null) {
+            if (this.parentManager instanceof CoreServiceManager) {
+                return ((CoreServiceManager)this.parentManager).getJmxDefaultDomain();
+            }
+            return JMX_DEFAULT_DOMAIN_NAME;
+        }
+        return this.jmxDefaultDomain;
+    }
+    
+    /**
+     * Return the service manager logger.
+     */
+    public Logger getServiceManagerLogger() {
+        return this.getLogger();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize()
+    throws Exception {
+        this.initialized = true;
+
+        // Initialize component handlers. This is done in no particular order, but initializing a
+        // handler may indirectly initialize another handler through a call to lookup().
+        // This isn't a problem as a handler's initialize() method can be called several times.
+
+        // We copy the list of handlers as the componentHandler Map may change if implicitely declared
+        // components are looked up.
+        ComponentHandler[] handlers = (ComponentHandler[])this.componentHandlers.values().toArray(
+                new ComponentHandler[this.componentHandlers.size()]);
+
+        for( int i = 0; i < handlers.length; i++ ) {
+            try {
+                handlers[i].initialize();
+            } catch( Exception e ) {
+                if( this.getLogger().isErrorEnabled() ) {
+                    this.getLogger().error( "Caught an exception trying to initialize "
+                                       + "the component handler.", e );
+                }
+                // Rethrow the exception
+                throw e;
+            }
+        }
+
+//        Object[] keyArray = this.componentHandlers.keySet().toArray();
+//        java.util.Arrays.sort(keyArray);
+//        for (int i = 0; i < keyArray.length; i++) {
+//            System.err.println("Component key = " + keyArray[i]);
+//        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        boolean forceDisposal = false;
+
+        final List disposed = new ArrayList();
+
+        while( componentHandlers.size() > 0 ) {
+            for( Iterator iterator = componentHandlers.keySet().iterator();
+                 iterator.hasNext(); ) {
+                final Object role = iterator.next();
+
+                final ComponentHandler handler =
+                    (ComponentHandler)componentHandlers.get( role );
+
+                if( forceDisposal || handler.canBeDisposed() ) {
+                    if( forceDisposal && getLogger().isWarnEnabled() ) {
+                        this.getLogger().warn
+                            ( "disposing of handler for unreleased component."
+                              + " role [" + role + "]" );
+                    }
+
+                    handler.dispose();
+                    disposed.add( role );
+                }
+            }
+
+            if( disposed.size() > 0 ) {
+                final Iterator i = disposed.iterator();
+                while ( i.hasNext() ) {
+                    this.componentHandlers.remove( i.next() );
+                }
+                disposed.clear();
+            } else {   
+                // no more disposable handlers!
+                forceDisposal = true;
+            }
+        }
+        this.disposed = true;
+    }
+
+    //=============================================================================================
+    // ServiceManager implementation
+    //=============================================================================================
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService( final String role ) {
+        if( !this.initialized || this.disposed ) return false;
+
+        boolean exists = this.componentHandlers.containsKey( role );
+
+        if( !exists && null != this.parentManager ) {
+            exists = this.parentManager.hasService( role );
+        }
+
+        return exists;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup( final String role )
+    throws ServiceException {
+        if( !this.initialized ) {
+            if( this.getLogger().isWarnEnabled() ) {
+                this.getLogger().warn(
+                    "Looking up component on an uninitialized CoreServiceManager [" + role + "]" );
+            }
+        }
+
+        if( this.disposed ) {
+            throw new IllegalStateException(
+                "You cannot lookup components on a disposed CoreServiceManager" );
+        }
+
+        if( role == null ) {
+            final String message =
+                "CoreServiceManager attempted to retrieve service with null role.";
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message );
+            }
+            throw new ServiceException( role, message );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get( role );
+
+        // Retrieve the instance of the requested component
+        if ( handler == null ) {
+            if( this.parentManager != null ) {
+                try {
+                    return this.parentManager.lookup( role );
+                } catch ( ServiceNotFoundException snfe) {
+                    // ignore.  If the exception is thrown, we try to
+                    // create the component next
+                } catch( Exception e ) {
+                    if( this.getLogger().isWarnEnabled() ) {
+                        final String message =
+                            "ComponentLocator exception from parent SM during lookup.";
+                        this.getLogger().warn( message, e );
+                    }
+                    // ignore.  If the exception is thrown, we try to
+                    // create the component next
+                }
+            }
+
+            if( this.roleManager != null ) {
+                final ComponentInfo info = this.roleManager.getDefaultServiceInfoForRole( role );
+
+                if( info != null ) {
+                    if( this.getLogger().isDebugEnabled() ) {
+                        this.getLogger().debug( "Could not find ComponentHandler, attempting to create "
+                            + "one for role [" + role + "]" );
+                    }
+
+                    try {
+                        final Configuration configuration = new DefaultConfiguration( "", "-" );
+
+                        handler = this.getComponentHandler(role,
+                                                           info.getServiceClassName(),
+                                                           configuration.getChild(role),
+                                                           info);
+
+                    } catch (ServiceException se) {
+                        throw se;
+                    } catch( final Exception e ) {
+                        final String message = "Could not find component for role [" + role + "]";
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( message, e );
+                        }
+                        throw new ServiceException( role, message, e );
+                    }
+                    try {
+                        handler.initialize();
+                    } catch (ServiceException se) {
+                        throw se;
+                    } catch( final Exception e ) {
+                        final String message = "Could not create component for role [" + role + "]: " + handler.getClass();
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( message, e );
+                        }
+                        throw new ServiceException( role, message, e );
+                    }
+
+                    this.componentHandlers.put( role, handler );
+                }
+            } else {
+                this.getLogger().debug( "Component requested without a RoleManager set.\n"
+                    + "That means setRoleManager() was not called during initialization." );
+            }
+        }
+
+        if( handler == null ) {
+            final String message = "Could not find component for role: [" + role + "]";
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message );
+            }
+            throw new ServiceNotFoundException( role, message );
+        }
+
+        Object component = null;
+
+        try {
+            component = handler.get();
+        } catch ( ServiceException se) {
+            // Rethrow insteand of wrapping it again
+            throw se;
+        } catch( final Exception e ) {
+            final String message = "Could not access the component for role [" + role + "]";
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message, e );
+            }
+
+            throw new ServiceException( role, message, e );
+        }
+        this.initialize( role, component );
+
+        // Add a mapping between the component and its handler.
+        //  In the case of a ThreadSafeComponentHandler, the same component will be mapped
+        //  multiple times but because each put will overwrite the last, this is not a
+        //  problem.  Checking to see if the put has already been done would be slower.
+        this.componentMapping.put( component, handler );
+
+        return component;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release( final Object component ) {
+        if( null == component ) {
+            return;
+        }
+
+        // The componentMapping StaticBucketMap itself is threadsafe, and because the same component
+        //  will never be released by more than one thread, this method does not need any
+        //  synchronization around the access to the map.
+
+        final ComponentHandler handler =
+            (ComponentHandler)this.componentMapping.get( component );
+
+        if ( handler != null ) {
+            // ThreadSafe components will always be using a ThreadSafeComponentHandler,
+            //  they will only have a single entry in the m_componentMapping map which
+            //  should not be removed until the ComponentLocator is disposed.  All
+            //  other components have an entry for each instance which should be
+            //  removed.
+            if( !handler.isSingleton() ) {
+                // Remove the component before calling put.  This is critical to avoid the
+                //  problem where another thread calls put on the same component before
+                //  remove can be called.
+                this.componentMapping.remove( component );
+            }
+
+            try {
+                handler.put( component );
+            } catch( Exception e ) {
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( "Error trying to release component.", e );
+                }
+            }
+        }
+        else if( this.parentManager != null ) {
+            this.parentManager.release( component );
+        } else {
+            this.getLogger().warn( "Attempted to release a " + component.getClass().getName() +
+                              " but its handler could not be located." );
+        }
+    }
+
+    //=============================================================================================
+    // Additional public & protected contract
+    //=============================================================================================
+
+    /**
+     * Add a new component to the manager.
+     *
+     * @param role the role name for the new component.
+     * @param className the class of this component.
+     * @param configuration the configuration for this component.
+     */
+    public void addComponent( String role,
+                              String className,
+                              Configuration configuration,
+                              ComponentInfo info)
+    throws ConfigurationException {
+        if( this.initialized ) {
+            throw new IllegalStateException("Cannot add components to an initialized CoreServiceManager." );
+        }
+
+        // check for old excalibur class names - we only test against the selector
+        // implementation
+        if ( "org.apache.cocoon.components.ExtendedComponentSelector".equals(className)) {
+            className = DefaultServiceSelector.class.getName();
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "Adding component (" + role + " = " + className + ")" );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
+        if (handler != null) {
+            // Check that override is allowed. If yes, the handler will be redefined below, allowing
+            // the new definition to feed this manager with its components.
+            checkComponentOverride(role, className, configuration, handler);
+        }
+
+        try {
+            handler = this.getComponentHandler(role, className, configuration, info);
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "Handler type = " + handler.getClass().getName() );
+            }
+
+            this.componentHandlers.put( role, handler );
+        } catch ( final ConfigurationException ce ) {
+            throw ce;
+        } catch( final Exception e ) {
+            throw new ConfigurationException( "Could not add component defined at " + configuration.getLocation(), e );
+        }
+
+//        // Initialize shadow selector now, it will feed this service manager
+//        if ( DefaultServiceSelector.class.isAssignableFrom( component )) {
+//            try {
+//                handler.initialize();
+//            } catch(ServiceException se) {
+//                throw se;
+//            } catch(Exception e) {
+//                throw new ServiceException(role, "Could not initialize selector", e);
+//            }
+//        }
+    }
+
+    /**
+     * Add an existing object to the manager. The object should be fully configured as no
+     * setup lifecycle methods are called. On manager disposal, the <code>Disposable</code>
+     * method is considered.
+     * 
+     * @param role the role under which the object will be known
+     * @param instance the component instance
+     * @throws ServiceException
+     */
+    public void addInstance(String role, Object instance) throws ServiceException {
+        if( this.initialized ) {
+            throw new ServiceException(role,
+                "Cannot add components to an initialized CoreServiceManager.");
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(role);
+        if (handler != null) {
+            ComponentInfo info = handler.getInfo();
+            throw new ServiceException(role, "Component already defined at " + info.getLocation()); 
+        }
+
+        this.componentHandlers.put(role, new InstanceComponentHandler(getLogger(), instance));
+    }
+
+    /**
+     * Add an alias to a role, i.e. define a synonym for the role.
+     * 
+     * @param existingRole the existing role that will be aliased
+     * @param newRole the new role
+     * @throws ServiceException if the existing role could not be found in the current
+     *         manager and its ancestors
+     */
+    public void addRoleAlias(String existingRole, String newRole) throws ServiceException {
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get(existingRole);
+        if (handler == null) {
+            // Aliased component not found here, but can be defined by an ancestor
+            CoreServiceManager current = this;
+            while(handler == null && current.parentManager != null) {
+                if (!(current.parentManager instanceof CoreServiceManager)) {
+                    throw new ServiceException(newRole, "Cannot alias to components not managed by CoreServiceManager");
+                }
+                current = (CoreServiceManager)current.parentManager;
+                handler = (ComponentHandler)current.componentHandlers.get(existingRole);
+            }
+        }
+
+        if (handler == null) {
+            throw new ServiceException(newRole, "Cannot alias non-existing role " + existingRole);
+        }
+
+        this.componentHandlers.put(newRole, new AliasComponentHandler(this.getLogger(), handler));
+    }
+
+    /**
+     * Initialize the component
+     * @throws ServiceException
+     */
+    protected void initialize(String role, Object component) 
+    throws ServiceException {
+        // we do nothing here, can be used in subclasses
+    }
+
+    //=============================================================================================
+    // Private methods
+    //=============================================================================================
+    
+    /**
+     * Obtain a new ComponentHandler for the specified component. 
+     * 
+     * @param role the component's role.
+     * @param className Class of the component for which the handle is
+     *                       being requested.
+     * @param configuration The configuration for this component.
+     * @param baseInfo The information for managing the component, like service manager etc.
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    private ComponentHandler getComponentHandler( final String role,
+                                                  final String className,
+                                                  final Configuration configuration,
+                                                  final ComponentInfo baseInfo)
+    throws Exception {
+
+        boolean lazyLoad;
+
+        if (configuration.getAttribute("preload", null) != null) {
+            // This one has precedence
+            lazyLoad = configuration.getAttributeAsBoolean("preload");
+
+        } else {
+            lazyLoad = this.settings.isLazyMode();
+
+            if (lazyLoad) {
+                // Check if the class implements Startable or Preloadable
+                Class componentClass;
+                try {
+                    componentClass = componentEnv.loadClass(className);
+                } catch (ClassNotFoundException cnfe) {
+                    throw new Exception("Cannot find class " + className + " for component at " +
+                            configuration.getLocation(), cnfe);
+                }
+                if (Startable.class.isAssignableFrom(componentClass) ||
+                    Preloadable.class.isAssignableFrom(componentClass)) {
+                    lazyLoad = false;
+                }
+            }
+        }
+
+        ComponentHandler handler;
+        if (lazyLoad) {
+            handler = new LazyHandler(role, className, configuration, componentEnv);
+        } else {
+            
+            // FIXME - we should ensure that we always get an info
+            ComponentInfo info;
+            if ( baseInfo != null ) {
+                info = baseInfo.duplicate();
+            } else {
+                info = new ComponentInfo();
+                info.fill(configuration);
+                info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), this));
+                info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), className));
+                info.setRole(role);
+            }
+            info.setConfiguration(configuration);
+            info.setServiceClassName(className);
+
+            handler = AbstractComponentHandler.getComponentHandler(role, this.componentEnv, info);
+            // TODO we probably need to keep the ObjectInstance returnde for setupJmxFor for 
+            //      later deregistering.
+            JMXUtils.setupJmxFor(handler, info, getLogger());
+        }
+        return handler;
+    }
+
+    private void parseConfiguration(final Configuration configuration, String contextURI, Set loadedURIs) 
+        throws ConfigurationException {
+
+        final Configuration[] configurations = configuration.getChildren();
+
+        for( int i = 0; i < configurations.length; i++ ) {
+            final Configuration componentConfig = configurations[i];
+
+            final String componentName = componentConfig.getName();
+
+            if ("include".equals(componentName)) {
+                handleInclude(contextURI, loadedURIs, componentConfig);
+
+            } else {
+                // Component declaration
+                // Find the role
+                String role = componentConfig.getAttribute("role", null);
+                if (role == null) {
+                    // Get the role from the role manager if not explicitely specified
+                    role = roleManager.getRoleForName(componentName);
+                    if (role == null) {
+                        // Unknown role
+                        throw new ConfigurationException("Unknown component type '" + componentName +
+                            "' at " + componentConfig.getLocation());
+                    }
+                }
+
+                // Find the className
+                String className = componentConfig.getAttribute("class", null);
+                if (className == null) {
+                    // Get the default class name for this role
+                    final ComponentInfo info = roleManager.getDefaultServiceInfoForRole(role);
+                    info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), this));
+                    info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), info.getServiceClassName()));
+                    if (info == null) {
+                        throw new ConfigurationException("Cannot find a class for role " + role + " at " + componentConfig.getLocation());
+                    }
+                    className = info.getServiceClassName();
+                }
+
+                // If it has a "name" attribute, add it to the role (similar to the
+                // declaration within a service selector)
+                // Note: this has to be done *after* finding the className above as we change the role
+                String name = componentConfig.getAttribute("name", null);
+                if (name != null) {
+                    role = role + "/" + name;
+                }
+
+                this.addComponent(role, className, componentConfig, null);
+            }
+        }
+    }
+
+    private void handleInclude(String contextURI, Set loadedURIs, Configuration includeStatement)
+            throws ConfigurationException {
+        String includeURI = includeStatement.getAttribute("src", null);
+        String directoryURI = null;
+        if ( includeURI == null ) {
+            // check for directories
+            directoryURI = includeStatement.getAttribute("dir", null);                    
+        }
+        if ( includeURI == null && directoryURI == null ) {
+            throw new ConfigurationException("Include statement must either have a 'src' or 'dir' attribute, at " +
+                    includeStatement.getLocation());
+        }
+
+        // Setup the source resolver if needed
+        setupSourceResolver();
+
+        if ( includeURI != null ) {
+            Source src;
+            try {
+                src = this.cachedSourceResolver.resolveURI(includeURI, contextURI, null);
+            } catch (Exception e) {
+                throw new ConfigurationException("Cannot load '" + includeURI + "' at " + includeStatement.getLocation(), e);
+            }
+            
+            loadURI(src, loadedURIs, includeStatement);
+        } else {
+            final String pattern = includeStatement.getAttribute("pattern", null);
+            int[] parsedPattern = null;
+            if ( pattern != null ) {
+                parsedPattern = WildcardHelper.compilePattern(pattern);
+            }
+            Source directory = null;
+            try {
+                directory = this.cachedSourceResolver.resolveURI(directoryURI, contextURI, CONTEXT_PARAMETERS);
+                if ( directory instanceof TraversableSource ) {
+                    final Iterator children = ((TraversableSource)directory).getChildren().iterator();
+                    while ( children.hasNext() ) {
+                        final Source s = (Source)children.next();
+                        if ( parsedPattern == null || this.match(s.getURI(), parsedPattern)) {
+                            this.loadURI(s, loadedURIs, includeStatement);
+                        }
+                    }
+                } else {
+                    throw new ConfigurationException("Include.dir must point to a directory, '" + directory.getURI() + "' is not a directory.'");
+                }
+            } catch (IOException ioe) {
+                throw new ConfigurationException("Unable to read configurations from " + directoryURI);
+            } finally {
+                this.cachedSourceResolver.release(directory);
+            }
+        }
+    }
+
+    private void loadURI(Source src, Set loadedURIs, Configuration includeStatement) 
+    throws ConfigurationException {
+        // If already loaded: do nothing
+        try {
+
+            String uri = src.getURI();
+
+            if (!loadedURIs.contains(uri)) {
+                if ( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug("Loading configuration from: " + uri);
+                }
+                // load it and store it in the read set
+                Configuration includeConfig = null;
+                try {
+                    ConfigurationBuilder builder = new ConfigurationBuilder(this.settings);
+                    includeConfig = builder.build(src.getInputStream(), uri);
+                } catch (Exception e) {
+                    throw new ConfigurationException("Cannot load '" + uri + "' at " + includeStatement.getLocation(), e);
+                }
+                loadedURIs.add(uri);
+
+                // what is it?
+                String includeKind = includeConfig.getName();
+                if (includeKind.equals("components")) {
+                    // more components
+                    parseConfiguration(includeConfig, uri, loadedURIs);
+                } else if (includeKind.equals("role-list")) {
+                    // more roles
+                    this.roleManager.configure(includeConfig);
+                } else {
+                    throw new ConfigurationException("Unknow document '" + includeKind + "' included at " +
+                            includeStatement.getLocation());
+                }
+            }
+        } finally {
+            this.cachedSourceResolver.release(src);
+        }
+    }
+
+    /**
+     * If the parent manager does not exist or does not
+     * provide a source resolver, a simple one is created here to load the file.
+     */
+    private void setupSourceResolver() {
+        if (this.cachedSourceResolver == null) {
+
+            if (this.parentManager != null && this.parentManager.hasService(SourceResolver.ROLE)) {
+                try {
+                    this.cachedSourceResolver = (SourceResolver)this.parentManager.lookup(SourceResolver.ROLE);
+                } catch(ServiceException se) {
+                    // Unlikely to happen
+                    throw new CoreResourceNotFoundException("Cannot get source resolver from parent, at " + location, se);
+                }
+            } else {
+                // Create our own
+                SimpleSourceResolver simpleSR = new SimpleSourceResolver();
+                simpleSR.enableLogging(getLogger());
+                try {
+                    simpleSR.contextualize(this.context);
+                } catch (ContextException ce) {
+                    throw new CoreResourceNotFoundException("Cannot setup source resolver, at " + location, ce);
+                }
+                this.cachedSourceResolver = simpleSR;
+            }
+        }        
+    }
+
+    private boolean match(String uri, int[] parsedPattern ) {
+        int pos = uri.lastIndexOf('/');
+        if ( pos != -1 ) {
+            uri = uri.substring(pos+1);
+        }
+        return WildcardHelper.match(null, uri, parsedPattern);      
+    }
+
+    /**
+     * Release the source resolver that may have been created by the first call to
+     * loadConfiguration().
+     */
+    private void releaseCachedSourceResolver() {
+        if (this.cachedSourceResolver != null &&
+            this.parentManager != null && this.parentManager.hasService(SourceResolver.ROLE)) {
+            this.parentManager.release(this.cachedSourceResolver);
+        }
+        this.cachedSourceResolver = null;
+    }
+
+    /** 
+     * Check if a component can be overriden. Only {@link DefaultServiceSelector} or its subclasses can be
+     * overriden, as they directly feed this manager with their component definitions and are empty
+     * shells delegating to this manager afterwards.
+     */
+    private void checkComponentOverride(String role, String className, Configuration config,
+            ComponentHandler existingHandler) throws ConfigurationException {
+        
+        // We only allow selectors to be overloaded
+        ComponentInfo info = existingHandler.getInfo();
+        if (!className.equals(info.getServiceClassName())) {
+            throw new ConfigurationException("Role " + role + " redefined with a different class name, at " +
+                    config.getLocation());
+        }
+
+        Class clazz;
+        try {
+            clazz = this.componentEnv.loadClass(className);
+        } catch(ClassNotFoundException cnfe) {
+            throw new ConfigurationException("Cannot load class " + className + " for component at " +
+                    config.getLocation(), cnfe);
+        }
+
+        if (!DefaultServiceSelector.class.isAssignableFrom(clazz)) {
+            throw new ConfigurationException("Component declared at " + info.getLocation() + " is redefined at " +
+                    config.getLocation());
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/DefaultServiceSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/DefaultServiceSelector.java
new file mode 100644
index 0000000..7b25fd5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/DefaultServiceSelector.java
@@ -0,0 +1,220 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.Preloadable;
+
+/**
+ * Default component selector for Cocoon's components. This selector "flattens" its declaration
+ * by adding them as components of its containing ServiceManager. This allows a smooth transition towards
+ * a fully flat configuration by allowing the use of selectors in legacy components and also
+ * declaration of hinted components (i.e. with a role of type "rolename/hint") in the service manager.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class DefaultServiceSelector extends AbstractLogEnabled implements ThreadSafe, Preloadable, Serviceable, Configurable, ServiceSelector {
+
+    /** Synthetic hint to alias the default component */
+    public static final String DEFAULT_HINT = "$default$";
+
+    private CoreServiceManager manager;
+    private RoleManager roleManager;
+    private String roleName;
+    private String rolePrefix;
+    
+    public void service(ServiceManager manager) throws ServiceException {
+        try {
+            this.manager = (CoreServiceManager)manager;
+        } catch (ClassCastException cce) {
+            throw new ServiceException ("DefaultServiceSelector", 
+                                        "A DefaultServiceSelector can only be hosted by a CoreServiceManager");
+        }
+    }
+    
+    public void setRole(String role) {
+        this.roleName = role;
+    }
+    
+    public void setRoleManager(RoleManager roles) {
+        this.roleManager = roles;
+    }
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        if (roleName == null) {
+            throw new ConfigurationException("No role given for DefaultServiceSelector at " + config.getLocation());
+        }
+        
+        // Remove "Selector" suffix, if any and add a trailing "/"
+        if (roleName.endsWith("Selector")) {
+            this.rolePrefix = roleName.substring(0, roleName.length() - 8) + "/";
+        } else {
+            this.rolePrefix = roleName + "/";
+        }
+
+        // Add components
+        String compInstanceName = getComponentInstanceName();
+
+        Configuration[] instances = config.getChildren();
+
+        for (int i = 0; i < instances.length; i++) {
+
+            Configuration instance = instances[i];
+            ComponentInfo info = null;
+
+            String key = instance.getAttribute("name");
+
+            String classAttr = instance.getAttribute(getClassAttributeName(), null);
+            String className;
+
+            if (compInstanceName == null) {
+                // component-instance implicitly defined by the presence of the 'class' attribute
+                if (classAttr == null) {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                } else {
+                    className = classAttr;
+                }
+
+            } else {
+                // component-instances names explicitly defined
+                if (compInstanceName.equals(instance.getName())) {
+                    className = (classAttr == null) ? null : classAttr;
+                } else {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                }
+            }
+
+            if (className == null) {
+                String message = "Unable to determine class name for component named '" + key +
+                    "' at " + instance.getLocation();
+
+                getLogger().error(message);
+                throw new ConfigurationException(message);
+            }
+            
+            // Add this component in the manager
+            this.manager.addComponent(this.rolePrefix + key, className, instance, info);
+        }
+        
+        // Register default key, if any
+        String defaultKey = config.getAttribute(this.getDefaultKeyAttributeName(), null);
+        if (defaultKey != null) {
+            try {
+                this.manager.addRoleAlias(this.rolePrefix + defaultKey, this.rolePrefix + DEFAULT_HINT);
+            } catch (ServiceException e) {
+                throw new ConfigurationException("Cannot set default to " + defaultKey + " at " + config.getLocation(), e);
+            }
+        }
+    }
+    
+    public Object select(Object hint) throws ServiceException {
+        String key = (hint == null) ? DEFAULT_HINT : hint.toString();
+
+        return this.manager.lookup(this.rolePrefix + key);
+    }
+
+    public boolean isSelectable(Object hint) {
+        String key = hint == null ? DEFAULT_HINT : hint.toString();
+        
+        return key != null && this.manager.hasService(this.rolePrefix + key);
+    }
+
+    public void release(Object obj) {
+        this.manager.release(obj);
+    }
+
+    // ---------------------------------------------------------------
+    /**
+     * Get the name for component-instance elements (i.e. components not defined
+     * by their role shortcut. If <code>null</code>, any element having a 'class'
+     * attribute will be considered as a component instance.
+     * <p>
+     * The default here is to return <code>null</code>, and subclasses can redefine
+     * this method to return particular values.
+     *
+     * @return <code>null</code>, but can be changed by subclasses
+     */
+    protected String getComponentInstanceName() {
+        return null;
+    }
+
+    /**
+     * Get the name of the attribute giving the class name of a component.
+     * The default here is "class", but this can be overriden in subclasses.
+     *
+     * @return "<code>class</code>", but can be changed by subclasses
+     */
+    protected String getClassAttributeName() {
+        return "class";
+    }
+
+    /**
+     * Get the name of the attribute giving the default key to use if
+     * none is given. The default here is "default", but this can be
+     * overriden in subclasses. If this method returns <code>null</code>,
+     * no default key can be specified.
+     *
+     * @return "<code>default</code>", but can be changed by subclasses
+     */
+    protected String getDefaultKeyAttributeName() {
+        return "default";
+    }
+    
+    /**
+     * A special factory for <code>DefaultServiceSelector</code>, that passes it the
+     * <code>RoleManager</code> and its role name.
+     */
+    public static class Factory extends ComponentFactory {
+        private final String role;
+        
+        public Factory(ComponentEnvironment env, ComponentInfo info, String role) 
+        throws Exception {
+            super(env, info);
+            this.role = role;
+        }
+        
+        protected void setupInstance(Object object)
+        throws Exception {
+            DefaultServiceSelector component = (DefaultServiceSelector)object;
+            
+            ContainerUtil.enableLogging(component, this.environment.logger);
+            ContainerUtil.contextualize(component, this.environment.context);
+            ContainerUtil.service(component, this.environment.serviceManager);
+            
+            component.setRoleManager(this.environment.roleManager);
+            component.setRole(this.role);
+            
+            ContainerUtil.configure(component, this.serviceInfo.getConfiguration());
+            ContainerUtil.initialize(component);
+            ContainerUtil.start(component);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/RoleManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/RoleManager.java
new file mode 100644
index 0000000..d928d46
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/RoleManager.java
@@ -0,0 +1,252 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.components.ComponentInfo;
+
+/**
+ * Default RoleManager implementation.  It populates the RoleManager
+ * from a configuration file.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class RoleManager
+extends AbstractLogEnabled
+implements Configurable {
+    
+    /** Map for shorthand to role mapping */
+    private final Map shorthands = new HashMap();
+
+    /** Map for role to default classname mapping */
+    private final Map classNames = new HashMap();
+
+    /** Map for role->key to classname mapping */
+    private final Map keyClassNames = new HashMap();
+
+    /** Parent role manager for nested resolution */
+    private final RoleManager parent;
+
+    /**
+     * Default constructor--this RoleManager has no parent.
+     */
+    public RoleManager() {
+        this.parent = null;
+    }
+
+    /**
+     * Alternate constructor--this RoleManager has the specified
+     * parent.
+     *
+     * @param parent  The parent <code>RoleManager</code>.
+     */
+    public RoleManager( RoleManager parent ) {
+        this.parent = parent;
+    }
+
+    /**
+     * Retrieves the real role name from a shorthand name.  Usually
+     * the shorthand name refers to a configuration element name.  If
+     * this RoleManager does not have the match, and there is a parent
+     * RoleManager, the parent will be asked to resolve the role.
+     *
+     * @param shorthandName  The shortname that is an alias for the role.
+     * @return the official role name.
+     */
+    public final String getRoleForName( final String shorthandName ) {
+        final String role = (String)this.shorthands.get( shorthandName );
+
+        if( null == role && null != this.parent ) {
+            return this.parent.getRoleForName( shorthandName );
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up shorthand " + shorthandName +
+                               ", returning " + role );
+        }
+
+        return role;
+    }
+
+    /**
+     * Retrieves the default class name for the specified role.  This
+     * is only called when the configuration does not specify the
+     * class explicitly.  If this RoleManager does not have the match,
+     * and there is a parent RoleManager, the parent will be asked
+     * to resolve the class name.
+     *
+     * @param role  The role that has a default implementation.
+     * @return the Fully Qualified Class Name (FQCN) for the role.
+     */
+    public final ComponentInfo getDefaultServiceInfoForRole( final String role ) {
+        final ComponentInfo info = (ComponentInfo)this.classNames.get( role );
+
+        if( info == null && this.parent != null ) {
+            return this.parent.getDefaultServiceInfoForRole( role );
+        }
+
+        return info;
+    }
+
+    /**
+     * Retrieves a default class name for a role/key combination.
+     * This is only called when a role is mapped to a
+     * StandaloneServiceSelector, and the configuration elements use
+     * shorthand names for the type of component.  If this RoleManager
+     * does not have the match, and there is a parent RoleManager, the
+     * parent will be asked to resolve the class name.
+     *
+     * @param role  The role that this shorthand refers to.
+     * @param shorthand  The shorthand name for the type of component
+     * @return the FQCN for the role/key combination.
+     */
+    public final ComponentInfo getDefaultServiceInfoForKey( final String role,
+                                                          final String shorthand ) {
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up keymap for role " + role );
+        }
+
+        final Map keyMap = (Map)this.keyClassNames.get( role );
+
+        if( null == keyMap ) {
+            if( null != this.parent ) {
+                return this.parent.getDefaultServiceInfoForKey( role, shorthand );
+            } 
+            return null;
+        }
+
+        if( this.getLogger().isDebugEnabled() ) {
+            this.getLogger().debug( "looking up classname for key " + shorthand );
+        }
+
+        final ComponentInfo s = ( ComponentInfo ) keyMap.get( shorthand );
+
+        if( s == null && this.parent != null ) {
+            return this.parent.getDefaultServiceInfoForKey( role, shorthand );
+        } 
+        return s;
+    }
+
+    /**
+     * Reads a configuration object and creates the role, shorthand,
+     * and class name mapping.
+     *
+     * @param configuration  The configuration object.
+     * @throws ConfigurationException if the configuration is malformed
+     */
+    public final void configure( final Configuration configuration )
+    throws ConfigurationException {
+        
+        // When reading a roles file, we only want "role" elements.
+        boolean strictMode = "roles-list".equals(configuration.getName());
+
+        final Configuration[] roles = configuration.getChildren();
+
+        for( int i = 0; i < roles.length; i++ ) {
+            Configuration role = roles[i];
+            
+            if (!"role".equals(role.getName())) {
+                if (strictMode) {
+                    throw new ConfigurationException("Unexpected '" + role.getName() + "' element at " + role.getLocation());
+                }
+                // Skip to next one
+                continue;
+            }
+            
+            final String roleName = role.getAttribute("name");
+            final String shorthand = role.getAttribute("shorthand", null);
+            final String defaultClassName = role.getAttribute("default-class", null);
+
+            if (shorthand != null) {
+                // Store the shorthand and check that its consistent with any previous one
+                Object previous = this.shorthands.put( shorthand, roleName );
+                if (previous != null && !previous.equals(roleName)) {
+                    throw new ConfigurationException("Shorthand '" + shorthand + "' already used for role " +
+                            previous + ": inconsistent declaration at " + role.getLocation());
+                }
+            }
+
+            if( defaultClassName != null ) {
+                ComponentInfo info = (ComponentInfo)this.classNames.get(roleName);
+                if (info == null) {
+                    // Create a new info and store it
+                    info = new ComponentInfo();
+                    info.setServiceClassName(defaultClassName);
+                    info.fill(role);
+                    info.setRole(roleName);
+                    this.classNames.put(roleName, info);
+                } else {
+                    // Check that it's consistent with the existing info
+                    if (!defaultClassName.equals(info.getServiceClassName())) {
+                        throw new ConfigurationException("Invalid redeclaration: default class already set to " + info.getServiceClassName() +
+                                " for role " + roleName + " at " + role.getLocation());
+                    }
+                    //FIXME: should check also other ServiceInfo members
+                }
+            }
+
+            final Configuration[] keys = role.getChildren( "hint" );
+            if( keys.length > 0 ) {
+                Map keyMap = (Map)this.keyClassNames.get(roleName);
+                if (keyMap == null) {
+                    keyMap = new HashMap();
+                    this.keyClassNames.put(roleName, keyMap);
+                }
+
+                for( int j = 0; j < keys.length; j++ ) {
+                    Configuration key = keys[j];
+                    
+                    final String shortHand = key.getAttribute( "shorthand" ).trim();
+                    final String className = key.getAttribute( "class" ).trim();
+
+                    ComponentInfo info = (ComponentInfo)keyMap.get(shortHand);
+                    if (info == null) {       
+                        info = new ComponentInfo();
+                        info.setServiceClassName(className);
+                        info.fill(key);
+    
+                        keyMap.put( shortHand, info );
+                        if( this.getLogger().isDebugEnabled() ) {
+                            this.getLogger().debug( "Adding key type " + shortHand +
+                                                    " associated with role " + roleName +
+                                                    " and class " + className );
+                        }
+                    } else {
+                        // Check that it's consistent with the existing info
+                        if (!className.equals(info.getServiceClassName())) {
+                            throw new ConfigurationException("Invalid redeclaration: class already set to " + info.getServiceClassName() +
+                                    " for hint " + shortHand + " at " + key.getLocation());
+                        }
+                        //FIXME: should check also other ServiceInfo members
+                    }
+                }
+            }
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "added Role " + roleName + " with shorthand " +
+                                   shorthand + " for " + defaultClassName );
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ServiceNotFoundException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ServiceNotFoundException.java
new file mode 100644
index 0000000..e9dbfb0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/ServiceNotFoundException.java
@@ -0,0 +1,35 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import org.apache.avalon.framework.service.ServiceException;
+
+/**
+ * This exception indicates the a services manager was not able to find a component.
+ * @since 2.2
+ * @version $Id$
+ */
+public class ServiceNotFoundException extends ServiceException {
+
+    public ServiceNotFoundException(String arg0, String arg1, Throwable arg2) {
+        super(arg0, arg1, arg2);
+    }
+
+    public ServiceNotFoundException(String arg0, String arg1) {
+        super(arg0, arg1);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/SingleComponentServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/SingleComponentServiceManager.java
new file mode 100644
index 0000000..2748d49
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/SingleComponentServiceManager.java
@@ -0,0 +1,86 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * This is a simple service manager implementation that just serves one
+ * single component.
+ * @since 2.2
+ * @version $Id$
+ */
+public final class SingleComponentServiceManager
+implements ServiceManager, Disposable {
+
+    protected final ServiceManager parent;
+    protected final Object component;
+    protected final String role;
+
+    public SingleComponentServiceManager(ServiceManager parent,
+                                         Object         component,
+                                         String         role) {
+        this.parent = parent;
+        this.component = component;
+        this.role = role;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService(String key) {
+        if ( this.role.equals(key) ) {
+            return true;
+        }
+        if ( this.parent != null ) {
+            return this.parent.hasService(key);
+        }
+        return false;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup(String key) throws ServiceException {
+        if ( this.role.equals(key) ) {
+            return this.component;
+        }
+        if ( this.parent != null ) {
+            return this.parent.lookup(key);
+        }
+        throw new ServiceException("Cocoon", "Component for key '" + key + "' not found.");
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        if ( component != this.component && parent != null ) {
+            this.parent.release(component);
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        ContainerUtil.dispose(this.parent);
+    }
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java
new file mode 100644
index 0000000..bef2957
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/StandaloneServiceSelector.java
@@ -0,0 +1,639 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.components.Preloadable;
+import org.apache.cocoon.core.container.handler.AbstractComponentHandler;
+import org.apache.cocoon.core.container.handler.ComponentHandler;
+import org.apache.cocoon.util.JMXUtils;
+
+/**
+ * Default component selector for Cocoon's components.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class StandaloneServiceSelector
+    extends AbstractLogEnabled
+    implements Preloadable,
+               ServiceSelector,
+               Serviceable,
+               Configurable,
+               Disposable,
+               Initializable,
+               Contextualizable {
+
+    /** The application context for components
+     */
+    protected ServiceManager serviceManager;
+
+    /** The parent selector, if any */
+    protected StandaloneServiceSelector parentSelector;
+
+    /** The parent locator, if any */
+    protected ServiceManager parentLocator;
+
+    /** The role of this selector. Set in <code>configure()</code>. */
+    protected String roleName;
+
+    /** The default key */
+    protected String defaultKey;
+
+    /** The application context for components */
+    protected Context context;
+
+    /** Static component mapping handlers. */
+    protected final Map componentMapping = Collections.synchronizedMap(new HashMap());
+
+    /** Used to map roles to ComponentHandlers. */
+    protected final Map componentHandlers = Collections.synchronizedMap(new HashMap());
+
+    /** Is the Manager disposed or not? */
+    protected boolean disposed;
+
+    /** Is the Manager initialized? */
+    protected boolean initialized;
+
+    /** RoleInfos. */
+    protected RoleManager roleManager;
+
+    /** LoggerManager. */
+    protected LoggerManager loggerManager;
+
+    protected ComponentEnvironment componentEnv;
+
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize( final Context context ) {
+        this.context = context;
+    }
+
+    public void setRoleManager( final RoleManager roles ) {
+        this.roleManager = roles;
+    }
+
+    /**
+     * Configure the LoggerManager.
+     */
+    public void setLoggerManager( final LoggerManager manager ) {
+        this.loggerManager = manager;
+    }
+
+    /**
+     * Obtain a new ComponentHandler for the specified component. 
+     * 
+     * @param role the component's role.
+     * @param componentClass Class of the component for which the handle is
+     *                       being requested.
+     * @param configuration The configuration for this component.
+     * @param serviceManager The service manager which will be managing the Component.
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    protected ComponentHandler getComponentHandler( final String role,
+                                                    final Class componentClass,
+                                                    final Configuration configuration,
+                                                    final ServiceManager serviceManager,
+                                                    final ComponentInfo  baseInfo)
+    throws Exception {
+        if (this.componentEnv == null) {
+            this.componentEnv = new ComponentEnvironment(null, getLogger(), this.roleManager,
+                    this.loggerManager, this.context, serviceManager);
+        }
+        // FIXME - we should always get an info here
+        ComponentInfo info;
+        if ( baseInfo != null ) {
+            info = baseInfo.duplicate();
+        } else {
+            info = new ComponentInfo();
+            info.fill(configuration);
+            info.setRole(role);
+            info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), serviceManager));
+            info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), componentClass.getName()));
+        }
+        info.setConfiguration(configuration);
+        info.setServiceClassName(componentClass.getName());
+
+        return AbstractComponentHandler.getComponentHandler(role,
+                                                     this.componentEnv,
+                                                     info);
+    }
+
+    protected void addComponent(String className,
+                                String role,
+                                Configuration configuration,
+                                ComponentInfo info) 
+    throws ConfigurationException {
+        // check for old excalibur class names - we only test against the selector
+        // implementation
+        if ( "org.apache.cocoon.components.ExtendedComponentSelector".equals(className)) {
+            className = DefaultServiceSelector.class.getName();
+        }
+
+        try {
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( "Adding component (" + role + " = " + className + ")" );
+            }
+            // FIXME - use different classloader
+            final Class clazz = this.getClass().getClassLoader().loadClass( className );
+            this.addComponent( role, clazz, configuration, info );
+        } catch( final ClassNotFoundException cnfe ) {
+            final String message = "Could not get class (" + className + ") for role "
+                                 + role + " at " + configuration.getLocation();
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, cnfe );
+            }
+
+            throw new ConfigurationException( message, cnfe );
+        } catch( final ServiceException ce ) {
+            final String message = "Cannot setup class "+ className + " for role " + role
+                                 + " at " + configuration.getLocation();
+
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, ce );
+            }
+
+            throw new ConfigurationException( message, ce );
+        } catch( final Exception e ) {
+            final String message = "Unexpected exception when setting up role " + role + " at " + configuration.getLocation();
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, e );
+            }
+            throw new ConfigurationException( message, e );
+        }        
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceSelector#select(java.lang.Object)
+     */
+    public Object select( Object hint )
+    throws ServiceException {
+        final String key;
+        if (hint == null) {
+            key = this.defaultKey;
+        } else {
+            key = hint.toString();
+        }
+
+        if( !this.initialized ) {
+            if( this.getLogger().isWarnEnabled() ) {
+                this.getLogger().warn( "Selecting a component on an uninitialized service selector "
+                    + "with key [" + key + "]" );
+            }
+        }
+
+        if( this.disposed ) {
+            throw new IllegalStateException(
+                "You cannot select a component from a disposed service selector." );
+        }
+
+        ComponentHandler handler = (ComponentHandler)this.componentHandlers.get( key );
+
+        // Retrieve the instance of the requested component
+        if( null == handler ) {
+            // Doesn't exist here : try in parent selector
+            if ( this.parentSelector != null ) {
+                return this.parentSelector.select(key);                
+            }
+            final String message = this.roleName
+                + ": service selector could not find the component for key [" + key + "]";
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message );
+            }
+            throw new ServiceException( key, message );
+        }
+
+        Object component = null;
+
+        try {
+            component = handler.get();
+        } catch( final ServiceException ce ) {
+            //rethrow
+            throw ce;
+        } catch( final Exception e ) {
+            final String message = this.roleName
+                + ": service selector could not access the component for key [" + key + "]";
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug( message, e );
+            }
+            throw new ServiceException( key, message, e );
+        }
+
+        if( null == component ) {
+            // Doesn't exist here : try in parent selector
+            if ( this.parentSelector != null ) {
+                component = this.parentSelector.select(key);
+            } else {
+                final String message = this.roleName
+                    + ": service selector could not find the component for key [" + key + "]";
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( message );
+                }
+                throw new ServiceException( key, message );
+            }
+        }
+
+        this.componentMapping.put( component, handler );
+        return component;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceSelector#isSelectable(java.lang.Object)
+     */
+    public boolean isSelectable( Object hint ) {
+        final String key;
+        if (hint == null) {
+            key = this.defaultKey;
+        } else {
+            key = hint.toString();
+        }
+
+        if( !this.initialized ) return false;
+        if( this.disposed ) return false;
+
+        boolean exists = false;
+
+        try {
+            ComponentHandler handler = (ComponentHandler)this.componentHandlers.get( key );
+            exists = (handler != null);
+        } catch( Throwable t ) {
+            // We can safely ignore all exceptions
+        }
+
+        if ( !exists && this.parentSelector != null ) {
+            exists = this.parentSelector.isSelectable( key );
+        }
+        return exists;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceSelector#release(java.lang.Object)
+     */
+    public void release( final Object component ) {
+        if( null == component ) {
+            return;
+        }
+
+        // Was it selected on the parent ?
+        if ( this.parentSelector != null &&
+             this.parentSelector.canRelease(component) ) {
+            this.parentSelector.release(component);
+
+        } else {
+            final ComponentHandler handler =
+                (ComponentHandler)this.componentMapping.get( component );
+
+            if( null == handler ) {
+                this.getLogger().warn( "Attempted to release a " + component.getClass().getName()
+                    + " but its handler could not be located." );
+                return;
+            }
+
+            // ThreadSafe components will always be using a ThreadSafeComponentHandler,
+            //  they will only have a single entry in the m_componentMapping map which
+            //  should not be removed until the ComponentLocator is disposed.  All
+            //  other components have an entry for each instance which should be
+            //  removed.
+            if( !handler.isSingleton() ) {
+                // Remove the component before calling put.  This is critical to avoid the
+                //  problem where another thread calls put on the same component before
+                //  remove can be called.
+                this.componentMapping.remove( component );
+            }
+
+            try {
+                handler.put( component );
+            } catch( Exception e ) {
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( "Error trying to release component", e );
+                }
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service( final ServiceManager componentManager )
+    throws ServiceException {
+        this.serviceManager = componentManager;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure( final Configuration config )
+    throws ConfigurationException {
+        this.roleName = getRoleName(config);
+
+        // Get default key
+        this.defaultKey = config.getAttribute(this.getDefaultKeyAttributeName(), null);
+
+        // Add components
+        String compInstanceName = getComponentInstanceName();
+
+        Configuration[] instances = config.getChildren();
+
+        for (int i = 0; i < instances.length; i++) {
+
+            Configuration instance = instances[i];
+            ComponentInfo info = null;
+
+            String key = instance.getAttribute("name").trim();
+
+            String classAttr = instance.getAttribute(getClassAttributeName(), null);
+            String className;
+
+            if (compInstanceName == null) {
+                // component-instance implicitly defined by the presence of the 'class' attribute
+                if (classAttr == null) {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                } else {
+                    className = classAttr.trim();
+                }
+
+            } else {
+                // component-instances names explicitly defined
+                if (compInstanceName.equals(instance.getName())) {
+                    className = (classAttr == null) ? null : classAttr.trim();
+                } else {
+                    info = this.roleManager.getDefaultServiceInfoForKey(roleName, instance.getName());
+                    className = info.getServiceClassName();
+                }
+            }
+
+            if (className == null) {
+                String message = "Unable to determine class name for component named '" + key +
+                    "' at " + instance.getLocation();
+
+                getLogger().error(message);
+                throw new ConfigurationException(message);
+            }
+
+            this.addComponent( className, key, instance, info );
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() 
+    throws Exception {
+        this.initialized = true;
+
+        List keys = new ArrayList( this.componentHandlers.keySet() );
+
+        for( int i = 0; i < keys.size(); i++ ) {
+            final Object key = keys.get( i );
+            final ComponentHandler handler =
+                (ComponentHandler)this.componentHandlers.get( key );
+
+            try {
+                handler.initialize();
+            } catch( Exception e ) {
+                if( this.getLogger().isDebugEnabled() ) {
+                    this.getLogger().debug( "Caught an exception trying to initialize "
+                        + "of the component handler.", e );
+                }
+            }
+
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        Iterator keys = this.componentHandlers.keySet().iterator();
+        List keyList = new ArrayList();
+
+        while( keys.hasNext() ) {
+            Object key = keys.next();
+            ComponentHandler handler =
+                (ComponentHandler)this.componentHandlers.get( key );
+
+            handler.dispose();
+
+            keyList.add( key );
+        }
+
+        keys = keyList.iterator();
+
+        while( keys.hasNext() ) {
+            this.componentHandlers.remove( keys.next() );
+        }
+
+        keyList.clear();
+
+        if ( this.parentLocator != null ) {
+            this.parentLocator.release( this.parentSelector );
+            this.parentLocator = null;
+            this.parentSelector = null;
+        }
+
+        this.disposed = true;
+    }
+
+    /** Add a new component to the manager.
+     * @param key the key for the new component.
+     * @param component the class of this component.
+     * @param configuration the configuration for this component.
+     */
+    public void addComponent( final String key,
+                              final Class component,
+                              final Configuration configuration,
+                              final ComponentInfo info)
+    throws ServiceException {
+        if( this.initialized ) {
+            throw new ServiceException( key,
+                "Cannot add components to an initialized service selector" );
+        }
+
+        try {
+            final ComponentHandler handler = getComponentHandler( null,
+                                                                  component,
+                                                                  configuration,
+                                                                  this.serviceManager,
+                                                                  info);
+
+            handler.initialize();
+            this.componentHandlers.put( key, handler );
+
+            if( this.getLogger().isDebugEnabled() ) {
+                this.getLogger().debug(
+                    "Adding " + component.getName() + " for key [" + key + "]" );
+            }
+        } catch (ServiceException se) {
+            throw se;
+        } catch( final Exception e ) {
+            final String message =
+                "Could not set up component for key [ " + key + "]";
+            if( this.getLogger().isErrorEnabled() ) {
+                this.getLogger().error( message, e );
+            }
+
+            throw new ServiceException(key, message, e );
+        }
+    }
+
+    /**
+     * Get the name for component-instance elements (i.e. components not defined
+     * by their role shortcut. If <code>null</code>, any element having a 'class'
+     * attribute will be considered as a component instance.
+     * <p>
+     * The default here is to return <code>null</code>, and subclasses can redefine
+     * this method to return particular values.
+     *
+     * @return <code>null</code>, but can be changed by subclasses
+     */
+    protected String getComponentInstanceName() {
+        return null;
+    }
+
+    /**
+     * Get the name of the attribute giving the class name of a component.
+     * The default here is "class", but this can be overriden in subclasses.
+     *
+     * @return "<code>class</code>", but can be changed by subclasses
+     */
+    protected String getClassAttributeName() {
+        return "class";
+    }
+
+    /**
+     * Get the name of the attribute giving the default key to use if
+     * none is given. The default here is "default", but this can be
+     * overriden in subclasses. If this method returns <code>null</code>,
+     * no default key can be specified.
+     *
+     * @return "<code>default</code>", but can be changed by subclasses
+     */
+    protected String getDefaultKeyAttributeName() {
+        return "default";
+    }
+
+    /**
+     * Get the role name for this selector. This is called by <code>configure()</code>
+     * to set the value of <code>this.roleName</code>.
+     *
+     * @return the role name, or <code>null<code> if it couldn't be determined.
+     */
+    protected String getRoleName(Configuration config) {
+        // Get the role for this selector
+        String name = config.getAttribute("role", null);
+        if (name == null && this.roleManager != null) {
+            name = this.roleManager.getRoleForName(config.getName());
+        }
+
+        return name;
+    }
+
+    /**
+     * Set the ComponentLocatorImpl that allows access to a possible
+     * parent of this selector
+     * @param locator
+     * @throws ServiceException
+     */
+    void setParentLocator(ServiceManager locator, String role)
+    throws ServiceException {
+        if (this.parentSelector != null) {
+            throw new ServiceException(null, "Parent selector is already set");
+        }
+        this.parentLocator = locator;
+
+        if (locator != null && locator.hasService(role)) {
+            // Get the parent, unwrapping it as far as needed
+            Object parent = locator.lookup(role);
+            
+            if (parent instanceof StandaloneServiceSelector) {
+                this.parentSelector = (StandaloneServiceSelector)parent;
+            } else {
+                throw new IllegalArgumentException("Parent selector is not an extended component selector (" + parent + ")");
+            }
+        }
+    }
+
+    protected boolean canRelease(Object component) {
+        if ( this.parentSelector != null &&
+             this.parentSelector.canRelease(component) ) {
+            return true;
+        }
+        return this.componentMapping.containsKey( component );
+    }
+
+    /**
+     * A special factory that sets the RoleManager and LoggerManager after service()
+     */
+    public static class Factory extends ComponentFactory {
+
+        private final String role;
+
+        public Factory(ComponentEnvironment env, ComponentInfo info, String role) 
+        throws Exception {
+            super(env, info);
+            this.role = role;
+        }
+
+        protected void setupObject(Object obj)
+        throws Exception {
+            final StandaloneServiceSelector component = (StandaloneServiceSelector)obj;
+
+            ContainerUtil.enableLogging(component, this.environment.logger);
+            ContainerUtil.contextualize(component, this.environment.context);
+            ContainerUtil.service(component, this.environment.serviceManager);
+
+            component.setLoggerManager(this.environment.loggerManager);
+            component.setRoleManager(this.environment.roleManager);
+
+            ServiceManager manager = this.environment.serviceManager;
+            if (manager instanceof CoreServiceManager) {
+                // Can it be something else?
+                component.setParentLocator( ((CoreServiceManager)manager).parentManager, this.role);
+            }
+
+            ContainerUtil.configure(component, this.serviceInfo.getConfiguration());
+            ContainerUtil.initialize(component);
+            ContainerUtil.start(component);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractComponentHandler.java
new file mode 100644
index 0000000..a5b5322
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractComponentHandler.java
@@ -0,0 +1,297 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.excalibur.pool.Poolable;
+import org.apache.avalon.framework.component.Composable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.SingleThreaded;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.ComponentEnvironment;
+import org.apache.cocoon.core.container.ComponentFactory;
+import org.apache.cocoon.core.container.DefaultServiceSelector;
+import org.apache.cocoon.core.container.StandaloneServiceSelector;
+import org.apache.cocoon.util.JMXUtils;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public abstract class AbstractComponentHandler 
+implements ComponentHandler {
+    
+    private final Object referenceSemaphore = new Object();
+    private int references = 0;
+
+    protected final Logger logger;
+    
+    /** State management boolean stating whether the Handler is disposed or not */
+    protected boolean disposed = false;
+
+    /** State management boolean stating whether the Handler is initialized or not */
+    private boolean initialized = false;
+    
+    /** Information about the component */
+    private ComponentInfo info;
+    
+    /**
+     * Looks up and returns a component handler for a given component class.
+     *
+     * @param role the component's role. Can be <code>null</code> if the role isn't known.
+     * @param componentEnv The component's creation environment.
+     * @param info          The description of the component (configuration, lifecycle etc.)
+     *
+     * @throws Exception If there were any problems obtaining a ComponentHandler
+     */
+    public static ComponentHandler getComponentHandler(String role, 
+                                                       ComponentEnvironment componentEnv,
+                                                       ComponentInfo info) 
+    throws Exception {
+        
+       // Load the class
+        Class componentClass;
+        
+        try {
+            componentClass = componentEnv.loadClass(info.getServiceClassName());
+        } catch (ClassNotFoundException cnfe) {
+            throw new Exception("Cannot find class " + info.getServiceClassName() + " for component at " +
+                    info.getConfiguration().getLocation(), cnfe);
+        }
+
+        int numInterfaces = 0;
+
+        // Early check for Composable
+        if ( Composable.class.isAssignableFrom( componentClass ) ) {
+            throw new Exception("Interface Composable is not supported anymore. Please change class "
+                                + componentClass.getName() + " to use Serviceable instead.");
+        }
+
+        if( SingleThreaded.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            info.setModel(ComponentInfo.MODEL_PRIMITIVE);
+        }
+
+        if( ThreadSafe.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            info.setModel(ComponentInfo.MODEL_SINGLETON);
+        }
+
+        if( Poolable.class.isAssignableFrom( componentClass ) ) {
+            numInterfaces++;
+            if ( info.getModel() != ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED ) {
+                info.setModel(ComponentInfo.MODEL_POOLED);
+                if ( ComponentInfo.TYPE_NON_THREAD_SAFE_POOLED.equals(info.getConfiguration().getAttribute("model", null))) {
+                    info.setModel(ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED);
+                }
+            }
+        }
+
+        if( numInterfaces > 1 ) {
+            throw new Exception( "[CONFLICT] More than one lifecycle interface in "
+                                 + componentClass.getName() + "  May implement no more than one of "
+                                 + "SingleThreaded, ThreadSafe, or Poolable" );
+        }
+
+        if ( numInterfaces == 0 ) {
+            // this component does not use avalon interfaces, so get the info from the configuration
+            info.fill(info.getConfiguration());
+        }
+        info.setRole(role);
+        
+        // Create the factory to use to create the instances of the Component.
+        ComponentFactory factory;
+        ComponentHandler handler;
+                
+        if (DefaultServiceSelector.class.isAssignableFrom(componentClass)) {
+            // Special factory for DefaultServiceSelector
+            factory = new DefaultServiceSelector.Factory(componentEnv, info, role);
+            handler = new ThreadSafeComponentHandler(info, componentEnv.logger, factory);
+            handler.initialize();
+            return handler;
+            
+        } else if (StandaloneServiceSelector.class.isAssignableFrom(componentClass)) {
+            // Special factory for StandaloneServiceSelector
+            factory = new StandaloneServiceSelector.Factory(componentEnv, info, role);
+                
+        } else {
+            factory = new ComponentFactory(componentEnv, info);
+        }
+
+        if( info.getModel() == ComponentInfo.MODEL_NON_THREAD_SAFE_POOLED)  {
+            handler = new NonThreadSafePoolableComponentHandler( info, componentEnv.logger, factory, info.getConfiguration() );
+        } else if( info.getModel() == ComponentInfo.MODEL_POOLED ) {
+            handler = new PoolableComponentHandler( info, componentEnv.logger, factory, info.getConfiguration() );
+        } else if( info.getModel() == ComponentInfo.MODEL_SINGLETON ) {
+            handler = new ThreadSafeComponentHandler( info, componentEnv.logger, factory );
+        } else {
+            // This is a SingleThreaded component
+            handler = new SingleThreadedComponentHandler( info, componentEnv.logger, factory );
+        }
+
+        return handler;
+    }
+
+    /**
+     * Creates a new ComponentHandler.
+     */
+    public AbstractComponentHandler(ComponentInfo info, Logger logger) {
+        this.logger = logger;
+        this.info = info;
+    }
+    
+    public ComponentInfo getInfo() {
+        return this.info;
+    }
+
+    /**
+     * Get an instance of the type of component handled by this handler.
+     * <p>
+     * Subclasses should not extend this method but rather the doGet method below otherwise
+     *  reference counts will not be supported.
+     * <p>
+     *
+     * @return an instance
+     * @exception Exception if an error occurs
+     */
+    public final Object get() throws Exception {
+        initialize();
+        if( this.disposed ) {
+            throw new IllegalStateException( "You cannot get a component from a disposed handler." );
+        }
+        
+        final Object component = this.doGet();
+
+        synchronized( this.referenceSemaphore ) {
+            this.references++;
+        }
+
+        return component;
+    }
+
+    /**
+     * Put back an instance of the type of component handled by this handler.
+     * <p>
+     * Subclasses should not extend this method but rather the doPut method below otherwise
+     *  reference counts will not be supported.
+     * <p>
+     *
+     * @param component a service
+     * @exception Exception if an error occurs
+     */
+    public final void put( Object component ) 
+    throws Exception {
+        if( !this.initialized ) {
+            throw new IllegalStateException(
+                "You cannot put a component to an uninitialized handler." );
+        }
+        //  The reference count must be decremented before any calls to doPut.
+        //  If there is another thread blocking, then this thread could stay deep inside
+        //  doPut for an undetermined amount of time until the thread scheduler gives it
+        //  some cycles again.  (It happened).  All ComponentHandler state must therefor
+        //  reflect the thread having left this method before the call to doPut to avoid
+        //  warning messages from the dispose() cycle if that takes place before this
+        //  thread has a chance to continue.
+        synchronized( this.referenceSemaphore ) {
+            this.references--;
+        }
+
+        try {
+            this.doPut( component );
+        } catch( Throwable t ) {
+            this.logger.error("Exception during putting back a component.", t);
+        }
+    }
+
+    /**
+     * Concrete implementation of getting a component.
+     *
+     * @return a service
+     * @exception Exception if an error occurs
+     */
+    protected abstract Object doGet() throws Exception;
+
+    /**
+     * Concrete implementation of putting back a component.
+     *
+     * @param component a <code>Component</code> value
+     * @exception Exception if an error occurs
+     */
+    protected abstract void doPut( Object component ) throws Exception;
+
+    /**
+     * Default here is to return <code>false</code>
+     */
+    public boolean isSingleton() {
+        return false;
+    }
+    
+    /**
+     * Returns <code>true</code> if this component handler can safely be
+     * disposed (i.e. none of the components it is handling are still
+     * being used).
+     *
+     * @return <code>true</code> if this component handler can safely be
+     *         disposed; <code>false</code> otherwise
+     */
+    public final boolean canBeDisposed() {
+        return ( this.references == 0 );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#dispose()
+     */
+    public void dispose() {
+        this.disposed = true;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#initialize()
+     */
+    public final void initialize() throws Exception {
+        if( this.initialized ) {
+            return;
+        }
+
+        doInitialize();
+        this.initialized = true;
+    }
+    
+    protected abstract void doInitialize() throws Exception;
+
+    /**
+     * Create a component handler (version used by XSP)
+     * TODO - perhaps we can remove this later?
+     */
+    public static ComponentHandler getComponentHandler(Class clazz, Logger logger, Context context, ServiceManager manager, Configuration config) throws Exception {
+        ComponentEnvironment env = new ComponentEnvironment(clazz.getClassLoader(), logger, null, null, context, manager);
+        ComponentInfo info = new ComponentInfo();
+        info.setServiceClassName(clazz.getName());
+        info.setConfiguration(config);
+        info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), manager));
+        info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), clazz.getName()));
+        info.setRole("XSP");
+        return getComponentHandler(null, env, info);
+
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractFactoryHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractFactoryHandler.java
new file mode 100644
index 0000000..01b4053
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AbstractFactoryHandler.java
@@ -0,0 +1,58 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.ComponentFactory;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public abstract class AbstractFactoryHandler extends AbstractComponentHandler {
+    
+    /** This factory is used to created new objects */
+    protected final ComponentFactory factory;
+    
+    /**
+     * Creates a new ComponentHandler.
+     */
+    public AbstractFactoryHandler(ComponentInfo info, Logger logger, ComponentFactory factory) {
+        super(info, logger);
+        this.factory = factory;
+    }
+
+    /**
+     * Decommission a component
+     * @param component Object to be decommissioned
+     */
+    protected void decommission( final Object component ) {
+        try {
+            this.factory.decommission( component );
+        } catch( final Exception e ) {
+            if( this.logger.isWarnEnabled() ) {
+                this.logger.warn( "Error decommissioning component: "
+                    + this.factory.getCreatedClass().getName(), e );
+            }
+        }
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AliasComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AliasComponentHandler.java
new file mode 100644
index 0000000..2d11fd6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/AliasComponentHandler.java
@@ -0,0 +1,55 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+/**
+ * A component handler used to alias roles: it delegates all its calls to another
+ * handler.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class AliasComponentHandler extends AbstractComponentHandler {
+
+    ComponentHandler aliasedHandler;
+    
+    public AliasComponentHandler(Logger logger, ComponentHandler aliasedHandler) {
+        super(new ComponentInfo(), logger);
+        getInfo().setConfiguration(CoreServiceManager.EMPTY_CONFIGURATION);
+        this.aliasedHandler = aliasedHandler;
+    }
+
+    protected Object doGet() throws Exception {
+        return this.aliasedHandler.get();
+    }
+
+    protected void doPut(Object component) throws Exception {
+        this.aliasedHandler.put(component);
+    }
+    
+    protected void doInitialize() {
+        // nothing to do here
+    }
+    
+    public boolean isSingleton() {
+        return this.aliasedHandler.isSingleton();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ComponentHandler.java
new file mode 100644
index 0000000..3fa9a06
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ComponentHandler.java
@@ -0,0 +1,80 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.cocoon.components.ComponentInfo;
+
+/**
+ * This class acts like a Factory to instantiate the correct version
+ * of the component handler that you need.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public interface ComponentHandler {
+
+    /**
+     * Get an instance of the type of component handled by this handler.
+     * 
+     * @return an instance
+     * @exception Exception if an error occurs
+     */
+    Object get() throws Exception;
+
+    /**
+     * Put back an instance of the type of component handled by this handler.
+     *
+     * @param component a service
+     * @exception Exception if an error occurs
+     */
+    void put( Object component ) 
+    throws Exception;
+    
+    /**
+     * Indicates if this handler manages a single object, i.e. all calls to {@link #get()}
+     * will return the same object.
+     * 
+     * @return <code>true</code> if managed object is a singleton
+     */
+    boolean isSingleton();
+
+    /**
+     * Returns <code>true</code> if this component handler can safely be
+     * disposed (i.e. none of the components it is handling are still
+     * being used).
+     *
+     * @return <code>true</code> if this component handler can safely be
+     *         disposed; <code>false</code> otherwise
+     */
+    boolean canBeDisposed();
+
+    /**
+     * Dispose of the component handler and any associated Pools and Factories.
+     */
+    public void dispose();
+    
+    /**
+     * Initialize this handler
+     */
+    void initialize() throws Exception;
+    
+    /**
+     * Get the service metadata for this handler
+     */
+    ComponentInfo getInfo();
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/InstanceComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/InstanceComponentHandler.java
new file mode 100644
index 0000000..9d06114
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/InstanceComponentHandler.java
@@ -0,0 +1,74 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+/**
+ * A component handler for instances created outside the container.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class InstanceComponentHandler extends AbstractComponentHandler {
+
+    private Object obj;
+
+    /**
+     * Creates a new ComponentHandler.
+     */
+    public InstanceComponentHandler(Logger logger, Object obj) {
+        super(new ComponentInfo(), logger);
+        // For info.getLocation() to work properly
+        this.getInfo().setConfiguration(CoreServiceManager.EMPTY_CONFIGURATION);
+        this.obj = obj;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.AbstractComponentHandler#doGet()
+     */
+    protected Object doGet() throws Exception {
+        return this.obj;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.AbstractComponentHandler#doPut(java.lang.Object)
+     */
+    protected void doPut(Object component) throws Exception {
+        // nothing
+    }
+    
+    protected void doInitialize() {
+        // nothing to do here
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#dispose()
+     */
+    public void dispose() {
+        if (this.obj instanceof Disposable) {
+            ((Disposable)this.obj).dispose();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/LazyHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/LazyHandler.java
new file mode 100644
index 0000000..0b1d244
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/LazyHandler.java
@@ -0,0 +1,135 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.CoreResourceNotFoundException;
+import org.apache.cocoon.core.container.ComponentEnvironment;
+import org.apache.cocoon.util.JMXUtils;
+
+/**
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class LazyHandler implements ComponentHandler {
+    
+    private String role;
+    private String className;
+    private Configuration config;
+    private ComponentEnvironment compEnv;
+    
+    private ComponentHandler delegate;
+    
+    public LazyHandler(String role, String className, Configuration configuration, ComponentEnvironment environment) {
+        this.role = role;
+        this.className = className;
+        this.config = configuration;
+        this.compEnv = environment;
+    }
+    
+    private ComponentHandler getDelegate() throws Exception {
+        if (this.delegate == null) {
+//            System.err.println("######## " + System.identityHashCode(compEnv.serviceManager) + " creating handler for " + this.role);
+            ComponentInfo info = new ComponentInfo();
+            info.setConfiguration(config);
+            info.setServiceClassName(className);
+            info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), this.compEnv.serviceManager));
+            info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), className));
+            info.setRole(this.role);
+            this.delegate = AbstractComponentHandler.getComponentHandler(role, compEnv, info);
+            this.delegate.initialize();
+            JMXUtils.setupJmxFor(this.delegate, info);
+        }
+        
+        return this.delegate;
+    }
+    
+    private ComponentHandler getDelegateRE() {
+        try {
+            return getDelegate();
+        } catch (Exception e) {
+            throw new CoreResourceNotFoundException("Cannot get delegate handler", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#get()
+     */
+    public Object get() throws Exception {
+        return getDelegate().get();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#put(java.lang.Object)
+     */
+    public void put(Object component) throws Exception {
+        getDelegate().put(component);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#isSingleton()
+     */
+    public boolean isSingleton() {
+        return getDelegateRE().isSingleton();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#canBeDisposed()
+     */
+    public boolean canBeDisposed() {
+        // We can always be disposed if handler was never used
+        if (this.delegate == null) {
+            return true;
+        } 
+        return getDelegateRE().canBeDisposed();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#dispose()
+     */
+    public void dispose() {
+        // Dispose only if handler was actually used
+        if (this.delegate != null) {
+            this.delegate.dispose();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#initialize()
+     */
+    public void initialize() throws Exception {
+        // nothing (delegate is initialized when created)
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ComponentHandler#getInfo()
+     */
+    public ComponentInfo getInfo() {
+        if (this.delegate == null) {
+            final ComponentInfo info = new ComponentInfo();
+            info.setServiceClassName(className);
+            info.setConfiguration(config);
+            info.setJmxDomain(JMXUtils.findJmxDomain(info.getJmxDomain(), this.compEnv.serviceManager));
+            info.setJmxName(JMXUtils.findJmxName(info.getJmxName(), className));
+            info.setRole(role);
+            return info;
+        } 
+        return this.delegate.getInfo();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/NonThreadSafePoolableComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/NonThreadSafePoolableComponentHandler.java
new file mode 100644
index 0000000..b7b10d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/NonThreadSafePoolableComponentHandler.java
@@ -0,0 +1,285 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.ComponentFactory;
+
+/**
+ * The PoolableComponentHandler to make sure that poolable components are initialized
+ * destroyed and pooled correctly.
+ * <p>
+ * Components which implement Poolable may be configured to be pooled using the following
+ *  example configuration.  This example assumes that the user component class MyComp
+ *  implements Poolable.
+ * <p>
+ * Configuration Example:
+ * <pre>
+ *   &lt;my-comp pool-max="8"/&gt;
+ * </pre>
+ * <p>
+ * Roles Example:
+ * <pre>
+ *   &lt;role name="com.mypkg.MyComponent"
+ *         shorthand="my-comp"
+ *         default-class="com.mypkg.DefaultMyComponent"/&gt;
+ * </pre>
+ * <p>
+ * Configuration Attributes:
+ * <ul>
+ * <li>The <code>pool-max</code> attribute is used to set the maximum number of components which
+ *  will be pooled. (Defaults to "8") If additional instances are required, they're created,
+ *  but not pooled.</li>
+ * </ul>
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class NonThreadSafePoolableComponentHandler
+extends AbstractFactoryHandler {
+    
+    /** The default max size of the pool */
+    public static final int DEFAULT_MAX_POOL_SIZE = 8;
+
+    /**
+     * Object used to synchronize access to the get and put methods
+     */
+    protected final Object semaphore = new Object();
+
+    /**
+     * The maximum size of the pool.
+     */
+    private final int max;
+
+    /**
+     * List of the Poolable instances which are available for use.
+     */
+    private LinkedList ready;
+
+    /**
+     * Store the size of the ready list to optimize operations which require this value.
+     */
+    private int readySize;
+
+    /**
+     * Total number of Poolable instances in the pool
+     */
+    private int size;
+
+    /**
+     * Total number of Poolable instances created 
+     */
+    private int highWaterMark;
+    
+    /**
+     * Create a PoolableComponentHandler which manages a pool of Components
+     *  created by the specified factory object.
+     *
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the ComponentHandler.
+     * @param config The configuration to use to configure the pool.
+     */
+    public NonThreadSafePoolableComponentHandler( final ComponentInfo info,
+                                     final Logger logger,
+                                     final ComponentFactory factory,
+                                     final Configuration config )
+    throws Exception {
+        super(info, logger, factory);
+
+        final int poolMax = config.getAttributeAsInteger( "pool-max", DEFAULT_MAX_POOL_SIZE );
+        this.max = ( poolMax <= 0 ? Integer.MAX_VALUE : poolMax );
+
+        // Create the pool lists.
+        this.ready = new LinkedList();
+    }
+
+    /**
+     * Dispose of the ComponentHandler and any associated Pools and Factories.
+     */
+    public void dispose() {
+        super.dispose();
+
+        // Any Poolables in the m_ready list need to be disposed of
+        synchronized( this.semaphore ) {
+            // Remove objects in the ready list.
+            for( Iterator iter = this.ready.iterator(); iter.hasNext(); ) {
+                Object poolable = iter.next();
+                iter.remove();
+                this.readySize--;
+                this.permanentlyRemovePoolable( poolable );
+            }
+
+            if( this.size > 0 && this.logger.isDebugEnabled() ) {
+                this.logger.debug( "There were " + this.size
+                                   + " outstanding objects when the pool was disposed." );
+            }
+        }
+    }
+    
+    /**
+     * Permanently removes a poolable from the pool's active list and
+     *  destroys it so that it will not ever be reused.
+     * <p>
+     * This method is only called by threads that have m_semaphore locked.
+     */
+    protected void permanentlyRemovePoolable( Object poolable ) {
+        this.size--;
+        this.decommission( poolable );
+    }
+
+    /**
+     * Gets a Poolable from the pool.  If there is room in the pool, a new Poolable will be
+     *  created.  Depending on the parameters to the constructor, the method may block or throw
+     *  an exception if a Poolable is not available on the pool.
+     *
+     * @return Always returns a Poolable.  Contract requires that put must always be called with
+     *  the Poolable returned.
+     * @throws Exception An exception may be thrown as described above or if there is an exception
+     *  thrown by the ObjectFactory's newInstance() method.
+     */
+    protected Object getFromPool() throws Exception {
+        Object poolable;
+        synchronized( this.semaphore ) {
+            // Look for a Poolable at the end of the m_ready list
+            if ( this.readySize > 0 ){
+                // A poolable is ready and waiting in the pool
+                poolable = this.ready.removeLast();
+                this.readySize--;
+            } else {
+                // Create a new poolable.  May throw an exception if the poolable can not be
+                //  instantiated.
+                poolable = this.factory.newInstance();
+                this.size++;
+                this.highWaterMark = (this.highWaterMark < this.size ? this.size : this.highWaterMark);
+
+                if ( this.logger.isDebugEnabled() ) {
+                    this.logger.debug( "Created a new " + poolable.getClass().getName()
+                                       + " from the object factory." );
+                }
+            }
+        }
+
+        this.factory.exitingPool(poolable);
+        
+        if( this.logger.isDebugEnabled() ) {
+            this.logger.debug( "Got a " + poolable.getClass().getName() + " from the pool." );
+        }
+
+        return poolable;
+    }
+
+    /**
+     * Returns a poolable to the pool 
+     *
+     * @param poolable Poolable to return to the pool.
+     */
+    protected void putIntoPool( final Object poolable ) {
+        try {
+            this.factory.enteringPool(poolable);
+        } catch (Exception ignore) {
+            this.logger.warn("Exception during putting component back into the pool.", ignore);
+        }
+
+        synchronized( this.semaphore ) {
+            if( this.size <= this.max ) {
+                if( this.disposed ) {
+                    // The pool has already been disposed.
+                    if( this.logger.isDebugEnabled() ) {
+                        this.logger.debug( "Put called for a " + poolable.getClass().getName()
+                                           + " after the pool was disposed." );
+                    }
+
+                    this.permanentlyRemovePoolable( poolable );
+                } else {
+                    // There is room in the pool to keep this poolable.
+                    if( this.logger.isDebugEnabled() ) {
+                        this.logger.debug( "Put a " + poolable.getClass().getName()
+                                           + " back into the pool." );
+                    }
+
+                    this.ready.addLast( poolable );
+                    this.readySize++;
+
+                }
+            } else {
+                // More Poolables were created than can be held in the pool, so remove.
+                if( this.logger.isDebugEnabled() ) {
+                    this.logger.debug( "No room to put a " + poolable.getClass().getName()
+                                       + " back into the pool, so remove it." );
+                }
+
+                this.permanentlyRemovePoolable( poolable );
+            }
+        }
+    }
+    
+    protected void doInitialize() {
+        // nothing to do here
+    }
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.handler.AbstractComponentHandler#doGet()
+     */
+    protected Object doGet() throws Exception {
+        return this.getFromPool();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.handler.AbstractComponentHandler#doPut(java.lang.Object)
+     */
+    protected void doPut(Object component) throws Exception {
+        this.putIntoPool(component);
+    }
+
+    /**
+     * @return Returns the max.
+     */
+    protected int getMax()
+    {
+        return max;
+    }
+
+    /**
+     * @return Returns the readySize.
+     */
+    protected int getReadySize()
+    {
+        return readySize;
+    }
+
+    /**
+     * @return Returns the size.
+     */
+    protected int getSize()
+    {
+        return size;
+    }
+
+    /**
+     * @return Returns the highWaterMark.
+     */
+    protected int getHighWaterMark()
+    {
+        return highWaterMark;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandler.java
new file mode 100644
index 0000000..908e77d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandler.java
@@ -0,0 +1,169 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.container.ComponentFactory;
+
+/**
+ * This is an extension to the {@link org.apache.cocoon.core.container.handler.NonThreadSafePoolableComponentHandler}
+ * that uses proxies to make the poolable components thread safe.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class PoolableComponentHandler
+extends NonThreadSafePoolableComponentHandler {
+    
+    /** All the interfaces for the proxy */
+    protected final Class[] interfaces;
+    
+    /**
+     * Create a PoolableComponentHandler which manages a pool of Components
+     *  created by the specified factory object.
+     *
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the ComponentHandler.
+     * @param config The configuration to use to configure the pool.
+     */
+    public PoolableComponentHandler( final ComponentInfo info,
+                                     final Logger logger,
+                                     final ComponentFactory factory,
+                                     final Configuration config )
+    throws Exception {
+        super(info, logger, factory, config);
+        final HashSet workInterfaces = new HashSet();
+
+        // Get *all* interfaces
+        this.guessWorkInterfaces( factory.getCreatedClass(), workInterfaces );
+
+        this.interfaces = (Class[]) workInterfaces.toArray( new Class[workInterfaces.size()] );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.handler.AbstractComponentHandler#doGet()
+     */
+    protected Object doGet() throws Exception {
+        return this.createProxy();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.handler.AbstractComponentHandler#doPut(java.lang.Object)
+     */
+    protected void doPut(Object component) throws Exception {
+        // nothing to do
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.handler.AbstractComponentHandler#doInitialize()
+     */
+    protected void doInitialize() {
+        // nothing to do here
+    }
+    
+    protected Object createProxy() {
+        return Proxy.newProxyInstance(this.factory.getCreatedClass().getClassLoader(), 
+                                      this.interfaces, 
+                                      new ProxyHandler(this));
+    }
+
+    /**
+     * Get a list of interfaces to proxy by scanning through
+     * all interfaces a class implements.
+     *
+     * @param clazz           the class
+     * @param workInterfaces  the set of current work interfaces
+     */
+    private void guessWorkInterfaces( final Class clazz,
+                                      final Set workInterfaces ) {
+        if ( null != clazz ) {
+            this.addInterfaces( clazz.getInterfaces(), workInterfaces );
+
+            this.guessWorkInterfaces( clazz.getSuperclass(), workInterfaces );
+        }
+    }
+
+    /**
+     * Get a list of interfaces to proxy by scanning through
+     * all interfaces a class implements.
+     *
+     * @param interfaces      the array of interfaces
+     * @param workInterfaces  the set of current work interfaces
+     */
+    private void addInterfaces( final Class[] interfaces,
+                                final Set workInterfaces ) {
+        for ( int i = 0; i < interfaces.length; i++ ) {
+            workInterfaces.add( interfaces[i] );
+            this.addInterfaces(interfaces[i].getInterfaces(), workInterfaces);
+        }
+    }
+
+    protected static final class ProxyHandler implements InvocationHandler, Core.CleanupTask {
+        
+        private final ThreadLocal componentHolder = new ThreadLocal();
+        private final PoolableComponentHandler handler;
+        
+        public ProxyHandler(PoolableComponentHandler handler) {
+            this.handler = handler;
+        }
+        
+        /* (non-Javadoc)
+         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+         */
+        public Object invoke(Object proxy, Method method, Object[] args)
+        throws Throwable {
+            if ( method.getName().equals("hashCode") && args == null ) {
+                return new Integer(this.hashCode());
+            }
+            if ( this.componentHolder.get() == null ) {
+                this.componentHolder.set(this.handler.getFromPool());
+                Core.addCleanupTask(this);
+            }
+            try {
+                return method.invoke(this.componentHolder.get(), args);
+            } catch (InvocationTargetException ite) {
+                throw ite.getTargetException();
+            }
+        }
+        
+        
+        /* (non-Javadoc)
+         * @see org.apache.cocoon.core.Core.CleanupTask#invoke()
+         */
+        public void invoke() {
+            try {
+                final Object o = this.componentHolder.get();
+                this.handler.putIntoPool(o);
+            } catch (Exception ignore) {
+                // we ignore this
+            }
+            this.componentHolder.set(null);
+        }
+    }
+    
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandlerMBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandlerMBean.java
new file mode 100644
index 0000000..95d6474
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/PoolableComponentHandlerMBean.java
@@ -0,0 +1,98 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+
+import org.apache.cocoon.components.ComponentInfo;
+import org.mortbay.util.jmx.ModelMBeanImpl;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+
+/**
+ * The PoolableComponentHandlerMBean adds JMX managability for PoolableComponentHandler.
+ *
+ * @version $Id: ThreadSafeComponentHandler.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class PoolableComponentHandlerMBean
+extends ModelMBeanImpl {
+    
+    private final PoolableComponentHandler handler;
+    private final ComponentInfo info;
+    
+    protected void defineManagedResource() {
+        super.defineManagedResource();
+        defineAttribute("interfaces", false, true);
+        defineAttribute("defaultMaxPoolSize", false, true);
+        defineAttribute("maxPoolSize", false, true);
+        defineAttribute("readyPoolSize", false, true);
+        defineAttribute("totalPoolSize", false, true);
+        defineAttribute("highWaterMark", false, true);
+    }
+    /**
+     * Construction of PoolableComponentHandlerMBean
+     *
+     * @param handler The managed PoolableComponentHandler instance
+     */
+    public PoolableComponentHandlerMBean(final PoolableComponentHandler handler, final ComponentInfo info)
+        throws MBeanException, InstanceNotFoundException {
+        super( handler );
+        this.handler = handler;
+        this.info = info;
+    }
+    
+    public String[] getInterfaces()
+    {
+        final String [] ifaces = new String[this.handler.interfaces.length];
+        for(int i = 0; i < ifaces.length; i++) {
+            ifaces[i] = this.handler.interfaces[i].getName();
+        }
+        return ifaces;
+    }
+
+    public int getDefaultMaxPoolSize()
+    {
+        return NonThreadSafePoolableComponentHandler.DEFAULT_MAX_POOL_SIZE;
+    }
+
+    public int getMaxPoolSize()
+    {
+        return handler.getMax();
+    }
+
+    public int getReadyPoolSize()
+    {
+        return handler.getReadySize();
+    }
+
+    public int getHighWaterMark()
+    {
+        return handler.getHighWaterMark();
+    }
+
+    public int getTotalPoolSize()
+    {
+        return handler.getSize();
+    }
+    
+    public String getJmxName() 
+    {
+        //return JMXUtils.genDefaultJmxName(handler.getInfo().getServiceClassName());
+        return "subsys=ECM++,handler=poolable" + (info.getRole() != null ? ",role=" + info.getRole() : "");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandler.java
new file mode 100644
index 0000000..d73474d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandler.java
@@ -0,0 +1,94 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.ComponentFactory;
+
+/**
+ * The DefaultComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class SingleThreadedComponentHandler
+extends AbstractFactoryHandler {
+
+    private long maxCreated = 0;
+    private long maxDecommissioned = 0;
+    
+    /**
+     * Create a SingleThreadedComponentHandler which manages a pool of Components
+     *  created by the specified factory object.
+     *
+     * @param logger The logger to use
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the handler.
+     */
+    public SingleThreadedComponentHandler( final ComponentInfo info,
+                                    final Logger logger,
+                                    final ComponentFactory factory ) {
+        super(info, logger, factory);
+    }
+
+    /**
+     * Get a reference of the desired Component
+     *
+     * @return A component instance.
+     *
+     * @throws Exception If there are any problems encountered acquiring a
+     *                   component instance.
+     */
+    protected Object doGet()
+    throws Exception {
+        maxCreated++;
+        return this.factory.newInstance();
+    }
+
+    /**
+     * Return a reference of the desired Component
+     *
+     * @param component Component to be be put/released back to the handler.
+     */
+    protected void doPut( final Object component ) {
+        this.decommission( component );
+        maxDecommissioned++;
+    }
+    
+    protected void doInitialize() {
+        // nothing to do here
+    }
+
+    /**
+     * @return Returns the maxCreated.
+     */
+    public long getMaxCreated()
+    {
+        return maxCreated;
+    }
+
+    /**
+     * @return Returns the maxDecommisioned.
+     */
+    public long getMaxDecommissioned()
+    {
+        return maxDecommissioned;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandlerMBean.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandlerMBean.java
new file mode 100644
index 0000000..30bdb6d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/SingleThreadedComponentHandlerMBean.java
@@ -0,0 +1,75 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+
+import org.apache.cocoon.components.ComponentInfo;
+import org.mortbay.util.jmx.ModelMBeanImpl;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+
+/**
+ * The SingleThreadedComponentHandlerMBean adds JMX managability for SingleThreadedComponentHandler.
+ *
+ * @version $Id: ThreadSafeComponentHandler.java 312637 2005-10-10 13:00:42Z cziegeler $
+ * @since 2.2
+ */
+public class SingleThreadedComponentHandlerMBean
+extends ModelMBeanImpl {
+    
+    private final SingleThreadedComponentHandler handler;
+    private final ComponentInfo info;
+    
+    protected void defineManagedResource() {
+        super.defineManagedResource();
+        defineAttribute("maxCreated", false, true);
+        defineAttribute("maxDecommissioned", false, true);
+        defineAttribute("outstanding", false, true);
+    }
+    /**
+     * Construction of PoolableComponentHandlerMBean
+     *
+     * @param handler The managed PoolableComponentHandler instance
+     */
+    public SingleThreadedComponentHandlerMBean(final SingleThreadedComponentHandler handler, final ComponentInfo info)
+        throws MBeanException, InstanceNotFoundException {
+        super( handler );
+        this.handler = handler;
+        this.info = info;
+    }
+
+    public long getMaxCreated()
+    {
+        return handler.getMaxCreated();
+    }
+
+    public long getMaxDecommissioned()
+    {
+        return handler.getMaxDecommissioned();
+    }
+
+    public long getOutstanding()
+    {
+        return handler.getMaxCreated() - handler.getMaxDecommissioned();
+    }
+    
+    public String getJmxName() 
+    {
+        return "subsys=ECM++,handler=single-threaded" + (info.getRole() != null ? ",role=" + info.getRole() : "");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ThreadSafeComponentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ThreadSafeComponentHandler.java
new file mode 100644
index 0000000..d54c892
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/ThreadSafeComponentHandler.java
@@ -0,0 +1,84 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.handler;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.ComponentFactory;
+import org.apache.cocoon.util.JMXUtils;
+
+/**
+ * The ThreadSafeComponentHandler to make sure components are initialized
+ * and destroyed correctly.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class ThreadSafeComponentHandler
+extends AbstractFactoryHandler {
+    
+    private Object instance;
+
+    /**
+     * Create a ThreadSafeComponentHandler which manages a single instance
+     * of an object return by the component factory.
+     * @param logger The logger to use
+     * @param factory The factory object which is responsible for creating the components
+     *                managed by the handler.
+     */
+    public ThreadSafeComponentHandler( final ComponentInfo info,
+                                       final Logger logger,
+                                       final ComponentFactory factory ) {
+        super(info, logger, factory);
+    }
+    
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public void doInitialize() throws Exception {
+        if( this.instance == null ) {
+            this.instance = this.factory.newInstance();
+            JMXUtils.setupJmxFor(this.instance, getInfo(), logger);
+        }
+    }
+
+    /**
+     * Get a reference of the desired Component
+     */
+    protected Object doGet()
+    throws Exception {
+        return this.instance;
+    }
+
+    /**
+     * Return a reference of the desired Component
+     */
+    protected void doPut( final Object component ) {
+        // nothing to do
+    }
+
+    /**
+     * Dispose of the ComponentHandler and any associated Pools and Factories.
+     */
+    public void dispose() {
+        this.decommission( this.instance );
+        this.instance = null;
+
+        super.dispose();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/mbean.properties b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/mbean.properties
new file mode 100644
index 0000000..493e47a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/handler/mbean.properties
@@ -0,0 +1,16 @@
+PoolableComponentHandler = Manages Pools of Components
+
+PoolableComponentHandler.interfaces = The Array of Interfaces the managed Components have
+PoolableComponentHandler.defaultMaxPoolSize = The Default maximum pool size
+PoolableComponentHandler.maxPoolSize = The configured maximum pool size
+PoolableComponentHandler.readyPoolSize = The number of Components ready to be used
+PoolableComponentHandler.totalPoolSize = The total number of Components in the pool
+PoolableComponentHandler.highWaterMark = The high water mark of Components created
+PoolableComponentHandler.role = The role name of the Component managed by his pool
+
+
+SingleThreadedComponentHandler = Handles Creation/Decomission of single threaded Components
+
+SingleThreadedComponentHandler.maxCreated = The current numbers of Components created
+SingleThreadedComponentHandler.maxDecommissioned = The current numbers of Components Decomissioned
+SingleThreadedComponentHandler.outstanding = Number of Components theoretically in use
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/util/PropertyHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/util/PropertyHelper.java
new file mode 100644
index 0000000..9e2a48b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/container/util/PropertyHelper.java
@@ -0,0 +1,101 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.util;
+
+import org.apache.cocoon.core.Settings;
+
+/**
+ * Helper class for replacing property references with the value of the
+ * property
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class PropertyHelper {
+
+        /**
+     * Replace all property references in the string with the current value
+     * and return it.
+     */
+    public static String replace(String value, Settings settings) {
+        // quick test for null or no references
+        if ( value == null || value.indexOf("${") == -1 ) {
+            return value;
+        }
+        final StringBuffer buffer = new StringBuffer();
+        int prev = 0;
+        int pos;
+        
+        // search for the next instance of $ from the 'prev' position
+        while ((pos = value.indexOf("$", prev)) >= 0) {
+
+            // if there was any text before this, add it
+            if (pos > prev) {
+                buffer.append(value.substring(prev, pos));
+            }
+            
+            // if we are at the end of the string, end
+            if (pos == (value.length() - 1)) {
+                buffer.append("$");
+                prev = pos + 1;
+            } else if (value.charAt(pos + 1) != '{') {
+                // peek ahead to see if the next char is a property or not
+                // not a property: insert the char as a literal
+                buffer.append(value.substring(pos, pos + 2));
+                prev = pos + 2;
+
+            } else {
+                // start token found, check for end token
+                int endName = value.indexOf('}', pos);
+                if (endName == -1) {
+                    // no end token found, just append the rest
+                    buffer.append(value.substring(pos));
+                    prev = value.length();
+                } else {
+                    final String propertyName = value.substring(pos + 2, endName);
+                    String propertyValue = getProperty(propertyName, settings);
+                    // compatibility fallback - if the value is null, just readd token
+                    if (propertyValue == null) {
+                        buffer.append("${");
+                        buffer.append(propertyName);
+                        buffer.append('}');
+                    } else {
+                        buffer.append(propertyValue);
+                    }
+                    prev = endName + 1;
+                }
+            }
+        }
+        // no more tokens found
+        // append the rest
+        if (prev < value.length()) {
+             buffer.append(value.substring(prev));
+        }
+        return buffer.toString();
+    }
+
+    static String getProperty(String name, Settings settings) {
+        String value = null;
+        if ( settings != null ) {
+            value = settings.getProperty(name);
+        }
+        if ( value == null ) {
+            value = System.getProperty(name);
+        }
+        return value;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/CocoonLogKitLoggerManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/CocoonLogKitLoggerManager.java
new file mode 100644
index 0000000..01ce41a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/CocoonLogKitLoggerManager.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core.logging;
+
+import org.apache.avalon.excalibur.logger.LogKitLoggerManager;
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.cocoon.environment.Environment;
+import org.apache.log.ContextMap;
+import org.apache.log.Hierarchy;
+
+/**
+ * This is an extension of the {@link LoggerManager}. It can be used to
+ * initialize a logging context on a per thread basis. This allows the
+ * logging implementation to access and log information about the current
+ * request.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class CocoonLogKitLoggerManager 
+    extends LogKitLoggerManager
+    implements PerRequestLoggerManager {
+    
+    public CocoonLogKitLoggerManager() {
+        // Use the default hierarchy, which is also used by commons-logging
+        super(Hierarchy.getDefaultHierarchy());
+    }
+
+    /**
+     * @see org.apache.cocoon.core.logging.PerRequestLoggerManager#initializePerRequestLoggingContext(org.apache.cocoon.environment.Environment)
+     */
+    public Object initializePerRequestLoggingContext(Environment env) {
+        ContextMap ctxMap;
+        // Initialize a fresh log context containing the object model: it
+        // will be used by the CocoonLogFormatter
+        ctxMap = ContextMap.getCurrentContext();
+        // Add thread name (default content for empty context)
+        String threadName = Thread.currentThread().getName();
+        ctxMap.set("threadName", threadName);
+        // Add the object model
+        ctxMap.set("objectModel", env.getObjectModel());
+        // Add a unique request id (threadName + currentTime
+        ctxMap.set("request-id", threadName + System.currentTimeMillis());
+        
+        return ctxMap;
+    }
+
+    /**
+     * @see org.apache.cocoon.core.logging.PerRequestLoggerManager#cleanPerRequestLoggingContext(java.lang.Object)
+     */
+    public void cleanPerRequestLoggingContext(Object ctxMap) {
+        if ( ctxMap != null ) {
+            ((ContextMap)ctxMap).clear();
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/PerRequestLoggerManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/PerRequestLoggerManager.java
new file mode 100644
index 0000000..624aba3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/PerRequestLoggerManager.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core.logging;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * This is an extension of the {@link LoggerManager}. It can be used to
+ * initialize a logging context on a per thread basis. This allows the
+ * logging implementation to access and log information about the current
+ * request.
+ * 
+ * @version $Id:$
+ * @since 2.2
+ */
+public interface PerRequestLoggerManager extends LoggerManager {
+
+    /**
+     * Initialize the context for logging.
+     */
+    Object initializePerRequestLoggingContext(Environment env);
+
+    /**
+     * Clean up the logging context.
+     */
+    void cleanPerRequestLoggingContext(Object ctxMap);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/SettingsContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/SettingsContext.java
new file mode 100644
index 0000000..eb3e203
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/logging/SettingsContext.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core.logging;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.cocoon.core.Settings;
+
+/**
+ * This is an extension the default context implementation.
+ * It first looks into the settings object and only if the key
+ * is not found there, it delegates to the parent.
+ * 
+ * @version $Id:$
+ * @since 2.2
+ */
+public class SettingsContext extends DefaultContext {
+
+    private final Settings settings;
+
+    public SettingsContext(Context parentContext, Settings s) {
+        super(parentContext);
+        this.settings = s;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.context.Context#get(java.lang.Object)
+     */
+    public Object get(Object name) throws ContextException {
+        if ( this.settings.getProperty(name.toString()) != null ) {
+            return this.settings.getProperty(name.toString());
+        }
+        return super.get(name);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreBlockActivator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreBlockActivator.java
new file mode 100644
index 0000000..dda6034
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreBlockActivator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.osgi;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public class CoreBlockActivator extends ServiceManagerActivator {
+
+    private Core core;
+    private Processor processor;
+
+    public void start(final BundleContext ctx) throws Exception {
+        Thread.currentThread().setContextClassLoader(CoreBlockActivator.class.getClassLoader());
+        BootstrapEnvironment env = new OSGiBootstrapEnvironment(ctx);
+        env.log("OSGiBootstrapEnvironment created");
+        OSGICoreUtil coreUtil = new OSGICoreUtil(env);
+        env.log("CoreUtil created");
+        this.core = coreUtil.getCore();
+        this.processor = coreUtil.createCocoon();
+
+        super.start(ctx);
+    }
+
+    public void stop(BundleContext ctx) throws Exception {
+        super.stop(ctx);
+    }
+
+    protected Context getContext() throws Exception {
+        return this.core.getContext();
+    }
+
+    /**
+     * This method may be overwritten by subclasses to provide an own
+     * configuration
+     */
+//     protected Configuration getConfiguration() {
+//         DefaultConfiguration config = new DefaultConfiguration("cocoon", "CoreBlockActivator");
+//         return config;
+//     }
+
+    /**
+     * This method may be overwritten by subclasses to add aditional
+     * components.
+     */
+    protected void addComponents(CoreServiceManager manager) 
+    throws ServiceException, ConfigurationException {
+        manager.addInstance(Core.ROLE, this.core);
+        manager.addInstance(Cocoon.class.getName(), this.processor);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreOSGIServiceException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreOSGIServiceException.java
new file mode 100644
index 0000000..a41a338
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/CoreOSGIServiceException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core.osgi;
+
+import org.apache.cocoon.core.CoreException;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public final class CoreOSGIServiceException extends CoreException {
+
+    public CoreOSGIServiceException(String message) {
+        super(message, null);
+    }
+
+    public CoreOSGIServiceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGICoreUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGICoreUtil.java
new file mode 100644
index 0000000..6beac9e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGICoreUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.core.osgi;
+
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreUtil;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public class OSGICoreUtil extends CoreUtil {
+
+    public OSGICoreUtil(BootstrapEnvironment environment) throws Exception {
+        super(environment);
+    }
+
+    protected void createClassloader() throws Exception {
+        this.classloader = OSGICoreUtil.class.getClassLoader();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiBootstrapEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiBootstrapEnvironment.java
new file mode 100644
index 0000000..9bbda08
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiBootstrapEnvironment.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.core.osgi;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.impl.AbstractContext;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public class OSGiBootstrapEnvironment implements BootstrapEnvironment {
+
+    private final String configuration = "/WEB-INF/block.xml";
+
+    public Logger logger = null;
+    private final String contextPath;
+    private final Context environmentContext;
+
+
+    public OSGiBootstrapEnvironment(BundleContext bc)
+        throws Exception {
+
+        // Create a logger manager that delegates to OSGi
+        // FIXME: have the maximum level as a property of the bundle
+        LoggerManager logManager = new OSGiLoggerManager(bc, LogService.LOG_DEBUG);
+        this.logger = logManager.getDefaultLogger();
+
+        Bundle bundle = bc.getBundle();
+        if (bundle == null) {
+            throw new Exception("No sitemap bundle");
+        }
+
+        // Try to figure out the path of the root from that of /WEB-INF/block.xml
+        URL pathURL = bundle.getResource(this.configuration);
+        if (pathURL == null) {
+            throw new FileNotFoundException("Unable to get resource '/WEB-INF/block.xml' from bundle ." + bundle);
+        }
+
+        String path = pathURL.toString();
+        path = path.substring(0, path.length() - (this.configuration.length() - 1));
+        this.contextPath = path;
+
+        this.environmentContext = new OSGiContext(bundle);
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BootstrapEnvironment#getBootstrapLogger(org.apache.cocoon.core.BootstrapEnvironment.LogLevel)
+     */
+    public Logger getBootstrapLogger(LogLevel logLevel) {
+        return this.logger;
+    }
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     */
+    public void log(String message) {
+        this.logger.info(message);
+    }
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     * @param error   An error.
+     */
+    public void log(String message, Throwable error) {
+        this.logger.info(message, error);
+    }
+
+    /**
+     * Pass the root logger back to the environment. As soon as the
+     * logging system is set up, this method is called.
+     * @param rootLogger The root logger.
+     */
+    public void setLogger(Logger rootLogger) {
+        this.logger = rootLogger;
+    }
+
+    /**
+     * Get the input stream from a resource at the given
+     * path. Only paths relative to the bootstrap context are
+     * supported. Returns null if no resource exists at the
+     * specified path
+     */
+    public InputStream getInputStream(String path) {
+        try {
+            return (new URL(this.contextPath + path)).openStream();
+        } catch (IOException e) {
+            this.log("Couldn't open " + this.contextPath + path);
+            return null;
+        }
+    }
+
+    public void configure(MutableSettings settings) {
+        // FIXME: Should be found from block.xml
+        settings.setConfiguration("/WEB-INF/cocoon.xconf");
+        settings.setWorkDirectory("work");
+        settings.setLoggingConfiguration("/WEB-INF/logkit.xconf");
+    }
+
+    public void configureLoggingContext(DefaultContext context) {
+        // simply do nothing
+    }
+
+    public void configure(DefaultContext context) {
+    }
+
+    public Context getEnvironmentContext() {
+        return this.environmentContext;
+    }
+
+    /**
+     * Returns the URL to the application context.
+     */
+    public String getContextURL() {
+        return this.contextPath;
+    }
+
+    /**
+     * Returns a file to the application context.
+     * @return A file pointing to the context or null if the context is not
+     *         writeable.
+     */
+    public File getContextForWriting() {
+        return null;
+    }
+
+    /**
+     * Set the ConfigFile for the Cocoon object.
+     *
+     * @param configFileName The file location for the cocoon.xconf
+     *
+     * @throws Exception
+     */
+    public URL getConfigFile(String configFileName) throws Exception {
+        this.logger.debug("getConfigFile: contextPath=" + this.contextPath +
+                          " configFileName=" + configFileName);
+        return new URL(this.contextPath + configFileName);
+    }
+
+    public class OSGiContext extends AbstractContext {
+
+        private Bundle bundle;
+        private Hashtable attributes = new Hashtable();
+        private Hashtable initparameters = new Hashtable();
+
+        public OSGiContext(Bundle bundle) {
+            this.bundle = bundle;
+            this.initparameters.put("work-directory", "work");
+        }
+
+        public Object getAttribute(String name) {
+            return attributes.get(name);
+        }
+
+        public void setAttribute(String name, Object value) {
+            attributes.put(name, value);
+        }
+
+        public void removeAttribute(String name) {
+            attributes.remove(name);
+        }
+
+        public Enumeration getAttributeNames() {
+            return attributes.keys();
+        }
+
+        public URL getResource(String path) throws MalformedURLException {
+            return this.bundle.getResource(path);
+        }
+
+        public String getRealPath(String path) {
+            // Everything is zipped up, no path.
+            return null;
+        }
+
+        public String getMimeType(String file) {
+            // TODO Implement
+            throw new UnsupportedOperationException("Not Implemented");
+        }
+
+        public String getInitParameter(String name) {
+            return (String) initparameters.get(name);
+        }
+
+        public InputStream getResourceAsStream(String path) {
+            try {
+                return bundle.getResource(path).openStream();
+            } catch (IOException e) {
+                // FIXME Error handling
+                e.printStackTrace();
+                return null;
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiCoreServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiCoreServiceManager.java
new file mode 100644
index 0000000..12a2613
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiCoreServiceManager.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.osgi;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.apache.cocoon.core.container.DefaultServiceSelector;
+import org.apache.cocoon.core.container.handler.ComponentHandler;
+import org.apache.cocoon.core.container.handler.PoolableComponentHandler;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * An extension of {@link org.apache.cocoon.core.container.CoreServiceManager} that registers some
+ * of its components as OSGi services.
+ * <p>
+ * The component role is used to find a component's interface. If the role is a hinted one (e.g.
+ * "org.apache.cocoon.generation.Generator/file", then the hint is registered as the "component.hint"
+ * property of the OSGi service.
+ * <p>
+ * Only those components whose configuration has an <code>exported="true"</code> attribute are exported.
+ * An important constraint is that such components be singleton (either real singletons or singleton proxies
+ * to non-singleton components).
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class OSGiCoreServiceManager extends CoreServiceManager {
+    
+    BundleContext ctx;
+    
+    public OSGiCoreServiceManager(ServiceManager parent, ClassLoader classloader, BundleContext ctx) {
+        super(parent, classloader);
+        this.ctx = ctx;
+    }
+
+    /**
+     * Catch component declarations and register exported ones as OSGi services.
+     */
+    public void addComponent(String role, String className, Configuration configuration, ComponentInfo info) throws ConfigurationException {
+        super.addComponent(role, className, configuration, info);
+
+        Class clazz;
+        try {
+            clazz = this.componentEnv.loadClass(className);
+        } catch(ClassNotFoundException cnfe) {
+            throw new ConfigurationException("Cannot load class " + className + " for component at " +
+                                             configuration.getLocation(), cnfe);
+        }
+
+        // The DefaultServiceSelector just add its children, no need to add it as a service
+        if (DefaultServiceSelector.class.isAssignableFrom(clazz))
+            return;
+        if (configuration.getAttributeAsBoolean("exported", true)) {
+            ComponentHandler handler = (ComponentHandler)super.componentHandlers.get(role);
+            // Shouldn't PoolableComponentHandler be marked as a singleton?
+            if (handler.isSingleton() ||
+                handler instanceof PoolableComponentHandler) {
+                this.addService(role, handler);
+            } else {
+                throw new ConfigurationException("Only singleton services and thread safe pool proxies can be exported as OSGi services, at " +
+                                                 configuration.getLocation() +
+                                                 " handler=" + handler);
+            }
+        }
+    }
+    
+    /**
+     * Catch a component insertion and register it as OSGi services.
+     */
+    public void addInstance(String role, Object instance) throws ServiceException {
+        super.addInstance(role, instance);
+        ComponentHandler handler = (ComponentHandler)super.componentHandlers.get(role);
+        this.addService(role, handler);
+    }
+
+    /**
+     * Register a component as an OSGi service.
+     */
+    protected void addService(String role, ComponentHandler handler) {
+        String itfName = OSGiServiceManager.getServiceInterface(role);
+        String hint = OSGiServiceManager.getServiceHint(role);
+        Dictionary dict = null;
+        if (hint != null) {
+            dict = new Hashtable();
+            dict.put(OSGiServiceManager.HINT_PROPERTY, hint);
+        }
+
+        Object service = new ComponentHandlerFactory(handler);
+        ctx.registerService(itfName, service, dict);
+    }
+    
+    /**
+     * An OSGi service factory implemented on top of a {@link ComponentHandler}.
+     *
+     */
+    public static class ComponentHandlerFactory implements ServiceFactory {
+        
+        private ComponentHandler handler;
+
+        public ComponentHandlerFactory(ComponentHandler handler) {
+            this.handler = handler;
+        }
+
+        public Object getService(Bundle bundle, ServiceRegistration reg) {
+            try {
+                return handler.get();
+            } catch (Exception e) {
+                throw new CoreOSGIServiceException("Cannot get service", e);
+            }
+        }
+
+        public void ungetService(Bundle bundle, ServiceRegistration reg, Object obj) {
+            try {
+                handler.put(obj);
+            } catch (Exception e) {
+                throw new CoreOSGIServiceException("Cannot unget service", e);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiLoggerManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiLoggerManager.java
new file mode 100644
index 0000000..87d8253
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiLoggerManager.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.osgi;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.logger.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * An implementation of Avalon's <code>LoggerManager</code> on top of OSGi's <code>LogService</code>.
+ * OSGi's service provides no way to check if a particular log level is enabled. Rather than always
+ * considering all levels to be enabled, which can lead to useless expensive expressions, the maximum
+ * log level is given at manager creation time, and is uses by all log categories within the bundle.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public class OSGiLoggerManager implements LoggerManager {
+    
+    LogService logService;
+    int maxLevel;
+    
+    /**
+     * Create an <code>OSGiLoggerManager</code>.
+     * 
+     * @param ctx the <code>BundleContext</code> used to get the <code>LogService</code>
+     * @param maxLevel the maximum log level (error is the lowest, debug the highest).
+     */
+    public OSGiLoggerManager(final BundleContext ctx, int maxLevel) {
+        this.maxLevel = maxLevel;
+        
+        // Lookup the log service
+        final ServiceReference logRef = ctx.getServiceReference(LogService.class.getName());
+        this.logService = (LogService)ctx.getService(logRef);
+        
+        // FIXME: check if we need this
+        ctx.addBundleListener(new BundleListener() {
+
+            public void bundleChanged(BundleEvent ev) {
+                if (ev.getType() == BundleEvent.STOPPED) {
+                    // release the log service.
+                    ctx.ungetService(logRef);
+                }
+            }
+        });
+    }
+
+    /** Loggers by category */
+    private Map loggers = Collections.synchronizedMap(new HashMap());
+
+    public Logger getLoggerForCategory(String category) {
+        Logger result = (Logger)loggers.get(category);
+        if (result == null) {
+            result = new OSGiLogger(category);
+            loggers.put(category, result);
+        }
+        return result;
+    }
+
+    public Logger getDefaultLogger() {
+        return getLoggerForCategory("");
+    }
+    
+    /**
+     * A Logger delegating to OSGi's LogService
+     */
+    private class OSGiLogger implements Logger {
+        
+        private String category;
+
+        OSGiLogger(String category) {
+            this.category = category;
+        }
+        
+        private void log(int level, String msg) {
+            if (level <= maxLevel) {
+                logService.log(level, "[" + category + "] " + msg);
+            }
+        }
+        
+        private void log(int level, String msg, Throwable thr) {
+            if (level <= maxLevel) {
+                logService.log(level, msg, thr);
+            }
+        }
+        
+        public Logger getChildLogger(String category) {
+            return getLoggerForCategory(this.category.length() == 0 ? category : this.category + "." + category);
+        }
+        
+        private boolean isLevelEnabled(int level) {
+            return level <= maxLevel;
+        }
+
+        public void debug(String msg) {
+            log(LogService.LOG_DEBUG, msg);
+        }
+
+        public void debug(String msg, Throwable thr) {
+            log(LogService.LOG_DEBUG, msg, thr);
+            
+        }
+
+        public boolean isDebugEnabled() {
+            return isLevelEnabled(LogService.LOG_DEBUG);
+        }
+
+        public void info(String msg) {
+            log(LogService.LOG_INFO, msg);
+        }
+
+        public void info(String msg, Throwable thr) {
+            log(LogService.LOG_INFO, msg, thr);
+        }
+
+        public boolean isInfoEnabled() {
+            return isLevelEnabled(LogService.LOG_INFO);
+        }
+
+        public void warn(String msg) {
+            log(LogService.LOG_WARNING, msg);
+        }
+
+        public void warn(String msg, Throwable thr) {
+            log(LogService.LOG_WARNING, msg, thr);
+        }
+
+        public boolean isWarnEnabled() {
+            return isLevelEnabled(LogService.LOG_WARNING);
+        }
+
+        public void error(String msg) {
+            log(LogService.LOG_ERROR, msg);
+        }
+
+        public void error(String msg, Throwable thr) {
+            log(LogService.LOG_ERROR, msg, thr);
+        }
+
+        public boolean isErrorEnabled() {
+            return isLevelEnabled(LogService.LOG_ERROR);
+        }
+
+        public void fatalError(String msg) {
+            // OSGi has no "fatal" level
+            log(LogService.LOG_ERROR, msg);
+        }
+
+        public void fatalError(String msg, Throwable thr) {
+            // OSGi has no "fatal" level
+            log(LogService.LOG_ERROR, msg, thr);
+        }
+
+        public boolean isFatalErrorEnabled() {
+            // OSGi has no "fatal" level
+           return isLevelEnabled(LogService.LOG_ERROR);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiServiceManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiServiceManager.java
new file mode 100644
index 0000000..72b43cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/OSGiServiceManager.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.osgi;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A <code>ServiceManager</code> that looks up components by getting OSGi services.
+ * <p>
+ * Roles are supposed to be interface names, which the OSGi framework will use. As some
+ * roles may contain hints (e.g. "org.apache.cocoon.generation.Generator/file"), in such
+ * cases the interface name is extracted, and the hint is expected to be found in the
+ * "<code>component.hint</code>" service property.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class OSGiServiceManager implements ServiceManager {
+    
+    /**
+     * The property that's used to hold component hints in component selectors.
+     */
+    public static final String HINT_PROPERTY = "component.hint";
+    
+    private BundleContext context;
+
+    /** Mapping from service instance to ServiceReference */
+    private Map serviceReferences = new IdentityHashMap();
+
+    public OSGiServiceManager(BundleContext context) {
+        this.context = context;
+    }
+
+    public Object lookup(String role) throws ServiceException {
+        // Get the service
+        ServiceReference ref;
+        try {
+            ref = getServiceReference(this.context, role);
+        } catch (InvalidSyntaxException e) {
+            throw new ServiceException(role, "Cannot lookup OSGi service", e);
+        }
+
+        if (ref == null) {
+            throw new ServiceException(role, "OSGi service not available");
+        }
+        
+        // Important hypothesis: for a given (role, requesting bundle) value, OSGi
+        // always returns the same service instance. This seems to be implied by the
+        // specification, and how the knopflerfish implementation behaves.
+        Object service = context.getService(ref);
+        
+        // Keep track of its reference
+        synchronized(this) {
+            this.serviceReferences.put(service, ref);
+        }
+
+        return service;
+    }
+
+    public boolean hasService(String role) {
+        try {
+            return getServiceReference(this.context, role) != null;
+        } catch (InvalidSyntaxException e) {
+            return false;
+        }
+   }
+
+    public void release(Object obj) {
+        ServiceReference ref = (ServiceReference)this.serviceReferences.get(obj);
+        
+        if (ref == null) {
+            // not handled here
+            return;
+        }
+        
+        synchronized(this) {
+            if (this.context.ungetService(ref)) {
+                // No more used here: remove it from our map.
+                this.serviceReferences.remove(obj);
+            }
+        }
+    }
+    
+    public static ServiceReference getServiceReference(BundleContext ctx, String role) throws InvalidSyntaxException {
+        ServiceReference result;
+
+        int pos = role.indexOf('/');
+
+        if (pos == -1) {
+            // Single interface role
+            result = ctx.getServiceReference(role);
+        } else {
+            // Hinted role: split it
+            String itf = role.substring(0, pos);
+            String query = "(" + HINT_PROPERTY + "=" + role.substring(pos + 1) + ")";
+            ServiceReference[] results = ctx.getServiceReferences(itf, query);
+            result = (results != null && results.length > 1) ? results[0] : null;
+        }
+
+        return result;
+    }
+    
+    public static String getServiceInterface(String role) {
+        int pos = role.indexOf('/');
+        
+        return pos == -1 ? role : role.substring(0, pos);
+    }
+    
+    public static String getServiceHint(String role) {
+        int pos = role.indexOf('/');
+        return pos == -1 ? null : role.substring(pos+1);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/ServiceManagerActivator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/ServiceManagerActivator.java
new file mode 100644
index 0000000..0ba40bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/osgi/ServiceManagerActivator.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.osgi;
+
+import java.net.URL;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * @version $Id$
+ * @since 2.2
+ */
+public class ServiceManagerActivator implements BundleActivator {
+
+
+//  Registering services must go through the ServiceFactory class wrapping the componentHandler
+    
+    private ServiceManager parentManager;
+    private OSGiCoreServiceManager manager;
+
+    public void start(final BundleContext ctx) throws Exception {
+        
+        // Create a logger manager that delegates to OSGi
+        // FIXME: have the maximum level as a property of the bundle
+        LoggerManager logManager = new OSGiLoggerManager(ctx, LogService.LOG_DEBUG);
+
+        // Create a parent manager that will lookup registered OSGi services
+        this.parentManager = new OSGiServiceManager(ctx);
+        
+        // Create a regular manager
+        this.manager = new OSGiCoreServiceManager(parentManager, this.getClass().getClassLoader(), ctx) {
+        };
+
+        //---- LogEnabled
+        this.manager.enableLogging(logManager.getDefaultLogger());
+        
+        //---- Contextualizable
+        //DefaultContext avalonCtx = new ComponentContext();
+        // Context entries defined in CocoonServlet/CoreUtil:
+        // "servlet-config"
+        // "servlet-context"
+        // ContextHelper.CONTEXT_ROOT_URL
+        // Constants.CONTEXT_ENVIRONMENT_CONTEXT
+        // Constants.CONTEXT_WORK_DIR
+        // Constants.CONTEXT_UPLOAD_DIR
+        // Constants.CONTEXT_CACHE_DIR
+        // Constants.CONTEXT_CONFIG_URL
+        // Constants.CONTEXT_DEFAULT_ENCODING
+        // Constants.CONTEXT_CLASS_LOADER
+        // Core.ROLE (???)
+        // Constants.CONTEXT_CLASSPATH
+
+        this.manager.contextualize(this.getContext());
+        
+        //---- LoggerManager
+        this.manager.setLoggerManager(logManager);
+        
+        //---- RoleManager
+        // No parent role manager
+        this.manager.setRoleManager(null);
+        
+        //---- Configurable
+        this.manager.configure(this.getConfiguration(ctx));
+        this.addComponents(this.manager);
+        
+        //---- Initializable
+        this.manager.initialize();
+
+    }
+
+    public void stop(BundleContext ctx) throws Exception {
+        // Dispose the ServiceManager
+        this.manager.dispose();
+    }
+
+    protected Context getContext() throws Exception {
+        Core core = (Core)this.parentManager.lookup(Core.ROLE);
+        return core.getContext();
+    }
+
+    /**
+     * This method may be overwritten by subclasses to provide an own
+     * configuration
+     */
+    protected Configuration getConfiguration(BundleContext ctx) throws Exception {
+	URL confURL = ctx.getBundle().getResource("/WEB-INF/block.xml");
+	DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+	Configuration block = builder.build(confURL.openStream());
+	Configuration components = block.getChild("components");
+
+        return components;
+    }
+
+    /**
+     * This method may be overwritten by subclasses to add aditional
+     * components.
+     */
+    protected void addComponents(CoreServiceManager manager) 
+    throws ServiceException, ConfigurationException {
+        // subclasses can add components here
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/source/SimpleSourceResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/source/SimpleSourceResolver.java
new file mode 100644
index 0000000..d0a9169
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/core/source/SimpleSourceResolver.java
@@ -0,0 +1,193 @@
+/* 
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.source;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.source.impl.ContextSourceFactory;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.impl.ResourceSourceFactory;
+import org.apache.excalibur.source.impl.URLSourceFactory;
+
+/**
+ * A minimalist <code>SourceResolver</code> that handles a fixed restricted number of protocols. It is
+ * used as a bootstrap resolver to load roles and imported files in a service manager.
+ * <p>
+ * The supported protocols schemes are:
+ * <ul>
+ * <li><code>resource</code> to load resources in the classpath,</li>
+ * <li><code>context</code> to load resources from the context, defined by the <code>context-root</code>
+ *     entry in the Avalon {@link Context} (either a {@link File} or an {@link URL}), or if not
+ *     present, from the <code>user.dir</code> system property,</li>
+ * <li>all standard JDK schemes (http, file, etc).
+ * </ul>
+ * Relative URIs are resolved relatively to the context root, i.e. similarily to "<code>context:</code>".
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public final class SimpleSourceResolver extends AbstractLogEnabled
+    implements ThreadSafe, Contextualizable, SourceResolver {
+    
+    // The base URI, initialized in contextualize()
+    private String contextBase;
+    
+    // The three factories we use (no need for a selector nor a Map)
+    private ResourceSourceFactory resourceFactory = new ResourceSourceFactory();
+    private URLSourceFactory urlFactory = new URLSourceFactory();    
+    private ContextSourceFactory contextFactory = new ContextSourceFactory();
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
+     */
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        this.resourceFactory.enableLogging(logger);
+        this.urlFactory.enableLogging(logger);
+        this.contextFactory.enableLogging(logger);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.contextFactory.contextualize(context);
+        try {
+            this.contextFactory.service(new SimpleServiceManager(this));            
+        } catch (ServiceException se) {
+            throw new ContextException("Unable to service context factory.", se);
+        }
+
+        try {
+            // Similar to Excalibur's SourceResolverImpl, and consistent with ContextHelper.CONTEXT_ROOT_URL
+            if( context.get("context-root") instanceof URL) {
+                contextBase = ((URL)context.get("context-root")).toExternalForm();
+            } else {
+                contextBase = ((File)context.get("context-root")).toURL().toExternalForm();
+            }
+        } catch(ContextException ce) {
+            // set the base URL to the current directory
+            try {
+                contextBase = new File(System.getProperty("user.dir")).toURL().toExternalForm();
+            } catch( MalformedURLException mue) {
+                throw new ContextException( "Malformed URL for user.dir, and no context-root exists", mue);
+            }
+        } catch( MalformedURLException mue) {
+            throw new ContextException("Malformed URL for context-root", mue);
+        }
+        
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Base URL set to " + this.contextBase);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String)
+     */
+    public Source resolveURI(String uri) throws MalformedURLException, IOException {
+        return resolveURI(uri, contextBase, null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String, java.lang.String, java.util.Map)
+     */
+    public Source resolveURI(String uri, String base, Map params) throws MalformedURLException, IOException {
+        if (uri.startsWith("resource://")) {
+            return resourceFactory.getSource(uri, null);
+        } else if (uri.startsWith("context://")) {
+            return this.contextFactory.getSource(uri, params);
+        } else {
+            // special handling for windows and unix file paths
+            if( uri.length() > 1 && uri.charAt( 1 ) == ':' ) {
+                uri = "file:/" + uri;
+                base = null;
+            } else if( uri.length() > 2 && uri.charAt(0) == '/' && uri.charAt(2) == ':' ) {
+                uri = "file:" + uri;
+                base = null;
+            }
+            URL url;
+            if ( base == null ) {
+                url = new URL(uri);
+            } else {
+                URL baseURL = new URL(base);
+                url = new URL(baseURL, uri);
+            }
+            return this.urlFactory.getSource(url.toExternalForm(), params);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.excalibur.source.SourceResolver#release(org.apache.excalibur.source.Source)
+     */
+    public void release(Source source) {
+        if ( source != null ) {
+            if ( "context".equals(source.getScheme()) ) {
+                this.contextFactory.release(source);
+            } else if ( "resource".equals(source.getScheme()) ) {
+                this.resourceFactory.release(source);
+            } else {
+                this.urlFactory.release(source);
+            }
+        }
+    }
+    
+    public static final class SimpleServiceManager implements ServiceManager {
+        
+        private final SourceResolver resolver;
+        
+        public SimpleServiceManager(SourceResolver resolver) {
+            this.resolver = resolver;
+        }
+                
+        /* (non-Javadoc)
+         * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+         */
+        public boolean hasService(String role) {
+            return SourceResolver.ROLE.equals(role);
+        }
+        
+        /* (non-Javadoc)
+         * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+         */
+        public Object lookup(String role) throws ServiceException {
+            if ( !SourceResolver.ROLE.equals(role) ) {
+                throw new ServiceException("SimpleServiceManager", "Unable to lookup component with role: " + role);
+            }
+            return this.resolver;
+        }
+        
+        /* (non-Javadoc)
+         * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+         */
+        public void release(Object component) {
+            // nothing to do
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/AbstractEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/AbstractEnvironment.java
new file mode 100644
index 0000000..5eba3ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/AbstractEnvironment.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.util.BufferedOutputStream;
+import org.apache.commons.collections.iterators.IteratorEnumeration;
+
+/**
+ * Base class for any environment
+ *
+ * @version $Id$
+ */
+public abstract class AbstractEnvironment 
+    extends AbstractLogEnabled 
+    implements Environment {
+
+    /** The current uri in progress */
+    protected String uri;
+
+    /** The prefix */
+    protected String prefix = "";
+    
+    /** The View requested */
+    protected String view;
+
+    /** The Action requested */
+    protected String action;
+
+    /** The object model */
+    protected Map objectModel = new HashMap();
+
+    /** The attributes */
+    private Map attributes = new HashMap();
+
+    /** The secure Output Stream */
+    protected BufferedOutputStream secureOutputStream;
+
+    /** The real output stream */
+    protected OutputStream outputStream;
+
+    /**
+     * Constructs the abstract environment
+     */
+    public AbstractEnvironment(String uri, String view) {
+        this(uri, view, null);
+    }
+
+    /**
+     * Constructs the abstract environment
+     */
+    public AbstractEnvironment(String uri, String view, String action) {
+        this.uri = uri;
+        this.view = view;
+        this.action = action;
+    }
+
+    /**
+     * Allow implementations to set view later than in super() constructor.
+     * View can be set only once, and should be set in implementation's constructor.
+     */
+    protected void setView(String view) {
+        if (this.view != null) {
+            throw new IllegalStateException("View was already set on this environment");
+        }
+        this.view = view;
+    }
+
+    /**
+     * Allow implementations to set action later than in super() constructor
+     * Action can be set only once, and should be set in implementation's constructor.
+     */
+    protected void setAction(String action) {
+        if (this.action != null) {
+            throw new IllegalStateException("Action was already set on this environment");
+        }
+        this.action = action;
+    }
+
+    /**
+     * Helper method to extract the view name from the request.
+     */
+    protected static String extractView(Request request) {
+        return request.getParameter(Constants.VIEW_PARAM);
+    }
+
+    /**
+     * Helper method to extract the action name from the request.
+     */
+    protected static String extractAction(Request req) {
+        String action = req.getParameter(Constants.ACTION_PARAM);
+        if (action != null) {
+            /* TC: still support the deprecated syntax */
+            return action;
+        }
+        for(Enumeration e = req.getParameterNames(); e.hasMoreElements(); ) {
+            String name = (String)e.nextElement();
+            if (name.startsWith(Constants.ACTION_PARAM_PREFIX)) {
+                if (name.endsWith(".x") || name.endsWith(".y")) {
+                    return name.substring(Constants.ACTION_PARAM_PREFIX.length(),name.length()-2);
+                }
+                 return name.substring(Constants.ACTION_PARAM_PREFIX.length());
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURI()
+     */
+    public String getURI() {
+        return this.uri;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURIPrefix()
+     */
+    public String getURIPrefix() {
+        return this.prefix;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setURI(java.lang.String)
+     */
+    public void setURI(String prefix, String value) {
+        this.prefix = prefix;
+        this.uri = value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getView()
+     */
+    public String getView() {
+        return this.view;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAction()
+     */
+    public String getAction() {
+        return this.action;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setStatus(int)
+     */
+    public void setStatus(int statusCode) {
+        // for subclasses
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getObjectModel()
+     */
+    public Map getObjectModel() {
+        return this.objectModel;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isResponseModified(long)
+     */
+    public boolean isResponseModified(long lastModified) {
+        return true; // always modified
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setResponseIsNotModified()
+     */
+    public void setResponseIsNotModified() {
+        // does nothing
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.attributes.put(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.attributes.remove(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return new IteratorEnumeration(this.attributes.keySet().iterator());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getOutputStream(int)
+     */
+    public OutputStream getOutputStream(int bufferSize)
+    throws IOException {
+
+        // This method could be called several times during request processing
+        // with differing values of bufferSize and should handle this situation
+        // correctly.
+
+        if (bufferSize == -1) {
+            if (this.secureOutputStream == null) {
+                this.secureOutputStream = new BufferedOutputStream(this.outputStream);
+            }
+            return this.secureOutputStream;
+        } else if (bufferSize == 0) {
+            // Discard secure output stream if it was created before.
+            if (this.secureOutputStream != null) {
+                this.secureOutputStream = null;
+            }
+            return this.outputStream;
+        } else {
+            // FIXME Triple buffering, anyone?
+            this.outputStream = new java.io.BufferedOutputStream(this.outputStream, bufferSize);
+            return this.outputStream;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#tryResetResponse()
+     */
+    public boolean tryResetResponse()
+    throws IOException {
+        if (this.secureOutputStream != null) {
+            this.secureOutputStream.clearBuffer();
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#commitResponse()
+     */
+    public void commitResponse()
+    throws IOException {
+        if (this.secureOutputStream != null) {
+            this.setContentLength(this.secureOutputStream.getCount());
+            this.secureOutputStream.realFlush();
+        } else if ( this.outputStream != null ){
+            this.outputStream.flush();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#startingProcessing()
+     */
+    public void startingProcessing() {
+        // do nothing here
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#finishingProcessing()
+     */
+    public void finishingProcessing() {
+        // do nothing here
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isInternRedirect()
+     */
+    public boolean isInternalRedirect() {
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/CocoonRunnable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/CocoonRunnable.java
new file mode 100644
index 0000000..4eca8fe
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/CocoonRunnable.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+
+/**
+ * A <code>Runnable</code> wrapper or base class that inherits the execution
+ * context of the thread creating it, as it was at the time of creation.
+ * <p>
+ * It is meant to be used when processing of a request is to be split across several
+ * cooperating threads (e.g. parallel aggregation).
+ * <p>
+ * <strong>Note</strong>: a <code>CocoonRunnable</code> should not live longer than the
+ * end of the execution of the request in the creating thread, otherwise some unexpected
+ * behaviours may happen because the parent's environment has been released.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class CocoonRunnable extends EnvironmentHelper.AbstractCocoonRunnable {
+    Runnable target;
+
+    /**
+     * Creates an empty <code>CocoonRunnable</code> and copies the environment context
+     * of the calling thread, for later use when calling {@link #doRun()}. Users of this
+     * constructor will override the {@link #doRun()} method where the actual job gets done.
+     */
+    public CocoonRunnable() {
+        // Nothing special here
+    }
+
+    /**
+     * Wraps an existing <code>Runnable</code> and copies the environment context of
+     * the calling thread, for later use when the <code>Runnable</code>'s <code>run()</code>
+     * method is called.
+     * 
+     * @param target the wrapped <code>Runnable</code>
+     */
+    public CocoonRunnable(Runnable target) {
+        this.target = target;
+    }
+
+    /**
+     * Does the actual job, in the environment of the creating thread. Calls the wrapped
+     * <code>Runnable</code> if one was given, and does nothing otherwise.
+     */
+    protected void doRun() {
+        if (target != null) {
+            target.run();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Context.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Context.java
new file mode 100644
index 0000000..adee09f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Context.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Map;
+import java.io.InputStream;
+
+/**
+ * Defines an interface to provide context information.
+ *
+ * @version $Id$
+ *
+ */
+public interface Context {
+
+    Object getAttribute(String name);
+
+    void setAttribute(String name, Object value);
+
+    /**
+     * Utility method for getting a <code>Map</code> view of the context attributes.
+     * Returns a <code>Map</code> with context attributes.
+     *
+     * @return                a <code>Map</code> containing the context attributes.
+     *
+     * @since 2.2
+     */
+    Map getAttributes();
+
+    void removeAttribute(String name);
+
+    Enumeration getAttributeNames();
+
+    URL getResource(String path) throws MalformedURLException;
+
+    String getRealPath(String path);
+
+    String getMimeType(String file);
+
+    String getInitParameter(String name);
+
+    InputStream getResourceAsStream(String path);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Cookie.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Cookie.java
new file mode 100644
index 0000000..8edafdf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Cookie.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link Response#addCookie(Cookie)} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link Request#getCookies()} method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @version $Id$
+ */
+public interface Cookie {
+
+    /**
+     *
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie
+     * to the user. Comments
+     * are not supported by Netscape Version 0 cookies.
+     *
+     * @param purpose		a <code>String</code> specifying the comment
+     *				to display to the user
+     *
+     * @see #getComment()
+     *
+     */
+
+    void setComment(String purpose);
+
+
+
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * <code>null</code> if the cookie has no comment.
+     *
+     * @return			a <code>String</code> containing the comment,
+     *				or <code>null</code> if none
+     *
+     * @see #setComment(String)
+     *
+     */
+
+    String getComment();
+
+
+
+
+    /**
+     *
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p>The form of the domain name is specified by RFC 2109. A domain
+     * name begins with a dot (<code>.foo.com</code>) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, <code>www.foo.com</code>, but not
+     * <code>a.b.foo.com</code>). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     *
+     * @param pattern		a <code>String</code> containing the domain name
+     *				within which this cookie is visible;
+     *				form is according to RFC 2109
+     *
+     * @see #getDomain()
+     *
+     */
+
+    void setDomain(String pattern);
+
+
+
+
+
+    /**
+     * Returns the domain name set for this cookie. The form of
+     * the domain name is set by RFC 2109.
+     *
+     * @return			a <code>String</code> containing the domain name
+     *
+     * @see #setDomain(String)
+     *
+     */
+
+    String getDomain();
+
+
+
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p>A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p>A negative value means
+     * that the cookie is not stored persistently and will be deleted
+     * when the Web browser exits. A zero value causes the cookie
+     * to be deleted.
+     *
+     * @param expiry		an integer specifying the maximum age of the
+     * 				cookie in seconds; if negative, means
+     *				the cookie is not stored; if zero, deletes
+     *				the cookie
+     *
+     *
+     * @see #getMaxAge()
+     *
+     */
+
+    void setMaxAge(int expiry);
+
+
+
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds,
+     * By default, <code>-1</code> indicating the cookie will persist
+     * until browser shutdown.
+     *
+     *
+     * @return			an integer specifying the maximum age of the
+     *				cookie in seconds; if negative, means
+     *				the cookie persists until browser shutdown
+     *
+     *
+     * @see #setMaxAge(int)
+     *
+     */
+
+    int getMaxAge();
+
+
+
+
+    /**
+     * Specifies a path for the cookie
+     * to which the client should return the cookie.
+     *
+     * <p>The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories.
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p>Consult RFC 2109 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     *
+     * @param uri		a <code>String</code> specifying a path
+     *
+     *
+     * @see #getPath()
+     *
+     */
+
+    void setPath(String uri);
+
+
+
+
+    /**
+     * Returns the path on the server
+     * to which the browser returns this cookie. The
+     * cookie is visible to all subpaths on the server.
+     *
+     *
+     * @return		a <code>String</code> specifying a path that contains
+     *			a servlet name, for example, <i>/catalog</i>
+     *
+     * @see #setPath(String)
+     *
+     */
+
+    String getPath();
+
+
+
+
+
+    /**
+     * Indicates to the browser whether the cookie should only be sent
+     * using a secure protocol, such as HTTPS or SSL.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @param flag	if <code>true</code>, sends the cookie from the browser
+     *			to the server using only when using a secure protocol;
+     *			if <code>false</code>, sent on any protocol
+     *
+     * @see #getSecure()
+     *
+     */
+
+    void setSecure(boolean flag);
+
+
+
+
+    /**
+     * Returns <code>true</code> if the browser is sending cookies
+     * only over a secure protocol, or <code>false</code> if the
+     * browser can send cookies using any protocol.
+     *
+     * @return		<code>true</code> if the browser can use
+     *			any standard protocol; otherwise, <code>false</code>
+     *
+     * @see #setSecure(boolean)
+     *
+     */
+
+    boolean getSecure();
+
+
+
+
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return		a <code>String</code> specifying the cookie's name
+     *
+     */
+
+    String getName();
+
+
+
+
+
+    /**
+     *
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p>With Version 0 cookies, values should not contain white
+     * space, brackets, parentheses, equals signs, commas,
+     * double quotes, slashes, question marks, at signs, colons,
+     * and semicolons. Empty values may not behave the same way
+     * on all browsers.
+     *
+     * @param newValue		a <code>String</code> specifying the new value
+     *
+     *
+     * @see #getValue()
+     * @see Cookie
+     *
+     */
+
+    void setValue(String newValue);
+
+
+
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return			a <code>String</code> containing the cookie's
+     *				present value
+     *
+     * @see #setValue(String)
+     * @see Cookie
+     *
+     */
+
+    String getValue();
+
+
+
+
+    /**
+     * Returns the version of the protocol this cookie complies
+     * with. Version 1 complies with RFC 2109,
+     * and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided
+     * by a browser use and identify the browser's cookie version.
+     *
+     *
+     * @return			0 if the cookie complies with the
+     *				original Netscape specification; 1
+     *				if the cookie complies with RFC 2109
+     *
+     * @see #setVersion(int)
+     *
+     */
+
+    int getVersion();
+
+
+
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2109.
+     *
+     * <p>Since RFC 2109 is still somewhat new, consider
+     * version 1 as experimental; do not use it yet on production sites.
+     *
+     *
+     * @param v			0 if the cookie should comply with
+     *				the original Netscape specification;
+     *				1 if the cookie should comply with RFC 2109
+     *
+     * @see #getVersion()
+     *
+     */
+
+    void setVersion(int v);
+
+
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Environment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Environment.java
new file mode 100644
index 0000000..9ef3ab1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Environment.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Map;
+
+/**
+ * Base interface for an environment abstraction
+ *
+ * @version $Id$
+ */
+public interface Environment {
+
+    /**
+     * Get the URI to process. The prefix is stripped off.
+     */
+    String getURI();
+
+    /**
+     * Get the prefix of the URI in progress.
+     */
+    String getURIPrefix();
+
+    /**
+     * Set the URI and the prefix to process.
+     */
+    void setURI(String prefix, String value);
+
+    /**
+     * Get the view to process
+     */
+    String getView();
+
+    /**
+     * Get the action to process
+     */
+    String getAction();
+
+    /**
+     * Redirect to the given URL
+     */
+    void redirect(String url, boolean global, boolean permanent) 
+    throws IOException;
+
+    /**
+     * Set the content type of the generated resource
+     */
+    void setContentType(String mimeType);
+
+    /**
+     * Get the content type of the resource
+     */
+    String getContentType();
+
+    /**
+     * Set the length of the generated content
+     */
+    void setContentLength(int length);
+
+    /**
+     * Set the response status code
+     */
+    void setStatus(int statusCode);
+
+    /**
+     * Get the output stream where to write the generated resource.
+     * The returned stream is buffered by the environment. If the
+     * buffer size is -1 then the complete output is buffered.
+     * If the buffer size is 0, no buffering takes place.
+     */
+    OutputStream getOutputStream(int bufferSize) throws IOException;
+
+    /**
+     * Get the underlying object model
+     */
+    Map getObjectModel();
+
+    /**
+     * Check if the response has been modified since the same
+     * "resource" was requested.
+     * The caller has to test if it is really the same "resource"
+     * which is requested.
+     * @return true if the response is modified or if the
+     *         environment is not able to test it
+     */
+    boolean isResponseModified(long lastModified);
+
+    /**
+     * Mark the response as not modified.
+     */
+    void setResponseIsNotModified();
+
+    /**
+     * Binds an object to this environment, using the name specified. This allows
+     * the pipeline assembly engine to store for its own use objects that souldn't
+     * be exposed to other components (generators, selectors, etc) and therefore
+     * cannot be put in the object model.
+     * <p>
+     * If an object of the same name is already bound, the object is replaced.
+     *
+     * @param name  the name to which the object is bound
+     * @param value the object to be bound
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     * Returns the object bound with the specified name, or <code>null</code>
+     * if no object is bound under the name.
+     *
+     * @param name                a string specifying the name of the object
+     * @return                    the object with the specified name
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Removes the object bound with the specified name from
+     * this environment. If the environment does not have an object
+     * bound with the specified name, this method does nothing.
+     *
+     * @param name the name of the object to remove
+     */
+    void removeAttribute(String name);
+
+    /**
+     * Returns an <code>Enumeration</code> of <code>String</code> objects
+     * containing the names of all the objects bound to this environment.
+     *
+     * @return an <code>Enumeration</code> of <code>String</code>s.
+     */
+    Enumeration getAttributeNames();
+
+    /**
+     * Reset the response if possible. This allows error handlers to have
+     * a higher chance to produce clean output if the pipeline that raised
+     * the error has already output some data.
+     * If a buffered output stream is used, resetting is always successful.
+     *
+     * @return true if the response was successfully reset
+     */
+    boolean tryResetResponse() throws IOException;
+
+
+    /**
+     * Commit the response
+     */
+    void commitResponse() throws IOException;
+    
+    /**
+     * Notify that the processing starts.
+     */
+    void startingProcessing();
+    
+    /**
+     * Notify that the processing is finished
+     * This can be used to cleanup the environment object
+     */
+    void finishingProcessing();
+    
+    /**
+     * Is this environment external ? An external environment is one that 
+     * is created in response to an external request (http, commandline, etc.). 
+     * Environments created by the "cocoon:" protocol aren't external.
+     * 
+     * @return true if this environment is external
+     */
+    boolean isExternal();
+    
+    /**
+     * Is this an internal redirect?
+     * An environment is on internal redirect if it is an internal request
+     * (via the cocoon: protocol) and used for a redirect.
+     */
+    boolean isInternalRedirect();
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ForwardRedirector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ForwardRedirector.java
new file mode 100644
index 0000000..da13f50
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ForwardRedirector.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.io.IOException;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * A base class for <code>Redirector</code>s that handle forward redirects, i.e. internal
+ * redirects using the "cocoon:" pseudo-protocol.
+ * <p>
+ * Concrete subclasses have to define the <code>cocoonRedirect()</code> method.
+ *
+ * @version $Id$
+ */
+public abstract class ForwardRedirector 
+extends AbstractLogEnabled 
+implements Redirector, PermanentRedirector {
+
+    /**
+     * Was there a call to <code>redirect()</code> ?
+     */
+    private boolean hasRedirected = false;
+    
+    /** The <code>Environment to use for redirection (either internal or external) */
+    protected Environment env;
+
+    /**
+     * Constructor
+     */
+    public ForwardRedirector(Environment env) {
+        this.env = env;
+    }
+
+    /**
+     * Redirects to a given URL. If this URL starts with "cocoon:", then an internal
+     * redirect is performed. Otherwise, an external redirect is send to the
+     * environment.
+     */
+    public void redirect(boolean sessionMode, String url) throws IOException, ProcessingException {
+        if (getLogger().isInfoEnabled()) {
+            getLogger().info("Redirecting to '" + url + "'");
+        }
+
+        if (url.startsWith("cocoon:")) {
+            cocoonRedirect(url);
+        } else {
+            this.doRedirect(sessionMode, url, false, false);
+        }
+
+        this.hasRedirected = true;
+    }
+
+    public void permanentRedirect(boolean sessionMode, String url) throws IOException, ProcessingException {
+        if (getLogger().isInfoEnabled()) {
+            getLogger().info("Redirecting to '" + url + "'");
+        }
+
+        if (url.startsWith("cocoon:")) {
+            cocoonRedirect(url);
+        } else {
+            this.doRedirect(sessionMode, url, true, false);
+        }
+
+        this.hasRedirected = true;
+    }
+
+    /**
+     * Unconditionally redirects to a given URL, even it this redirector is part of a
+     * subpipeline.
+     */
+    public void globalRedirect(boolean sessionMode, String url) throws IOException, ProcessingException {
+        if (getLogger().isInfoEnabled()) {
+            getLogger().info("Redirecting to '" + url + "'");
+        }
+
+        // FIXME : how to handle global redirect to cocoon: ?
+        if (url.startsWith("cocoon:")) {
+            cocoonRedirect(url);
+        } else {
+            this.doRedirect(sessionMode, url, false, true);
+        }
+        this.hasRedirected = true;
+    }
+
+    protected abstract void cocoonRedirect(String uri) throws IOException, ProcessingException;
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Redirector#hasRedirected()
+     */
+    public boolean hasRedirected() {
+        return this.hasRedirected;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Redirector#sendStatus(int)
+     */
+    public void sendStatus(int sc) {
+        env.setStatus(sc);
+        this.hasRedirected = true;
+    }
+
+
+    /**
+     * Redirect the client to new URL with session mode
+     */
+    protected void doRedirect(boolean sessionmode, 
+                                String newURL, 
+                                boolean permanent,
+                                boolean global) 
+    throws IOException {
+        final Request request = ObjectModelHelper.getRequest(this.env.getObjectModel());
+        // check if session mode shall be activated
+        if (sessionmode) {
+
+            // The session
+            Session session = null;
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("redirect: entering session mode");
+            }
+            String s = request.getRequestedSessionId();
+            if (s != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Old session ID found in request, id = " + s);
+                    if ( request.isRequestedSessionIdValid() ) {
+                        getLogger().debug("And this old session ID is valid");
+                    }
+                }
+            }
+            // get session from request, or create new session
+            session = request.getSession(true);
+            if (session == null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("redirect session mode: unable to get session object!");
+                }
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug ("redirect: session mode completed, id = " + session.getId() );
+            }
+        }
+        // redirect
+        this.env.redirect(newURL, global, permanent);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ObjectModelHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ObjectModelHelper.java
new file mode 100644
index 0000000..4af4c15
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/ObjectModelHelper.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.util.Map;
+
+/**
+ * A set of constants and methods to access the content of the object model.
+ * <p>
+ * The object model is a <code>Map</code> used to pass information about the
+ * calling environment to the sitemap and its components (matchers, actions,
+ * transformers, etc).
+ * <p>
+ * This class provides accessors only for the objects in the object model that are
+ * common to every environment and which can thus be used safely. Some environments
+ * provide additional objects, but they are not described here and accessing them
+ * should be done in due cause since this ties the application to that particular
+ * environment.
+ *
+ * @version $Id$
+ */
+public final class ObjectModelHelper {
+
+    /** Key for the environment {@link Request} in the object model. */
+    public final static String REQUEST_OBJECT  = "request";
+
+    /** Key for the environment {@link Response} in the object model. */
+    public final static String RESPONSE_OBJECT = "response";
+
+    /** Key for the environment {@link Context} in the object model. */
+    public final static String CONTEXT_OBJECT  = "context";
+
+    /** Key for the expiration value (Long) in the object model. */
+    public final static String EXPIRES_OBJECT  = "expires";
+    
+    /** Key for the throwable object, only available within a &lt;map:handle-errors>. */
+    public final static String THROWABLE_OBJECT = "throwable";
+
+    /**
+     * Key for a {@link Map} containing information from
+     * a parent request provided to a sub-request (internal processing)
+     */
+    public final static String PARENT_CONTEXT = "parent-context";
+
+
+    private ObjectModelHelper() {
+        // Forbid instantiation
+    }
+
+    public static final Request getRequest(Map objectModel) {
+        return (Request)objectModel.get(REQUEST_OBJECT);
+    }
+
+    public static final Response getResponse(Map objectModel) {
+        return (Response)objectModel.get(RESPONSE_OBJECT);
+    }
+
+    public static final Context getContext(Map objectModel) {
+        return (Context)objectModel.get(CONTEXT_OBJECT);
+    }
+
+    public static final Long getExpires(Map objectModel) {
+        return (Long)objectModel.get(EXPIRES_OBJECT);
+    }
+    
+    public static final Throwable getThrowable(Map objectModel) {
+        return (Throwable)objectModel.get(THROWABLE_OBJECT);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/PermanentRedirector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/PermanentRedirector.java
new file mode 100644
index 0000000..69938e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/PermanentRedirector.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import org.apache.cocoon.ProcessingException;
+import java.io.IOException;
+
+/**
+ * Interface for a permanent redirector abstraction
+ *
+ * @version $Id$
+ */
+public interface PermanentRedirector {
+
+    /**
+     * Redirect to the given URL
+     */
+    void permanentRedirect(boolean sessionmode, String url) throws IOException, ProcessingException;
+ }
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Redirector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Redirector.java
new file mode 100644
index 0000000..e30b972
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Redirector.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import org.apache.cocoon.ProcessingException;
+import java.io.IOException;
+
+/**
+ * Interface for an redirector abstraction
+ *
+ * @version $Id$
+ */
+public interface Redirector {
+
+    /**
+     * Redirect to the given URL
+     */
+    void redirect(boolean sessionmode, String url) throws IOException, ProcessingException;
+    void globalRedirect(boolean sessionmode, String url) throws IOException, ProcessingException;
+    
+    /**
+     * Was one of the redirection methods called ?
+     */
+    boolean hasRedirected();
+    
+    /**
+     * Send a content-less response with the given status code.
+     * 
+     * @param sc  an http status code.
+     */
+    void sendStatus(int sc);
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Request.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Request.java
new file mode 100644
index 0000000..7769152
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Request.java
@@ -0,0 +1,991 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Defines an interface to provide client request information .
+ *
+ * A client can bind an object attribute into a <code>Request</code> by name.
+ * The <code>Request</code> interface defines two scopes for storing objects:
+ * <ul>
+ * <li><code>GLOBAL_SCOPE</code>
+ * <li><code>REQUEST_SCOPE</code>
+ * </ul>
+ * All objects stored in the request using the <code>GLOBAL_SCOPE</code> 
+ * are available to all sub requests and the main request associatiated
+ * Objects stored in the request using the <code>REQUEST_SCOPE</code> are
+ * only available for the current (sub) request.
+ * 
+ * @version $Id$
+ */
+public interface Request {
+
+    /**
+     * This constant defines an request wide scope for the request attribute.
+     * @since 2.2
+     */
+    public static final int GLOBAL_SCOPE = 1;
+
+    /**
+     * This constant defines the scope of the request attribute to be
+     * private to the current (sub) request. 
+     * @since 2.2
+     */
+    public static final int REQUEST_SCOPE = 2;
+
+    /**
+     *
+     * Returns the value of the named parameter as an <code>Object</code>,
+     * or <code>null</code> if no parameter of the given name exists.
+     * Basically, this method is similar to {@link #getParameter(String)},
+     * but it returns an object instead. 
+     * This is useful when special processing has been made on these parameters,
+     * for example for file uploads. In this case you get an object 
+     * representing the uploaded file.
+     * If the parameters have not been processed, you either get a String
+     * object if the parameter has one value, or a Collection of Strings
+     * if the parameter has more than one value.
+     * 
+     * @param name        a <code>String</code> specifying the name of
+     *                        the parameter
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the parameter, or <code>null</code> if
+     *                        the parameter does not exist
+     *
+     */
+
+    Object get(String name);
+
+    /**
+     *
+     * Returns the value of the named attribute from the <code>GLOBAL_SCOPE</code>
+     * as an <code>Object</code>, or <code>null</code> if no attribute 
+     * of the given name exists.
+     *
+     * @param name        a <code>String</code> specifying the name of
+     *                        the attribute
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the attribute, or <code>null</code> if
+     *                        the attribute does not exist
+     *
+     */
+    Object getAttribute(String name);
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * names of the attributes available to this request in the  <code>GLOBAL_SCOPE</code>.
+     * This method returns an empty <code>Enumeration</code>
+     * if the request has no attributes available to it.
+     *
+     *
+     * @return                an <code>Enumeration</code> of strings
+     *                        containing the names
+     *                         of the request's attributes
+     *
+     */
+    Enumeration getAttributeNames();
+
+    /**
+     *
+     * Stores an attribute in this request in the <code>GLOBAL_SCOPE</code>.
+     * Attributes are reset between requests.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute
+     *
+     * @param o                                the <code>Object</code> to be stored
+     *
+     */
+    void setAttribute(String name, Object o);
+
+    /**
+     *
+     * Removes an attribute from this request in the <code>GLOBAL_SCOPE</code>.  
+     * This method is not
+     * generally needed as attributes only persist as long as the request
+     * is being handled.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute to remove
+     *
+     */
+    void removeAttribute(String name);
+
+    /**
+     * Returns the value of the named attribute from the scope
+     * as an <code>Object</code>, or <code>null</code> if no attribute 
+     * of the given name exists.
+     *
+     * @param name        a <code>String</code> specifying the name of
+     *                        the attribute
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the attribute, or <code>null</code> if
+     *                        the attribute does not exist
+     *
+     * @since 2.2
+     */
+    Object getAttribute(String name, int scope);
+
+    /**
+     * Returns the value of the named attribute searching both scopes
+     * as an <code>Object</code>, or <code>null</code> if no attribute 
+     * of the given name exists. This method first searches in the 
+     * request scope and then, if no object is found, in the global scope.
+     *
+     * @param name        a <code>String</code> specifying the name of
+     *                        the attribute
+     *
+     * @return                an <code>Object</code> containing the value
+     *                        of the attribute, or <code>null</code> if
+     *                        the attribute does not exist
+     *
+     * @since 2.2
+     */
+    Object searchAttribute(String name);
+
+    /**
+     * Returns an <code>Enumeration</code> containing the
+     * names of the attributes available to this request in the scope.
+     * This method returns an empty <code>Enumeration</code>
+     * if the request has no attributes available to it.
+     *
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @return                an <code>Enumeration</code> of strings
+     *                        containing the names
+     *                         of the request's attributes
+     *
+     * @since 2.2
+     */
+    Enumeration getAttributeNames(int scope);
+
+    /**
+     *
+     * Stores an attribute in this request in the scope.
+     * Attributes are reset between requests.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                    the name of the attribute    
+     * @param o                            the <code>Object</code> to be stored
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @since 2.2
+     */
+    void setAttribute(String name, Object o, int scope);
+
+    /**
+     * Removes an attribute from this request in the scope.  
+     * This method is not
+     * generally needed as attributes only persist as long as the request
+     * is being handled.
+     *
+     * <p>Attribute names should follow the same conventions as
+     * package names. Names beginning with <code>java.*</code>,
+     * <code>javax.*</code>, and <code>com.sun.*</code>, are
+     * reserved for use by Sun Microsystems.
+     *
+     *
+     * @param name                        a <code>String</code> specifying
+     *                                        the name of the attribute to remove
+     * @param scope        scope (global or request) of the attribute
+     *
+     * @since 2.2
+     */
+    void removeAttribute(String name, int scope);
+
+    /**
+     * Utility method for getting a <code>Map</code> view of the request attributes.
+     * Returns a <code>Map</code> with attributes from the <code>GLOBAL_SCOPE</code>.
+     *
+     * @return                a <code>Map</code> containing the request attributes.
+     *
+     * @since 2.2
+     */
+    Map getAttributes();
+
+    /**
+     *
+     * Returns the name of the authentication scheme used to protect
+     * the servlet, for example, "BASIC" or "SSL," or null if the servlet was
+     * not protected
+     *
+     * @return                The name of the authentication scheme used to
+     *                        protect the servlet, or null if the servlet was
+     *                        not protected
+     */
+
+    String getAuthType();
+
+    /**
+     * Returns the name of the character encoding used in the body of this
+     * request. This method returns <code>null</code> if the request
+     * does not specify a character encoding
+     *
+     *
+     * @return                a <code>String</code> containing the name of
+     *                        the chararacter encoding, or <code>null</code>
+     *                        if the request does not specify a character encoding
+     *
+     */
+
+    String getCharacterEncoding();
+
+    /**
+     * Overrides the charactor encoding of parameters.
+     *
+     * @throws java.io.UnsupportedEncodingException if this is not a valid encoding.
+     *
+     */
+
+    void setCharacterEncoding(String enc) throws java.io.UnsupportedEncodingException;
+
+    /**
+     * Returns the length, in bytes, of the request body
+     *
+     * @return                an integer containing the length of the
+     *                         request body or -1 if the length is not known
+     *
+     */
+
+    int getContentLength();
+
+    /**
+     * Returns the MIME type of the body of the request
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the MIME type of
+     *                         the request, or -1 if the type is not known
+     *
+     */
+
+    String getContentType();
+
+    /**
+     * Returns the value of a request parameter as a <code>String</code>,
+     *
+     * @param name         a <code>String</code> specifying the
+     *                        name of the parameter
+     *
+     * @return                a <code>String</code> representing the
+     *                        single value of the parameter
+     *
+     * @see                 #getParameterValues(String)
+     *
+     */
+
+    String getParameter(String name);
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code>
+     * objects containing the names of the parameters contained
+     * in this request. If the request has
+     * no parameters, the method returns an
+     * empty <code>Enumeration</code>.
+     *
+     * @return                an <code>Enumeration</code> of <code>String</code>
+     *                        objects, each <code>String</code> containing
+     *                         the name of a request parameter; or an
+     *                        empty <code>Enumeration</code> if the
+     *                        request has no parameters
+     *
+     */
+
+    Enumeration getParameterNames();
+
+    /**
+     * Returns an array of <code>String</code> objects containing
+     * all of the values the given request parameter has, or
+     * <code>null</code> if the parameter does not exist.
+     *
+     * <p>If the parameter has a single value, the array has a length
+     * of 1.
+     *
+     * @param name        a <code>String</code> containing the name of
+     *                        the parameter whose value is requested
+     *
+     * @return                an array of <code>String</code> objects
+     *                        containing the parameter's values
+     *
+     * @see                #getParameter(String)
+     *
+     */
+
+    String[] getParameterValues(String name);
+
+
+    /**
+     * Utility method for getting a <code>Map</code> view of the request parameters.
+     * Returns a <code>Map</code> with request parameters.
+     *
+     * @return                a <code>Map</code> containing the request parameters.
+     *
+     * @since 2.2
+     */
+    Map getParameters();
+
+    /**
+     * Returns the name and version of the protocol the request uses
+     * in the form <i>protocol/majorVersion.minorVersion</i>, for
+     * example, HTTP/1.1. For HTTP servlets, the value
+     * returned is the same as the value of the CGI variable
+     * <code>SERVER_PROTOCOL</code>.
+     *
+     * @return                a <code>String</code> containing the protocol
+     *                        name and version number
+     *
+     */
+
+    String getProtocol();
+
+    /**
+     * Returns the name of the scheme used to make this request,
+     * for example,
+     * <code>http</code>, <code>https</code>, or <code>ftp</code>.
+     * Different schemes have different rules for constructing URLs,
+     * as noted in RFC 1738.
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the scheme used to make this request
+     *
+     */
+
+    String getScheme();
+
+    /**
+     * Returns the host name of the server that received the request.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_NAME</code>.
+     *
+     * @return                a <code>String</code> containing the name
+     *                        of the server to which the request was sent
+     */
+
+    String getServerName();
+
+    /**
+     * Returns the port number on which this request was received.
+     * For HTTP servlets, same as the value of the CGI variable
+     * <code>SERVER_PORT</code>.
+     *
+     * @return                an integer specifying the port number
+     *
+     */
+
+    int getServerPort();
+
+    /**
+     * Returns the Internet Protocol (IP) address of the client
+     * that sent the request.  For HTTP servlets, same as the value of the
+     * CGI variable <code>REMOTE_ADDR</code>.
+     *
+     * @return                a <code>String</code> containing the
+     *                        IP address of the client that sent the request
+     *
+     */
+
+    String getRemoteAddr();
+
+    /**
+     * Returns the fully qualified name of the client that sent the
+     * request, or the IP address of the client if the name cannot be
+     * determined. For HTTP servlets, same as the value of the CGI variable
+     * <code>REMOTE_HOST</code>.
+     *
+     * @return                a <code>String</code> containing the fully qualified name
+     *                        of the client
+     *
+     */
+
+    String getRemoteHost();
+
+    /**
+     *
+     * Returns the preferred <code>Locale</code> that the client will
+     * accept content in, based on the Accept-Language header.
+     * If the client request doesn't provide an Accept-Language header,
+     * this method returns the default locale for the server.
+     *
+     *
+     * @return                the preferred <code>Locale</code> for the client
+     *
+     */
+
+    Locale getLocale();
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>Locale</code> objects
+     * indicating, in decreasing order starting with the preferred locale, the
+     * locales that are acceptable to the client based on the Accept-Language
+     * header.
+     * If the client request doesn't provide an Accept-Language header,
+     * this method returns an <code>Enumeration</code> containing one
+     * <code>Locale</code>, the default locale for the server.
+     *
+     *
+     * @return                an <code>Enumeration</code> of preferred
+     *                  <code>Locale</code> objects for the client
+     *
+     */
+
+    Enumeration getLocales();
+
+    /**
+     *
+     * Returns a boolean indicating whether this request was made using a
+     * secure channel, such as HTTPS.
+     *
+     *
+     * @return                a boolean indicating if the request was made using a
+     *                  secure channel
+     *
+     */
+
+    boolean isSecure();
+
+    /**
+     *
+     * Returns an array containing all of the <code>Cookie</code>
+     * objects the client sent with this request.
+     * This method returns <code>null</code> if no cookies were sent.
+     *
+     * @return                an array of all the <code>Cookies</code>
+     *                        included with this request, or <code>null</code>
+     *                        if the request has no cookies
+     *
+     *
+     */
+
+    Cookie[] getCookies();
+
+    /**
+     * Returns a map of the <code>Cookie</code> objects the client sent
+     * with this request, indexed by name. This method returns an empty
+     * map if no cookies were sent.
+     *
+     * @return a Map of <code>Cookie</code> objects
+     */
+    Map getCookieMap();
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>long</code> value that represents a
+     * <code>Date</code> object. Use this method with
+     * headers that contain dates, such as
+     * <code>If-Modified-Since</code>.
+     *
+     * <p>The date is returned as
+     * the number of milliseconds since January 1, 1970 GMT.
+     * The header name is case insensitive.
+     *
+     * <p>If the request did not have a header of the
+     * specified name, this method returns -1. If the header
+     * can't be converted to a date, the method throws
+     * an <code>IllegalArgumentException</code>.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                name of the header
+     *
+     * @return                        a <code>long</code> value
+     *                                representing the date specified
+     *                                in the header expressed as
+     *                                the number of milliseconds
+     *                                since January 1, 1970 GMT,
+     *                                or -1 if the named header
+     *                                was not included with the
+     *                                reqest
+     *
+     * @exception        IllegalArgumentException        If the header value
+     *                                                        can't be converted
+     *                                                        to a date
+     *
+     */
+
+    long getDateHeader(String name);
+
+    /**
+     *
+     * Returns the value of the specified request header
+     * as a <code>String</code>. If the request did not include a header
+     * of the specified name, this method returns <code>null</code>.
+     * The header name is case insensitive. You can use
+     * this method with any request header.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                header name
+     *
+     * @return                        a <code>String</code> containing the
+     *                                value of the requested
+     *                                header, or <code>null</code>
+     *                                if the request does not
+     *                                have a header of that name
+     *
+     */
+
+    String getHeader(String name);
+
+    /**
+     *
+     * Returns all the values of the specified request header
+     * as an <code>Enumeration</code> of <code>String</code> objects.
+     *
+     * <p>Some headers, such as <code>Accept-Language</code> can be sent
+     * by clients as several headers each with a different value rather than
+     * sending the header as a comma separated list.
+     *
+     * <p>If the request did not include any headers
+     * of the specified name, this method returns an empty
+     * <code>Enumeration</code>.
+     * The header name is case insensitive. You can use
+     * this method with any request header.
+     *
+     * @param name                a <code>String</code> specifying the
+     *                                header name
+     *
+     * @return                        a <code>Enumeration</code> containing the
+     *                                values of the requested
+     *                                header, or <code>null</code>
+     *                                if the request does not
+     *                                have any headers of that name
+     *
+     */
+
+    Enumeration getHeaders(String name);
+
+    /**
+     *
+     * Returns an enumeration of all the header names
+     * this request contains. If the request has no
+     * headers, this method returns an empty enumeration.
+     *
+     * <p>Some servlet containers do not allow do not allow
+     * servlets to access headers using this method, in
+     * which case this method returns <code>null</code>
+     *
+     * @return                        an enumeration of all the
+     *                                header names sent with this
+     *                                request; if the request has
+     *                                no headers, an empty enumeration;
+     *                                if the servlet container does not
+     *                                allow servlets to use this method,
+     *                                <code>null</code>
+     *
+     */
+
+    Enumeration getHeaderNames();
+    
+    /**
+     * Utility method for getting a <code>Map</code> view of the request headers.
+     * Returns a <code>Map</code> with request headers.
+     *
+     * @return                a <code>Map</code> containing the request headers.
+     *
+     * @since 2.2
+     */
+    Map getHeaders();
+
+    /**
+     * Retrieves the body of the request as binary data using 
+     * an <code>InputStream</code>.
+     * 
+     * @return                        an <code>InputStream</code>
+     *                                containing the body of the request.
+     * 
+     * @throws IOException            if an input or output exception occurred
+     * @throws UnsupportedOperationException
+     */
+    InputStream getInputStream() throws IOException, UnsupportedOperationException;
+
+    /**
+     *
+     * Returns the name of the HTTP method with which this
+     * request was made, for example, GET, POST, or PUT.
+     * Same as the value of the CGI variable REQUEST_METHOD.
+     *
+     * @return                        a <code>String</code>
+     *                                specifying the name
+     *                                of the method with which
+     *                                this request was made
+     *
+     */
+
+    String getMethod();
+
+    /**
+     *
+     * Returns any extra path information associated with
+     * the URL the client sent when it made this request.
+     * The extra path information follows the servlet path
+     * but precedes the query string.
+     * This method returns <code>null</code> if there
+     * was no extra path information.
+     *
+     * <p>Same as the value of the CGI variable PATH_INFO.
+     *
+     *
+     * @return                a <code>String</code> specifying
+     *                        extra path information that comes
+     *                        after the servlet path but before
+     *                        the query string in the request URL;
+     *                        or <code>null</code> if the URL does not have
+     *                        any extra path information
+     *
+     */
+
+    String getPathInfo();
+
+    /**
+     *
+     * Returns any extra path information after the servlet name
+     * but before the query string, and translates it to a real
+     * path. Same as the value of the CGI variable PATH_TRANSLATED.
+     *
+     * <p>If the URL does not have any extra path information,
+     * this method returns <code>null</code>.
+     *
+     *
+     * @return                a <code>String</code> specifying the
+     *                        real path, or <code>null</code> if
+     *                        the URL does not have any extra path
+     *                        information
+     *
+     *
+     */
+
+    String getPathTranslated();
+
+    /**
+     *
+     * Returns the portion of the request URI that indicates the context
+     * of the request.  The context path always comes first in a request
+     * URI.  The path starts with a "/" character but does not end with a "/"
+     * character.  For servlets in the default (root) context, this method
+     * returns "".
+     *
+     *
+     * @return                a <code>String</code> specifying the
+     *                        portion of the request URI that indicates the context
+     *                        of the request
+     *
+     *
+     */
+
+    String getContextPath();
+
+    /**
+     *
+     * Returns the query string that is contained in the request
+     * URL after the path. This method returns <code>null</code>
+     * if the URL does not have a query string. Same as the value
+     * of the CGI variable QUERY_STRING.
+     *
+     * @return                a <code>String</code> containing the query
+     *                        string or <code>null</code> if the URL
+     *                        contains no query string
+     *
+     */
+
+    String getQueryString();
+
+    /**
+     *
+     * Returns the login of the user making this request, if the
+     * user has been authenticated, or <code>null</code> if the user
+     * has not been authenticated.
+     * Whether the user name is sent with each subsequent request
+     * depends on the browser and type of authentication. Same as the
+     * value of the CGI variable REMOTE_USER.
+     *
+     * @return                a <code>String</code> specifying the login
+     *                        of the user making this request, or <code>null</code
+     *                        if the user login is not known
+     *
+     */
+
+    String getRemoteUser();
+
+    /**
+     *
+     * Returns the login of the user making this request, if the
+     * user has been authenticated, or <code>null</code> if the user
+     * has not been authenticated.
+     * Whether the user name is sent with each subsequent request
+     * depends on the browser and type of authentication. Same as the
+     * value of the CGI variable REMOTE_USER.
+     *
+     * @return                a <code>String</code> specifying the login
+     *                        of the user making this request, or <code>null</code
+     *                        if the user login is not known
+     *
+     */
+
+    Principal getUserPrincipal();
+
+    /**
+     *
+     * Checks whether the currently logged in user is in a specified role.
+     *
+     * @return                        <code>true</code> if the user is
+     *                                authenticated and in the role;
+     *                                otherwise, <code>false</code>
+     *
+     *
+     * @see                        #getRemoteUser()
+     *
+     */
+
+    boolean isUserInRole(String role);
+
+    /**
+     *
+     * Returns the session ID specified by the client. This may
+     * not be the same as the ID of the actual session in use.
+     * For example, if the request specified an old (expired)
+     * session ID and the server has started a new session, this
+     * method gets a new session with a new ID. If the request
+     * did not specify a session ID, this method returns
+     * <code>null</code>.
+     *
+     *
+     * @return                a <code>String</code> specifying the session
+     *                        ID, or <code>null</code> if the request did
+     *                        not specify a session ID
+     *
+     * @see                #isRequestedSessionIdValid()
+     *
+     */
+
+    String getRequestedSessionId();
+
+    /**
+     *
+     * Returns the part of this request's URL from the protocol
+     * name up to the query string in the first line of the HTTP request.
+     * For example:
+     *
+     * <blockquote>
+     * <table>
+     * <tr align=left><th>First line of HTTP request<th>
+     * <th>Returned Value
+     * <tr><td>POST /some/path.html HTTP/1.1<td><td>/some/path.html
+     * <tr><td>GET http://foo.bar/a.html HTTP/1.0
+     * <td><td>http://foo.bar/a.html
+     * <tr><td>HEAD /xyz?a=b HTTP/1.1<td><td>/xyz
+     * </table>
+     * </blockquote>
+     * 
+     * For internal requests, this method returns
+     * the information for the original/external request!
+     *
+     * @return                a <code>String</code> containing
+     *                        the part of the URL from the
+     *                        protocol name up to the query string
+     */
+    String getRequestURI();
+
+    /**
+     * <p>
+     * Returns the URI of the requested resource as interpreted by the sitemap.
+     * For example, if your webapp is mounted at "/webapp" and the HTTP request
+     * is for "/webapp/foo", this method returns "foo". Consequently, if the
+     * request is for "/webapp", this method returns an empty string.
+     * </p>
+     * <p>
+     * Note that if the request is mapped to a pipeline that contains
+     * aggregated content, and if this method is called in the context of
+     * one of the aggregated parts (e.g. a server page), this method will
+     * return the URI of the aggregated part, not the original requested URI.
+     * </p>
+     *
+     * @return a <code>String</code> containing the URL as mangled by the
+     *         sitemap
+     */
+    String getSitemapURI();
+
+    /**
+     * <p>
+     * Returns the URI Prefix of the requested resource where the sitemap is mounted.
+     * For example, if your webapp is mounted at "/webapp" and the HTTP request
+     * is for "/webapp/foo", this method returns "webapp/".
+     * </p>
+     *
+     * @return a <code>String</code> containing the URI prefix as mangled by the
+     *         sitemap
+     */
+
+    String getSitemapURIPrefix();
+
+    /**
+     * <p>
+     * Returns the path to the sitemap of the requested resource as interpreted 
+     * by the sitemap.
+     * For example, if your webapp is mounted at "webapp" and the HTTP request
+     * is for "webapp/foo", this method returns "webapp/". Consequently, if the
+     * request is for "foo", this method returns the empty string.
+     * </p>
+     *
+     * @return a <code>String</code> containing the path to the sitemap
+     * @since 2.2
+     */
+
+    String getSitemapPath();
+    
+    /**
+     *
+     * Returns the part of this request's URL that calls
+     * the servlet. This includes either the servlet name or
+     * a path to the servlet, but does not include any extra
+     * path information or a query string. Same as the value
+     * of the CGI variable SCRIPT_NAME.
+     *
+     *
+     * @return                a <code>String</code> containing
+     *                        the name or path of the servlet being
+     *                        called, as specified in the request URL
+     *
+     *
+     */
+
+    String getServletPath();
+
+    /**
+     *
+     * Returns the current <code>Session</code>
+     * associated with this request or, if if there is no
+     * current session and <code>create</code> is true, returns
+     * a new session.
+     *
+     * <p>If <code>create</code> is <code>false</code>
+     * and the request has no valid <code>Session</code>,
+     * this method returns <code>null</code>.
+     *
+     * <p>To make sure the session is properly maintained,
+     * you must call this method before
+     * the response is committed.
+     *
+     *
+     *
+     *
+     * @param create          <code>true</code> to create
+     *                        a new session for this request if necessary;
+     *                        <code>false</code> to return <code>null</code>
+     *                        if there's no current session
+     *
+     *
+     * @return                 the <code>Session</code> associated
+     *                        with this request or <code>null</code> if
+     *                         <code>create</code> is <code>false</code>
+     *                        and the request has no valid session
+     *
+     * @see        #getSession()
+     *
+     *
+     */
+
+    Session getSession(boolean create);
+
+    /**
+     *
+     * Returns the current session associated with this request,
+     * or if the request does not have a session, creates one.
+     *
+     * @return                the <code>Session</code> associated
+     *                        with this request
+     *
+     * @see        #getSession(boolean)
+     *
+     */
+
+     Session getSession();
+
+    /**
+     *
+     * Checks whether the requested session ID is still valid.
+     *
+     * @return                        <code>true</code> if this
+     *                                request has an id for a valid session
+     *                                in the current session context;
+     *                                <code>false</code> otherwise
+     *
+     * @see                        #getRequestedSessionId()
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdValid();
+
+    /**
+     *
+     * Checks whether the requested session ID came in as a cookie.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as a
+     *                                cookie; otherwise, <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdFromCookie();
+
+    /**
+     *
+     * Checks whether the requested session ID came in as part of the
+     * request URL.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as part of a URL; otherwise,
+     *                                <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     *
+     */
+
+    boolean isRequestedSessionIdFromURL();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Response.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Response.java
new file mode 100644
index 0000000..5f5c327
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Response.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.util.Locale;
+
+/**
+ * Defines an interface to provide client response information.
+ *
+ * @version $Id$
+ */
+public interface Response {
+
+    /**
+     * Returns the name of the charset used for
+     * the MIME body sent in this response.
+     *
+     * <p>If no charset has been assigned, it is implicitly
+     * set to <code>ISO-8859-1</code> (<code>Latin-1</code>).
+     *
+     * <p>See RFC 2047 (http://ds.internic.net/rfc/rfc2045.txt)
+     * for more information about character encoding and MIME.
+     *
+     * @return                a <code>String</code> specifying the
+     *                        name of the charset, for
+     *                        example, <code>ISO-8859-1</code>
+     *
+     */
+
+    String getCharacterEncoding();
+
+    /**
+     * Sets the locale of the response, setting the headers (including the
+     * Content-Type's charset) as appropriate.  By default, the response locale
+     * is the default locale for the server.
+     *
+     * @param loc  the locale of the response
+     *
+     * @see                 #getLocale()
+     *
+     */
+
+    void setLocale(Locale loc);
+
+    /**
+     * Returns the locale assigned to the response.
+     *
+     *
+     * @see                 #setLocale(Locale)
+     *
+     */
+
+    Locale getLocale();
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p>The name must conform to RFC 2109. That means it can contain
+     * only ASCII alphanumeric characters and cannot contain commas,
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p>The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * <code>setValue</code> method.
+     *
+     * <p>By default, cookies are created according to the Netscape
+     * cookie specification. The version can be changed with the
+     * <code>setVersion</code> method.
+     *
+     *
+     * @param name                         a <code>String</code> specifying the name of the cookie
+     *
+     * @param value                        a <code>String</code> specifying the value of the cookie
+     *
+     * @throws IllegalArgumentException        if the cookie name contains illegal characters
+     *                                        (for example, a comma, space, or semicolon)
+     *                                        or it is one of the tokens reserved for use
+     *                                        by the cookie protocol
+     *
+     */
+    Cookie createCookie(String name, String value);
+
+    /**
+     * Adds the specified cookie to the response.  This method can be called
+     * multiple times to set more than one cookie.
+     *
+     * @param cookie the Cookie to return to the client
+     *
+     */
+
+    void addCookie(Cookie cookie);
+
+    /**
+     * Returns a boolean indicating whether the named response header
+     * has already been set.
+     *
+     * @param        name        the header name
+     * @return                <code>true</code> if the named response header
+     *                        has already been set;
+     *                         <code>false</code> otherwise
+     */
+
+    boolean containsHeader(String name);
+
+    /**
+     * Encodes the specified URL by including the session ID in it,
+     * or, if encoding is not needed, returns the URL unchanged.
+     * The implementation of this method includes the logic to
+     * determine whether the session ID needs to be encoded in the URL.
+     * For example, if the browser supports cookies, or session
+     * tracking is turned off, URL encoding is unnecessary.
+     *
+     * <p>For robust session tracking, all URLs emitted by a servlet
+     * should be run through this
+     * method.  Otherwise, URL rewriting cannot be used with browsers
+     * which do not support cookies.
+     *
+     * @param        url        the url to be encoded.
+     * @return                the encoded URL if encoding is needed;
+     *                         the unchanged URL otherwise.
+     */
+
+    String encodeURL(String url);
+
+    /**
+     *
+     * Sets a response header with the given name and
+     * date-value.  The date is specified in terms of
+     * milliseconds since the epoch.  If the header had already
+     * been set, the new value overwrites the previous one.  The
+     * <code>containsHeader</code> method can be used to test for the
+     * presence of a header before setting its value.
+     *
+     * @param        name        the name of the header to set
+     * @param        date        the assigned date value
+     *
+     * @see #containsHeader(String)
+     * @see #addDateHeader(String, long)
+     */
+
+    void setDateHeader(String name, long date);
+
+    /**
+     *
+     * Adds a response header with the given name and
+     * date-value.  The date is specified in terms of
+     * milliseconds since the epoch.  This method allows response headers
+     * to have multiple values.
+     *
+     * @param        name        the name of the header to set
+     * @param        date        the additional date value
+     *
+     * @see #setDateHeader(String, long)
+     */
+
+    void addDateHeader(String name, long date);
+
+    /**
+     *
+     * Sets a response header with the given name and value.
+     * If the header had already been set, the new value overwrites the
+     * previous one.  The <code>containsHeader</code> method can be
+     * used to test for the presence of a header before setting its
+     * value.
+     *
+     * @param        name        the name of the header
+     * @param        value        the header value
+     *
+     * @see #containsHeader(String)
+     * @see #addHeader(String, String)
+     */
+
+    void setHeader(String name, String value);
+
+    /**
+     * Adds a response header with the given name and value.
+     * This method allows response headers to have multiple values.
+     *
+     * @param        name        the name of the header
+     * @param        value        the additional header value
+     *
+     * @see #setHeader(String, String)
+     */
+
+    void addHeader(String name, String value);
+
+    /**
+     * Sets a response header with the given name and
+     * int value. If the header had already
+     * been set, the new value overwrites the previous one.  The
+     * <code>containsHeader</code> method can be used to test for the
+     * presence of a header before setting its value.
+     *
+     * @param        name        the name of the header to set
+     * @param        value       the assigned int value
+     *
+     * @see #containsHeader(String)
+     * @see #addIntHeader(String, int)
+     */
+
+    void setIntHeader(String name, int value);
+
+    /**
+     * Adds a response header with the given name and
+     * int value. This method allows response headers
+     * to have multiple values.
+     *
+     * @param        name        the name of the header to set
+     * @param        value       the additional int value
+     *
+     * @see #setIntHeader(String, int)
+     */
+
+    void addIntHeader(String name, int value);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Session.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Session.java
new file mode 100644
index 0000000..3eff4ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/Session.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.util.Enumeration;
+import java.util.Map;
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>Cocoon uses this interface to create a session
+ * between a client and the "cocoon server". The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows Cocoon to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ *     the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ *     across multiple user connections
+ * </ul>
+ *
+ * <p>Session information is scoped only to the current context
+ * (<code>Context</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @version $Id$
+ */
+
+public interface Session {
+
+    /**
+     *
+     * Returns the time when this session was created, measured
+     * in milliseconds since midnight January 1, 1970 GMT.
+     *
+     * @return                                a <code>long</code> specifying
+     *                                         when this session was created,
+     *                                        expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    long getCreationTime();
+
+    /**
+     *
+     * Returns a string containing the unique identifier assigned
+     * to this session. The identifier is assigned
+     * by the context container and is implementation dependent.
+     *
+     * @return                                a string specifying the identifier
+     *                                        assigned to this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    String getId();
+
+    /**
+     *
+     * Returns the last time the client sent a request associated with
+     * this session, as the number of milliseconds since midnight
+     * January 1, 1970 GMT.
+     *
+     * <p>Actions that your application takes, such as getting or setting
+     * a value associated with the session, do not affect the access
+     * time.
+     *
+     * @return                                a <code>long</code>
+     *                                        representing the last time
+     *                                        the client sent a request associated
+     *                                        with this session, expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+
+    long getLastAccessedTime();
+
+    /**
+     *
+     * Specifies the time, in seconds, between client requests before the
+     * contextcontainer will invalidate this session.  A negative time
+     * indicates the session should never timeout.
+     *
+     * @param interval                An integer specifying the number
+     *                                 of seconds
+     *
+     */
+    void setMaxInactiveInterval(int interval);
+
+   /**
+    * Returns the maximum time interval, in seconds, that
+    * the context container will keep this session open between
+    * client accesses. After this interval, the context container
+    * will invalidate the session.  The maximum time interval can be set
+    * with the <code>setMaxInactiveInterval</code> method.
+    * A negative time indicates the session should never timeout.
+    *
+    *
+    * @return                an integer specifying the number of
+    *                        seconds this session remains open
+    *                        between client requests
+    *
+    * @see                #setMaxInactiveInterval(int)
+    *
+    *
+    */
+    int getMaxInactiveInterval();
+
+    /**
+     *
+     * Returns the object bound with the specified name in this session, or
+     * <code>null</code> if no object is bound under the name.
+     *
+     * @param name                a string specifying the name of the object
+     *
+     * @return                        the object with the specified name
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    Object getAttribute(String name);
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code> objects
+     * containing the names of all the objects bound to this session.
+     *
+     * @return                        an <code>Enumeration</code> of
+     *                                <code>String</code> objects specifying the
+     *                                names of all the objects bound to
+     *                                this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    Enumeration getAttributeNames();
+
+    /**
+     * Binds an object to this session, using the name specified.
+     * If an object of the same name is already bound to the session,
+     * the object is replaced.
+     *
+     *
+     * @param name                        the name to which the object is bound;
+     *                                        cannot be null
+     *
+     * @param value                        the object to be bound; cannot be null
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    void setAttribute(String name, Object value);
+
+    /**
+     *
+     * Removes the object bound with the specified name from
+     * this session. If the session does not have an object
+     * bound with the specified name, this method does nothing.
+     *
+     *
+     * @param name                                the name of the object to
+     *                                                remove from this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     */
+    void removeAttribute(String name);
+
+    /**
+     * Utility method for getting a <code>Map</code> view of the request attributes.
+     * Returns a <code>Map</code> with attributes.
+     *
+     * @return                a <code>Map</code> containing the request attributes.
+     *
+     * @since 2.2
+     */
+    Map getAttributes();
+
+    /**
+     *
+     * Invalidates this session
+     * to it.
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    void invalidate();
+
+    /**
+     *
+     * Returns <code>true</code> if the client does not yet know about the
+     * session or if the client chooses not to join the session.  For
+     * example, if the server used only cookie-based sessions, and
+     * the client had disabled the use of cookies, then a session would
+     * be new on each request.
+     *
+     * @return                                 <code>true</code> if the
+     *                                        server has created a session,
+     *                                        but the client has not yet joined
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    boolean isNew();
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/SourceResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/SourceResolver.java
new file mode 100644
index 0000000..ca96938
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/SourceResolver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+/**
+ * Base interface for resolving a source by system identifiers. This 
+ * component is a special extension of the Avalon Excalibur 
+ * {@link org.apache.excalibur.source.SourceResolver} that is only
+ * used for Cocoon sitemap components.
+ *
+ * @version $Id$
+ */
+public interface SourceResolver
+extends org.apache.excalibur.source.SourceResolver {
+
+    // no methods to add
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/TemplateObjectModelHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/TemplateObjectModelHelper.java
new file mode 100644
index 0000000..a65cdf7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/TemplateObjectModelHelper.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptFlowHelper;
+import org.apache.commons.jxpath.DynamicPropertyHandler;
+import org.apache.commons.jxpath.JXPathBeanInfo;
+import org.apache.commons.jxpath.JXPathIntrospector;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.NativeJavaPackage;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+
+/**
+ * This is an utility class to create an object model which is similar to the one
+ * used in flow, that can be used from every component.
+ * 
+ * Work-in-progress, derived from JXTemplateGenerator
+ * 
+ * @version $Id$
+ */
+public class TemplateObjectModelHelper {
+    private static Scriptable rootScope = null;
+    
+    /** Avoid instantiation */
+    private TemplateObjectModelHelper() {}
+
+    public static Scriptable getScope() {
+        Context ctx = Context.enter();
+        try {
+            // Create it if never used up to now
+            if (rootScope == null)
+                rootScope = ctx.initStandardObjects(null);
+            
+            Scriptable scope = ctx.newObject(rootScope);
+            scope.setPrototype(rootScope);
+            scope.setParentScope(null);
+            return scope;
+        } finally {
+            Context.exit();
+        }
+    }
+    
+    public static void fillContext(Object contextObject, Map map) {
+        // Hack: I use jxpath to populate the context object's properties
+        // in the jexl context
+        final JXPathBeanInfo bi =
+            JXPathIntrospector.getBeanInfo(contextObject.getClass());
+        if (bi.isDynamic()) {
+            Class cl = bi.getDynamicPropertyHandlerClass();
+            try {
+                DynamicPropertyHandler h =
+                    (DynamicPropertyHandler) cl.newInstance();
+                String[] result = h.getPropertyNames(contextObject);
+                int len = result.length;
+                for (int i = 0; i < len; i++) {
+                    try {
+                        map.put(result[i], h.getProperty(contextObject, result[i]));
+                    } catch (Exception exc) {
+                        exc.printStackTrace();
+                    }
+                }
+            } catch (Exception ignored) {
+                ignored.printStackTrace();
+            }
+        } else {
+            PropertyDescriptor[] props =  bi.getPropertyDescriptors();
+            int len = props.length;
+            for (int i = 0; i < len; i++) {
+                try {
+                    Method read = props[i].getReadMethod();
+                    if (read != null) {
+                        map.put(props[i].getName(),
+                                read.invoke(contextObject, null));
+                    }
+                } catch (Exception ignored) {
+                    ignored.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * Create the object model.
+     * Currently the object model is a map with one single entry:
+     *  cocoon + request         The Request Object
+     *         + session         The Session (if available)
+     *         + context         The Context
+     *         + continuation    The Continuation (if available)
+     *         + parameters      The parameters (if provided)
+     */
+    public static Object getTemplateObjectModel(final Map objectModel, 
+                                                final Parameters parameters) {
+
+        // first create the "cocoon object":
+        final Map cocoon = new HashMap();
+
+        // Needed for the FOM wrappers
+        Context.enter();
+        try {
+            // cocoon.request
+            final Request request = ObjectModelHelper.getRequest( objectModel );
+            cocoon.put("request", request);
+            
+            // cocoon.session
+            final Session session = request.getSession(false);
+            if (session != null) {
+                cocoon.put("session", session);
+            }
+        
+            // cocoon.context
+            final org.apache.cocoon.environment.Context context =
+                ObjectModelHelper.getContext( objectModel );
+            cocoon.put("context", context);
+
+        } finally {
+            Context.exit();
+        }
+            
+        // cocoon.continuation
+        final Object cont = FlowHelper.getWebContinuation(objectModel);
+        if ( cont != null ) {
+            cocoon.put("continuation", cont);
+        }
+            
+        // cocoon.parameters
+        if ( parameters != null ) {
+            cocoon.put("parameters", Parameters.toProperties(parameters));
+        }
+
+        final Map map = new HashMap();
+        map.put("cocoon", cocoon);
+
+        // Now add objects from flow context (if any)
+        final Object contextObject = FlowHelper.getContextObject(objectModel);
+        if (contextObject instanceof Map) {
+            map.putAll((Map)contextObject);
+        } else if ( contextObject != null ) {
+            fillContext(contextObject, map);
+        }
+        
+        return map;
+    }
+
+    /**
+     * Add java packages to object model. Allows to construct java objects.
+     * @param objectModel usually the result of invoking getTemplateObjectModel
+     */
+    public static Object addJavaPackages( Map objectModel ) {
+        Object javaPkg = FOM_JavaScriptFlowHelper.getJavaPackage(objectModel);
+        Object pkgs = FOM_JavaScriptFlowHelper.getPackages(objectModel);
+        
+        // packages might have already been set up if flowscript is being used
+        if ( javaPkg != null && pkgs != null ) {
+            objectModel.put( "Packages", javaPkg );
+            objectModel.put( "java", pkgs );
+        } else { 
+            Context.enter();
+            try {
+                final String JAVA_PACKAGE = "JavaPackage";
+                ClassLoader cl = Thread.currentThread().getContextClassLoader();
+                Scriptable newPackages = new NativeJavaPackage( "", cl );
+                newPackages.setParentScope( getScope() );
+                newPackages.setPrototype( ScriptableObject.getClassPrototype(   getScope(),
+                                                                                JAVA_PACKAGE ) );
+                objectModel.put( "Packages", newPackages );
+                objectModel.put( "java", ScriptableObject.getProperty( getScope(), "java" ) );
+            } finally {
+                Context.exit();
+            }
+        }
+        return objectModel;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java
new file mode 100644
index 0000000..5f9884d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/AbstractCommandLineEnvironment.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.CascadingIOException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.AbstractEnvironment;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceResolver;
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+
+/**
+ * This environment is used to save the requested file to disk.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractCommandLineEnvironment
+extends AbstractEnvironment {
+
+    protected String contentType;
+    protected int contentLength;
+    protected int statusCode;
+
+    public AbstractCommandLineEnvironment(String uri,
+                                          String view,
+                                          File context,
+                                          OutputStream stream,
+                                          Logger log)
+    throws MalformedURLException {
+        super(uri, view);
+        this.enableLogging(log);
+        this.outputStream = stream;
+        this.statusCode = 0;
+    }
+
+    /**
+     * Redirect the client to a new URL
+     */
+    public void redirect(String newURL, boolean global, boolean permanent) 
+    throws IOException {
+
+        // fix all urls created with request.getScheme()+... etc.
+        if (newURL.startsWith("cli:/")) {
+            int pos = newURL.indexOf('/', 6);
+            newURL = newURL.substring(pos+1);
+        }
+
+        // fix all relative urls to use to cocoon: protocol
+        if (newURL.indexOf(":") == -1) {
+            newURL = "cocoon:/" + newURL;
+        }
+
+        // FIXME: this is a hack for the links view
+        ServiceManager manager = EnvironmentHelper.getSitemapServiceManager();
+        SourceResolver resolver = null;
+        try {
+            resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+            if (newURL.startsWith("cocoon:")
+                && this.getView() != null
+                && this.getView().equals(Constants.LINK_VIEW)) {
+            
+                // as the internal cocoon protocol is used the last
+                // serializer is removed from it! And therefore
+                // the LinkSerializer is not used.
+                // so we create one without Avalon...
+                org.apache.cocoon.serialization.LinkSerializer ls =
+                    new org.apache.cocoon.serialization.LinkSerializer();
+                ls.setOutputStream(this.outputStream);
+    
+                Source redirectSource = null;
+                try {
+                    redirectSource = resolver.resolveURI(newURL);
+                    SourceUtil.parse( manager, redirectSource, ls);
+                } catch (SourceException se) {
+                    throw new CascadingIOException("SourceException: " + se, se);
+                } catch (SAXException se) {
+                    throw new CascadingIOException("SAXException: " + se, se);
+                } catch (ProcessingException pe) {
+                    throw new CascadingIOException("ProcessingException: " + pe, pe);
+                } finally {
+                    resolver.release( redirectSource );
+                }
+                
+            } else {
+                Source redirectSource = null;
+                try {
+                    redirectSource = resolver.resolveURI(newURL);
+                    InputStream is = redirectSource.getInputStream();
+                    byte[] buffer = new byte[8192];
+                    int length = -1;
+    
+                    while ((length = is.read(buffer)) > -1) {
+                        this.outputStream.write(buffer, 0, length);
+                    }
+                } catch (SourceException se) {
+                    throw new CascadingIOException("SourceException: " + se, se);
+                } finally {
+                    resolver.release( redirectSource);
+                }
+            }
+        } catch (ServiceException se) {
+            throw new CascadingIOException("Unable to get source resolver.", se);
+        } finally {
+            manager.release(resolver);
+        }
+    }
+
+    /**
+     * Set the StatusCode
+     */
+    public void setStatus(int statusCode) {
+        this.statusCode = statusCode;
+    }
+
+    /**
+     * Get the StatusCode
+     */
+    public int getStatus() {
+        return statusCode;
+    }
+
+    /**
+     * Set the ContentType
+     */
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    /**
+     * Set the ContentLength
+     */
+    public void setContentLength(int contentLength) {
+        this.contentLength = contentLength;
+    }
+
+    /**
+     * Get the ContentType
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+    
+    /**
+     * Always return <code>true</code>.
+     */
+    public boolean isExternal() {
+        return true;
+    }
+
+    /**
+     * Return an OutputStream, but allow it to be null for when
+     * the pipeline is being streamed to the provided SAX 
+     * content handler (using CocoonBean)
+     */
+    public OutputStream getOutputStream(int bufferSize) throws IOException {
+        if (this.outputStream == null) {
+            return null;
+        }
+        return super.getOutputStream(bufferSize);
+    }
+
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineContext.java
new file mode 100644
index 0000000..cb442a8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineContext.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import org.apache.commons.collections.iterators.IteratorEnumeration;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.impl.ContextMap;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.HashMap;
+import java.io.InputStream;
+
+/**
+ *
+ * Implements the {@link org.apache.cocoon.environment.Context} interface
+ * @version $Id$
+ */
+public class CommandLineContext extends AbstractLogEnabled implements Context {
+
+    /** The context directory path*/
+    private String contextDir;
+
+    /** The context attributes */
+    private Map attributes;
+
+    /**
+     * Constructs a CommandlineContext object from a ServletContext object
+     */
+    public CommandLineContext (String contextDir) {
+        String contextDirPath = new File(contextDir).getAbsolutePath();
+        // store contextDirPath as is don't remove trailing /.
+        this.contextDir = contextDirPath;
+        this.attributes = new HashMap();
+    }
+
+    public Object getAttribute(String name) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: getAttribute=" + name);
+        }
+        return this.attributes.get(name);
+    }
+
+    public void setAttribute(String name, Object value) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: setAttribute=" + name);
+        }
+        this.attributes.put(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: removeAttribute=" + name);
+        }
+        this.attributes.remove(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: getAttributeNames");
+        }
+        return new IteratorEnumeration(this.attributes.keySet().iterator());
+    }
+
+    public Map getAttributes() {
+	return new ContextMap(this);
+    }
+
+    public URL getResource(String path) throws MalformedURLException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: getResource=" + path);
+        }
+        // rely on File to build correct File and URL
+        File f = new File( contextDir, path );
+        if (!f.exists()) return null;
+        return f.toURL();
+    }
+
+    public String getRealPath(String path) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: getRealPath=" + path);
+        }
+        // rely on File to build correct File and URL
+        File f = new File( this.contextDir, path );
+        return f.getAbsolutePath();
+    }
+
+    public String getMimeType(String file) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("CommandlineContext: getMimeType=" + file);
+        }
+        //return servletContext.getMimeType(file);
+        return null;
+    }
+
+    public String getInitParameter(String name) {
+        getLogger().debug("CommandlineContext: getInitParameter=" + name);
+        return null;
+    }
+
+    public InputStream getResourceAsStream(String path){
+        getLogger().debug("CommandlineContext: getResourceAsStream "+path);
+    return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineRequest.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineRequest.java
new file mode 100644
index 0000000..f862f48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineRequest.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.commandline;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.impl.AbstractRequest;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.NotImplementedException;
+
+/**
+ * Creates a specific servlet request simulation from command line usage.
+ *
+ * @version $Id$
+ */
+/*
+ * NOTE: method with a non-compliant implementation are marked with FIXME
+ * and should be fixed in the future if required
+ */
+public class CommandLineRequest extends AbstractRequest {
+
+    private class EmptyEnumeration implements Enumeration {
+        public boolean hasMoreElements() {
+            return false;
+        }
+        public Object nextElement() {
+            return null;
+        }
+    }
+
+    private Environment env;
+    private String contextPath;
+    private String servletPath;
+    private String pathInfo;
+    private Map globalAttributes;
+    private Map attributes;
+    private Map parameters;
+    private Map headers;
+    private String characterEncoding;
+
+    public CommandLineRequest(Environment env,
+                              String contextPath,
+                              String servletPath,
+                              String pathInfo) {
+        this(env, contextPath, servletPath, pathInfo, null, null, null);
+    }
+
+    public CommandLineRequest(Environment env,
+                              String contextPath,
+                              String servletPath,
+                              String pathInfo,
+                              Map attributes) {
+        this(env, contextPath, servletPath, pathInfo, attributes, null, null);
+    }
+
+    public CommandLineRequest(Environment env,
+                              String contextPath,
+                              String servletPath,
+                              String pathInfo,
+                              Map attributes,
+                              Map parameters) {
+        this(env, contextPath, servletPath, pathInfo, attributes, parameters, null);
+    }
+
+    public CommandLineRequest(Environment env,
+                              String contextPath,
+                              String servletPath,
+                              String pathInfo,
+                              Map attributes,
+                              Map parameters,
+                              Map headers) {
+        this.env = env;
+        this.contextPath = contextPath;
+        this.servletPath = servletPath;
+        this.pathInfo = pathInfo;
+        this.globalAttributes = (attributes == null ? new HashMap() : attributes);
+        this.attributes = new HashMap();
+        this.parameters = parameters;
+        this.headers = headers;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#get(java.lang.String)
+     */
+    public Object get(String name) {
+        String[] values = this.getParameterValues(name);
+        if (values == null || values.length == 0) {
+            return null;
+        } else if (values.length == 1) {
+            return values[0];
+        } else {
+            Vector vect = new Vector(values.length);
+            for (int i = 0; i < values.length; i++) {
+                vect.add(values[i]);
+            }
+            return vect;
+        }
+    }
+
+    public String getContextPath() { return contextPath; }
+    public String getServletPath() { return servletPath; }
+    public String getPathInfo() { return pathInfo; }
+    public String getRequestURI() {
+        StringBuffer buffer = new StringBuffer();
+        if (servletPath != null) buffer.append(servletPath);
+        if (contextPath != null) buffer.append(contextPath);
+        if (pathInfo != null) buffer.append(pathInfo);
+        return buffer.toString();
+    }
+    // FIXME
+    public String getSitemapURI() {
+        return this.env.getURI();
+    }
+    public String getSitemapURIPrefix() {
+        return this.env.getURIPrefix();
+    }
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapPath()
+     */
+    public String getSitemapPath() {
+        return this.env.getURIPrefix();
+    }
+
+    public String getQueryString() { return null; } // use parameters instead
+    public String getPathTranslated() { return null; } // FIXME (SM) this is legal but should we do something more?
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.getAttribute(name, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.getAttributeNames(Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.setAttribute(name, value, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.removeAttribute(name, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return this.attributes.get(name);
+        }
+        return this.globalAttributes.get(name);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return IteratorUtils.asEnumeration(this.attributes.keySet().iterator());
+        }
+        return IteratorUtils.asEnumeration(this.globalAttributes.keySet().iterator());
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object value, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.put(name, value);
+        } else {
+            this.globalAttributes.put(name, value);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.remove(name);
+        } else {
+            this.globalAttributes.remove(name);
+        }
+    }
+
+    public String getParameter(String name) {
+        if (this.parameters == null) {
+            return null;
+        }
+
+        final Object value = this.parameters.get(name);
+        if (value instanceof String) {
+            return (String)value;
+        } else if (value == null) {
+            return null;
+        } else {
+            final String[] values = (String[]) value;
+            if (values.length == 0) {
+                return null;
+            }
+            return values[0];
+        }
+    }
+
+    public Enumeration getParameterNames() {
+        return (this.parameters != null) ? IteratorUtils.asEnumeration(this.parameters.keySet().iterator()) : null;
+    }
+
+    public String[] getParameterValues(String name) {
+        final Object value = this.parameters.get(name);
+        if (value instanceof String) {
+            return new String[] { (String)value };
+        }
+        return (String[]) value;
+    }
+
+    public String getHeader(String name) {
+        return (headers != null) ? (String) headers.get(name.toLowerCase()) : null;
+    }
+
+    public int getIntHeader(String name) {
+        String header = (headers != null) ? (String) headers.get(name.toLowerCase()) : null;
+        return (header != null) ? Integer.parseInt(header) : -1;
+    }
+
+    public long getDateHeader(String name) {
+        //FIXME
+        return 0;
+    }
+
+    public Enumeration getHeaders(String name) {
+        // FIXME
+        return new EmptyEnumeration();
+    }
+
+    public Enumeration getHeaderNames() {
+        if (headers != null) {
+            return IteratorUtils.asEnumeration(headers.keySet().iterator());
+        }
+        return new EmptyEnumeration();
+    }
+
+    public String getCharacterEncoding() { return characterEncoding; }
+    public int getContentLength() { return -1; }
+
+    public String getContentType() { return null; }
+    public String getProtocol()  { return "cli"; }
+    public String getScheme() { return "cli"; }
+    public String getServerName() { return Constants.COMPLETE_NAME; }
+    public int getServerPort() { return -1; }
+    public String getRemoteAddr() { return "127.0.0.1"; }
+    public String getRemoteHost() { return "localhost"; }
+    public String getMethod() { return "get"; }
+    public String getRemoteUser() { return SystemUtils.USER_NAME; }
+
+    public Cookie[] getCookies() { return null; }
+    public Map getCookieMap() {
+        return Collections.unmodifiableMap(new HashMap());
+    }
+
+    /**
+     * Returns the current session associated with this request,
+     * or if the request does not have a session, creates one.
+     *
+     * @return                the <code>Session</code> associated
+     *                        with this request
+     *
+     * @see        #getSession(boolean)
+     */
+    public Session getSession() {
+        return this.getSession(true);
+    }
+
+    /**
+     * Returns the current <code>Session</code>
+     * associated with this request or, if if there is no
+     * current session and <code>create</code> is true, returns
+     * a new session.
+     *
+     * <p>If <code>create</code> is <code>false</code>
+     * and the request has no valid <code>Session</code>,
+     * this method returns <code>null</code>.
+     *
+     * <p>To make sure the session is properly maintained,
+     * you must call this method before
+     * the response is committed.
+     *
+     * @param create  <code>true</code> to create a new session for this request
+     *                if necessary;
+     *                <code>false</code> to return <code>null</code> if there's
+     *                no current session
+     *
+     * @return  the <code>Session</code> associated with this request or
+     *          <code>null</code> if <code>create</code> is <code>false</code>
+     *          and the request has no valid session
+     *
+     * @see  #getSession()
+     */
+    public Session getSession(boolean create) {
+        return CommandLineSession.getSession(create);
+    }
+
+    /**
+     * Returns the session ID specified by the client. This may
+     * not be the same as the ID of the actual session in use.
+     * For example, if the request specified an old (expired)
+     * session ID and the server has started a new session, this
+     * method gets a new session with a new ID. If the request
+     * did not specify a session ID, this method returns
+     * <code>null</code>.
+     *
+     *
+     * @return                a <code>String</code> specifying the session
+     *                        ID, or <code>null</code> if the request did
+     *                        not specify a session ID
+     *
+     * @see                #isRequestedSessionIdValid()
+     */
+    public String getRequestedSessionId() {
+        return (CommandLineSession.getSession(false) != null) ?
+                CommandLineSession.getSession(false).getId() : null;
+    }
+
+    /**
+     * Checks whether the requested session ID is still valid.
+     *
+     * @return                        <code>true</code> if this
+     *                                request has an id for a valid session
+     *                                in the current session context;
+     *                                <code>false</code> otherwise
+     *
+     * @see                        #getRequestedSessionId()
+     * @see                        #getSession()
+     */
+    public boolean isRequestedSessionIdValid() {
+        return (CommandLineSession.getSession(false) != null);
+    }
+
+    /**
+     * Checks whether the requested session ID came in as a cookie.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as a
+     *                                cookie; otherwise, <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     */
+    public boolean isRequestedSessionIdFromCookie() {
+        return false;
+    }
+
+    /**
+     * Checks whether the requested session ID came in as part of the
+     * request URL.
+     *
+     * @return                        <code>true</code> if the session ID
+     *                                came in as part of a URL; otherwise,
+     *                                <code>false</code>
+     *
+     *
+     * @see                        #getSession()
+     */
+    public boolean isRequestedSessionIdFromURL() {
+        return false;
+    }
+
+    public Locale getLocale() { return Locale.getDefault(); }
+    public Enumeration getLocales() {
+        // FIXME
+        throw new NotImplementedException (getClass().getName() + ".getLocales() method not yet implemented!");
+    }
+
+    public String getAuthType() { return null; }
+    public boolean isSecure() { return false; }
+    public boolean isUserInRole(String role) { return false; }
+    public java.security.Principal getUserPrincipal() { return null; }
+
+    public java.util.Map getParameterMap() { return parameters; }
+    public void setCharacterEncoding(java.lang.String env)
+                          throws java.io.UnsupportedEncodingException { characterEncoding = env; }
+    public StringBuffer getRequestURL() { return null; }
+
+	/*
+	 * @see org.apache.cocoon.environment.Request#getInputStream()
+	 */
+	public InputStream getInputStream() throws UnsupportedOperationException {
+		throw new UnsupportedOperationException();
+	}
+
+    /**
+     * @see org.apache.cocoon.environment.Request#searchAttribute(java.lang.String)
+     */
+    public Object searchAttribute(String name) {
+        Object result = this.getAttribute(name, REQUEST_SCOPE);
+        if ( result == null ) {
+            result = this.getAttribute(name, GLOBAL_SCOPE);
+        }
+        return result;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineResponse.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineResponse.java
new file mode 100644
index 0000000..fb1f659
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineResponse.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Response;
+
+import java.util.Locale;
+
+/**
+ * Creates a specific servlet response simulation from command line usage.
+ *
+ * @version $Id$
+ */
+public class CommandLineResponse implements Response {
+
+    public String getCharacterEncoding() { return null; }
+    public Cookie createCookie(String name, String value) { return null; }
+    public void addCookie(Cookie cookie) {}
+    public boolean containsHeader(String name) { return false; }
+    public void setHeader(String name, String value) {}
+    public void setIntHeader(String name, int value) {}
+    public void setDateHeader(String name, long date) {}
+    public String encodeURL (String url) { return url; }
+    public void setLocale(Locale locale) { }
+    public Locale getLocale() { return null; }
+    public void addDateHeader(String name, long date) { }
+    public void addHeader(String name, String value) { }
+    public void addIntHeader(String name, int value) { }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineSession.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineSession.java
new file mode 100644
index 0000000..15fa883
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/CommandLineSession.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.impl.AbstractSession;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ *
+ * Command-line version of Http Session.
+ *
+ * @version $Id$
+ */
+public final class CommandLineSession
+extends AbstractSession {
+
+    private long creationTime = System.currentTimeMillis();
+
+    private Hashtable attributes = new Hashtable();
+
+    public CommandLineSession() {
+    }
+
+    public long getCreationTime() {
+        return this.creationTime;
+    }
+
+    public String getId() {
+        return "1";
+    }
+
+    public long getLastAccessedTime() {
+        return this.creationTime;
+    }
+
+    public void setMaxInactiveInterval(int interval) {
+        // ignored
+    }
+
+    public int getMaxInactiveInterval() {
+        return -1;
+    }
+
+    public Object getAttribute(String name) {
+        return this.attributes.get(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        return this.attributes.keys();
+    }
+
+    public void setAttribute(String name, Object value) {
+        this.attributes.put(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        this.attributes.remove(name);
+    }
+
+    public void invalidate() {
+        this.attributes.clear();
+        invalidateSession();
+    }
+
+    public boolean isNew() {
+        return false;
+    }
+
+    protected static CommandLineSession session;
+
+    /**
+     * Get the current session object - if available
+     */
+    public static Session getSession(boolean create) {
+        if (create && session == null) {
+            session = new CommandLineSession();
+        }
+        return session;
+    }
+
+    /**
+     * Invalidate the current session
+     */
+    public static void invalidateSession() {
+        session = null;
+    }
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java
new file mode 100644
index 0000000..e3d991f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/FileSavingEnvironment.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import org.apache.avalon.framework.logger.Logger;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.util.Map;
+import java.util.List;
+
+/**
+ * This environment is used to save the requested file to disk.
+ *
+ * @version $Id$
+ */
+public class FileSavingEnvironment extends AbstractCommandLineEnvironment {
+
+    protected boolean modified = true;
+    protected long sourceLastModified = 0L;
+
+    public FileSavingEnvironment(String uri,
+                                 long lastModified,
+                                 File context,
+                                 Map attributes,
+                                 Map parameters,
+                                 Map links,
+                                 List gatheredLinks,
+                                 CommandLineContext cliContext,
+                                 OutputStream stream,
+                                 Logger log)
+    throws MalformedURLException {
+        super(uri, null, context, stream, log);
+        this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT,
+                             new CommandLineRequest(this, null, uri, null, attributes, parameters));
+        this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT,
+                             new CommandLineResponse());
+        this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT,
+                             cliContext);
+        this.sourceLastModified = lastModified;
+        if (links != null) {
+            this.objectModel.put(Constants.LINK_OBJECT, links);
+        }
+        if (gatheredLinks != null) {
+            this.objectModel.put(Constants.LINK_COLLECTION_OBJECT, gatheredLinks);
+        }
+    }
+    
+    public FileSavingEnvironment(String uri,
+                                 File context,
+                                 Map attributes,
+                                 Map parameters,
+                                 Map links,
+                                 List gatheredLinks,
+                                 CommandLineContext cliContext,
+                                 OutputStream stream,
+                                 Logger log)
+    throws MalformedURLException {
+        this(uri, 0L, context, attributes, parameters, links, gatheredLinks, cliContext, stream, log);
+    }
+
+    /**
+     * Check if the response has been modified since the same
+     * "resource" was requested.
+     * The caller has to test if it is really the same "resource"
+     * which is requested.
+     * @return true if the response is modified or if the
+     *         environment is not able to test it
+     */
+    public boolean isResponseModified(long cacheLastModified) {
+        if (cacheLastModified != 0) {
+            return cacheLastModified / 1000 > sourceLastModified / 1000;
+        }
+        return true;
+    }
+
+    /**
+     * Mark the response as not modified.
+     */
+    public void setResponseIsNotModified() {
+       this.modified = false;
+    }
+
+    public boolean isModified() {
+        return this.modified;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java
new file mode 100644
index 0000000..6060b3e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/commandline/LinkSamplingEnvironment.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.commandline;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+/**
+ * This environment is sample the links of the resource.
+ *
+ * @version $Id$
+ */
+public class LinkSamplingEnvironment extends AbstractCommandLineEnvironment {
+
+    private boolean skip = false;
+
+    public LinkSamplingEnvironment(String uri,
+                                   File contextFile,
+                                   Map attributes,
+                                   Map parameters,
+                                   CommandLineContext cliContext,
+                                   Logger log)
+    throws MalformedURLException, IOException {
+        super(uri, Constants.LINK_VIEW, contextFile, new ByteArrayOutputStream(), log);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("uri = " + uri);
+        }
+        this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT,
+                             new CommandLineRequest(this, null, uri, null, attributes, parameters));
+        this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT,
+                             new CommandLineResponse());
+        this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT,
+                             cliContext);
+    }
+
+    /**
+     * Set the ContentType
+     */
+    public void setContentType(String contentType) {
+        if (!Constants.LINK_CONTENT_TYPE.equals(contentType)) {
+            this.skip = true;
+        }
+    }
+
+    /**
+     * Indicates if other links are present.
+     */
+    public Collection getLinks() throws IOException {
+        HashSet set = new HashSet();
+        if (!skip) {
+            BufferedReader buffer = null;
+            try {
+                buffer = new BufferedReader(
+                        new InputStreamReader(
+                                new ByteArrayInputStream(
+                                        ((ByteArrayOutputStream) super.outputStream).toByteArray())));
+
+                String line;
+                while ((line = buffer.readLine()) !=null) {
+                    set.add(line);
+                }
+            } finally {
+                // explictly close the input
+                if (buffer != null) {
+                    try {
+                        buffer.close();
+                        buffer = null;
+                    } catch (IOException ignored) {
+                    }
+                }
+            }
+        }
+        return set;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/ContextURLException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/ContextURLException.java
new file mode 100644
index 0000000..764d60b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/ContextURLException.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright 1999-2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.environment.http;

+

+import org.apache.avalon.framework.CascadingRuntimeException;

+

+public final class ContextURLException extends CascadingRuntimeException

+{

+    public ContextURLException(String message)

+    {

+        super(message, null);

+    }

+

+    public ContextURLException(String message, Throwable cause)

+    {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpContext.java
new file mode 100644
index 0000000..2f2bf5f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpContext.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.http;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+
+import org.apache.cocoon.environment.impl.AbstractContext;
+
+/**
+ *
+ * Implements the {@link org.apache.cocoon.environment.Context} interface
+ * @version $Id$
+ */
+public final class HttpContext extends AbstractContext {
+
+    /** The ServletContext */
+    private final ServletContext servletContext;
+
+    /**
+     * Constructs a HttpContext object from a ServletContext object
+     */
+    public HttpContext (ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
+
+    public Object getAttribute(String name) {
+        return servletContext.getAttribute(name);
+    }
+
+    public void setAttribute(String name, Object value) {
+        servletContext.setAttribute(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        servletContext.removeAttribute(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        return servletContext.getAttributeNames();
+    }
+
+    public URL getResource(String path)
+       throws MalformedURLException {
+       return servletContext.getResource(path);
+    }
+
+    public InputStream getResourceAsStream(String path) {
+    return servletContext.getResourceAsStream(path);
+    }
+
+    public String getRealPath(String path) {
+        if (path.equals("/")) {
+            String value = servletContext.getRealPath(path);
+            if (value == null) {
+                // Try to figure out the path of the root from that of WEB-INF
+                try {
+                value = this.servletContext.getResource("/WEB-INF/web.xml").toString();
+                } catch (MalformedURLException mue) {
+                    throw new ContextURLException("Cannot determine the base URL for " + path, mue);
+                }
+                value = value.substring(0,value.length()-"WEB-INF/web.xml".length());
+            }
+            return value;
+        }
+        return servletContext.getRealPath(path);
+    }
+
+    public String getMimeType(String file) {
+      return servletContext.getMimeType(file);
+    }
+
+    public String getInitParameter(String name) {
+        return servletContext.getInitParameter(name);
+    }
+
+    /*
+     * These methods are not in Cocoon's Context interface, but in the
+     * ServletContext. To use them you have to downcast Cocoon's Context
+     * to this HttpContext until we decide to add them to the Context
+     * interface too.
+     * 
+     * The following methods are deprecated since Servlet API 2.0 or 2.1
+     * and will not be implemented here:
+     * - public Servlet getServlet(String name)
+     * - public Enumeration getServletNames()
+     * - public Enumeration getServlets()
+     * - public void log(Exception exception, String msg)
+     */
+
+    public ServletContext getContext(String uripath) {
+        return this.servletContext.getContext(uripath);
+    }
+
+    public Enumeration getInitParameterNames() {
+        return this.servletContext.getInitParameterNames();
+    }
+
+    public int getMajorVersion() {
+        return this.servletContext.getMajorVersion();
+    }
+
+    public int getMinorVersion() {
+        return this.servletContext.getMinorVersion();
+    }
+
+    public RequestDispatcher getNamedDispatcher(String name) {
+        return this.servletContext.getNamedDispatcher(name);
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return this.servletContext.getRequestDispatcher(path);
+    }
+
+    public String getServerInfo() {
+        return this.servletContext.getServerInfo();
+    }
+
+    public void log(String msg) {
+        this.servletContext.log(msg);
+    }
+
+    public void log(String msg, Throwable throwable) {
+        this.servletContext.log(msg, throwable);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpCookie.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpCookie.java
new file mode 100644
index 0000000..c41f915
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpCookie.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.http;
+
+import org.apache.cocoon.environment.Cookie;
+
+/**
+ *
+ * Creates a cookie, a small amount of information sent by a servlet to
+ * a Web browser, saved by the browser, and later sent back to the server.
+ * A cookie's value can uniquely
+ * identify a client, so cookies are commonly used for session management.
+ *
+ * <p>A cookie has a name, a single value, and optional attributes
+ * such as a comment, path and domain qualifiers, a maximum age, and a
+ * version number. Some Web browsers have bugs in how they handle the
+ * optional attributes, so use them sparingly to improve the interoperability
+ * of your servlets.
+ *
+ * <p>The servlet sends cookies to the browser by using the
+ * {@link HttpResponse#addCookie(Cookie)} method, which adds
+ * fields to HTTP response headers to send cookies to the
+ * browser, one at a time. The browser is expected to
+ * support 20 cookies for each Web server, 300 cookies total, and
+ * may limit cookie size to 4 KB each.
+ *
+ * <p>The browser returns cookies to the servlet by adding
+ * fields to HTTP request headers. Cookies can be retrieved
+ * from a request by using the {@link HttpRequest#getCookies()} method.
+ * Several cookies might have the same name but different path attributes.
+ *
+ * <p>Cookies affect the caching of the Web pages that use them.
+ * HTTP 1.0 does not cache pages that use cookies created with
+ * this class. This class does not support the cache control
+ * defined with HTTP 1.1.
+ *
+ * <p>This class supports both the Version 0 (by Netscape) and Version 1
+ * (by RFC 2109) cookie specifications. By default, cookies are
+ * created using Version 0 to ensure the best interoperability.
+ *
+ *
+ * @version $Id$
+ */
+public final class HttpCookie
+implements Cookie {
+
+    private javax.servlet.http.Cookie cookie;
+
+    public HttpCookie(String name, String value) {
+        this.cookie = new javax.servlet.http.Cookie(name, value);
+    }
+
+    public HttpCookie(javax.servlet.http.Cookie cookie) {
+        this.cookie = cookie;
+    }
+
+    public javax.servlet.http.Cookie getServletCookie() {
+        this.checkState();
+        return this.cookie;
+    }
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p>The name must conform to RFC 2109. That means it can contain
+     * only ASCII alphanumeric characters and cannot contain commas,
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p>The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * <code>setValue</code> method.
+     *
+     * <p>By default, cookies are created according to the Netscape
+     * cookie specification. The version can be changed with the
+     * <code>setVersion</code> method.
+     *
+     *
+     * @param name                         a <code>String</code> specifying the name of the cookie
+     *
+     * @param value                        a <code>String</code> specifying the value of the cookie
+     *
+     * @throws IllegalArgumentException        if the cookie name contains illegal characters
+     *                                        (for example, a comma, space, or semicolon)
+     *                                        or it is one of the tokens reserved for use
+     *                                        by the cookie protocol
+     * @see #setValue(String)
+     * @see #setVersion(int)
+     *
+     */
+
+    public void init(String name, String value) {
+        if (this.cookie == null) {
+            this.cookie = new javax.servlet.http.Cookie(name, value);
+        } else {
+            throw new IllegalStateException("Cookie is already initialised");
+        }
+    }
+
+
+    private void checkState() {
+        if (this.cookie == null) {
+            throw new IllegalStateException("Cookie is not initialised");
+        }
+    }
+
+    /**
+     *
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie
+     * to the user. Comments
+     * are not supported by Netscape Version 0 cookies.
+     *
+     * @param purpose                a <code>String</code> specifying the comment
+     *                                to display to the user
+     *
+     * @see #getComment()
+     *
+     */
+
+    public void setComment(String purpose) {
+        this.checkState();
+        this.cookie.setComment(purpose);
+    }
+
+
+
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * <code>null</code> if the cookie has no comment.
+     *
+     * @return                        a <code>String</code> containing the comment,
+     *                                or <code>null</code> if none
+     *
+     * @see #setComment(String)
+     *
+     */
+
+    public String getComment() {
+        this.checkState();
+        return this.cookie.getComment();
+    }
+
+
+
+
+    /**
+     *
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p>The form of the domain name is specified by RFC 2109. A domain
+     * name begins with a dot (<code>.foo.com</code>) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, <code>www.foo.com</code>, but not
+     * <code>a.b.foo.com</code>). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     *
+     * @param pattern                a <code>String</code> containing the domain name
+     *                                within which this cookie is visible;
+     *                                form is according to RFC 2109
+     *
+     * @see #getDomain()
+     *
+     */
+
+    public void setDomain(String pattern) {
+        this.checkState();
+        this.cookie.setDomain(pattern);
+    }
+
+
+
+
+
+    /**
+     * Returns the domain name set for this cookie. The form of
+     * the domain name is set by RFC 2109.
+     *
+     * @return                        a <code>String</code> containing the domain name
+     *
+     * @see #setDomain(String)
+     *
+     */
+
+    public String getDomain() {
+        this.checkState();
+        return this.cookie.getDomain();
+    }
+
+
+
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p>A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p>A negative value means
+     * that the cookie is not stored persistently and will be deleted
+     * when the Web browser exits. A zero value causes the cookie
+     * to be deleted.
+     *
+     * @param expiry                an integer specifying the maximum age of the
+     *                                 cookie in seconds; if negative, means
+     *                                the cookie is not stored; if zero, deletes
+     *                                the cookie
+     *
+     *
+     * @see #getMaxAge()
+     *
+     */
+
+    public void setMaxAge(int expiry) {
+        this.checkState();
+        this.cookie.setMaxAge(expiry);
+    }
+
+
+
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds,
+     * By default, <code>-1</code> indicating the cookie will persist
+     * until browser shutdown.
+     *
+     *
+     * @return                        an integer specifying the maximum age of the
+     *                                cookie in seconds; if negative, means
+     *                                the cookie persists until browser shutdown
+     *
+     *
+     * @see #setMaxAge(int)
+     *
+     */
+
+    public int getMaxAge() {
+        this.checkState();
+        return this.cookie.getMaxAge();
+    }
+
+
+
+
+    /**
+     * Specifies a path for the cookie
+     * to which the client should return the cookie.
+     *
+     * <p>The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories.
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p>Consult RFC 2109 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     *
+     * @param uri                a <code>String</code> specifying a path
+     *
+     *
+     * @see #getPath()
+     *
+     */
+
+    public void setPath(String uri) {
+        this.checkState();
+        this.cookie.setPath(uri);
+    }
+
+
+
+
+    /**
+     * Returns the path on the server
+     * to which the browser returns this cookie. The
+     * cookie is visible to all subpaths on the server.
+     *
+     *
+     * @return                a <code>String</code> specifying a path that contains
+     *                        a servlet name, for example, <i>/catalog</i>
+     *
+     * @see #setPath(String)
+     *
+     */
+
+    public String getPath() {
+        this.checkState();
+        return this.cookie.getPath();
+    }
+
+
+
+
+
+    /**
+     * Indicates to the browser whether the cookie should only be sent
+     * using a secure protocol, such as HTTPS or SSL.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * @param flag        if <code>true</code>, sends the cookie from the browser
+     *                        to the server using only when using a secure protocol;
+     *                        if <code>false</code>, sent on any protocol
+     *
+     * @see #getSecure()
+     *
+     */
+
+    public void setSecure(boolean flag) {
+        this.checkState();
+        this.cookie.setSecure(flag);
+    }
+
+
+
+
+    /**
+     * Returns <code>true</code> if the browser is sending cookies
+     * only over a secure protocol, or <code>false</code> if the
+     * browser can send cookies using any protocol.
+     *
+     * @return                <code>true</code> if the browser can use
+     *                        any standard protocol; otherwise, <code>false</code>
+     *
+     * @see #setSecure(boolean)
+     *
+     */
+
+    public boolean getSecure() {
+        this.checkState();
+        return this.cookie.getSecure();
+    }
+
+
+
+
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return                a <code>String</code> specifying the cookie's name
+     *
+     */
+
+    public String getName() {
+        this.checkState();
+        return this.cookie.getName();
+    }
+
+
+
+
+
+    /**
+     *
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p>With Version 0 cookies, values should not contain white
+     * space, brackets, parentheses, equals signs, commas,
+     * double quotes, slashes, question marks, at signs, colons,
+     * and semicolons. Empty values may not behave the same way
+     * on all browsers.
+     *
+     * @param newValue                a <code>String</code> specifying the new value
+     *
+     *
+     * @see #getValue()
+     * @see Cookie
+     *
+     */
+
+    public void setValue(String newValue) {
+        this.checkState();
+        this.cookie.setValue(newValue);
+    }
+
+
+
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return                        a <code>String</code> containing the cookie's
+     *                                present value
+     *
+     * @see #setValue(String)
+     * @see Cookie
+     *
+     */
+
+    public String getValue() {
+        this.checkState();
+        return this.cookie.getValue();
+    }
+
+
+
+
+    /**
+     * Returns the version of the protocol this cookie complies
+     * with. Version 1 complies with RFC 2109,
+     * and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided
+     * by a browser use and identify the browser's cookie version.
+     *
+     *
+     * @return                        0 if the cookie complies with the
+     *                                original Netscape specification; 1
+     *                                if the cookie complies with RFC 2109
+     *
+     * @see #setVersion(int)
+     *
+     */
+
+    public int getVersion() {
+        this.checkState();
+        return this.cookie.getVersion();
+    }
+
+
+
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2109.
+     *
+     * <p>Since RFC 2109 is still somewhat new, consider
+     * version 1 as experimental; do not use it yet on production sites.
+     *
+     *
+     * @param v                        0 if the cookie should comply with
+     *                                the original Netscape specification;
+     *                                1 if the cookie should comply with RFC 2109
+     *
+     * @see #getVersion()
+     *
+     */
+
+    public void setVersion(int v) {
+        this.checkState();
+        this.cookie.setVersion(v);
+    }
+
+
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java
new file mode 100644
index 0000000..f047bc2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpEnvironment.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.http;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.cocoon.environment.AbstractEnvironment;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.util.NetUtils;
+
+/**
+ * HTTP Servlet environment.
+ *
+ * @version $Id$
+ */
+public class HttpEnvironment extends AbstractEnvironment {
+
+    public static final String HTTP_REQUEST_OBJECT = "httprequest";
+    public static final String HTTP_RESPONSE_OBJECT= "httpresponse";
+    public static final String HTTP_SERVLET_CONTEXT= "httpservletcontext";
+
+    /** The HttpRequest */
+    private HttpRequest request;
+
+    /** The HttpResponse */
+    private HttpResponse response;
+
+    /** Cache content type as there is no getContentType() in reponse object */
+    private String contentType;
+
+    /**
+     * Constructs a HttpEnvironment object from a HttpServletRequest
+     * and HttpServletResponse objects
+     */
+    public HttpEnvironment(String uri,
+                           String root,
+                           HttpServletRequest req,
+                           HttpServletResponse res,
+                           ServletContext servletContext,
+                           Context context,
+                           String containerEncoding,
+                           String defaultFormEncoding)
+    throws IOException {
+        super(uri, null, null);
+
+        this.request = new HttpRequest(req, this);
+        this.request.setCharacterEncoding(defaultFormEncoding);
+        this.request.setContainerEncoding(containerEncoding);
+        this.response = new HttpResponse(res);
+
+        setView(extractView(this.request));
+        setAction(extractAction(this.request));
+
+        this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT, this.request);
+        this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT, this.response);
+        this.objectModel.put(ObjectModelHelper.CONTEXT_OBJECT, context);
+
+        // This is a kind of a hack for the components that need
+        // the real servlet objects to pass them along to other
+        // libraries.
+        this.objectModel.put(HTTP_REQUEST_OBJECT, req);
+        this.objectModel.put(HTTP_RESPONSE_OBJECT, res);
+        this.objectModel.put(HTTP_SERVLET_CONTEXT, servletContext);
+    }
+
+    /**
+     *  Redirect the client to new URL
+     */
+    public void redirect(String newURL,
+                         boolean global,
+                         boolean permanent)
+    throws IOException {
+        // Redirect
+        String redirect = this.response.encodeRedirectURL(newURL);
+
+        // FIXME (VG): WebSphere 4.0/4.0.1 bug
+        if (!newURL.startsWith("/") && newURL.indexOf(':') == -1 && redirect.indexOf(':') != -1) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Redirect: WebSphere Bug Detected!");
+            }
+            String base = NetUtils.getPath(request.getRequestURI());
+            if (base.startsWith("/")) {
+                base = base.substring(1);
+            }
+            redirect = response.encodeRedirectURL(base + '/' + newURL);
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Sending redirect to '" + redirect + "'");
+        }
+
+        if (permanent) {
+            this.response.sendPermanentRedirect(redirect);
+        } else {
+            this.response.sendRedirect(redirect);
+        }
+    }
+
+    /**
+     * Set the StatusCode
+     */
+    public void setStatus(int statusCode) {
+        this.response.setStatus(statusCode);
+    }
+
+    /**
+     * Set the ContentType
+     */
+    public void setContentType(String contentType) {
+        this.response.setContentType(contentType);
+        this.contentType = contentType;
+    }
+
+    /**
+     * Get the ContentType
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+
+    /**
+     * Set the length of the generated content
+     */
+    public void setContentLength(int length) {
+        this.response.setContentLength(length);
+    }
+
+    /**
+     * Check if the response has been modified since the same
+     * "resource" was requested.
+     * The caller has to test if it is really the same "resource"
+     * which is requested.
+     * @return true if the response is modified or if the
+     *         environment is not able to test it
+     */
+    public boolean isResponseModified(long lastModified) {
+        if (lastModified != 0) {
+            long if_modified_since = this.request.getDateHeader("If-Modified-Since");
+            this.response.setDateHeader("Last-Modified", lastModified);
+            return (if_modified_since / 1000 < lastModified  / 1000);
+        }
+        return true;
+    }
+
+    /**
+     * Mark the response as not modified.
+     */
+    public void setResponseIsNotModified() {
+        this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+    }
+
+    /**
+     * Reset the response if possible. This allows error handlers to have
+     * a higher chance to produce clean output if the pipeline that raised
+     * the error has already output some data.
+     *
+     * @return true if the response was successfully reset
+     */
+    public boolean tryResetResponse()
+    throws IOException {
+        if (!super.tryResetResponse()) {
+            try {
+                if (!this.response.isCommitted()) {
+                    this.response.reset();
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Response successfully reset");
+                    }
+                    return true;
+                }
+            } catch (Exception e) {
+                // Log the error, but don't transmit it
+                getLogger().warn("Problem resetting response", e);
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Response wasn't reset");
+            }
+            return false;
+        }
+        return true;
+    }
+
+
+    /**
+     * Get the output stream where to write the generated resource.
+     * The returned stream is buffered by the environment. If the
+     * buffer size is -1 then the complete output is buffered.
+     * If the buffer size is 0, no buffering takes place.
+     */
+    public OutputStream getOutputStream(final int bufferSize)
+    throws IOException {
+        if (this.outputStream == null) {
+            this.outputStream = this.response.getOutputStream();
+        }
+        return super.getOutputStream(bufferSize);
+    }
+
+    /**
+     * Always return <code>true</code>.
+     */
+    public boolean isExternal() {
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpRequest.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpRequest.java
new file mode 100644
index 0000000..e2c676e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpRequest.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.http;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.impl.AbstractRequest;
+import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
+import org.apache.commons.collections.IteratorUtils;
+
+/**
+ * Implements the {@link org.apache.cocoon.environment.Request} interface
+ * to provide request information in the HTTP servlets environment.
+ *
+ * @version $Id$
+ */
+public final class HttpRequest extends AbstractRequest {
+
+    /** The real HttpServletRequest object */
+    private final HttpServletRequest req;
+
+    /** The HttpEnvironment object */
+    private final HttpEnvironment env;
+
+    /** The character encoding of parameters */
+    private String form_encoding;
+
+    /** The default form encoding of the servlet container */
+    private String container_encoding;
+
+    /**
+     * The map to assure 1:1-mapping of server sessions and Cocoon session wrappers
+     */
+    private static final Map sessions = new WeakHashMap();
+
+    private final Map attributes = new HashMap();
+
+    /**
+     * Creates a HttpRequest based on a real HttpServletRequest object
+     */
+    protected HttpRequest(HttpServletRequest req, HttpEnvironment env) {
+        super();
+        this.req = req;
+        this.env = env;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#get(java.lang.String)
+     */
+    public Object get(String name) {
+        // if the request has been wrapped then access its method
+        if (req instanceof MultipartHttpServletRequest) {
+            return ((MultipartHttpServletRequest) req).get(name);
+        }
+        String[] values = req.getParameterValues(name);
+        if (values == null) {
+            return null;
+        }
+        if (values.length == 1) {
+            return values[0];
+        }
+        if (values.length > 1) {
+            Vector vect = new Vector(values.length);
+            for (int i = 0; i < values.length; i++) {
+                vect.add(values[i]);
+            }
+            return vect;
+        }
+        return null;
+    }
+
+    /* The HttpServletRequest interface methods */
+
+    public String getAuthType() {
+        return this.req.getAuthType();
+    }
+
+    private Cookie[] wrappedCookies = null;
+    private Map wrappedCookieMap = null;
+
+    public Cookie[] getCookies() {
+        if (this.wrappedCookieMap == null) {
+            wrapCookies();
+        }
+        return this.wrappedCookies;
+    }
+
+    public Map getCookieMap() {
+        if (this.wrappedCookieMap == null) {
+            wrapCookies();
+        }
+        return this.wrappedCookieMap;
+    }
+
+    private synchronized void wrapCookies() {
+        this.wrappedCookieMap = new HashMap();
+        javax.servlet.http.Cookie[] cookies = this.req.getCookies();
+        if (cookies != null) {
+            this.wrappedCookies = new Cookie[cookies.length];
+            for(int i=0; i<cookies.length;i++) {
+                HttpCookie cookie = new HttpCookie(cookies[i]);
+                this.wrappedCookies[i] = cookie;
+                this.wrappedCookieMap.put(cookie.getName(),cookie);
+            }
+        }
+        this.wrappedCookieMap = Collections.unmodifiableMap(this.wrappedCookieMap);
+    }
+
+    public long getDateHeader(String name) {
+        return this.req.getDateHeader(name);
+    }
+
+    public String getHeader(String name) {
+        return this.req.getHeader(name);
+    }
+
+    public Enumeration getHeaders(String name) {
+        return this.req.getHeaders(name);
+    }
+
+    public Enumeration getHeaderNames() {
+        return this.req.getHeaderNames();
+    }
+
+    public int getIntHeader(String name) {
+        return this.req.getIntHeader(name);
+    }
+
+    public String getMethod() {
+        return this.req.getMethod();
+    }
+
+    public String getPathInfo() {
+        return this.req.getPathInfo();
+    }
+
+    public String getPathTranslated() {
+        return this.req.getPathTranslated();
+    }
+
+    public String getContextPath() {
+        return this.req.getContextPath();
+    }
+
+    public String getQueryString() {
+        return this.req.getQueryString();
+    }
+
+    public String getRemoteUser() {
+        return this.req.getRemoteUser();
+    }
+
+    public boolean isUserInRole(String role) {
+        return this.req.isUserInRole(role);
+    }
+
+    public java.security.Principal getUserPrincipal() {
+        return this.req.getUserPrincipal();
+    }
+
+    public String getRequestedSessionId() {
+        return this.req.getRequestedSessionId();
+    }
+
+    protected String reqURI;
+
+    public String getRequestURI() {
+        if (this.reqURI == null) {
+            this.reqURI = this.req.getRequestURI();
+            if ( this.reqURI.equals("/") ) {
+                String s = this.req.getServletPath();
+                final StringBuffer buffer = new StringBuffer();
+                if ( null != s ) buffer.append(s);
+                s = this.req.getPathInfo();
+                if ( null != s ) buffer.append(s);
+                this.reqURI = buffer.toString();
+            }
+        }
+        return this.reqURI;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapURI()
+     */
+    public String getSitemapURI() {
+        return this.env.getURI();
+    }
+
+    public String getSitemapURIPrefix() {
+        return this.env.getURIPrefix();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapPath()
+     */
+    public String getSitemapPath() {
+        return this.env.getURIPrefix();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getServletPath()
+     */
+    public String getServletPath() {
+        return this.req.getServletPath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSession(boolean)
+     */
+    public Session getSession(boolean create) {
+        javax.servlet.http.HttpSession serverSession = this.req.getSession(create);
+        HttpSession session;
+        if (serverSession != null)
+        {
+            synchronized (sessions)
+            {
+                // retrieve existing wrapper
+                WeakReference ref = (WeakReference) sessions.get(serverSession);
+                if (ref == null || (session = (HttpSession) ref.get()) == null)
+                {
+                    // create new wrapper
+                    session = new HttpSession(serverSession);
+                    sessions.put(serverSession, new WeakReference(session));
+                }
+            }
+        }
+        else
+        {
+            // invalidate
+            session = null;
+        }
+        return session;
+    }
+
+    public Session getSession() {
+        return this.getSession(true);
+    }
+
+    public boolean isRequestedSessionIdValid() {
+        return this.req.isRequestedSessionIdValid();
+    }
+
+    public boolean isRequestedSessionIdFromCookie()  {
+        return this.req.isRequestedSessionIdFromCookie();
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+        return this.req.isRequestedSessionIdFromURL();
+    }
+
+    /**
+     * @deprecated As of Version 2.1 of the Java Servlet API, use
+     *             {@link #isRequestedSessionIdFromURL()} instead.
+     */
+    public boolean isRequestedSessionIdFromUrl() {
+        return this.req.isRequestedSessionIdFromURL();
+    }
+
+    /* The ServletRequest interface methods */
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.getAttribute(name, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.getAttributeNames(Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.setAttribute(name, value, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.removeAttribute(name, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return this.attributes.get(name);
+        }
+        return this.req.getAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return IteratorUtils.asEnumeration(this.attributes.keySet().iterator());
+        }
+        return this.req.getAttributeNames();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object value, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.put(name, value);
+        } else {
+            this.req.setAttribute(name, value);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.remove(name);
+        } else {
+            this.req.removeAttribute(name);
+        }
+    }
+
+    public String getCharacterEncoding() {
+        if (this.form_encoding == null) {
+            return this.req.getCharacterEncoding();
+        }
+        return this.form_encoding;
+    }
+
+    public void setCharacterEncoding(String form_encoding)
+    throws java.io.UnsupportedEncodingException {
+        this.form_encoding = form_encoding;
+    }
+
+    /**
+     * Sets the default encoding of the servlet container.
+     */
+    public void setContainerEncoding(String container_encoding) {
+        this.container_encoding = container_encoding;
+    }
+
+    public int getContentLength() {
+        return this.req.getContentLength();
+    }
+
+    public String getContentType() {
+        return this.req.getContentType();
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return this.req.getInputStream();
+    }
+
+    public String getParameter(String name) {
+        String value = this.req.getParameter(name);
+        if (this.form_encoding == null || value == null) {
+            return value;
+        }
+        return decode(value);
+    }
+
+    private String decode(String str) {
+        if (str == null) return null;
+        try {
+            if (this.container_encoding == null)
+                this.container_encoding = "ISO-8859-1";
+            byte[] bytes = str.getBytes(this.container_encoding);
+            return new String(bytes, form_encoding);
+        } catch (java.io.UnsupportedEncodingException uee) {
+            throw new RequestEncodingException("Unsupported Encoding Exception", uee);
+        }
+    }
+
+    public Enumeration getParameterNames() {
+        return this.req.getParameterNames();
+    }
+
+    public String[] getParameterValues(String name) {
+        String[] values = this.req.getParameterValues(name);
+        if (values == null) return null;
+        if (this.form_encoding == null) {
+            return values;
+        }
+        String[] decoded_values = new String[values.length];
+        for (int i = 0; i < values.length; ++i) {
+            decoded_values[i] = decode(values[i]);
+        }
+        return decoded_values;
+    }
+
+    public String getProtocol() {
+        return this.req.getProtocol();
+    }
+
+    public String getScheme() {
+        return this.req.getScheme();
+    }
+
+    public String getServerName() {
+        return this.req.getServerName();
+    }
+
+    public int getServerPort() {
+        return this.req.getServerPort();
+    }
+
+    public BufferedReader getReader() throws IOException {
+        return this.req.getReader();
+    }
+
+    public String getRemoteAddr() {
+        return this.req.getRemoteAddr();
+    }
+
+    public String getRemoteHost() {
+        return this.req.getRemoteHost();
+    }
+
+    public Locale getLocale() {
+        return this.req.getLocale();
+    }
+
+    public Enumeration getLocales() {
+        return this.req.getLocales();
+    }
+
+    public boolean isSecure() {
+        return this.req.isSecure();
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return this.req.getRequestDispatcher(path);
+    }
+
+    /**
+     * @deprecated As of Version 2.1 of the Java Servlet API, use
+     * {@link javax.servlet.ServletContext#getRealPath(java.lang.String)}instead.
+     */
+    public String getRealPath(String path) {
+        return this.req.getRealPath(path);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Request#searchAttribute(java.lang.String)
+     */
+    public Object searchAttribute(String name) {
+        Object result = this.getAttribute(name, REQUEST_SCOPE);
+        if ( result == null ) {
+            result = this.getAttribute(name, GLOBAL_SCOPE);
+        }
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpResponse.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpResponse.java
new file mode 100644
index 0000000..cd59e5c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpResponse.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.http;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Response;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+/**
+ * Implements the {@link org.apache.cocoon.environment.Response} interface
+ * to provide response functionality in the HTTP servlets environment.
+ * 
+ * @version $Id$
+ */
+public final class HttpResponse implements Response {
+
+    /** The real HttpServletResponse object */
+    private final HttpServletResponse res;
+
+    /**
+     * Creates a HttpServletResponse based on a real HttpServletResponse object
+     */
+    protected HttpResponse (HttpServletResponse res) {
+        this.res = res;
+    }
+
+    /**
+     * Create a new cookie which is not added to the response
+     */
+    public Cookie createCookie(String name, String value) {
+        return new HttpCookie(name, value);
+    }
+
+    public void addCookie(Cookie cookie) {
+        if (cookie instanceof HttpCookie) {
+            this.res.addCookie(((HttpCookie)cookie).getServletCookie());
+        } else {
+            javax.servlet.http.Cookie newCookie;
+            newCookie = new javax.servlet.http.Cookie(cookie.getName(), cookie.getValue());
+            newCookie.setComment(cookie.getComment());
+            newCookie.setDomain(cookie.getDomain());
+            newCookie.setMaxAge(cookie.getMaxAge());
+            newCookie.setPath(cookie.getPath());
+            newCookie.setSecure(cookie.getSecure());
+            newCookie.setVersion(cookie.getVersion());
+            this.res.addCookie(newCookie);
+        }
+    }
+
+    public boolean containsHeader(String name) {
+        return this.res.containsHeader(name);
+    }
+
+    public String encodeURL(String url) {
+        if (url != null && url.indexOf(";jsessionid=") != -1)
+            return url;
+        return this.res.encodeURL(url);
+    }
+
+    public String encodeRedirectURL(String url) {
+        if (url != null && url.indexOf(";jsessionid=") != -1) {
+            return url;
+        }
+
+        return this.res.encodeRedirectURL(url);
+    }
+
+    public void sendError(int sc, String msg) throws IOException {
+        this.res.sendError(sc, msg);
+    }
+
+    public void sendError(int sc) throws IOException {
+        this.res.sendError(sc);
+    }
+
+    public void sendRedirect(String location) throws IOException {
+        this.res.sendRedirect(location);
+    }
+
+    public void sendPermanentRedirect(String location) throws IOException {
+        this.res.setHeader("location", location);
+        this.res.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
+    }
+    
+    public void setDateHeader(String name, long date) {
+        this.res.setDateHeader(name, date);
+    }
+
+    public void addDateHeader(String name, long date) {
+        this.res.addDateHeader(name, date);
+    }
+
+    public void setHeader(String name, String value) {
+        this.res.setHeader(name, value);
+    }
+
+    public void addHeader(String name, String value) {
+        this.res.addHeader(name, value);
+    }
+
+    public void setIntHeader(String name, int value) {
+        this.res.setIntHeader(name, value);
+    }
+
+    public void addIntHeader(String name, int value) {
+        this.res.addIntHeader(name, value);
+    }
+
+    public void setStatus(int sc) {
+        this.res.setStatus(sc);
+    }
+
+    /**
+     * @deprecated        As of version 2.1, use encodeURL(String url) instead
+     */
+    public String encodeUrl(String url) {
+        return this.res.encodeUrl(url);
+    }
+
+    /**
+     * @deprecated        As of version 2.1, use
+     *              encodeRedirectURL(String url) instead
+     */
+    public String encodeRedirectUrl(String url) {
+        return this.res.encodeRedirectUrl(url);
+    }
+
+    /**
+     * @deprecated As of version 2.1, due to ambiguous meaning of the
+     * message parameter. To set a status code
+     * use <code>setStatus(int)</code>, to send an error with a description
+     * use <code>sendError(int, String)</code>.
+     */
+    public void setStatus(int sc, String sm) {
+        this.res.setStatus(sc, sm);
+    }
+
+    /* The ServletResponse interface methods */
+
+    public String getCharacterEncoding() {
+        return this.res.getCharacterEncoding();
+    }
+
+    public ServletOutputStream getOutputStream() throws IOException {
+        //throw new IllegalStateException ("you are not a serializer or reader");
+        return this.res.getOutputStream();
+    }
+
+    public PrintWriter getWriter() throws IOException {
+        //throw new IllegalStateException ("you are not a serializer or reader");
+        return this.res.getWriter();
+    }
+
+    public void setContentLength(int len) {
+        this.res.setContentLength(len);
+    }
+
+    public void setContentType(String type) {
+        this.res.setContentType(type);
+    }
+
+    public void setBufferSize(int size) {
+        this.res.setBufferSize(size);
+    }
+
+    public int getBufferSize() {
+        return this.res.getBufferSize();
+    }
+
+    public void flushBuffer() throws IOException {
+        this.res.flushBuffer();
+    }
+
+    public boolean isCommitted() {
+        return this.res.isCommitted();
+    }
+
+    public void reset() {
+        this.res.reset();
+    }
+
+    public void setLocale(Locale loc) {
+        this.res.setLocale(loc);
+    }
+
+    public Locale getLocale() {
+        return this.res.getLocale();
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpSession.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpSession.java
new file mode 100644
index 0000000..d4249ba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/HttpSession.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.http;
+
+import org.apache.cocoon.environment.impl.AbstractSession;
+
+import java.util.Enumeration;
+
+/**
+ *
+ * Provides a way to identify a user across more than one page
+ * request or visit to a Web site and to store information about that user.
+ *
+ * <p>Cocoon uses this interface to create a session
+ * between a client and the "cocoon server". The session persists
+ * for a specified time period, across more than one connection or
+ * page request from the user. A session usually corresponds to one
+ * user, who may visit a site many times. The server can maintain a
+ * session in many ways such as using cookies or rewriting URLs.
+ *
+ * <p>This interface allows Cocoon to
+ * <ul>
+ * <li>View and manipulate information about a session, such as
+ *     the session identifier, creation time, and last accessed time
+ * <li>Bind objects to sessions, allowing user information to persist
+ *     across multiple user connections
+ * </ul>
+ *
+ * <p>Session information is scoped only to the current context
+ * (<code>Context</code>), so information stored in one context
+ * will not be directly visible in another.
+ *
+ * @version $Id$
+ *
+ */
+public final class HttpSession
+extends AbstractSession {
+
+    javax.servlet.http.HttpSession wrappedSession;
+
+    /**
+     * Construct a new session from an HttpSession
+     */
+    public HttpSession(javax.servlet.http.HttpSession session) {
+        this.wrappedSession = session;
+    }
+
+    /**
+     *
+     * Returns the time when this session was created, measured
+     * in milliseconds since midnight January 1, 1970 GMT.
+     *
+     * @return                                a <code>long</code> specifying
+     *                                         when this session was created,
+     *                                        expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public long getCreationTime() {
+        return this.wrappedSession.getCreationTime();
+    }
+
+    /**
+     *
+     * Returns a string containing the unique identifier assigned
+     * to this session. The identifier is assigned
+     * by the context container and is implementation dependent.
+     *
+     * @return                                a string specifying the identifier
+     *                                        assigned to this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public String getId() {
+        return this.wrappedSession.getId();
+    }
+
+    /**
+     *
+     * Returns the last time the client sent a request associated with
+     * this session, as the number of milliseconds since midnight
+     * January 1, 1970 GMT.
+     *
+     * <p>Actions that your application takes, such as getting or setting
+     * a value associated with the session, do not affect the access
+     * time.
+     *
+     * @return                                a <code>long</code>
+     *                                        representing the last time
+     *                                        the client sent a request associated
+     *                                        with this session, expressed in
+     *                                        milliseconds since 1/1/1970 GMT
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+
+    public long getLastAccessedTime() {
+        return this.wrappedSession.getLastAccessedTime();
+    }
+
+    /**
+     *
+     * Specifies the time, in seconds, between client requests before the
+     * contextcontainer will invalidate this session.  A negative time
+     * indicates the session should never timeout.
+     *
+     * @param interval                An integer specifying the number
+     *                                 of seconds
+     *
+     */
+    public void setMaxInactiveInterval(int interval) {
+        this.wrappedSession.setMaxInactiveInterval(interval);
+    }
+
+   /**
+    * Returns the maximum time interval, in seconds, that
+    * the context container will keep this session open between
+    * client accesses. After this interval, the context container
+    * will invalidate the session.  The maximum time interval can be set
+    * with the <code>setMaxInactiveInterval</code> method.
+    * A negative time indicates the session should never timeout.
+    *
+    *
+    * @return                an integer specifying the number of
+    *                        seconds this session remains open
+    *                        between client requests
+    *
+    * @see                #setMaxInactiveInterval(int)
+    *
+    *
+    */
+    public int getMaxInactiveInterval() {
+        return this.wrappedSession.getMaxInactiveInterval();
+    }
+
+    /**
+     *
+     * Returns the object bound with the specified name in this session, or
+     * <code>null</code> if no object is bound under the name.
+     *
+     * @param name                a string specifying the name of the object
+     *
+     * @return                        the object with the specified name
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public Object getAttribute(String name) {
+        return this.wrappedSession.getAttribute(name);
+    }
+
+    /**
+     *
+     * Returns an <code>Enumeration</code> of <code>String</code> objects
+     * containing the names of all the objects bound to this session.
+     *
+     * @return                        an <code>Enumeration</code> of
+     *                                <code>String</code> objects specifying the
+     *                                names of all the objects bound to
+     *                                this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public Enumeration getAttributeNames() {
+        return this.wrappedSession.getAttributeNames();
+    }
+
+    /**
+     * Binds an object to this session, using the name specified.
+     * If an object of the same name is already bound to the session,
+     * the object is replaced.
+     *
+     *
+     * @param name                        the name to which the object is bound;
+     *                                        cannot be null
+     *
+     * @param value                        the object to be bound; cannot be null
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     *
+     */
+    public void setAttribute(String name, Object value) {
+        this.wrappedSession.setAttribute(name, value);
+    }
+
+    /**
+     *
+     * Removes the object bound with the specified name from
+     * this session. If the session does not have an object
+     * bound with the specified name, this method does nothing.
+     *
+     *
+     * @param name                                the name of the object to
+     *                                                remove from this session
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        invalidated session
+     */
+    public void removeAttribute(String name) {
+        this.wrappedSession.removeAttribute(name);
+    }
+
+    /**
+     *
+     * Invalidates this session
+     * to it.
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    public void invalidate() {
+        this.wrappedSession.invalidate();
+    }
+
+    /**
+     *
+     * Returns <code>true</code> if the client does not yet know about the
+     * session or if the client chooses not to join the session.  For
+     * example, if the server used only cookie-based sessions, and
+     * the client had disabled the use of cookies, then a session would
+     * be new on each request.
+     *
+     * @return                                 <code>true</code> if the
+     *                                        server has created a session,
+     *                                        but the client has not yet joined
+     *
+     * @exception IllegalStateException        if this method is called on an
+     *                                        already invalidated session
+     *
+     */
+    public boolean isNew() {
+        return this.wrappedSession.isNew();
+    }
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/RequestEncodingException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/RequestEncodingException.java
new file mode 100644
index 0000000..92f0962
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/http/RequestEncodingException.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright 1999-2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.environment.http;

+

+import org.apache.avalon.framework.CascadingRuntimeException;

+

+public final class RequestEncodingException extends CascadingRuntimeException

+{

+    public RequestEncodingException(String message)

+    {

+        super(message, null);

+    }

+

+    public RequestEncodingException(String message, Throwable cause)

+    {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractContext.java
new file mode 100644
index 0000000..5b2bd8f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractContext.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.impl;
+
+import java.util.Map;
+
+import org.apache.cocoon.environment.Context;
+
+/**
+ * Base class for any context
+ *
+ * @version $Id$
+ */
+public abstract class AbstractContext 
+    implements Context {
+
+    public Map getAttributes() {
+	return new ContextMap(this);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractRequest.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractRequest.java
new file mode 100644
index 0000000..0bde7d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractRequest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.impl;
+
+import java.util.Map;
+
+import org.apache.cocoon.environment.Request;
+
+/**
+ * Base class for any request
+ *
+ * @version $Id$
+ */
+public abstract class AbstractRequest 
+    implements Request {
+
+    public Map getAttributes() {
+	return new RequestMap(this);
+    }
+
+    public Map getParameters() {
+	return new RequestParameterMap(this);
+    }
+
+    public Map getHeaders() {
+	return new RequestHeaderMap(this);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractSession.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractSession.java
new file mode 100644
index 0000000..b659a9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/AbstractSession.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.impl;
+
+import java.util.Map;
+
+import org.apache.cocoon.environment.Session;
+
+/**
+ * Base class for any session
+ *
+ * @version $Id$
+ */
+public abstract class AbstractSession 
+    implements Session {
+
+    public Map getAttributes() {
+	return new SessionMap(this);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/BaseMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/BaseMap.java
new file mode 100644
index 0000000..1590e76
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/BaseMap.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Base class for context maps
+ *
+ * @version $Id$
+ */
+public abstract class BaseMap extends java.util.AbstractMap {
+
+    protected static class Entry implements Map.Entry {
+        private final Object key;
+        private final Object value;
+
+        public Entry(Object key, Object value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        public Object getKey() {
+            return key;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object setValue(Object value) {
+            throw new UnsupportedOperationException();
+        }
+
+        public int hashCode() {
+            return (key != null ? key.hashCode() : 0) ^ (value != null ? value.hashCode() : 0);
+        }
+
+        public boolean equals(Object obj) {
+            if (obj == null || !(obj instanceof Map.Entry)) {
+                return false;
+            }
+
+            Map.Entry other = (Map.Entry) obj;
+            Object key = other.getKey();
+            if (key == this.key || key != null && key.equals(this.key)) {
+                Object value = other.getValue();
+                return value == this.value || value != null && value.equals(this.value);
+            }
+            return false;
+        }
+    }
+
+
+    public BaseMap() {
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void putAll(Map t) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object remove(Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Set entrySet() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/ContextMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/ContextMap.java
new file mode 100644
index 0000000..caf3e77
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/ContextMap.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import org.apache.cocoon.environment.Context;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Context attributes map
+ *
+ * @version $Id$
+ */
+public class ContextMap extends BaseMap {
+
+    private Context context;
+
+
+    public ContextMap(Context context) {
+        this.context = context;
+    }
+
+    public Object get(Object key) {
+        return context.getAttribute(key.toString());
+    }
+
+    public Object put(Object key, Object value) {
+        String sKey = key.toString();
+        Object old = context.getAttribute(sKey);
+        context.setAttribute(sKey, value);
+        return old;
+    }
+
+    public Object remove(Object key) {
+        String sKey = key.toString();
+        Object old = context.getAttribute(sKey);
+        context.removeAttribute(sKey);
+        return old;
+    }
+
+    public Set entrySet() {
+        Set entries = new HashSet();
+        for (Enumeration e = context.getAttributeNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            entries.add(new BaseMap.Entry(name, context.getAttribute(name)));
+        }
+
+        return entries;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof ContextMap)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestHeaderMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestHeaderMap.java
new file mode 100644
index 0000000..148dbc7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestHeaderMap.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Request headers map
+ *
+ * @version $Id$
+ */
+public class RequestHeaderMap extends BaseMap {
+
+    private Request request;
+
+
+    public RequestHeaderMap(Request request) {
+        this.request = request;
+    }
+
+    public Object get(Object key) {
+        return request.getHeader(key.toString());
+    }
+
+    public Set entrySet() {
+        Set entries = new HashSet();
+        for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            entries.add(new BaseMap.Entry(name, request.getHeader(name)));
+        }
+
+        return entries;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof RequestHeaderMap)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestMap.java
new file mode 100644
index 0000000..a9fadcd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestMap.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Request attributes map
+ *
+ * @version $Id$
+ */
+public class RequestMap extends BaseMap {
+
+    private Request request;
+
+
+    public RequestMap(Request request) {
+        this.request = request;
+    }
+
+    public Object get(Object key) {
+        return request.getAttribute(key.toString());
+    }
+
+    public Object put(Object key, Object value) {
+        String sKey = key.toString();
+        Object old = request.getAttribute(sKey);
+        request.setAttribute(sKey, value);
+        return old;
+    }
+
+    public Object remove(Object key) {
+        String sKey = key.toString();
+        Object old = request.getAttribute(sKey);
+        request.removeAttribute(sKey);
+        return old;
+    }
+
+    public Set entrySet() {
+        Set entries = new HashSet();
+        for (Enumeration e = request.getAttributeNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            entries.add(new BaseMap.Entry(name, request.getAttribute(name)));
+        }
+
+        return entries;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof RequestMap)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestParameterMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestParameterMap.java
new file mode 100644
index 0000000..8fd0174
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/RequestParameterMap.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import org.apache.cocoon.environment.Request;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Request parameters map
+ *
+ * @version $Id$
+ */
+public class RequestParameterMap extends BaseMap {
+
+    private Request request;
+
+
+    public RequestParameterMap(Request request) {
+        this.request = request;
+    }
+
+    public Object get(Object key) {
+        return request.getParameter(key.toString());
+    }
+
+    public Set entrySet() {
+        Set entries = new HashSet();
+        for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            entries.add(new BaseMap.Entry(name, request.getParameter(name)));
+        }
+
+        return entries;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof RequestParameterMap)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/SessionMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/SessionMap.java
new file mode 100644
index 0000000..9d8eebc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/impl/SessionMap.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.impl;
+
+import org.apache.cocoon.environment.Session;
+
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Session attributes map
+ *
+ * @version $Id$
+ */
+public class SessionMap extends BaseMap {
+
+    private Session session;
+
+
+    public SessionMap(Session session) {
+        this.session = session;
+    }
+
+    public Object get(Object key) {
+        return session.getAttribute(key.toString());
+    }
+
+    public Object put(Object key, Object value) {
+        String sKey = key.toString();
+        Object old = session.getAttribute(sKey);
+        session.setAttribute(sKey, value);
+        return old;
+    }
+
+    public Object remove(Object key) {
+        String sKey = key.toString();
+        Object old = session.getAttribute(sKey);
+        session.removeAttribute(sKey);
+        return old;
+    }
+
+    public Set entrySet() {
+        Set entries = new HashSet();
+        for (Enumeration e = session.getAttributeNames(); e.hasMoreElements();) {
+            String name = (String) e.nextElement();
+            entries.add(new BaseMap.Entry(name, session.getAttribute(name)));
+        }
+
+        return entries;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof SessionMap)) {
+            return false;
+        }
+
+        return super.equals(obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelper.java
new file mode 100644
index 0000000..04a5766
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelper.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.excalibur.source.Source;
+
+/**
+ * Helper class for maintaining the environment stack.
+ *
+ * This is an internal class, and it might change in an incompatible way over time.
+ * For developing your own components/applications based on Cocoon, you shouldn't
+ * really need it.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class EnvironmentHelper
+extends AbstractLogEnabled
+implements SourceResolver, Serviceable, Disposable {
+
+    /** The environment information */
+    static protected final ThreadLocal environmentStack = new ThreadLocal();
+
+    /** The real source resolver */
+    protected org.apache.excalibur.source.SourceResolver resolver;
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    /** The complete prefix */
+    protected String prefix;
+
+     /** The Context path */
+    protected String context;
+
+    /** The last prefix, which is stripped off from the request uri */
+    protected String lastPrefix;
+
+    /**
+     * Constructor
+     *
+     */
+    public EnvironmentHelper(URL context) {
+        if ( context != null ) {
+            this.context = context.toExternalForm();
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     */
+    public EnvironmentHelper(EnvironmentHelper parent) {
+        this.context = parent.context;
+        this.lastPrefix = parent.lastPrefix;
+        this.prefix = parent.prefix;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (org.apache.excalibur.source.SourceResolver)
+                          this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
+        Source source = null;
+        try {
+            source = this.resolver.resolveURI(this.context);
+            this.context = source.getURI();
+
+        } catch (IOException ioe) {
+            throw new ServiceException("EnvironmentHelper", "Unable to resolve environment context. ", ioe);
+        } finally {
+            this.resolver.release(source);
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release( this.resolver );
+            this.resolver = null;
+            this.manager = null;
+        }
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#release(org.apache.excalibur.source.Source)
+     */
+    public void release(Source source) {
+        this.resolver.release(source);
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String, java.lang.String, java.util.Map)
+     */
+    public Source resolveURI(final String location,
+                             String baseURI,
+                             final Map    parameters)
+    throws MalformedURLException, IOException {
+        return this.resolver.resolveURI(location,
+                                        (baseURI == null ? this.context : baseURI),
+                                        parameters);
+    }
+
+    /**
+     * @see org.apache.excalibur.source.SourceResolver#resolveURI(java.lang.String)
+     */
+    public Source resolveURI(final String location)
+    throws MalformedURLException, IOException {
+        return this.resolveURI(location, null, null);
+    }
+
+    /**
+     * Return the current context URI
+     */
+    public String getContext() {
+        return this.context;
+    }
+
+    /**
+     * Return the prefix
+     */
+    public String getPrefix() {
+        return this.prefix;
+    }
+
+    /**
+     * Change the context of the environment.
+     * @param env The environment to change
+     * @throws ProcessingException
+     */
+    public void changeContext(Environment env)
+    throws ProcessingException {
+        if ( this.lastPrefix != null ) {
+            final String uris = env.getURI();
+            if (!uris.startsWith(this.lastPrefix)) {
+                final String message = "The current URI (" + uris +
+                                 ") doesn't start with given prefix (" + this.lastPrefix + ")";
+                throw new ProcessingException(message);
+            }
+            // we don't need to check for slash at the beginning
+            // of uris - the prefix always ends with a slash!
+            final int l = this.lastPrefix.length();
+            env.setURI(this.prefix, uris.substring(l));
+        }
+    }
+
+    /**
+     * Adds an prefix to the overall stripped off prefix from the request uri
+     */
+    public void changeContext(Source newSource, String newPrefix)
+    throws IOException {
+        final String newContext = newSource.getURI();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Changing Cocoon context");
+            getLogger().debug("  from context(" + this.context + ") and prefix(" + this.prefix + ")");
+            getLogger().debug("  to context(" + newContext + ") and prefix(" + newPrefix + ")");
+        }
+        int l = newPrefix.length();
+        if (l >= 1) {
+            this.lastPrefix = newPrefix;
+            if ( this.prefix == null ) {
+                this.prefix = "";
+            }
+            final StringBuffer buffer = new StringBuffer(this.prefix);
+            buffer.append(newPrefix);
+            // check for a slash at the beginning to avoid problems with subsitemaps
+            if ( buffer.charAt(buffer.length()-1) != '/') {
+                buffer.append('/');
+                this.lastPrefix = this.lastPrefix + '/';
+            }
+            this.prefix = buffer.toString();
+        } else {
+            this.lastPrefix = null;
+        }
+
+        if (SourceUtil.getScheme(this.context).equals("zip")) {
+            // if the resource is zipped into a war file (e.g. Weblogic temp deployment)
+            // FIXME (VG): Is this still required? Better to unify both cases.
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Base context is zip: " + this.context);
+            }
+
+            org.apache.excalibur.source.Source source = null;
+            try {
+                source = this.resolver.resolveURI(this.context + newContext);
+                this.context = source.getURI();
+            } finally {
+                this.resolver.release(source);
+            }
+        } else {
+            String sContext;
+            // if we got a absolute context or one with a protocol resolve it
+            if (newContext.charAt(0) == '/') {
+                // context starts with the '/' - absolute file URL
+                sContext = "file:" + newContext;
+            } else if (newContext.indexOf(':') > 1) {
+                // context have ':' - absolute URL
+                sContext = newContext;
+            } else {
+                // context is relative to old one
+                sContext = this.context + '/' + newContext;
+            }
+
+            // Cut the file name part from context (if present)
+            int i = sContext.lastIndexOf('/');
+            if (i != -1 && i + 1 < sContext.length()) {
+                sContext = sContext.substring(0, i + 1);
+            }
+
+            Source source = null;
+            try {
+                source = this.resolver.resolveURI(sContext);
+                this.context = source.getURI();
+            } finally {
+                this.resolver.release(source);
+            }
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("New context is " + this.context);
+        }
+    }
+
+    /**
+     * This hook must be called by the sitemap each time a sitemap is entered.
+     *
+     * <p>This method should never raise an exception, except when the
+     * parameters are not set!</p>
+     *
+     * @throws ProcessingException if processor is null
+     */
+    public static void enterProcessor(Processor processor,
+                                      ServiceManager manager,
+                                      Environment env)
+    throws ProcessingException {
+        if (null == processor) {
+            throw new ProcessingException("Processor is not set.");
+        }
+
+        EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        if (stack == null) {
+            stack = new EnvironmentStack();
+            environmentStack.set(stack);
+        }
+        stack.pushInfo(new EnvironmentInfo(processor, stack.getOffset(), manager, env));
+        stack.setOffset(stack.size() - 1);
+    }
+
+    /**
+     * This hook must be called by the sitemap each time a sitemap is left.
+     *
+     * <p>It's the counterpart to the {@link #enterProcessor(Processor, ServiceManager, Environment)}
+     * method.</p>
+     */
+    public static void leaveProcessor() {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        final EnvironmentInfo info = (EnvironmentInfo)stack.pop();
+        stack.setOffset(info.oldStackCount);
+    }
+
+    /**
+     * This method is used for entering a new environment.
+     *
+     * @throws ProcessingException if there is no current processing environment
+     */
+    public static void enterEnvironment(Environment env)
+    throws ProcessingException {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        EnvironmentInfo info = null;
+        if ( stack != null && !stack.isEmpty()) {
+            info = stack.getCurrentInfo();
+        } else {
+            throw new ProcessingException("There must be a current processing environment.");
+        }
+
+        stack.pushInfo(new EnvironmentInfo(info.processor, stack.getOffset(), info.manager, env));
+        stack.setOffset(stack.size() - 1);
+    }
+
+    /**
+     * This method is used for leaving the current environment.
+     * 
+     * <p>It's the counterpart to the {@link #enterEnvironment(Environment)} method.</p>
+     */
+    public static Environment leaveEnvironment() {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        final EnvironmentInfo info = (EnvironmentInfo)stack.pop();
+        stack.setOffset(info.oldStackCount);
+
+        return info.environment;
+    }
+
+    /**
+     * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
+     */
+    public static int markEnvironment() {
+        // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        if (stack != null) {
+            return stack.size();
+        }
+
+        return 0;
+    }
+
+    /**
+     * INTERNAL METHOD. Do not use, can be removed without warning or deprecation cycle.
+     */
+    public static void checkEnvironment(int depth, Logger logger)
+    throws Exception {
+        // TODO (CZ): This is only for testing - remove it later on. See also Cocoon.java.
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        int currentDepth = stack != null? stack.size() : 0;
+        if (currentDepth != depth) {
+            logger.error("ENVIRONMENT STACK HAS NOT BEEN CLEANED PROPERLY!");
+            throw new ProcessingException("Environment stack has not been cleaned up properly. " +
+                                          "Please report this (and if possible, together with a test case) " +
+                                          "to the Cocoon developers.");
+        }
+    }
+
+    /**
+     * Return the environment
+     */
+    public static Environment getCurrentEnvironment() {
+        final EnvironmentStack stack = (EnvironmentStack) environmentStack.get();
+        if ( stack != null && !stack.empty() ) {
+            final EnvironmentInfo info = stack.getCurrentInfo();
+            return info.environment;
+        }
+        return null;
+    }
+
+    /**
+     * Return the current processor
+     */
+    public static Processor getCurrentProcessor() {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        if ( stack != null && !stack.isEmpty()) {
+            final EnvironmentInfo info = stack.getCurrentInfo();
+            return info.processor;
+        }
+        return null;
+    }
+
+    /**
+     * Get the current sitemap component manager.
+     * This method return the current sitemap component manager. This
+     * is the manager that holds all the components of the currently
+     * processed (sub)sitemap.
+     */
+    static public ServiceManager getSitemapServiceManager() {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        if ( stack != null && !stack.isEmpty()) {
+            final EnvironmentInfo info = stack.getCurrentInfo();
+            return info.manager;
+        }
+        return null;
+    }
+
+    /**
+     * Create an environment aware xml consumer for the cocoon
+     * protocol
+     */
+    public static XMLConsumer createEnvironmentAwareConsumer(XMLConsumer consumer) {
+        final EnvironmentStack stack = (EnvironmentStack)environmentStack.get();
+        final EnvironmentInfo info = stack.getCurrentInfo();
+        return stack.getEnvironmentAwareConsumerWrapper(consumer, info.oldStackCount);
+    }
+
+    /**
+     * Create an environment aware xml consumer that push an
+     * environment before calling the consumer.
+     */
+    public static XMLConsumer createPushEnvironmentConsumer(XMLConsumer consumer, Environment environment) {
+        return new PushEnvironmentChanger(consumer, environment);
+    }
+
+    /**
+     * Create an environment aware xml consumer that pop and save the
+     * current environment before calling the consumer.
+     */
+    public static XMLConsumer createPopEnvironmentConsumer(XMLConsumer consumer) {
+        return new PopEnvironmentChanger(consumer);
+    }
+
+    /**
+     * A runnable wrapper that inherits the environment stack of the thread it is
+     * created in.
+     * <p>
+     * It's defined as an abstract class here to use some internals of EnvironmentHelper, and
+     * should only be used through its public counterpart, {@link org.apache.cocoon.environment.CocoonRunnable}
+     */
+    public static abstract class AbstractCocoonRunnable implements Runnable {
+        private Object parentStack = null;
+
+        public AbstractCocoonRunnable() {
+            // Clone the environment stack of the calling thread.
+            // We'll use it in run() below
+            Object stack = EnvironmentHelper.environmentStack.get();
+            if (stack != null) {
+                this.parentStack = ((EnvironmentStack)stack).clone();
+            }
+        }
+
+        /**
+         * Calls {@link #doRun()} within the environment context of the creating thread.
+         */
+        public final void run() {
+            // Install the stack from the parent thread and run the Runnable
+            Object oldStack = environmentStack.get();
+            EnvironmentHelper.environmentStack.set(this.parentStack);
+            try {
+                doRun();
+            } finally {
+                // Restore the previous stack
+                EnvironmentHelper.environmentStack.set(oldStack);
+            }
+            // FIXME: Check the lifetime of this run compared to the parent thread.
+            // A CocoonThread is meant to start and die within the execution period of the parent request,
+            // and it is an error if it lives longer as the parent environment is no more valid.
+        }
+
+        abstract protected void doRun();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelperException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelperException.java
new file mode 100644
index 0000000..2c859e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentHelperException.java
@@ -0,0 +1,33 @@
+/*

+ * Copyright 1999-2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.environment.internal;

+

+import org.apache.avalon.framework.CascadingRuntimeException;

+

+/**

+ * @version $Id$

+ * @since 2.2

+ */

+public class EnvironmentHelperException extends CascadingRuntimeException {

+

+    public EnvironmentHelperException(String message) {

+        super(message, null);

+    }

+

+    public EnvironmentHelperException(String message, Throwable cause) {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentInfo.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentInfo.java
new file mode 100644
index 0000000..ed811c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentInfo.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * This object holds a set of objects for an environment.
+ *
+ * This is an internal class, and it might change in an incompatible way over time.
+ * For developing your own components/applications based on Cocoon, you shouldn't 
+ * really need it.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public class EnvironmentInfo {
+
+    public final Processor      processor;
+    public final int            oldStackCount;
+    public final ServiceManager manager;
+    public final Environment    environment;
+
+    public EnvironmentInfo(Processor processor, 
+                           int oldStackCount,
+                           ServiceManager manager,
+                           Environment    environment) {
+        this.processor = processor;
+        this.oldStackCount = oldStackCount;
+        this.manager = manager;
+        this.environment = environment;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentStack.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentStack.java
new file mode 100644
index 0000000..3daadb2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/EnvironmentStack.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.commons.collections.ArrayStack;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * The stack for the processing environment.
+ *
+ * This is an internal class, and it might change in an incompatible way over time.
+ * For developing your own components/applications based on Cocoon, you shouldn't 
+ * really need it.
+ * This is a special implementation of a stack for the handling of the
+ * cocoon protocol and the sitemap source resolving.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+final class EnvironmentStack 
+    extends ArrayStack 
+    implements Cloneable {
+
+    int offset;
+
+    EnvironmentInfo getCurrentInfo() {
+        return (EnvironmentInfo)this.get(offset);
+    }
+
+    void pushInfo(EnvironmentInfo info) {
+        this.push(info);
+    }
+
+    EnvironmentInfo popInfo() {
+        return (EnvironmentInfo)this.pop();
+    }
+
+    EnvironmentInfo peekInfo() {
+        return (EnvironmentInfo)this.peek();
+    }
+
+    int getOffset() {
+        return this.offset;
+    }
+
+    void setOffset(int value) {
+        this.offset = value;  
+    }
+
+    public Object clone() {
+        EnvironmentStack old = (EnvironmentStack) super.clone();
+        old.offset = offset;
+        return old;
+    }
+
+    XMLConsumer getEnvironmentAwareConsumerWrapper(XMLConsumer consumer, 
+                                                   int oldOffset) {
+        return new EnvironmentChanger(consumer, this, oldOffset, this.offset);
+    }
+}
+
+/**
+ * This class is an {@link XMLConsumer} that changes the current environment.
+ * When a pipeline calls an internal pipeline, two environments are
+ * established: one for the calling pipeline and one for the internal pipeline.
+ * Now, if SAX events are send from the internal pipeline, they are
+ * received by some component of the calling pipeline, so inbetween we
+ * have to change the environment forth and back.
+ */
+final class EnvironmentChanger
+implements XMLConsumer {
+
+    final XMLConsumer consumer;
+    final EnvironmentStack stack;
+    final int oldOffset;
+    final int newOffset;
+
+    EnvironmentChanger(XMLConsumer consumer, EnvironmentStack es,
+                       int oldOffset, int newOffset) {
+        this.consumer = consumer;
+        this.stack = es;
+        this.oldOffset = oldOffset;
+        this.newOffset = newOffset;
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.setDocumentLocator(locator);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startDocument()
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startDocument();
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endDocument()
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endDocument();
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startPrefixMapping(prefix, uri);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endPrefixMapping(prefix);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startElement(uri, loc, raw, a);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endElement(uri, loc, raw);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.characters(c, start, len);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.ignorableWhitespace(c, start, len);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.processingInstruction(target, data);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void skippedEntity(String name)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.skippedEntity(name);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startDTD(name, publicId, systemId);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endDTD()
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endDTD();
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startEntity(String name)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startEntity(name);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endEntity(String name)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endEntity(name);
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void startCDATA()
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.startCDATA();
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void endCDATA()
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.endCDATA();
+        this.stack.setOffset(this.newOffset);
+    }
+
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        this.stack.setOffset(this.oldOffset);
+        this.consumer.comment(ch, start, len);
+        this.stack.setOffset(this.newOffset);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/ForwardEnvironmentWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/ForwardEnvironmentWrapper.java
new file mode 100644
index 0000000..5c2c5e5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/ForwardEnvironmentWrapper.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.source.impl.SitemapSourceInfo;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.wrapper.EnvironmentWrapper;
+
+/**
+ * Local extension of EnvironmentWrapper to propagate otherwise blocked
+ * methods to the actual environment.
+ * 
+ * @version $Id$
+ * @since 2.2
+ */
+public final class ForwardEnvironmentWrapper extends EnvironmentWrapper {
+
+    public ForwardEnvironmentWrapper(Environment env,
+                                     SitemapSourceInfo info, 
+                                     Logger logger) {
+        super(env, info, logger, false);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#setStatus(int)
+     */
+    public void setStatus(int statusCode) {
+        environment.setStatus(statusCode);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#setContentLength(int)
+     */
+    public void setContentLength(int length) {
+        environment.setContentLength(length);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#setContentType(java.lang.String)
+     */
+    public void setContentType(String contentType) {
+        environment.setContentType(contentType);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#getContentType()
+     */
+    public String getContentType() {
+        return environment.getContentType();
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#isResponseModified(long)
+     */
+    public boolean isResponseModified(long lastModified) {
+        return environment.isResponseModified(lastModified);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Environment#setResponseIsNotModified()
+     */
+    public void setResponseIsNotModified() {
+        environment.setResponseIsNotModified();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#redirect(java.lang.String, boolean, boolean)
+    public void redirect(String newURL, boolean global, boolean permanent)
+    throws IOException {
+        this.environment.redirect(newURL, global, permanent);
+    }
+     */
+
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PopEnvironmentChanger.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PopEnvironmentChanger.java
new file mode 100644
index 0000000..b0b04bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PopEnvironmentChanger.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * This is an internal class, and it might change in an incompatible way over time.
+ * For developing your own components/applications based on Cocoon, you shouldn't 
+ * really need it.
+ *
+ * This class is an {@link XMLConsumer} that changes the current environment.
+ * When a pipeline calls an internal pipeline, two environments are
+ * established: one for the calling pipeline and one for the internal pipeline.
+ * Now, if SAX events are send from the internal pipeline, they are
+ * received by some component of the calling pipeline, so inbetween we
+ * have to change the environment forth and back.
+ *
+ * This environment changer pop the current environment from the
+ * environment stack before calling the embeded consumer and push it
+ * back afterwards. It should be placed after a sitemap component that
+ * is be executed in another environment.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+final class PopEnvironmentChanger
+    implements XMLConsumer {
+
+    final XMLConsumer consumer;
+
+    PopEnvironmentChanger(XMLConsumer consumer) {
+        this.consumer = consumer;
+    }
+
+    private Environment leaveEnvironment() {
+        return EnvironmentHelper.leaveEnvironment();
+    }
+
+    private void enterEnvironment(Environment environment) throws SAXException {
+        try {
+            EnvironmentHelper.enterEnvironment(environment);
+        } catch (ProcessingException e) {
+            throw new SAXException("Unable to enter the environment: " + environment, e);
+        }
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        Environment environment = leaveEnvironment();
+        this.consumer.setDocumentLocator(locator);
+        try {
+            enterEnvironment(environment);
+        } catch (SAXException e) {
+            throw new UnableToPopEnvironmentException("Unable to re-enter the environment: " + environment, e);
+        }
+    }
+
+    public void startDocument()
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startDocument();
+        enterEnvironment(environment);
+    }
+
+    public void endDocument()
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endDocument();
+        enterEnvironment(environment);
+    }
+
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startPrefixMapping(prefix, uri);
+        enterEnvironment(environment);
+    }
+
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endPrefixMapping(prefix);
+        enterEnvironment(environment);
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startElement(uri, loc, raw, a);
+        enterEnvironment(environment);
+    }
+
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endElement(uri, loc, raw);
+        enterEnvironment(environment);
+    }
+
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.characters(c, start, len);
+        enterEnvironment(environment);
+    }
+
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.ignorableWhitespace(c, start, len);
+        enterEnvironment(environment);
+    }
+
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.processingInstruction(target, data);
+        enterEnvironment(environment);
+    }
+
+    public void skippedEntity(String name)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.skippedEntity(name);
+        enterEnvironment(environment);
+    }
+
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startDTD(name, publicId, systemId);
+        enterEnvironment(environment);
+    }
+
+    public void endDTD()
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endDTD();
+        enterEnvironment(environment);
+    }
+
+    public void startEntity(String name)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startEntity(name);
+        enterEnvironment(environment);
+    }
+
+    public void endEntity(String name)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endEntity(name);
+        enterEnvironment(environment);
+    }
+
+    public void startCDATA()
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.startCDATA();
+        enterEnvironment(environment);
+    }
+
+    public void endCDATA()
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.endCDATA();
+        enterEnvironment(environment);
+    }
+
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        Environment environment = leaveEnvironment();
+        this.consumer.comment(ch, start, len);
+        enterEnvironment(environment);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PushEnvironmentChanger.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PushEnvironmentChanger.java
new file mode 100644
index 0000000..bb7d449
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/PushEnvironmentChanger.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.internal;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * This is an internal class, and it might change in an incompatible way over time.
+ * For developing your own components/applications based on Cocoon, you shouldn't 
+ * really need it.
+ *
+ * This class is an {@link XMLConsumer} that changes the current environment.
+ * When a pipeline calls an internal pipeline, two environments are
+ * established: one for the calling pipeline and one for the internal pipeline.
+ * Now, if SAX events are send from the internal pipeline, they are
+ * received by some component of the calling pipeline, so inbetween we
+ * have to change the environment forth and back.
+ *
+ * This environment changer push a given environment on the
+ * environment stack before calling the embeded consumer and pops it
+ * afterwards. It should be placed before a sitemap component that
+ * should be executed in another environment.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+final class PushEnvironmentChanger
+    implements XMLConsumer {
+
+    final XMLConsumer consumer;
+    final Environment environment;
+
+    PushEnvironmentChanger(XMLConsumer consumer, Environment environment) {
+        this.consumer = consumer;
+        this.environment = environment;
+    }
+
+    private void enterEnvironment() throws SAXException {
+        try {
+            EnvironmentHelper.enterEnvironment(this.environment);
+        } catch (ProcessingException e) {
+            throw new SAXException("PushEnvironmentChanger: ", e);
+        }
+    }
+
+    private void leaveEnvironment() {
+        EnvironmentHelper.leaveEnvironment();
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        try {
+            enterEnvironment();
+        } catch (SAXException e) {
+            throw new UnableToPushEnvironmentException("Unable to push the environment", e);
+        }
+        this.consumer.setDocumentLocator(locator);
+        leaveEnvironment();
+    }
+
+    public void startDocument()
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startDocument();
+        leaveEnvironment();
+    }
+
+    public void endDocument()
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endDocument();
+        leaveEnvironment();
+    }
+
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startPrefixMapping(prefix, uri);
+        leaveEnvironment();
+    }
+
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endPrefixMapping(prefix);
+        leaveEnvironment();
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startElement(uri, loc, raw, a);
+        leaveEnvironment();
+    }
+
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endElement(uri, loc, raw);
+        leaveEnvironment();
+    }
+
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.characters(c, start, len);
+        leaveEnvironment();
+    }
+
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.ignorableWhitespace(c, start, len);
+        leaveEnvironment();
+    }
+
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.processingInstruction(target, data);
+        leaveEnvironment();
+    }
+
+    public void skippedEntity(String name)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.skippedEntity(name);
+        leaveEnvironment();
+    }
+
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startDTD(name, publicId, systemId);
+        leaveEnvironment();
+    }
+
+    public void endDTD()
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endDTD();
+        leaveEnvironment();
+    }
+
+    public void startEntity(String name)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startEntity(name);
+        leaveEnvironment();
+    }
+
+    public void endEntity(String name)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endEntity(name);
+        leaveEnvironment();
+    }
+
+    public void startCDATA()
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.startCDATA();
+        leaveEnvironment();
+    }
+
+    public void endCDATA()
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.endCDATA();
+        leaveEnvironment();
+    }
+
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        enterEnvironment();
+        this.consumer.comment(ch, start, len);
+        leaveEnvironment();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPopEnvironmentException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPopEnvironmentException.java
new file mode 100644
index 0000000..6c81049
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPopEnvironmentException.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright 2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.environment.internal;

+

+/**

+ * @version $Id$

+ * @since 2.2

+ */

+public final class UnableToPopEnvironmentException extends EnvironmentHelperException {

+

+    public UnableToPopEnvironmentException(String message) {

+        super(message, null);

+    }

+

+    public UnableToPopEnvironmentException(String message, Throwable cause) {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPushEnvironmentException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPushEnvironmentException.java
new file mode 100644
index 0000000..de21211
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/internal/UnableToPushEnvironmentException.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright 2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.environment.internal;

+

+/**

+ * @version $Id$

+ * @since 2.2

+ */

+public final class UnableToPushEnvironmentException extends EnvironmentHelperException {

+

+    public UnableToPushEnvironmentException(String message) {

+        super(message, null);

+    }

+

+    public UnableToPushEnvironmentException(String message, Throwable cause) {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/AbstractRequestWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/AbstractRequestWrapper.java
new file mode 100644
index 0000000..d8dd871
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/AbstractRequestWrapper.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.impl.AbstractRequest;
+
+
+/**
+ * This is a wrapper class for the <code>Request</code> object. It
+ * just forwards every methods. It is the base class for all wrapper
+ * implementations.
+ *
+ * @version $Id$
+ * @since 2.2
+ */
+public abstract class AbstractRequestWrapper extends AbstractRequest {
+
+    /** The real {@link Request} object */
+    protected final Request req;
+
+    /**
+     * Constructor
+     */
+    public AbstractRequestWrapper(Request request) {
+        this.req = request;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#get(java.lang.String)
+     */
+    public Object get(String name) {
+        return this.req.get(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.req.getAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.req.getAttributeNames();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getCharacterEncoding()
+     */
+    public String getCharacterEncoding() {
+        return this.req.getCharacterEncoding();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setCharacterEncoding(java.lang.String)
+     */
+    public void setCharacterEncoding(String enc)
+    throws java.io.UnsupportedEncodingException {
+        this.req.setCharacterEncoding(enc);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getContentLength()
+     */
+    public int getContentLength() {
+        return this.req.getContentLength();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getContentType()
+     */
+    public String getContentType() {
+        return this.req.getContentType();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameter(java.lang.String)
+     */
+    public String getParameter(String name) {
+        return this.req.getParameter(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameterNames()
+     */
+    public Enumeration getParameterNames() {
+        return this.req.getParameterNames();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameterValues(java.lang.String)
+     */
+    public String[] getParameterValues(String name) {
+        return this.req.getParameterValues(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getProtocol()
+     */
+    public String getProtocol() {
+        return this.req.getProtocol();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getScheme()
+     */
+    public String getScheme() {
+        return this.req.getScheme();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getServerName()
+     */
+    public String getServerName() {
+        return this.req.getServerName();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getServerPort()
+     */
+    public int getServerPort() {
+        return this.req.getServerPort();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRemoteAddr()
+     */
+    public String getRemoteAddr() {
+        return this.req.getRemoteAddr();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRemoteHost()
+     */
+    public String getRemoteHost() {
+        return this.req.getRemoteHost();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object o) {
+        this.req.setAttribute(name, o);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.req.removeAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getLocale()
+     */
+    public Locale getLocale() {
+        return this.req.getLocale();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getLocales()
+     */
+    public Enumeration getLocales() {
+        return this.req.getLocales();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#isSecure()
+     */
+    public boolean isSecure() {
+        return this.req.isSecure();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getCookies()
+     */
+    public Cookie[] getCookies() {
+        return this.req.getCookies();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getCookieMap()
+     */
+    public Map getCookieMap() {
+        return this.req.getCookieMap();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getDateHeader(java.lang.String)
+     */
+    public long getDateHeader(String name) {
+        return this.req.getDateHeader(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getHeader(java.lang.String)
+     */
+    public String getHeader(String name) {
+        return this.req.getHeader(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getHeaders(java.lang.String)
+     */
+    public Enumeration getHeaders(String name) {
+        return this.req.getHeaders(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getHeaderNames()
+     */
+    public Enumeration getHeaderNames() {
+        return this.req.getHeaderNames();
+    }
+
+	/* (non-Javadoc)
+	 * @see org.apache.cocoon.environment.Request#getInputStream()
+	 */
+	public InputStream getInputStream() throws IOException, UnsupportedOperationException {
+		return this.req.getInputStream();
+	}
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getMethod()
+     */
+    public String getMethod() {
+        return this.req.getMethod();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getPathInfo()
+     */
+    public String getPathInfo() {
+        return this.req.getPathInfo();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getPathTranslated()
+     */
+    public String getPathTranslated() {
+        return this.req.getPathTranslated();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getContextPath()
+     */
+    public String getContextPath() {
+        return this.req.getContextPath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getQueryString()
+     */
+    public String getQueryString() {
+        return this.req.getQueryString();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRemoteUser()
+     */
+    public String getRemoteUser() {
+        return this.req.getRemoteUser();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRequestedSessionId()
+     */
+    public String getRequestedSessionId() {
+        return this.req.getRequestedSessionId();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRequestURI()
+     */
+    public String getRequestURI() {
+        return this.req.getRequestURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapURI()
+     */
+    public String getSitemapURI() {
+        return this.req.getSitemapURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapPath()
+     */
+    public String getSitemapPath() {
+        return this.req.getSitemapPath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getServletPath()
+     */
+    public String getServletPath() {
+        return this.req.getServletPath();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSession(boolean)
+     */
+    public Session getSession(boolean create) {
+        return this.req.getSession(create);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSession()
+     */
+    public Session getSession() {
+        return this.req.getSession();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#isRequestedSessionIdValid()
+     */
+    public boolean isRequestedSessionIdValid() {
+        return this.req.isRequestedSessionIdValid();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#isRequestedSessionIdFromCookie()
+     */
+    public boolean isRequestedSessionIdFromCookie()  {
+        return this.req.isRequestedSessionIdFromCookie();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#isRequestedSessionIdFromURL()
+     */
+    public boolean isRequestedSessionIdFromURL() {
+        return this.req.isRequestedSessionIdFromURL();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getUserPrincipal()
+     */
+    public Principal getUserPrincipal() {
+        return this.req.getUserPrincipal();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#isUserInRole(java.lang.String)
+     */
+    public boolean isUserInRole(String role) {
+        return this.req.isUserInRole(role);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAuthType()
+     */
+    public String getAuthType() {
+        return this.req.getAuthType();
+    }       
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        return this.req.getAttribute(name, scope);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        return this.req.getAttributeNames(scope);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        this.req.removeAttribute(name,scope);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object o, int scope) {
+        this.req.setAttribute(name, o, scope);
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Request#getSitemapURIPrefix()
+     */
+    public String getSitemapURIPrefix() {
+        return this.req.getSitemapURIPrefix();
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Request#searchAttribute(java.lang.String)
+     */
+    public Object searchAttribute(String name) {
+        return this.req.searchAttribute(name);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java
new file mode 100644
index 0000000..2a3ec9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/EnvironmentWrapper.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.source.impl.SitemapSourceInfo;
+import org.apache.cocoon.environment.AbstractEnvironment;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.util.BufferedOutputStream;
+
+
+/**
+ * This is a wrapper class for the <code>Environment</code> object.
+ * It has the same properties except that the object model
+ * contains a <code>RequestWrapper</code> object.
+ *
+ * @version $Id$
+ */
+public class EnvironmentWrapper 
+    extends AbstractEnvironment {
+
+    /** The wrapped environment */
+    protected final Environment environment;
+
+    /** The redirect url */
+    protected String redirectURL;
+
+    /** The request object */
+    protected final Request request;
+
+    /** The stream to output to */
+    protected OutputStream outputStream;
+    
+    protected String contentType;
+
+    protected boolean internalRedirect = false;
+    
+    /**
+     * Construct a new environment.
+     * 
+     * @param env    The origial Environment
+     * @param info   A description of the uri for the new environment
+     * @param logger The logger to be used by this environment
+     */
+    public EnvironmentWrapper(Environment       env,
+                              SitemapSourceInfo info,
+                              Logger            logger) {
+        this(env, info, logger, true);
+    }
+
+    /**
+     * Construct a new environment.
+     * 
+     * @param env    The origial Environment
+     * @param info   A description of the uri for the new environment
+     * @param logger The logger to be used by this environment
+     * @param wrapResponse  Whether or not to wrap the Response object
+     */
+    public EnvironmentWrapper(Environment       env,
+                              SitemapSourceInfo info,
+                              Logger            logger,
+                              boolean           wrapResponse) {
+        super(env.getURI(), info.view, env.getAction());
+        
+        this.enableLogging(logger);
+        this.environment = env;
+
+        // create new object model and replace the request object
+        Map oldObjectModel = env.getObjectModel();
+        if (oldObjectModel instanceof HashMap) {
+            this.objectModel = (Map)((HashMap)oldObjectModel).clone();
+        } else {
+            this.objectModel = new HashMap(oldObjectModel.size()*2);
+            Iterator entries = oldObjectModel.entrySet().iterator();
+            Map.Entry entry;
+            while (entries.hasNext()) {
+                entry = (Map.Entry)entries.next();
+                this.objectModel.put(entry.getKey(), entry.getValue());
+            }
+        }
+        this.request = new RequestWrapper(ObjectModelHelper.getRequest(oldObjectModel),
+                                          info.requestURI,
+                                          info.queryString,
+                                          this,
+                                          info.rawMode);
+
+        this.objectModel.put(ObjectModelHelper.REQUEST_OBJECT, this.request);
+        if (wrapResponse) {
+            Response response = new ResponseWrapper(ObjectModelHelper.getResponse(oldObjectModel));
+            this.objectModel.put(ObjectModelHelper.RESPONSE_OBJECT, response);
+        }
+
+        this.setURI(info.prefix, info.uri);        
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#redirect(java.lang.String, boolean, boolean)
+     */
+    public void redirect(String newURL, boolean global, boolean permanent)
+    throws IOException {
+        if ( !global && !this.internalRedirect ) {
+            this.redirectURL = newURL;
+        } else {
+            this.environment.redirect(newURL, global, permanent);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getOutputStream(int)
+     */
+    public OutputStream getOutputStream(int bufferSize)
+    throws IOException {
+        return this.outputStream == null
+                ? this.environment.getOutputStream(bufferSize)
+                : this.outputStream;
+    }
+
+    /**
+     * Set the output stream for this environment. It hides the one of the
+     * wrapped environment.
+     */
+    public void setOutputStream(OutputStream stream) {
+        this.outputStream = stream;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#tryResetResponse()
+     */
+    public boolean tryResetResponse()
+    throws IOException {
+        final OutputStream os = this.getOutputStream(-1);
+        if (os != null
+            && os instanceof BufferedOutputStream) {
+            ((BufferedOutputStream)os).clearBuffer();
+            return true;
+        }
+        return super.tryResetResponse();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#commitResponse()
+     */
+    public void commitResponse() 
+    throws IOException {
+        final OutputStream os = this.getOutputStream(-1);
+        if (os != null
+            && os instanceof BufferedOutputStream) {
+            ((BufferedOutputStream)os).realFlush();
+        } else {
+            super.commitResponse();
+        }
+    }
+
+    /**
+     * if a redirect should happen this returns the url,
+     * otherwise <code>null</code> is returned
+     */
+    public String getRedirectURL() {
+        return this.redirectURL;
+    }
+    
+    public void reset() {
+        this.redirectURL = null;
+    }
+
+    /**
+     * Set the StatusCode
+     */
+    public void setStatus(int statusCode) {
+        // ignore this
+    }
+
+    public void setContentLength(int length) {
+        // ignore this
+    }
+
+    /**
+     * Set the ContentType
+     */
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    /**
+     * Get the ContentType
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+
+    /**
+     * Lookup an attribute in this instance, and if not found search it
+     * in the wrapped environment.
+     *
+     * @param name a <code>String</code>, the name of the attribute to
+     * look for
+     * @return an <code>Object</code>, the value of the attribute or
+     * null if no such attribute was found.
+     */
+    public Object getAttribute(String name) {
+        Object value = super.getAttribute(name);
+        if (value == null)
+            value = this.environment.getAttribute(name);
+
+        return value;
+    }
+
+    /**
+     * Remove attribute from the current instance, as well as from the
+     * wrapped environment.
+     *
+     * @param name a <code>String</code> value
+     */
+    public void removeAttribute(String name) {
+        super.removeAttribute(name);
+        this.environment.removeAttribute(name);
+    }
+
+    /**
+     * Always return <code>false</code>.
+     */
+    public boolean isExternal() {
+        return false;
+    }
+
+    public void setInternalRedirect(boolean flag) {
+        this.internalRedirect = flag;
+        if ( flag ) {
+            ((RequestWrapper)this.request).setRequestURI(this.prefix, this.uri);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isInternRedirect()
+     */
+    public boolean isInternalRedirect() {
+        return this.internalRedirect;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/MutableEnvironmentFacade.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/MutableEnvironmentFacade.java
new file mode 100644
index 0000000..422a2a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/MutableEnvironmentFacade.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.apache.cocoon.components.treeprocessor.sitemap.MountNode;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Enviroment facade, whose delegate object can be changed. This class is
+ * required to handle internal redirects in sitemap sources ("cocoon:").
+ * This is because {@link org.apache.cocoon.components.source.impl.SitemapSource}
+ * keeps the environment in which the internal request should be processed.
+ * But internal redirects create a new processing environment and there's
+ * no way to change the one held by the <code>SitemapSource</code>. So the
+ * processing of internal redirects actually changes the delegate of this
+ * class, transparently for the <code>SitemapSource</code>.
+ *
+ * @see org.apache.cocoon.components.source.impl.SitemapSource
+ *
+ * @version $Id$
+ */
+public class MutableEnvironmentFacade implements Environment {
+
+    private EnvironmentWrapper env;
+
+    public MutableEnvironmentFacade(EnvironmentWrapper env) {
+        this.env = env;
+        // Ensure we start with a false passthrough flag.
+        // FIXME: this should really be part of the Processor contract rather
+        // than an environment attribute
+        env.setAttribute(MountNode.COCOON_PASS_THROUGH, Boolean.FALSE);
+    }
+
+    public EnvironmentWrapper getDelegate() {
+        return this.env;
+    }
+
+    public void setDelegate(EnvironmentWrapper env) {
+        this.env = env;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setURI(java.lang.String, java.lang.String)
+     */
+    public void setURI(String prefix, String uri) {
+        this.env.setURI(prefix, uri);
+    }
+
+    public void setOutputStream(OutputStream os) {
+        this.env.setOutputStream(os);
+    }
+
+    // Move this to the Environment interface ?
+    public String getRedirectURL() {
+        return this.env.getRedirectURL();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURI()
+     */
+    public String getURI() {
+        return env.getURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getURIPrefix()
+     */
+    public String getURIPrefix() {
+        return env.getURIPrefix();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getView()
+     */
+    public String getView() {
+        return env.getView();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAction()
+     */
+    public String getAction() {
+        return env.getAction();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#redirect(String, boolean, boolean)
+     */
+    public void redirect(String url,
+                         boolean global,
+                         boolean permanent) throws IOException {
+        env.redirect(url, global, permanent);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setContentType(String)
+     */
+    public void setContentType(String mimeType) {
+        env.setContentType(mimeType);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getContentType()
+     */
+    public String getContentType() {
+        return env.getContentType();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setContentLength(int)
+     */
+    public void setContentLength(int length) {
+        env.setContentLength(length);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setStatus(int)
+     */
+    public void setStatus(int statusCode) {
+        env.setStatus(statusCode);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getOutputStream(int)
+     */
+    public OutputStream getOutputStream(int bufferSize) throws IOException {
+        return env.getOutputStream(bufferSize);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getObjectModel()
+     */
+    public Map getObjectModel() {
+        return env.getObjectModel();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isResponseModified(long)
+     */
+    public boolean isResponseModified(long lastModified) {
+        return env.isResponseModified(lastModified);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setResponseIsNotModified()
+     */
+    public void setResponseIsNotModified() {
+        env.setResponseIsNotModified();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#setAttribute(String, Object)
+     */
+    public void setAttribute(String name, Object value) {
+        env.setAttribute(name, value);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return env.getAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        env.removeAttribute(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return env.getAttributeNames();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#tryResetResponse()
+     */
+    public boolean tryResetResponse() throws IOException {
+        return env.tryResetResponse();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#commitResponse()
+     */
+    public void commitResponse() throws IOException {
+        env.commitResponse();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#startingProcessing()
+     */
+    public void startingProcessing() {
+        env.startingProcessing();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#finishingProcessing()
+     */
+    public void finishingProcessing() {
+        env.finishingProcessing();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isExternal()
+     */
+    public boolean isExternal() {
+        return env.isExternal();
+    }
+
+    public void reset() {
+        this.env.reset();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isInternRedirect()
+     */
+    public boolean isInternalRedirect() {
+        return env.isInternalRedirect();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestParameters.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestParameters.java
new file mode 100644
index 0000000..9f0deef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestParameters.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * This class is used by the <code>RequestWrapper</code>. It parses
+ * a query string and creates a parameter representation required
+ * for the <code>Request</code> object.
+ *
+ * @version $Id$
+ */
+public final class RequestParameters
+implements Serializable {
+
+    /** The parameter names are the keys and the value is a List object */
+    private Map names;
+
+    /**
+     * Decode the string
+     */
+    private String parseName(String s) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '+':
+                    sb.append(' ');
+                    break;
+                case '%':
+                    try {
+                        sb.append((char) Integer.parseInt(s.substring(i+1, i+3),
+                              16));
+                        i += 2;
+                    } catch (NumberFormatException e) {
+                        throw new IllegalArgumentException();
+                    } catch (StringIndexOutOfBoundsException e) {
+                        String rest  = s.substring(i);
+                        sb.append(rest);
+                        if (rest.length()==2)
+                            i++;
+                    }
+
+                    break;
+                default:
+                    sb.append(c);
+                    break;
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Construct a new object from a queryString
+     */
+    public RequestParameters(String queryString) {
+        this.names = new HashMap(5);
+        if (queryString != null) {
+            StringTokenizer st = new StringTokenizer(queryString, "&");
+            while (st.hasMoreTokens()) {
+                String pair = st.nextToken();
+                int pos = pair.indexOf('=');
+                if (pos != -1) {
+                    this.setParameter(this.parseName(pair.substring(0, pos)),
+                                      this.parseName(pair.substring(pos+1, pair.length())));
+                }
+            }
+        }
+    }
+
+    /**
+     * Add a parameter.
+     * The parameter is added with the given value.
+     * @param name   The name of the parameter.
+     * @param value  The value of the parameter.
+     */
+    private void setParameter(String name, String value) {
+        ArrayList list;
+        if (names.containsKey(name)) {
+            list = (ArrayList)names.get(name);
+        } else {
+            list = new ArrayList(3);
+            names.put(name, list);
+        }
+        list.add(value);
+    }
+
+    /**
+     * Get the value of a parameter.
+     * @param name   The name of the parameter.
+     * @return       The value of the first parameter with the name
+     *               or <CODE>null</CODE>
+     */
+    public String getParameter(String name) {
+        if (names.containsKey(name)) {
+            return (String)((ArrayList)names.get(name)).get(0);
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of a parameter.
+     * @param name   The name of the parameter.
+     * @param defaultValue The default value if the parameter does not exist.
+     * @return       The value of the first parameter with the name
+     *               or <CODE>defaultValue</CODE>
+     */
+    public String getParameter(String name, String defaultValue) {
+        if (names.containsKey(name)) {
+            return (String)((ArrayList)names.get(name)).get(0);
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Get all values of a parameter.
+     * @param name   The name of the parameter.
+     * @return       Array of the (String) values or null if the parameter
+     *               is not defined.
+     */
+    public String[] getParameterValues(String name) {
+        if (names.containsKey(name)) {
+            String values[] = null;
+            ArrayList list = (ArrayList)names.get(name);
+            Iterator iter = list.iterator();
+            while (iter.hasNext()) {
+                if (values == null) {
+                    values = new String[1];
+                } else {
+                    String[] copy = new String[values.length+1];
+                    System.arraycopy(values, 0, copy, 0, values.length);
+                    values = copy;
+                }
+                values[values.length-1] = (String)iter.next();
+            }
+            return values;
+        }
+        return null;
+    }
+
+    /**
+     * Get all parameter names.
+     * @return  Enumeration for the (String) parameter names.
+     */
+    public Enumeration getParameterNames() {
+        return new EnumerationFromIterator(names.keySet().iterator());
+    }
+
+    final class EnumerationFromIterator implements Enumeration {
+        private Iterator iter;
+        EnumerationFromIterator(Iterator iter) {
+            this.iter = iter;
+        }
+
+        public boolean hasMoreElements() {
+            return iter.hasNext();
+        }
+        public Object nextElement() { return iter.next(); }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestWrapper.java
new file mode 100644
index 0000000..47db1e4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/RequestWrapper.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Request;
+import org.apache.commons.collections.IteratorUtils;
+
+/**
+ * This is a wrapper class for the <code>Request</code> object.
+ * It has the same properties except that the url and the parameters
+ * are different.
+ *
+ * @version $Id$
+ */
+public final class RequestWrapper extends AbstractRequestWrapper {
+
+    /** The query string */
+    private String queryString;
+
+    /** The request parameters */
+    private final RequestParameters parameters ;
+
+    /** The environment */
+    private final Environment environment;
+
+    /** raw mode? **/
+    private final boolean rawMode;
+
+    /** The request uri */
+    private String requestURI;
+
+    private final Map requestAttributes = new HashMap();
+    
+    /**
+     * Constructor
+     */
+    public RequestWrapper(Request request,
+                          String  requestURI,
+                          String  queryString,
+                          Environment env) {
+        this(request, requestURI, queryString, env, false);
+    }
+
+    /**
+     * Constructor
+     */
+    public RequestWrapper(Request request,
+                          String  requestURI,
+                          String  queryString,
+                          Environment env,
+                          boolean rawMode) {
+        super(request);
+        this.environment = env;
+        this.queryString = queryString;
+        this.parameters = new RequestParameters(queryString);
+        this.rawMode = rawMode;
+        if (this.req.getQueryString() != null && !this.rawMode) {
+            if (this.queryString == null)
+                this.queryString = this.req.getQueryString();
+            else
+                this.queryString += '&' + this.req.getQueryString();
+        }
+        this.requestURI = this.req.getRequestURI();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameter(java.lang.String)
+     */
+    public String getParameter(String name) {
+        String value = this.parameters.getParameter(name);
+        if (value == null && !this.rawMode) {
+            return this.req.getParameter(name);
+        }
+        return value;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameterNames()
+     */
+    public Enumeration getParameterNames() {
+        if ( !this.rawMode ) {
+            // put all parameter names into a set
+            Set parameterNames = new HashSet();
+            Enumeration names = this.parameters.getParameterNames();
+            while (names.hasMoreElements()) {
+                parameterNames.add(names.nextElement());
+            }
+            names = this.req.getParameterNames();
+            while (names.hasMoreElements()) {
+                parameterNames.add(names.nextElement());
+            }
+            return new EnumerationFromIterator(parameterNames.iterator());
+        }
+        return this.parameters.getParameterNames();
+    }
+
+    final class EnumerationFromIterator implements Enumeration {
+        private Iterator iter;
+        EnumerationFromIterator(Iterator iter) {
+            this.iter = iter;
+        }
+
+        public boolean hasMoreElements() {
+            return iter.hasNext();
+        }
+        public Object nextElement() { return iter.next(); }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getParameterValues(java.lang.String)
+     */
+    public String[] getParameterValues(String name) {
+        if ( !this.rawMode ) {
+            String[] values = this.parameters.getParameterValues(name);
+            String[] inherited = this.req.getParameterValues(name);
+            if (inherited == null) return values;
+            if (values == null) return inherited;
+            String[] allValues = new String[values.length + inherited.length];
+            System.arraycopy(values, 0, allValues, 0, values.length);
+            System.arraycopy(inherited, 0, allValues, values.length, inherited.length);
+            return allValues;
+        }
+        return this.parameters.getParameterValues(name);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getQueryString()
+     */
+    public String getQueryString() {
+        return this.queryString;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getRequestURI()
+     */
+    public String getRequestURI() {
+        return this.requestURI;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapURI()
+     */
+    public String getSitemapURI() {
+        return this.environment.getURI();
+    }
+
+    public String getSitemapURIPrefix() {
+        return this.environment.getURIPrefix();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getSitemapPath()
+     */
+    public String getSitemapPath() {
+        return this.environment.getURIPrefix();
+    }
+
+    public void setRequestURI(String prefix, String uri) {
+        StringBuffer buffer = new StringBuffer(this.getContextPath());
+        buffer.append('/');
+        buffer.append(prefix);
+        buffer.append(uri);
+        this.requestURI = buffer.toString();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        if ( scope == Request.GLOBAL_SCOPE ) {
+            return super.getAttribute(name, scope);
+        }
+        return this.requestAttributes.get( name );
+    }
+        
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        if ( scope == Request.GLOBAL_SCOPE ) {
+            return super.getAttributeNames(scope);
+        }
+        return IteratorUtils.asEnumeration(this.requestAttributes.keySet().iterator());
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        if ( scope == Request.GLOBAL_SCOPE ) {
+            super.removeAttribute(name, scope);
+        } else {
+            this.requestAttributes.remove( name );
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object o, int scope) {
+        if ( scope == Request.GLOBAL_SCOPE ) {
+            super.setAttribute(name, o, scope);
+        } else {
+            this.requestAttributes.put( name, o );
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Request#searchAttribute(java.lang.String)
+     */
+    public Object searchAttribute(String name) {
+        Object result = this.getAttribute(name, REQUEST_SCOPE);
+        if ( result == null ) {
+            result = this.getAttribute(name, GLOBAL_SCOPE);
+            if ( result == null ) {
+                result = this.req.getAttribute(name, REQUEST_SCOPE);
+            }
+        }
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/ResponseWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/ResponseWrapper.java
new file mode 100644
index 0000000..ff18f35
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/environment/wrapper/ResponseWrapper.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.wrapper;
+
+import java.util.Locale;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Response;
+
+/**
+ * This is a wrapper class for the Response object.
+ * It contains the same properties as the wrapped instance
+ * but swallows calls that would modify response headers.
+ */
+public class ResponseWrapper implements Response {
+
+    private Response res;
+    
+    public ResponseWrapper(Response response) {
+        this.res = response;
+    }
+
+    public String getCharacterEncoding() {
+        return res.getCharacterEncoding();
+    }
+
+    public void setLocale(Locale loc) {
+        res.setLocale(loc);
+    }
+
+    public Locale getLocale() {
+        return res.getLocale();
+    }
+
+    public Cookie createCookie(String name, String value) {
+        return res.createCookie(name, value);
+    }
+
+    public void addCookie(Cookie cookie) {
+        res.addCookie(cookie);
+    }
+
+    public String encodeURL(String url) {
+        return res.encodeURL(url);
+    }
+
+    public boolean containsHeader(String name) {
+        return res.containsHeader(name);
+    }
+
+    public void setDateHeader(String name, long date) {
+    }
+
+    public void addDateHeader(String name, long date) {
+    }
+
+    public void setHeader(String name, String value) {
+    }
+
+    public void addHeader(String name, String value) {
+    }
+
+    public void setIntHeader(String name, int value) {
+    }
+
+    public void addIntHeader(String name, int value) {
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/AbstractGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/AbstractGenerator.java
new file mode 100644
index 0000000..eaeed32
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/AbstractGenerator.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.AbstractXMLProducer;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * An abstract class that can be used to implement an own generator.
+ * If you need other components, use the {@link ServiceableGenerator}
+ * instead.
+ * 
+ * @version $Id$
+ */
+public abstract class AbstractGenerator 
+    extends AbstractXMLProducer 
+    implements Generator {
+
+    /** The current <code>SourceResolver</code>. */
+    protected SourceResolver resolver;
+    /** The current <code>Map</code> objectModel. */
+    protected Map objectModel;
+    /** The current <code>Parameters</code>. */
+    protected Parameters parameters;
+    /** The source URI associated with the request or <b>null</b>. */
+    protected String source;
+
+    /**
+     * Set the <code>SourceResolver</code>, object model <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+        throws ProcessingException, SAXException, IOException {
+        this.resolver=resolver;
+        this.objectModel=objectModel;
+        this.source=src;
+        this.parameters=par;
+    }
+
+    /**
+     * Recycle the generator by removing references
+     */
+    public void recycle() {
+        super.recycle();
+        this.resolver = null;
+        this.objectModel = null;
+        this.source = null;
+        this.parameters = null;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CSVGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CSVGenerator.java
new file mode 100644
index 0000000..1294461
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CSVGenerator.java
@@ -0,0 +1,426 @@
+/* =============================================================================== *
+ * Copyright (C) 1999-2004, The Apache Software Foundation.   All rights reserved. *
+ *                                                                                 *
+ * Licensed 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.cocoon.generation;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * <p>A simple parser converting a Comma Separated Values (CSV) file into XML.</p>
+ * 
+ * <p>This parser is controlled by the following sitemap parameters:</p>
+ * 
+ * <ul>
+ *   <li>
+ *     <b>process-headers</b>: whether the first line in the CSV is considered
+ *     to be the header defining column names (the resulting output will be
+ *     different if this is <i>true</i> or <i>false</i> (default: <i>false</i>).
+ *   </li>
+ *   <li>
+ *     <b>encoding</b>: the character encoding (UTF-8, ISO8859-1, ...) used to
+ *     interpret the input CSV source file (default: <i>system default</i>).
+ *   </li>
+ *   <li>
+ *     <b>separator</b>: the field-separator character in the CSV file (comma,
+ *     tab, ...) (default: <i>,</i> <small>comma</small>).
+ *   </li>
+ *   <li>
+ *     <b>escape</b>: the character used to escape fields, or part of them, in
+ *     the CSV file (default: <i>"</i> <small>quote</small>).
+ *   </li>
+ *   <li>
+ *     <b>buffer-size</b>: the size of the buffer used for reading the source
+ *     CSV file (default: <i>4096 bytes</i>).
+ *   </li>
+ * </ul>
+ *
+ * <p>The generated output will look something like the following:</p>
+ * 
+ * <pre>
+ * &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+ * &lt;csv:document xmlns:csv="http://apache.org/cocoon/csv/1.0"&gt;
+ *   &lt;csv:header&gt;
+ *     &lt;csv:column number="1"&gt;Column A&lt;/csv:column&gt;
+ *     &lt;csv:column number="2"&gt;Column B&lt;/csv:column&gt;
+ *     &lt;csv:column number="3"&gt;Column C&lt;/csv:column&gt;
+ *   &lt;/csv:header&gt;
+ *   &lt;csv:record number="1"&gt;
+ *     &lt;csv:field number="1" column="Column A"&gt;Field A1&lt;/csv:field&gt;
+ *     &lt;csv:field number="2" column="Column B"&gt;Field B1&lt;/csv:field&gt;
+ *     &lt;csv:field number="3" column="Column C"&gt;Field C1&lt;/csv:field&gt;
+ *   &lt;/csv:record&gt;
+ *   &lt;csv:record number="2"&gt;
+ *     &lt;csv:field number="1" column="Column A"&gt;Field A2&lt;/csv:field&gt;
+ *     &lt;csv:field number="2" column="Column B"&gt;Field B2&lt;/csv:field&gt;
+ *     &lt;csv:field number="3" column="Column C"&gt;Field C2&lt;/csv:field&gt;
+ *   &lt;/csv:record&gt;
+ * &lt;/csv:document&gt;
+ * </pre>
+ *
+ * <p>Note that this generator has been thoroughly tested with CSV files generated
+ * by <a href="http://office.microsoft.com/" target="_new">Microsoft Excel</a>.
+ * Unfortunately no official CSV specification has ever been published by
+ * any standard body, so the interpretation of the format might be slightly
+ * different in cases.</p>
+ *
+ */
+public class CSVGenerator extends FileGenerator {
+
+    /** <p>The namespace URI of XML generated by this instance.</p> */
+    public static final String NAMESPACE_URI = "http://apache.org/cocoon/csv/1.0";
+    /** <p>The namespace prefix of XML generated by this instance.</p> */
+    public static final String NAMESPACE_PREFIX = "csv";
+
+    /** <p>The default encoding configured in the Java VM.</p> */
+    private static final String DEFAULT_ENCODING = 
+        new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding();
+    /** <p>The default field separator character.</p> */
+    private static final String DEFAULT_SEPARATOR = ",";
+    /** <p>The default field separator character.</p> */
+    private static final String DEFAULT_ESCAPE = "\"";
+    /** <p>The default field separator character.</p> */
+    private static final int DEFAULT_BUFFER_SIZE = 4096;
+    /** <p>A string used for indenting.</p> */
+    private static final char INDENT_STRING[] = "\n          ".toCharArray();
+
+    /** <p>The encoding used to read the CSV resource from a stream.</p> */
+    private String encoding = DEFAULT_ENCODING;
+    /** <p>The character used to separate fields.</p> */
+    private char separator = DEFAULT_SEPARATOR.charAt(0);
+    /** <p>The character used to initiate and terminate esacaped sequences.</p> */
+    private char escape = DEFAULT_ESCAPE.charAt(0);
+    /** <p>The size of the buffer used to read the input.</p> */
+    private int buffersize = DEFAULT_BUFFER_SIZE;
+    /** <p>The current field (column) number in the current record.</p> */
+    private int fieldnumber = 1;
+    /** <p>The current record (line) number in the current CSV.</p> */
+    private int recordnumber = 1;
+    /** <p>A flag indicating whether the &lt;record&gt; tag was opened.</p> */
+    private boolean openrecord = false;
+    /** <p>The character buffer for the current field.</p> */
+    private CharArrayWriter buffer = null;
+    /** <p>A map of all known columns or null if no headers are processed.</p> */
+    private Map columns = null;
+
+    /**
+     * <p>Create a new {@link CSVGenerator} instance.</p>
+     */
+    public CSVGenerator() {
+        super();
+    }
+
+    /**
+     * <p>Recycle this component.</p>.
+     */
+    public void recycle() {
+        super.recycle();
+        
+        this.encoding = DEFAULT_ENCODING;
+        this.separator = DEFAULT_SEPARATOR.charAt(0);
+        this.escape = DEFAULT_ESCAPE.charAt(0);
+        this.buffersize = DEFAULT_BUFFER_SIZE;
+        this.buffer = null;
+        this.columns = null;
+        this.recordnumber = 1;
+        this.fieldnumber = 1;
+        this.openrecord = false;
+    }
+
+    /**
+     * <p>Setup this {@link CSVGenerator} instance.</p>
+     */
+    public void setup(SourceResolver resolver, Map object_model, String source,
+                      Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, object_model, source, parameters);
+
+        boolean header = parameters.getParameterAsBoolean("process-header", false);
+
+        this.encoding = parameters.getParameter("encoding", DEFAULT_ENCODING);
+        this.separator = parameters.getParameter("separator", DEFAULT_SEPARATOR).charAt(0);
+        this.escape = parameters.getParameter("escape", DEFAULT_ESCAPE).charAt(0);
+        this.buffersize = parameters.getParameterAsInteger("buffer-size", DEFAULT_BUFFER_SIZE);
+        this.buffer = new CharArrayWriter();
+        this.columns =  (header ? new HashMap() : null);
+        this.recordnumber = (header ? 0 : 1);
+        this.fieldnumber = 1;
+        this.openrecord = false;
+    }
+
+    /**
+     * <p>Generate the unique key.</p>
+     */
+    public Serializable getKey() {
+        String key = this.inputSource.getURI();
+        if (this.columns != null) return (key + "+headers");
+        return key;
+    }
+
+    /**
+     * <p>Generate XML data from a Comma Separated Value resource.</p>.
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+
+        /* Create a new Reader correctly decoding the source stream */
+        CSVReader csv = new CSVReader(this.inputSource, this.encoding, this.buffersize);
+
+        try {
+            /* Start the document */
+            this.contentHandler.setDocumentLocator(csv);
+            this.contentHandler.startDocument();
+            this.contentHandler.startPrefixMapping(NAMESPACE_PREFIX, NAMESPACE_URI);
+            this.indent(0);
+            this.startElement("document");
+
+            /* Allocate buffer and status for parsing */
+            boolean unescaped = true;
+            int prev = -1;
+            int curr = -1;
+
+            /* Parse the file reading characters one-by-one */
+            while ((curr = csv.read()) >= 0) {
+
+                /* Process any occurrence of the escape character */
+                if (curr == this.escape) {
+                    if ((unescaped) && (prev == this.escape)) {
+                        this.buffer.write(this.escape);
+                    }
+                    unescaped = ! unescaped;
+                    prev = curr;
+                    continue;
+                }
+
+                /* Process any occurrence of the field separator */
+                if ((unescaped) && (curr == this.separator)) {
+                    this.dumpField();
+                    prev = curr;
+                    continue;
+                }
+
+                /* Process newline characters */
+                if ((unescaped) && ((curr == '\r') || (curr == '\n'))) {
+                    this.dumpField();
+                    this.dumpRecord();
+
+                    /* Record numbering */
+                    if (((curr == '\n') && (prev != '\r')) || (curr == '\r')) {
+                        this.recordnumber ++;
+                    }
+                    
+                    /* Nothing else to do */
+                    prev = curr;
+                    continue;
+                }
+
+                /* Any other character simply gets added to the buffer */
+                this.buffer.write(curr);
+                prev = curr;
+            }
+
+            /* Terminate any hanging open record element (just in case) */
+            this.dumpField();
+            this.dumpRecord();
+
+            /* Terminate the document */
+            this.indent(0);
+            this.endElement("document");
+            this.contentHandler.endPrefixMapping(NAMESPACE_PREFIX);
+            this.contentHandler.endDocument();
+
+        } finally {
+            csv.close();
+        }
+    }
+
+    
+    private void dumpField()
+    throws SAXException {
+        if (this.buffer.size() < 1) {
+            this.fieldnumber ++;
+            return;
+        }
+
+        if (! this.openrecord) {
+            this.indent(4);
+
+            if (this.recordnumber > 0) {
+                AttributesImpl attributes = new AttributesImpl();
+                String value = Integer.toString(this.recordnumber);
+                attributes.addAttribute("", "number", "number", "CDATA", value);
+                this.startElement("record", attributes);
+            } else {
+                this.startElement("header");
+            }
+            this.openrecord = true;
+        }
+
+        /* Enclode the field in the proper element */
+        String element = "field";
+        char array[] = this.buffer.toCharArray();
+        this.indent(8);
+
+        AttributesImpl attributes = new AttributesImpl();
+        String value = Integer.toString(this.fieldnumber);
+        attributes.addAttribute("", "number", "number", "CDATA", value);
+
+        if (this.recordnumber < 1) {
+            this.columns.put(new Integer(this.fieldnumber), new String(array));
+            element = "column";
+        } else if (this.columns != null) {
+            String header = (String) this.columns.get(new Integer(this.fieldnumber));
+            if (header != null) {
+                attributes.addAttribute("", "column", "column", "CDATA", header);
+            }
+        }
+
+        this.startElement(element, attributes);
+        this.contentHandler.characters(array, 0, array.length);
+        this.endElement(element);
+        this.buffer.reset();
+
+        this.fieldnumber ++;
+    }
+
+    private void dumpRecord()
+    throws SAXException {
+        if (this.openrecord) {
+            this.indent(4);
+            if (this.recordnumber > 0) {
+                this.endElement("record");
+            } else {
+                this.endElement("header");
+            }
+            this.openrecord = false;
+        }
+        this.fieldnumber = 1;
+    }
+
+    private void indent(int level)
+    throws SAXException {
+        this.contentHandler.characters(INDENT_STRING, 0, level + 1);
+    }
+
+    private void startElement(String name)
+    throws SAXException {
+        this.startElement(name, new AttributesImpl());
+    }
+
+    private void startElement(String name, Attributes atts)
+    throws SAXException {
+        if (name == null) throw new NullPointerException("Null name");
+        if (atts == null) atts = new AttributesImpl();
+        String qual = NAMESPACE_PREFIX + ':' + name;
+        this.contentHandler.startElement(NAMESPACE_URI, name, qual, atts);
+    }
+
+    private void endElement(String name)
+    throws SAXException {
+        String qual = NAMESPACE_PREFIX + ':' + name;
+        this.contentHandler.endElement(NAMESPACE_URI, name, qual);
+    }
+
+    private static final class CSVReader extends Reader implements Locator {
+        
+        private String uri = null;
+        private Reader input = null;
+        private int column = 1;
+        private int line = 1;
+        private int last = -1;
+
+        private CSVReader(Source source, String encoding, int buffer)
+        throws IOException {
+            InputStream stream = source.getInputStream();
+            Reader reader = new InputStreamReader(stream, encoding);
+            this.input = new BufferedReader(reader, buffer);
+            this.uri = source.getURI();
+        }
+
+        public String getPublicId() {
+            return null;
+        }
+
+        public String getSystemId() {
+            return this.uri;
+        }
+
+        public int getLineNumber() {
+            return this.line;
+        }
+
+        public int getColumnNumber() {
+            return this.column;
+        }
+
+        public void close()
+        throws IOException {
+            this.input.close();
+        }
+        
+        public int read()
+        throws IOException {
+            int c = this.input.read();
+            if (c < 0) return c;
+
+            if (((c == '\n') && (this.last != '\r')) || (c == '\r')) {
+                this.column = 1;
+                this.line ++;
+            }
+
+            this.last = c;
+            return c;
+        }
+
+        public int read(char b[], int o, int l)
+        throws IOException {
+            if (b == null) throw new NullPointerException();
+            if ((o<0)||(o>b.length)||(l<0)||((o+l)>b.length)||((o+l)<0)) {
+                throw new IndexOutOfBoundsException();
+            }
+            if (l == 0) return 0;
+
+            int c = read();
+            if (c == -1) return -1;
+            b[o] = (char)c;
+
+            int i = 1;
+            try {
+                for (i = 1; i < l ; i++) {
+                    c = read();
+                    if (c == -1) break;
+                    if (b != null) b[o + i] = (char)c;
+                }
+            } catch (IOException ee) {
+                return i;
+            }
+            return i;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CalendarGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CalendarGenerator.java
new file mode 100644
index 0000000..446ddd7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/CalendarGenerator.java
@@ -0,0 +1,364 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML document representing a calendar for a given month and year.
+ * 
+ * @cocoon.sitemap.component.documentation.caching TBD
+ * @cocoon.sitemap.component.name   calendar
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.calendar
+ * 
+ * 
+ * <p>
+ * Here is a sample output:
+ * </p>
+ * <pre>
+ * &lt;calendar:calendar xmlns:calendar="http://apache.org/cocoon/calendar/1.0"
+ *     year="2004" month="January" prevMonth="12" prevYear="2003"
+ *     nextMonth="02" nextYear="2004"&gt;
+ *   &lt;calendar:week number="1"&gt;
+ *     &lt;calendar:day number="1" weekday="THURSDAY" date="January 1, 2004"/&gt;
+ *     &lt;calendar:day number="2" weekday="FRIDAY" date="January 2, 2004"/&gt;
+ *     &lt;calendar:day number="3" weekday="SATURDAY" date="January 3, 2004"/&gt;
+ *     &lt;calendar:day number="4" weekday="SUNDAY" date="January 4, 2004"/&gt;
+ *   &lt;/calendar:week&gt;
+ *   ...
+ * &lt;/calendar:calendar&gt;
+ * </pre>
+ * <p>
+ * The <i>src</i> parameter is ignored.
+ * </p>
+ * <p>
+ *  <b>Configuration options:</b>
+ *  <dl>
+ *   <dt> <i>month</i> (optional)</dt>
+ *   <dd> Sets the month for the calendar (January is 1). Default is the current month.</dd>
+ *   <dt> <i>year</i> (optional)</dt>
+ *   <dd> Sets the year for the calendar. Default is the current year.</dd>
+ *   <dt> <i>dateFormat</i> (optional)</dt>
+ *   <dd> Sets the format for the date attribute of each node, as
+ *        described in java.text.SimpleDateFormat. If unset, the default
+ *        format for the current locale will be used.</dd>
+ *   <dt> <i>lang</i> (optional)</dt>
+ *   <dd> Sets the ISO language code for determining the locale.</dd>
+ *   <dt> <i>country</i> (optional)</dt>
+ *   <dd> Sets the ISO country code for determining the locale.</dd>
+ *   <dt> <i>padWeeks</i> (optional)</dt>
+ *   <dd> If set to true, full weeks will be generated by adding
+ *        days from the end of the previous month and the beginning
+ *        of the following month.</dd>
+ *  </dl>
+ * </p>
+ *               
+ * @version $Id$
+ */
+public class CalendarGenerator extends ServiceableGenerator implements CacheableProcessingComponent {
+    
+    /** The URI of the namespace of this generator. */
+    protected static final String URI = "http://apache.org/cocoon/calendar/1.0";
+    
+    /** The namespace prefix for this namespace. */
+    protected static final String PREFIX = "calendar";
+    
+    /** Node and attribute names */
+    protected static final String CALENDAR_NODE_NAME   = "calendar";
+    protected static final String WEEK_NODE_NAME       = "week";
+    protected static final String DAY_NODE_NAME        = "day";
+    protected static final String MONTH_ATTR_NAME      = "month";
+    protected static final String YEAR_ATTR_NAME       = "year";
+    protected static final String DATE_ATTR_NAME       = "date";
+    protected static final String NUMBER_ATTR_NAME     = "number";
+    protected static final String WEEKDAY_ATTR_NAME    = "weekday";
+    protected static final String PREV_MONTH_ATTR_NAME = "prevMonth";
+    protected static final String PREV_YEAR_ATTR_NAME  = "prevYear";
+    protected static final String NEXT_MONTH_ATTR_NAME = "nextMonth";
+    protected static final String NEXT_YEAR_ATTR_NAME  = "nextYear";
+    
+    /** Formatter for month number */
+    protected static final DecimalFormat monthNumberFormatter = new DecimalFormat("00");
+    
+    /** Convenience object, so we don't need to create an AttributesImpl for every element. */
+    protected AttributesImpl attributes;
+    
+    /**
+     * The cache key needs to be generated for the configuration of this
+     * generator, so storing the parameters for generateKey().
+     */
+    protected List cacheKeyParList;
+    
+    /** The year to generate the calendar for */
+    protected int year;
+    
+    /** The month to generate the calendar for */
+    protected int month;
+    
+    /** The format for dates */
+    protected DateFormat dateFormatter;
+    
+    /** The format for month names */
+    protected DateFormat monthFormatter;
+    
+    /** The current locale */
+    protected Locale locale;
+    
+    /** Do we need to pad out the first and last weeks? */
+    protected boolean padWeeks;
+    
+    /* Add the day of the week 
+     * 
+     * since SUNDAY=1, we start with a dummy
+     * entry. 
+     */
+    protected String weekdays[] = { "",
+        "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", 
+        "FRIDAY", "SATURDAY"
+    };
+	
+    /**
+     * Set the request parameters. Must be called before the generate method.
+     *
+     * @param resolver     the SourceResolver object
+     * @param objectModel  a <code>Map</code> containing model object
+     * @param src          the source URI (ignored)
+     * @param par          configuration parameters
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+        
+        this.cacheKeyParList = new ArrayList();
+        this.cacheKeyParList.add(src);
+
+        // Determine the locale
+        String langString = par.getParameter("lang", null);
+        locale = Locale.getDefault();
+        if (langString != null) {
+            this.cacheKeyParList.add(langString);
+            String countryString = par.getParameter("country", "");
+            if (! "".equals(countryString)) {
+                this.cacheKeyParList.add(countryString);
+            }
+            locale = new Locale(langString, countryString);
+        }
+        
+        // Determine year and month. Default is current year and month.
+        Calendar now = Calendar.getInstance(locale);
+        this.year = par.getParameterAsInteger("year", now.get(Calendar.YEAR));
+        this.cacheKeyParList.add(String.valueOf(this.year));
+        this.month = par.getParameterAsInteger("month", now.get(Calendar.MONTH) + 1) - 1;
+        this.cacheKeyParList.add(String.valueOf(this.month));
+        
+        String dateFormatString = par.getParameter("dateFormat", null);
+        this.cacheKeyParList.add(dateFormatString);
+        if (dateFormatString != null) {
+            this.dateFormatter = new SimpleDateFormat(dateFormatString, locale);
+        } else {
+            this.dateFormatter = DateFormat.getDateInstance(DateFormat.LONG, locale);
+        }
+        this.padWeeks = par.getParameterAsBoolean("padWeeks", false);
+        this.cacheKeyParList.add(BooleanUtils.toBooleanObject(this.padWeeks));
+        this.monthFormatter = new SimpleDateFormat("MMMM", locale);        
+        this.attributes = new AttributesImpl();
+    }
+    
+    /**
+     * Generate XML data.
+     *
+     * @throws  SAXException if an error occurs while outputting the document
+     */
+    public void generate() throws SAXException, ProcessingException {
+        Calendar start = Calendar.getInstance(locale);
+        start.clear();
+        start.set(Calendar.YEAR, this.year);
+        start.set(Calendar.MONTH, this.month);
+        start.set(Calendar.DAY_OF_MONTH, 1);
+        Calendar end = (Calendar) start.clone();
+        end.add(Calendar.MONTH, 1);
+
+        // Determine previous and next months
+        Calendar prevMonth = (Calendar) start.clone();
+        prevMonth.add(Calendar.MONTH, -1);
+        
+        this.contentHandler.startDocument();
+        this.contentHandler.startPrefixMapping(PREFIX, URI);
+        attributes.clear();
+        attributes.addAttribute("", YEAR_ATTR_NAME, YEAR_ATTR_NAME, "CDATA", String.valueOf(year));
+        attributes.addAttribute("", MONTH_ATTR_NAME, MONTH_ATTR_NAME, "CDATA", 
+                monthFormatter.format(start.getTime()));
+        
+        // Add previous and next month
+        attributes.addAttribute("", PREV_YEAR_ATTR_NAME, PREV_YEAR_ATTR_NAME, "CDATA", 
+                String.valueOf(prevMonth.get(Calendar.YEAR)));
+        attributes.addAttribute("", PREV_MONTH_ATTR_NAME, PREV_MONTH_ATTR_NAME, "CDATA", 
+                monthNumberFormatter.format(prevMonth.get(Calendar.MONTH) + 1));
+        attributes.addAttribute("", NEXT_YEAR_ATTR_NAME, NEXT_YEAR_ATTR_NAME, "CDATA", 
+                String.valueOf(end.get(Calendar.YEAR)));
+        attributes.addAttribute("", NEXT_MONTH_ATTR_NAME, NEXT_MONTH_ATTR_NAME, "CDATA", 
+                monthNumberFormatter.format(end.get(Calendar.MONTH) + 1));
+
+        this.contentHandler.startElement(URI, CALENDAR_NODE_NAME,
+                PREFIX + ':' + CALENDAR_NODE_NAME, attributes);
+        int weekNo = start.get(Calendar.WEEK_OF_MONTH);
+        int firstDay = start.getFirstDayOfWeek();
+        if (start.get(Calendar.DAY_OF_WEEK) != firstDay) {
+            attributes.clear();
+            attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA", String.valueOf(weekNo));
+            this.contentHandler.startElement(URI, WEEK_NODE_NAME,
+                    PREFIX + ':' + WEEK_NODE_NAME, attributes);
+            if (padWeeks) {
+                Calendar previous = (Calendar) start.clone();
+                while (previous.get(Calendar.DAY_OF_WEEK) != firstDay) {
+                    previous.add(Calendar.DAY_OF_MONTH, -1);		
+                }
+                while (previous.before(start)) {
+                    attributes.clear();
+                    attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
+                            String.valueOf(previous.get(Calendar.DAY_OF_MONTH)));
+                    attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
+                            weekdays[previous.get(Calendar.DAY_OF_WEEK)]);
+                    attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
+                            dateFormatter.format(previous.getTime()));
+                    this.contentHandler.startElement(URI, DAY_NODE_NAME,
+                            PREFIX + ':' + DAY_NODE_NAME, attributes);
+                    addContent(previous, locale);
+                    this.contentHandler.endElement(URI, DAY_NODE_NAME,
+                            PREFIX + ':' + DAY_NODE_NAME);
+                    previous.add(Calendar.DAY_OF_MONTH, 1); 
+                } 
+            }
+        }
+        while (start.before(end)) {
+            if (start.get(Calendar.DAY_OF_WEEK) == firstDay) {
+                weekNo = start.get(Calendar.WEEK_OF_MONTH);
+                attributes.clear();
+                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA", String.valueOf(weekNo));
+                this.contentHandler.startElement(URI, WEEK_NODE_NAME,
+                        PREFIX + ':' + WEEK_NODE_NAME, attributes);
+            }
+            attributes.clear();
+            attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
+                    String.valueOf(start.get(Calendar.DAY_OF_MONTH)));
+            attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
+                    weekdays[start.get(Calendar.DAY_OF_WEEK)]);
+            attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
+                    dateFormatter.format(start.getTime()));
+            this.contentHandler.startElement(URI, DAY_NODE_NAME,
+                    PREFIX + ':' + DAY_NODE_NAME, attributes);
+            addContent(start, locale);
+            this.contentHandler.endElement(URI, DAY_NODE_NAME,
+                    PREFIX + ':' + DAY_NODE_NAME);
+            start.add(Calendar.DAY_OF_MONTH, 1);
+            if (start.get(Calendar.DAY_OF_WEEK) == firstDay
+                    || (!padWeeks && ! start.before(end))) {
+                this.contentHandler.endElement(URI, WEEK_NODE_NAME,
+                        PREFIX + ':' + WEEK_NODE_NAME);
+            }
+        }
+        
+        if (padWeeks) {
+            while (firstDay != end.get(Calendar.DAY_OF_WEEK)) {
+                attributes.clear();
+                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
+                        String.valueOf(end.get(Calendar.DAY_OF_MONTH)));
+                attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
+                        weekdays[end.get(Calendar.DAY_OF_WEEK)]);
+                attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
+                        dateFormatter.format(end.getTime()));
+                this.contentHandler.startElement(URI, DAY_NODE_NAME,
+                        PREFIX + ':' + DAY_NODE_NAME, attributes);
+                addContent(end, locale);
+                this.contentHandler.endElement(URI, DAY_NODE_NAME,
+                        PREFIX + ':' + DAY_NODE_NAME);
+                end.add(Calendar.DAY_OF_MONTH, 1); 		
+                if (firstDay == end.get(Calendar.DAY_OF_WEEK)) { 
+                        this.contentHandler.endElement(URI, WEEK_NODE_NAME,
+	                       PREFIX + ':' + WEEK_NODE_NAME);
+                }
+            }
+        }
+        this.contentHandler.endElement(URI, CALENDAR_NODE_NAME,
+                PREFIX + ':' + CALENDAR_NODE_NAME);
+        this.contentHandler.endPrefixMapping(PREFIX);
+        this.contentHandler.endDocument();
+    }
+    
+    /**
+     * Add content to a &lt;day&gt; element. This method is intended to be overridden
+     * by subclasses that want to add content to one or more days of the calendar.
+     * 
+     * @param date   The date corresponding to the current element.
+     * @param locale The current locale.
+     * @throws SAXException if an error occurs while outputting the document
+     */
+    protected void addContent(Calendar date, Locale locale) throws SAXException {}
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
+     */
+    public Serializable getKey() {
+        StringBuffer buffer = new StringBuffer();
+        int len = this.cacheKeyParList.size();
+        for (int i = 0; i < len; i++) {
+            buffer.append(this.cacheKeyParList.get(i) + ":");
+        }
+        return buffer.toString();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+    
+    /**
+     * Recycle resources
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        this.cacheKeyParList = null;
+        this.attributes = null;
+        this.dateFormatter = null;
+        this.monthFormatter = null;
+        this.locale = null;
+        super.recycle();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/DirectoryGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/DirectoryGenerator.java
new file mode 100644
index 0000000..bc25ad2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/DirectoryGenerator.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML directory listing.
+ * A more general approach is implemented by the TraversableGenerator (src/blocks/repository/java/org/apache/cocoon/generation/TraversableGenerator.java)
+ * 
+ * @cocoon.sitemap.component.name   directory
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.directory
+ * @cocoon.sitemap.component.documentation.caching
+ *               Uses the last modification date of the directory and the contained files
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ *  
+ * @version $Id$
+ */
+public class DirectoryGenerator 
+    extends ServiceableGenerator 
+    implements CacheableProcessingComponent {
+
+    /** Constant for the file protocol. */
+    private static final String FILE = "file:";
+
+    /** The URI of the namespace of this generator. */
+    protected static final String URI = "http://apache.org/cocoon/directory/2.0";
+
+    /** The namespace prefix for this namespace. */
+    protected static final String PREFIX = "dir";
+
+    /* Node and attribute names */
+    protected static final String DIR_NODE_NAME = "directory";
+    protected static final String FILE_NODE_NAME = "file";
+
+    protected static final String FILENAME_ATTR_NAME = "name";
+    protected static final String LASTMOD_ATTR_NAME = "lastModified";
+    protected static final String DATE_ATTR_NAME = "date";
+    protected static final String SIZE_ATTR_NAME = "size";
+
+    /** The validity that is being built */
+    protected DirValidity validity;
+    /** Convenience object, so we don't need to create an AttributesImpl for every element. */
+    protected AttributesImpl attributes;
+
+    /**
+     * The cache key needs to be generated for the configuration of this
+     * generator, so storing the parameters for generateKey().
+     * Using the member variables after setup() would not work I guess. I don't
+     * know a way from the regular expressions back to the pattern or at least
+     * a useful string.
+     */
+    protected List cacheKeyParList;
+
+    /** The depth parameter determines how deep the DirectoryGenerator should delve. */
+    protected int depth;
+    /**
+     * The dateFormatter determines into which date format the lastModified
+     * time should be converted.
+     * FIXME: SimpleDateFormat is not supported by all locales!
+     */
+    protected SimpleDateFormat dateFormatter;
+    /** The delay between checks on updates to the filesystem. */
+    protected long refreshDelay;
+    /**
+     * The sort parameter determines by which attribute the content of one
+     * directory should be sorted. Possible values are "name", "size", "lastmodified"
+     * and "directory", where "directory" is the same as "name", except that
+     * directory entries are listed first.
+     */
+    protected String sort;
+    /** The reverse parameter reverses the sort order. <code>false</code> is default. */
+    protected boolean reverse;
+    /** The regular expression for the root pattern. */
+    protected RE rootRE;
+    /** The regular expression for the include pattern. */
+    protected RE includeRE;
+    /** The regular expression for the exclude pattern. */
+    protected RE excludeRE;
+    /**
+     * This is only set to true for the requested directory specified by the
+     * <code>src</code> attribute on the generator's configuration.
+     */
+    protected boolean isRequestedDirectory;
+
+    /** The source object for the directory. */
+    protected Source directorySource;
+
+    /**
+     * Set the request parameters. Must be called before the generate method.
+     *
+     * @param resolver     the SourceResolver object
+     * @param objectModel  a <code>Map</code> containing model object
+     * @param src          the directory to be XMLized specified as src attribute on &lt;map:generate/>
+     * @param par          configuration parameters
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+            throws ProcessingException, SAXException, IOException {
+        if (src == null) {
+            throw new ProcessingException("No src attribute pointing to a directory to be XMLized specified.");
+        }
+        super.setup(resolver, objectModel, src, par);
+
+        try {
+            this.directorySource = this.resolver.resolveURI(src);
+        } catch (SourceException se) {
+            throw SourceUtil.handle(se);
+        }
+
+        this.cacheKeyParList = new ArrayList();
+        this.cacheKeyParList.add(this.directorySource.getURI());
+
+        this.depth = par.getParameterAsInteger("depth", 1);
+        this.cacheKeyParList.add(String.valueOf(this.depth));
+
+        String dateFormatString = par.getParameter("dateFormat", null);
+        this.cacheKeyParList.add(dateFormatString);
+        if (dateFormatString != null) {
+            this.dateFormatter = new SimpleDateFormat(dateFormatString);
+        } else {
+            this.dateFormatter = new SimpleDateFormat();
+        }
+
+        this.sort = par.getParameter("sort", "name");
+        this.cacheKeyParList.add(this.sort);
+
+        this.reverse = par.getParameterAsBoolean("reverse", false);
+        this.cacheKeyParList.add(String.valueOf(this.reverse));
+
+        this.refreshDelay = par.getParameterAsLong("refreshDelay", 1L) * 1000L;
+        this.cacheKeyParList.add(String.valueOf(this.refreshDelay));
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("depth: " + this.depth);
+            this.getLogger().debug("dateFormat: " + this.dateFormatter.toPattern());
+            this.getLogger().debug("sort: " + this.sort);
+            this.getLogger().debug("reverse: " + this.reverse);
+            this.getLogger().debug("refreshDelay: " + this.refreshDelay);
+        }
+
+        String rePattern = null;
+        try {
+            rePattern = par.getParameter("root", null);
+            this.cacheKeyParList.add(rePattern);
+            this.rootRE = (rePattern == null) ? null : new RE(rePattern);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("root pattern: " + rePattern);
+            }
+
+            rePattern = par.getParameter("include", null);
+            this.cacheKeyParList.add(rePattern);
+            this.includeRE = (rePattern == null) ? null : new RE(rePattern);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("include pattern: " + rePattern);
+            }
+
+            rePattern = par.getParameter("exclude", null);
+            this.cacheKeyParList.add(rePattern);
+            this.excludeRE = (rePattern == null) ? null : new RE(rePattern);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("exclude pattern: " + rePattern);
+            }
+        } catch (RESyntaxException rese) {
+            throw new ProcessingException("Syntax error in regexp pattern '"
+                                          + rePattern + "'", rese);
+        }
+
+        this.isRequestedDirectory = false;
+        this.attributes = new AttributesImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
+     */
+    public Serializable getKey() {
+        StringBuffer buffer = new StringBuffer();
+        int len = this.cacheKeyParList.size();
+        for (int i = 0; i < len; i++) {
+            buffer.append((String)this.cacheKeyParList.get(i) + ":");
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Gets the source validity, using a deferred validity object. The validity
+     * is initially empty since the files that define it are not known before
+     * generation has occured. So the returned object is kept by the generator
+     * and filled with each of the files that are traversed.
+     * 
+     * @see DirectoryGenerator.DirValidity
+     */
+    public SourceValidity getValidity() {
+        if (this.validity == null) {
+            this.validity = new DirValidity(this.refreshDelay);
+        }
+        return this.validity;
+    }
+
+    /**
+     * Generate XML data.
+     * 
+     * @throws SAXException  if an error occurs while outputting the document
+     * @throws ProcessingException  if the requsted URI isn't a directory on the local filesystem
+     */
+    public void generate() throws SAXException, ProcessingException {
+        try {
+            String systemId = this.directorySource.getURI();
+            if (!systemId.startsWith(FILE)) {
+                throw new ResourceNotFoundException(systemId + " does not denote a directory");
+            }
+            // This relies on systemId being of the form "file://..."
+            File directoryFile = new File(new URL(systemId).getFile());
+            if (!directoryFile.isDirectory()) {
+                throw new ResourceNotFoundException(super.source + " is not a directory.");
+            }
+
+            this.contentHandler.startDocument();
+            this.contentHandler.startPrefixMapping(PREFIX, URI);
+
+            Stack ancestors = getAncestors(directoryFile);
+            addAncestorPath(directoryFile, ancestors);
+
+            this.contentHandler.endPrefixMapping(PREFIX);
+            this.contentHandler.endDocument();
+        } catch (IOException ioe) {
+            throw new ResourceNotFoundException("Could not read directory " + super.source, ioe);
+        }
+    }
+
+    /**
+     * Creates a stack containing the ancestors of File up to specified directory.
+     * 
+     * @param path the File whose ancestors shall be retrieved
+     * @return a Stack containing the ancestors.
+     */
+    protected Stack getAncestors(File path) {
+        File parent = path;
+        Stack ancestors = new Stack();
+
+        while ((parent != null) && !isRoot(parent)) {
+            parent = parent.getParentFile();
+            if (parent != null) {
+                ancestors.push(parent);
+            } else {
+                // no ancestor matched the root pattern
+                ancestors.clear();
+            }
+        }
+
+        return ancestors;
+    }
+
+    /**
+     * Adds recursively the path from the directory matched by the root pattern
+     * down to the requested directory.
+     * 
+     * @param path       the requested directory.
+     * @param ancestors  the stack of the ancestors.
+     * @throws SAXException
+     */
+    protected void addAncestorPath(File path, Stack ancestors) throws SAXException {
+        if (ancestors.empty()) {
+            this.isRequestedDirectory = true;
+            addPath(path, depth);
+        } else {
+            startNode(DIR_NODE_NAME, (File)ancestors.pop());
+            addAncestorPath(path, ancestors);
+            endNode(DIR_NODE_NAME);
+        }
+    }
+
+    /**
+     * Adds a single node to the generated document. If the path is a
+     * directory, and depth is greater than zero, then recursive calls
+     * are made to add nodes for the directory's children.
+     * 
+     * @param path   the file/directory to process
+     * @param depth  how deep to scan the directory
+     * @throws SAXException  if an error occurs while constructing nodes
+     */
+    protected void addPath(File path, int depth) throws SAXException {
+        if (path.isDirectory()) {
+            startNode(DIR_NODE_NAME, path);
+            if (depth > 0) {
+                File contents[] = path.listFiles();
+
+                if (sort.equals("name")) {
+                    Arrays.sort(contents, new Comparator() {
+                        public int compare(Object o1, Object o2) {
+                            if (reverse) {
+                                return ((File)o2).getName().compareTo(((File)o1).getName());
+                            }
+                            return ((File)o1).getName().compareTo(((File)o2).getName());
+                        }
+                    });
+                } else if (sort.equals("size")) {
+                    Arrays.sort(contents, new Comparator() {
+                        public int compare(Object o1, Object o2) {
+                            if (reverse) {
+                                return new Long(((File)o2).length()).compareTo(
+                                    new Long(((File)o1).length()));
+                            }
+                            return new Long(((File)o1).length()).compareTo(
+                                new Long(((File)o2).length()));
+                        }
+                    });
+                } else if (sort.equals("lastmodified")) {
+                    Arrays.sort(contents, new Comparator() {
+                        public int compare(Object o1, Object o2) {
+                            if (reverse) {
+                                return new Long(((File)o2).lastModified()).compareTo(
+                                    new Long(((File)o1).lastModified()));
+                            }
+                            return new Long(((File)o1).lastModified()).compareTo(
+                                new Long(((File)o2).lastModified()));
+                        }
+                    });
+                } else if (sort.equals("directory")) {
+                    Arrays.sort(contents, new Comparator() {
+                        public int compare(Object o1, Object o2) {
+                            File f1 = (File)o1;
+                            File f2 = (File)o2;
+
+                            if (reverse) {
+                                if (f2.isDirectory() && f1.isFile())
+                                    return -1;
+                                if (f2.isFile() && f1.isDirectory())
+                                    return 1;
+                                return f2.getName().compareTo(f1.getName());
+                            }
+                            if (f2.isDirectory() && f1.isFile())
+                                return 1;
+                            if (f2.isFile() && f1.isDirectory())
+                                return -1;
+                            return f1.getName().compareTo(f2.getName());
+                        }
+                    });
+                }
+
+                for (int i = 0; i < contents.length; i++) {
+                    if (isIncluded(contents[i]) && !isExcluded(contents[i])) {
+                        addPath(contents[i], depth - 1);
+                    }
+                }
+            }
+            endNode(DIR_NODE_NAME);
+        } else {
+            if (isIncluded(path) && !isExcluded(path)) {
+                startNode(FILE_NODE_NAME, path);
+                endNode(FILE_NODE_NAME);
+            }
+        }
+    }
+
+    /**
+     * Begins a named node and calls setNodeAttributes to set its attributes.
+     * 
+     * @param nodeName  the name of the new node
+     * @param path      the file/directory to use when setting attributes
+     * @throws SAXException  if an error occurs while creating the node
+     */
+    protected void startNode(String nodeName, File path) throws SAXException {
+        if (this.validity != null) {
+            this.validity.addFile(path);
+        }
+        setNodeAttributes(path);
+        super.contentHandler.startElement(URI, nodeName, PREFIX + ':' + nodeName, attributes);
+    }
+
+    /**
+     * Sets the attributes for a given path. The default method sets attributes
+     * for the name of thefile/directory and for the last modification time
+     * of the path.
+     * 
+     * @param path  the file/directory to use when setting attributes
+     * @throws SAXException  if an error occurs while setting the attributes
+     */
+    protected void setNodeAttributes(File path) throws SAXException {
+        long lastModified = path.lastModified();
+        attributes.clear();
+        attributes.addAttribute("", FILENAME_ATTR_NAME, FILENAME_ATTR_NAME,
+                                "CDATA", path.getName());
+        attributes.addAttribute("", LASTMOD_ATTR_NAME, LASTMOD_ATTR_NAME,
+                                "CDATA", Long.toString(path.lastModified()));
+        attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME,
+                                "CDATA", dateFormatter.format(new Date(lastModified)));
+        attributes.addAttribute("", SIZE_ATTR_NAME, SIZE_ATTR_NAME,
+                                "CDATA", Long.toString(path.length()));
+        if (this.isRequestedDirectory) {
+            attributes.addAttribute("", "sort", "sort", "CDATA", this.sort);
+            attributes.addAttribute("", "reverse", "reverse", "CDATA",
+                                    String.valueOf(this.reverse));
+            attributes.addAttribute("", "requested", "requested", "CDATA", "true");
+            this.isRequestedDirectory = false;
+        }
+    }
+
+    /**
+     * Ends the named node.
+     * 
+     * @param nodeName  the name of the new node
+     * @throws SAXException  if an error occurs while closing the node
+     */
+    protected void endNode(String nodeName) throws SAXException {
+        super.contentHandler.endElement(URI, nodeName, PREFIX + ':' + nodeName);
+    }
+
+    /**
+     * Determines if a given File is the defined root.
+     * 
+     * @param path  the File to check
+     * @return true if the File is the root or the root pattern is not set,
+     *         false otherwise.
+     */
+    protected boolean isRoot(File path) {
+        return (this.rootRE == null) ? true : this.rootRE.match(path.getName());
+    }
+
+    /**
+     * Determines if a given File shall be visible.
+     * 
+     * @param path  the File to check
+     * @return true if the File shall be visible or the include Pattern is <code>null</code>,
+     *         false otherwise.
+     */
+    protected boolean isIncluded(File path) {
+        return (this.includeRE == null) ? true : this.includeRE.match(path.getName());
+    }
+
+    /**
+     * Determines if a given File shall be excluded from viewing.
+     * 
+     * @param path  the File to check
+     * @return false if the given File shall not be excluded or the exclude Pattern is <code>null</code>,
+     *         true otherwise.
+     */
+    protected boolean isExcluded(File path) {
+        return (this.excludeRE == null) ? false : this.excludeRE.match(path.getName());
+    }
+
+    /**
+     * Recycle resources
+     */
+    public void recycle() {
+        if ( this.resolver != null ) {
+            this.resolver.release(this.directorySource);
+            this.directorySource = null;
+        }
+        this.cacheKeyParList = null;
+        this.attributes = null;
+        this.dateFormatter = null;
+        this.rootRE = null;
+        this.includeRE = null;
+        this.excludeRE = null;
+        this.validity = null;
+        super.recycle();
+    }
+
+    /** Specific validity class, that holds all files that have been generated */
+    public static class DirValidity implements SourceValidity {
+
+        private long expiry;
+        private long delay;
+        List files = new ArrayList();
+        List fileDates = new ArrayList();
+
+        public DirValidity(long delay) {
+            expiry = System.currentTimeMillis() + delay;
+            this.delay = delay;
+        }
+
+        public int isValid() {
+            if (System.currentTimeMillis() <= expiry) {
+                return 1;
+            }
+
+            expiry = System.currentTimeMillis() + delay;
+            int len = files.size();
+            for (int i = 0; i < len; i++) {
+                File f = (File)files.get(i);
+                if (!f.exists()) {
+                    return -1; // File was removed
+                }
+
+                long oldDate = ((Long)fileDates.get(i)).longValue();
+                long newDate = f.lastModified();
+
+                if (oldDate != newDate) {
+                    return -1;
+                }
+            }
+
+            // all content is up to date: update the expiry date
+            expiry = System.currentTimeMillis() + delay;
+            return 1;
+        }
+
+        public int isValid(SourceValidity newValidity) {
+            return isValid();
+        }
+
+        public void addFile(File f) {
+            files.add(f);
+            fileDates.add(new Long(f.lastModified()));
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ExceptionGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
new file mode 100644
index 0000000..cd3e564
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ExceptionGenerator.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.location.LocatableException;
+import org.apache.cocoon.util.location.Location;
+import org.apache.cocoon.util.location.LocationUtils;
+import org.apache.cocoon.util.location.MultiLocatable;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A generator that dumps an XML representation of the exception raised during a pipeline execution.
+ * <p>
+ * The Cocoon stack trace is produced, reflecting all locations the original exception went through,
+ * along with the root exception stacktrace and the full exception stacktrace.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class ExceptionGenerator extends AbstractGenerator {
+    
+    private Throwable thr;
+    
+    public static String EXCEPTION_NS = "http://apache.org/cocoon/exception/1.0";
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+        thr = (Throwable)objectModel.get(ObjectModelHelper.THROWABLE_OBJECT);
+        if (thr == null) {
+            throw new ProcessingException("ExceptionGenerator should be used in <map:handle-errors>");
+        }
+    }
+
+    public void generate() throws IOException, SAXException, ProcessingException {
+        this.contentHandler.startDocument();
+        toSAX(thr, this.contentHandler);
+        this.contentHandler.endDocument();
+    }
+    
+    public static void toSAX(Throwable thr, ContentHandler handler) throws SAXException {
+        Throwable root = ExceptionUtils.getRootCause(thr);
+        if (root == null) root = thr;
+
+        AttributesImpl attr = new AttributesImpl();
+        handler.startPrefixMapping("ex", EXCEPTION_NS);
+        attr.addCDATAAttribute("class", root.getClass().getName());
+        handler.startElement(EXCEPTION_NS, "exception-report", "ex:exception-report", attr);
+        
+        // Root exception location
+        Location loc = LocationUtils.getLocation(root);        
+        if (LocationUtils.isKnown(loc)) {
+            attr.clear();
+            dumpLocation(loc, attr, handler);
+        }
+
+        // Root exception message
+        attr.clear();
+        String message = root instanceof LocatableException ? ((LocatableException)root).getRawMessage() : root.getMessage();
+        simpleElement("message", attr, message, handler);
+        
+        // Cocoon stacktrace: dump all located exceptions in the exception stack
+        handler.startElement(EXCEPTION_NS, "cocoon-stacktrace", "ex:cocoon-stacktrace", attr);
+        Throwable current = thr;
+        while (current != null) {
+            loc = LocationUtils.getLocation(current);
+            if (LocationUtils.isKnown(loc)) {
+                // One or more locations: dump it
+                handler.startElement(EXCEPTION_NS, "exception", "ex:exception", attr);
+                
+                message = current instanceof LocatableException ? ((LocatableException)current).getRawMessage() : current.getMessage();
+                simpleElement("message", attr, message, handler);
+
+                attr.clear();
+                handler.startElement(EXCEPTION_NS, "locations", "ex:locations", attr);
+                dumpLocation(loc, attr, handler);
+                
+                if (current instanceof MultiLocatable) {
+                    List locations = ((MultiLocatable)current).getLocations();
+                    for (int i = 1; i < locations.size(); i++) { // start at 1 because we already dumped the first one
+                        attr.clear();
+                        dumpLocation((Location)locations.get(i), attr, handler);
+                    }
+                }
+                handler.endElement(EXCEPTION_NS, "locations", "ex:locations");
+                handler.endElement(EXCEPTION_NS, "exception", "ex:exception");
+            }
+            
+            
+            // Dump parent location
+            current = ExceptionUtils.getCause(current);
+        }
+        
+        handler.endElement(EXCEPTION_NS, "cocoon-stacktrace", "ex:cocoon-stacktrace");
+        
+        // Root exception stacktrace
+        attr.clear();
+        simpleElement("stacktrace", attr, ExceptionUtils.getStackTrace(root), handler);
+        
+        // Full stack trace (if exception is chained)
+        if (thr != root) {
+            String trace = SystemUtils.isJavaVersionAtLeast(140) ?
+                    ExceptionUtils.getStackTrace(thr) :
+                    ExceptionUtils.getFullStackTrace(thr);
+
+            simpleElement("full-stacktrace", attr, trace, handler);
+        }
+        
+        handler.endElement(EXCEPTION_NS, "exception-report", "ex:exception-report");
+        handler.endPrefixMapping("ex");
+    }
+    
+    private static void dumpLocation(Location loc, AttributesImpl attr, ContentHandler handler) throws SAXException {
+        attr.addCDATAAttribute("uri", loc.getURI());
+        attr.addCDATAAttribute("line", Integer.toString(loc.getLineNumber()));
+        attr.addCDATAAttribute("column", Integer.toString(loc.getColumnNumber()));        
+        simpleElement("location", attr, loc.getDescription(), handler);
+    }
+
+    private static void simpleElement(String name, Attributes attr, String value, ContentHandler handler) throws SAXException {
+        handler.startElement(EXCEPTION_NS, name, "ex:" + name, attr);
+        if (value != null && value.length() > 0) {
+            handler.characters(value.toCharArray(), 0, value.length());
+        }
+        handler.endElement(EXCEPTION_NS, name, "ex:" + name);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGenerator.java
new file mode 100644
index 0000000..c98529c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGenerator.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The <code>FileGenerator</code> is a class that reads XML from a source
+ * and generates SAX Events. The <code>FileGenerator</code> implements the
+ * <code>CacheableProcessingComponent</code> interface.
+ *
+ * <br>See {@link FileGeneratorFactory} for thread safe implementation of this
+ * component.
+ *
+ * @cocoon.sitemap.component.name   file
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.file
+ * @cocoon.sitemap.component.documentation.caching
+ *     Uses the last modification date of the xml document for validation
+ *
+ * @cocoon.sitemap.component.pooling.max  32
+ *
+ * @version $Id$
+ */
+public class FileGenerator extends ServiceableGenerator
+                           implements CacheableProcessingComponent {
+
+    /** The input source */
+    protected Source inputSource;
+
+    /**
+     * Recycle this component.
+     * All instance variables are set to <code>null</code>.
+     */
+    public void recycle() {
+        if (null != this.inputSource) {
+            super.resolver.release(this.inputSource);
+            this.inputSource = null;
+        }
+        super.recycle();
+    }
+
+    /**
+     * Setup the file generator.
+     * Try to get the last modification date of the source for caching.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, par);
+        try {
+            this.inputSource = super.resolver.resolveURI(src);
+        } catch (SourceException se) {
+            throw SourceUtil.handle("Error during resolving of '" + src + "'.", se);
+        }
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public Serializable getKey() {
+        return this.inputSource.getURI();
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        return this.inputSource.getValidity();
+    }
+
+    /**
+     * Generate XML data.
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+
+        try {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Source " + super.source +
+                                  " resolved to " + this.inputSource.getURI());
+            }
+            SourceUtil.parse(this.manager, this.inputSource, super.xmlConsumer);
+        } catch (SAXException e) {
+            SourceUtil.handleSAXException(this.inputSource.getURI(), e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGeneratorFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGeneratorFactory.java
new file mode 100644
index 0000000..9bd362d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FileGeneratorFactory.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceException;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.AbstractXMLProducer;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The <code>FileGeneratorFactory</code> is a class that reads XML from a source
+ * and generates SAX Events. The <code>FileGeneratorFactory</code> implements the
+ * <code>CacheableProcessingComponent</code> interface.
+ *
+ * @cocoon.sitemap.component.name   file
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.file
+ * @cocoon.sitemap.component.documentation.caching
+ *     Uses the last modification date of the xml document for validation
+ *
+ * @version $Id$
+ */
+public class FileGeneratorFactory extends AbstractLogEnabled
+                                  implements GeneratorFactory, Serviceable {
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Single threaded instance implementing generator functionality.
+     */
+    private class Instance extends AbstractXMLProducer
+                           implements GeneratorFactory.Instance,
+                                      CacheableProcessingComponent, Disposable {
+
+        /** The source resolver */
+        private SourceResolver resolver;
+
+        /** The input source */
+        private Source source;
+
+        /** Return GeneratorFactory */
+        public GeneratorFactory getFactory() {
+            return FileGeneratorFactory.this;
+        }
+
+        public Instance(Logger logger) {
+            enableLogging(logger);
+        }
+
+        /** Setup: resolve the source */
+        public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+        throws ProcessingException, SAXException, IOException {
+            this.resolver = resolver;
+            try {
+                this.source = this.resolver.resolveURI(src);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Source '" + src +
+                                      "' resolved to <" + this.source.getURI() + ">");
+                }
+            } catch (SourceException se) {
+                throw SourceUtil.handle("Error during resolving of '" + src + "'.", se);
+            }
+        }
+
+        /** Dispose: release the source */
+        public void dispose() {
+            if (this.source != null) {
+                this.resolver.release(this.source);
+                this.source = null;
+            }
+        }
+
+        /**
+         * Generate the unique key.
+         * This key must be unique inside the space of this component.
+         *
+         * @return The generated key hashes the src
+         */
+        public Serializable getKey() {
+            return this.source.getURI();
+        }
+
+        /**
+         * Generate the validity object.
+         *
+         * @return The generated validity object or <code>null</code> if the
+         *         component is currently not cacheable.
+         */
+        public SourceValidity getValidity() {
+            return this.source.getValidity();
+        }
+
+        /**
+         * Generate XML data.
+         */
+        public void generate()
+        throws IOException, SAXException, ProcessingException {
+            try {
+                SourceUtil.parse(manager, this.source, super.xmlConsumer);
+            } catch (SAXException e) {
+                SourceUtil.handleSAXException(this.source.getURI(), e);
+            }
+        }
+    }
+
+    public GeneratorFactory.Instance getInstance() {
+        return new Instance(getLogger());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FragmentExtractorGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FragmentExtractorGenerator.java
new file mode 100644
index 0000000..5431be2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/FragmentExtractorGenerator.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.Serializable;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.apache.excalibur.store.Store;
+
+import org.xml.sax.SAXException;
+
+/**
+ * The generation half of FragmentExtractor.
+ *
+ * FragmentExtractor is a transformer-generator pair which is designed to allow
+ * sitemap managers to extract certain nodes from a SAX stream and move them
+ * into a separate pipeline. The main use for this is to extract inline SVG
+ * images and serve them up through a separate pipeline, usually serializing
+ * them to PNG or JPEG format first.
+ *
+ * This is by no means complete yet, but it should prove useful, particularly
+ * for offline generation.
+ *
+ * @version $Id$
+ */
+public class FragmentExtractorGenerator extends ServiceableGenerator
+                                        implements CacheableProcessingComponent {
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public Serializable getKey() {
+        return this.source;
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+
+    public void generate() throws SAXException, ProcessingException {
+        // Obtain the fragmentID  (which is simply the filename portion of the source)
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Retrieving fragment " + source + ".");
+        }
+
+        Store store = null;
+        Object fragment = null;
+        try {
+            store = (Store) this.manager.lookup(Store.TRANSIENT_STORE);
+            fragment = store.get(source);
+            if (fragment == null) {
+                throw new ResourceNotFoundException("Could not find fragment " + source + " in store");
+            }
+
+            XMLByteStreamInterpreter deserializer = new XMLByteStreamInterpreter();
+            deserializer.setConsumer(this.xmlConsumer);
+            deserializer.deserialize(fragment);
+
+        } catch (ServiceException ce) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Could not lookup for component.", ce);
+            }
+            throw new SAXException("Could not lookup for component.", ce);
+        } finally {
+            this.manager.release(store);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/Generator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/Generator.java
new file mode 100644
index 0000000..016701c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/Generator.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.xml.XMLProducer;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+/**
+ * A generator is the starting point of a pipeline. It "generates" XML
+ * and starts streaming them into the pipeline.
+ * 
+ * @version $Id$
+ */
+public interface Generator extends XMLProducer, SitemapModelComponent {
+
+    String ROLE = Generator.class.getName();
+
+    /**
+     * Generate the XML and stream it into the pipeline
+     */
+    void generate()
+    throws IOException, SAXException, ProcessingException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/GeneratorFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/GeneratorFactory.java
new file mode 100644
index 0000000..9461b02
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/GeneratorFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+/**
+ * A generator factory is the factory of {@link Generator}s.
+ *
+ * <p>Regular GeneratorFactory implementation should be
+ * {@link org.apache.avalon.framework.thread.ThreadSafe} component
+ * serving as a factory of lightweight {@link Generator} objects.</p>
+ *
+ * <p>GeneratorFactory can implement any number of Avalon lifecycle interfaces
+ * and perform any initializations necessary. Ligtweight Generator instances
+ * created by {@link #getInstance()} method will only need to parse
+ * additional parameters passed on sitemap component invocation via
+ * {@link org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, String, org.apache.avalon.framework.parameters.Parameters)}
+ * method and can access global configuration of GeneratorFactory.</p>
+ *
+ * <p><strong>NOTE:</strong> Only Disposable interface is applicable to
+ * the Generator instance returned by the {@link #getInstance()}.</p>
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public interface GeneratorFactory {
+
+    String ROLE = Generator.ROLE;
+
+    /**
+     * Instance of the Generator created by the GeneratorFactory
+     */
+    interface Instance extends Generator {
+
+        /**
+         * @return GeneratorFactory which created this Generator instance
+         */
+        GeneratorFactory getFactory();
+    }
+
+    /**
+     * Create an instance of the Generator
+     */
+    Instance getInstance();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ImageDirectoryGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ImageDirectoryGenerator.java
new file mode 100644
index 0000000..a74a7c1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ImageDirectoryGenerator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.cocoon.util.FileFormatException;
+import org.apache.cocoon.util.ImageProperties;
+import org.apache.cocoon.util.ImageUtils;
+
+import org.xml.sax.SAXException;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML directory listing. This is an extension of 
+ * the <link href="directory-generator.html">Directory Generator</link> that 
+ * adds extra attributes for image files.
+ * 
+ * @cocoon.sitemap.component.name   imagedirectory
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.imagedirectory
+ * @cocoon.sitemap.component.documentation.caching
+ *               Uses the last modification date of the directory and the contained files
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ *
+ *
+ * @version $Id$
+ */
+final public class ImageDirectoryGenerator extends DirectoryGenerator {
+
+    protected static String IMAGE_WIDTH_ATTR_NAME = "width";
+    protected static String IMAGE_HEIGHT_ATTR_NAME = "height";
+    protected static String IMAGE_COMMENT_ATTR_NAME = "comment";
+
+    /**
+     * Extends the <code>setNodeAttributes</code> method from the
+     * <code>DirectoryGenerator</code> by adding width, height and comment attributes
+     * if the path is a GIF or a JPEG file.
+     */
+    protected void setNodeAttributes(File path) throws SAXException {
+        super.setNodeAttributes(path);
+        if (path.isDirectory()) {
+            return;
+        }
+        try {
+            ImageProperties p = ImageUtils.getImageProperties(path);
+            if (p != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug(String.valueOf(path) + " = " + String.valueOf(p));
+                }
+                attributes.addAttribute("", IMAGE_WIDTH_ATTR_NAME, IMAGE_WIDTH_ATTR_NAME, "CDATA", String.valueOf(p.width));
+                attributes.addAttribute("", IMAGE_HEIGHT_ATTR_NAME, IMAGE_HEIGHT_ATTR_NAME, "CDATA", String.valueOf(p.height));
+                if (p.comment != null) attributes.addAttribute("", IMAGE_COMMENT_ATTR_NAME, IMAGE_COMMENT_ATTR_NAME, "CDATA", String.valueOf(p.comment));
+            }
+        }
+        catch (FileFormatException e) {
+            throw new SAXException(e);
+        }
+        catch (FileNotFoundException e) {
+            throw new SAXException(e);
+        }
+        catch (IOException e) {
+            throw new SAXException(e);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/LinkStatusGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/LinkStatusGenerator.java
new file mode 100644
index 0000000..c7574cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/LinkStatusGenerator.java
@@ -0,0 +1,659 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.Constants;
+import org.apache.commons.lang.StringUtils;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URLConnection;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates a list of links that are reachable from the src and their status.
+ * 
+ * @cocoon.sitemap.component.name   linkstatus
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.linkstatus
+ *
+ * @version $Id$
+ */
+public class LinkStatusGenerator extends ServiceableGenerator
+                                 implements Recyclable, Configurable {
+
+    /** The URI of the namespace of this generator. */
+    protected static final String URI =
+            "http://apache.org/cocoon/linkstatus/2.0";
+
+    /** The namespace prefix for this namespace. */
+    protected static final String PREFIX = "linkstatus";
+
+    /* Node and attribute names */
+    protected static final String TOP_NODE_NAME = "linkstatus";
+    protected static final String LINK_NODE_NAME = "link";
+
+    protected static final String HREF_ATTR_NAME = "href";
+    protected static final String REFERRER_ATTR_NAME = "referrer";
+    protected static final String CONTENT_ATTR_NAME = "content";
+    protected static final String STATUS_ATTR_NAME = "status";
+    protected static final String MESSAGE_ATTR_NAME = "message";
+
+    protected AttributesImpl attributes;
+
+    /**
+     * Config element name specifying expected link content-typ.
+     * <p>
+     *   Its value is <code>link-content-type</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String LINK_CONTENT_TYPE_CONFIG = "link-content-type";
+
+    /**
+     * Default value of <code>link-content-type</code> configuration value.
+     * <p>
+     *   Its value is <code>application/x-cocoon-links</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final String LINK_CONTENT_TYPE_DEFAULT = "application/x-cocoon-links";
+
+    /**
+     * Config element name specifying query-string appendend for requesting links
+     * of an URL.
+     * <p>
+     *  Its value is <code>link-view-query</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String LINK_VIEW_QUERY_CONFIG = "link-view-query";
+    /**
+     * Default value of <code>link-view-query</code> configuration value.
+     * <p>
+     *   Its value is <code>?cocoon-view=links</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String LINK_VIEW_QUERY_DEFAULT = "cocoon-view=links";
+
+    /**
+     * Config element name specifying excluding regular expression pattern.
+     * <p>
+     *  Its value is <code>exclude</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String EXCLUDE_CONFIG = "exclude";
+
+    /**
+     * Config element name specifying including regular expression pattern.
+     * <p>
+     *  Its value is <code>include</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String INCLUDE_CONFIG = "include";
+
+    /**
+     * Config element name specifying http header value for user-Agent.
+     * <p>
+     *  Its value is <code>user-agent</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String USER_AGENT_CONFIG = "user-agent";
+    /**
+     * Default value of <code>user-agent</code> configuration value.
+     *
+     * @see org.apache.cocoon.Constants#COMPLETE_NAME
+     * @since
+     */
+    public final static String USER_AGENT_DEFAULT = Constants.COMPLETE_NAME;
+
+    /**
+     * Config element name specifying http header value for accept.
+     * <p>
+     *  Its value is <code>accept</code>.
+     * </p>
+     *
+     * @since
+     */
+    public final static String ACCEPT_CONFIG = "accept";
+    /**
+     * Default value of <code>accept</code> configuration value.
+     * <p>
+     *   Its value is <code>* / *</code>
+     * </p>
+     *
+     * @since
+     */
+    public final static String ACCEPT_DEFAULT = "*/*";
+
+    private String linkViewQuery = LINK_VIEW_QUERY_DEFAULT;
+    private String linkContentType = LINK_CONTENT_TYPE_DEFAULT;
+    private HashSet excludeCrawlingURL;
+    private HashSet includeCrawlingURL;
+    // FIXME - The following two are never read, can we delete them?
+    //private String userAgent = USER_AGENT_DEFAULT;
+    //private String accept = ACCEPT_DEFAULT;
+
+    private HashSet crawled;
+    private HashSet linksToProcess;
+
+    /**
+     * Stores links to process and the referrer links
+     */
+    private class Link {
+        private URL url;
+        private String referrer;
+
+        public Link(URL url, String referrer) {
+            this.url = url;
+            this.referrer = referrer;
+        }
+
+        public URL getURL() {
+            return url;
+        }
+
+        public String getReferrer() {
+            return referrer;
+        }
+
+        public boolean equals(Link l) {
+            return url.equals(l.getURL());
+        }
+    }
+
+    /**
+     * Configure the crawler component.
+     * <p>
+     *  Configure can specify which URI to include, and which URI to exclude
+     *  from crawling. You specify the patterns as regular expressions.
+     * </p>
+     * <p>
+     *  Morover you can configure
+     *  the required content-type of crawling request, and the
+     *  query-string appended to each crawling request.
+     * </p>
+     * <pre><tt>
+     * &lt;include&gt;.*\.html?&lt;/include&gt; or &lt;include&gt;.*\.html?, .*\.xsp&lt;/include&gt;
+     * &lt;exclude&gt;.*\.gif&lt;/exclude&gt; or &lt;exclude&gt;.*\.gif, .*\.jpe?g&lt;/exclude&gt;
+     * &lt;link-content-type&gt; application/x-cocoon-links &lt;/link-content-type&gt;
+     * &lt;link-view-query&gt; ?cocoon-view=links &lt;/link-view-query&gt;
+     * &lt;user-agent&gt; Cocoon &lt;/user-agent&gt;
+     * &lt;accept&gt; text/xml &lt;/accept&gt;
+     * </tt></pre>
+     *
+     * @param  configuration               XML configuration of this avalon component.
+     * @exception  ConfigurationException  is throwing if configuration is invalid.
+     * @since
+     */
+    public void configure(Configuration configuration)
+            throws ConfigurationException {
+
+        Configuration[] children;
+        children = configuration.getChildren(INCLUDE_CONFIG);
+        if (children.length > 0) {
+            includeCrawlingURL = new HashSet();
+            for (int i = 0; i < children.length; i++) {
+                String pattern = children[i].getValue();
+                try {
+                    String params[] = StringUtils.split(pattern, ", ");
+                    for (int index = 0; index < params.length; index++) {
+                        String tokenized_pattern = params[index];
+                        this.includeCrawlingURL.add(new RE(tokenized_pattern));
+                    }
+                } catch (RESyntaxException rese) {
+                    getLogger().error("Cannot create including regular-expression for " +
+                            pattern, rese);
+                }
+            }
+        }
+
+        children = configuration.getChildren(EXCLUDE_CONFIG);
+        if (children.length > 0) {
+            excludeCrawlingURL = new HashSet();
+            for (int i = 0; i < children.length; i++) {
+                String pattern = children[i].getValue();
+                try {
+                    String params[] = StringUtils.split(pattern, ", ");
+                    for (int index = 0; index < params.length; index++) {
+                        String tokenized_pattern = params[index];
+                        this.excludeCrawlingURL.add(new RE(tokenized_pattern));
+                    }
+                } catch (RESyntaxException rese) {
+                    getLogger().error("Cannot create excluding regular-expression for " +
+                            pattern, rese);
+                }
+            }
+        } else {
+            excludeCrawlingURL = new HashSet();
+            setDefaultExcludeFromCrawling();
+        }
+
+        Configuration child;
+        String value;
+        child = configuration.getChild(LINK_CONTENT_TYPE_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.linkContentType = value.trim();
+            }
+        }
+        child = configuration.getChild(LINK_VIEW_QUERY_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.linkViewQuery = value.trim();
+            }
+        }
+/*      FIXME: Also delete this if you delete the fields above.
+        child = configuration.getChild(USER_AGENT_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.userAgent = value;
+            }
+        }
+
+        child = configuration.getChild(ACCEPT_CONFIG, false);
+        if (child != null) {
+            value = child.getValue();
+            if (value != null && value.length() > 0) {
+                this.accept = value;
+            }
+        }
+*/
+    }
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, par);
+
+        /* Create a reusable attributes for creating nodes */
+        this.attributes = new AttributesImpl();
+
+        // already done in configure...
+        //excludeCrawlingURL = new HashSet();
+        //this.setDefaultExcludeFromCrawling();
+    }
+
+    /**
+     * Generate XML data.
+     *
+     * @throws  SAXException
+     *      if an error occurs while outputting the document
+     * @throws  ProcessingException
+     *      if the requsted URI wasn't found
+     */
+    public void generate()
+    throws SAXException, ProcessingException {
+        try {
+
+            crawled = new HashSet();
+            linksToProcess = new HashSet();
+
+            URL root = new URL(source);
+            linksToProcess.add(new Link(root, ""));
+
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("crawl URL " + root);
+            }
+
+            this.contentHandler.startDocument();
+            this.contentHandler.startPrefixMapping(PREFIX, URI);
+
+            attributes.clear();
+            super.contentHandler.startElement(URI, TOP_NODE_NAME, PREFIX + ':' + TOP_NODE_NAME, attributes);
+
+            while (linksToProcess.size() > 0) {
+                Iterator i = linksToProcess.iterator();
+
+                if (i.hasNext()) {
+                    // fetch a URL
+                    Link link = (Link) i.next();
+                    URL url = link.getURL();
+
+                    // remove it from the to-do list
+                    linksToProcess.remove(link);
+
+                    String new_url_link = processURL(url, link.getReferrer());
+
+                    // calc all links from this url
+                    if (new_url_link != null) {
+
+                        List url_links = getLinksFromConnection(new_url_link, url);
+                        if (url_links != null) {
+                            // add links of this url to the to-do list
+                            linksToProcess.addAll(url_links);
+                        }
+                    }
+                }
+            }
+
+            super.contentHandler.endElement(URI, TOP_NODE_NAME, PREFIX + ':' + TOP_NODE_NAME);
+            this.contentHandler.endPrefixMapping(PREFIX);
+            this.contentHandler.endDocument();
+        } catch (IOException ioe) {
+            getLogger().warn("Could not read source ", ioe);
+            throw new ResourceNotFoundException("Could not read source ", ioe);
+        }
+    }
+
+    /**
+     * Default exclude patterns.
+     * <p>
+     *   By default URLs matching following patterns are excluded:
+     * </p>
+     * <ul>
+     *   <li>.*\\.gif(\\?.*)?$ - exclude gif images</li>
+     *   <li>.*\\.png(\\?.*)?$ - exclude png images</li>
+     *   <li>.*\\.jpe?g(\\?.*)?$ - exclude jpeg images</li>
+     *   <li>.*\\.js(\\?.*)?$ - exclude javascript </li>
+     *   <li>.*\\.css(\\?.*)?$ - exclude cascaded stylesheets</li>
+     * </ul>
+     *
+     * @since
+     */
+    private void setDefaultExcludeFromCrawling() {
+        String[] EXCLUDE_FROM_CRAWLING_DEFAULT = {
+            ".*\\.gif(\\?.*)?$",
+            ".*\\.png(\\?.*)?$",
+            ".*\\.jpe?g(\\?.*)?$",
+            ".*\\.js(\\?.*)?$",
+            ".*\\.css(\\?.*)?$"
+        };
+
+        for (int i = 0; i < EXCLUDE_FROM_CRAWLING_DEFAULT.length; i++) {
+            String pattern = EXCLUDE_FROM_CRAWLING_DEFAULT[i];
+            try {
+                excludeCrawlingURL.add(new RE(pattern));
+            } catch (RESyntaxException rese) {
+                getLogger().error("Cannot create excluding regular-expression for " +
+                        pattern, rese);
+            }
+        }
+    }
+
+
+    /**
+     * Retrieve a list of links of a url
+     *
+     * @param url_link_string url for requesting links, it is assumed that
+     *   url_link_string queries the cocoon view links, ie of the form
+     *   <code>http://host/foo/bar?cocoon-view=links</code>
+     * @param url_of_referrer base url of which links are requested, ie of the form
+     *   <code>http://host/foo/bar</code>
+     * @return List of links from url_of_referrer, as result of requesting url
+     *   url_link_string
+     */
+    protected List getLinksFromConnection(String url_link_string, URL url_of_referrer) {
+        List url_links = null;
+        BufferedReader br = null;
+        try {
+            URL url_link = new URL(url_link_string);
+            URLConnection conn = url_link.openConnection();
+            String content_type = conn.getContentType();
+
+            if (content_type == null) {
+                getLogger().warn("No content type available for " + String.valueOf(url_link_string));
+                // caller checks if null
+                return url_links;
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Content-type: " + content_type);
+            }
+
+            if (content_type.equals(linkContentType) ||
+                content_type.startsWith(linkContentType + ";")) {
+                url_links = new ArrayList();
+
+                InputStream is = conn.getInputStream();
+                br = new BufferedReader(new InputStreamReader(is));
+
+                // content is supposed to be a list of links,
+                // relative to current URL
+                String line;
+                String referrer = url_of_referrer.toString();
+
+                while ((line = br.readLine()) != null) {
+                    URL new_url = new URL(url_link, line);
+                    boolean add_url = true;
+                    // don't add new_url twice
+                    if (add_url) {
+                        add_url &= !url_links.contains(new_url);
+                    }
+
+                    // don't add new_url if it has been crawled already
+                    if (add_url) {
+                        add_url &= !crawled.contains(new_url.toString());
+                    }
+
+                    Link new_link = new Link(new_url, referrer);
+                    if (add_url) {
+                        add_url &= !linksToProcess.contains(new_link);
+                    }
+
+                    // don't add if is not matched by existing include definition
+                    if (add_url) {
+                        add_url &= isIncludedURL(new_url.toString());
+                    }
+
+                    if (add_url) {
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Add URL: " + new_url.toString());
+                        }
+                        url_links.add(new_link);
+                    }
+                }
+                // now we have a list of URL which should be examined
+            }
+        } catch (IOException ioe) {
+            getLogger().warn("Problems get links of " + url_link_string, ioe);
+        } finally {
+            // explictly close the stream
+            if (br != null) {
+                try {
+                    br.close();
+                    br = null;
+                } catch (IOException ignored) {
+                }
+            }
+        }
+        return url_links;
+    }
+
+    /**
+     * Generate xml attributes of a url, calculate url for retrieving links
+     *
+     * @param url to process
+     * @param referrer of the url
+     * @return String url for retrieving links, or null if url is an excluded-url,
+     *   and not an included-url.
+     */
+    protected String processURL(URL url, String referrer) throws SAXException {
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("getLinks URL " + url);
+        }
+
+        String result = null;
+
+        // don't try to investigate a url which has been crawled already
+        if (crawled.contains(url.toString())) {
+            return null;
+        }
+
+        // mark it as crawled
+        crawled.add(url.toString());
+
+        attributes.clear();
+        attributes.addAttribute("", HREF_ATTR_NAME,
+                HREF_ATTR_NAME, "CDATA", url.toString());
+        attributes.addAttribute("", REFERRER_ATTR_NAME,
+                REFERRER_ATTR_NAME, "CDATA", referrer);
+
+        // Output url, referrer, content-type, status, message for traversable url's
+        HttpURLConnection h = null;
+        try {
+
+            URLConnection links_url_connection = url.openConnection();
+            h = (HttpURLConnection) links_url_connection;
+            String content_type = links_url_connection.getContentType();
+
+            attributes.addAttribute("", CONTENT_ATTR_NAME,
+                    CONTENT_ATTR_NAME, "CDATA",
+                    content_type);
+
+            attributes.addAttribute("", MESSAGE_ATTR_NAME,
+                    MESSAGE_ATTR_NAME, "CDATA",
+                    h.getResponseMessage());
+
+            attributes.addAttribute("", STATUS_ATTR_NAME,
+                    STATUS_ATTR_NAME, "CDATA",
+                    String.valueOf(h.getResponseCode()));
+        } catch (IOException ioe) {
+            attributes.addAttribute("", MESSAGE_ATTR_NAME,
+                    MESSAGE_ATTR_NAME, "CDATA",
+                    ioe.getMessage());
+        } finally {
+            if (h != null) {
+                h.disconnect();
+            }
+        }
+
+        // don't try to get links of a url which is excluded from crawling
+        // try to get links of a url which is included for crawling
+        if (!isExcludedURL(url.toString()) && isIncludedURL(url.toString())) {
+            // add prefix and query to get data from the linkserializer.
+            result = url.toExternalForm()
+                    + ((url.toExternalForm().indexOf("?") == -1) ? "?" : "&")
+                    + linkViewQuery;
+        }
+
+        super.contentHandler.startElement(URI, LINK_NODE_NAME, PREFIX + ':' + LINK_NODE_NAME, attributes);
+        super.contentHandler.endElement(URI, LINK_NODE_NAME, PREFIX + ':' + LINK_NODE_NAME);
+
+        return result;
+    }
+
+    /**
+     * check if URL is a candidate for indexing
+     *
+     * @param  url  Description of Parameter
+     * @return      The excludedURL value
+     * @since
+     */
+    private boolean isExcludedURL(String url) {
+        // by default include URL for crawling
+        if (excludeCrawlingURL == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("exclude no URL " + url);
+            }
+            return false;
+        }
+
+        final String s = url.toString();
+        Iterator i = excludeCrawlingURL.iterator();
+        while (i.hasNext()) {
+            RE pattern = (RE) i.next();
+            if (pattern.match(s)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("exclude URL " + url);
+                }
+                return true;
+            }
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("exclude not URL " + url);
+        }
+        return false;
+    }
+
+
+    /**
+     * check if URL is a candidate for indexing
+     *
+     * @param  url  Description of Parameter
+     * @return      The includedURL value
+     * @since
+     */
+    private boolean isIncludedURL(String url) {
+        // by default include URL for crawling
+        if (includeCrawlingURL == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("include all URL " + url);
+            }
+            return true;
+        }
+
+        final String s = url.toString();
+        Iterator i = includeCrawlingURL.iterator();
+        while (i.hasNext()) {
+            RE pattern = (RE) i.next();
+            if (pattern.match(s)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("include URL " + url);
+                }
+                return true;
+            }
+        }
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("include not URL " + url);
+        }
+        return false;
+    }
+
+    public void recycle() {
+        super.recycle();
+
+        this.attributes = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/MP3DirectoryGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/MP3DirectoryGenerator.java
new file mode 100644
index 0000000..6895baf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/MP3DirectoryGenerator.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * An extension of DirectoryGenerators that adds extra attributes for MP3
+ * files.
+ * 
+ * @cocoon.sitemap.component.name   mp3directory
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.mp3directory
+ * @cocoon.sitemap.component.documentation.caching
+ *               Uses the last modification date of the directory and the contained files
+ * 
+ *
+ * @version $Id$
+ */
+public class MP3DirectoryGenerator extends DirectoryGenerator
+{
+    // MP3 Constants
+    private static final int VERSION_MPEG1       = 3;
+    // private static final int VERSION_MPEG2       = 2;
+    private static final int MODE_DUAL_CHANNEL   = 2;
+    private static final int MODE_JOINT_STEREO   = 1;
+    private static final int MODE_SINGLE_CHANNEL = 3;
+    private static final int MODE_STEREO         = 0;
+    private static final int VBR_FRAMES_FLAG     = 1;
+    // private static final int VBR_BYTES_FLAG      = 2;
+    // private static final int VBR_TOC_FLAG        = 4;
+    // private static final int VBR_SCALE_FLAG      = 8;
+
+    // Attributes
+    protected static String MP3_FREQUENCY_ATTR_NAME = "frequency";
+    protected static String MP3_BITRATE_ATTR_NAME   = "bitrate";
+    protected static String MP3_MODE_ATTR_NAME      = "mode";
+    protected static String MP3_VBR_ATTR_NAME   = "variable-rate";
+
+    protected static String MP3_TITLE_ATTR_NAME   = "title";
+    protected static String MP3_ARTIST_ATTR_NAME = "artist";
+    protected static String MP3_ALBUM_ATTR_NAME   = "album";
+    protected static String MP3_YEAR_ATTR_NAME    = "year";
+    protected static String MP3_COMMENT_ATTR_NAME = "comment";
+    protected static String MP3_TRACK_ATTR_NAME   = "track";
+    protected static String MP3_GENRE_ATTR_NAME   = "genre";
+
+    /**
+     * Extends the <code>setNodeAttributes</code> method from the
+     * <code>DirectoryGenerator</code> by adding MP3 tag attributes
+     * if the path is a MP3 file with valid tag.
+     */
+    protected void setNodeAttributes(File path) throws SAXException {
+        super.setNodeAttributes(path);
+        if (path.isDirectory()) {
+            return;
+        }
+
+        RandomAccessFile in = null;
+        try {
+            in = new RandomAccessFile(path, "r");
+            setID3HeaderAttributes(in);
+            setID3TagAttributes(in);
+        } catch (IOException e) {
+            getLogger().debug("Could not set attributes for " + path, e);
+        } finally {
+            if(in != null) try{ in.close(); }catch(IOException ignored){}
+        }
+    }
+
+    /**
+     * Read ID3 Tag
+     */
+    private void setID3TagAttributes(RandomAccessFile in) throws IOException  {
+        String s;
+
+        // TAG takes 128 bytes
+        if (in.length() < 128) return;
+        in.seek(in.length() - 128);
+        byte [] buf = new byte[128];
+        // Read TAG
+        if (in.read(buf,0, 128) != 128) return;
+        // Check TAG presence
+        if(buf[0] != 'T' || buf[1] != 'A' || buf[2] != 'G') return;
+
+        s = getID3TagValue(buf, 3, 30);
+        if(s.length() > 0)
+            attributes.addAttribute("", MP3_TITLE_ATTR_NAME, MP3_TITLE_ATTR_NAME, "CDATA", s);
+        s = getID3TagValue(buf, 33,30);
+        if(s.length() > 0)
+            attributes.addAttribute("", MP3_ARTIST_ATTR_NAME, MP3_ARTIST_ATTR_NAME, "CDATA", s);
+        s = getID3TagValue(buf, 63,30);
+        if(s.length() > 0)
+            attributes.addAttribute("", MP3_ALBUM_ATTR_NAME, MP3_ALBUM_ATTR_NAME, "CDATA", s);
+        s = getID3TagValue(buf, 93, 4);
+        if(s.length() > 0)
+            attributes.addAttribute("", MP3_YEAR_ATTR_NAME, MP3_YEAR_ATTR_NAME, "CDATA", s);
+        s = getID3TagValue(buf, 97,29);
+        if(s.length() > 0)
+            attributes.addAttribute("", MP3_COMMENT_ATTR_NAME, MP3_COMMENT_ATTR_NAME, "CDATA", s);
+        if(buf[126] > 0)
+            attributes.addAttribute("", MP3_TRACK_ATTR_NAME, MP3_TRACK_ATTR_NAME, "CDATA",
+                Byte.toString(buf[126]));
+        if(buf[127] > 0)
+            attributes.addAttribute("", MP3_GENRE_ATTR_NAME, MP3_GENRE_ATTR_NAME, "CDATA",
+                Byte.toString(buf[127]));
+    }
+
+    private String getID3TagValue(byte[] buf, int offset, int length) {
+        String s = new String(buf, offset, length);
+        int index = s.indexOf(0x00);
+        if (index != -1) {
+            s = s.substring(0, index);
+        }
+        return s.trim();
+    }
+
+    private void setID3HeaderAttributes(RandomAccessFile in) throws IOException {
+        byte[] buffer = new byte[4];
+
+        // http://floach.pimpin.net/grd/mp3info/frmheader/index.html
+        if (in.read(buffer, 0, 3) != 3) {
+            return;
+        }
+        int header = ((buffer[0] << 16) & 0x00FF0000) | ((buffer[1] << 8) & 0x0000FF00) | ((buffer[2] << 0) & 0x000000FF);
+        do {
+            header <<= 8;
+            if (in.read(buffer, 3, 1) != 1) {
+                return;
+            }
+            header |= (buffer[3] & 0x000000FF);
+        } while (!isSyncMark(header));
+
+        int version = (header >>> 19) & 3;
+        int layer = 4 - (header >>> 17) & 3;
+        // int protection = (header >>> 16) & 1;
+        int bitrate = (header >>> 12) & 0xF;
+        int frequency = (header >>> 10) & 3;
+        // Value 3 is reserved
+        if (frequency == 3) {
+            return;
+        }
+        // int padding = (header >>> 9) & 1;
+        int mode = ((header >>> 6) & 3);
+
+        attributes.addAttribute("", MP3_FREQUENCY_ATTR_NAME, MP3_FREQUENCY_ATTR_NAME, "CDATA",
+            frequencyString(version, frequency));
+        attributes.addAttribute("", MP3_MODE_ATTR_NAME, MP3_MODE_ATTR_NAME, "CDATA",
+            mode(mode));
+
+        int frames = getVBRHeaderFrames(in, version, mode);
+        if (frames != -1) {
+            // get average frame size by deviding fileSize by the number of frames
+            float medFrameSize = (float)in.length() / frames;
+            // This does not work properly: (version == VERSION_MPEG1? 12000.0:144000.0)
+            bitrate = (int)(medFrameSize * frequency(version, frequency) / 144000.0);
+            attributes.addAttribute("", MP3_BITRATE_ATTR_NAME, MP3_BITRATE_ATTR_NAME, "CDATA",
+                Integer.toString(bitrate));
+        } else {
+            attributes.addAttribute("", MP3_BITRATE_ATTR_NAME, MP3_BITRATE_ATTR_NAME, "CDATA",
+                bitrate(version, layer, bitrate));
+        }
+    }
+
+    private static boolean isSyncMark(int header) {
+        boolean sync = ((header & 0xFFF00000) == 0xFFF00000);
+        // filter out invalid sample rate
+        if (sync) sync = ((header >>> 10) & 3) != 3;
+        // filter out invalid layer
+        if (sync) sync = ((header >>> 17) & 3) != 0;
+        // filter out invalid version
+        if (sync) sync = ((header >>> 19) & 3) != 1;
+        return sync;
+    }
+
+    private int getVBRHeaderFrames(RandomAccessFile in, int version, int mode) throws IOException {
+        byte[] buffer = new byte[12];
+
+        // Try to detect VBR header
+        int skip;
+        if (version == VERSION_MPEG1) {
+            if (mode == MODE_SINGLE_CHANNEL) skip = 17;
+            else skip = 32;
+        } else { // mpeg version 2 or 2.5
+            if (mode == MODE_SINGLE_CHANNEL) skip = 9;
+            else skip = 17;
+        }
+        while (skip > 0) {
+            if (in.read() == -1) return -1;
+            skip --;
+        }
+
+        if (in.read(buffer, 0, 12) != 12) {
+            return -1;
+        }
+        if (buffer[0] != 'X' || buffer[1] != 'i' || buffer[2] != 'n' || buffer[3] != 'g'){
+            return -1;
+        }
+
+        attributes.addAttribute("", MP3_VBR_ATTR_NAME, MP3_VBR_ATTR_NAME, "CDATA",
+            "yes");
+
+        int flags =
+            ((buffer[4] & 0xFF) << 24) |
+            ((buffer[5] & 0xFF) << 16) |
+            ((buffer[6] & 0xFF) <<  8) |
+             (buffer[7] & 0xFF);
+
+        if ((flags & VBR_FRAMES_FLAG) == VBR_FRAMES_FLAG){
+            int frames =
+                ((buffer[ 8] & 0xFF) << 24) |
+                ((buffer[ 9] & 0xFF) << 16) |
+                ((buffer[10] & 0xFF) <<  8) |
+                 (buffer[11] & 0xFF);
+            return frames;
+        } else {
+            return -1;
+        }
+    }
+
+    // version - layer - bitrate index
+    private static final String bitrates[][][] = {
+    {
+        // MPEG2 - layer 1
+        {"free format", "32", "48", "56", "64", "80", "96", "112", "128", "144", "160", "176", "192", "224", "256", "forbidden"},
+        // MPEG2 - layer 2
+        {"free format", "8", "16", "24", "32", "40", "48", "56", "64", "80", "96", "112", "128", "144", "160", "forbidden"},
+        // MPEG2 - layer 3
+        {"free format", "8", "16", "24", "32", "40", "48", "56", "64", "80", "96", "112", "128", "144", "160", "forbidden"}
+      },
+      {
+        // MPEG1 - layer 1
+        {"free format", "32", "64", "96", "128", "160", "192", "224", "256", "288", "320", "352", "384", "416", "448", "forbidden"},
+        // MPEG1 - layer 2
+        {"free format", "32", "48", "56", "64", "80", "96", "112", "128", "160", "192", "224", "256", "320", "384", "forbidden"},
+        // MPEG1 - layer 3
+        {"free format", "32", "40", "48", "56", "64", "80" , "96", "112", "128", "160", "192", "224", "256", "320", "forbidden"}
+      }
+    };
+
+    private static String bitrate(int version, int layer, int bitrate_index) {
+        return bitrates[version & 1][layer - 1][bitrate_index];
+    }
+
+    private static String mode(int mode) {
+        switch(mode)
+        {
+        case MODE_STEREO:
+            return "Stereo";
+        case MODE_JOINT_STEREO:
+            return "Joint stereo";
+        case MODE_DUAL_CHANNEL:
+            return "Dual channel";
+        case MODE_SINGLE_CHANNEL:
+            return "Single channel";
+        }
+        return null;
+    }
+
+    private static final int frequencies[][] = {
+        {32000, 16000,  8000}, //MPEG 2.5
+        {    0,     0,     0}, //reserved
+        {22050, 24000, 16000}, //MPEG 2
+        {44100, 48000, 32000}  //MPEG 1
+    };
+
+    private static int frequency(int version, int frequency) {
+        return frequencies[version][frequency];
+    }
+
+    private static String frequencyString(int version, int frequency) {
+        return String.valueOf((float)frequency(version, frequency)/1000);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestGenerator.java
new file mode 100644
index 0000000..05bd844
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestGenerator.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.http.RequestEncodingException;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML representation of the incoming request.
+ * 
+ * @cocoon.sitemap.component.name   request
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.request
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ * 
+ * <p>
+ * <b>Configuration options:</b>
+ * <dl>
+ * <dt> <i>container-encoding</i> (optional)
+ * <dd> The encoding used by container. Default value is ISO-8859-1.
+ * <dt> <i>form-encoding</i> (optional)
+ * <dd> The supposed encoding of the request parameter. Default is null.
+ * <dt> <i>generate-attributes</i> (optional)
+ * <dd> If true, request attributes were also included. Default is false.
+ * </dl>
+ * These configuration options are supported at both declaration and use time.
+ * The configuration at use time takes priority over declaration time.
+ *
+ * @version $Id$
+ */
+public class RequestGenerator extends ServiceableGenerator implements Parameterizable {
+
+    /** The namespace prefix of this generator. */
+    private final static String PREFIX = "h";
+    /** The namespace URI of this generator. */
+    private final static String URI = "http://apache.org/cocoon/request/2.0";
+
+    /** The configured container encoding at declaration time. */
+    private String global_container_encoding;
+    /** The configured container encoding at use time. */
+    private String container_encoding;
+
+    /** The configured form encoding at declaration time. */
+    private String global_form_encoding;
+    /** The configured form encoding at use time. */
+    private String form_encoding;
+
+    /** The configuration for including request attributes at declaration time. */
+    private boolean global_generate_attributes;
+    /** The configuration for including request attributes at use time. */
+    private boolean generate_attributes;
+
+    public void parameterize(Parameters parameters)
+    throws ParameterException {
+        global_container_encoding = parameters.getParameter("container-encoding", "ISO-8859-1");
+        global_form_encoding = parameters.getParameter("form-encoding", null);
+        global_generate_attributes = parameters.getParameterAsBoolean("generate-attributes", false);
+    }
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, parameters);
+        container_encoding = parameters.getParameter("container-encoding", global_container_encoding);
+        form_encoding = parameters.getParameter("form-encoding", global_form_encoding);
+        generate_attributes = parameters.getParameterAsBoolean("generate-attributes", global_generate_attributes);
+    }
+
+    /**
+     * Generate XML data.
+     */
+    public void generate()
+    throws SAXException {
+        final Request request = ObjectModelHelper.getRequest(objectModel);
+        final AttributesImpl attr = new AttributesImpl();
+
+        this.contentHandler.startDocument();
+        this.contentHandler.startPrefixMapping(PREFIX, URI);
+
+        attribute(attr, "target", request.getRequestURI());
+        attribute(attr, "sitemap", request.getSitemapURI());
+        attribute(attr, "source", (this.source != null ? this.source : ""));
+        start("request", attr);
+
+        start("requestHeaders", attr);
+        Enumeration headers = request.getHeaderNames();
+        if ( headers != null ) {
+            while (headers.hasMoreElements()) {
+                String header = (String)headers.nextElement();
+                attribute(attr, "name", header);
+                start("header", attr);
+                data(request.getHeader(header));
+                end("header");
+            }
+        }
+        end("requestHeaders");
+
+        start("requestParameters", attr);
+        Enumeration parameters = request.getParameterNames();
+        while (parameters.hasMoreElements()) {
+            String parameter = (String)parameters.nextElement();
+            attribute(attr, "name", parameter);
+            start("parameter", attr);
+            String values[] = request.getParameterValues(parameter);
+            if (values != null) {
+                for (int x = 0; x < values.length; x++) {
+                    start("value", attr);
+                    if (form_encoding != null) {
+                        try {
+                            data(values[x], container_encoding, form_encoding);
+                        } catch (UnsupportedEncodingException uee) {
+                            throw new RequestEncodingException("The suggested encoding is not supported.", uee);
+                        }
+                    } else if (parameter.startsWith("xml:")) {
+                        parse(values[x]);
+                    } else {
+                        data(values[x]);
+                    }
+                    end("value");
+                }
+            }
+            end("parameter");
+        }
+        end("requestParameters");
+
+        if (generate_attributes) {
+            start("requestAttributes", attr);
+            Enumeration attributes = request.getAttributeNames();
+            while (attributes.hasMoreElements()) {
+                String attribute = (String)attributes.nextElement();
+                attribute(attr, "name", attribute);
+                start("attribute", attr);
+                Object value = request.getAttribute(attribute);
+                if (value != null) {
+                    start("value", attr);
+                    XMLUtils.valueOf(this.contentHandler, value);
+                    end("value");
+                }
+                end("attribute");
+            }
+            end("requestAttributes");
+        }
+
+        this.start("configurationParameters", attr);
+        String[] confparams = super.parameters.getNames();
+        for (int i = 0; i < confparams.length; i++) {
+            attribute(attr, "name", confparams[i]);
+            start("parameter", attr);
+            data(super.parameters.getParameter(confparams[i], ""));
+            end("parameter");
+        }
+        end("configurationParameters");
+
+        end("request");
+
+        this.contentHandler.endPrefixMapping(PREFIX);
+        this.contentHandler.endDocument();
+    }
+
+    private void attribute(AttributesImpl attr, String name, String value) {
+        attr.addAttribute("", name, name, "CDATA", value);
+    }
+
+    private void start(String name, AttributesImpl attr)
+    throws SAXException {
+        super.contentHandler.startElement(URI, name, PREFIX + ":" + name, attr);
+        attr.clear();
+    }
+
+    private void end(String name)
+    throws SAXException {
+        super.contentHandler.endElement(URI, name, PREFIX + ":" + name);
+    }
+
+    private void data(String data)
+    throws SAXException {
+        super.contentHandler.characters(data.toCharArray(), 0, data.length());
+    }
+    
+    private void data(String data, String container_encoding, String form_encoding) 
+    throws SAXException, UnsupportedEncodingException {
+        this.data(new String(data.getBytes(container_encoding), form_encoding));
+    }
+    
+    private void parse(String data)
+    throws SAXException {
+        SAXParser parser = null;
+        try {
+            parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+            InputSource is = new InputSource(new StringReader(data));
+            parser.parse(is, new IncludeXMLConsumer(super.xmlConsumer));
+	} catch (SAXException se) {
+	    // rethrow sax exceptions
+	    throw se;
+	} catch (Exception e) {
+	    // wrap all others
+	    throw new RequestParseException("Could not parse the parameters.", e);
+        } finally {
+            manager.release(parser);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestParseException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestParseException.java
new file mode 100644
index 0000000..61403f2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/RequestParseException.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright 1999-2005 The Apache Software Foundation.

+ *

+ * Licensed 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.cocoon.generation;

+

+import org.xml.sax.SAXException;

+

+public final class RequestParseException extends SAXException

+{

+    public RequestParseException(String message)

+    {

+        super(message, null);

+    }

+

+    public RequestParseException(String message, Exception cause)

+    {

+        super(message, cause);

+    }

+}

diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServiceableGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServiceableGenerator.java
new file mode 100644
index 0000000..a0177c8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServiceableGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * A default implementation that can be used for writing own generators.
+ *  
+ * @version $Id$
+ * @since 2.1.1
+ */
+public abstract class ServiceableGenerator extends AbstractGenerator
+implements Serviceable, Disposable {
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Release all resources.
+     */
+    public void dispose() {
+        this.manager = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServletGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServletGenerator.java
new file mode 100644
index 0000000..3cfce8b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/ServletGenerator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public abstract class ServletGenerator extends AbstractGenerator
+implements Serviceable, Disposable {
+
+    protected Request request;
+    protected Response response;
+    protected Context context;
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.manager = null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, par);
+        this.request = ObjectModelHelper.getRequest(objectModel);
+        this.response = ObjectModelHelper.getResponse(objectModel);
+        this.context = ObjectModelHelper.getContext(objectModel);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        super.recycle();
+        this.request = null;
+        this.response = null;
+        this.context = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/SessionAttributeGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/SessionAttributeGenerator.java
new file mode 100644
index 0000000..c421f54
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/SessionAttributeGenerator.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates a document from a session attribute.
+ *
+ * @cocoon.sitemap.component.name   sessionattribute
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.sessionattribute
+ *
+ * Generates a document from a session attribute. The attribute may be a DOM
+ * node, an <code>XMLizable</code>, or any other object, and is streamed using
+ * the same rules as for &lt;xsp:expr&gt; in XSPs (see {@link
+ * org.apache.cocoon.components.language.markup.xsp.XSPObjectHelper}).
+ * <p>
+ * Name of the session attribute is specified using src attribute of the generate
+ * tag, or, if no src tag present, using attr-name parameter.
+ * <p>
+ * This generator has 2 parameters:
+ * <ul>
+ * <li><code>attr-name</code> : the session attribute name (mandatory if no src
+ *     attribute specified).
+ * </li>
+ * <li><code>root-element</code> (optional) : the name of the root element of the
+ *     produced document. This parameter is optional if the session attribute is
+ *     a DOM or an <code>XMLizable</code>.
+ * </li>
+ * </ul>
+ * <p>
+ * Example usage :
+ * <pre>
+ *   &lt;map:generator name="session-attr" logger="sitemap.generator.session-attr"
+ *     src="org.apache.cocoon.generation.SessionAttributeGenerator"/&gt;
+ *   ...
+ *   &lt;map:generate type="session-attr"&gt;
+ *     &lt;map:parameter name="attr-name" value="myAttribute"/&gt;
+ *     &lt;map:parameter name="root-element" value="root"/&gt;
+ *   &lt;/map:generate&gt;
+ * </pre>
+ *
+ * @see org.apache.cocoon.transformation.ReadDOMSessionTransformer
+ * @see org.apache.cocoon.transformation.WriteDOMSessionTransformer
+ * @version $Id$
+ */
+public class SessionAttributeGenerator extends AbstractGenerator {
+
+    public static final String ATTR_NAME = "attr-name";
+    public static final String ELEMENT_NAME = "root-element";
+
+    /** The object to generate */
+    private Object attrObject;
+
+    /** The element name */
+    private String elementName;
+
+    /**
+     * Setup the file generator :try to retrieve the session attribute given as sitemap parameter
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+      throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, par);
+
+        // Get the element name (can be null if the object is a DOM or an XMLizable)
+        this.elementName = par.getParameter(ELEMENT_NAME, null);
+
+        // Get the attribute name
+        String attrName = par.getParameter(ATTR_NAME, src);
+        if (attrName == null) {
+            String msg = "SessionAttributeGenerator needs an attribute name !";
+            getLogger().error(msg);
+            throw new ProcessingException(msg);
+        }
+
+        // Get the object to stream
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Session session = request.getSession(false);
+        if (session != null) {
+            this.attrObject = session.getAttribute(attrName);
+        }
+
+        // Controls
+        if (this.attrObject == null) {
+            if (this.elementName == null) {
+                // Can't generate nothing...
+                String msg = "Session attribute '" + attrName + "' doesn't exist";
+                getLogger().error(msg);
+                throw new ProcessingException(msg);
+            } else {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Session attribute '" + attrName +
+                        "' doesn't exist : will generate a single '" + this.elementName +
+                        "' element.");
+                }
+            }
+        } else {
+            // Need an element name for non-xml objects
+            if (this.elementName == null &&
+                ! (this.attrObject instanceof XMLizable) &&
+                ! (this.attrObject instanceof Node)) {
+
+                String msg = "Session attribute '" + attrName + "' needs an enclosing element : class is " +
+                    this.attrObject.getClass().getName();
+
+                getLogger().warn(msg);
+                throw new ProcessingException(msg);
+            }
+        }
+    }
+
+    /**
+     * Generate XML data
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+        xmlConsumer.startDocument();
+
+        if (this.elementName != null) {
+            xmlConsumer.startElement("", this.elementName, this.elementName, XMLUtils.EMPTY_ATTRIBUTES);
+            XMLUtils.valueOf(new IncludeXMLConsumer(xmlConsumer), this.attrObject);
+            xmlConsumer.endElement("", this.elementName, this.elementName);
+        } else {
+            XMLUtils.valueOf(new IncludeXMLConsumer(xmlConsumer), this.attrObject);
+        }
+
+        xmlConsumer.endDocument();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StatusGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StatusGenerator.java
new file mode 100644
index 0000000..debbf22
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StatusGenerator.java
@@ -0,0 +1,682 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.flow.ContinuationsManager;
+import org.apache.cocoon.components.flow.WebContinuationDataBean;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.Settings;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.SystemUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.store.StoreJanitor;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML representation of the current status of Cocoon.
+ *
+ * @cocoon.sitemap.component.name   status
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.status
+ *
+ * @cocoon.sitemap.component.pooling.max  16
+ *
+ * Potted DTD:
+ *
+ * <code>
+ * &lt;!ELEMENT statusinfo (group|value)*&gt;
+ *
+ * &lt;!ATTLIST statusinfo
+ *     date CDATA #IMPLIED
+ *     host CDATA #IMPLIED
+ *     cocoon-version CDATA #IMPLIED
+ * &gt;
+ *
+ * &lt;!ELEMENT group (group|value)*&gt;
+ * &lt;!ATTLIST group
+ *     name CDATA #IMPLIED
+ * &gt;
+ *
+ * &lt;!ELEMENT value (line)+&gt;
+ * &lt;!ATTLIST value
+ *     name CDATA #REQUIRED
+ *
+ * &lt;!ELEMENT line (#PCDATA)+&gt;
+ * &gt;
+ * </code>
+ *
+ * @version $Id$
+ */
+public class StatusGenerator extends ServiceableGenerator
+                             implements Contextualizable, Configurable {
+
+    /**
+     * The XML namespace for the output document.
+     */
+    public static final String NAMESPACE = "http://apache.org/cocoon/status/2.0";
+
+    /**
+     * The XML namespace for xlink
+     */
+    protected static final String XLINK_NS = "http://www.w3.org/1999/xlink";
+
+    /**
+     * The namespace prefix for xlink namespace
+     */
+    protected static final String XLINK_PREFIX = "xlink";
+
+    /**
+     * The component context.
+     */
+    protected Context context;
+
+    /**
+     * The Cocoon core.
+     */
+    protected Core core;
+
+    /**
+     * The StoreJanitor used to get cache statistics
+     */
+    protected StoreJanitor storeJanitor;
+
+    /**
+     * The persistent store
+     */
+    protected Store storePersistent;
+
+    /**
+     * Show continuations information
+     */
+    private boolean showContinuations;
+
+    /**
+     * The ContinuationManager
+     */
+    private ContinuationsManager continuationsManager;
+
+    /**
+     * List & show the contents of WEB/lib
+     */
+    private boolean showLibrary;
+
+    /**
+     * WEB-INF/lib directory
+     */
+    private Source libDirectory;
+
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    public void configure(Configuration configuration) throws ConfigurationException {
+        this.showContinuations = configuration.getChild("show-continuations").getValueAsBoolean(true);
+        this.showLibrary = configuration.getChild("show-libraries").getValueAsBoolean(true);
+    }
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     * Need to get statistics about cache hits
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.core = (Core) this.manager.lookup(Core.ROLE);
+
+        if (this.manager.hasService(StoreJanitor.ROLE)) {
+            this.storeJanitor = (StoreJanitor) manager.lookup(StoreJanitor.ROLE);
+        } else {
+            getLogger().info("StoreJanitor is not available. Sorry, no cache statistics");
+        }
+
+        if (this.manager.hasService(Store.PERSISTENT_STORE)) {
+            this.storePersistent = (Store) this.manager.lookup(Store.PERSISTENT_STORE);
+        } else {
+            getLogger().info("Persistent Store is not available. Sorry no cache statistics about it.");
+        }
+
+        if(this.manager.hasService(ContinuationsManager.ROLE)) {
+            continuationsManager = (ContinuationsManager) this.manager.lookup(ContinuationsManager.ROLE);
+        } else {
+            getLogger().info("ContinuationsManager is not available. Sorry no overview of created continuations");
+        }
+    }
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        if (this.showLibrary) {
+            try {
+                this.libDirectory = super.resolver.resolveURI("context://WEB-INF/lib");
+            } catch (SourceException e) {
+                throw SourceUtil.handle(e);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            this.manager.release(this.core);
+            this.manager.release(this.storePersistent);
+            this.manager.release(this.storeJanitor);
+            this.manager.release(this.continuationsManager);
+            this.core = null;
+            this.storePersistent = null;
+            this.storeJanitor = null;
+            this.continuationsManager = null;
+        }
+
+        if (this.libDirectory != null) {
+            super.resolver.release(this.libDirectory);
+            this.libDirectory = null;
+        }
+
+        super.dispose();
+    }
+
+    /**
+     * Generate the status information in XML format.
+     * @throws SAXException
+     *         when there is a problem creating the output SAX events.
+     */
+    public void generate() throws SAXException, ProcessingException {
+
+        // Start the document and set the namespace.
+        super.contentHandler.startDocument();
+        super.contentHandler.startPrefixMapping("", NAMESPACE);
+        super.contentHandler.startPrefixMapping(XLINK_PREFIX, XLINK_NS);
+
+        genStatus();
+
+        // End the document.
+        super.contentHandler.endPrefixMapping(XLINK_PREFIX);
+        super.contentHandler.endPrefixMapping("");
+        super.contentHandler.endDocument();
+    }
+
+    /**
+     * Generate the main status document.
+     */
+    private void genStatus() throws SAXException, ProcessingException {
+        // Root element.
+
+        // The current date and time.
+        String dateTime = DateFormat.getDateTimeInstance().format(new Date());
+        String localHost;
+
+        // The local host.
+        try {
+            localHost = InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+            getLogger().debug("StatusGenerator:UnknownHost", e);
+            localHost = "";
+        } catch (SecurityException e) {
+            getLogger().debug("StatusGenerator:Security", e);
+            localHost = "";
+        }
+
+        AttributesImpl atts = new AttributesImpl();
+        atts.addCDATAAttribute(NAMESPACE, "date", dateTime);
+        atts.addCDATAAttribute(NAMESPACE, "host", localHost);
+        atts.addCDATAAttribute(NAMESPACE, "cocoon-version", Constants.VERSION);
+        dateTime = DateFormat.getDateTimeInstance().format(new Date(this.core.getSettings().getCreationTime()));
+        atts.addCDATAAttribute(NAMESPACE, "creation-time", dateTime);
+        atts.addCDATAAttribute(NAMESPACE, "build-info", Constants.BUILD_INFO);
+        super.contentHandler.startElement(NAMESPACE, "statusinfo", "statusinfo", atts);
+
+        if (this.showContinuations) {
+            genContinuationsTree();
+        }
+        genSettings();
+        genVMStatus();
+        genProperties();
+        if (this.showLibrary) {
+            genLibrarylist();
+        }
+
+        // End root element.
+        super.contentHandler.endElement(NAMESPACE, "statusinfo", "statusinfo");
+    }
+
+    private void genContinuationsTree() throws SAXException {
+        startGroup("Continuations");
+        List continuationsAsDataBeansList = this.continuationsManager.getWebContinuationsDataBeanList();
+        for (Iterator i = continuationsAsDataBeansList.iterator(); i.hasNext();) {
+            displayContinuation((WebContinuationDataBean) i.next());
+        }
+        endGroup();
+    }
+
+    private void displayContinuation(WebContinuationDataBean wc) throws SAXException {
+        AttributesImpl ai = new AttributesImpl();
+        ai.addAttribute(NAMESPACE, "id", "id", "CDATA", wc.getId());
+        ai.addAttribute(NAMESPACE, "interpreter", "interpreter", "CDATA", wc.getInterpreterId());
+        ai.addAttribute(NAMESPACE, "expire-time", "expire-time", "CDATA", wc.getExpireTime());
+        ai.addAttribute(NAMESPACE, "time-to-live", "time-to-live", "CDATA", wc.getTimeToLive());
+        ai.addAttribute(NAMESPACE, "last-access-time", "last-access-time", "CDATA", wc.getLastAccessTime());
+
+        super.contentHandler.startElement(NAMESPACE, "cont", "cont", ai);
+        List children = wc.get_children();
+        for (int i = 0; i < children.size(); i++) {
+            displayContinuation((WebContinuationDataBean) children.get(i));
+        }
+        super.contentHandler.endElement(NAMESPACE, "cont", "cont");
+    }
+
+    private void genVMStatus() throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+        startGroup("VM");
+
+        // BEGIN ClassPath
+        String classpath = SystemUtils.JAVA_CLASS_PATH;
+        if (classpath != null) {
+            List paths = new ArrayList();
+            StringTokenizer tokenizer = new StringTokenizer(classpath, SystemUtils.PATH_SEPARATOR);
+            while (tokenizer.hasMoreTokens()) {
+                paths.add(tokenizer.nextToken());
+            }
+            addMultilineValue("classpath", paths);
+        }
+        // END ClassPath
+
+        // BEGIN CONTEXT CLASSPATH
+        String contextClassPath = null;
+        try {
+            contextClassPath = (String) this.context.get(Constants.CONTEXT_CLASSPATH);
+        } catch (ContextException e) {
+            // we ignore this
+        }
+        if (contextClassPath != null) {
+            List paths = new ArrayList();
+            StringTokenizer tokenizer = new StringTokenizer(contextClassPath, File.pathSeparator);
+            while (tokenizer.hasMoreTokens()) {
+                paths.add(tokenizer.nextToken());
+            }
+            addMultilineValue("context-classpath", paths);
+        }
+        // END CONTEXT CLASSPATH
+
+        // BEGIN Memory status
+        startGroup("Memory");
+        final long totalMemory = Runtime.getRuntime().totalMemory();
+        final long freeMemory = Runtime.getRuntime().freeMemory();
+        addValue("total", String.valueOf(totalMemory));
+        addValue("used", String.valueOf(totalMemory - freeMemory));
+        addValue("free", String.valueOf(freeMemory));
+        endGroup();
+        // END Memory status
+
+        // BEGIN JRE
+        startGroup("JRE");
+        addValue("version", SystemUtils.JAVA_VERSION);
+        atts.clear();
+        // qName = prefix + ':' + localName
+        atts.addAttribute(XLINK_NS, "type", XLINK_PREFIX + ":type", "CDATA", "simple");
+        atts.addAttribute(XLINK_NS, "href", XLINK_PREFIX + ":href", "CDATA", SystemUtils.JAVA_VENDOR_URL);
+        addValue("java-vendor", SystemUtils.JAVA_VENDOR, atts);
+        endGroup();
+        // END JRE
+
+        // BEGIN Operating system
+        startGroup("Operating System");
+        addValue("name", SystemUtils.OS_NAME);
+        addValue("architecture", SystemUtils.OS_ARCH);
+        addValue("version", SystemUtils.OS_VERSION);
+        endGroup();
+        // END operating system
+
+        // BEGIN Cache
+        if (this.storeJanitor != null) {
+            startGroup("Store Janitor");
+
+            // For each element in StoreJanitor
+            Iterator i = this.storeJanitor.iterator();
+            while (i.hasNext()) {
+                Store store = (Store) i.next();
+                startGroup(store.getClass().getName() + " (hash = 0x" + Integer.toHexString(store.hashCode()) + ")" );
+                int size = 0;
+                int empty = 0;
+                atts.clear();
+                atts.addAttribute(NAMESPACE, "name", "name", "CDATA", "cached");
+                super.contentHandler.startElement(NAMESPACE, "value", "value", atts);
+
+                atts.clear();
+                Enumeration e = store.keys();
+                while (e.hasMoreElements()) {
+                    size++;
+                    Object key = e.nextElement();
+                    Object val = store.get(key);
+                    String line;
+                    if (val == null) {
+                        empty++;
+                    } else {
+                        line = key + " (class: " + val.getClass().getName() + ")";
+                        super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
+                        super.contentHandler.characters(line.toCharArray(), 0, line.length());
+                        super.contentHandler.endElement(NAMESPACE, "line", "line");
+                    }
+                }
+                if (size == 0) {
+                    super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
+                    String value = "[empty]";
+                    super.contentHandler.characters(value.toCharArray(), 0, value.length());
+                    super.contentHandler.endElement(NAMESPACE, "line", "line");
+                }
+                super.contentHandler.endElement(NAMESPACE, "value", "value");
+
+                addValue("size", String.valueOf(size) + " items in cache (" + empty + " are empty)");
+                endGroup();
+            }
+            endGroup();
+        }
+
+        if (this.storePersistent != null) {
+            startGroup(storePersistent.getClass().getName() + " (hash = 0x" + Integer.toHexString(storePersistent.hashCode()) + ")");
+            int size = 0;
+            int empty = 0;
+            atts.clear();
+            atts.addAttribute(NAMESPACE, "name", "name", "CDATA", "cached");
+            super.contentHandler.startElement(NAMESPACE, "value", "value", atts);
+
+            atts.clear();
+            Enumeration e = this.storePersistent.keys();
+            while (e.hasMoreElements()) {
+                size++;
+                Object key = e.nextElement();
+                Object val = storePersistent.get(key);
+                String line;
+                if (val == null) {
+                    empty++;
+                } else {
+                    line = key + " (class: " + val.getClass().getName() + ")";
+                    super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
+                    super.contentHandler.characters(line.toCharArray(), 0, line.length());
+                    super.contentHandler.endElement(NAMESPACE, "line", "line");
+                }
+            }
+            if (size == 0) {
+                super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
+                String value = "[empty]";
+                super.contentHandler.characters(value.toCharArray(), 0, value.length());
+                super.contentHandler.endElement(NAMESPACE, "line", "line");
+            }
+            super.contentHandler.endElement(NAMESPACE, "value", "value");
+
+            addValue("size", size + " items in cache (" + empty + " are empty)");
+            endGroup();
+        }
+        // END Cache
+
+        endGroup();
+    }
+
+    private void genSettings() throws SAXException {
+        final Settings s = core.getSettings();
+        this.startGroup("Base Settings");
+
+        this.addValue("Running mode", s.getProperty(Settings.PROPERTY_RUNNING_MODE,
+                                                    Settings.DEFAULT_RUNNING_MODE));
+        this.addValue(Settings.KEY_CONFIGURATION, s.getConfiguration());
+        this.addMultilineValue(Settings.KEY_EXTRA_CLASSPATHS, s.getExtraClasspaths());
+        this.addMultilineValue(Settings.KEY_LOAD_CLASSES, s.getLoadClasses());
+        this.addValue(Settings.KEY_FORCE_PROPERTIES, s.getForceProperties());
+        this.addValue(Settings.KEY_PROPERTY_PROVIDER, s.getPropertyProviders());
+        this.addValue(Settings.KEY_LOGGING_CONFIGURATION, s.getLoggingConfiguration());
+        this.addValue(Settings.KEY_LOGGING_BOOTSTRAP_LOGLEVEL, s.getBootstrapLogLevel());
+        this.addValue(Settings.KEY_LOGGING_MANAGER_CLASS, s.getLoggerManagerClassName());
+        this.addValue(Settings.KEY_PARENT_SERVICE_MANAGER, s.getParentServiceManagerClassName());
+        this.addValue(Settings.KEY_LOGGING_COCOON_LOGGER, s.getCocoonLogger());
+        this.addValue(Settings.KEY_LOGGING_ENVIRONMENT_LOGGER, s.getEnvironmentLogger());
+        this.addValue(Settings.KEY_LOGGING_OVERRIDE_LOGLEVEL, s.getOverrideLogLevel());
+        this.addValue(Settings.KEY_MANAGE_EXCEPTIONS, s.isManageExceptions());
+        this.addValue(Settings.KEY_UPLOADS_DIRECTORY, s.getUploadDirectory());
+        this.addValue(Settings.KEY_CACHE_DIRECTORY, s.getCacheDirectory());
+        this.addValue(Settings.KEY_WORK_DIRECTORY, s.getWorkDirectory());
+        this.addValue(Settings.KEY_FORM_ENCODING, s.getFormEncoding());
+
+        this.endGroup();
+
+        this.startGroup("Dynamic Settings");
+
+        this.addValue(Settings.KEY_RELOADING, s.isReloadingEnabled(null));
+        this.addValue(Settings.KEY_RELOAD_DELAY, s.getReloadDelay(null));
+        Iterator i = s.getProperties("org.apache.cocoon." + Settings.KEY_RELOADING + '.').iterator();
+        while ( i.hasNext() ) {
+            final String key = (String)i.next();
+            final String value = s.getProperty(key);
+            this.addValue(key.substring(18), value);
+        }
+        i = s.getProperties("org.apache.cocoon." + Settings.KEY_RELOAD_DELAY + '.').iterator();
+        while ( i.hasNext() ) {
+            final String key = (String)i.next();
+            final String value = s.getProperty(key);
+            this.addValue(key.substring(18), value);
+        }
+        this.addValue(Settings.KEY_UPLOADS_AUTOSAVE, s.isAutosaveUploads());
+        this.addValue(Settings.KEY_UPLOADS_ENABLE, s.isEnableUploads());
+        this.addValue(Settings.KEY_UPLOADS_MAXSIZE, s.getMaxUploadSize());
+        this.addValue(Settings.KEY_UPLOADS_OVERWRITE, s.isAllowOverwrite());
+        this.addValue(Settings.KEY_SHOWTIME, s.isShowTime());
+        this.addValue(Settings.KEY_HIDE_SHOWTIME, s.isHideShowTime());
+        this.addValue(Settings.KEY_SHOW_VERSION, s.isShowVersion());
+        this.addValue(Settings.KEY_LAZY_MODE, s.isLazyMode());
+
+        this.endGroup();
+    }
+
+    private void genProperties() throws SAXException {
+        this.startGroup("System-Properties");
+        final Properties p = System.getProperties();
+        final Enumeration e = p.keys();
+        while ( e.hasMoreElements() ) {
+            final String key = (String)e.nextElement();
+            final String value = p.getProperty(key);
+            this.addValue(key, value);
+        }
+        this.endGroup();
+    }
+
+    private void genLibrarylist() throws SAXException,ProcessingException {
+        try {
+            if (this.libDirectory instanceof TraversableSource) {
+                startGroup("WEB-INF/lib");
+
+                Set files = new TreeSet();
+                Collection kids = ((TraversableSource) this.libDirectory).getChildren();
+                try {
+                    for (Iterator i = kids.iterator(); i.hasNext(); ) {
+                        final Source lib = (Source) i.next();
+                        final String name = lib.getURI().substring(lib.getURI().lastIndexOf('/'));
+                        files.add(name);
+                    }
+                } finally {
+                    for (Iterator i = kids.iterator(); i.hasNext(); ) {
+                        final Source lib = (Source) i.next();
+                        super.resolver.release(lib);
+                    }
+                }
+
+                for (Iterator i = files.iterator(); i.hasNext(); ) {
+                    addValue("file", (String) i.next());
+                }
+
+                endGroup();
+            }
+        } catch (SourceException e) {
+            throw new ResourceNotFoundException("Could not read directory", e);
+        }
+    }
+
+    /** Utility function to begin a <code>group</code> tag pair. */
+    private void startGroup(String name) throws SAXException {
+        startGroup(name, null);
+    }
+
+    /** Utility function to begin a <code>group</code> tag pair with added attributes. */
+    private void startGroup(String name, Attributes atts)
+    throws SAXException {
+        AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
+        ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
+        super.contentHandler.startElement(NAMESPACE, "group", "group", ai);
+    }
+
+    /** Utility function to end a <code>group</code> tag pair. */
+    private void endGroup() throws SAXException {
+        super.contentHandler.endElement(NAMESPACE, "group", "group");
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, String value)
+    throws SAXException {
+        addValue(name, value, null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, boolean value) throws SAXException {
+        addValue(name, String.valueOf(value), null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, int value) throws SAXException {
+        addValue(name, String.valueOf(value), null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, long value) throws SAXException {
+        addValue(name, String.valueOf(value), null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, List value) throws SAXException {
+        addValue(name, value.iterator());
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, Iterator value) throws SAXException {
+        final StringBuffer buffer = new StringBuffer();
+        boolean first = true;
+        while ( value.hasNext() ) {
+            if ( !first ) {
+                buffer.append(',');
+            } else {
+                first = false;
+            }
+            buffer.append(value.next());
+        }
+        addValue(name, buffer.toString(), null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addValue(String name, Map value) throws SAXException {
+        final StringBuffer buffer = new StringBuffer();
+        final Iterator i = value.entrySet().iterator();
+        boolean first = true;
+        while ( i.hasNext() ) {
+            if ( !first ) {
+                buffer.append(',');
+            } else {
+                first = false;
+            }
+            Map.Entry current = (Map.Entry)i.next();
+            buffer.append(current.getKey()).append('=').append(current.getValue());
+        }
+        addValue(name, buffer.toString(), null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair with added attributes. */
+    private void addValue(String name, String value, Attributes atts)
+    throws SAXException {
+        AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
+        ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
+        super.contentHandler.startElement(NAMESPACE, "value", "value", ai);
+        super.contentHandler.startElement(NAMESPACE, "line", "line", XMLUtils.EMPTY_ATTRIBUTES);
+
+        if (value != null) {
+            super.contentHandler.characters(value.toCharArray(), 0, value.length());
+        }
+
+        super.contentHandler.endElement(NAMESPACE, "line", "line");
+        super.contentHandler.endElement(NAMESPACE, "value", "value");
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair. */
+    private void addMultilineValue(String name, List values)
+    throws SAXException {
+        addMultilineValue(name, values, null);
+    }
+
+    /** Utility function to begin and end a <code>value</code> tag pair with added attributes. */
+    private void addMultilineValue(String name, List values, Attributes atts)
+    throws SAXException {
+        AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
+        ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
+        super.contentHandler.startElement(NAMESPACE, "value", "value", ai);
+
+        for (int i = 0; i < values.size(); i++) {
+            String value = (String) values.get(i);
+            if (value != null) {
+                super.contentHandler.startElement(NAMESPACE, "line", "line", XMLUtils.EMPTY_ATTRIBUTES);
+                super.contentHandler.characters(value.toCharArray(), 0, value.length());
+                super.contentHandler.endElement(NAMESPACE, "line", "line");
+            }
+        }
+        super.contentHandler.endElement(NAMESPACE, "value", "value");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StreamGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StreamGenerator.java
new file mode 100644
index 0000000..b7652ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/StreamGenerator.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.http.HttpEnvironment;
+import org.apache.cocoon.servlet.multipart.Part;
+import org.apache.cocoon.util.PostInputStream;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.servlet.http.HttpServletRequest;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The <code>StreamGenerator</code> is a class that reads XML from a
+ * request InputStream and generates SAX Events.
+ * 
+ * @cocoon.sitemap.component.name   stream
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.logger sitemap.generator.stream
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ *
+ * For the POST requests with a mimetype of application/x-www-form-urlencoded,
+ * or multipart/form-data the xml data is expected to be associated with the
+ * sitemap parameter 'form-name'.
+ *
+ * For the POST requests with mimetypes: text/plain, text/xml,
+ * application/xml the xml data is in the body of the POST request and
+ * its length is specified by the value returned by getContentLength()
+ * method.  The StreamGenerator uses helper
+ * org.apache.cocoon.util.PostInputStream class for InputStream
+ * reading operations.  At the time that Parser is reading the data
+ * out of InputStream - Parser has no knowledge about the length of
+ * data to be read.  The only way to signal to the Parser that all
+ * data was read from the InputStream is to control reading operation-
+ * PostInputStream--and to return to the requestor '-1' when the
+ * number of bytes read is equal to the getContentLength() value.
+ *
+ * @version $Id$
+ */
+public class StreamGenerator extends ServiceableGenerator
+{
+
+    /** The parameter holding the name associated with the xml data  **/
+    public static final String FORM_NAME = "form-name";
+
+    /** The input source */
+    private InputSource inputSource;
+
+    /**
+     * Recycle this component.
+     * All instance variables are set to <code>null</code>.
+     */
+    public void recycle() {
+        super.recycle();
+        this.inputSource = null;
+    }
+
+    /**
+     * Generate XML data out of request InputStream.
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+        SAXParser parser = null;
+        int len = 0;
+        String contentType = null;
+
+        Request request = ObjectModelHelper.getRequest(this.objectModel);
+        try {
+            contentType = request.getContentType();
+            if (contentType == null) {
+                contentType = parameters.getParameter("defaultContentType", null);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("no Content-Type header - using contentType parameter: " + contentType);
+                }
+                if (contentType == null) {
+                    throw new IOException("both Content-Type header and defaultContentType parameter are not set");
+                }
+            }
+            if (contentType.startsWith("application/x-www-form-urlencoded") ||
+                    contentType.startsWith("multipart/form-data")) {
+                String parameter = parameters.getParameter(FORM_NAME, null);
+                if (parameter == null) {
+                    throw new ProcessingException(
+                        "StreamGenerator expects a sitemap parameter called '" +
+                        FORM_NAME + "' for handling form data"
+                    );
+                }
+                Object xmlObject = request.get(parameter);
+                Reader xmlReader = null;
+                if (xmlObject instanceof String) {
+                    xmlReader  = new StringReader((String)xmlObject);
+                } else if (xmlObject instanceof Part) {
+                    xmlReader = new InputStreamReader(((Part)xmlObject).getInputStream());
+                } else {
+                    throw new ProcessingException("Unknown request object encountered named " + 
+                                                  parameter + " : " + xmlObject);
+                }                
+                inputSource = new InputSource(xmlReader);
+            } else if (contentType.startsWith("text/plain") ||
+                    contentType.startsWith("text/xml") ||
+                    contentType.startsWith("application/xml")) {
+
+                HttpServletRequest httpRequest = (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);
+                if ( httpRequest == null ) {
+                    throw new ProcessingException("This feature is only available in an http environment.");
+                }
+                len = request.getContentLength();
+                if (len > 0) {
+                        PostInputStream anStream = new PostInputStream(httpRequest.getInputStream(), len);
+                        inputSource = new InputSource(anStream);
+                } else {
+                    throw new IOException("getContentLen() == 0");
+                }
+            } else {
+                throw new IOException("Unexpected getContentType(): " + request.getContentType());
+            }
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("processing stream ContentType=" + contentType + " ContentLen=" + len);
+            }
+            String charset =  getCharacterEncoding(request, contentType) ;
+            if( charset != null) {
+                this.inputSource.setEncoding(charset);
+            }
+            parser = (SAXParser)this.manager.lookup(SAXParser.ROLE);
+            parser.parse(this.inputSource, super.xmlConsumer);
+        } catch (IOException e) {
+            getLogger().error("StreamGenerator.generate()", e);
+            throw new ResourceNotFoundException("StreamGenerator could not find resource", e);
+        } catch (SAXException e) {
+            getLogger().error("StreamGenerator.generate()", e);
+            throw(e);
+        } catch (Exception e) {
+            getLogger().error("Could not get parser", e);
+            throw new ProcessingException("Exception in StreamGenerator.generate()", e);
+        } finally {
+            this.manager.release( parser);
+        }
+    }
+
+    /**
+    * Content type HTTP header can contains character encodinf info
+    * for ex. Content-Type: text/xml; charset=UTF-8
+    * If the servlet is following spec 2.3 and higher the servlet API can be used to retrieve character encoding part of
+    * Content-Type header. Some containers can choose to not unpack charset info - the spec is not strong about it.
+    * in any case this method can be used as a latest resource to retrieve the passed charset value.
+    * <code>null</code> is returned.
+    * It is very common mistake to send : Content-Type: text/xml; charset="UTF-8".
+    * Some containers are not filtering this mistake and the processing results in exception..
+    * The getCharacterEncoding() compensates for above mistake.
+    *
+    * @param contentType value associated with Content-Type HTTP header.
+    */
+    public String getCharacterEncoding(Request req, String contentType) {
+        String charencoding = null;
+        String charset = "charset=";
+        if (contentType == null) {
+            return null;
+        }
+        int idx = contentType.indexOf(charset);
+        if (idx == -1) {
+            return null;
+        }
+        try {
+            charencoding = req.getCharacterEncoding();
+
+            if ( charencoding != null) {
+                getLogger().debug("charset from container: " + charencoding);
+                charencoding = charencoding.trim();
+                if ((charencoding.length() > 2) && (charencoding.startsWith("\""))&& (charencoding.endsWith("\""))) {
+                    charencoding = charencoding.substring(1, charencoding.length() - 1);
+                }
+                getLogger().debug("charset from container clean: " + charencoding);
+                return charencoding;
+            } else {
+                return extractCharset( contentType, idx );
+            }
+        } catch(Throwable e) {
+            // We will be there if the container do not implement getCharacterEncoding() method
+             return extractCharset( contentType, idx );
+        }
+    }
+
+
+    protected String extractCharset(String contentType, int idx) {
+        String charencoding = null;
+        String charset = "charset=";
+
+        getLogger().debug("charset from extractCharset");
+        charencoding = contentType.substring(idx + charset.length());
+        int idxEnd = charencoding.indexOf(";");
+        if (idxEnd != -1) {
+            charencoding = charencoding.substring(0, idxEnd);
+        }
+        charencoding = charencoding.trim();
+        if ((charencoding.length() > 2) && (charencoding.startsWith("\""))&& (charencoding.endsWith("\""))) {
+            charencoding = charencoding.substring(1, charencoding.length() - 1);
+        }
+        getLogger().debug("charset from extractCharset: " + charencoding);
+        return charencoding.trim();
+
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/TraversableGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/TraversableGenerator.java
new file mode 100644
index 0000000..06ca536
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/TraversableGenerator.java
@@ -0,0 +1,603 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.MultiSourceValidity;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.TimeZone;
+
+/**
+ * Generates an XML source hierarchy listing from a Traversable Source.
+ * <p>
+ * The root node of the generated document will normally be a
+ * <code>collection</code> node and a collection node can contain zero or more
+ * <code>resource</code> or collection nodes. A resource node has no children.
+ * Each node will contain the following attributes:
+ * <blockquote>
+ *  <dl>
+ *   <dt> name
+ *   <dd> the name of the source
+ *   <dt> lastModified
+ *   <dd> the time the source was last modified, measured as the number of
+ *        milliseconds since the epoch (as in java.io.File.lastModified)
+ *   <dt> size
+ *   <dd> the source size, in bytes (as in java.io.File.length)
+ *   <dt> date (optional)
+ *   <dd> the time the source was last modified in human-readable form
+ *  </dl>
+ * </blockquote>
+ * <p>
+ *  <b>Configuration options:</b>
+ *  <dl>
+ *   <dt> <i>depth</i> (optional)
+ *   <dd> Sets how deep TraversableGenerator should delve into the
+ *        source hierarchy. If set to 1 (the default), only the starting
+ *        collection's immediate contents will be returned.
+ *   <dt> <i>sort</i> (optional)
+ *   <dd> Sort order in which the nodes are returned. Possible values are
+ *        name, size, time, collection. collection is the same as name,
+ *        except that the collection entries are listed first. System order is
+ *        default.
+ *   <dt> <i>reverse</i> (optional)
+ *   <dd> Reverse the order of the sort
+ *   <dt> <i>dateFormat</i> (optional)
+ *   <dd> Sets the format for the date attribute of each node, as
+ *        described in java.text.SimpleDateFormat. If unset, the default
+ *        format for the current locale will be used.
+ *   <dt> <i>timeZone</i> (optional)
+ *   <dd> Sets the time zone offset ID for the date attribute, as
+ *        described in java.util.TimeZone. If unset, the default
+ *        system time zone will be used.
+ *   <dt> <i>refreshDelay</i> (optional)
+ *   <dd> Sets the delay (in seconds) between checks on the source hierarchy
+ *        for changed content. Defaults to 1 second.
+ *  </dl>
+ * </p>
+ *
+ * @version $Id$
+ */
+public class TraversableGenerator extends ServiceableGenerator
+                                  implements CacheableProcessingComponent {
+
+    /** The URI of the namespace of this generator. */
+    protected static final String URI = "http://apache.org/cocoon/collection/1.0";
+
+    /** The namespace prefix for this namespace. */
+    protected static final String PREFIX = "collection";
+
+    /* Node and attribute names */
+    protected static final String COL_NODE_NAME = "collection";
+    protected static final String RESOURCE_NODE_NAME = "resource";
+
+    protected static final String RES_NAME_ATTR_NAME = "name";
+    protected static final String URI_ATTR_NAME = "uri";
+    protected static final String LASTMOD_ATTR_NAME = "lastModified";
+    protected static final String DATE_ATTR_NAME = "date";
+    protected static final String SIZE_ATTR_NAME = "size";
+
+    /** The validity that is being built */
+    protected MultiSourceValidity validity;
+
+    /**
+     * Convenience object, so we don't need to create an AttributesImpl for every element.
+     */
+    protected AttributesImpl attributes;
+
+    /**
+     * The cache key needs to be generated for the configuration of this
+     * generator, so storing the parameters for generateKey().
+     * Using the member variables after setup() would not work I guess. I don't
+     * know a way from the regular expressions back to the pattern or at least
+     * a useful string.
+     */
+    protected List cacheKeyParList;
+
+    /**
+     * The depth parameter determines how deep the TraversableGenerator should delve.
+     */
+    protected int depth;
+
+    /**
+     * The dateFormatter determines into which date format the lastModified
+     * time should be converted.
+     * FIXME: SimpleDateFormat is not supported by all locales!
+     */
+    protected SimpleDateFormat dateFormatter;
+
+    /** The delay between checks on updates to the source hierarchy. */
+    protected long refreshDelay;
+
+    /**
+     * The sort parameter determines by which attribute the content of one
+     * collection should be sorted. Possible values are "name", "size", "time"
+     * and "collection", where "collection" is the same as "name", except that
+     * collection entries are listed first.
+     */
+    protected String sort;
+
+    /** The reverse parameter reverses the sort order. <code>false</code> is default. */
+    protected boolean reverse;
+
+    /** The regular expression for the root pattern. */
+    protected RE rootRE;
+
+    /** The regular expression for the include pattern. */
+    protected RE includeRE;
+
+    /** The regular expression for the exclude pattern. */
+    protected RE excludeRE;
+
+    /**
+     * This is only set to true for the requested source specified by the
+     * <code>src</code> attribute on the generator's configuration.
+     */
+    protected boolean isRequestedSource;
+
+    /**
+     * Set the request parameters. Must be called before the generate method.
+     *
+     * @param resolver     the SourceResolver object
+     * @param objectModel  a <code>Map</code> containing model object
+     * @param src          the Traversable Source to be XMLized specified as
+     *                     <code>src</code> attribute on &lt;map:generate/>
+     * @param par          configuration parameters
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        if (src == null) {
+            throw new ProcessingException("No src attribute pointing to a traversable source to be XMLized specified.");
+        }
+        super.setup(resolver, objectModel, src, par);
+
+        this.cacheKeyParList = new ArrayList();
+        this.cacheKeyParList.add(src);
+
+        this.depth = par.getParameterAsInteger("depth", 1);
+        this.cacheKeyParList.add(String.valueOf(this.depth));
+
+        String dateFormatString = par.getParameter("dateFormat", null);
+        this.cacheKeyParList.add(dateFormatString);
+        if (dateFormatString != null) {
+            String locale = par.getParameter("locale", null);
+            if (locale != null) {
+                this.dateFormatter = new SimpleDateFormat(dateFormatString, new Locale(locale, ""));
+            } else {
+                this.dateFormatter = new SimpleDateFormat(dateFormatString);
+            }
+        } else {
+            this.dateFormatter = new SimpleDateFormat();
+        }
+
+        String timeZone = par.getParameter("timeZone", null);
+        if (timeZone != null) {
+            this.dateFormatter.setTimeZone(TimeZone.getTimeZone(timeZone));
+        }
+
+        this.sort = par.getParameter("sort", "name");
+        this.cacheKeyParList.add(this.sort);
+
+        this.reverse = par.getParameterAsBoolean("reverse", false);
+        this.cacheKeyParList.add(String.valueOf(this.reverse));
+
+        this.refreshDelay = par.getParameterAsLong("refreshDelay", 1L) * 1000L;
+        this.cacheKeyParList.add(String.valueOf(this.refreshDelay));
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("depth: " + this.depth);
+            this.getLogger().debug("dateFormat: " + this.dateFormatter.toPattern());
+            this.getLogger().debug("timeZone: " + timeZone);
+            this.getLogger().debug("sort: " + this.sort);
+            this.getLogger().debug("reverse: " + this.reverse);
+            this.getLogger().debug("refreshDelay: " + this.refreshDelay);
+        }
+
+        String rePattern = null;
+        try {
+            rePattern = par.getParameter("root", null);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("root pattern: " + rePattern);
+            }
+            this.cacheKeyParList.add(rePattern);
+            this.rootRE = (rePattern == null) ? null : new RE(rePattern);
+
+            rePattern = par.getParameter("include", null);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("include pattern: " + rePattern);
+            }
+            this.cacheKeyParList.add(rePattern);
+            this.includeRE = (rePattern == null) ? null : new RE(rePattern);
+
+            rePattern = par.getParameter("exclude", null);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("exclude pattern: " + rePattern);
+            }
+            this.cacheKeyParList.add(rePattern);
+            this.excludeRE = (rePattern == null) ? null : new RE(rePattern);
+
+        } catch (RESyntaxException rese) {
+            throw new ProcessingException("Syntax error in regexp pattern '"
+            			                  + rePattern + "'", rese);
+        }
+
+        this.isRequestedSource = false;
+        this.attributes = new AttributesImpl();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
+     */
+    public Serializable getKey() {
+        StringBuffer buffer = new StringBuffer();
+        int len = this.cacheKeyParList.size();
+        for (int i = 0; i < len; i++) {
+            buffer.append(this.cacheKeyParList.get(i));
+            buffer.append(':');
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Gets the source validity, using a deferred validity object. The validity
+     * is initially empty since the resources that define it are not known
+     * before generation has occured. So the returned object is kept by the
+     * generator and filled with each of the resources that is traversed.
+     *
+     * @see org.apache.cocoon.components.source.impl.MultiSourceValidity
+     */
+    public SourceValidity getValidity() {
+        if (this.validity == null) {
+            this.validity = new MultiSourceValidity(this.resolver, this.refreshDelay);
+        }
+        return this.validity;
+    }
+
+    /**
+     * Generate XML data.
+     *
+     * @throws  SAXException if an error occurs while outputting the document
+     * @throws  ProcessingException if something went wrong while traversing
+     *                              the source hierarchy
+     */
+    public void generate() throws SAXException, ProcessingException {
+        Source src = null;
+        Stack ancestors = null;
+        try {
+            src = this.resolver.resolveURI(this.source);
+            if (!(src instanceof TraversableSource)) {
+                throw new SourceException(this.source + " is not a traversable source");
+            }
+            final TraversableSource inputSource =
+                (TraversableSource) this.resolver.resolveURI(this.source);
+
+            if (!inputSource.exists()) {
+                throw new ResourceNotFoundException(this.source + " does not exist.");
+            }
+
+            this.contentHandler.startDocument();
+            this.contentHandler.startPrefixMapping(PREFIX, URI);
+
+            ancestors = getAncestors(inputSource);
+            addAncestorPath(inputSource, ancestors);
+
+            this.contentHandler.endPrefixMapping(PREFIX);
+            this.contentHandler.endDocument();
+            if (this.validity != null) {
+                this.validity.close();
+            }
+        } catch (SourceException se) {
+            throw SourceUtil.handle(se);
+        } catch (IOException ioe) {
+            throw new ResourceNotFoundException("Could not read collection "
+                                                + this.source, ioe);
+        } finally {
+            if (src != null) {
+                this.resolver.release(src);
+            }
+            if (ancestors != null) {
+                Enumeration enumeration = ancestors.elements();
+                while (enumeration.hasMoreElements()) {
+                    resolver.release((Source) enumeration.nextElement());
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a stack containing the ancestors of a traversable source up to
+     * specific parent matching the root pattern.
+     *
+     * @param source the traversable source whose ancestors shall be retrieved
+     * @return a Stack containing the ancestors.
+     */
+    protected Stack getAncestors(TraversableSource source) throws IOException {
+        TraversableSource parent = source;
+        Stack ancestors = new Stack();
+
+        while ((parent != null) && !isRoot(parent)) {
+            parent = (TraversableSource) parent.getParent();
+            if (parent != null) {
+                ancestors.push(parent);
+            } else {
+                // no ancestor matched the root pattern
+                ancestors.clear();
+            }
+        }
+
+        return ancestors;
+    }
+
+    /**
+     * Adds recursively the path from the source matched by the root pattern
+     * down to the requested source.
+     *
+     * @param source       the requested source.
+     * @param ancestors  the stack of the ancestors.
+     * @throws SAXException
+     * @throws ProcessingException
+     */
+    protected void addAncestorPath(TraversableSource source, Stack ancestors)
+    throws SAXException, ProcessingException {
+        if (ancestors.empty()) {
+            this.isRequestedSource = true;
+            addPath(source, depth);
+        } else {
+            startNode(COL_NODE_NAME, (TraversableSource) ancestors.pop());
+            addAncestorPath(source, ancestors);
+            endNode(COL_NODE_NAME);
+        }
+    }
+
+    /**
+     * Adds a single node to the generated document. If the path is a
+     * collection and depth is greater than zero, then recursive calls
+     * are made to add nodes for the collection's children.
+     *
+     * @param source  the resource/collection to process
+     * @param depth   how deep to scan the collection hierarchy
+     *
+     * @throws SAXException  if an error occurs while constructing nodes
+     * @throws ProcessingException  if a problem occurs with the source
+     */
+    protected void addPath(TraversableSource source, int depth)
+    throws SAXException, ProcessingException {
+        if (source.isCollection()) {
+            startNode(COL_NODE_NAME, source);
+            addContent(source);
+            if (depth > 0) {
+
+                Collection contents = null;
+
+                try {
+                    contents = source.getChildren();
+                    if (sort.equals("name")) {
+                        Arrays.sort(contents.toArray(), new Comparator() {
+                            public int compare(Object o1, Object o2) {
+                                if (reverse) {
+                                    return ((TraversableSource) o2).getName().compareTo(((TraversableSource) o1).getName());
+                                }
+                                return ((TraversableSource) o1).getName().compareTo(((TraversableSource) o2).getName());
+                            }
+                        });
+                    } else if (sort.equals("size")) {
+                        Arrays.sort(contents.toArray(), new Comparator() {
+                            public int compare(Object o1, Object o2) {
+                                if (reverse) {
+                                    return new Long(((TraversableSource) o2).getContentLength()).compareTo(new Long(((TraversableSource) o1).getContentLength()));
+                                }
+                                return new Long(((TraversableSource) o1).getContentLength()).compareTo(new Long(((TraversableSource) o2).getContentLength()));
+                            }
+                        });
+                    } else if (sort.equals("lastmodified")) {
+                        Arrays.sort(contents.toArray(), new Comparator() {
+                            public int compare(Object o1, Object o2) {
+                                if (reverse) {
+                                    return new Long(((TraversableSource) o2).getLastModified()).compareTo(new Long(((TraversableSource) o1).getLastModified()));
+                                }
+                                return new Long(((TraversableSource) o1).getLastModified()).compareTo(new Long(((TraversableSource) o2).getLastModified()));
+                            }
+                        });
+                    } else if (sort.equals("collection")) {
+                        Arrays.sort(contents.toArray(), new Comparator() {
+                            public int compare(Object o1, Object o2) {
+                                TraversableSource ts1 = (TraversableSource) o1;
+                                TraversableSource ts2 = (TraversableSource) o2;
+
+                                if (reverse) {
+                                    if (ts2.isCollection() && !ts1.isCollection())
+                                        return -1;
+                                    if (!ts2.isCollection() && ts1.isCollection())
+                                        return 1;
+                                    return ts2.getName().compareTo(ts1.getName());
+                                }
+                                if (ts2.isCollection() && !ts1.isCollection())
+                                    return 1;
+                                if (!ts2.isCollection() && ts1.isCollection())
+                                    return -1;
+                                return ts1.getName().compareTo(ts2.getName());
+                            }
+                        });
+                    }
+
+                    for (int i = 0; i < contents.size(); i++) {
+                        if (isIncluded((TraversableSource) contents.toArray()[i]) && !isExcluded((TraversableSource) contents.toArray()[i])) {
+                            addPath((TraversableSource) contents.toArray()[i], depth - 1);
+                        }
+                    }
+    			} catch (SourceException e) {
+                    throw new ProcessingException("Error adding paths", e);
+                } finally {
+                    if (contents != null) {
+                        Iterator iter = contents.iterator();
+                        while (iter.hasNext()) {
+                            resolver.release((Source) iter.next());
+                        }
+                    }
+                }
+            }
+            endNode(COL_NODE_NAME);
+        } else {
+            if (isIncluded(source) && !isExcluded(source)) {
+                startNode(RESOURCE_NODE_NAME, source);
+                addContent(source);
+                endNode(RESOURCE_NODE_NAME);
+            }
+        }
+    }
+
+    /**
+     * Allow subclasses a chance to generate additional elements within collection and resource
+     * elements.
+     *
+     * @param source  the source to generate additional data for.
+     */
+    protected void addContent(TraversableSource source) throws SAXException, ProcessingException {
+    }
+
+    /**
+     * Begins a named node and calls setNodeAttributes to set its attributes.
+     *
+     * @param nodeName  the name of the new node
+     * @param source    the source a node with its attributes is added for
+     *
+     * @throws SAXException  if an error occurs while creating the node
+     */
+    protected void startNode(String nodeName, TraversableSource source)
+    throws SAXException, ProcessingException {
+        if (this.validity != null) {
+            this.validity.addSource(source);
+        }
+        setNodeAttributes(source);
+        super.contentHandler.startElement(URI, nodeName, PREFIX + ':' + nodeName, attributes);
+    }
+
+    /**
+     * Sets the attributes for a given source. For example attributes for the
+     * name, the size and the last modification date of the source are added.
+     *
+     * @param source  the source attributes are added for
+     */
+    protected void setNodeAttributes(TraversableSource source)
+    throws SAXException, ProcessingException {
+        long lastModified = source.getLastModified();
+        attributes.clear();
+        attributes.addAttribute("", RES_NAME_ATTR_NAME,RES_NAME_ATTR_NAME,
+                                "CDATA", source.getName());
+        attributes.addAttribute("", URI_ATTR_NAME,URI_ATTR_NAME,
+                                "CDATA", source.getURI());
+        attributes.addAttribute("", LASTMOD_ATTR_NAME, LASTMOD_ATTR_NAME,
+                                "CDATA", Long.toString(source.getLastModified()));
+        attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME,
+                                "CDATA", dateFormatter.format(new Date(lastModified)));
+        attributes.addAttribute("", SIZE_ATTR_NAME, SIZE_ATTR_NAME,
+                                "CDATA", Long.toString(source.getContentLength()));
+        if (this.isRequestedSource) {
+            attributes.addAttribute("", "sort", "sort", "CDATA", this.sort);
+            attributes.addAttribute("", "reverse", "reverse", "CDATA",
+                                    String.valueOf(this.reverse));
+            attributes.addAttribute("", "requested", "requested", "CDATA", "true");
+            this.isRequestedSource = false;
+        }
+    }
+
+    /**
+     * Ends the named node.
+     *
+     * @param nodeName  the name of the new node
+     *
+     * @throws SAXException  if an error occurs while closing the node
+     */
+    protected void endNode(String nodeName) throws SAXException {
+        super.contentHandler.endElement(URI, nodeName, PREFIX + ':' + nodeName);
+    }
+
+    /**
+     * Determines if a given source is the defined root.
+     *
+     * @param source  the source to check
+     *
+     * @return true if the source is the root or the root pattern is not set,
+     *         false otherwise.
+     */
+    protected boolean isRoot(TraversableSource source) {
+        return this.rootRE == null ? true : this.rootRE.match(source.getName());
+    }
+
+    /**
+     * Determines if a given source shall be visible.
+     *
+     * @param source  the source to check
+     *
+     * @return true if the source shall be visible or the include Pattern is not set,
+     *         false otherwise.
+     */
+    protected boolean isIncluded(TraversableSource source) {
+        return this.includeRE == null ? true : this.includeRE.match(source.getName());
+    }
+
+    /**
+     * Determines if a given source shall be excluded from viewing.
+     *
+     * @param source  the source to check
+     *
+     * @return false if the given source shall not be excluded or the exclude Pattern is not set,
+     *         true otherwise.
+     */
+    protected boolean isExcluded(TraversableSource source) {
+        return this.excludeRE == null ? false : this.excludeRE.match(source.getName());
+    }
+
+    /**
+     * Recycle resources
+     */
+    public void recycle() {
+        this.cacheKeyParList = null;
+        this.attributes = null;
+        this.dateFormatter = null;
+        this.rootRE = null;
+        this.includeRE = null;
+        this.excludeRE = null;
+        this.validity = null;
+        super.recycle();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/VirtualPipelineGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/VirtualPipelineGenerator.java
new file mode 100644
index 0000000..025c357
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/VirtualPipelineGenerator.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.impl.AbstractVirtualSitemapComponent;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+public class VirtualPipelineGenerator extends AbstractVirtualSitemapComponent
+    implements Generator {
+
+    protected String getTypeName() {
+        return "generator";
+    }
+
+    /**
+     * @see org.apache.cocoon.generation.Generator#generate()
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+
+        // Should use SourceResolver and context of the this
+        // components' sitemap, not caller sitemap
+        EnvironmentHelper.enterEnvironment(this.getVPCEnvironment());
+        try {
+            this.getPipeline().prepareInternal(this.getVPCEnvironment());
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+
+        // Should use SourceResolver of the this components' sitemap, not caller sitemap
+        EnvironmentHelper.enterEnvironment(this.getMappedSourceEnvironment());
+        try {
+            this.getPipeline().process(this.getMappedSourceEnvironment(),
+                                  EnvironmentHelper.createPopEnvironmentConsumer(this.xmlConsumer));
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+    }
+ }
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathDirectoryGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathDirectoryGenerator.java
new file mode 100644
index 0000000..2e918ea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathDirectoryGenerator.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+
+import org.apache.cocoon.components.source.SourceUtil;
+
+import org.apache.cocoon.environment.SourceResolver;
+
+import org.apache.cocoon.xml.dom.DOMStreamer;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+
+import org.apache.excalibur.xml.dom.DOMParser;
+import org.apache.excalibur.xml.xpath.PrefixResolver;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.SAXException;
+
+import org.xml.sax.helpers.AttributesImpl;
+
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Generates an XML directory listing performing XPath queries on XML files. It can be used both as a plain
+ * DirectoryGenerator or, by specifying a parameter <code>xpath</code>, it will perform an XPath query on every XML
+ * resource. 
+ * 
+ * @cocoon.sitemap.component.name   xpathdirectory
+ * @cocoon.sitemap.component.label  content
+ * @cocoon.sitemap.component.documentation.caching
+ *               Uses the last modification date of the directory and the contained documents
+ * @cocoon.sitemap.component.logger sitemap.generator.xpathdirectory
+ * 
+ * 
+ * <p>
+ * Generates an XML directory listing performing XPath queries on XML files. It can be used both as a plain
+ * DirectoryGenerator or, by specifying a parameter <code>xpath</code>, it will perform an XPath query on every XML
+ * resource. A <code>nsmapping</code> parameter can be specified to point to a file containing lines to map prefixes
+ * to namespaces like this:
+ * </p>
+ * 
+ * <p>
+ * prefix=namespace-uri<br/> prefix2=namespace-uri-2
+ * </p>
+ * 
+ * <p>
+ * A parameter <code>nsmapping-reload</code> specifies if the prefix-2-namespace mapping file should be checked to be
+ * reloaded on each request to this generator if it was modified since the last time it was read.
+ * </p>
+ * 
+ * <p>
+ * An additional parameter <code>xmlFiles</code> can be set in the sitemap setting the regular expression pattern for
+ * determining if a file should be handled as XML file or not. The default value for this param is
+ * <code>\.xml$</code>, so that it  matches all files ending <code>.xml</code>.
+ * </p>
+ * 
+ * <p></p>
+ * <br>Sample usage: <br><br>Sitemap:
+ * <pre>
+ *  &lt;map:match pattern="documents/**"&gt; 
+ *   &lt;map:generate type="xpathdirectory" src="docs/{1}"&gt; 
+ *    &lt;map:parameter name="xpath" value="/article/title|/article/abstract"/&gt; 
+ *    &lt;map:parameter name="nsmapping" value="mapping.properties"/&gt; 
+ *    &lt;map:parameter name="nsmapping-reload" value="false"/&gt; 
+ *    &lt;map:parameter name="xmlFiles" value="\.xml$"/&gt; 
+ *   &lt;/map:generate&gt; 
+ *   &lt;map:serialize type="xml" /&gt; 
+ *  &lt;/map:match&gt;
+ * </pre>
+ * 
+ * <p>
+ * Request: <br>http://www.some.host/documents/test
+ * </p>
+ * Result:
+ * <pre>
+ *  &lt;dir:directory name="test" lastModified="1010400942000" date="1/7/02 11:55 AM" requested="true" xmlns:dir="http://apache.org/cocoon/directory/2.0"&gt; 
+ *   &lt;dir:directory name="subdirectory" lastModified="1010400942000" date="1/7/02 11:55 AM"/&gt; 
+ *   &lt;dir:file name="test.xml" lastModified="1011011579000" date="1/14/02 1:32 PM"&gt; 
+ *    &lt;dir:xpath query="/article/title"&gt; 
+ *     &lt;title&gt;This is a test document&lt;/title&gt; 
+ *      &lt;abstract&gt; 
+ *       &lt;para&gt;Abstract of my test article&lt;/para&gt; 
+ *      &lt;/abstract&gt; 
+ *     &lt;/dir:xpath&gt; 
+ *    &lt;/dir:file&gt; 
+ *   &lt;dir:file name="test.gif" lastModified="1011011579000" date="1/14/02 1:32 PM"/&gt; 
+ *  &lt;/dir:directory&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class XPathDirectoryGenerator
+extends DirectoryGenerator {
+    /** Local name for the element that contains the included XML snippet. */
+    protected static final String XPATH_NODE_NAME = "xpath";
+
+    /** Attribute for the XPath query. */
+    protected static final String QUERY_ATTR_NAME = "query";
+
+    /** All the mapping files lastmodified dates */
+    protected static Map mappingFiles = new HashMap();
+
+    /** The parser for the XML snippets to be included. */
+    protected DOMParser parser = null;
+
+    /** The document that should be parsed and (partly) included. */
+    protected Document doc = null;
+
+    /** The PrefixResolver responsable for processing current request (if any). */
+    protected PrefixResolver prefixResolver = null;
+
+    /** The regular expression for the XML files pattern. */
+    protected RE xmlRE = null;
+
+    /** The XPath. */
+    protected String xpath = null;
+
+    /** The XPath processor. */
+    protected XPathProcessor processor = null;
+
+    /**
+     * Disposable
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            this.manager.release(this.processor);
+            this.manager.release(this.parser);
+            this.processor = null;
+            this.parser = null;
+        }
+
+        super.dispose();
+    }
+
+    /**
+     * Recycle resources
+     */
+    public void recycle() {
+        this.xpath = null;
+        this.doc = null;
+
+        //this.parser = null;
+        //this.processor = null;
+        super.recycle();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager)
+    throws ServiceException {
+        super.service(manager);
+        this.processor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
+        this.parser = (DOMParser)manager.lookup(DOMParser.ROLE);
+    }
+
+    /**
+     * Setup this sitemap component
+     *
+     * @param resolver the SourceResolver
+     * @param objectModel The environmental object model
+     * @param src the source attribute
+     * @param par the parameters
+     *
+     * @throws ProcessingException if processing failes
+     * @throws SAXException in case of XML related errors
+     * @throws IOException in case of file related errors
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        // See if an XPath was specified
+        this.xpath = par.getParameter("xpath", null);
+        this.cacheKeyParList.add(this.xpath);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Applying XPath: " + this.xpath + " to directory " + this.source);
+        }
+
+        final String mappings = par.getParameter("nsmapping", null);
+
+        if (null != mappings) {
+            final boolean mapping_reload = par.getParameterAsBoolean("nsmapping-reload", false);
+            final Source mappingSource = resolver.resolveURI(mappings);
+            final String mappingKey = mappingSource.getURI();
+            final MappingInfo mappingInfo = (MappingInfo)XPathDirectoryGenerator.mappingFiles.get(mappingKey);
+
+            if ((null == mappingInfo) || (mappingInfo.reload == false) ||
+                (mappingInfo.mappingSource.getLastModified() < mappingSource.getLastModified())) {
+                this.prefixResolver =
+                    new MappingInfo(getLogger().getChildLogger("prefix-resolver"), mappingSource, mapping_reload);
+                XPathDirectoryGenerator.mappingFiles.put(mappingKey, this.prefixResolver);
+            } else {
+                this.prefixResolver = mappingInfo;
+            }
+        }
+
+        String xmlFilesPattern = null;
+
+        try {
+            xmlFilesPattern = par.getParameter("xmlFiles", "\\.xml$");
+            this.cacheKeyParList.add(xmlFilesPattern);
+            this.xmlRE = new RE(xmlFilesPattern);
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("pattern for XML files: " + xmlFilesPattern);
+            }
+        } catch (RESyntaxException rese) {
+            throw new ProcessingException("Syntax error in regexp pattern '" + xmlFilesPattern + "'", rese);
+        }
+    }
+
+    /**
+     * Determines if a given File shall be handled as XML.
+     *
+     * @param path the File to check
+     *
+     * @return true if the given File shall handled as XML, false otherwise.
+     */
+    protected boolean isXML(File path) {
+        return this.xmlRE.match(path.getName());
+    }
+
+    /**
+     * Performs an XPath query on the file.
+     *
+     * @param xmlFile the File the XPath is performed on.
+     *
+     * @throws SAXException if something goes wrong while adding the XML snippet.
+     */
+    protected void performXPathQuery(File xmlFile)
+    throws SAXException {
+        this.doc = null;
+
+        Source source = null;
+
+        try {
+            source = resolver.resolveURI(xmlFile.toURL().toExternalForm());
+            this.doc = this.parser.parseDocument(SourceUtil.getInputSource(source));
+        } catch (SAXException e) {
+            getLogger().error("Warning:" + xmlFile.getName() + " is not a valid XML file. Ignoring.", e);
+        } catch (ProcessingException e) {
+            getLogger().error("Warning: Problem while reading the file " + xmlFile.getName() + ". Ignoring.", e);
+        } catch (IOException e) {
+            getLogger().error("Warning: Problem while reading the file " + xmlFile.getName() + ". Ignoring.", e);
+        } finally {
+            resolver.release(source);
+        }
+
+        if (doc != null) {
+            NodeList nl =
+                (null == this.prefixResolver)
+                ? this.processor.selectNodeList(this.doc.getDocumentElement(), this.xpath)
+                : this.processor.selectNodeList(this.doc.getDocumentElement(), this.xpath, this.prefixResolver);
+            AttributesImpl attributes = new AttributesImpl();
+            attributes.addAttribute("", QUERY_ATTR_NAME, QUERY_ATTR_NAME, "CDATA", xpath);
+            super.contentHandler.startElement(URI, XPATH_NODE_NAME, PREFIX + ":" + XPATH_NODE_NAME, attributes);
+
+            DOMStreamer ds = new DOMStreamer(super.xmlConsumer);
+
+            for (int i = 0; i < nl.getLength(); i++) {
+                ds.stream(nl.item(i));
+            }
+
+            super.contentHandler.endElement(URI, XPATH_NODE_NAME, PREFIX + ":" + XPATH_NODE_NAME);
+        }
+    }
+
+    /**
+     * Extends the startNode() method of the DirectoryGenerator by starting a possible XPath query on a file.
+     *
+     * @param nodeName the node currently processing
+     * @param path the file path
+     *
+     * @throws SAXException in case of errors
+     */
+    protected void startNode(String nodeName, File path)
+    throws SAXException {
+        super.startNode(nodeName, path);
+
+        if ((this.xpath != null) && path.isFile() && this.isXML(path)) {
+            performXPathQuery(path);
+        }
+    }
+
+    /**
+     * The MappingInfo class to resolve namespace prefixes to their namespace URI
+     *
+     * @version $Id$
+     */
+    private static class MappingInfo
+    implements PrefixResolver {
+        /** The Source of the mapping file */
+        public final Source mappingSource;
+
+        /** Whether to reload if mapping file has changed */
+        public final boolean reload;
+
+        /** Our Logger */
+        private final Logger logger;
+
+        /** Map of prefixes to namespaces */
+        private final Map prefixMap;
+
+        /**
+         * Creates a new MappingInfo object.
+         *
+         * @param logger DOCUMENT ME!
+         * @param mappingSource The Source of the mapping file
+         * @param reload Whether to reload if mapping file has changed
+         *
+         * @throws SourceNotFoundException In case the mentioned source is not there
+         * @throws IOException in case the source could not be read
+         */
+        public MappingInfo(final Logger logger, final Source mappingSource, final boolean reload)
+        throws SourceNotFoundException, IOException {
+            this.logger = logger;
+            this.mappingSource = mappingSource;
+            this.reload = reload;
+            prefixMap = new HashMap();
+            InputStreamReader input = null;
+            BufferedReader br = null;
+
+            try {
+                input = new InputStreamReader(mappingSource.getInputStream());
+                br = new BufferedReader(input);
+    
+                for (String line = br.readLine(); line != null; line = br.readLine()) {
+                    final int i = line.indexOf('=');
+    
+                    if (i > 0) {
+                        final String prefix = line.substring(0, i);
+                        final String namespace = line.substring(i + 1);
+                        prefixMap.put(prefix, namespace);
+                        logger.debug("added mapping: '" + prefix + "'='" + namespace + "'");
+                    }
+                }
+            } finally {
+                if (br != null) {
+                    br.close();
+                }
+                if (input != null) {
+                    input.close();
+                }
+            }
+        }
+
+        /* (non-Javadoc)
+         * @see org.apache.excalibur.xml.xpath.PrefixResolver#prefixToNamespace(java.lang.String)
+         */
+        public String prefixToNamespace(String prefix) {
+            final String namespace = (String)this.prefixMap.get(prefix);
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("have to resolve prefix='" + prefix + ", found namespace='" + namespace + "'");
+            }
+
+            return namespace;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathTraversableGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathTraversableGenerator.java
new file mode 100644
index 0000000..bed45f7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/generation/XPathTraversableGenerator.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.excalibur.source.TraversableSource;
+import org.apache.excalibur.xml.xpath.PrefixResolver;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Generates an XML collection listing performing XPath queries on XML sources.
+ * It can be used both as a plain TraversableGenerator or, if an XPath is
+ * specified, it will perform an XPath query on every XML resource, where "xml
+ * resource" is, by default, any resource ending with ".xml", which can be
+ * overriden by setting the (regexp) pattern "xmlFiles as a sitemap parameter,
+ * or where the name of the resource has a container-wide mime-type mapping to
+ * 'text/xml' such as specified by mime-mapping elements in a web.xml
+ * descriptor file.
+ *
+ * The XPath can be specified in two ways:
+ * <ol>
+ *    <li>By using an XPointerish syntax in the URL: everything following the
+ *         pound                 sign                 (possiby preceding  query
+ * string arguments)  will be treated as the XPath;
+ *     </li>
+ *     <li>Specifying it as a sitemap parameter named "xpath"
+ *  </ol>
+ *
+ * Sample usage:
+ *
+ * Sitemap:
+ * &lt;map:match pattern="documents/**"&gt;
+ *   &lt;map:generate type="xpathdirectory"
+ *     src="    docs/{1}#/article/title|/article/abstract" &gt;
+ *     &lt;          map:parameter name="xmlFiles" value="\.xml$"/&gt;
+ * &lt;/map:generate&gt;
+ * &lt;map: serialize type="xml" /&gt; &lt;/map:match&gt;
+ *
+ * Request:
+ *   http://www.some.host/documents/test
+ * Result:
+ * &lt;collection:collection
+ *   name="test" lastModified="1010400942000"
+ *   date="1/7/02 11:55 AM" requested="true"
+ *   xmlns:collection="http://apache.org/cocoon/collection/1.0"&gt;
+ *   &lt;collection:collection name="subdirectory" lastModified="1010400942000" date="1/7/02 11:55 AM" /&gt;
+ *   &lt;collection:resource name="test.xml" lastModified="1011011579000" date="1/14/02 1:32 PM"&gt;
+ *     &lt;collection:xpath docid="test.xml" query="/article/title"&gt;
+ *       &lt;title&gt;This is a test document&lt;/title&gt;
+ *       &lt;abstract&gt;
+ *         &lt;para&gt;Abstract of my test article&lt;/para&gt;
+ *       &lt;/abstract&gt;
+ *     &lt;/collection:xpath&gt;
+ *   &lt;/collection:resource&gt;
+ *   &lt;collection:resource name="test.gif" lastModified="1011011579000" date="1/14/02 1:32 PM"&gt;
+ * &lt;/collection:collection&gt;
+ *
+ * If you need to use namespaces, you can set them as sitemap parameters in
+ * the form:
+ * lt;map:parameter name="xmlns:<i>your prefix</i>" value="nsURI"/**"&gt;
+ *
+ * @version $Id$
+ */
+public class XPathTraversableGenerator extends TraversableGenerator {
+
+    /** Local name for the element that contains the included XML snippet. */
+    protected static final String XPATH_NODE_NAME = "xpath";
+    /** Attribute for the XPath query. */
+    protected static final String QUERY_ATTR_NAME = "query";
+    /** The document containing a successful XPath query */
+    protected static final String RESULT_DOCID_ATTR = "docid";
+
+    /** The regular expression for the XML files pattern. */
+    protected RE xmlRE;
+
+    /** The document that should be parsed and (partly) included. */
+    protected Document doc;
+
+    /** The XPath. */
+    protected String xpath;
+
+    /** The XPath processor. */
+    protected XPathProcessor processor;
+
+    /** The prefix resolver for namespaced queries */
+    protected XPathPrefixResolver prefixResolver;
+
+    /** The cocoon context used for mime-type mappings */
+    protected Context context;
+
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        // See if an XPath was specified
+        int pointer;
+        if ((pointer = this.source.indexOf("#")) != -1) {
+            int endpointer = this.source.indexOf('?');
+            if (endpointer != -1) {
+                this.xpath = source.substring(pointer + 1, endpointer);
+            } else {
+                this.xpath = source.substring(pointer + 1);
+            }
+            this.source = src.substring(0, pointer);
+            if (endpointer != -1) {
+                this.source += src.substring(endpointer);
+            }
+        } else {
+            this.xpath = par.getParameter("xpath", null);
+        }
+        this.cacheKeyParList.add(this.xpath);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Applying XPath: " + xpath + " to collection " + source);
+        }
+
+        String xmlFilesPattern = null;
+        try {
+            xmlFilesPattern = par.getParameter("xmlFiles", "\\.xml$");
+            this.cacheKeyParList.add(xmlFilesPattern);
+            this.xmlRE = new RE(xmlFilesPattern);
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("pattern for XML files: " + xmlFilesPattern);
+            }
+        } catch (RESyntaxException rese) {
+            throw new ProcessingException("Syntax error in regexp pattern '"
+                    + xmlFilesPattern + "'", rese);
+        }
+
+        String[] params = par.getNames();
+        this.prefixResolver = new XPathPrefixResolver(this.getLogger());
+        for (int i = 0; i < params.length; i++) {
+            if (params[i].startsWith("xmlns:")) {
+                String paramValue = par.getParameter(params[i], "");
+                String paramName = params[i].substring(6);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("add param to prefixResolver: " + paramName);
+                }
+                this.prefixResolver.addPrefix(paramName, paramValue);
+            }
+        }
+
+        this.context = ObjectModelHelper.getContext(objectModel);
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        processor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
+    }
+
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release( processor );
+            this.processor = null;
+        }
+        super.dispose();
+    }
+
+    protected void addContent(TraversableSource source)
+    throws SAXException, ProcessingException {
+        super.addContent(source);
+        if (!source.isCollection() && isXML(source) && xpath != null) {
+            performXPathQuery(source);
+        }
+    }
+
+    /**
+     * Determines if a given TraversableSource shall be handled as XML.
+     *
+     * @param path  the TraversableSource to check
+     * @return true  if the given TraversableSource shall handled as XML, false
+     * otherwise.
+     */
+    protected boolean isXML(TraversableSource path) {
+        String mimeType = this.context.getMimeType(path.getName());
+        return this.xmlRE.match(path.getName()) || "text/xml".equalsIgnoreCase(mimeType);
+    }
+
+    /**
+     * Performs an XPath query on the source.
+     * @param in  the Source the XPath is performed on.
+     * @throws SAXException  if something goes wrong while adding the XML snippet.
+     */
+    protected void performXPathQuery(TraversableSource in) throws SAXException {
+        doc = null;
+        try {
+            doc = SourceUtil.toDOM(this.manager, "text/xml", in);
+        } catch (SAXException se) {
+            getLogger().error("Warning:" + in.getName() + " is not a valid XML document. Ignoring");
+        } catch (Exception e) {
+            this.getLogger().error("Unable to resolve and parse document" + e);
+        }
+        if (doc != null) {
+            NodeList nl = processor.selectNodeList(doc.getDocumentElement(), xpath, this.prefixResolver);
+            final String id = in.getName();
+            AttributesImpl attributes = new AttributesImpl();
+            attributes.addAttribute("", RESULT_DOCID_ATTR, RESULT_DOCID_ATTR," CDATA", id);
+            attributes.addAttribute("", QUERY_ATTR_NAME, QUERY_ATTR_NAME, "CDATA",xpath);
+            super.contentHandler.startElement(URI, XPATH_NODE_NAME, PREFIX + ":" + XPATH_NODE_NAME, attributes);
+            DOMStreamer ds = new DOMStreamer(super.xmlConsumer);
+            for (int i = 0; i < nl.getLength(); i++) {
+                ds.stream(nl.item(i));
+            }
+            super.contentHandler.endElement(URI, XPATH_NODE_NAME, PREFIX + ":" + XPATH_NODE_NAME);
+        }
+    }
+
+    /**
+     * Recycle resources
+     *
+     */
+    public void recycle() {
+        this.xpath = null;
+        this.doc = null;
+        this.xmlRE = null;
+        this.prefixResolver = null;
+        this.context = null;
+        super.recycle();
+    }
+
+    /**
+     * A brain-dead PrefixResolver implementation
+     */
+    class XPathPrefixResolver implements PrefixResolver {
+
+        private Map params;
+
+        private Logger logger;
+
+        public XPathPrefixResolver(Logger logger) {
+            this.params = new HashMap();
+            this.logger = logger;
+        }
+
+        /**
+         * Get a namespace URI given a prefix.
+         *
+         * @see org.apache.excalibur.xml.xpath.PrefixResolver#prefixToNamespace(java.lang.String)
+         */
+        public String prefixToNamespace(String prefix) {
+            if (this.logger.isDebugEnabled()) {
+                this.logger.debug("prefix: " + prefix);
+            }
+            if (this.params.containsKey(prefix)) {
+                if(this.logger.isDebugEnabled()) {
+                    this.logger.debug("prefix; " + prefix + " - namespace: " + this.params.get(prefix));
+                }
+                return (String) this.params.get(prefix);
+            }
+            return null;
+        }
+
+        public void addPrefix(String prefix, String uri) {
+            this.params.put(prefix, uri);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/Bundle.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/Bundle.java
new file mode 100644
index 0000000..6ec0674
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/Bundle.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.i18n;
+
+import java.util.MissingResourceException;
+
+/**
+ * Resource bundle component interface.
+ * Provide the minimal number of methods to be used for i18n.
+ *
+ * @version $Id$
+ */
+public interface Bundle {
+
+    String ROLE = Bundle.class.getName();
+
+    /**
+     * Get string value by key.
+     *
+     * @param key
+     * @return Resource as string.
+     * @exception MissingResourceException if resource was not found
+     */
+    String getString(String key) throws MissingResourceException;
+
+    /**
+     * Get object value by key.
+     *
+     * @param key The resource key.
+     * @return The resource as object.
+     * @exception MissingResourceException if resource was not found
+     */
+    Object getObject(String key) throws MissingResourceException;
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/BundleFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/BundleFactory.java
new file mode 100644
index 0000000..290d200
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/BundleFactory.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.i18n;
+
+import java.util.Locale;
+
+/**
+ * Bundle Factory implementations are responsible for loading and providing
+ * particular types of resource bundles, implementors of Bundle interface.
+ *
+ * @version $Id$
+ */
+public interface BundleFactory {
+
+    /**
+     * Bundle factory ROLE name
+     */
+    String ROLE = BundleFactory.class.getName();
+
+    /**
+     * Constants for bundle factory configuration keys
+     */
+    static class ConfigurationKeys {
+        /**
+         * Configuration element specifying default location of the
+         * resource bundles.
+         *
+         * @see BundleFactory#select(String, String)
+         * @see BundleFactory#select(String, java.util.Locale)
+         */
+        public static final String ROOT_DIRECTORY = "catalogue-location";
+
+        /**
+         * Configuration element specifying role of the Store instance to use
+         * for storing cached bundles
+         * @since 2.1.8
+         */
+        public static final String STORE_ROLE = "store-role";
+
+        /**
+         * Configuration element specifying delay (in ms) between
+         * reload checks.
+         * @since 2.1.8
+         */
+        public static final String RELOAD_INTERVAL = "reload-interval";
+    }
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale name.
+     *
+     * @param base    catalogue base location (URI)
+     * @param bundleName    bundle name
+     * @param locale  locale name
+     * @return        the bundle
+     * @exception     Exception if a bundle is not found
+     */
+    Bundle select(String base, String bundleName, String locale) throws Exception;
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale.
+     *
+     * @param base    catalogue base location (URI)
+     * @param bundleName    bundle name
+     * @param locale  locale
+     * @return        the bundle
+     * @exception     Exception if a bundle is not found
+     */
+    Bundle select(String base, String bundleName, Locale locale) throws Exception;
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale.
+     *
+     * @param directories    catalogue base location (URI)
+     * @param bundleName    bundle name
+     * @param locale  locale
+     * @return        the bundle
+     * @exception     Exception if a bundle is not found
+     */
+    Bundle select(String[] directories, String bundleName, Locale locale) throws Exception;
+
+    /**
+     * Select a bundle based on the bundle name and the locale name from
+     * the default catalogue.
+     *
+     * @param bundleName    bundle name
+     * @param locale  locale name
+     * @return        the bundle
+     * @exception     Exception if a bundle is not found
+     */
+    Bundle select(String bundleName, String locale) throws Exception;
+
+    /**
+     * Select a bundle based on the bundle name and the locale from
+     * the default catalogue.
+     *
+     * @param bundleName    bundle name
+     * @param locale  locale
+     * @return        the bundle
+     * @exception     Exception if a bundle is not found
+     */
+    Bundle select(String bundleName, Locale locale) throws Exception;
+
+    /**
+     * Releases a bundle back to the bundle factory when it's not needed
+     * anymore.
+     * @param bundle the bundle
+     */
+    void release(Bundle bundle);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/I18nUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/I18nUtils.java
new file mode 100644
index 0000000..e02c1eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/I18nUtils.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.i18n;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.transformation.I18nTransformer;
+import org.apache.cocoon.util.Deprecation;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * A utility class for i18n formatting and parsing routing.
+ *
+ * @version $Id$
+ */
+public class I18nUtils {
+
+    // Locale string delimiter
+    private static final String LOCALE_DELIMITER = "_-@.";
+
+    /**
+     * Did we already encountered an old namespace? This is static to ensure
+     * that the associated message will be logged only once.
+     */
+    private static boolean deprecationFound = false;
+
+    private I18nUtils() {
+        // Disable instantiation
+    }
+
+    /**
+     * Parses given locale string to Locale object. If the string is null
+     * then the given locale is returned.
+     *
+     * @param localeString a string containing locale in
+     * <code>language_country_variant</code> format.
+     * @param defaultLocale returned if localeString is <code>null</code>
+     */
+    public static Locale parseLocale(String localeString, Locale defaultLocale) {
+        if (localeString != null) {
+            StringTokenizer st = new StringTokenizer(localeString,
+                                                     LOCALE_DELIMITER);
+            String l = st.hasMoreElements() ? st.nextToken()
+                                            : defaultLocale.getLanguage();
+            String c = st.hasMoreElements() ? st.nextToken() : "";
+            String v = st.hasMoreElements() ? st.nextToken() : "";
+            return new Locale(l, c, v);
+        }
+
+        return defaultLocale;
+    }
+
+    /**
+     * Parses given locale string to Locale object. If the string is null
+     * then the VM default locale is returned.
+     *
+     * @param localeString a string containing locale in
+     * <code>language_country_variant</code> format.
+     *
+     * @see #parseLocale(String, Locale)
+     * @see java.util.Locale#getDefault()
+     */
+    public static Locale parseLocale(String localeString) {
+        return parseLocale(localeString, Locale.getDefault());
+    }
+
+
+    /**
+     * Callback interface for
+     * {@link I18nUtils#findLocale(Map, String, Parameters, Locale, boolean, boolean, boolean, I18nUtils.LocaleValidator)}
+     * @since 2.1.6
+     */
+    public interface LocaleValidator {
+
+        /**
+         * @param name of the locale (for debugging)
+         * @param locale to test
+         * @return true if locale satisfies validator's criteria
+         */
+        public boolean test(String name, Locale locale);
+    }
+
+    /**
+     * Find a suitable locale from an objectModel.
+     * @since 2.1.6
+     * @return locale found, or null if none found.
+     */
+    public static Locale findLocale(Map objectModel,
+                                    String attribute,
+                                    Parameters parameters,
+                                    Locale defaultLocale,
+                                    boolean useLocale,
+                                    boolean useLocales,
+                                    boolean useBlankLocale,
+                                    LocaleValidator test) {
+        String localeStr;
+        Locale locale;
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        // 1. Request parameter 'locale'
+        localeStr = request.getParameter(attribute);
+        if (localeStr != null) {
+            locale = parseLocale(localeStr);
+            if (test == null || test.test("request", locale)) {
+                return locale;
+            }
+        }
+
+        // 2. Session attribute 'locale'
+        Session session = request.getSession(false);
+        if (session != null &&
+                ((localeStr = (String) session.getAttribute(attribute)) != null)) {
+            locale = parseLocale(localeStr);
+            if (test == null || test.test("session", locale)) {
+                return locale;
+            }
+        }
+
+        // 3. First matching cookie parameter 'locale' within each cookie sent
+        Cookie[] cookies = request.getCookies();
+        if (cookies != null) {
+            for (int i = 0; i < cookies.length; i++) {
+                Cookie cookie = cookies[i];
+                if (cookie.getName().equals(attribute)) {
+                    localeStr = cookie.getValue();
+                    locale = parseLocale(localeStr);
+                    if (test == null || test.test("cookie", locale)) {
+                        return locale;
+                    }
+                    break;
+                }
+            }
+        }
+
+        // 4. Sitemap parameter "locale"
+        if (parameters != null) {
+            localeStr = parameters.getParameter("locale", null);
+            if (localeStr != null) {
+                locale = parseLocale(localeStr);
+                if (test == null || test.test("sitemap", locale)) {
+                    return locale;
+                }
+            }
+        }
+
+        // 5. Locale setting of the requesting browser or server default
+        if (useLocale && !useLocales) {
+            locale = request.getLocale();
+            if (test == null || test.test("request", locale)) {
+                return locale;
+            }
+        }
+        if (useLocales) {
+            Enumeration locales = request.getLocales();
+            while (locales.hasMoreElements()) {
+                locale = (Locale)locales.nextElement();
+                if (test == null || test.test("request", locale)) {
+                    return locale;
+                }
+            }
+        }
+
+        // 6. Default
+        if (defaultLocale != null) {
+            locale = defaultLocale;
+            if (test == null || test.test("default", locale)) {
+                return locale;
+            }
+        }
+
+        // 7. Blank
+        if (useBlankLocale) {
+            locale = new Locale("", "");
+            if (test == null || test.test("blank", locale)) {
+                return locale;
+            }
+        }
+
+        // 8. Fail
+        return null;
+    }
+
+    /**
+     * Find a suitable locale from an objectModel.
+     * @since 2.1.6
+     * @return locale found, or server default (never null).
+     */
+    public static Locale findLocale(Map objectModel,
+                                    String attribute,
+                                    Parameters parameters,
+                                    Locale defaultLocale,
+                                    boolean useLocale) {
+        return findLocale(objectModel, attribute, parameters, defaultLocale, useLocale, false, false, null);
+    }
+
+    /**
+     * Store locale in request, session, or cookie.
+     * @since 2.1.6
+     */
+    public static void storeLocale(Map objectModel,
+                                   String attribute,
+                                   String locale,
+                                   boolean storeInRequest,
+                                   boolean storeInSession,
+                                   boolean storeInCookie,
+                                   boolean createSession) {
+        // store in a request if so configured
+        if (storeInRequest) {
+            Request request = ObjectModelHelper.getRequest(objectModel);
+            request.setAttribute(attribute, locale);
+        }
+
+        // store in session if so configured
+        if (storeInSession) {
+            Request request = ObjectModelHelper.getRequest(objectModel);
+            Session session = request.getSession(createSession);
+            if (session != null) {
+                session.setAttribute(attribute, locale);
+            }
+        }
+
+        // store in a cookie if so configured
+        if (storeInCookie) {
+            Response response = ObjectModelHelper.getResponse(objectModel);
+            response.addCookie(response.createCookie(attribute, locale));
+        }
+    }
+
+    public static boolean matchesI18nNamespace(String uri) {
+        if (I18nTransformer.I18N_NAMESPACE_URI.equals(uri)) {
+            return true;
+        } else if (I18nTransformer.I18N_OLD_NAMESPACE_URI.equals(uri)) {
+            if (!deprecationFound) {
+                deprecationFound = true;
+                Deprecation.logger.warn("The namespace <" + I18nTransformer.I18N_OLD_NAMESPACE_URI +
+                                        "> is deprecated, use: <" + I18nTransformer.I18N_NAMESPACE_URI + ">");
+            }
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java
new file mode 100644
index 0000000..4f22bfb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundle.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.i18n;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.ExpiresValidity;
+
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.validity.DelayedValidity;
+import org.apache.cocoon.xml.ParamSaxBuffer;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+import java.net.MalformedURLException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Implementation of <code>Bundle</code> interface for XML resources. Represents a
+ * single XML message bundle.
+ *
+ * <p>
+ * XML format for this resource bundle implementation is the following:
+ * <pre>
+ * &lt;catalogue xml:lang="en"&gt;
+ *   &lt;message key="key1"&gt;Message &lt;br/&gt; Value 1&lt;/message&gt;
+ *   &lt;message key="key2"&gt;Message &lt;br/&gt; Value 1&lt;/message&gt;
+ *   ...
+ * &lt;/catalogue&gt;
+ * </pre>
+ *
+ * <p>
+ * Value can be any well formed XML snippet and it will be cached by the key specified
+ * in the attribute <code>key</code>. Objects returned by this {@link Bundle} implementation
+ * are instances of the {@link ParamSaxBuffer} class.
+ *
+ * <p>
+ * If value for a key is not present in this bundle, parent bundle will be queried.
+ *
+ * @version $Id$
+ */
+public class XMLResourceBundle extends AbstractLogEnabled
+                               implements Bundle {
+
+    /**
+     * XML bundle root element name
+     */
+    public static final String EL_CATALOGUE = "catalogue";
+
+    /**
+     * XML bundle message element name
+     */
+    public static final String EL_MESSAGE = "message";
+
+    /**
+     * XML bundle message element's key attribute name
+     */
+    public static final String AT_KEY = "key";
+
+    /**
+     * Source URI of the bundle
+     */
+    private String sourceURI;
+
+    /**
+     * Bundle validity
+     */
+    private SourceValidity validity;
+
+    /**
+     * Locale of the bundle
+     */
+    private Locale locale;
+
+    /**
+     * Parent of the current bundle
+     */
+    protected Bundle parent;
+
+    /**
+     * Objects stored in the bundle
+     */
+    protected Map values;
+
+
+    /**
+     * Processes XML bundle file and creates map of values
+     */
+    private static class SAXContentHandler implements ContentHandler {
+        private Map values;
+        private int state;
+        private String namespace;
+        private ParamSaxBuffer buffer;
+
+        public SAXContentHandler(Map values) {
+            this.values = values;
+        }
+
+        public void setDocumentLocator(Locator arg0) {
+            // Ignore
+        }
+
+        public void startDocument() throws SAXException {
+            // Ignore
+        }
+
+        public void endDocument() throws SAXException {
+            // Ignore
+        }
+
+        public void processingInstruction(String arg0, String arg1) throws SAXException {
+            // Ignore
+        }
+
+        public void skippedEntity(String arg0) throws SAXException {
+            // Ignore
+        }
+
+        public void startElement(String ns, String localName, String qName, Attributes atts) throws SAXException {
+            switch (this.state) {
+                case 0:
+                    // <i18n:catalogue>
+                    if (!"".equals(ns) && !I18nUtils.matchesI18nNamespace(ns)) {
+                        throw new SAXException("Root element <" + EL_CATALOGUE +
+                                               "> must be non-namespaced or in i18n namespace.");
+                    }
+                    if (!EL_CATALOGUE.equals(localName)) {
+                        throw new SAXException("Root element must be <" + EL_CATALOGUE + ">.");
+                    }
+                    this.namespace = ns;
+                    this.state++;
+                    break;
+
+                case 1:
+                    // <i18n:message>
+                    if (!EL_MESSAGE.equals(localName)) {
+                        throw new SAXException("<" + EL_CATALOGUE + "> must contain <" +
+                                               EL_MESSAGE + "> elements only.");
+                    }
+                    if (!this.namespace.equals(ns)) {
+                        throw new SAXException("<" + EL_MESSAGE + "> element must be in '" +
+                                               this.namespace + "' namespace.");
+                    }
+                    String key =  atts.getValue(AT_KEY);
+                    if (key == null) {
+                        throw new SAXException("<" + EL_MESSAGE + "> must have '" +
+                                               AT_KEY + "' attribute.");
+                    }
+                    this.buffer = new ParamSaxBuffer();
+                    this.values.put(key, this.buffer);
+                    this.state++;
+                    break;
+
+                case 2:
+                    this.buffer.startElement(ns, localName, qName, atts);
+                    break;
+
+                default:
+                    throw new SAXException("Internal error: Invalid state");
+            }
+        }
+
+        public void endElement(String ns, String localName, String qName) throws SAXException {
+            switch (this.state) {
+                case 0:
+                    break;
+
+                case 1:
+                    // </i18n:catalogue>
+                    this.state--;
+                    break;
+
+                case 2:
+                    if (this.namespace.equals(ns) && EL_MESSAGE.equals(localName)) {
+                        // </i18n:message>
+                        this.buffer = null;
+                        this.state--;
+                    } else {
+                        this.buffer.endElement(ns, localName, qName);
+                    }
+                    break;
+
+                default:
+                    throw new SAXException("Internal error: Invalid state");
+            }
+        }
+
+        public void startPrefixMapping(String prefix, String uri) throws SAXException {
+            if (this.buffer != null) {
+                this.buffer.startPrefixMapping(prefix, uri);
+            }
+        }
+
+        public void endPrefixMapping(String prefix) throws SAXException {
+            if (this.buffer != null) {
+                this.buffer.endPrefixMapping(prefix);
+            }
+        }
+
+        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+            if (this.buffer != null) {
+                this.buffer.ignorableWhitespace(ch, start, length);
+            }
+        }
+
+        public void characters(char[] ch, int start, int length) throws SAXException {
+            if (this.buffer != null) {
+                this.buffer.characters(ch, start, length);
+            }
+        }
+    }
+
+
+    /**
+     * Construct a bundle.
+     * @param sourceURI source URI of the XML bundle
+     * @param locale locale
+     * @param parent parent bundle of this bundle
+     */
+    public XMLResourceBundle(String sourceURI, Locale locale, Bundle parent) {
+        this.sourceURI = sourceURI;
+        this.locale = locale;
+        this.parent = parent;
+        this.values = Collections.EMPTY_MAP;
+    }
+
+    /**
+     * (Re)Loads the XML bundle if necessary, based on the source URI.
+     * @return true if reloaded successfully
+     */
+    protected boolean reload(SourceResolver resolver, long interval) {
+        Source newSource = null;
+        Map newValues;
+
+        try {
+            int valid = this.validity == null ? SourceValidity.INVALID : this.validity.isValid();
+            if (valid != SourceValidity.VALID) {
+                // Saved validity is not valid, get new source and validity
+                newSource = resolver.resolveURI(this.sourceURI);
+                SourceValidity newValidity = newSource.getValidity();
+
+                if (valid == SourceValidity.INVALID || this.validity.isValid(newValidity) != SourceValidity.VALID) {
+                    newValues = new HashMap();
+                    SourceUtil.toSAX(newSource, new SAXContentHandler(newValues));
+                    synchronized (this) {
+                        // Update source validity and values
+                        if (interval > 0 && newValidity != null) {
+                            this.validity = new DelayedValidity(interval, newValidity);
+                        } else {
+                            this.validity = newValidity;
+                        }
+                        this.values = newValues;
+                    }
+                }
+            }
+
+            // Success
+            return true;
+
+        } catch (MalformedURLException e) {
+            getLogger().error("Bundle <" + this.sourceURI + "> not loaded: Invalid URI", e);
+            newValues = Collections.EMPTY_MAP;
+
+        } catch (ResourceNotFoundException e) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().info("Bundle <" + sourceURI + "> not loaded: Source URI not found", e);
+            } else if (getLogger().isInfoEnabled()) {
+                getLogger().info("Bundle <" + sourceURI + "> not loaded: Source URI not found");
+            }
+            newValues = Collections.EMPTY_MAP;
+
+        } catch (SourceNotFoundException e) {
+            // Nominal case where a bundle doesn't exist
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Bundle <" + sourceURI + "> not loaded: Source URI not found");
+            }
+            newValues = Collections.EMPTY_MAP;
+
+        } catch (SAXException e) {
+            getLogger().error("Bundle <" + sourceURI + "> not loaded: Invalid XML", e);
+            // Keep existing loaded values
+            newValues = this.values;
+
+        } catch (Exception e) {
+            getLogger().error("Bundle <" + sourceURI + "> not loaded: Exception", e);
+            // Keep existing loaded values
+            newValues = this.values;
+
+        } finally {
+            if (newSource != null) {
+                resolver.release(newSource);
+            }
+        }
+
+        synchronized (this) {
+            // Use expires validity to delay next reloading.
+            if (interval > 0) {
+                this.validity = new ExpiresValidity(interval);
+            } else {
+                this.validity = null;
+            }
+            this.values = newValues;
+        }
+
+        // Failure
+        return false;
+    }
+
+    /**
+     * Gets the locale of the bundle.
+     *
+     * @return the locale
+     */
+    public Locale getLocale() {
+        return this.locale;
+    }
+
+    /**
+     * Gets the source URI of the bundle.
+     *
+     * @return the source URI
+     */
+    public String getSourceURI() {
+        return this.sourceURI;
+    }
+
+    /**
+     * Gets the validity of the bundle.
+     *
+     * @return the validity
+     */
+    public SourceValidity getValidity() {
+        return this.validity;
+    }
+
+    /**
+     * Get an instance of the {@link ParamSaxBuffer} associated with the key.
+     *
+     * @param key the key
+     * @return the value, or null if no value associated with the key.
+     */
+    public Object getObject(String key) {
+        if (key == null) {
+            return null;
+        }
+
+        Object value = this.values.get(key);
+        if (value != null) {
+            return value;
+        }
+
+        if (this.parent != null) {
+            return this.parent.getObject(key);
+        }
+
+        return null;
+    }
+
+    /**
+     * Get a string representation of the value object by key.
+     *
+     * @param key the key
+     * @return the string value, or null if no value associated with the key.
+     */
+    public String getString(String key) {
+        if (key == null) {
+            return null;
+        }
+
+        Object value = this.values.get(key);
+        if (value != null) {
+            return value.toString();
+        }
+
+        if (this.parent != null) {
+            return this.parent.getString(key);
+        }
+
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundleFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundleFactory.java
new file mode 100644
index 0000000..811dfc9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/XMLResourceBundleFactory.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.i18n;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.store.Store;
+
+import org.apache.cocoon.util.NetUtils;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * This is the XMLResourceBundleFactory, the method for getting and creating
+ * XMLResourceBundles.
+ *
+ * @version $Id$
+ */
+public class XMLResourceBundleFactory extends AbstractLogEnabled
+                                      implements BundleFactory, Serviceable, Configurable,
+                                                 Disposable, ThreadSafe, LogEnabled {
+
+    /**
+     * Root directory to all bundle names
+     */
+    private String directory;
+
+    /**
+     * Reload check interval in milliseconds.
+     * Defaults to 60000 (1 minute), use <code>-1</code> to
+     * disable reloads and <code>0</code> to check for modifications
+     * on each catalogue request.
+     */
+    private long interval;
+
+    /**
+     * Service Manager
+     */
+    protected ServiceManager manager;
+
+    /**
+     * Source resolver
+     */
+    protected SourceResolver resolver;
+
+    /**
+     * Store of the loaded bundles
+     */
+    protected Store cache;
+
+
+    //
+    // Lifecycle
+    //
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    /**
+     * Configure the component.
+     *
+     * @param configuration the configuration
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        this.directory = configuration.getChild(ConfigurationKeys.ROOT_DIRECTORY).getValue("");
+
+        String cacheRole = configuration.getChild(ConfigurationKeys.STORE_ROLE).getValue(Store.TRANSIENT_STORE);
+        try {
+            this.cache = (Store) this.manager.lookup(cacheRole);
+        } catch (ServiceException e) {
+            throw new ConfigurationException("Unable to lookup store '" + cacheRole + "'");
+        }
+
+        this.interval = configuration.getChild(ConfigurationKeys.RELOAD_INTERVAL).getValueAsLong(60000L);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Bundle directory '" + this.directory + "'");
+            getLogger().debug("Store role '" + cacheRole + "'");
+        }
+    }
+
+    /**
+     * Disposes this component.
+     */
+    public void dispose() {
+        this.manager.release(this.resolver);
+        this.manager.release(this.cache);
+        this.resolver = null;
+        this.cache = null;
+        this.manager = null;
+    }
+
+    //
+    // BundleFactory Interface
+    //
+
+    /**
+     * Returns the root directory to all bundles.
+     *
+     * @return the directory path
+     */
+    protected String getDirectory() {
+        return this.directory;
+    }
+
+    /**
+     * Select a bundle based on the bundle name and the locale name.
+     *
+     * @param name        bundle name
+     * @param locale      locale name
+     * @return            the bundle
+     * @exception         Exception if a bundle is not found
+     */
+    public Bundle select(String name, String locale) throws Exception {
+        return select(getDirectory(), name, locale);
+    }
+
+    /**
+     * Select a bundle based on the bundle name and the locale.
+     *
+     * @param name        bundle name
+     * @param locale      locale
+     * @return            the bundle
+     * @exception         Exception if a bundle is not found
+     */
+    public Bundle select(String name, Locale locale) throws Exception {
+        return select(getDirectory(), name, locale);
+    }
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale name.
+     *
+     * @param directory   catalogue base location (URI)
+     * @param name        bundle name
+     * @param localeName  locale name
+     * @return            the bundle
+     * @exception         Exception if a bundle is not found
+     */
+    public Bundle select(String directory, String name, String localeName)
+    throws Exception {
+        return select(directory, name, new Locale(localeName, localeName));
+    }
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale.
+     *
+     * @param directory   catalogue base location (URI)
+     * @param name        bundle name
+     * @param locale      locale
+     * @return            the bundle
+     * @exception         Exception if a bundle is not found
+     */
+    public Bundle select(String directory, String name, Locale locale)
+    throws Exception {
+        return select(new String[] { directory }, name, locale);
+    }
+
+    /**
+     * Select a bundle based on the catalogue base location, bundle name,
+     * and the locale.
+     *
+     * @param directories catalogue base location (URI)
+     * @param name        bundle name
+     * @param locale      locale
+     * @return            the bundle
+     * @exception         Exception if a bundle is not found
+     */
+    public Bundle select(String[] directories, String name, Locale locale)
+    throws Exception {
+        Bundle bundle = _select(directories, 0, name, locale);
+        if (bundle == null) {
+            throw new Exception("Unable to locate resource: " + name);
+        }
+        return bundle;
+    }
+
+    public void release(Bundle bundle) {
+        // Do nothing
+    }
+
+    //
+    // Implementation
+    //
+
+    /**
+     * Select a bundle based on bundle name and locale.
+     *
+     * @param directories       catalogue location(s)
+     * @param name              bundle name
+     * @param locale            locale
+     * @return                  the bundle
+     */
+    private XMLResourceBundle _select(String[] directories, int index, String name,
+                                      Locale locale)
+    throws Exception {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Selecting from: " + name + ", locale: " + locale +
+                              ", directory: " + directories[index]);
+        }
+
+        final String cacheKey = "XRB" + getCacheKey(directories, index, name, locale);
+
+        XMLResourceBundle bundle = selectCached(cacheKey);
+        if (bundle == null) {
+            synchronized (this) {
+                bundle = selectCached(cacheKey);
+                if (bundle == null) {
+                    boolean localeAvailable = (locale != null && !locale.getLanguage().equals(""));
+                    index++;
+
+                    // Find parent bundle first
+                    XMLResourceBundle parent = null;
+                    if (localeAvailable && index == directories.length) {
+                        // all directories have been searched with this locale,
+                        // now start again with the first directory and the parent locale
+                        parent = _select(directories, 0, name, getParentLocale(locale));
+                    } else if (index < directories.length) {
+                        // there are directories left to search for with this locale
+                        parent = _select(directories, index, name, locale);
+                    }
+
+                    // Create this bundle (if source exists) and pass parent to it.
+                    final String sourceURI = getSourceURI(directories[index - 1], name, locale);
+                    bundle = _create(sourceURI, locale, parent);
+                    updateCache(cacheKey, bundle);
+                }
+            }
+        }
+        return bundle;
+    }
+
+    /**
+     * Constructs new bundle.
+     *
+     * <p>
+     * If there is a problem loading the bundle, created bundle will be empty.
+     *
+     * @param sourceURI   source URI of the XML resource bundle
+     * @param locale      locale of the bundle
+     * @param parent      parent bundle, if any
+     * @return            the bundle
+     */
+    private XMLResourceBundle _create(String sourceURI,
+                                      Locale locale,
+                                      XMLResourceBundle parent) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Creating bundle <" + sourceURI + ">");
+        }
+
+        XMLResourceBundle bundle = new XMLResourceBundle(sourceURI, locale, parent);
+        bundle.enableLogging(getLogger());
+        bundle.reload(this.resolver, this.interval);
+        return bundle;
+    }
+
+    /**
+     * Returns the next locale up the parent hierarchy.
+     * E.g. the parent of new Locale("en","us","mac") would be
+     * new Locale("en", "us", "").
+     *
+     * @param locale      the locale
+     * @return            the parent locale
+     */
+    protected Locale getParentLocale(Locale locale) {
+        Locale newloc;
+        if (locale.getVariant().equals("")) {
+            if (locale.getCountry().equals("")) {
+                newloc = new Locale("", "", "");
+            } else {
+                newloc = new Locale(locale.getLanguage(), "", "");
+            }
+        } else {
+            newloc = new Locale(locale.getLanguage(), locale.getCountry(), "");
+        }
+        return newloc;
+    }
+
+    /**
+     * Creates a cache key for the bundle.
+     * @return the cache key
+     */
+    protected String getCacheKey(String[] directories, int index, String name, Locale locale)
+    throws SourceException {
+        StringBuffer cacheKey = new StringBuffer();
+        if (index < directories.length) {
+            cacheKey.append(":");
+            cacheKey.append(getSourceURI(directories[index], name, locale));
+            index++;
+            cacheKey.append(getCacheKey(directories, index, name, locale));
+        } else if ((locale != null && !locale.getLanguage().equals(""))) {
+            cacheKey.append(getCacheKey(directories, 0, name, getParentLocale(locale)));
+        }
+        return cacheKey.toString();
+    }
+
+    /**
+     * Maps a bundle name and locale to a bundle source URI.
+     * If you need a different mapping, then just override this method.
+     *
+     * @param base    the base URI for the catalogues
+     * @param name    the name of the catalogue
+     * @param locale  the locale of the bundle
+     * @return        the source URI for the bundle
+     */
+    protected String getSourceURI(String base, String name, Locale locale)
+    throws SourceException {
+        // If base is null default to the current location
+        if (base == null) {
+            base = "";
+        }
+
+        // Resolve base URI
+        Source src = null;
+        Map parameters = Collections.EMPTY_MAP;
+        StringBuffer sb = new StringBuffer();
+        try {
+            src = this.resolver.resolveURI(base);
+
+            // Deparameterize base URL before adding catalogue name
+            String uri = NetUtils.deparameterize(src.getURI(),
+                                                 parameters = new HashMap(7));
+
+            // Append trailing slash
+            sb.append(uri);
+            if (!uri.endsWith("/")) {
+                sb.append('/');
+            }
+
+        } catch (IOException e) {
+            throw new SourceNotFoundException("Cannot resolve catalogue base URI <" + base + ">", e);
+        } finally {
+            this.resolver.release(src);
+        }
+
+        // Append catalogue name
+        sb.append(name);
+
+        // Append catalogue locale
+        if (locale != null) {
+            if (!locale.getLanguage().equals("")) {
+                sb.append("_");
+                sb.append(locale.getLanguage());
+            }
+            if (!locale.getCountry().equals("")) {
+                sb.append("_");
+                sb.append(locale.getCountry());
+            }
+            if (!locale.getVariant().equals("")) {
+                sb.append("_");
+                sb.append(locale.getVariant());
+            }
+        }
+        sb.append(".xml");
+
+        // Reconstruct complete bundle URI with parameters
+        String uri = NetUtils.parameterize(sb.toString(), parameters);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Resolved name: " + name +
+                              ", locale: " + locale + " --> " + uri);
+        }
+        return uri;
+    }
+
+    /**
+     * Selects a bundle from the cache, and reloads it if needed.
+     *
+     * @param cacheKey    caching key of the bundle
+     * @return            the cached bundle; null, if not found
+     */
+    protected XMLResourceBundle selectCached(String cacheKey) {
+        XMLResourceBundle bundle = (XMLResourceBundle) this.cache.get(cacheKey);
+
+        if (bundle != null && this.interval != -1) {
+            // Reload this bundle and all parent bundles, as necessary
+            for (XMLResourceBundle b = bundle; b != null; b = (XMLResourceBundle) b.parent) {
+                b.reload(this.resolver, this.interval);
+            }
+        }
+
+        return bundle;
+    }
+
+    /**
+     * Stores bundle in the cache.
+     *
+     * @param cacheKey    caching key of the bundle
+     * @param bundle      bundle to be placed in the cache
+     */
+    protected void updateCache(String cacheKey, XMLResourceBundle bundle) {
+        try {
+            this.cache.store(cacheKey, bundle);
+        } catch (IOException e) {
+            getLogger().error("Bundle <" + bundle.getSourceURI() + ">: unable to store.", e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/package.html
new file mode 100644
index 0000000..acf304a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/i18n/package.html
@@ -0,0 +1,30 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+  <head>
+    <title>Internationalization</title>
+  </head>
+  <body>
+    <h1>Internationalization support.</h1>
+    <p>
+      Internationalization bundle resource handling interfaces and default
+      implementation for XML message catalogue. 
+    </p>
+    <p>
+      Other helper classes for i18n and localization.
+    </p>
+  </body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractPreparableMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractPreparableMatcher.java
new file mode 100644
index 0000000..a631abf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractPreparableMatcher.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.Map;
+
+/**
+ * A matcher that can prepare patterns during sitemap setup for faster match at request time.
+ * This is also a regular matcher, meaning the sitemap can decide either to prepare the pattern
+ * or to match with a request-time evaluated pattern (for {..} substitution).
+ *
+ * @version $Id$
+ */
+public abstract class AbstractPreparableMatcher extends AbstractLogEnabled implements PreparableMatcher {
+
+    /**
+     * Match the pattern by preparing it and matching the prepared pattern.
+     */
+    public Map match (String pattern, Map objectModel, Parameters parameters)
+      throws PatternException {
+        return preparedMatch(preparePattern(pattern), objectModel, parameters);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractRegexpMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractRegexpMatcher.java
new file mode 100644
index 0000000..a163126
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractRegexpMatcher.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.REProgram;
+import org.apache.regexp.RESyntaxException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Base class for all matchers using a regular expression pattern.
+ *
+ * @version $Id$
+ */
+
+public abstract class AbstractRegexpMatcher extends AbstractPreparableMatcher implements ThreadSafe {
+
+    /**
+     * Compile the pattern in a <code>org.apache.regexp.REProgram</code>.
+     */
+    public Object preparePattern(String pattern) throws PatternException {
+        // if pattern is null, return null to allow throwing a located exception in preparedMatch()
+        if (pattern == null) {
+            return null;
+        }
+
+        if (pattern.length() == 0) {
+            pattern = "^$";
+            if (getLogger().isWarnEnabled()) {
+                getLogger().warn("The empty pattern string was rewritten to '^$'"
+                                 + " to match for empty strings.  If you intended"
+                                 + " to match all strings, please change your"
+                                 + " pattern to '.*'");
+            }
+        }
+
+        try {
+            RECompiler compiler = new RECompiler();
+            REProgram program = compiler.compile(pattern);
+            return program;
+
+        } catch (RESyntaxException rse) {
+            getLogger().debug("Failed to compile the pattern '" + pattern + "'", rse);
+            throw new PatternException(rse.getMessage(), rse);
+        }
+    }
+
+    /**
+     * Match the prepared pattern against the value returned by {@link #getMatchString(Map, Parameters)}.
+     */
+    public Map preparedMatch(Object preparedPattern, Map objectModel, Parameters parameters) throws PatternException {
+
+        if(preparedPattern == null) {
+            throw new PatternException("A pattern is needed at " + SitemapParameters.getLocation(parameters));
+        }
+
+        RE re = new RE((REProgram)preparedPattern);
+        String match = getMatchString(objectModel, parameters);
+
+        if (match == null)
+            return null;
+
+        if(re.match(match)) {
+            /* Handle parenthesised subexpressions. XXX: could be faster if we count
+             * parens *outside* the generated code.
+             * Note: *ONE* based, not zero, zero contains complete match
+             */
+            int parenCount = re.getParenCount();
+            Map map = new HashMap();
+            for (int paren = 0; paren <= parenCount; paren++) {
+                map.put(Integer.toString(paren), re.getParen(paren));
+            }
+
+            return map;
+        }
+
+        return null;
+    }
+
+    /**
+     * Get the string to test against the regular expression. To be defined
+     * by concrete subclasses.
+     */
+    protected abstract String getMatchString(Map objectModel, Parameters parameters);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java
new file mode 100644
index 0000000..9cde263
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapParameters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Base class for wildcard matchers
+ *
+ * @version $Id$
+ */
+
+public abstract class AbstractWildcardMatcher extends AbstractPreparableMatcher implements ThreadSafe {
+
+    /**
+     * Compile the pattern in an <code>int[]</code>.
+     */
+    public Object preparePattern(String pattern) {
+        // if pattern is null, return null to allow throwing a located exception in preparedMatch()
+        return pattern == null ? null : WildcardHelper.compilePattern(pattern);
+    }
+
+    /**
+     * Match the prepared pattern against the result of {@link #getMatchString(Map, Parameters)}.
+     */
+    public Map preparedMatch(Object preparedPattern, Map objectModel, Parameters parameters) throws PatternException {
+
+        if(preparedPattern == null) {
+            throw new PatternException("A pattern is needed at " +
+                    SitemapParameters.getLocation(parameters));
+        }
+
+        String match = getMatchString(objectModel, parameters);
+
+        if (match == null) {
+            return null;
+        }
+
+        HashMap map = new HashMap();
+
+        if (WildcardHelper.match(map, match, (int[])preparedPattern)) {
+            return map;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Get the string to test against the wildcard expression. To be defined
+     * by concrete subclasses.
+     */
+    protected abstract String getMatchString(Map objectModel, Parameters parameters);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/CookieMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/CookieMatcher.java
new file mode 100644
index 0000000..b991df2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/CookieMatcher.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Matches cookies agains given name. Returns value of the matched cookie.
+ *
+ * @version $Id$
+ */
+public class CookieMatcher extends AbstractLogEnabled implements Matcher, ThreadSafe {
+
+    public Map match(String pattern, Map objectModel, Parameters parameters)
+            throws PatternException {
+
+        if (pattern == null) {
+            throw new PatternException("No cookie name given.");
+        }
+
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        Cookie[] cookies = request.getCookies();
+        HashMap result = null;
+
+        if (cookies != null) {
+            for (int i = 0; i < cookies.length; i++) {
+                Cookie cookie = cookies[i];
+                if (cookie.getName().equals(pattern)) {
+                    result = new HashMap();
+                    result.put("1", cookie.getValue());
+                    break;
+                }
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/HeaderMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/HeaderMatcher.java
new file mode 100644
index 0000000..e38dd70
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/HeaderMatcher.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class allows for matching based on a request header.
+ * If the specified request header parameter exists, its value is
+ * retrieved for later sitemap substitution.
+ *
+ * <p><b>Example:</b></p>
+ * <pre>
+ * &lt;map:match type="header" pattern="referer"&gt;
+ *     &lt;map:redirect-to uri="{1}"/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class HeaderMatcher implements Matcher, ThreadSafe
+{
+    /**
+     * Match method to see if the request header exists. If it does
+     * have a value the header added to the array list for later
+     * sitemap substitution.
+     *
+     * @param pattern name of request header to find
+     * @param objectModel environment passed through via cocoon
+     * @return null or map containing value of request header 'pattern'
+     */
+    public Map match(String pattern, Map objectModel, Parameters parameters) {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        String value = request.getHeader(pattern);
+        if (value == null) {
+            return null; // no request header defined
+        } else {
+            Map map = new HashMap();
+            map.put("1", value);
+            return map; // request header defined, return map
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/LocaleMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/LocaleMatcher.java
new file mode 100644
index 0000000..88f0880
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/LocaleMatcher.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.i18n.I18nUtils;
+import org.apache.cocoon.sitemap.PatternException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * A matcher that locates and identifies to the pipeline a source document to
+ * be used as the content for an i18n site, based upon a locale provided in a
+ * range of ways.
+ *
+ * <h1>Configuration</h1>
+ * <p>A sample configuration (given in the &lt;map:matchers&gt; section of the
+ * sitemap) is given below. This configuration shows default values.
+ * </p>
+ * <pre>
+ *   &lt;map:matcher name="i18n" src="org.apache.cocoon.matching.LocaleMatcher"&gt;
+ *     &lt;locale-attribute&gt;locale&lt;/locale-attribute&gt;
+ *     &lt;negotiate&gt;false&lt;/negotiate&gt;
+ *     &lt;use-locale&gt;true&lt;/use-locale&gt;
+ *     &lt;use-locales&gt;false&lt;/use-locales&gt;
+ *     &lt;use-blank-locale&gt;true&lt;/use-blank-locale&gt;
+ *     &lt;default-locale language="en" country="US"/&gt;
+ *     &lt;store-in-request&gt;false&lt;store-in-request&gt;
+ *     &lt;create-session&gt;false&lt;create-session&gt;
+ *     &lt;store-in-session&gt;false&lt;store-in-session&gt;
+ *     &lt;store-in-cookie&gt;false&lt;store-in-cookie&gt;
+ *   &lt;/map:matcher&gt;
+ * </pre>
+ *
+ * <p>Above configuration parameters mean:
+ *   <ul>
+ *     <li><b>locale-attribute</b> specifies the name of the request
+ *     parameter / session attribute / cookie that is to be used as a locale
+ *     (defaults to <code>locale</code>)</li>
+ *     <li><b>negotiate</b> specifies whether matcher should check that
+ *     resource exists. If set to true, matcher will look for the locale
+ *     till matching resource is found. If no resource found even with
+ *     default or blank locale, matcher will not match.</li>
+ *     <li><b>use-locale</b> specifies whether the primary locale provided
+ *     by the user agent (or server default, is no locale passed by the agent)
+ *     is to be used</li>
+ *     <li><b>use-locales</b> specifies whether each locale provided by the
+ *     user agent should be tested in turn (makes sense only when
+ *     <code>negotiate</code> is set to <code>true</code>)</li>
+ *     <li><b>default-locale</b> specifies the default locale to be used when
+ *     none matches any of the previous ones.</li>
+ *     <li><b>use-blank-locale</b> specifies whether a file should be looked
+ *     for without a locale in its filename or filepath (e.g. after looking
+ *     for index.en.html, try index.html) if none matches any of the previous
+ *     locales.</li>
+ *     <li><b>store-in-request</b> specifies whether found locale should be
+ *     stored as request attribute.</li>
+ *     <li><b>create-session</b> specifies whether session should be created
+ *     when storing found locale as session attribute.</li>
+ *     <li><b>store-in-session</b> specifies whether found locale should be
+ *     stored as session attribute.</li>
+ *     <li><b>store-in-cookie</b> specifies whether found locale should be
+ *     stored as cookie.</li>
+ *   </ul>
+ * </p>
+ *
+ * <h1>Usage</h1>
+ * <p>This matcher will be used in a pipeline like so:</p>
+ * <pre>
+ *   &lt;map:match pattern="*.html"&gt;
+ *     &lt;map:match type="i18n" pattern="xml/{1}.*.xml"&gt;
+ *       &lt;map:generate src="{source}"/&gt;
+ *       ...
+ *     &lt;/map:match&gt;
+ *   &lt;/map:match&gt;
+ * </pre>
+ * <p><code>*</code> in the pattern identifies the place where locale should
+ * be inserted. In case of a blank locale, if character before and after
+ * <code>*</code> is the same (like in example above), duplicate will
+ * be removed (<code>xml/{1}.*.xml</code> becomes <code>xml/{1}.xml</code>).</p>
+ *
+ * <h1>Locale Identification</h1>
+ * <p>Locales will be tested in following order:</p>
+ * <ul>
+ *   <li>Locale provided as a request parameter</li>
+ *   <li>Locale provided as a session attribute</li>
+ *   <li>Locale provided as a cookie</li>
+ *   <li>Locale provided using a sitemap parameter<br>
+ *   (&lt;map:parameter name="locale" value="{1}"/&gt; style parameter within
+ *   the &lt;map:match&gt; node)</li>
+ *   <li>Locale provided by the user agent, or server default,
+ *   if <code>use-locale</code> is set to <code>true</code></li>
+ *   <li>Locales provided by the user agent, if <code>use-locales</code>
+ *   is set to <code>true</code>.</li>
+ *   <li>The default locale, if specified in the matcher's configuration</li>
+ *   <li>Resources with no defined locale (blank locale)</li>
+ * </ul>
+ * <p>If <code>negotiate</code> mode is set to <code>true</code>, a source will
+ * be looked up using each locale. Where the full locale (language, country,
+ * variant) doesn't match, it will fall back first to language and country,
+ * and then just language, before moving on to the next locale.</p>
+ * <p>If <code>negotiate</code> mode is set to <code>false</code> (default),
+ * first found locale will be returned.</p>
+ *
+ * <h1>Sitemap Variables</h1>
+ * <p>Once a matching locale has been found, the following sitemap variables
+ * will be available to sitemap elements contained within the matcher:</p>
+ * <ul>
+ *   <li>{source}: The URI of the source that matched</li>
+ *   <li>{locale}: The locale that matched that resource</li>
+ *   <li>{matched-locale}: The part of the locale that matched the resource</li>
+ *   <li>{language}: The language of the matching resource</li>
+ *   <li>{country}: The country of the matching resource</li>
+ *   <li>{variant}: The variant of the matching resource</li>
+ * </ul>
+ *
+ * @since 2.1.6
+ * @version $Id$
+ */
+public class LocaleMatcher extends AbstractLogEnabled
+                           implements Matcher, ThreadSafe, Serviceable, Configurable, Disposable {
+
+    private static final String DEFAULT_LOCALE_ATTRIBUTE = "locale";
+    private static final String DEFAULT_DEFAULT_LANG = "en";
+    private static final String DEFAULT_DEFAULT_COUNTRY = "US";
+    private static final String DEFAULT_DEFAULT_VARIANT = "";
+
+    private ServiceManager manager;
+    private SourceResolver resolver;
+
+    /**
+     * Name of the locale request parameter, session attribute, cookie.
+     */
+    private String localeAttribute;
+
+    /**
+     * Whether to query locale provided by the user agent or not.
+     */
+    private boolean useLocale;
+
+    private boolean useLocales;
+    private Locale defaultLocale;
+    private boolean useBlankLocale;
+    private boolean testResourceExists;
+
+    /**
+     * Store the locale in request. Default is not to do this.
+     */
+    private boolean storeInRequest;
+
+    /**
+     * Store the locale in session, if available. Default is not to do this.
+     */
+    private boolean storeInSession;
+
+    /**
+     * Should we create a session if needed. Default is not to do this.
+     */
+    private boolean createSession;
+
+    /**
+     * Should we add a cookie with the locale. Default is not to do this.
+     */
+    private boolean storeInCookie;
+
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    public void configure(Configuration config) {
+        this.storeInRequest = config.getChild("store-in-request").getValueAsBoolean(false);
+        this.createSession = config.getChild("create-session").getValueAsBoolean(false);
+        this.storeInSession = config.getChild("store-in-session").getValueAsBoolean(false);
+        this.storeInCookie = config.getChild("store-in-cookie").getValueAsBoolean(false);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug((this.storeInRequest ? "will" : "won't") + " set values in request");
+            getLogger().debug((this.createSession ? "will" : "won't") + " create session");
+            getLogger().debug((this.storeInSession ? "will" : "won't") + " set values in session");
+            getLogger().debug((this.storeInCookie ? "will" : "won't") + " set values in cookies");
+        }
+
+        this.localeAttribute = config.getChild("locale-attribute").getValue(DEFAULT_LOCALE_ATTRIBUTE);
+        this.testResourceExists = config.getChild("negotiate").getValueAsBoolean(false);
+
+        this.useLocale = config.getChild("use-locale").getValueAsBoolean(true);
+        this.useLocales = config.getChild("use-locales").getValueAsBoolean(false);
+        this.useBlankLocale = config.getChild("use-blank-locale").getValueAsBoolean(true);
+
+        Configuration child = config.getChild("default-locale", false);
+        if (child != null) {
+            this.defaultLocale = new Locale(child.getAttribute("language", DEFAULT_DEFAULT_LANG),
+                                            child.getAttribute("country", DEFAULT_DEFAULT_COUNTRY),
+                                            child.getAttribute("variant", DEFAULT_DEFAULT_VARIANT));
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Locale attribute name is " + this.localeAttribute);
+            getLogger().debug((this.testResourceExists ? "will" : "won't") + " negotiate locale");
+            getLogger().debug((this.useLocale ? "will" : "won't") + " use request locale");
+            getLogger().debug((this.useLocales ? "will" : "won't") + " use request locales");
+            getLogger().debug((this.useBlankLocale ? "will" : "won't") + " blank locales");
+            getLogger().debug("default locale " + this.defaultLocale);
+        }
+    }
+
+    public void dispose() {
+        this.manager.release(this.resolver);
+        this.resolver = null;
+        this.manager = null;
+    }
+
+
+    public Map match(final String pattern, Map objectModel, Parameters parameters)
+    throws PatternException {
+        final Map map = new HashMap();
+
+        I18nUtils.LocaleValidator validator = new I18nUtils.LocaleValidator() {
+            public boolean test(String name, Locale locale) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Testing " + name + " locale: '" + locale + "'");
+                }
+                return isValidResource(pattern, locale, map);
+            }
+        };
+
+        Locale locale = I18nUtils.findLocale(objectModel,
+                                             localeAttribute,
+                                             parameters,
+                                             defaultLocale,
+                                             useLocale,
+                                             useLocales,
+                                             useBlankLocale,
+                                             validator);
+
+        if (locale == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("No locale found for resource: " + pattern);
+            }
+            return null;
+        }
+
+        String localeStr = locale.toString();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Locale " + localeStr + " found for resource: " + pattern);
+        }
+
+        I18nUtils.storeLocale(objectModel,
+                              localeAttribute,
+                              localeStr,
+                              storeInRequest,
+                              storeInSession,
+                              storeInCookie,
+                              createSession);
+
+        return map;
+    }
+
+    private boolean isValidResource(String pattern, Locale locale, Map map) {
+        Locale testLocale;
+
+        // Test "language, country, variant" locale
+        if (locale.getVariant().length() > 0) {
+            if (isValidResource(pattern, locale, locale, map)) {
+                return true;
+            }
+        }
+
+        // Test "language, country" locale
+        if (locale.getCountry().length() > 0) {
+            testLocale = new Locale(locale.getLanguage(), locale.getCountry());
+            if (isValidResource(pattern, locale, testLocale, map)) {
+                return true;
+            }
+        }
+
+        // Test "language" locale (or empty - if language is "")
+        testLocale = new Locale(locale.getLanguage(), "");
+        if (isValidResource(pattern, locale, testLocale, map)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean isValidResource(String pattern, Locale locale, Locale testLocale, Map map) {
+        String url;
+
+        String testLocaleStr = testLocale.toString();
+        if ("".equals(testLocaleStr)) {
+            // If same character found before and after the '*', leave only one.
+            int starPos = pattern.indexOf("*");
+            if (starPos < pattern.length() - 1 && starPos > 1 &&
+                    pattern.charAt(starPos - 1) == pattern.charAt(starPos + 1)) {
+                url = pattern.substring(0, starPos - 1) + pattern.substring(starPos + 1);
+            } else {
+                url = StringUtils.replace(pattern, "*", "");
+            }
+        } else {
+            url = StringUtils.replace(pattern, "*", testLocaleStr);
+        }
+
+        boolean result = true;
+        if (testResourceExists) {
+            Source source = null;
+            try {
+                source = resolver.resolveURI(url);
+                result = source.exists();
+            } catch (IOException e) {
+                result = false;
+            } finally {
+                if (source != null) {
+                    resolver.release(source);
+                }
+            }
+        }
+
+        if (result) {
+            map.put("source", url);
+            map.put("matched-locale", testLocaleStr);
+            if (locale != null) {
+                map.put("locale", locale.toString());
+                map.put("language", locale.getLanguage());
+                map.put("country", locale.getCountry());
+                map.put("variant", locale.getVariant());
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/Matcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/Matcher.java
new file mode 100644
index 0000000..b4b7b24
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/Matcher.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface Matcher {
+
+    String ROLE = Matcher.class.getName();
+
+    /**
+     * Matches the pattern against some <code>Request</code> values
+     * and returns a <code>Map</code> object with replacements
+     * for wildcards contained in the pattern.
+     * @param pattern     The pattern to match against. Depending on the
+     *                    implementation the pattern can contain wildcards
+     *                    or regular expressions.
+     * @param objectModel The <code>Map</code> with object of the
+     *                    calling environment which can be used
+     *                    to select values this matchers matches against.
+     * @return Map        The returned <code>Map</code> object with
+     *                    replacements for wildcards/regular-expressions
+     *                    contained in the pattern.
+     *                    If the return value is null there was no match.
+     */
+    Map match (String pattern, Map objectModel, Parameters parameters) throws PatternException;
+}
+
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/MountTableMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/MountTableMatcher.java
new file mode 100644
index 0000000..29fe06a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/MountTableMatcher.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.sitemap.PatternException;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * A matcher that manages a "mount table", allowing to add subsitemaps to a Cocoon application without
+ * modifying the main sitemap. This is especially useful for prototypes and demos where installing
+ * a separate instance of Cocoon is overkill.
+ * <p>
+ * The mount table is an xml file which has a format similar to the <code>map:mount</code> syntax:
+ * <pre>
+ *   &lt;mount-table&gt;
+ *     &lt;mount uri-prefix="foo" src="file://path/to/foo/directory/"/&gt;
+ *     &lt;mount uri-prefix="bar/baz" src="file://path/to/bar-baz/directory/"/&gt;
+ *   &lt;/mount-table&gt;
+ * </pre>
+ * The matcher will scan the mount table for an "uri-prefix" value matching the beginning of the current
+ * request URI, and if found, succeed and populate the "src" and "uri-prefix" sitemap variables.
+ * <p>
+ * Usage in the sitemap is therefore as follows:
+ * <pre>
+ *   &lt;map:match type="mount-table" pattern="path/to/mount-table.xml"&gt;
+ *     &lt;map:mount uri-prefix="{uri-prefix}" src="{src}"/&gt;
+ *   &lt;/map:match&gt;
+ * </pre>
+ * <p>
+ * This matcher accepts a single configuration parameter, indicating if missing mount tables should be
+ * silently ignored (defaults is <code>false</code>, meaning "don't ignore"):
+ * <pre>
+ *   &lt;map:matcher type="mount-table" src="org.apache.cocoon.matching.MountTableMatcher"&gt;
+ *     &lt;map:parameter name="ignore-missing-tables" value="true"/&gt;
+ *   &lt;/map:matcher&gt;
+ * </pre>
+ * <p>
+ * This configuration is used in the main sitemap of Cocoon samples, to allow users to define their own mount
+ * table, but not fail if it does not exist.
+ *
+ * @version $Id$
+ */
+public class MountTableMatcher extends AbstractLogEnabled
+                               implements Matcher, ThreadSafe, Serviceable, Parameterizable {
+
+    private ServiceManager manager;
+    private SourceResolver resolver;
+    private Map mountTables = Collections.synchronizedMap(new HashMap());
+    private boolean ignoreMissingTables;
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    public void parameterize(Parameters params) throws ParameterException {
+        this.ignoreMissingTables = params.getParameterAsBoolean("ignore-missing-tables", false);
+    }
+
+    private Map getMountTable(String src) throws Exception {
+        Source source = null;
+        try {
+            source = this.resolver.resolveURI(src);
+            final String uri = source.getURI();
+
+            // Check if source exists
+            // FIXME: source.exists() returns true in the case of an OSGI bundle uri,
+            // For example if uri=bundle://11/../mount-table.xml, exists() returns true
+            // but the Source is unusable
+            if (!source.exists()) {
+                if (this.ignoreMissingTables) {
+                    return Collections.EMPTY_MAP;
+                } else {
+                    throw new PatternException("Mount table does not exist: '" + uri + "'");
+                }
+            }
+
+            // Source exists
+            Object[] values = (Object[]) this.mountTables.get(uri);
+            if (values != null) {
+                // Check validity
+                SourceValidity oldValidity = (SourceValidity) values[1];
+
+                int valid = oldValidity != null ? oldValidity.isValid() : SourceValidity.INVALID;
+                if (valid == SourceValidity.VALID) {
+                    // Valid without needing the new validity
+                    return (Map) values[0];
+                }
+
+                if (valid == SourceValidity.UNKNOWN &&
+                        oldValidity.isValid(source.getValidity()) == SourceValidity.VALID) {
+                    // Valid after comparing with the new validity
+                    return (Map) values[0];
+                }
+
+                // Invalid: fallback below to read the mount table
+            } else {
+                values = new Object[2];
+            }
+
+            // Read the mount table
+            Map mounts = new HashMap();
+            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+            Configuration config = builder.build(SourceUtil.getInputSource(source));
+
+            Configuration[] children = config.getChildren();
+            for (int i = 0; i < children.length; i++) {
+                Configuration child = children[i];
+                if ("mount".equals(child.getName())) {
+                    String prefix = children[i].getAttribute("uri-prefix");
+                    // Append a '/' at the end of a not-empty prefix
+                    // this avoids flat uri matching which would cause
+                    // exceptions in the sub sitemap!
+                    if (!prefix.endsWith("/") && prefix.length() != 0) {
+                        prefix = prefix + '/';
+                    }
+                    mounts.put(prefix, children[i].getAttribute("src"));
+                } else {
+                    throw new PatternException(
+                        "Unexpected element '" + child.getName() + "' (awaiting 'mount'), at " + child.getLocation());
+                }
+            }
+            values[0] = mounts;
+            values[1] = source.getValidity();
+
+            // Cache it with the source validity
+            this.mountTables.put(uri, values);
+
+            return mounts;
+
+        } catch (SecurityException e) {
+            if (this.ignoreMissingTables) {
+                return Collections.EMPTY_MAP;
+            } else {
+                throw new PatternException("Mount table is not accessible: '" + src + "' (" + e + ")");
+            }
+
+        } finally {
+            if (source != null) {
+                this.resolver.release(source);
+            }
+        }
+    }
+
+    public Map match(String pattern, Map objectModel, Parameters parameters) throws PatternException {
+        Map mounts;
+        try {
+            mounts = getMountTable(pattern);
+        } catch (PatternException pe) {
+            throw pe;
+        } catch (Exception e) {
+            throw new PatternException(e);
+        }
+
+        // Get the request URI
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        String uri = request.getSitemapURI();
+
+        // and search for a matching prefix
+        Iterator iter = mounts.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            String prefix = (String) entry.getKey();
+            if (uri.startsWith(prefix)) {
+                // Found it
+                Map result = new HashMap(2);
+                result.put("uri-prefix", prefix);
+                result.put("src", entry.getValue());
+
+                // Return immediately
+                return result;
+            }
+        }
+
+        // Not found
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/ParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/ParameterMatcher.java
new file mode 100644
index 0000000..a11959e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/ParameterMatcher.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class allows for matching based on a parameter provided from the sitemap.
+ * If the specified sitemap parameter exists, its value is retrieved for later
+ * sitemap substitution.
+ *
+ * <p><b>Example:</b></p>
+ * <pre>
+ * &lt;map:match type="parameter" pattern="dest"&gt;
+ *     &lt;map:redirect-to uri="{1}"/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class ParameterMatcher implements Matcher, ThreadSafe
+{
+    /**
+     * Match method to see if the sitemap parameter exists. If it does
+     * have a value the parameter added to the array list for later
+     * sitemap substitution.
+     *
+     * @param pattern name of sitemap parameter to find
+     * @param objectModel environment passed through via cocoon
+     * @return null or map containing value of sitemap parameter 'pattern'
+     */
+    public Map match(String pattern, Map objectModel, Parameters parameters) {
+
+        String parameter = parameters.getParameter(pattern, null);
+        if (parameter == null) {
+            return null; // no parameter defined
+        } else {
+            Map map = new HashMap();
+            map.put("1", parameter);
+            return map; // parameter defined, return map
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/PreparableMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/PreparableMatcher.java
new file mode 100644
index 0000000..b64ab00
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/PreparableMatcher.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.sitemap.PatternException;
+
+import java.util.Map;
+
+/**
+ * A matcher that can prepare patterns during sitemap setup for faster match at request time.
+ * This is also a regular matcher, meaning the sitemap can decide either to prepare the pattern
+ * or to match with a request-time evaluated pattern (for {..} substitution).
+ *
+ * @version $Id$
+ */
+public interface PreparableMatcher extends Matcher {
+
+    /**
+     * Prepares a pattern in a form that allows faster match. For example, a regular
+     * expression matcher can precompile the expression and return the corresponding
+     * object. This method is called once for each pattern used with a particular matcher
+     * class. The returned value is then passed back as the <code>preparedPattern</code>
+     * parameter of {@link #preparedMatch(Object, Map, Parameters)}.
+     *
+     * @param pattern The pattern to prepare. Depending on the implementation the pattern
+     *                can contain wildcards or regular expressions.
+     * @return an optimized representation of the pattern.
+     * @throws PatternException if the pattern couldn't be prepared.
+     */
+    Object preparePattern(String pattern) throws PatternException;
+
+    /**
+     * Matches the prepared pattern against some values in the object model (most often the
+     * <code>Request</code>) and returns a <code>Map</code> object with replacements
+     * for wildcards contained in the pattern.
+     *
+     * @param preparedPattern The preparedPattern to match against, as returned by {@link #preparePattern(String)}.
+     * @param objectModel     The <code>Map</code> with objects of the calling environment
+     *                        which can be used to select values this matchers matches against.
+     * @return                a <code>Map</code> object with replacements for wildcards/regular-expressions
+     *                        contained in the pattern. If the return value is null there was no match.
+     */
+    Map preparedMatch(Object preparedPattern, Map objectModel, Parameters parameters) throws PatternException;
+}
+
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHeaderMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHeaderMatcher.java
new file mode 100644
index 0000000..f29d94d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHeaderMatcher.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request header (e.g. "referer") against a regular expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>header-name</code></td><td>Name of the request header to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+
+public class RegexpHeaderMatcher extends AbstractRegexpMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.defaultParam = config.getChild("header-name").getValue(null);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("header-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No header name given. FAILING");
+            return null;
+        }
+
+        String result = ObjectModelHelper.getRequest(objectModel).getHeader(paramName);
+        if (result == null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Header '" + paramName + "' not set.");
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHostMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHostMatcher.java
new file mode 100644
index 0000000..f34b0d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpHostMatcher.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import java.util.Map;
+
+/**
+ * Matches the target host ("Host" request header) against a regular expression.
+ *
+ * @version $Id$
+ */
+public class RegexpHostMatcher extends AbstractRegexpMatcher
+{
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+        return ObjectModelHelper.getRequest(objectModel).getHeader("Host");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpParameterMatcher.java
new file mode 100644
index 0000000..2f90e46
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpParameterMatcher.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import java.util.Map;
+
+/**
+ * Matches a sitemap parameter against a regular expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>parameter-name</code></td><td>Name of the sitemap parameter to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RegexpParameterMatcher extends AbstractRegexpMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No parameter name given. FAILING");
+            return null;
+        }
+
+        String result = parameters.getParameter(paramName, null);
+        if (result == null) {
+            getLogger().debug("Parameter '" + paramName + "' not set.");
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestAttributeMatcher.java
new file mode 100644
index 0000000..eac53c9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestAttributeMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request attribute against a regular expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <tableborder="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the request attribute</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RegexpRequestAttributeMatcher extends AbstractRegexpMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("attribute-name").getValue(null);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default attribute-name is = '" + this.defaultParam + "'");
+        }
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("attribute-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No attribute name given. FAILING");
+            return null;
+        }
+
+        Object result = ObjectModelHelper.getRequest(objectModel).getAttribute(paramName);
+        if (result == null) {
+            getLogger().debug("Request attribute '" + paramName + "' not set.");
+            return null;
+        }
+
+        return result.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestParameterMatcher.java
new file mode 100644
index 0000000..e2a3881
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpRequestParameterMatcher.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request parameter against a regular expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>parameter-name</code></td><td>Name of the request parameter to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RegexpRequestParameterMatcher extends AbstractRegexpMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No parameter name given. FAILING");
+            return null;
+        }
+
+        String result = ObjectModelHelper.getRequest(objectModel).getParameter(paramName);
+        if (result == null) {
+            getLogger().debug("Parameter '" + paramName + "' not set.");
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpSessionAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpSessionAttributeMatcher.java
new file mode 100644
index 0000000..1011272
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpSessionAttributeMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a session attribute against a regular expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <tableborder="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the session attribute</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RegexpSessionAttributeMatcher extends AbstractRegexpMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("attribute-name").getValue(null);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default attribute-name is = '" + this.defaultParam + "'");
+        }
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("attribute-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No attribute name given. FAILING");
+            return null;
+        }
+
+        Object result = ObjectModelHelper.getRequest(objectModel).getSession().getAttribute(paramName);
+        if (result == null) {
+            getLogger().debug("Session attribute '" + paramName + "' not set.");
+            return null;
+        }
+
+        return result.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpURIMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpURIMatcher.java
new file mode 100644
index 0000000..3d2232f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RegexpURIMatcher.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches the request URIs against a regular expression pattern.
+ *
+ * @version $Id$
+ */
+public class RegexpURIMatcher extends AbstractRegexpMatcher
+{
+    /**
+     * Return the request URI.
+     */
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+        String uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+
+        if (uri.startsWith("/")) {
+            uri = uri.substring(1);
+        }
+
+        return uri;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestAttributeMatcher.java
new file mode 100644
index 0000000..eeb2054
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestAttributeMatcher.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class allows for matching based on a request attribute.
+ * If the specified request attribute exists, its string representation
+ * is retrieved for later sitemap substitution.
+ *
+ * <p><b>Example:</b></p>
+ * <pre>
+ * &lt;map:match type="request-attribute" pattern="next"&gt;
+ *     &lt;map:redirect-to src="{1}"/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class RequestAttributeMatcher implements Matcher, ThreadSafe
+{
+    /**
+     * Match method to see if the request attribute exists. If it does
+     * have a value the string represenation of attribute is added to
+     * the array list for later sitemap substitution.
+     *
+     * @param pattern name of request attribute to find
+     * @param objectModel environment passed through via cocoon
+     * @return null or map containing value of request attribute 'pattern'
+     */
+    public Map match(String pattern, Map objectModel, Parameters parameters) {
+
+        Object attribute = ObjectModelHelper.getRequest(objectModel).getAttribute(pattern);
+
+        if (attribute == null) {
+            return null;
+        } else {
+            Map map = new HashMap();
+            map.put("1", attribute.toString());
+            return map;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestParameterMatcher.java
new file mode 100644
index 0000000..41d5661
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/RequestParameterMatcher.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class allows for matching based on a request parameter.
+ * If the specified request parameter exists, its value is retrieved for later
+ * sitemap substitution.
+ *
+ * <p><b>Example:</b></p>
+ * <pre>
+ * &lt;map:match type="request" pattern="dest"&gt;
+ *     &lt;map:redirect-to uri="{1}"/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class RequestParameterMatcher implements Matcher, ThreadSafe
+{
+    /**
+     * Match method to see if the request parameter exists. If it does
+     * have a value the parameter is added to the array list for later
+     * sitemap substitution.
+     *
+     * @param pattern name of request parameter to find
+     * @param objectModel environment passed through via cocoon
+     * @return null or map containing value of request parameter 'pattern'
+     */
+    public Map match(String pattern, Map objectModel, Parameters parameters) {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+
+        String parameter = request.getParameter(pattern);
+        if (parameter == null) {
+            return null; // no parameter defined
+        } else {
+            Map map = new HashMap();
+            map.put("1", parameter);
+            return map; // parameter defined, return map
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/SessionAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/SessionAttributeMatcher.java
new file mode 100644
index 0000000..3502fce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/SessionAttributeMatcher.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class allows for matching based on a session attribute.
+ * If the specified session attribute exists, its string representation
+ * is retrieved for later sitemap substitution.
+ *
+ * <p><b>Example:</b></p>
+ * <pre>
+ * &lt;map:match type="session-attribute" pattern="style"&gt;
+ *     &lt;map:read src="{1}"/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class SessionAttributeMatcher implements Matcher, ThreadSafe
+{
+    /**
+     * Match method to see if the request attribute exists. If it does
+     * have a value the string represenation of attribute is added to
+     * the array list for later sitemap substitution.
+     *
+     * @param pattern name of session attribute to find
+     * @param objectModel environment passed through via cocoon
+     * @return null or map containing value of session attribute 'pattern'
+     */
+    public Map match(String pattern, Map objectModel, Parameters parameters) {
+
+        Object attribute = ObjectModelHelper.getRequest(objectModel).getSession().getAttribute(pattern);
+        if (attribute == null) {
+            return null;
+        } else {
+            Map map = new HashMap();
+            map.put("1", attribute.toString());
+            return map;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHeaderMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHeaderMatcher.java
new file mode 100644
index 0000000..69345e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHeaderMatcher.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request header (e.g. "referer") against a wildcard expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>header-name</code></td><td>Name of the request header to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardHeaderMatcher extends AbstractWildcardMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        // Check old name
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+        if (defaultParam != null) {
+            getLogger().warn("'parameter-name' is deprecated. Please use 'header-name'");
+        }
+        // Load with new one
+        this.defaultParam = config.getChild("header-name").getValue(this.defaultParam);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        // Check old name
+        String paramName = parameters.getParameter("parameter-name", null);
+        if (paramName != null) {
+            getLogger().warn("'parameter-name' is deprecated. Please use 'header-name'");
+        } else {
+            paramName = this.defaultParam;
+        }
+
+        // Load with new one.
+        paramName = parameters.getParameter("header-name", paramName);
+
+        if (paramName == null) {
+            getLogger().warn("No header name given. FAILING");
+            return null;
+        }
+
+        String result = ObjectModelHelper.getRequest(objectModel).getHeader(paramName);
+        if (result == null) {
+            getLogger().debug("Header '" + paramName + "' not set.");
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHostMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHostMatcher.java
new file mode 100644
index 0000000..f924dca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardHostMatcher.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import java.util.Map;
+
+/**
+ * Matches the target host ("Host" request header) against a wildcard expression.
+ *
+ * @version $Id$
+ */
+public class WildcardHostMatcher extends AbstractWildcardMatcher
+{
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+        return ObjectModelHelper.getRequest(objectModel).getHeader("Host");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardParameterMatcher.java
new file mode 100644
index 0000000..aa38cb0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardParameterMatcher.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import java.util.Map;
+
+/**
+ * Matches a sitemap parameter against a wildcard expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>parameter-name</code></td><td>Name of the sitemap parameter to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardParameterMatcher extends AbstractWildcardMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No parameter name given. FAILING");
+            return null;
+        }
+
+        String value = parameters.getParameter(paramName, null);
+        if (value == null) {
+            getLogger().debug("Parameter '" + paramName + "' not set.");
+        }
+
+        return value;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestAttributeMatcher.java
new file mode 100644
index 0000000..516c567
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestAttributeMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request attribute against a wildcard expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <tableborder="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the request attribute</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardRequestAttributeMatcher extends AbstractWildcardMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("attribute-name").getValue(null);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default attribute-name is = '" + this.defaultParam + "'");
+        }
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("attribute-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No attribute name given. FAILING");
+            return null;
+        }
+
+        Object result = ObjectModelHelper.getRequest(objectModel).getAttribute(paramName);
+        if (result == null) {
+            getLogger().debug("Request attribute '" + paramName + "' not set.");
+            return null;
+        }
+
+        return result.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestParameterMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestParameterMatcher.java
new file mode 100644
index 0000000..9bc0ab2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardRequestParameterMatcher.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a request parameter against a wildcard expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>parameter-name</code></td><td>Name of the request parameter to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardRequestParameterMatcher extends AbstractWildcardMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No parameter name given. FAILING");
+            return null;
+        }
+
+        String result = ObjectModelHelper.getRequest(objectModel).getParameter(paramName);
+        if (result == null) {
+            getLogger().debug("Parameter '" + paramName + "' not set.");
+        }
+
+        return result;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardSessionAttributeMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardSessionAttributeMatcher.java
new file mode 100644
index 0000000..0d0607a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardSessionAttributeMatcher.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Matches a session attribute against a wildcard expression.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <tableborder="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the session attribute</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardSessionAttributeMatcher extends AbstractWildcardMatcher
+    implements Configurable
+{
+    private String defaultParam;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("attribute-name").getValue(null);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default attribute-name is = '" + this.defaultParam + "'");
+        }
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("attribute-name", this.defaultParam);
+        if (paramName == null) {
+            getLogger().warn("No attribute name given. FAILING");
+            return null;
+        }
+
+        Object result = ObjectModelHelper.getRequest(objectModel).getSession().getAttribute(paramName);
+        if (result == null) {
+            getLogger().debug("Session attribute '" + paramName + "' not set.");
+            return null;
+        }
+
+        return result.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardURIMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardURIMatcher.java
new file mode 100644
index 0000000..eef2d48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/WildcardURIMatcher.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Match the request URI against a wildcard expression.
+ *
+ * @version $Id$
+ */
+public class WildcardURIMatcher extends AbstractWildcardMatcher
+{
+    /**
+     * Return the request URI.
+     */
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+        String uri = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+
+        if (uri.startsWith("/")) {
+            uri = uri.substring(1);
+        }
+
+        return uri;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/helpers/WildcardHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
new file mode 100644
index 0000000..59eb24e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching.helpers;
+
+import java.util.HashMap;
+
+/**
+ * This class is an utility class that perform wilcard-patterns matching and
+ * isolation.
+ *
+ * @version $Id$
+ */
+public class WildcardHelper {
+
+    /** The int representing '*' in the pattern <code>int []</code>. */
+    protected static final int MATCH_FILE = -1;
+    /** The int representing '**' in the pattern <code>int []</code>. */
+    protected static final int MATCH_PATH = -2;
+    /** The int representing begin in the pattern <code>int []</code>. */
+    protected static final int MATCH_BEGIN = -4;
+    /** The int representing end in pattern <code>int []</code>. */
+    protected static final int MATCH_THEEND = -5;
+    /** The int value that terminates the pattern <code>int []</code>. */
+    protected static final int MATCH_END = -3;
+
+
+    /**
+     * Translate the given <code>String</code> into a <code>int []</code>
+     * representing the pattern matchable by this class.
+     * <br>
+     * This function translates a <code>String</code> into an int array
+     * converting the special '*' and '\' characters.
+     * <br>
+     * Here is how the conversion algorithm works:
+     * <ul>
+     *   <li>The '*' character is converted to MATCH_FILE, meaning that zero
+     *        or more characters (excluding the path separator '/') are to
+     *        be matched.</li>
+     *   <li>The '**' sequence is converted to MATCH_PATH, meaning that zero
+     *       or more characters (including the path separator '/') are to
+     *        be matched.</li>
+     *   <li>The '\' character is used as an escape sequence ('\*' is
+     *       translated in '*', not in MATCH_FILE). If an exact '\' character
+     *       is to be matched the source string must contain a '\\'.
+     *       sequence.</li>
+     * </ul>
+     * When more than two '*' characters, not separated by another character,
+     * are found their value is considered as '**' (MATCH_PATH).
+     * <br>
+     * The array is always terminated by a special value (MATCH_END).
+     * <br>
+     * All MATCH* values are less than zero, while normal characters are equal
+     * or greater.
+     *
+     * @param data The string to translate.
+     * @return The encoded string as an int array, terminated by the MATCH_END
+     *         value (don't consider the array length).
+     * @exception NullPointerException If data is null.
+     */
+    public static int[] compilePattern(String data)
+    throws NullPointerException {
+
+        // Prepare the arrays
+        int expr[] = new int[data.length() + 2];
+        char buff[] = data.toCharArray();
+
+        // Prepare variables for the translation loop
+        int y = 0;
+        boolean slash = false;
+
+        // Must start from beginning
+        expr[y++] = MATCH_BEGIN;
+
+        if (buff.length > 0) {
+            if (buff[0]=='\\') {
+                slash = true;
+            } else if (buff[0] == '*') {
+                expr[y++] = MATCH_FILE;
+            }  else {
+                expr[y++] = buff[0];
+            }
+
+            // Main translation loop
+            for (int x = 1; x < buff.length; x++) {
+                // If the previous char was '\' simply copy this char.
+                if (slash) {
+                    expr[y++] = buff[x];
+                    slash = false;
+                // If the previous char was not '\' we have to do a bunch of checks
+                } else {
+                    // If this char is '\' declare that and continue
+                    if (buff[x] == '\\') {
+                        slash = true;
+                    // If this char is '*' check the previous one
+                    } else if (buff[x] == '*') {
+                        // If the previous character als was '*' match a path
+                        if (expr[y-1] <= MATCH_FILE) {
+                            expr[y-1] = MATCH_PATH;
+                        } else {
+                            expr[y++] = MATCH_FILE;
+                        }
+                    } else {
+                        expr[y++]=buff[x];
+                    }
+                }
+            }
+        }
+
+        // Must match end at the end
+        expr[y] = MATCH_THEEND;
+        return expr;
+    }
+
+    /**
+     * match a pattern agains a string and isolates wildcard replacement into a
+     * <code>Stack</code>.
+     */
+    public static boolean match (HashMap map, String data, int[] expr) 
+    throws NullPointerException {
+        if (data == null) {
+            throw new NullPointerException ("No data provided");
+        }
+        if (expr == null) {
+            throw new NullPointerException ("No pattern expression provided");
+        }
+
+
+        char buff[] = data.toCharArray();
+        // Allocate the result buffer
+        char rslt[] = new char[expr.length + buff.length];
+
+
+        // The previous and current position of the expression character
+        // (MATCH_*)
+        int charpos = 0;
+
+        // The position in the expression, input, translation and result arrays
+        int exprpos = 0;
+        int buffpos = 0;
+        int rsltpos = 0;
+        int offset = -1;
+
+        // The matching count
+        int mcount = 0;
+
+        if ( map != null ) {
+            // We want the complete data be in {0}
+            map.put(Integer.toString(mcount),data);
+        }
+
+        // First check for MATCH_BEGIN
+        boolean matchBegin = false;
+        if (expr[charpos] == MATCH_BEGIN) {
+            matchBegin = true;
+            exprpos = ++charpos;
+        }
+
+        // Search the fist expression character (except MATCH_BEGIN - already skipped)
+        while (expr[charpos] >= 0)
+            charpos++;
+
+        // The expression charater (MATCH_*)
+        int exprchr = expr[charpos];
+
+        while (true) {
+            // Check if the data in the expression array before the current
+            // expression character matches the data in the input buffer
+            if (matchBegin) {
+                if (!matchArray(expr, exprpos, charpos, buff, buffpos))
+                    return (false);
+                matchBegin = false;
+            } else {
+                offset = indexOfArray (expr, exprpos, charpos, buff,
+                        buffpos);
+                if (offset < 0)
+                    return (false);
+            }
+
+            // Check for MATCH_BEGIN
+            if (matchBegin) {
+                if (offset != 0)
+                    return (false);
+                matchBegin = false;
+            }
+
+            // Advance buffpos
+            buffpos += (charpos - exprpos);
+
+            // Check for END's
+            if (exprchr == MATCH_END) {
+                if (rsltpos > 0 && map != null) {
+                    map.put(Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+                }
+                // Don't care about rest of input buffer
+                return (true);
+            } else if (exprchr == MATCH_THEEND) {
+                if (rsltpos > 0 && map != null ) {
+                    map.put (Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+                }
+                // Check that we reach buffer's end
+                return (buffpos == buff.length);
+            }
+
+            // Search the next expression character
+            exprpos = ++charpos;
+            while (expr[charpos] >= 0)
+                charpos++;
+            int prevchr = exprchr;
+            exprchr = expr[charpos];
+
+            // We have here prevchr == * or **.
+            offset = (prevchr == MATCH_FILE) ?
+                    indexOfArray (expr, exprpos, charpos, buff, buffpos) :
+                    lastIndexOfArray (expr, exprpos, charpos, buff,
+                    buffpos);
+
+            if (offset < 0)
+                return (false);
+
+            // Copy the data from the source buffer into the result buffer
+            // to substitute the expression character
+            if (prevchr == MATCH_PATH) {
+                while (buffpos < offset)
+                    rslt[rsltpos++] = buff[buffpos++];
+            } else {
+                // Matching file, don't copy '/'
+                while (buffpos < offset) {
+                    if (buff[buffpos] == '/')
+                        return (false);
+                    rslt[rsltpos++] = buff[buffpos++];
+                }
+            }
+
+            if ( map != null ) {
+                map.put(Integer.toString(++mcount),new String (rslt, 0, rsltpos));
+            }
+            rsltpos = 0;
+        }
+    }
+
+    /**
+      * Get the offset of a part of an int array within a char array.
+      * <br>
+      * This method return the index in d of the first occurrence after dpos of
+      * that part of array specified by r, starting at rpos and terminating at
+      * rend.
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param rend The index of the last character in r to look for plus 1.
+      * @param d The array of char that should contain a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return The offset in d of the part of r matched in d or -1 if that was
+      *         not found.
+      */
+    protected static int indexOfArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos)
+            throw new IllegalArgumentException ("rend < rpos");
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos)
+            return (d.length); //?? dpos?
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = dpos; x < d.length; x++)
+                if (r[rpos] == d[x])
+                    return (x);
+        }
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        while ((dpos + rend - rpos) <= d.length) {
+            // Set current startpoint in d
+            int y = dpos;
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend)
+                    return (dpos);
+                if (r[x] != d[y++])
+                    break;
+            }
+            // Increase dpos to search for the same string at next offset
+            dpos++;
+        }
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+      * Get the offset of a last occurance of an int array within a char array.
+      * <br>
+      * This method return the index in d of the last occurrence after dpos of
+      * that part of array specified by r, starting at rpos and terminating at
+      * rend.
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param rend The index of the last character in r to look for plus 1.
+      * @param d The array of char that should contain a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return The offset in d of the last part of r matched in d or -1 if that was
+      *         not found.
+      */
+    protected static int lastIndexOfArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos)
+            throw new IllegalArgumentException ("rend < rpos");
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos)
+            return (d.length); //?? dpos?
+
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = d.length - 1; x > dpos; x--)
+                if (r[rpos] == d[x])
+                    return (x);
+        }
+
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        int l = d.length - (rend - rpos);
+        while (l >= dpos) {
+            // Set current startpoint in d
+            int y = l;
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend)
+                    return (l);
+                if (r[x] != d[y++])
+                    break;
+            }
+            // Decrease l to search for the same string at next offset
+            l--;
+        }
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+      * Matches elements of array r from rpos to rend with array d, starting from dpos.
+      * <br>
+      * This method return true if elements of array r from rpos to rend
+      * equals elements of array d starting from dpos to dpos+(rend-rpos).
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param d The array of char that should start from a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return true if array d starts from portion of array r.
+      */
+    protected static boolean matchArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        if (d.length - dpos < rend - rpos)
+            return (false);
+        for (int i = rpos; i < rend; i++)
+            if (r[i] != d[dpos++])
+                return (false);
+        return (true);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java
new file mode 100644
index 0000000..f2313eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingRegexpMatcher.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+
+import org.apache.cocoon.matching.AbstractRegexpMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a regular expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class CachingRegexpMatcher extends AbstractRegexpMatcher
+    implements Configurable,  Initializable, Serviceable, Disposable
+{
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    private String defaultParam;
+    private String defaultInput = "request-param"; // default to request parameters
+    private Configuration inputConf = null; // will become an empty configuration object
+                                            // during configure() so why bother here...
+    String INPUT_MODULE_ROLE = InputModule.ROLE;
+    String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+    private boolean initialized = false;
+    private InputModule input;
+    private ServiceSelector inputSelector;
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager=manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() {
+        try {
+            // obtain input module
+            this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+            if (this.defaultInput != null && 
+                this.inputSelector != null && 
+                this.inputSelector.isSelectable(this.defaultInput)
+                ){
+                this.input = (InputModule) this.inputSelector.select(this.defaultInput);
+                if (!(this.input instanceof ThreadSafe && this.inputSelector instanceof ThreadSafe) ) {
+                    this.inputSelector.release(this.input);
+                    this.manager.release(this.inputSelector);
+                    this.input = null;
+                    this.inputSelector = null;
+                }
+                this.initialized = true;
+            } else {
+                if (getLogger().isErrorEnabled())
+                    getLogger().error("A problem occurred setting up '" + this.defaultInput 
+                                      + "': Selector is "+(this.inputSelector!=null?"not ":"")
+                                      +"null, Component is "
+                                      +(this.inputSelector!=null&&this.inputSelector.isSelectable(this.defaultInput)?"known":"unknown"));
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("A problem occurred setting up '" + this.defaultInput + "': " + e.getMessage());
+        }
+    }
+
+
+
+    public void dispose() {
+
+        if (!this.initialized) 
+            if (getLogger().isErrorEnabled()) 
+                getLogger().error("Uninitialized Component! FAILING");
+        else 
+            if (this.inputSelector != null) {
+                if (this.input != null)
+                    this.inputSelector.release(this.input);
+                this.manager.release(this.inputSelector);
+            }
+    }
+
+
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+        if (!this.initialized) {
+            if (getLogger().isErrorEnabled()) 
+                getLogger().error("Uninitialized Component! FAILING");
+            return null;
+        }
+        if (paramName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No parameter name given. Trying to Continue");
+        }
+        if (inputName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        Object result = null;
+
+        if (this.input != null && inputName.equals(this.defaultInput)) {
+            // input module is thread safe
+            // thus we still have a reference to it
+            try {
+                if (this.input != null) {
+                    result = this.input.getAttribute(paramName, this.inputConf, objectModel);
+                }
+            } catch (Exception e) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring Parameter '" + paramName 
+                                      + "' from '" + inputName + "': " + e.getMessage());
+            }
+        } else {
+            // input was not thread safe
+            // so acquire it again
+            ServiceSelector iputSelector = null;
+            InputModule iput = null;
+            try {
+                // obtain input module
+                iputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+                if (inputName != null && iputSelector != null && iputSelector.isSelectable(inputName)){
+                    iput = (InputModule) iputSelector.select(inputName);
+                }
+                if (iput != null) {
+                    result = iput.getAttribute(paramName, this.inputConf, objectModel);
+                }
+            } catch (Exception e) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring Parameter '" + paramName 
+                                     + "' from '" + inputName + "': " + e.getMessage());
+            } finally {
+                // release components
+                if (iputSelector != null) {
+                    if (iput != null)
+                        iputSelector.release(iput);
+                    this.manager.release(iputSelector);
+                }
+            }
+        }
+
+        if (result instanceof String) {
+            return (String) result;
+        } else {
+            return result.toString();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java
new file mode 100644
index 0000000..2bf97d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/CachingWildcardMatcher.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.matching.AbstractWildcardMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a wildcard expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class CachingWildcardMatcher extends AbstractWildcardMatcher
+    implements Configurable,  Initializable, Serviceable, Disposable
+{
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    private String defaultParam;
+    private String defaultInput = "request-param"; // default to request parameters
+    private Configuration inputConf = null; // will become an empty configuration object
+                                            // during configure() so why bother here...
+    String INPUT_MODULE_ROLE = InputModule.ROLE;
+    String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+    private boolean initialized = false;
+    private InputModule input;
+    private ServiceSelector inputSelector;
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() {
+        try {
+            // obtain input module
+            this.inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+            if (this.defaultInput != null && 
+                this.inputSelector != null && 
+                this.inputSelector.isSelectable(this.defaultInput)
+                ){
+                this.input = (InputModule) this.inputSelector.select(this.defaultInput);
+                if (!(this.input instanceof ThreadSafe && this.inputSelector instanceof ThreadSafe) ) {
+                    this.inputSelector.release(this.input);
+                    this.manager.release(this.inputSelector);
+                    this.input = null;
+                    this.inputSelector = null;
+                }
+                this.initialized = true;
+            } else {
+                if (getLogger().isErrorEnabled())
+                    getLogger().error("A problem occurred setting up '" + this.defaultInput 
+                                      + "': Selector is "+(this.inputSelector!=null?"not ":"")
+                                      +"null, Component is "
+                                      +(this.inputSelector!=null&&this.inputSelector.isSelectable(this.defaultInput)?"known":"unknown"));
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("A problem occurred setting up '" + this.defaultInput + "': " + e.getMessage());
+        }
+    }
+
+
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (!this.initialized) 
+            if (getLogger().isErrorEnabled()) 
+                getLogger().error("Uninitialized Component! FAILING");
+        else 
+            if (this.inputSelector != null) {
+                if (this.input != null)
+                    this.inputSelector.release(this.input);
+                this.manager.release(this.inputSelector);
+            }
+    }
+
+
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+        if (!this.initialized) {
+            if (getLogger().isErrorEnabled()) 
+                getLogger().error("Uninitialized Component! FAILING");
+            return null;
+        }
+        if (paramName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No parameter name given. Trying to Continue");
+        }
+        if (inputName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        Object result = null;
+
+        if (this.input != null && inputName.equals(this.defaultInput)) {
+            // input module is thread safe
+            // thus we still have a reference to it
+            try {
+                if (this.input != null) {
+                    result = this.input.getAttribute(paramName, this.inputConf, objectModel);
+                }
+            } catch (Exception e) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring Parameter '" + paramName 
+                                      + "' from '" + inputName + "': " + e.getMessage());
+            }
+        } else {
+            // input was not thread safe
+            // so acquire it again
+            ServiceSelector iputSelector = null;
+            InputModule iput = null;
+            try {
+                // obtain input module
+                iputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+                if (inputName != null && iputSelector != null && iputSelector.isSelectable(inputName)){
+                    iput = (InputModule) iputSelector.select(inputName);
+                }
+                if (iput != null) {
+                    result = iput.getAttribute(paramName, this.inputConf, objectModel);
+                }
+            } catch (Exception e) {
+                if (getLogger().isWarnEnabled()) 
+                    getLogger().warn("A problem occurred acquiring Parameter '" + paramName 
+                                     + "' from '" + inputName + "': " + e.getMessage());
+            } finally {
+                // release components
+                if (iputSelector != null) {
+                    if (iput != null)
+                        iputSelector.release(iput);
+                    this.manager.release(iputSelector);
+                }
+            }
+        }
+
+        if (result instanceof String) {
+            return (String) result;
+        } else {
+            return result.toString();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/WildcardMatcher.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/WildcardMatcher.java
new file mode 100644
index 0000000..b79ba1b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/matching/modular/WildcardMatcher.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.matching.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.matching.AbstractWildcardMatcher;
+
+import java.util.Map;
+
+/**
+ * Matches against a wildcard expression. Needs an input module to
+ * obtain value to match against.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>input-module</code></td><td>Name of the input module used to obtain the value</td></tr>
+ * <tr><td><code>parameter-name</code></td><td>Name of the parameter to match * against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class WildcardMatcher extends AbstractWildcardMatcher
+    implements Configurable, Serviceable
+{
+
+    /** The service manager instance */
+    protected ServiceManager manager;
+
+    private String defaultParam;
+    private String defaultInput = "request-param"; // default to request parameters
+    private Configuration inputConf = null; // will become an empty configuration object
+                                            // during configure() so why bother here...
+    String INPUT_MODULE_ROLE = InputModule.ROLE;
+    String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager=manager;
+    }
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultParam = config.getChild("parameter-name").getValue(null);
+        this.inputConf = config.getChild("input-module");
+        this.defaultInput = this.inputConf.getAttribute("name",this.defaultInput);
+    }
+
+    protected String getMatchString(Map objectModel, Parameters parameters) {
+
+        String paramName = parameters.getParameter("parameter-name", this.defaultParam);
+        String inputName = parameters.getParameter("input-module", this.defaultInput);
+
+        if (paramName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No parameter name given. Trying to continue");
+        }
+        if (inputName == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("No input module given. FAILING");
+            return null;
+        }
+
+        InputModule input = null;
+        ServiceSelector inputSelector = null;
+        Object result = null;
+
+        // one could test whether the input module is ThreadSafe and
+        // keep a reference for that instance. Then one would need
+        // to implement Disposable in order to release it at EOL
+        // That would probably speed up things a lot. Especially, since
+        // matchers are invoked very often.
+        // Perhaps a CachingWildcardMatcher ?
+
+        try {
+            // obtain input module
+            inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+            if (inputName != null && inputSelector != null && inputSelector.isSelectable(inputName)){
+                input = (InputModule) inputSelector.select(inputName);
+            }
+            if (input != null) {
+                result = input.getAttribute(paramName, this.inputConf, objectModel);
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("A problem occurred acquiring Parameter '" + paramName 
+                                 + "' from '" + inputName + "': " + e.getMessage());
+        } finally {
+            // release components
+            if (inputSelector != null) {
+                if (input != null)
+                    inputSelector.release(input);
+                this.manager.release(inputSelector);
+            }
+        }
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(" using "+inputName+" obtained value "+result);
+
+        if (result instanceof String) {
+            return (String) result;
+        } else {
+            return result.toString();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/AbstractReader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/AbstractReader.java
new file mode 100644
index 0000000..10eb5c0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/AbstractReader.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.reading;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.SAXException;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+/**
+ * A reader can be used to generate binary output for a request. This
+ * abstract class helps in implementing a custom reader.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractReader
+  extends AbstractLogEnabled
+  implements Reader, Recyclable {
+
+    /** The current <code>SourceResolver</code>. */
+    protected SourceResolver resolver;
+    /** The current <code>Map</code> of the object model. */
+    protected Map objectModel;
+    /** The current <code>Parameters</code>. */
+    protected Parameters parameters;
+    /** The source URI associated with the request or <b>null</b>. */
+    protected String source;
+    /** The <code>OutputStream</code> to write on. */
+    protected OutputStream out;
+
+    /**
+     * Set the <code>SourceResolver</code> the object model <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        this.resolver=resolver;
+        this.objectModel=objectModel;
+        this.source=src;
+        this.parameters=par;
+    }
+
+    /**
+     * Set the <code>OutputStream</code>
+     */
+    public void setOutputStream(OutputStream out) {
+        if ( out instanceof BufferedOutputStream 
+             || out instanceof org.apache.cocoon.util.BufferedOutputStream ) {
+            this.out = out;
+        } else {
+            this.out = new BufferedOutputStream(out, 1536);
+        }
+    }
+
+    /**
+     * Get the mime-type of the output of this <code>Reader</code>
+     * This default implementation returns null to indicate that the
+     * mime-type specified in the sitemap is to be used
+     */
+    public String getMimeType() {
+        return null;
+    }
+
+    /**
+     * @return the time the read source was last modified or 0 if it is not
+     *         possible to detect
+     */
+    public long getLastModified() {
+        return 0;
+    }
+
+    /**
+     * Recycle the component
+     */
+    public void recycle() {
+        this.out = null;
+        this.resolver = null;
+        this.source = null;
+        this.parameters = null;
+        this.objectModel = null;
+    }
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return false;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ImageReader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ImageReader.java
new file mode 100644
index 0000000..0af5376
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ImageReader.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.reading;
+
+import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorConvertOp;
+import java.awt.image.RescaleOp;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.SAXException;
+
+import com.sun.image.codec.jpeg.ImageFormatException;
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGDecodeParam;
+import com.sun.image.codec.jpeg.JPEGEncodeParam;
+import com.sun.image.codec.jpeg.JPEGImageDecoder;
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
+
+/**
+ * The <code>ImageReader</code> component is used to serve binary image data
+ * in a sitemap pipeline. It makes use of HTTP Headers to determine if
+ * the requested resource should be written to the <code>OutputStream</code>
+ * or if it can signal that it hasn't changed.
+ *
+ * Parameters:
+ *   <dl>
+ *     <dt>&lt;width&gt;</dt>
+ *     <dd> This parameter is optional. When specified, it determines the
+ *          width of the binary image.
+ *          If no height parameter is specified, the aspect ratio
+ *          of the image is kept. The parameter may be expressed as an int or a percentage.
+ *     </dd>
+ *     <dt>&lt;height&gt;</dt>
+ *     <dd> This parameter is optional. When specified, it determines the
+ *          height of the binary image.
+ *          If no width parameter is specified, the aspect ratio
+ *          of the image is kept. The parameter may be expressed as an int or a percentage.
+ *     </dd>
+ *     <dt>&lt;scale(Red|Green|Blue)&gt;</dt>
+ *     <dd>This parameter is optional. When specified it will cause the
+ *         specified color component in the image to be multiplied by the
+ *         specified floating point value.
+ *     </dd>
+ *     <dt>&lt;offset(Red|Green|Blue)&gt;</dt>
+ *     <dd>This parameter is optional. When specified it will cause the
+ *         specified color component in the image to be incremented by the
+ *         specified floating point value.
+ *     </dd>
+ *     <dt>&lt;grayscale&gt;</dt>
+ *     <dd>This parameter is optional. When specified and set to true it
+ *         will cause each image pixel to be normalized. Default is "false".
+ *     </dd>
+ *     <dt>&lt;allow-enlarging&gt;</dt>
+ *     <dd>This parameter is optional. By default, if the image is smaller
+ *         than the specified width and height, the image will be enlarged.
+ *         In some circumstances this behaviour is undesirable, and can be
+ *         switched off by setting this parameter to "<code>false</code>" so that
+ *         images will be reduced in size, but not enlarged. The default is
+ *         "<code>true</code>".
+ *     </dd>
+ *     <dt>&lt;quality&gt;</dt>
+ *     <dd>This parameter is optional. By default, the quality uses the
+ *         default for the JVM. If it is specified, the proper JPEG quality
+ *         compression is used. The range is 0.0 to 1.0, if specified. 
+ *     </dd>
+ *   </dl>
+ *
+ * @version $Id$
+ */
+final public class ImageReader extends ResourceReader {
+    private static final boolean GRAYSCALE_DEFAULT = false;
+    private static final boolean ENLARGE_DEFAULT = true;
+    private static final boolean FIT_DEFAULT = false;
+
+    private int width;
+    private int height;
+    private float[] scaleColor = new float[3];
+    private float[] offsetColor = new float[3];
+    private float[] quality = new float[1];
+
+    private boolean enlarge;
+    private boolean fitUniform;
+    private boolean usePercent;
+    private RescaleOp colorFilter;
+    private ColorConvertOp grayscaleFilter;
+
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+
+        char lastChar;
+        String tmpWidth = par.getParameter("width", "0");
+        String tmpHeight = par.getParameter("height", "0");
+
+        this.scaleColor[0] = par.getParameterAsFloat("scaleRed", -1.0f);
+        this.scaleColor[1] = par.getParameterAsFloat("scaleGreen", -1.0f);
+        this.scaleColor[2] = par.getParameterAsFloat("scaleBlue", -1.0f);
+        this.offsetColor[0] = par.getParameterAsFloat("offsetRed", 0.0f);
+        this.offsetColor[1] = par.getParameterAsFloat("offsetGreen", 0.0f);
+        this.offsetColor[2] = par.getParameterAsFloat("offsetBlue", 0.0f);
+        this.quality[0] = par.getParameterAsFloat("quality", 0.9f);
+
+        boolean filterColor = false;
+        for (int i = 0; i < 3; ++i) {
+            if (this.scaleColor[i] != -1.0f) {
+                filterColor = true;
+            } else {
+                this.scaleColor[i] = 1.0f;
+            }
+            if (this.offsetColor[i] != 0.0f) {
+                filterColor = true;
+            }
+        }
+
+        if (filterColor) {
+            this.colorFilter = new RescaleOp(scaleColor, offsetColor, null);
+        }
+
+        usePercent = false;
+        lastChar = tmpWidth.charAt(tmpWidth.length() - 1);
+        if (lastChar == '%') {
+            usePercent = true;
+            width = Integer.parseInt(tmpWidth.substring(0, tmpWidth.length() - 1));
+        } else {
+            width = Integer.parseInt(tmpWidth);
+        }
+
+        lastChar = tmpHeight.charAt(tmpHeight.length() - 1);
+        if(lastChar == '%') {
+            usePercent = true;
+            height = Integer.parseInt(tmpHeight.substring(0, tmpHeight.length() - 1));
+        } else {
+            height = Integer.parseInt(tmpHeight);
+        }
+
+        if (par.getParameterAsBoolean("grayscale", GRAYSCALE_DEFAULT)) {
+            this.grayscaleFilter = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
+        }
+
+        this.enlarge = par.getParameterAsBoolean("allow-enlarging", ENLARGE_DEFAULT);
+        this.fitUniform = par.getParameterAsBoolean("fit-uniform", FIT_DEFAULT);
+
+        super.setup(resolver, objectModel, src, par);
+    }
+
+    protected void setupHeaders() {
+        // Reset byte ranges support for dynamic response
+        if (byteRanges && hasTransform()) {
+            byteRanges = false;
+        }
+
+        super.setupHeaders();
+    }
+
+    /**
+     * @return True if image transform is specified
+     */
+    private boolean hasTransform() {
+        return width > 0 || height > 0 || null != colorFilter || null != grayscaleFilter || (this.quality[0] != 0.9f);
+    }
+
+    /**
+     * Returns the affine transform that implements the scaling.
+     * The behavior is the following: if both the new width and height values
+     * are positive, the image is rescaled according to these new values and
+     * the original aspect ratio is lost.
+     * Otherwise, if one of the two parameters is zero or negative, the
+     * aspect ratio is maintained and the positive parameter indicates the
+     * scaling.
+     * If both new values are zero or negative, no scaling takes place (a unit
+     * transformation is applied).
+     */
+    private AffineTransform getTransform(double ow, double oh, double nw, double nh) {
+        double wm = 1.0d;
+        double hm = 1.0d;
+
+        if (fitUniform) {
+            //
+            // Compare aspect ratio of image vs. that of the "box"
+            // defined by nw and nh
+            //
+            if (ow/oh > nw/nh) {
+                nh = 0;    // Original image is proportionately wider than the box,
+                        // so scale to fit width
+            } else {
+                nw = 0;    // Scale to fit height
+            }
+        }
+
+        if (nw > 0) {
+            wm = nw / ow;
+            if (nh > 0) {
+                hm = nh / oh;
+            } else {
+                hm = wm;
+            }
+        } else {
+            if (nh > 0) {
+                hm = nh / oh;
+                wm = hm;
+            }
+        }
+
+        if (!enlarge) {
+            if ((nw > ow && nh <= 0) || (nh > oh && nw <=0)) {
+                wm = 1.0d;
+                hm = 1.0d;
+            } else if (nw > ow) {
+                wm = 1.0d;
+            } else if (nh > oh) {
+                hm = 1.0d;
+            }
+        }
+        return new AffineTransform(wm, 0.0d, 0.0d, hm, 0.0d, 0.0d);
+    }
+
+    protected void processStream(InputStream inputStream) throws IOException, ProcessingException {
+        if (hasTransform()) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("image " + ((width == 0) ? "?" : Integer.toString(width))
+                                  + "x"    + ((height == 0) ? "?" : Integer.toString(height))
+                                  + " expires: " + expires);
+            }
+
+            try {
+                JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(inputStream);
+                BufferedImage original = decoder.decodeAsBufferedImage();
+                BufferedImage currentImage = original;
+
+                if (width > 0 || height > 0) {
+                    JPEGDecodeParam decodeParam = decoder.getJPEGDecodeParam();
+                    double ow = decodeParam.getWidth();
+                    double oh = decodeParam.getHeight();
+
+                    if (usePercent) {
+                        if (width > 0) {
+                            width = Math.round((int)(ow * width) / 100);
+                        }
+                        if (height > 0) {
+                            height = Math.round((int)(oh * height) / 100);
+                        }
+                    }
+
+                    AffineTransformOp filter = new AffineTransformOp(getTransform(ow, oh, width, height), AffineTransformOp.TYPE_BILINEAR);
+                    WritableRaster scaledRaster = filter.createCompatibleDestRaster(currentImage.getRaster());
+
+                    filter.filter(currentImage.getRaster(), scaledRaster);
+
+                    currentImage = new BufferedImage(original.getColorModel(), scaledRaster, true, null);
+                }
+
+                if (null != grayscaleFilter) {
+                    grayscaleFilter.filter(currentImage, currentImage);
+                }
+
+                if (null != colorFilter) {
+                    colorFilter.filter(currentImage, currentImage);
+                }
+
+                JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
+                JPEGEncodeParam p = encoder.getDefaultJPEGEncodeParam(currentImage);
+                p.setQuality(this.quality[0], true);
+                encoder.setJPEGEncodeParam(p);
+                encoder.encode(currentImage);
+
+                out.flush();
+            } catch (ImageFormatException e) {
+                throw new ProcessingException("Error reading the image. " +
+                                              "Note that only JPEG images are currently supported.");
+            } finally {
+              // Bugzilla Bug 25069, close inputStream in finally block
+              // this will close inputStream even if processStream throws
+              // an exception
+              inputStream.close();
+            }
+        } else {
+            // only read the resource - no modifications requested
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("passing original resource");
+            }
+            super.processStream(inputStream);
+        }
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key consists of the src and width and height,
+     *         and the color transform parameters
+    */
+    public Serializable getKey() {
+        return super.getKey().toString()
+                + ':' + this.width
+                + ':' + this.height
+                + ":" + this.scaleColor[0]
+                + ":" + this.scaleColor[1]
+                + ":" + this.scaleColor[2]
+                + ":" + this.offsetColor[0]
+                + ":" + this.offsetColor[1]
+                + ":" + this.offsetColor[2]
+                + ":" + this.quality[0]
+                + ":" + (this.grayscaleFilter == null ? "color" : "bw");
+    }
+
+    public void recycle(){
+        super.recycle();
+        this.colorFilter = null;
+        this.grayscaleFilter = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/Reader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/Reader.java
new file mode 100644
index 0000000..a0b02df
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/Reader.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.reading;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.sitemap.SitemapOutputComponent;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+
+/**
+ * A reader can be used to generate binary output for a request.
+ *
+ * @version $Id$
+ */
+public interface Reader extends SitemapModelComponent, SitemapOutputComponent {
+
+    String ROLE = Reader.class.getName();
+
+    /**
+     * Generate the response.
+     */
+    void generate()
+    throws IOException, SAXException, ProcessingException;
+
+    /**
+     * @return the time the read source was last modified or 0 if it is not
+     *         possible to detect
+     */
+    long getLastModified();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ResourceReader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ResourceReader.java
new file mode 100644
index 0000000..39f9e2d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ResourceReader.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.reading;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.http.HttpResponse;
+import org.apache.cocoon.util.ByteRange;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The <code>ResourceReader</code> component is used to serve binary data
+ * in a sitemap pipeline. It makes use of HTTP Headers to determine if
+ * the requested resource should be written to the <code>OutputStream</code>
+ * or if it can signal that it hasn't changed.
+ *
+ * <p>Configuration:
+ * <dl>
+ *   <dt>&lt;expires&gt;</dt>
+ *   <dd>This parameter is optional. When specified it determines how long
+ *       in miliseconds the resources can be cached by any proxy or browser
+ *       between Cocoon and the requesting visitor. Defaults to -1.
+ *   </dd>
+ *   <dt>&lt;quick-modified-test&gt;</dt>
+ *   <dd>This parameter is optional. This boolean parameter controls the
+ *       last modified test. If set to true (default is false), only the
+ *       last modified of the current source is tested, but not if the
+ *       same source is used as last time
+ *       (see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102921894301915 )
+ *   </dd>
+ *   <dt>&lt;byte-ranges&gt;</dt>
+ *   <dd>This parameter is optional. This boolean parameter controls whether
+ *       Cocoon should support byterange requests (to allow clients to resume
+ *       broken/interrupted downloads).
+ *       Defaults to true.
+ * </dl>
+ *
+ * <p>Default configuration:
+ * <pre>
+ *   &lt;expires&gt;-1&lt;/expires&gt;
+ *   &lt;quick-modified-test&gt;false&lt;/quick-modified-test&gt;
+ *   &lt;byte-ranges&gt;true&lt;/byte-ranges&gt;
+ * </pre>
+ *
+ * <p>In addition to reader configuration, above parameters can be passed
+ * to the reader at the time when it is used.
+ *
+ * @version $Id$
+ */
+public class ResourceReader extends AbstractReader
+                            implements CacheableProcessingComponent, Configurable {
+
+    /**
+     * The list of generated documents
+     */
+    private static final Map documents = new HashMap();
+
+    protected long configuredExpires;
+    protected boolean configuredQuickTest;
+    protected int configuredBufferSize;
+    protected boolean configuredByteRanges;
+
+    protected long expires;
+    protected boolean quickTest;
+    protected int bufferSize;
+    protected boolean byteRanges;
+
+    protected Response response;
+    protected Request request;
+    protected Source inputSource;
+
+    /**
+     * Read reader configuration
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        // VG Parameters are deprecated as of 2.2.0-Dev/2.1.6-Dev
+        final Parameters parameters = Parameters.fromConfiguration(configuration);
+        this.configuredExpires = parameters.getParameterAsLong("expires", -1);
+        this.configuredQuickTest = parameters.getParameterAsBoolean("quick-modified-test", false);
+        this.configuredBufferSize = parameters.getParameterAsInteger("buffer-size", 8192);
+        this.configuredByteRanges = parameters.getParameterAsBoolean("byte-ranges", true);
+
+        // Configuration has precedence over parameters.
+        this.configuredExpires = configuration.getChild("expires").getValueAsLong(configuredExpires);
+        this.configuredQuickTest = configuration.getChild("quick-modified-test").getValueAsBoolean(configuredQuickTest);
+        this.configuredBufferSize = configuration.getChild("buffer-size").getValueAsInteger(configuredBufferSize);
+        this.configuredByteRanges = configuration.getChild("byte-ranges").getValueAsBoolean(configuredByteRanges);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(Parameters)
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+    }
+
+    /**
+     * Setup the reader.
+     * The resource is opened to get an <code>InputStream</code>,
+     * the length and the last modification date
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        this.request = ObjectModelHelper.getRequest(objectModel);
+        this.response = ObjectModelHelper.getResponse(objectModel);
+
+        this.expires = par.getParameterAsLong("expires", this.configuredExpires);
+        this.quickTest = par.getParameterAsBoolean("quick-modified-test", this.configuredQuickTest);
+        this.bufferSize = par.getParameterAsInteger("buffer-size", this.configuredBufferSize);
+        this.byteRanges = par.getParameterAsBoolean("byte-ranges", this.configuredByteRanges);
+
+        try {
+            this.inputSource = resolver.resolveURI(src);
+        } catch (SourceException e) {
+            throw SourceUtil.handle("Error during resolving of '" + src + "'.", e);
+        }
+
+        setupHeaders();
+    }
+
+    /**
+     * Setup the response headers: Accept-Ranges, Expires.
+     */
+    protected void setupHeaders() {
+        // Tell the client whether we support byte range requests or not
+        if (byteRanges) {
+            response.setHeader("Accept-Ranges", "bytes");
+        } else {
+            response.setHeader("Accept-Ranges", "none");
+        }
+
+        if (expires > 0) {
+            response.setDateHeader("Expires", System.currentTimeMillis() + expires);
+        } else if (expires == 0) {
+            // See Bug #14048
+            response.addHeader("Vary", "Host");
+        }
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        this.request = null;
+        this.response = null;
+        if (this.inputSource != null) {
+            super.resolver.release(this.inputSource);
+            this.inputSource = null;
+        }
+        super.recycle();
+    }
+
+    /**
+     * @return True if byte ranges support is enabled and request has range header.
+     */
+    protected boolean hasRanges() {
+        return this.byteRanges && this.request.getHeader("Range") != null;
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public Serializable getKey() {
+        return inputSource.getURI();
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        if (hasRanges()) {
+            // This is a byte range request so we can't use the cache, return null.
+            return null;
+        } else {
+            return inputSource.getValidity();
+        }
+    }
+
+    /**
+     * @return the time the read source was last modified or 0 if it is not
+     *         possible to detect
+     */
+    public long getLastModified() {
+        if (hasRanges()) {
+            // This is a byte range request so we can't use the cache, return null.
+            return 0;
+        }
+
+        if (quickTest) {
+            return inputSource.getLastModified();
+        }
+
+        final String systemId = (String) documents.get(request.getRequestURI());
+        if (systemId == null || inputSource.getURI().equals(systemId)) {
+            return inputSource.getLastModified();
+        }
+
+        documents.remove(request.getRequestURI());
+        return 0;
+    }
+
+    protected void processStream(InputStream inputStream)
+    throws IOException, ProcessingException {
+        byte[] buffer = new byte[bufferSize];
+        int length = -1;
+
+        String ranges = request.getHeader("Range");
+
+        ByteRange byteRange;
+        if (byteRanges && ranges != null) {
+            try {
+                ranges = ranges.substring(ranges.indexOf('=') + 1);
+                byteRange = new ByteRange(ranges);
+            } catch (NumberFormatException e) {
+                byteRange = null;
+
+                // TC: Hm.. why don't we have setStatus in the Response interface ?
+                if (response instanceof HttpResponse) {
+                    // Respond with status 416 (Request range not satisfiable)
+                    ((HttpResponse)response).setStatus(416);
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("malformed byte range header [" + String.valueOf(ranges) + "]");
+                    }
+                }
+            }
+        } else {
+            byteRange = null;
+        }
+
+        long contentLength = inputSource.getContentLength();
+
+        if (byteRange != null) {
+            String entityLength;
+            String entityRange;
+            if (contentLength != -1) {
+                entityLength = "" + contentLength;
+                entityRange = byteRange.intersection(new ByteRange(0, contentLength)).toString();
+            } else {
+                entityLength = "*";
+                entityRange = byteRange.toString();
+            }
+
+            response.setHeader("Content-Range", entityRange + "/" + entityLength);
+            if (response instanceof HttpResponse) {
+                // Response with status 206 (Partial content)
+                ((HttpResponse)response).setStatus(206);
+            }
+
+            int pos = 0;
+            int posEnd;
+            while ((length = inputStream.read(buffer)) > -1) {
+                posEnd = pos + length - 1;
+                ByteRange intersection = byteRange.intersection(new ByteRange(pos, posEnd));
+                if (intersection != null) {
+                    out.write(buffer, (int) intersection.getStart() - pos, (int) intersection.length());
+                }
+                pos += length;
+            }
+        } else {
+            if (contentLength != -1) {
+                response.setHeader("Content-Length", Long.toString(contentLength));
+            }
+
+            while ((length = inputStream.read(buffer)) > -1) {
+                out.write(buffer, 0, length);
+            }
+        }
+
+        out.flush();
+    }
+
+    /**
+     * Generates the requested resource.
+     */
+    public void generate()
+    throws IOException, ProcessingException {
+        try {
+            InputStream inputStream;
+            try {
+                inputStream = inputSource.getInputStream();
+            } catch (SourceException e) {
+                throw SourceUtil.handle("Error during resolving of the input stream", e);
+            }
+
+            // Bugzilla Bug #25069: Close inputStream in finally block.
+            try {
+                processStream(inputStream);
+            } finally {
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            }
+
+            if (!quickTest) {
+                // if everything is ok, add this to the list of generated documents
+                // (see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=102921894301915 )
+                documents.put(request.getRequestURI(), inputSource.getURI());
+            }
+        } catch (IOException e) {
+            getLogger().debug("Received an IOException, assuming client severed connection on purpose");
+        }
+    }
+
+    /**
+     * Returns the mime-type of the resource in process.
+     */
+    public String getMimeType() {
+        Context ctx = ObjectModelHelper.getContext(objectModel);
+        if (ctx != null) {
+            final String mimeType = ctx.getMimeType(source);
+            if (mimeType != null) {
+                return mimeType;
+            }
+        }
+
+        return inputSource.getMimeType();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ServiceableReader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ServiceableReader.java
new file mode 100644
index 0000000..9226bde
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/ServiceableReader.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.reading;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+/**
+ * The serviceable reader will allow any {@link Reader} implementation that
+ * extends this to access other Avalon components.
+ *
+ * @version $Id$
+ */
+public abstract class ServiceableReader 
+    extends AbstractReader 
+    implements Serviceable {
+
+       
+    protected ServiceManager manager;
+     
+    /**
+	 * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+	 */
+	public void service(ServiceManager manager) 
+    throws ServiceException {
+        this.manager = manager;
+	}
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/VirtualPipelineReader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/VirtualPipelineReader.java
new file mode 100644
index 0000000..ce33cdb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/reading/VirtualPipelineReader.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.reading;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.impl.AbstractVirtualSitemapComponent;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class VirtualPipelineReader extends AbstractVirtualSitemapComponent
+    implements Reader {
+
+    protected String getTypeName() {
+        return "reader";
+    }
+
+    /**
+     * Set the <code>OutputStream</code>
+     */
+    public void setOutputStream(OutputStream out) {
+        this.getMappedSourceEnvironment().setOutputStream(out);
+    }
+
+    /**
+     * Get the mime-type of the output of this <code>Reader</code>
+     */
+    public String getMimeType() {
+        return this.getPipeline().getMimeType();
+    }
+
+    /**
+     * @return the time the read source was last modified or 0 if it is not
+     *         possible to detect
+     */
+    public long getLastModified() {
+        return 0;
+    }
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return this.getPipeline().shouldSetContentLength();
+    }
+
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+
+        // Should use SourceResolver and context of the this
+        // components' sitemap, not caller sitemap
+        EnvironmentHelper.enterEnvironment(this.getVPCEnvironment());
+        try {
+            this.getPipeline().prepareInternal(this.getVPCEnvironment());
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+
+        // Should use SourceResolver of the this components' sitemap, not caller sitemap
+        EnvironmentHelper.enterEnvironment(this.getMappedSourceEnvironment());
+        try {
+            this.getPipeline().process(this.getMappedSourceEnvironment());
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractRegexpSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractRegexpSelector.java
new file mode 100644
index 0000000..5679f84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractRegexpSelector.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.REProgram;
+import org.apache.regexp.RESyntaxException;
+
+/**
+ * <p>The {@link AbstractRegexpSelector} abstract class defines a simple selector
+ * operating over configured regular-expression patterns.</p> 
+ *
+ * <p>Configuration of an {@link AbstractRegexpSelector} is quite simple: first of
+ * all the patterns used for selections must be configured:</p>
+ * 
+ * <pre>
+ * &lt;map:components&gt;
+ *   ...
+ *   &lt;map:selectors default="..."&gt;
+ *     &lt;map:selector name="..." src="org.apache.cocoon.selection...."&gt;
+ *       &lt;pattern name="empty"&gt;^$&lt;/pattern&gt;
+ *       &lt;pattern name="number"&gt;^[0-9]+$&lt;/pattern&gt;
+ *       &lt;pattern name="string"&gt;^.+$&lt;/pattern&gt;
+ *     &lt;/map:selector&gt;
+ *  &lt;/map:selectors&gt;
+ * &lt;/map:components&gt;
+ * </pre>
+ * 
+ * <p>Then, each configured pattern can be referenced in the pipelines section of
+ * the sitemap:</p>
+ * 
+ * <pre>
+ * &lt;map:pipelines&gt;
+ *   ...
+ *   &lt;map:match ...&gt;
+ *     ...
+ *     &lt;map:select type="browser"&gt;
+ *       &lt;map:when test="empty"&gt;...&lt;/map:when&gt;
+ *       &lt;map:when test="number"&gt;...&lt;/map:when&gt;
+ *       &lt;map:when test="string"&gt;...&lt;/map:when&gt;
+ *       &lt;map:otherwise&gt;...&lt;/map:otherwise&gt;
+ *     &lt;/map:select&gt;
+ *     ...
+ *   &lt;/map:match&gt;
+ *   ...
+ * &lt;/map:pipelines&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public abstract class AbstractRegexpSelector extends AbstractSwitchSelector
+implements Configurable, ThreadSafe {
+
+    /** <p>A {@link Map} of regular expression programs by name.</p> */
+    protected Map patterns = new HashMap();
+
+    /**
+     * <p>Create a new {@link AbstractRegexpSelector} instance.</p>
+     */
+    protected AbstractRegexpSelector() {
+        super();
+    }
+
+    /**
+     * <p>Select a pipeline fragment based on a previously configured pattern.</p>
+     * 
+     * @param patternName the name of the configured pattern.
+     * @param selectorContext the string to be matched by the named pattern.
+     * @return <b>true</b> if the contexts is matched by the configured pattern.
+     */
+    public boolean select(String patternName, Object selectorContext) {
+
+        /* Check that the context selection returned something */
+        if (selectorContext == null) return(false);
+
+        /* Check that we actually have a configured pattern */
+        REProgram pattern = (REProgram) this.patterns.get(patternName);
+        if (pattern == null) {
+            if (this.getLogger().isWarnEnabled()) {
+                this.getLogger().warn("The specified pattern name \"" + patternName
+                                      + "\" was not configured in this instance");
+            }
+            return(false);
+        }
+
+        /* Pattern matching */
+        return(new RE(pattern).match(selectorContext.toString()));
+    }
+
+    /**
+     * <p>Configure this instance parsing all regular expression patterns.</p>
+     * 
+     * @param configuration the {@link Configuration} instance where configured
+     *                      patterns are defined.
+     * @throws ConfigurationException if one of the regular-expression to configure
+     *                                could not be compiled.
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        Configuration patterns[] = configuration.getChildren("pattern");
+        for (int x = 0; x < patterns.length; x++) {
+            String name = patterns[x].getAttribute("name");
+            String pattern = patterns[x].getValue();
+            this.patterns.put(name, this.compile(pattern));
+        }
+    }
+
+    /**
+     * <p>Compile the pattern in a {@link REProgram}.</p>
+     * 
+     * @param pattern the regular expression pattern in a textual format.
+     * @return a compiled regular expression pattern.
+     * @throws ConfigurationException in the pattern could not be compiled. 
+     */
+    protected REProgram compile(String pattern)
+    throws ConfigurationException {
+        if (pattern == null) {
+            throw new ConfigurationException("Null pattern");
+        }
+
+        if (pattern.length() == 0) {
+            pattern = "^$";
+            if (this.getLogger().isWarnEnabled()) {
+                this.getLogger().warn("The empty pattern string was rewritten to "
+                                      + "'^$' to match for empty strings.  If you "
+                                      + "intended to match all strings, please "
+                                      + "change your pattern to '.*'");
+            }
+        }
+
+        try {
+            RECompiler compiler = new RECompiler();
+            REProgram program = compiler.compile(pattern);
+            return program;
+        } catch (RESyntaxException rse) {
+            getLogger().debug("Failed to compile the pattern '" + pattern + "'", rse);
+            throw new ConfigurationException(rse.getMessage(), rse);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractSwitchSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractSwitchSelector.java
new file mode 100644
index 0000000..6d51a0b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/AbstractSwitchSelector.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import java.util.Map;
+
+/**
+ * Abstract SwitchSelector class.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractSwitchSelector extends AbstractLogEnabled
+    implements SwitchSelector {
+
+    /**
+     * Method to create a selector context.
+     *
+     * @param objectModel The <code>Map</code> containing object of the
+     *                    calling environment which may be used
+     *                    to select values to test the expression.
+     * @param parameters  The sitemap parameters, as specified by
+     *                    &lt;parameter/&gt; tags.
+     * @return selector context
+     */
+    public abstract Object getSelectorContext(Map objectModel, Parameters parameters);
+
+    /**
+     * Selectors test pattern against some objects in a <code>Map</code>
+     * model and signals success with the returned boolean value
+     * @param expression  The expression to test.
+     * @return boolean    Signals successful test.
+     */
+    public abstract boolean select(String expression, Object selectorContext);
+
+    /**
+     * Selectors test pattern against some objects in a <code>Map</code>
+     * model and signals success with the returned boolean value
+     * @param expr        The expression to test.
+     * @return Signals successful test.
+     */
+    public boolean select(String expr, Map objectModel, Parameters params) {
+        return select(expr, getSelectorContext(objectModel, params));
+    }
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/BrowserSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/BrowserSelector.java
new file mode 100644
index 0000000..6e6a1bd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/BrowserSelector.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * Tests a specific browser pattern against the requesting user-agent.
+ *
+ * @version $Id$
+ */
+
+public class BrowserSelector extends NamedPatternsSelector {
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        configure(conf, "browser", "name", "useragent");
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        // Inform proxies that response varies with the user-agent header
+        ObjectModelHelper.getResponse(objectModel).addHeader("Vary", "User-Agent");
+
+        // Get the user-agent request header
+        String userAgent = ObjectModelHelper.getRequest(objectModel).getHeader("User-Agent");
+        if (userAgent == null) {
+            getLogger().debug("No User-Agent header -- failing.");
+            return false;
+        }
+
+        return checkPatterns(expression, userAgent);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/CookieSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/CookieSelector.java
new file mode 100644
index 0000000..171e236
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/CookieSelector.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string against a configurable cookie's value.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr>
+ *	<td><code>cookie-name</code></td>
+ *	<td>Name of the cookie whose value to match against</td>
+ *	</tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class CookieSelector extends AbstractLogEnabled
+        implements Configurable, Selector, ThreadSafe {
+
+    protected String defaultName;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultName = config.getChild("cookie-name").getValue(null);
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+
+        String name = parameters.getParameter("cookie-name", this.defaultName);
+        if (name == null) {
+            getLogger().warn("No cookie name given -- failing.");
+            return false;
+        }
+
+        Cookie[] cookies = ObjectModelHelper.getRequest(objectModel).getCookies();
+        if (cookies == null) {
+            getLogger().debug("Cookie '" + name + "' not set -- failing");
+            return false;
+        }
+
+        // TODO: this is not optimized
+        String value = null;
+        for (int i = 0; i < cookies.length; i++) {
+            if (cookies[i].getName().equals(name)) {
+                value = cookies[i].getValue();
+                break;
+            }
+        }
+
+        if (value == null) {
+            getLogger().debug("Cookie '" + name + "' not set -- failing");
+            return false;
+        }
+
+        return value.equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ExceptionSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ExceptionSelector.java
new file mode 100644
index 0000000..3246b22
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ExceptionSelector.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+
+/**
+ * In a &lt;map:handle-errors>, selects depending on the exception that caused the error.
+ * The configuration of this selector allows to map exception class names to symbolic names
+ * that are used in the &lt;map:when> alternatives.
+ * <p>
+ * Example configuration :
+ * <pre>
+ *   &lt;map:selector type="error" src="....ExceptionSelector">
+ *     &lt;exception class="org.xml.sax.SAXException" name="sax" unroll="true"/>
+ *     &lt;exception name="not-found" class="org.apache.cocoon.ResourceNotFoundException"/>
+ *     &lt;exception class="org.apache.cocoon.ProcessingException" unroll="true"/>
+ *     &lt;exception name="denied" class="java.security.SecurityException"/>
+ *     &lt;exception name="denied" class="my.comp.auth.AuthenticationFailure"/>
+ *   &lt;/map:selector>
+ * </pre>
+ * This example shows several features :
+ * <li>the "class" is the class name of the exception (which can be any <code>Throwable</code>),</li>
+ * <li>an exception can be given a name, which is used in the &lt;map:when> tests,</li>
+ * <li>an exception can be unrolled, meaning we try to get its cause and then consider this cause for
+ *     the exception name</li>
+ * Note that both "name" and "unroll" can be specified. In that case, we first try to unroll the exception,
+ * and if none of the causes has a name, then the "name" attribute is considered.
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+
+public class ExceptionSelector extends AbstractSwitchSelector implements Configurable {
+
+	/** Exception classes */
+    private Class[] clazz;
+    
+    /** Associated symbolic names (can be null) */
+    private String[] name;
+    
+    /** Do we want to unroll them ? */
+    private boolean[] unroll;
+
+    public void configure(Configuration conf) throws ConfigurationException {
+
+        Configuration[] children = conf.getChildren("exception");
+
+        this.clazz = new Class[children.length];
+        this.name = new String[children.length];
+        this.unroll = new boolean[children.length];
+
+        for (int i = 0; i < children.length; i++) {
+            Configuration child = children[i];
+
+            String childClassName = child.getAttribute("class");
+            Class childClass = null;
+            try {
+                childClass = ClassUtils.loadClass(childClassName);
+            }
+            catch (Exception e) {
+                throw new ConfigurationException("Cannot load class '" + childClassName + "' at " + child.getLocation());
+            }
+            
+            // Check that this class is not hidden by a more general class already declared
+            for (int j = 0; j < i; j++) {
+                if (this.clazz[j].isAssignableFrom(childClass)) {
+                    throw new ConfigurationException("Class '" + this.clazz[j].getName() + "' hides its subclass '" +
+                    	childClassName + "' at " + child.getLocation());
+                }
+            }
+
+			this.clazz[i] = childClass;
+            this.name[i] = child.getAttribute("name", null);
+            this.unroll[i] = child.getAttributeAsBoolean("unroll", false);
+
+            if (this.name[i] == null && !this.unroll[i]) {
+                throw new ConfigurationException("Must specify one of 'name' or 'unroll' at " + child.getLocation());
+            }
+        }
+    }
+
+    /**
+     * Compute the exception type, given the configuration and the exception stored in the object model.
+     * 
+     * @see ObjectModelHelper#getThrowable(java.util.Map)
+     */
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+        // Get the name of the exception
+        Throwable thr = ObjectModelHelper.getThrowable(objectModel);
+        if (thr == null) {
+            throw new IllegalStateException("No exception in object model. ExceptionSelector can only be used in <map:handle-errors>");
+        }
+
+        return find(thr);
+    }
+
+    private FindResult find(Throwable thr) {
+        // Now find the proper name
+        for (int i = 0; i < this.clazz.length; i++) {
+            if (this.clazz[i].isInstance(thr)) {
+
+                // If exception needs to be unrolled, and it has a cause,
+                // return the cause name, if not null (recursively)
+                if (this.unroll[i]) {
+                    Throwable cause = ExceptionUtils.getCause(thr);
+                    if (cause != null) {
+                        FindResult result = find(cause);
+                        if (result != null) {
+                            return result;
+                        }
+                    }
+                }
+
+                // Not unrolled
+                return new FindResult(this.name[i], thr);
+            }
+        }
+
+        // Not found
+        return null;
+    }
+
+    public boolean select(String expression, Object selectorContext) {
+        if ( selectorContext == null ) {
+            return false;
+        }
+        // Just compare the expression with the previously found name
+		boolean result = expression.equals(((FindResult)selectorContext).getName());
+		
+		if (result) {
+			if (getLogger().isDebugEnabled())
+				getLogger().debug("select succesfull for condition " + selectorContext.toString());						
+		}
+        
+		return result; 
+    }
+    
+    static class FindResult {
+    	private String name;
+    	private Throwable throwable;
+    	
+    	public FindResult(String name, Throwable throwable) {
+    		this.name = name;
+    		this.throwable = throwable;
+    	}
+    	
+		public String getName() {
+			return this.name;
+		}
+
+		public void setName(String name) {
+			this.name = name;
+		}
+
+		public Throwable getThrowable() {
+			return this.throwable;
+		}
+
+		public void setThrowable(Throwable throwable) {
+			this.throwable = throwable;
+		}
+		
+		public String toString() {
+			return this.name;
+		}
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HeaderSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HeaderSelector.java
new file mode 100644
index 0000000..267d629
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HeaderSelector.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string against a configurable
+ * request header, e.g. "referer".
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>header-name</code></td><td>Name of the request header to
+ * match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class HeaderSelector extends AbstractLogEnabled
+  implements Configurable, ThreadSafe, Selector {
+
+    protected String defaultName;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        // Check old name
+        this.defaultName = config.getChild("parameter-name").getValue(null);
+        if (defaultName != null) {
+            getLogger().warn("'parameter-name' is deprecated. Please use 'header-name'");
+        }
+        // Load with new one
+        this.defaultName = config.getChild("header-name").getValue(this.defaultName);
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        // Check old name
+        String name = parameters.getParameter("parameter-name", null);
+        if (name != null) {
+            getLogger().warn("'parameter-name' is deprecated. Please use 'header-name'");
+        } else {
+            name = this.defaultName;
+        }
+
+        // Load with new one.
+        name = parameters.getParameter("header-name", name);
+
+        if (name == null) {
+            getLogger().warn("No header name given -- failing.");
+            return false;
+        }
+
+        String value = ObjectModelHelper.getRequest(objectModel).getHeader(name);
+        if (value == null) {
+            getLogger().debug("Header '" + name + "' not set -- failing.");
+            return false;
+        }
+
+        return value.equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HostSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HostSelector.java
new file mode 100644
index 0000000..856958f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/HostSelector.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string from within the host parameter
+ * of the HTTP request.
+ *
+ * <p>Configuration:
+ * <pre>
+ * &lt;map:selector name="host" src="org.apache.cocoon.selection.HostSelector"&gt;
+ *   &lt;host name="uk-site" value="www.foo.co.uk"/&gt;
+ * &lt;/map:selector&gt;
+ * </pre>
+ * <p>Usage:
+ * <pre>
+ * &lt;map:select type="host"&gt;
+ *   &lt;map:when test="uk-site"&gt;
+ *     &lt;map:transform src="stylesheets/page/uk.xsl"/&gt;
+ *   &lt;/map:when&gt;
+ *   &lt;map:otherwise&gt;
+ *     &lt;map:transform src="stylesheets/page/us.xsl"/&gt;
+ *   &lt;/map:otherwise&gt;
+ * &lt;/map:select&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+
+public class HostSelector extends NamedPatternsSelector {
+
+    public void configure(Configuration conf) throws ConfigurationException {
+        configure(conf, "host", "name", "value");
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        // Inform proxies that response varies with the Host header
+        ObjectModelHelper.getResponse(objectModel).addHeader("Vary", "Host");
+
+        // Get the host request header
+        String host = ObjectModelHelper.getRequest(objectModel).getHeader("Host");
+        if (host == null) {
+            getLogger().debug("No Host header -- failing.");
+            return false;
+        }
+
+        return checkPatterns(expression, host);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java
new file mode 100644
index 0000000..2c6b17c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/NamedPatternsSelector.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract class for selectors that select a value when it matches
+ * some patterns associated to the select expression.
+ *
+ * @see BrowserSelector
+ * @see HostSelector
+ * @version $Id$
+ */
+
+public abstract class NamedPatternsSelector extends AbstractLogEnabled
+  implements Configurable, ThreadSafe, Selector {
+
+    /**
+     * Association of names to String[] of values.
+     */
+    private Map strings;
+
+    /**
+     * Setup the association from expressions to a list of patterns. The configuration
+     * should look like :
+     * &lt;pre&gt;
+     *  &lt;map:selector name="foo" src="..."&gt;
+     *    &lt;confName nameAttr="expression" valueAttr="pattern"/&gt;
+     *    ... others (expression, pattern) associations ...
+     *  &lt;/map:selector&gt;
+     * &lt;/pre&gt;
+     *
+     * @param conf the configuration
+     * @param confName the name of children of <code>conf</code> that will be used to
+     *            build associations
+     * @param nameAttr the name of the attribute that holds the expression
+     * @param valueAttr the name of the attribute that holds the pattern
+     */
+    protected void configure(Configuration conf, String confName, String nameAttr, String valueAttr)
+      throws ConfigurationException {
+        Configuration confs[] = conf.getChildren(confName);
+        Map configMap = new HashMap();
+
+        // Build a list of strings for each name
+        for (int i = 0; i < confs.length; i++) {
+            String name = confs[i].getAttribute(nameAttr);
+            String value = confs[i].getAttribute(valueAttr);
+
+            // Get value list for this name
+            List nameList = (List)configMap.get(name);
+            if (nameList == null) {
+                nameList = new ArrayList();
+                configMap.put(name, nameList);
+            }
+
+            // Add the current value
+            nameList.add(value);
+        }
+
+        // Convert lists to arrays for faster lookup
+        Iterator entries = configMap.entrySet().iterator();
+        while(entries.hasNext()) {
+            Map.Entry entry = (Map.Entry)entries.next();
+            List nameList = (List)entry.getValue();
+            entry.setValue(nameList.toArray(new String[nameList.size()]));
+        }
+
+        this.strings = configMap;
+    }
+
+    /**
+     * Checks if <code>value</code> is a substring of one of the patterns associated
+     * to <code>expression</code>
+     *
+     * @param expression the expression that is selected
+     * @param value the value to check
+     * @return true if <code>value</code> matches one of the patterns
+     */
+    protected boolean checkPatterns(String expression, String value) {
+        if (value == null) {
+            getLogger().debug("No value given -- failing.");
+            return false;
+        }
+        // Get patterns for 'expression'
+        String[] patterns = (String[])this.strings.get(expression);
+        if (patterns == null) {
+            getLogger().warn("No configuration for expression '" + expression + "' -- failing.");
+            return false;
+        }
+
+        // Does a pattern match 'value' ?
+        for (int i = 0; i < patterns.length; i++) {
+            if (value.indexOf(patterns[i]) != -1) {
+                getLogger().debug(expression + " selected value " + value);
+                return true;
+            }
+        }
+
+        // No match
+        return false;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ParameterSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ParameterSelector.java
new file mode 100644
index 0000000..31181d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ParameterSelector.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string in the parameters object passed to it.
+ *
+ * <pre>
+ *  &lt;map:selector name="parameter" factory="org.apache.cocoon.selection.ParameterSelector"/&gt;
+ *
+ *   &lt;map:select type="parameter"&gt;
+ *      &lt;map:parameter name="parameter-selector-test" value="{mySitemapParameter}"/&gt;
+ *
+ *      &lt;map:when test="myParameterValue"&gt;
+ *         &lt;!-- executes iff {mySitemapParameter} == "myParameterValue" --&gt;
+ *         &lt;map:transform src="stylesheets/page/uk.xsl"/&gt;
+ *      &lt;/map:when&gt;
+ *      &lt;map:otherwise&gt;
+ *         &lt;map:transform src="stylesheets/page/us.xsl"/&gt;
+ *      &lt;/map:otherwise&gt;
+ *   &lt;/map:select&gt;
+ * </pre>
+ *
+ * The purpose of this selector is to allow an action to set parameters
+ * and to be able to select between different pipeline configurations
+ * depending on those parameters.
+ *
+ * @version $Id$
+ */
+public class ParameterSelector implements ThreadSafe, Selector {
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        String compareToString = parameters.getParameter("parameter-selector-test", null);
+        return compareToString != null && compareToString.equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpHeaderSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpHeaderSelector.java
new file mode 100644
index 0000000..f0297aa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpHeaderSelector.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+/**
+ * <p>The {@link RegexpHeaderSelector} class defines a selector matching
+ * specific headers to configured regular-expression patterns.</p> 
+ *
+ * <p>The configuration of an {@link RegexpHeaderSelector} follows exactly
+ * what has been outlined in {@link AbstractRegexpSelector} regarding regular
+ * expression patterns, and additionally it requires an extra configuration element
+ * specifying the header whose value needs to be matched:</p>
+ * 
+ * <pre>
+ * &lt;map:components&gt;
+ *   ...
+ *   &lt;map:selectors default="..."&gt;
+ *     &lt;map:selector name="..." src="org.apache.cocoon.selection...."&gt;
+ *       &lt;pattern name="empty"&gt;^$&lt;/pattern&gt;
+ *       &lt;pattern name="number"&gt;^[0-9]+$&lt;/pattern&gt;
+ *       &lt;pattern name="string"&gt;^.+$&lt;/pattern&gt;
+ *       &lt;header-name&gt;...&lt;/header-name&gt;
+ *     &lt;/map:selector&gt;
+ *  &lt;/map:selectors&gt;
+ * &lt;/map:components&gt;
+ * </pre>
+ * 
+ * <p>If not configured, or if it needs to be overriddent, the header name can
+ * also be specified as a <code>&lt;map:parameter&nbsp;.../&gt;</code> inside the
+ * pipeline itself.</p>
+ * 
+ * @version $Id$
+ */
+public class RegexpHeaderSelector extends AbstractRegexpSelector {
+
+    /** <p>The name of the header to work on.</p> */
+    protected String headerName;
+
+    /**
+     * <p>Create a new {@link RegexpHeaderSelector} instance.</p>
+     */
+    public RegexpHeaderSelector() {
+        super();
+    }
+
+    /**
+     * <p>Configure this instance parsing all regular expression patterns and
+     * storing the header name upon which selection occurs.</p>
+     * 
+     * @param configuration the {@link Configuration} instance where configured
+     *                      patterns are defined.
+     * @throws ConfigurationException if one of the regular-expression to configure
+     *                                could not be compiled.
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        super.configure(configuration);
+        this.headerName = configuration.getChild("header-name").getValue(null);
+    }
+
+    /**
+     * <p>Return the value of the header identified by the configured header
+     * name, if any.</p>
+     * 
+     * @param objectModel the Cocoon object model.
+     * @param parameters the {@link Parameters} associated with the pipeline.
+     * @return the value of the configured request parameter or <b>null</b>.
+     */
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+        String name = parameters.getParameter("header-name", this.headerName);
+        if (name == null) {
+            this.getLogger().warn("No header name given -- failing.");
+            return null;
+        }
+        return ObjectModelHelper.getRequest(objectModel).getHeader(name);
+    }
+
+    /**
+     * Selectors test pattern against some objects in a <code>Map</code>
+     * model and signals success with the returned boolean value
+     * @param expr        The expression to test.
+     * @return Signals successful test.
+     */
+    public boolean select(String expr, Map objectModel, Parameters params) {
+	// Inform proxies that response varies with the selector header
+	String name = params.getParameter("header-name", this.headerName);
+	if (name != null)
+	    ObjectModelHelper.getResponse(objectModel).addHeader("Vary", name);
+        return select(expr, getSelectorContext(objectModel, params));
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpRequestParameterSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpRequestParameterSelector.java
new file mode 100644
index 0000000..09219fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RegexpRequestParameterSelector.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+/**
+ * <p>The {@link RegexpRequestParameterSelector} class defines a selector matching
+ * specific request parameters to configured regular-expression patterns.</p> 
+ *
+ * <p>The configuration of an {@link RegexpRequestParameterSelector} follows exactly
+ * what has been outlined in {@link AbstractRegexpSelector} regarting regular
+ * expression patterns, and additionally it requires an extra configuration element
+ * specifying the request parameter whose value needs to be matched:</p>
+ * 
+ * <pre>
+ * &lt;map:components&gt;
+ *   ...
+ *   &lt;map:selectors default="..."&gt;
+ *     &lt;map:selector name="..." src="org.apache.cocoon.selection...."&gt;
+ *       &lt;pattern name="empty"&gt;^$&lt;/pattern&gt;
+ *       &lt;pattern name="number"&gt;^[0-9]+$&lt;/pattern&gt;
+ *       &lt;pattern name="string"&gt;^.+$&lt;/pattern&gt;
+ *       &lt;parameter-name&gt;...&lt;/parameter-name&gt;
+ *     &lt;/map:selector&gt;
+ *  &lt;/map:selectors&gt;
+ * &lt;/map:components&gt;
+ * </pre>
+ * 
+ * <p>If not configured, or if it needs to be overriddent, the parameter name can
+ * also be specified as a <code>&lt;map:parameter&nbsp;.../&gt;</code> inside the
+ * pipeline itself.</p>
+ * 
+ * @version $Id$
+ */
+public class RegexpRequestParameterSelector extends AbstractRegexpSelector {
+
+    /** <p>The name of the parameter to work on.</p> */
+    protected String parameterName;
+
+    /**
+     * <p>Create a new {@link RegexpRequestParameterSelector} instance.</p>
+     */
+    public RegexpRequestParameterSelector() {
+        super();
+    }
+
+    /**
+     * <p>Configure this instance parsing all regular expression patterns and
+     * storing the parameter name upon which selection occurs.</p>
+     * 
+     * @param configuration the {@link Configuration} instance where configured
+     *                      patterns are defined.
+     * @throws ConfigurationException if one of the regular-expression to configure
+     *                                could not be compiled.
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        super.configure(configuration);
+        this.parameterName = configuration.getChild("parameter-name").getValue(null);
+    }
+
+    /**
+     * <p>Return the value of the parameter identified by the configured parameter
+     * name, if any.</p>
+     * 
+     * @param objectModel the Cocoon object model.
+     * @param parameters the {@link Parameters} associated with the pipeline.
+     * @return the value of the configured request parameter or <b>null</b>.
+     */
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+        String name = parameters.getParameter("parameter-name", this.parameterName);
+        if (name == null) {
+            this.getLogger().warn("No parameter name given -- failing.");
+            return null;
+        }
+        return ObjectModelHelper.getRequest(objectModel).getParameter(name);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestAttributeSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestAttributeSelector.java
new file mode 100644
index 0000000..b26f6a7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestAttributeSelector.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string against a configurable request
+ * attribute's string represenation.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the request attribute.</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RequestAttributeSelector extends AbstractLogEnabled
+  implements Configurable, ThreadSafe, Selector {
+
+    protected String defaultName;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultName = config.getChild("attribute-name").getValue(null);
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        String name = parameters.getParameter("attribute-name", this.defaultName);
+
+        if (name == null) {
+            getLogger().warn("No attribute name given -- failing.");
+            return false;
+        }
+
+        Object value = ObjectModelHelper.getRequest(objectModel).getAttribute(name);
+        if (value == null) {
+            getLogger().debug("Request attribute '" + name + "' not set -- failing.");
+            return false;
+        }
+
+        return value.toString().equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestMethodSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestMethodSelector.java
new file mode 100644
index 0000000..2d31e32
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestMethodSelector.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a getMethod() of the HTTP request.
+ *
+ * @version $Id$
+ */
+public class RequestMethodSelector extends AbstractLogEnabled
+  implements ThreadSafe, Selector {
+
+    public boolean select(
+         String expression, Map objectModel, Parameters parameters) 
+    {
+        String method = ObjectModelHelper.getRequest(objectModel).getMethod();
+        return method.equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestParameterSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestParameterSelector.java
new file mode 100644
index 0000000..945af72
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/RequestParameterSelector.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string against a configurable request parameter's value.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>parameter-name</code></td><td>Name of the request
+ * parameter whose value to match against</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class RequestParameterSelector extends AbstractSwitchSelector
+  implements Configurable, ThreadSafe {
+
+    protected String defaultName;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultName = config.getChild("parameter-name").getValue(null);
+    }
+
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+        
+        String name = parameters.getParameter("parameter-name", this.defaultName);
+
+        if (name == null) {
+            getLogger().warn("No parameter name given -- failing.");
+            return null;
+        }
+
+        return ObjectModelHelper.getRequest(objectModel).getParameter(name);
+    }
+
+    public boolean select(String expression, Object selectorContext) {
+        if (selectorContext == null) {
+            getLogger().debug("Request parameter '" + selectorContext + "' not set -- failing.");
+            return false;
+        }
+
+        return selectorContext.equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ResourceExistsSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ResourceExistsSelector.java
new file mode 100644
index 0000000..b83f1d5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/ResourceExistsSelector.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * Selects the first of a set of Resources (usually files) that exists.
+ * 
+ * <p>
+ * A parameter 'prefix', 
+ * <pre>
+ *   &lt;map:parameter src="prefix" value="<code>some/path</code>"/&lt;
+ * </pre>
+ * may be supplied to the selector instance.  This prefix is prepended to all
+ * test expressions before evaluation.  The default prefix is '' (empty string),
+ * meaning that all expressions are relative to the current sitemap, unless
+ * explicitly overridden.
+ * 
+ * <p><b>NOTE:</b>
+ * Provided resource URI is resolved as Source, relative to the current
+ * sitemap, which differs from behavior of selector in previous versions.
+ * To resolve resource paths relative to the context root, provide prefix
+ * parameter:
+ * <pre>
+ *   &lt;map:parameter name="prefix" value="context://"/&lt;
+ * </pre>
+ * 
+ * <p>
+ * For example, we could define a ResourceExistsSelector with:
+ * <pre>
+ * &lt;map:selector name="resource-exists"
+ *               logger="sitemap.selector.resource-exists"
+ *               src="org.apache.cocoon.selection.ResourceExistsSelector" /&lt;
+ * </pre>
+ * And use it to build a PDF from XSL:FO or a higher-level XML format with:
+ *
+ * <pre>
+ *  &lt;map:match pattern="**.pdf"&lt;
+ *    &lt;map:select type="resource-exists"&lt;
+ *       &lt;map:when test="context/xdocs/{1}.fo"&lt;
+ *          &lt;map:generate src="content/xdocs/{1}.fo" /&lt;
+ *       &lt;/map:when&lt;
+ *       &lt;map:otherwise&lt;
+ *         &lt;map:generate src="content/xdocs/{1}.xml" /&lt;
+ *         &lt;map:transform src="stylesheets/document2fo.xsl" /&lt;
+ *       &lt;/map:otherwise&lt;
+ *    &lt;/map:select&lt;
+ *    &lt;map:serialize type="fo2pdf" /&lt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class ResourceExistsSelector extends AbstractLogEnabled
+                                    implements ThreadSafe, Serviceable, Disposable, Selector {
+
+    private ServiceManager manager;
+    private SourceResolver resolver;
+    
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
+    }
+
+    public void dispose() {
+        this.manager.release(this.resolver);
+        this.resolver = null;
+        this.manager = null;
+    }
+    
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        String resourceURI = parameters.getParameter("prefix", "") + expression;
+        Source source = null;
+        try {
+            source = resolver.resolveURI(resourceURI);
+            return source.exists();
+        } catch (SourceNotFoundException e) {
+            return false;
+        } catch (Exception e) {
+            getLogger().warn("Exception resolving resource " + resourceURI, e);
+            return false;
+        } finally {
+            if (source != null) {
+                resolver.release(source);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/Selector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/Selector.java
new file mode 100644
index 0000000..423d69e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/Selector.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import java.util.Map;
+
+/**
+ *
+ * @version $Id$
+ */
+public interface Selector {
+
+    String ROLE = Selector.class.getName();
+    /**
+     * Selectors test pattern against some objects in a <code>Map</code>
+     * model and signals success with the returned boolean value
+     * @param expression  The expression to test.
+     * @param objectModel The <code>Map</code> containing object of the
+     *                    calling environment which may be used
+     *                    to select values to test the expression.
+     * @param parameters  The sitemap parameters, as specified by &lt;parameter/&gt; tags.
+     * @return boolean    Signals successfull test.
+     */
+    boolean select (String expression, Map objectModel, Parameters parameters);
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SessionAttributeSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SessionAttributeSelector.java
new file mode 100644
index 0000000..eaf7bbc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SessionAttributeSelector.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+import java.util.Map;
+
+/**
+ * A <code>Selector</code> that matches a string against a configurable session
+ * attribute's string represenation.
+ *
+ * <p><b>Global and local configuration</b></p>
+ * <table border="1">
+ * <tr><td><code>attribute-name</code></td><td>String identifying the session attribute.</td></tr>
+ * </table>
+ *
+ * @version $Id$
+ */
+public class SessionAttributeSelector extends AbstractLogEnabled
+  implements Configurable, ThreadSafe, Selector {
+
+    protected String defaultName;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.defaultName = config.getChild("attribute-name").getValue(null);
+    }
+
+    public boolean select(String expression, Map objectModel, Parameters parameters) {
+        String name = parameters.getParameter("attribute-name", this.defaultName);
+
+        if (name == null) {
+            getLogger().warn("No attribute name given -- failing.");
+            return false;
+        }
+
+        Object value = ObjectModelHelper.getRequest(objectModel).getSession().getAttribute(name);
+        if (value == null) {
+            getLogger().debug("Session attribute '" + name + "' not set -- failing.");
+            return false;
+        }
+
+        return value.toString().equals(expression);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SimpleSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SimpleSelector.java
new file mode 100644
index 0000000..d646376
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SimpleSelector.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * A very simple selector that operates on string literals, useful especially 
+ * in conjunction with input modules. Usage example:
+ * <pre>
+ *    &lt;map:selector name="simple" src="org.apache.cocoon.selection.SimpleSelector"/&gt;
+ * 
+ *    &lt;map:select type="simple"&gt;
+ *       &lt;map:parameter name="value" value="{request:method}"/&gt;
+ *       &lt;map:when test="GET"&gt;
+ *           ...
+ *       &lt;/map:when&gt;
+ *       &lt;map:when test="POST"&gt;
+ *           ...
+ *       &lt;/map:when&gt;
+ *       &lt;map:when test="PUT"&gt;
+ *           ...
+ *       &lt;/map:when&gt;
+ *       &lt;map:otherwise&gt;
+ *           ...
+ *       &lt;/map:otherwise&gt;
+ *    &lt;/map:select&gt;
+ * </pre>
+ * 
+ * @version $Id$
+ * @since 2.1
+ */
+public class SimpleSelector extends AbstractSwitchSelector implements ThreadSafe {
+
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+        return parameters.getParameter("value", "");
+    }
+
+    public boolean select(String expression, Object selectorContext) {
+        if (selectorContext == null) {
+            if (getLogger().isWarnEnabled()) 
+                getLogger().warn("Value not set -- failing.");
+            return false;
+        }
+
+        return selectorContext.equals(expression);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SwitchSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SwitchSelector.java
new file mode 100644
index 0000000..840279e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/SwitchSelector.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Map;
+
+/**
+ * SwitchSelector is an enhanced Selector interface that allows a
+ * context object to be created to optimize selector conditional testing.
+ *
+ * <p>
+ * The original Selector interface supports an <code>if-then-else</code> style
+ * of conditional testing depending on whether a particular expression is true.
+ * This causes Selector.select() to be invoked for each &lt;map:when&gt;
+ * statement which may be undesirable due to performance or logic reasons.
+ * </p>
+ *
+ * <p>
+ *  <pre>
+ *  Example, the following sitemap snippet:
+ *
+ *  &lt;map:select type="aSelector"&gt;
+ *   &lt;map:when test="test-expr1"&gt;...&lt;/map:when&gt;
+ *   &lt;map:when test="test-expr2"&gt;...&lt;/map:when&gt;
+ *  &lt;/map:select&gt;
+ *
+ *  is interpreted as (pseudo-code):
+ *
+ *  if (aSelector.select("test-expr1", objectModel, params)) {
+ *   ...
+ *  } else if (aSelector.select("test-expr2", objectModel, params)) {
+ *   ...
+ *  }
+ *
+ *  ie. aSelector.select(...) is called once for each &lt;map:when&gt;
+ *  statement.
+ *  </pre>
+ * </p>
+ *
+ * <p>
+ * SwitchSelector allows the developer to first create a
+ * context object which is passed with each call to select(). This context
+ * object is created before any conditional tests are made, and hence can be
+ * used to optimize conditional testing.
+ * </p>
+ *
+ * <p>
+ *  <pre>
+ *  The above example implemented as a SwitchSelector would be
+ *  interpreted as (psuedo-code):
+ *
+ *  Object selectorContext = aSelector.getSelectorContext(objectModel, params);
+ *  
+ *  if (aSelector.select("test-expr1", selectorContext)) {
+ *   ...
+ *  else if (aSelector.select("test-expr2", selectorContext)) {
+ *   ...
+ *  }
+ *
+ *  ie. the bulk of the selector's work is done in getSelectorContext(),
+ *  select() simply compares whether the expression should be considered true. 
+ *  </pre>
+ * </p>
+ *
+ * @version $Id$
+ */
+public interface SwitchSelector extends Selector, ThreadSafe {
+
+    String ROLE = SwitchSelector.class.getName();
+
+    /**
+     * Method to create a selector context.
+     *
+     * @param objectModel The <code>Map</code> containing object of the
+     *                    calling environment which may be used
+     *                    to select values to test the expression.
+     * @param parameters  The sitemap parameters, as specified by
+     *                    &lt;parameter/&gt; tags.
+     * @return            Selector context
+     */
+    Object getSelectorContext(Map objectModel, Parameters parameters);
+
+    /**
+     * Switch Selectors test patterns against a context object
+     * and signal success with the returned boolean value
+     * @param expression  The expression to test.
+     * @param selectorContext The context this test should be performed in.
+     * @return            true if the test was successful.
+     */
+    boolean select(String expression, Object selectorContext);
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/XPathExceptionSelector.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/XPathExceptionSelector.java
new file mode 100644
index 0000000..4eaa7a3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/selection/XPathExceptionSelector.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.selection;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.commons.jxpath.CompiledExpression;
+import org.apache.commons.jxpath.JXPathContext;
+
+/**
+ * Additional to the inherited functionality from its superclass ExceptionSelector,
+ * this selector allows to define xpath expressions to evaluate supplemental information
+ * given in the thrown exception.
+ * The configuration of this selector allows to map not only exceptions but also
+ * xpath expressions to symbolic names that are used in the &lt;map:when> alternatives.
+ * <p>
+ * Example configuration :
+ * <pre>
+ *   &lt;map:selector type="error" src="....XPathExceptionSelector">
+ *     &lt;exception name="denied" class="my.comp.auth.AuthenticationFailure">
+ *       &lt;xpath name="PasswordWrong" test="authCode=10"/>
+ *       &lt;xpath name="PasswordExpired" test="errorCode=11"/>
+ *       &lt;xpath name="AccessForbidden" test="errorCode&gt;11"/>
+ *     &lt;/exception>
+ *   &lt;/map:selector>
+ * </pre>
+ * This example shows several features :
+ * <li>the test is the xpath expression that will be evaluated against the exception ,</li>
+ * <li>an xpath expression can be given a name, which is used in the &lt;map:when> tests,</li>
+ *
+ * @since 2.1
+ * @version $Id$
+ */
+public class XPathExceptionSelector extends ExceptionSelector
+  implements Configurable {
+
+    private Map exception2XPath = new HashMap();
+
+    public void configure(Configuration conf) throws ConfigurationException {
+
+        super.configure(conf);
+
+        Configuration[] children = conf.getChildren("exception");
+        Configuration[] xPathChildren;
+
+        for (int i = 0; i < children.length; i++) {
+            // Check if there are XPath-Expressions configured
+            xPathChildren = children[i].getChildren("xpath");
+            Map xPathMap = new LinkedMap(11);
+
+            for (int j = 0; j < xPathChildren.length; j++) {
+                Configuration xPathChild = xPathChildren[j];
+
+                String xPathName = xPathChild.getAttribute("name");
+                CompiledExpression xPath = JXPathContext.compile(xPathChild.getAttribute("test"));
+
+                xPathMap.put(xPathName, xPath);
+            }
+            if (xPathMap.size() > 0) {
+                // store xpath - config if there is some
+                exception2XPath.put(children[i].getAttribute("name", null),
+                                    xPathMap);
+            }
+        }
+    }
+
+    /**
+     * Compute the exception type, given the configuration and the exception stored in the object model.
+     */
+    public Object getSelectorContext(Map objectModel, Parameters parameters) {
+
+        // get exception from super class
+        FindResult selectorContext = (FindResult) super.getSelectorContext(objectModel,
+                                         parameters);
+
+        if (selectorContext != null) {
+            String exceptionName = selectorContext.getName();
+            Throwable t = selectorContext.getThrowable();
+
+            Map xPathMap = (Map) exception2XPath.get(exceptionName);
+
+            if (xPathMap != null) {
+                // create a context for the thrown exception
+                JXPathContext context = JXPathContext.newContext(t);
+
+                for (Iterator iterator = xPathMap.entrySet().iterator(); iterator.hasNext(); ) {
+                    Map.Entry entry = (Map.Entry) iterator.next();
+
+                    if (((CompiledExpression) entry.getValue()).getValue(context).equals(Boolean.TRUE)) {
+                        // set the configured name if the expression is succesfull
+                        selectorContext.setName((String) entry.getKey());
+                        return selectorContext;
+                    }
+                }
+            }
+        }
+
+        return selectorContext;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractSerializer.java
new file mode 100644
index 0000000..e31ae99
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractSerializer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @version $Id$
+ */
+
+public abstract class AbstractSerializer
+extends AbstractXMLPipe implements Serializer {
+
+    /**
+     * The <code>OutputStream</code> used by this serializer.
+     */
+    protected OutputStream output;
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) 
+    throws IOException {
+        this.output = out;
+    }
+
+    /**
+     * Get the mime-type of the output of this <code>Serializer</code>
+     * This default implementation returns null to indicate that the
+     * mime-type specified in the sitemap is to be used
+     */
+    public String getMimeType() {
+        return null;
+    }
+
+    /**
+     * Recycle serializer by removing references
+     */
+    public void recycle() {
+        super.recycle();
+        this.output = null;
+    }
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return false;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractTextSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractTextSerializer.java
new file mode 100644
index 0000000..8864aa9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/AbstractTextSerializer.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.TraxErrorHandler;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @version $Id$
+ */
+public abstract class AbstractTextSerializer extends AbstractSerializer
+        implements Configurable, CacheableProcessingComponent {
+
+    /**
+     * Cache for avoiding unnecessary checks of namespaces abilities.
+     * It associates a Boolean to the transformer class name.
+     */
+    private static final Map needsNamespaceCache = new HashMap();
+
+    /**
+     * The trax <code>TransformerFactory</code> used by this serializer.
+     */
+    private SAXTransformerFactory tfactory;
+
+    /**
+     * The <code>Properties</code> used by this serializer.
+     */
+    protected final Properties format = new Properties();
+
+    /**
+     * The pipe that adds namespaces as xmlns attributes.
+     */
+    private NamespaceAsAttributes namespacePipe;
+
+    /**
+     * The caching key
+     */
+    private String cachingKey = "1";
+
+    /**
+     * Interpose namespace pipe if needed.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        if (this.namespacePipe == null) {
+            super.setConsumer(consumer);
+        } else {
+            this.namespacePipe.setConsumer(consumer);
+            super.setConsumer(this.namespacePipe);
+        }
+    }
+
+    /**
+     * Interpose namespace pipe if needed.
+     */
+    public void setContentHandler(ContentHandler handler) {
+        if (this.namespacePipe == null) {
+            super.setContentHandler(handler);
+        } else {
+            this.namespacePipe.setContentHandler(handler);
+            super.setContentHandler(this.namespacePipe);
+        }
+    }
+
+    /**
+     * Interpose namespace pipe if needed.
+     */
+    public void setLexicalHandler(LexicalHandler handler) {
+        if (this.namespacePipe == null) {
+            super.setLexicalHandler(handler);
+        } else {
+            this.namespacePipe.setLexicalHandler(handler);
+            super.setLexicalHandler(this.namespacePipe);
+        }
+    }
+
+    /**
+     * Helper for TransformerFactory.
+     */
+    protected SAXTransformerFactory getTransformerFactory() {
+        return tfactory;
+    }
+
+    /**
+     * Helper for TransformerHandler.
+     */
+    protected TransformerHandler getTransformerHandler() throws TransformerException {
+        return this.getTransformerFactory().newTransformerHandler();
+    }
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) throws IOException {
+        /*
+         * Add a level of buffering to the output stream. Xalan serializes
+         * every character individually. In conjunction with chunked
+         * transfer encoding this would otherwise lead to a whopping 6-fold
+         * increase of data on the wire.
+         */
+        //  if (outputBufferSize > 0) {
+        //      super.setOutputStream(
+        //        new BufferedOutputStream(out, outputBufferSize));
+        //  } else {
+        super.setOutputStream(out);
+        //  }
+    }
+
+    public void configure(Core core) {
+        String defaultEncoding  = core.getSettings().getFormEncoding();
+        if (defaultEncoding != null) {
+            this.format.setProperty(OutputKeys.ENCODING, defaultEncoding);
+        }        
+    }
+
+    /**
+     * Set the configurations for this serializer.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        // configure buffer size
+        //   Configuration bsc = conf.getChild("buffer-size", false);
+        //   if(null != bsc)
+        //    outputBufferSize = bsc.getValueAsInteger(DEFAULT_BUFFER_SIZE);
+
+        // configure xalan
+        String cdataSectionElements = conf.getChild("cdata-section-elements").getValue(null);
+        String dtPublic = conf.getChild("doctype-public").getValue(null);
+        String dtSystem = conf.getChild("doctype-system").getValue(null);
+        String encoding = conf.getChild("encoding").getValue(null);
+        String indent = conf.getChild("indent").getValue(null);
+        String mediaType = conf.getChild("media-type").getValue(null);
+        String method = conf.getChild("method").getValue(null);
+        String omitXMLDeclaration = conf.getChild("omit-xml-declaration").getValue(null);
+        String standAlone = conf.getChild("standalone").getValue(null);
+        String version = conf.getChild("version").getValue(null);
+
+        final StringBuffer buffer = new StringBuffer();
+
+        if (cdataSectionElements != null) {
+            format.put(OutputKeys.CDATA_SECTION_ELEMENTS, cdataSectionElements);
+            buffer.append(";cdata-section-elements=").append(cdataSectionElements);
+        }
+        if (dtPublic != null) {
+            format.put(OutputKeys.DOCTYPE_PUBLIC, dtPublic);
+            buffer.append(";doctype-public=").append(dtPublic);
+        }
+        if (dtSystem != null) {
+            format.put(OutputKeys.DOCTYPE_SYSTEM, dtSystem);
+            buffer.append(";doctype-system=").append(dtSystem);
+        }
+        if (encoding != null) {
+            format.put(OutputKeys.ENCODING, encoding);
+            buffer.append(";encoding=").append(encoding);
+        }
+        if (indent != null) {
+            format.put(OutputKeys.INDENT, indent);
+            buffer.append(";indent=").append(indent);
+        }
+        if (mediaType != null) {
+            format.put(OutputKeys.MEDIA_TYPE, mediaType);
+            buffer.append(";media-type=").append(mediaType);
+        }
+        if (method != null) {
+            format.put(OutputKeys.METHOD, method);
+            buffer.append(";method=").append(method);
+        }
+        if (omitXMLDeclaration != null) {
+            format.put(OutputKeys.OMIT_XML_DECLARATION, omitXMLDeclaration);
+            buffer.append(";omit-xml-declaration=").append(omitXMLDeclaration);
+        }
+        if (standAlone != null) {
+            format.put(OutputKeys.STANDALONE, standAlone);
+            buffer.append(";standalone=").append(standAlone);
+        }
+        if (version != null) {
+            format.put(OutputKeys.VERSION, version);
+            buffer.append(";version=").append(version);
+        }
+
+        if ( buffer.length() > 0 ) {
+            this.cachingKey = buffer.toString();
+        }
+        
+        String tFactoryClass = conf.getChild("transformer-factory").getValue(null);
+        if (tFactoryClass != null) {
+            try {
+                this.tfactory = (SAXTransformerFactory) ClassUtils.newInstance(tFactoryClass);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using transformer factory " + tFactoryClass);
+                }
+            } catch (Exception e) {
+                throw new ConfigurationException("Cannot load transformer factory " + tFactoryClass, e);
+            }
+        } else {
+            // Standard TrAX behaviour
+            this.tfactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+        }
+        tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
+
+        // Check if we need namespace as attributes.
+        try {
+            if (needsNamespacesAsAttributes()) {
+                // Setup a correction pipe
+                this.namespacePipe = new NamespaceAsAttributes();
+                this.namespacePipe.enableLogging(getLogger());
+            }
+        } catch (Exception e) {
+            getLogger().warn("Cannot know if transformer needs namespaces attributes - assuming NO.", e);
+        }
+
+    }
+
+    /**
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        super.recycle();
+
+        if (this.namespacePipe != null) {
+            this.namespacePipe.recycle();
+        }
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     * This method must be invoked before the generateValidity() method.
+     *
+     * @return The generated key or <code>0</code> if the component
+     *              is currently not cacheable.
+     */
+    public java.io.Serializable getKey() {
+        return this.cachingKey;
+    }
+
+    /**
+     * Generate the validity object.
+     * Before this method can be invoked the generateKey() method
+     * must be invoked.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+
+    /**
+     * Checks if the used Trax implementation correctly handles namespaces set using
+     * <code>startPrefixMapping()</code>, but wants them also as 'xmlns:' attributes.
+     * <p>
+     * The check consists in sending SAX events representing a minimal namespaced document
+     * with namespaces defined only with calls to <code>startPrefixMapping</code> (no
+     * xmlns:xxx attributes) and check if they are present in the resulting text.
+     */
+    protected boolean needsNamespacesAsAttributes() throws Exception {
+
+        SAXTransformerFactory factory = getTransformerFactory();
+
+        Boolean cacheValue = (Boolean) needsNamespaceCache.get(factory.getClass().getName());
+        if (cacheValue != null) {
+            return cacheValue.booleanValue();
+        } else {
+            // Serialize a minimal document to check how namespaces are handled.
+            StringWriter writer = new StringWriter();
+
+            String uri = "namespaceuri";
+            String prefix = "nsp";
+            String check = "xmlns:" + prefix + "='" + uri + "'";
+
+            TransformerHandler handler = this.getTransformerHandler();
+
+            handler.getTransformer().setOutputProperties(format);
+            handler.setResult(new StreamResult(writer));
+
+            // Output a single element
+            handler.startDocument();
+            handler.startPrefixMapping(prefix, uri);
+            handler.startElement(uri, "element", "", XMLUtils.EMPTY_ATTRIBUTES);
+            handler.endPrefixMapping(prefix);
+            handler.endDocument();
+
+            String text = writer.toString();
+
+            // Check if the namespace is there (replace " by ' to be sure of what we search in)
+            boolean needsIt = (text.replace('"', '\'').indexOf(check) == -1);
+
+            String msg = needsIt ? " needs namespace attributes (will be slower)." : " handles correctly namespaces.";
+
+            getLogger().debug("Trax handler " + handler.getClass().getName() + msg);
+
+            needsNamespaceCache.put(factory.getClass().getName(), BooleanUtils.toBooleanObject(needsIt));
+
+            return needsIt;
+        }
+    }
+
+    //--------------------------------------------------------------------------------------------
+
+    /**
+     * A pipe that ensures that all namespace prefixes are also present as
+     * 'xmlns:' attributes. This used to circumvent Xalan's serialization behaviour
+     * which is to ignore namespaces if they're not present as 'xmlns:xxx' attributes.
+     */
+    public static class NamespaceAsAttributes extends AbstractXMLPipe {
+
+        /**
+         * The prefixes of startPrefixMapping() declarations for the coming element.
+         */
+        private List prefixList = new ArrayList();
+
+        /**
+         * The URIs of startPrefixMapping() declarations for the coming element.
+         */
+        private List uriList = new ArrayList();
+
+        /**
+         * Maps of URI<->prefix mappings. Used to work around a bug in the Xalan
+         * serializer.
+         */
+        private Map uriToPrefixMap = new HashMap();
+        private Map prefixToUriMap = new HashMap();
+
+        /**
+         * True if there has been some startPrefixMapping() for the coming element.
+         */
+        private boolean hasMappings = false;
+
+        public void startDocument() throws SAXException {
+            // Cleanup
+            this.uriToPrefixMap.clear();
+            this.prefixToUriMap.clear();
+            clearMappings();
+            super.startDocument();
+        }
+
+        /**
+         * Track mappings to be able to add <code>xmlns:</code> attributes
+         * in <code>startElement()</code>.
+         */
+        public void startPrefixMapping(String prefix, String uri) throws SAXException {
+            // Store the mappings to reconstitute xmlns:attributes
+            // except prefixes starting with "xml": these are reserved
+            // VG: (uri != null) fixes NPE in startElement
+            if (uri != null && !prefix.startsWith("xml")) {
+                this.hasMappings = true;
+                this.prefixList.add(prefix);
+                this.uriList.add(uri);
+
+                // append the prefix colon now, in order to save concatenations later, but
+                // only for non-empty prefixes.
+                if (prefix.length() > 0) {
+                    this.uriToPrefixMap.put(uri, prefix + ":");
+                } else {
+                    this.uriToPrefixMap.put(uri, prefix);
+                }
+
+                this.prefixToUriMap.put(prefix, uri);
+            }
+            super.startPrefixMapping(prefix, uri);
+        }
+
+        /**
+         * Ensure all namespace declarations are present as <code>xmlns:</code> attributes
+         * and add those needed before calling superclass. This is a workaround for a Xalan bug
+         * (at least in version 2.0.1) : <code>org.apache.xalan.serialize.SerializerToXML</code>
+         * ignores <code>start/endPrefixMapping()</code>.
+         */
+        public void startElement(String eltUri, String eltLocalName, String eltQName, Attributes attrs)
+                throws SAXException {
+
+            // try to restore the qName. The map already contains the colon
+            if (null != eltUri && eltUri.length() != 0 && this.uriToPrefixMap.containsKey(eltUri)) {
+                eltQName = this.uriToPrefixMap.get(eltUri) + eltLocalName;
+            }
+            if (this.hasMappings) {
+                // Add xmlns* attributes where needed
+
+                // New Attributes if we have to add some.
+                AttributesImpl newAttrs = null;
+
+                int mappingCount = this.prefixList.size();
+                int attrCount = attrs.getLength();
+
+                for (int mapping = 0; mapping < mappingCount; mapping++) {
+
+                    // Build infos for this namespace
+                    String uri = (String) this.uriList.get(mapping);
+                    String prefix = (String) this.prefixList.get(mapping);
+                    String qName = prefix.equals("") ? "xmlns" : ("xmlns:" + prefix);
+
+                    // Search for the corresponding xmlns* attribute
+                    boolean found = false;
+                    for (int attr = 0; attr < attrCount; attr++) {
+                        if (qName.equals(attrs.getQName(attr))) {
+                            // Check if mapping and attribute URI match
+                            if (!uri.equals(attrs.getValue(attr))) {
+                                getLogger().error("URI in prefix mapping and attribute do not match : '"
+                                                  + uri + "' - '" + attrs.getURI(attr) + "'");
+                                throw new SAXException("URI in prefix mapping and attribute do not match");
+                            }
+                            found = true;
+                            break;
+                        }
+                    }
+
+                    if (!found) {
+                        // Need to add this namespace
+                        if (newAttrs == null) {
+                            // Need to test if attrs is empty or we go into an infinite loop...
+                            // Well know SAX bug which I spent 3 hours to remind of :-(
+                            if (attrCount == 0) {
+                                newAttrs = new AttributesImpl();
+                            } else {
+                                newAttrs = new AttributesImpl(attrs);
+                            }
+                        }
+
+                        if (prefix.equals("")) {
+                            newAttrs.addAttribute(Constants.XML_NAMESPACE_URI, "xmlns", "xmlns", "CDATA", uri);
+                        } else {
+                            newAttrs.addAttribute(Constants.XML_NAMESPACE_URI, prefix, qName, "CDATA", uri);
+                        }
+                    }
+                } // end for mapping
+
+                // Cleanup for the next element
+                clearMappings();
+
+                // Start element with new attributes, if any
+                super.startElement(eltUri, eltLocalName, eltQName, newAttrs == null ? attrs : newAttrs);
+            } else {
+                // Normal job
+                super.startElement(eltUri, eltLocalName, eltQName, attrs);
+            }
+        }
+
+
+        /**
+         * Receive notification of the end of an element.
+         * Try to restore the element qName.
+         */
+        public void endElement(String eltUri, String eltLocalName, String eltQName) throws SAXException {
+            // try to restore the qName. The map already contains the colon
+            if (null != eltUri && eltUri.length() != 0 && this.uriToPrefixMap.containsKey(eltUri)) {
+                eltQName = this.uriToPrefixMap.get(eltUri) + eltLocalName;
+            }
+            super.endElement(eltUri, eltLocalName, eltQName);
+        }
+
+        /**
+         * End the scope of a prefix-URI mapping:
+         * remove entry from mapping tables.
+         */
+        public void endPrefixMapping(String prefix) throws SAXException {
+            // remove mappings for xalan-bug-workaround.
+            // Unfortunately, we're not passed the uri, but the prefix here,
+            // so we need to maintain maps in both directions.
+            if (this.prefixToUriMap.containsKey(prefix)) {
+                this.uriToPrefixMap.remove(this.prefixToUriMap.get(prefix));
+                this.prefixToUriMap.remove(prefix);
+            }
+
+            if (hasMappings) {
+                // most of the time, start/endPrefixMapping calls have an element event between them,
+                // which will clear the hasMapping flag and so this code will only be executed in the
+                // rather rare occasion when there are start/endPrefixMapping calls with no element
+                // event in between. If we wouldn't remove the items from the prefixList and uriList here,
+                // the namespace would be incorrectly declared on the next element following the
+                // endPrefixMapping call.
+                int pos = prefixList.lastIndexOf(prefix);
+                if (pos != -1) {
+                    prefixList.remove(pos);
+                    uriList.remove(pos);
+                }
+            }
+
+            super.endPrefixMapping(prefix);
+        }
+
+        /**
+         *
+         */
+        public void endDocument() throws SAXException {
+            // Cleanup
+            this.uriToPrefixMap.clear();
+            this.prefixToUriMap.clear();
+            clearMappings();
+            super.endDocument();
+        }
+
+        private void clearMappings() {
+            this.hasMappings = false;
+            this.prefixList.clear();
+            this.uriList.clear();
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException {
+        super.endDocument();
+
+        //   if (this.output != null) {
+        //       try {
+        //           this.output.flush();
+        //       } catch (IOException ignored) {
+        //       }
+        //   }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/HTMLSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/HTMLSerializer.java
new file mode 100644
index 0000000..9a266c7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/HTMLSerializer.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.CascadingIOException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The html serializer serializes sax events into an html document.
+ * 
+ * @cocoon.sitemap.component.name      html
+ * @cocoon.sitemap.component.mimetype  text/html
+ * @cocoon.sitemap.component.logger sitemap.serializer.html
+ * 
+ * @cocoon.sitemap.component.pooling.max  32
+ * 
+ * @cocoon.sitemap.component.configuration
+ * <doctype-public>-//W3C//DTD HTML 4.01 Transitional//EN</doctype-public>
+ * <doctype-system>http://www.w3.org/TR/html4/loose.dtd</doctype-system>
+ *
+ * 
+ * @version $Id$
+ */
+
+public class HTMLSerializer extends AbstractTextSerializer {
+
+    /**
+     * Set the configurations for this serializer.
+     */
+    public void configure(Configuration conf)
+    throws ConfigurationException {
+        super.configure(conf);
+        this.format.put(OutputKeys.METHOD,"html");
+    }
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) 
+    throws IOException {
+        super.setOutputStream(out);
+        try {
+            TransformerHandler handler = this.getTransformerHandler();
+            handler.getTransformer().setOutputProperties(this.format);
+            handler.setResult(new StreamResult(this.output));
+            this.setContentHandler(handler);
+            this.setLexicalHandler(handler);
+        } catch (Exception e) {
+            final String message = "Cannot set HTMLSerializer outputstream"; 
+            throw new CascadingIOException(message, e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/LinkSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/LinkSerializer.java
new file mode 100644
index 0000000..b83ae2a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/LinkSerializer.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.xml.xlink.ExtendedXLinkPipe;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * @version $Id$
+ */
+
+public class LinkSerializer 
+    extends ExtendedXLinkPipe 
+    implements Serializer {
+
+    private PrintStream out;
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) throws IOException {
+        this.out = new PrintStream(out);
+    }
+
+    /**
+     * Get the mime-type of the output of this <code>Component</code>.
+     */
+    public String getMimeType() {
+        return Constants.LINK_CONTENT_TYPE;
+    }
+
+    public void simpleLink(String href, String role, String arcrole, String title, String show, String actuate, String uri, String name, String raw, Attributes attr)
+    throws SAXException {
+        if (traversable(href)) {
+            print(href);
+        }
+        super.simpleLink(href, role, arcrole, title, show, actuate, uri, name, raw, attr);
+    }
+
+    public void startLocator(String href, String role, String title, String label, String uri, String name, String raw, Attributes attr)
+    throws SAXException {
+        if (traversable(href)) {
+            print(href);
+        }
+        super.startLocator(href, role, title, label, uri, name, raw, attr);
+    }
+
+    private boolean traversable(String href) {
+        if (href.length() == 0) return false;
+        if (href.charAt(0) == '#') return false;
+        if (href.indexOf("://") != -1) return false;
+        if (href.startsWith("mailto:")) return false;
+        if (href.startsWith("news:")) return false;
+        if (href.startsWith("javascript:")) return false;
+        return true;
+    }
+
+    private void print(String href) {
+        int ankerPos = href.indexOf('#');
+        if (ankerPos == -1) {
+            // TODO: Xalan encodes international characters into URL encoding
+            out.println(href);
+        } else {
+            out.println(href.substring(0, ankerPos));
+        }
+    }
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return false;
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        super.recycle();
+        this.out = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/Serializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/Serializer.java
new file mode 100644
index 0000000..b52af13
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/Serializer.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.cocoon.sitemap.SitemapOutputComponent;
+import org.apache.cocoon.xml.XMLConsumer;
+
+/**
+ * A serializer is the last point of a pipeline. It "serializes" XML
+ * arriving as SAX events into any binary format. <br> Serializers can 
+ * additionally implement the {@link org.apache.cocoon.sitemap.SitemapModelComponent} 
+ * interface to gain access to the <code>resolver</code>, <code>objectModel</code>, 
+ * <code>source</code> or <code>parameters</code> objects.
+ * 
+ *
+ * @version $Id$
+ */
+public interface Serializer extends XMLConsumer, SitemapOutputComponent {
+
+    String ROLE = Serializer.class.getName();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/SerializerFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/SerializerFactory.java
new file mode 100644
index 0000000..d48da01
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/SerializerFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+/**
+ * A serializer factory is the factory of {@link Serializer}s.
+ *
+ * <p>Regular SerializerFactory implementation should be
+ * {@link org.apache.avalon.framework.thread.ThreadSafe} component
+ * serving as a factory of lightweight {@link Serializer} objects.</p>
+ *
+ * <p><strong>NOTE:</strong> Only Disposable interface is applicable to
+ * the Serializer instance returned by the {@link #getInstance()}.</p>
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public interface SerializerFactory {
+
+    String ROLE = Serializer.ROLE;
+
+    /**
+     * Instance of the Serializer created by the SerializerFactory
+     */
+    interface Instance extends Serializer {
+
+        /**
+         * @return SerializerFactory which created this Serializer instance
+         */
+        SerializerFactory getFactory();
+    }
+
+    /**
+     * Create an instance of the Serializer
+     */
+    Instance getInstance();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/TextSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/TextSerializer.java
new file mode 100644
index 0000000..b6314ff
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/TextSerializer.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.CascadingIOException;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Text serializer converts XML into plain text.
+ * It omits all XML tags and writes only character events to the output.
+ * Internally, text serializer uses XML serializer with {@link OutputKeys#METHOD}
+ * set to <code>text</code>.
+ *
+ * <p>Input document must have at least one element - root element - which
+ * should wrap all the text inside it.
+ *
+ * @version $Id$
+ */
+public class TextSerializer extends AbstractTextSerializer {
+
+    /**
+     * Set to true after first XML element
+     */
+    private boolean hasRootElement;
+
+    /**
+     * Set to true after first XML element
+     */
+    private boolean hadNoRootElement;
+
+    /**
+     * Set the configurations for this serializer.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        super.configure(conf);
+        this.format.put(OutputKeys.METHOD, "text");
+    }
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) throws IOException {
+        super.setOutputStream(out);
+        try {
+            TransformerHandler handler = this.getTransformerHandler();
+            handler.getTransformer().setOutputProperties(format);
+            handler.setResult(new StreamResult(this.output));
+            this.setContentHandler(handler);
+            this.setLexicalHandler(handler);
+       } catch (Exception e) {
+            final String message = "Cannot set TextSerializer outputstream";
+            throw new CascadingIOException(message, e);
+        }
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        this.hasRootElement = true;
+        super.startElement(uri, loc, raw, a);
+    }
+
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        if (!this.hasRootElement) {
+            this.hasRootElement = this.hadNoRootElement = true;
+            getLogger().warn("Encountered text before root element. Creating <text> wrapper element.");
+            super.startElement("", "text", "text", XMLUtils.EMPTY_ATTRIBUTES);
+        }
+        super.characters(c, start, len);
+    }
+
+    public void endDocument() throws SAXException {
+        if (this.hadNoRootElement) {
+            super.endElement("", "text", "text");
+        }
+        super.endDocument();
+    }
+
+    public void recycle() {
+        super.recycle();
+        this.hasRootElement = false;
+        this.hadNoRootElement = false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/VirtualPipelineSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/VirtualPipelineSerializer.java
new file mode 100644
index 0000000..6656385
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/VirtualPipelineSerializer.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.impl.AbstractVirtualSitemapComponent;
+
+import org.xml.sax.SAXException;
+
+import java.io.OutputStream;
+
+public class VirtualPipelineSerializer extends AbstractVirtualSitemapComponent
+    implements Serializer {
+
+    protected String getTypeName() {
+        return "serializer";
+    }
+
+    /**
+     * Set the <code>OutputStream</code>
+     */
+    public void setOutputStream(OutputStream out) {
+        this.getMappedSourceEnvironment().setOutputStream(out);
+    }
+
+    /**
+     * Get the mime-type of the output of this <code>Reader</code>
+     */
+    public String getMimeType() {
+        return this.getPipeline().getMimeType();
+    }
+
+    /**
+     * Test if the component wants to set the content length
+     */
+    public boolean shouldSetContentLength() {
+        return this.getPipeline().shouldSetContentLength();
+    }
+
+    /**
+     *  Process the SAX event. A new document is processed. The
+     *  internal pipeline is prepared.
+     *
+     *  @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        // Should use SourceResolver and context of the this
+        // components' sitemap, not caller sitemap
+        try {
+            EnvironmentHelper.enterEnvironment(this.getVPCEnvironment());
+            this.getPipeline().prepareInternal(this.getVPCEnvironment());
+        } catch (Exception e) {
+            throw new SAXException("VirtualPipelineSerializer: couldn't create internal pipeline ", e);
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+
+        try {
+            super.setConsumer(EnvironmentHelper
+                              .createPushEnvironmentConsumer(this.getPipeline().getXMLConsumer(this.getMappedSourceEnvironment()),
+                                                             this.getMappedSourceEnvironment()));
+        } catch (ProcessingException e) {
+            throw new SAXException("VirtualPipelineSerializer: couldn't get xml consumer from the pipeline ", e);
+        }
+
+        super.startDocument();
+    }
+ }
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/XMLSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/XMLSerializer.java
new file mode 100644
index 0000000..76d247a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/XMLSerializer.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.serialization;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.cocoon.CascadingIOException;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @version $Id$
+ */
+
+public class XMLSerializer extends AbstractTextSerializer {
+
+    /**
+     * Set the configurations for this serializer.
+     */
+    public void configure(Configuration conf)
+    throws ConfigurationException {
+        super.configure( conf );
+        this.format.put(OutputKeys.METHOD,"xml");
+    }
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     */
+    public void setOutputStream(OutputStream out) throws IOException {
+        super.setOutputStream(out);
+        try {
+            TransformerHandler handler = this.getTransformerHandler();
+            handler.getTransformer().setOutputProperties(this.format);
+            handler.setResult(new StreamResult(this.output));
+            this.setContentHandler(handler);
+            this.setLexicalHandler(handler);
+        } catch (Exception e) {
+            final String message = "Cannot set XMLSerializer outputstream"; 
+            throw new CascadingIOException(message, e);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/ZipArchiveSerializer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/ZipArchiveSerializer.java
new file mode 100644
index 0000000..661d429
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/serialization/ZipArchiveSerializer.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.serialization;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.NamespaceSupport;
+
+/**
+ * A serializer that builds Zip archives by aggregating several sources.
+ * <p>
+ * The input document should describe entries of the archive by means of
+ * their name (which can be a path) and their content either as URLs or
+ * inline data :
+ * <ul>
+ * <li>URLs, given by the "src" attribute, are Cocoon sources and as such
+ *     can use any of the protocols handled by Cocoon, including "cocoon:" to
+ *     include dynamically generated content in the archive.</li>
+ * <li>inline data is represented by an XML document that is serialized to the
+ *     zip entry using the serializer identified by the "serializer" attribute.</li>
+ * </ul>
+ * <p>
+ * Example :
+ * <pre>
+ *   &lt;zip:archive xmlns:zip="http://apache.org/cocoon/zip-archive/1.0"&gt;
+ *     &lt;zip:entry name="foo.html" src="cocoon://dynFoo.html"/&gt;
+ *     &lt;zip:entry name="images/bar.jpeg" src="bar.jpeg"/&gt;
+ *     &lt;zip:entry name="index.html" serializer="html"&gt;
+ *       &lt;html&gt;
+ *         &lt;head&gt;
+ *           &lt;title&gt;Index page&lt;/title&gt;
+ *         &lt;/head&gt;
+ *         &lt;body&gt;
+ *           Please go &lt;a href="foo.html"&gt;there&lt;/a&gt;
+ *         &lt;/body&lt;
+ *       &lt;/html&gt;
+ *     &lt;/zip:entry&gt;
+ *   &lt;/zip:archive:zip&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+
+// TODO (1) : handle more attributes on <archive> for properties of ZipOutputStream
+//            such as comment or default compression method and level
+
+// TODO (2) : handle more attributes on <entry> for properties of ZipEntry
+//            (compression method and level, time, comment, etc.)
+
+public class ZipArchiveSerializer extends AbstractSerializer
+                                  implements Disposable, Serviceable {
+
+    /**
+     * The namespace for elements handled by this serializer,
+     * "http://apache.org/cocoon/zip-archive/1.0".
+     */
+    public static final String ZIP_NAMESPACE = "http://apache.org/cocoon/zip-archive/1.0";
+
+    private static final int START_STATE = 0;
+    private static final int IN_ZIP_STATE = 1;
+    private static final int IN_CONTENT_STATE = 2;
+
+    /** The component manager */
+    protected ServiceManager manager;
+
+    /** The serializer component selector */
+    protected ServiceSelector selector;
+
+    /** The Zip stream where entries will be written */
+    protected ZipOutputStream zipOutput;
+
+    /** The current state */
+    protected int state = START_STATE;
+
+    /** The resolver to get sources */
+    protected SourceResolver resolver;
+
+    /** Temporary byte buffer to read source data */
+    protected byte[] buffer;
+
+    /** Serializer used when in IN_CONTENT state */
+    protected Serializer serializer;
+
+    /** Current depth of the serialized content */
+    protected int contentDepth;
+
+    /** Used to collect namespaces */
+    private NamespaceSupport nsSupport = new NamespaceSupport();
+
+    /**
+     * Store exception
+     */
+    private SAXException exception;
+
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    /**
+     * Returns default mime type for zip archives, <code>application/zip</code>.
+     * Can be overridden in the sitemap.
+     * @return application/zip
+     */
+    public String getMimeType() {
+        return "application/zip";
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        this.state = START_STATE;
+        this.zipOutput = new ZipOutputStream(this.output);
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     */
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        if (state == IN_CONTENT_STATE && this.contentDepth > 0) {
+            // Pass to the serializer
+            super.startPrefixMapping(prefix, uri);
+
+        } else {
+            // Register it if it's not our own namespace (useless to content)
+            if (!uri.equals(ZIP_NAMESPACE)) {
+                this.nsSupport.declarePrefix(prefix, uri);
+            }
+        }
+    }
+    
+    public void endPrefixMapping(String prefix) throws SAXException {
+        if (state == IN_CONTENT_STATE && this.contentDepth > 0) {
+            // Pass to the serializer
+            super.endPrefixMapping(prefix);
+        }
+    }
+
+    // Note : no need to implement endPrefixMapping() as we just need to pass it through if there
+    // is a serializer, which is what the superclass does.
+
+    /**
+     * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
+     */
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
+        throws SAXException {
+
+        // Damage control. Sometimes one exception is just not enough...
+        if (this.exception != null) {
+            throw this.exception;
+        }
+
+        switch (state) {
+            case START_STATE:
+                // expecting "zip" as the first element
+                if (namespaceURI.equals(ZIP_NAMESPACE) && localName.equals("archive")) {
+                    this.nsSupport.pushContext();
+                    this.state = IN_ZIP_STATE;
+                } else {
+                    throw this.exception =
+                        new SAXException("Expecting 'archive' root element (got '" + localName + "')");
+                }
+                break;
+
+            case IN_ZIP_STATE:
+                // expecting "entry" element
+                if (namespaceURI.equals(ZIP_NAMESPACE) && localName.equals("entry")) {
+                    this.nsSupport.pushContext();
+                    // Get the source
+                    addEntry(atts);
+                } else {
+                    throw this.exception =
+                        new SAXException("Expecting 'entry' element (got '" + localName + "')");
+                }
+                break;
+
+            case IN_CONTENT_STATE:
+                if (this.contentDepth == 0) {
+                    // Give it any namespaces already declared
+                    Enumeration prefixes = this.nsSupport.getPrefixes();
+                    while (prefixes.hasMoreElements()) {
+                        String prefix = (String) prefixes.nextElement();
+                        super.startPrefixMapping(prefix, this.nsSupport.getURI(prefix));
+                    }
+                }
+
+                this.contentDepth++;
+                super.startElement(namespaceURI, localName, qName, atts);
+                break;
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+     */
+    public void characters(char[] buffer, int offset, int length) throws SAXException {
+        // Propagate text to the serializer only if we have encountered the content's top-level
+        // element. Otherwhise, the serializer may be confused by some characters occuring between
+        // startDocument() and the first startElement() (e.g. Batik fails hard in that case)
+        if (this.state == IN_CONTENT_STATE && this.contentDepth > 0) {
+            super.characters(buffer, offset, length);
+        }
+    }
+
+    /**
+     * Add an entry in the archive.
+     * @param atts the attributes that describe the entry
+     */
+    protected void addEntry(Attributes atts) throws SAXException {
+        String name = atts.getValue("name");
+        if (name == null) {
+            throw this.exception =
+                new SAXException("No name given to the Zip entry");
+        }
+
+        String src = atts.getValue("src");
+        String serializerType = atts.getValue("serializer");
+
+        if (src == null && serializerType == null) {
+            throw this.exception =
+                new SAXException("No source nor serializer given for the Zip entry '" + name + "'");
+        }
+
+        if (src != null && serializerType != null) {
+            throw this.exception =
+                new SAXException("Cannot specify both 'src' and 'serializer' on a Zip entry '" + name + "'");
+        }
+
+        Source source = null;
+        try {
+            // Create a new Zip entry
+            ZipEntry entry = new ZipEntry(name);
+            this.zipOutput.putNextEntry(entry);
+
+            if (src != null) {
+                // Get the source and its data
+                source = resolver.resolveURI(src);
+                InputStream sourceInput = source.getInputStream();
+                
+                // Buffer lazily allocated
+                if (this.buffer == null)
+                    this.buffer = new byte[1024];
+
+                // Copy the source to the zip
+                int len;
+                while ((len = sourceInput.read(this.buffer)) > 0) {
+                    this.zipOutput.write(this.buffer, 0, len);
+                }
+
+                // and close the entry
+                this.zipOutput.closeEntry();
+
+            } else {
+                // Serialize content
+                if (this.selector == null) {
+                    this.selector =
+                        (ServiceSelector) this.manager.lookup(Serializer.ROLE + "Selector");
+                }
+
+                // Get the serializer
+                this.serializer = (Serializer) this.selector.select(serializerType);
+
+                // Direct its output to the zip file, filtering calls to close()
+                // (we don't want the archive to be closed by the serializer)
+                this.serializer.setOutputStream(new FilterOutputStream(this.zipOutput) {
+                    public void close() { /* nothing */ }
+                });
+
+                // Set it as the current XMLConsumer
+                setConsumer(serializer);
+
+                // start its document
+                this.serializer.startDocument();
+
+                this.state = IN_CONTENT_STATE;
+                this.contentDepth = 0;
+            }
+
+        } catch (RuntimeException re) {
+            throw re;
+        } catch (SAXException se) {
+            throw this.exception = se;
+        } catch (Exception e) {
+            throw this.exception = new SAXException(e);
+        } finally {
+            this.resolver.release( source );
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endElement(String, String, String)
+     */
+    public void endElement(String namespaceURI, String localName, String qName)
+        throws SAXException {
+
+        // Damage control. Sometimes one exception is just not enough...
+        if (this.exception != null) {
+            throw this.exception;
+        }
+
+        if (state == IN_CONTENT_STATE) {
+            super.endElement(namespaceURI, localName, qName);
+            this.contentDepth--;
+
+            if (this.contentDepth == 0) {
+                // End of this entry
+
+                // close all declared namespaces.
+                Enumeration prefixes = this.nsSupport.getPrefixes();
+                while (prefixes.hasMoreElements()) {
+                    String prefix = (String) prefixes.nextElement();
+                    super.endPrefixMapping(prefix);
+                }
+
+                super.endDocument();
+
+                try {
+                    this.zipOutput.closeEntry();
+                } catch (IOException ioe) {
+                    throw this.exception = new SAXException(ioe);
+                }
+
+                super.setConsumer(null);
+                this.selector.release(this.serializer);
+                this.serializer = null;
+
+                // Go back to listening for entries
+                this.state = IN_ZIP_STATE;
+            }
+        } else {
+            this.nsSupport.popContext();
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException {
+        try {
+            // Close the zip archive
+            this.zipOutput.finish();
+
+        } catch (IOException ioe) {
+            throw new SAXException(ioe);
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        this.exception = null;
+        if (this.serializer != null) {
+            this.selector.release(this.serializer);
+        }
+        if (this.selector != null) {
+            this.manager.release(this.selector);
+        }
+
+        this.nsSupport.reset();
+        super.recycle();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            this.manager.release(this.resolver);
+            this.resolver = null;
+            this.manager = null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/CocoonServlet.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/CocoonServlet.java
new file mode 100644
index 0000000..a251bb1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/CocoonServlet.java
@@ -0,0 +1,916 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.servlet;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.avalon.excalibur.logger.ServletLogger;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ConnectionResetException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.notification.DefaultNotifyingBuilder;
+import org.apache.cocoon.components.notification.Notifier;
+import org.apache.cocoon.components.notification.Notifying;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreUtil;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.http.HttpContext;
+import org.apache.cocoon.environment.http.HttpEnvironment;
+import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
+import org.apache.cocoon.servlet.multipart.RequestFactory;
+import org.apache.commons.lang.time.StopWatch;
+
+/**
+ * This is the entry point for Cocoon execution as an HTTP Servlet.
+ *
+ * @version $Id$
+ */
+public class CocoonServlet extends HttpServlet {
+
+    /**
+     * Application <code>Context</code> Key for the servlet configuration
+     * @since 2.1.3
+     */
+    public static final String CONTEXT_SERVLET_CONFIG = "servlet-config";
+
+    // Processing time message
+    protected static final String PROCESSED_BY = "Processed by "
+            + Constants.COMPLETE_NAME + " in ";
+
+    // Used by "show-time"
+    static final float SECOND = 1000;
+    static final float MINUTE = 60 * SECOND;
+    static final float HOUR   = 60 * MINUTE;
+
+    /**
+     * The <code>Processor</code> instance
+     */
+    protected Processor processor;
+
+    /**
+     * Holds exception happened during initialization (if any)
+     */
+    protected Exception exception;
+
+    private String containerEncoding;
+
+    protected ServletContext servletContext;
+
+    /**
+     * This is the path to the servlet context (or the result
+     * of calling getRealPath('/') on the ServletContext.
+     * Note, that this can be null.
+     */
+    protected String servletContextPath;
+
+    /**
+     * This is the url to the servlet context directory
+     */
+    protected String servletContextURL;
+
+    /**
+     * The RequestFactory is responsible for wrapping multipart-encoded
+     * forms and for handing the file payload of incoming requests
+     */
+    protected RequestFactory requestFactory;
+
+    /** CoreUtil */
+    protected CoreUtil coreUtil;
+
+    /** The logger */
+    protected Logger log;
+
+    protected Context environmentContext;
+
+    /**
+     * Initialize this <code>CocoonServlet</code> instance.  You will
+     * notice that I have broken the init into sub methods to make it
+     * easier to maintain (BL).  The context is passed to a couple of
+     * the subroutines.  This is also because it is better to explicitly
+     * pass variables than implicitely.  It is both more maintainable,
+     * and more elegant.
+     *
+     * @param conf The ServletConfig object from the servlet engine.
+     *
+     * @throws ServletException
+     */
+    public void init(ServletConfig conf)
+    throws ServletException {
+        this.servletContext = conf.getServletContext();
+        this.servletContext.log("Initializing Apache Cocoon " + Constants.VERSION);
+
+        super.init(conf);
+
+        this.servletContextPath = this.servletContext.getRealPath("/");
+        String path = this.servletContextPath;
+        // these two variables are just for debugging. We can't log at this point
+        // as the logger isn't initialized yet.
+        String debugPathOne = null, debugPathTwo = null;
+        if (path == null) {
+            // Try to figure out the path of the root from that of WEB-INF/web.xml
+            try {
+                path = this.servletContext.getResource("/WEB-INF/web.xml").toString();
+            } catch (MalformedURLException me) {
+                throw new ServletException("Unable to get resource 'WEB-INF/web.xml'.", me);
+            }
+            debugPathOne = path;
+            path = path.substring(0, path.length() - "WEB-INF/web.xml".length());
+            debugPathTwo = path;
+        }
+        try {
+            if (path.indexOf(':') > 1) {
+                this.servletContextURL = path;
+            } else {
+                this.servletContextURL = new File(path).toURL().toExternalForm();
+            }
+        } catch (MalformedURLException me) {
+            // VG: Novell has absolute file names starting with the
+            // volume name which is easily more then one letter.
+            // Examples: sys:/apache/cocoon or sys:\apache\cocoon
+            try {
+                this.servletContextURL = new File(path).toURL().toExternalForm();
+            } catch (MalformedURLException ignored) {
+                throw new ServletException("Unable to determine servlet context URL.", me);
+            }
+        }
+
+        try {
+            // FIXME (VG): We shouldn't have to specify these. Need to override
+            // jaxp implementation of weblogic before initializing logger.
+            // This piece of code is also required in the Cocoon class.
+            String value = System.getProperty("javax.xml.parsers.SAXParserFactory");
+            if (value != null && value.startsWith("weblogic")) {
+                System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
+                System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
+            }
+        } catch (Exception e) {
+            // Ignore security exception
+            this.servletContext.log("CocoonServlet: Could not check system properties, got: " + e);
+        }
+
+        // initialize settings
+        ServletBootstrapEnvironment env = new ServletBootstrapEnvironment(conf, this.servletContextPath, this.servletContextURL);
+
+        try {
+            this.coreUtil = new CoreUtil(env);
+            this.environmentContext = env.getEnvironmentContext();
+            this.log = env.logger;
+        } catch (Exception e) {
+            if ( e instanceof ServletException ) {
+                throw (ServletException)e;
+            }
+            throw new ServletException(e);
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug(this.coreUtil.getSettings().toString());
+            getLogger().debug("getRealPath for /: " + this.servletContextPath);
+            if (this.servletContextPath == null) {
+                getLogger().debug("getResource for /WEB-INF: " + debugPathOne);
+                getLogger().debug("Path for Root: " + debugPathTwo);
+            }
+        }
+
+        this.containerEncoding = this.getInitParameter("container-encoding", "ISO-8859-1");
+        this.requestFactory = new RequestFactory(coreUtil.getSettings().isAutosaveUploads(),
+                                                 new File(coreUtil.getCore().getSettings().getUploadDirectory()),
+                                                 coreUtil.getSettings().isAllowOverwrite(),
+                                                 coreUtil.getSettings().isSilentlyRename(),
+                                                 coreUtil.getSettings().getMaxUploadSize(),
+                                                 this.containerEncoding);
+
+        try {
+            this.exception = null;
+            this.processor = this.coreUtil.createProcessor();          
+        } catch (Exception e) {
+            this.exception = e;
+        }
+        if (this.exception == null) {
+            this.servletContext.log("Apache Cocoon " + Constants.VERSION + " is up and ready.");
+        } else {
+            final String message = "Errors during initializing Apache Cocoon " + Constants.VERSION + " : " + this.exception.getMessage();
+            this.servletContext.log(message, this.exception);
+        }
+    }
+
+    /**
+     * Dispose Cocoon when servlet is destroyed
+     */
+    public void destroy() {
+        this.servletContext.log("Destroying Cocoon Servlet.");
+        if (this.coreUtil != null) {
+            this.coreUtil.destroy();
+            this.coreUtil = null;
+            // coreUtil will dispose it.
+            this.processor = null;
+        }
+
+        this.requestFactory = null;
+        this.servletContext = null;
+        this.environmentContext = null;
+        this.log = null;
+        super.destroy();
+    }
+
+    /**
+     * Process the specified <code>HttpServletRequest</code> producing output
+     * on the specified <code>HttpServletResponse</code>.
+     */
+    public void service(HttpServletRequest req, HttpServletResponse res)
+    throws ServletException, IOException {
+        
+        // used for timing the processing
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start();
+
+        // add the cocoon header timestamp
+        if (this.coreUtil.getSettings().isShowVersion()) {
+            res.addHeader("X-Cocoon-Version", Constants.VERSION);
+        }
+
+        // get the request (wrapped if contains multipart-form data)
+        HttpServletRequest request;
+        try{
+            if (this.coreUtil.getSettings().isEnableUploads()) {
+                request = requestFactory.getServletRequest(req);
+            } else {
+                request = req;
+            }
+        } catch (Exception e) {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error("Problem with Cocoon servlet", e);
+            }
+
+            manageException(req, res, null, null,
+                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                            "Problem in creating the Request", null, null, e);
+            return;
+        }
+
+        // Get the cocoon engine instance
+        try {
+            this.exception = null;
+            this.processor = this.coreUtil.getProcessor(request.getPathInfo(), request.getParameter(Constants.RELOAD_PARAM));
+        } catch (Exception e) {
+            this.exception = e;
+        }
+
+        // Check if cocoon was initialized
+        if (this.processor == null) {
+            manageException(request, res, null, null,
+                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                            "Initialization Problem",
+                            null /* "Cocoon was not initialized" */,
+                            null /* "Cocoon was not initialized, cannot process request" */,
+                            this.exception);
+            return;
+        }
+
+        // We got it... Process the request
+        String uri = request.getServletPath();
+        if (uri == null) {
+            uri = "";
+        }
+        String pathInfo = request.getPathInfo();
+        if (pathInfo != null) {
+            // VG: WebLogic fix: Both uri and pathInfo starts with '/'
+            // This problem exists only in WL6.1sp2, not in WL6.0sp2 or WL7.0b.
+            if (uri.length() > 0 && uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            uri += pathInfo;
+        }
+
+        if (uri.length() == 0) {
+            /* empty relative URI
+                 -> HTTP-redirect from /cocoon to /cocoon/ to avoid
+                    StringIndexOutOfBoundsException when calling
+                    "".charAt(0)
+               else process URI normally
+            */
+            String prefix = request.getRequestURI();
+            if (prefix == null) {
+                prefix = "";
+            }
+
+            res.sendRedirect(res.encodeRedirectURL(prefix + "/"));
+            return;
+        }
+
+        String contentType = null;
+        Object handle = null;
+
+        Environment env;
+        try{
+            if (uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            // Pass uri into environment without URLDecoding, as it is already decoded.
+            env = getEnvironment(uri, request, res);
+        } catch (Exception e) {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error("Problem with Cocoon servlet", e);
+            }
+
+            manageException(request, res, null, uri,
+                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                            "Problem in creating the Environment", null, null, e);
+            return;
+        }
+
+        try {
+            try {
+                handle = this.coreUtil.initializeRequest(env);
+
+                if (this.processor.process(env)) {
+                    contentType = env.getContentType();
+                } else {
+                    // We reach this when there is nothing in the processing change that matches
+                    // the request. For example, no matcher matches.
+                    getLogger().fatalError("The Cocoon engine failed to process the request.");
+                    manageException(request, res, env, uri,
+                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                    "Request Processing Failed",
+                                    "Cocoon engine failed in process the request",
+                                    "The processing engine failed to process the request. This could be due to lack of matching or bugs in the pipeline engine.",
+                                    null);
+                    return;
+                }
+            } catch (ResourceNotFoundException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().warn(e.getMessage(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.getMessage());
+                }
+
+                manageException(request, res, env, uri,
+                                HttpServletResponse.SC_NOT_FOUND,
+                                "Resource Not Found",
+                                "Resource Not Found",
+                                "The requested resource \"" + request.getRequestURI() + "\" could not be found",
+                                e);
+                return;
+
+            } catch (ConnectionResetException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug(e.toString(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.toString());
+                }
+
+            } catch (IOException e) {
+                // Tomcat5 wraps SocketException into ClientAbortException which extends IOException.
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug(e.toString(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.toString());
+                }
+
+            } catch (Exception e) {
+                if (getLogger().isErrorEnabled()) {
+                    getLogger().error("Internal Cocoon Problem", e);
+                }
+
+                manageException(request, res, env, uri,
+                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                "Internal Server Error", null, null, e);
+                return;
+            }
+
+            stopWatch.stop();
+            String timeString = null;
+            if (getLogger().isInfoEnabled()) {
+                timeString = processTime(stopWatch.getTime());
+                getLogger().info("'" + uri + "' " + timeString);
+            }
+
+            if (contentType != null && contentType.equals("text/html")) {
+                String showTime = request.getParameter(Constants.SHOWTIME_PARAM);
+                boolean show = this.coreUtil.getSettings().isShowTime();
+                if (showTime != null) {
+                    show = !showTime.equalsIgnoreCase("no");
+                }
+                if (show) {
+                    if ( timeString == null ) {
+                        timeString = processTime(stopWatch.getTime());
+                    }
+                    boolean hide = this.coreUtil.getSettings().isHideShowTime();
+                    if (showTime != null) {
+                        hide = showTime.equalsIgnoreCase("hide");
+                    }
+                    ServletOutputStream out = res.getOutputStream();
+                    out.print((hide) ? "<!-- " : "<p>");
+                    out.print(timeString);
+                    out.println((hide) ? " -->" : "</p>");
+                }
+            }
+        } finally {
+            this.coreUtil.cleanUpRequest(handle);
+
+            try {
+                if (request instanceof MultipartHttpServletRequest) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Deleting uploaded file(s).");
+                    }
+                    ((MultipartHttpServletRequest) request).cleanup();
+                }
+            } catch (IOException e) {
+                getLogger().error("Cocoon got an Exception while trying to cleanup the uploaded files.", e);
+            }
+
+            /*
+             * Servlet Specification 2.2, 6.5 Closure of Response Object:
+             *
+             *   A number of events can indicate that the servlet has provided all of the
+             *   content to satisfy the request and that the response object can be
+             *   considered to be closed. The events are:
+             *     o The termination of the service method of the servlet.
+             *     o When the amount of content specified in the setContentLength method
+             *       of the response has been written to the response.
+             *     o The sendError method is called.
+             *     o The sendRedirect method is called.
+             *   When a response is closed, all content in the response buffer, if any remains,
+             *   must be immediately flushed to the client.
+             *
+             * Due to the above, out.flush() and out.close() are not necessary, and sometimes
+             * (if sendError or sendRedirect were used) request may be already closed.
+             */
+        }
+    }
+
+    protected void manageException(HttpServletRequest req, HttpServletResponse res, Environment env,
+                                   String uri, int errorStatus,
+                                   String title, String message, String description,
+                                   Exception e)
+    throws IOException {
+        if (this.coreUtil.getSettings().isManageExceptions()) {
+            if (env != null) {
+                env.tryResetResponse();
+            } else {
+                res.reset();
+            }
+
+            String type = Notifying.FATAL_NOTIFICATION;
+            HashMap extraDescriptions = null;
+
+            if (errorStatus == HttpServletResponse.SC_NOT_FOUND) {
+                type = "resource-not-found";
+                // Do not show the exception stacktrace for such common errors.
+                e = null;
+            } else {
+                extraDescriptions = new HashMap(2);
+                extraDescriptions.put(Notifying.EXTRA_REQUESTURI, req.getRequestURI());
+                if (uri != null) {
+                     extraDescriptions.put("Request URI", uri);
+                }
+
+                // Do not show exception stack trace when log level is WARN or above. Show only message.
+                if (!getLogger().isInfoEnabled()) {
+                    Throwable t = DefaultNotifyingBuilder.getRootCause(e);
+                    if (t != null) extraDescriptions.put(Notifying.EXTRA_CAUSE, t.getMessage());
+                    e = null;
+                }
+            }
+
+            Notifying n = new DefaultNotifyingBuilder().build(this,
+                                                              e,
+                                                              type,
+                                                              title,
+                                                              "Cocoon Servlet",
+                                                              message,
+                                                              description,
+                                                              extraDescriptions);
+
+            res.setContentType("text/html");
+            res.setStatus(errorStatus);
+            Notifier.notify(n, res.getOutputStream(), "text/html");
+        } else {
+            res.sendError(errorStatus, title);
+            res.flushBuffer();
+        }
+    }
+
+    /**
+     * Create the environment for the request
+     */
+    protected Environment getEnvironment(String uri,
+                                         HttpServletRequest req,
+                                         HttpServletResponse res)
+    throws Exception {
+        HttpEnvironment env;
+
+        String formEncoding = req.getParameter("cocoon-form-encoding");
+        if (formEncoding == null) {
+            formEncoding = this.coreUtil.getSettings().getFormEncoding();
+        }
+        env = new HttpEnvironment(uri,
+                                  this.servletContextURL,
+                                  req,
+                                  res,
+                                  this.servletContext,
+                                  this.environmentContext,
+                                  this.containerEncoding,
+                                  formEncoding);
+        env.enableLogging(getLogger());
+        return env;
+    }
+
+    private String processTime(long time) {
+        StringBuffer out = new StringBuffer(PROCESSED_BY);
+        if (time <= SECOND) {
+            out.append(time);
+            out.append(" milliseconds.");
+        } else if (time <= MINUTE) {
+            out.append(time / SECOND);
+            out.append(" seconds.");
+        } else if (time <= HOUR) {
+            out.append(time / MINUTE);
+            out.append(" minutes.");
+        } else {
+            out.append(time / HOUR);
+            out.append(" hours.");
+        }
+        return out.toString();
+    }
+
+    /**
+     * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
+     * is empty.
+     */
+    public String getInitParameter(String name) {
+        String result = super.getInitParameter(name);
+        if (result != null) {
+            result = result.trim();
+            if (result.length() == 0) {
+                result = null;
+            }
+        }
+
+        return result;
+    }
+
+    /** Convenience method to access servlet parameters */
+    protected String getInitParameter(String name, String defaultValue) {
+        String result = getInitParameter(name);
+        if (result == null) {
+            if (getLogger() != null && getLogger().isDebugEnabled()) {
+                getLogger().debug(name + " was not set - defaulting to '" + defaultValue + "'");
+            }
+            return defaultValue;
+        }
+        return result;
+    }
+
+    protected Logger getLogger() {
+        return this.log;
+    }
+
+    protected static final class ServletBootstrapEnvironment
+        implements BootstrapEnvironment {
+
+        private final ServletConfig config;
+        private final File writeableContextPath;
+        private final String contextPath;
+        public Logger logger;
+        private final HttpContext environmentContext;
+
+        public ServletBootstrapEnvironment(ServletConfig config, 
+                                           String writeablePath,
+                                           String path) {
+            this.config = config;
+            if ( writeablePath == null ) {
+                this.writeableContextPath = null;
+            } else {
+                this.writeableContextPath = new File(writeablePath);
+            }
+            this.contextPath = path;
+            this.environmentContext = new HttpContext(this.config.getServletContext());
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getBootstrapLogger(org.apache.cocoon.core.BootstrapEnvironment.LogLevel)
+         */
+        public Logger getBootstrapLogger(BootstrapEnvironment.LogLevel logLevel) {
+            return new ServletLogger(this.config, logLevel.getLevel());
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String)
+         */
+        public void log(String message) {
+            this.config.getServletContext().log(message);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#log(java.lang.String, java.lang.Throwable)
+         */
+        public void log(String message, Throwable error) {
+            this.config.getServletContext().log(message, error);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#setLogger(org.apache.avalon.framework.logger.Logger)
+         */
+        public void setLogger(Logger rootLogger) {
+            this.logger = rootLogger;
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.cocoon.core.MutableSettings)
+         */
+        public void configure(MutableSettings settings) {
+            // fill from the servlet parameters
+            SettingsHelper.fill(settings, this.config);
+            if ( settings.getWorkDirectory() == null ) {
+                final File workDir = (File)this.config.getServletContext().getAttribute("javax.servlet.context.tempdir");
+                settings.setWorkDirectory(workDir.getAbsolutePath());
+            }
+            if ( settings.getLoggingConfiguration() == null ) {
+                settings.setLoggingConfiguration("/WEB-INF/logkit.xconf");
+            }
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getEnvironmentContext()
+         */
+        public Context getEnvironmentContext() {
+            return this.environmentContext;
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getContextURL()
+         */
+        public String getContextURL() {
+            return this.contextPath;
+        }
+
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getContextForWriting()
+         */
+        public File getContextForWriting() {
+            return this.writeableContextPath;
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configureLoggingContext(org.apache.avalon.framework.context.DefaultContext)
+         */
+        public void configureLoggingContext(DefaultContext context) {
+            context.put("servlet-context", this.config.getServletContext());
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.avalon.framework.context.DefaultContext)
+         */
+        public void configure(DefaultContext context) {
+            context.put(CONTEXT_SERVLET_CONFIG, this.config);
+        }
+
+        /**
+         * @see org.apache.cocoon.core.BootstrapEnvironment#getConfigFile(java.lang.String)
+         */
+        public URL getConfigFile(final String configFileName)
+        throws Exception {
+            final String usedFileName;
+
+            if (configFileName == null) {
+                if (this.logger.isWarnEnabled()) {
+                    this.logger.warn("Servlet initialization argument 'configurations' not specified, attempting to use '/WEB-INF/cocoon.xconf'");
+                }
+                usedFileName = "/WEB-INF/cocoon.xconf";
+            } else {
+                usedFileName = configFileName;
+            }
+
+            if (this.logger.isDebugEnabled()) {
+                this.logger.debug("Using configuration file: " + usedFileName);
+            }
+
+            URL result;
+            try {
+                // test if this is a qualified url
+                if (usedFileName.indexOf(':') == -1) {
+                    result = this.config.getServletContext().getResource(usedFileName);
+                } else {
+                    result = new URL(usedFileName);
+                }
+            } catch (Exception mue) {
+                String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+                this.logger.error(msg, mue);
+                throw new ServletException(msg, mue);
+            }
+
+            if (result == null) {
+                File resultFile = new File(usedFileName);
+                if (resultFile.isFile()) {
+                    try {
+                        result = resultFile.getCanonicalFile().toURL();
+                    } catch (Exception e) {
+                        String msg = "Init parameter 'configurations' is invalid : " + usedFileName;
+                        this.logger.error(msg, e);
+                        throw new ServletException(msg, e);
+                    }
+                }
+            }
+
+            if (result == null) {
+                String msg = "Init parameter 'configuration' doesn't name an existing resource : " + usedFileName;
+                this.logger.error(msg);
+                throw new ServletException(msg);
+            }
+            return result;
+        }
+
+// (RP) comment this stuff out as it isn't used any more except in the StatusGenerator and I also think it returns wrong information
+//      under some circumstances.
+//        /**
+//         * This builds the important ClassPath used by this Servlet.  It
+//         * does so in a Servlet Engine neutral way.  It uses the
+//         * <code>ServletContext</code>'s <code>getRealPath</code> method
+//         * to get the Servlet 2.2 identified classes and lib directories.
+//         * It iterates in alphabetical order through every file in the
+//         * lib directory and adds it to the classpath.
+//         *
+//         * Also, we add the files to the ClassLoader for the Cocoon system.
+//         * In order to protect ourselves from skitzofrantic classloaders,
+//         * we need to work with a known one.
+//         *
+//         * We need to get this to work properly when Cocoon is in a war.
+//         *
+//         */
+//        public String getClassPath(Settings settings) {
+//            StringBuffer buildClassPath = new StringBuffer();
+//
+//            File root = null;
+//            if (this.getContextForWriting() != null) {
+//                // Old method.  There *MUST* be a better method than this...
+//
+//                String classDir = this.config.getServletContext().getRealPath("/WEB-INF/classes");
+//                String libDir = this.config.getServletContext().getRealPath("/WEB-INF/lib");
+//
+//                if (libDir != null) {
+//                    root = new File(libDir);
+//                }
+//
+//                if (classDir != null) {
+//                    buildClassPath.append(classDir);
+//                }
+//            } else {
+//                // New(ish) method for war'd deployments
+//                URL classDirURL = null;
+//                URL libDirURL = null;
+//
+//                try {
+//                    classDirURL = this.config.getServletContext().getResource("/WEB-INF/classes");
+//                } catch (MalformedURLException me) {
+//                    this.logger.warn("Unable to add WEB-INF/classes to the classpath", me);
+//                }
+//
+//                try {
+//                    libDirURL = this.config.getServletContext().getResource("/WEB-INF/lib");
+//                } catch (MalformedURLException me) {
+//                    this.logger.warn("Unable to add WEB-INF/lib to the classpath", me);
+//                }
+//
+//                if (libDirURL != null && libDirURL.toExternalForm().startsWith("file:")) {
+//                    root = new File(libDirURL.toExternalForm().substring("file:".length()));
+//                }
+//
+//                if (classDirURL != null) {
+//                    buildClassPath.append(classDirURL.toExternalForm());
+//                }
+//            }
+//
+//            // Unable to find lib directory. Going the hard way.
+//            if (root == null) {
+//                root = this.extractLibraries(settings);
+//            }
+//
+//            if (root != null && root.isDirectory()) {
+//                File[] libraries = root.listFiles();
+//                Arrays.sort(libraries);
+//                for (int i = 0; i < libraries.length; i++) {
+//                    String fullName = IOUtils.getFullFilename(libraries[i]);
+//                    buildClassPath.append(File.pathSeparatorChar).append(fullName);
+//                }
+//            }
+//
+//            buildClassPath.append(File.pathSeparatorChar)
+//                          .append(SystemUtils.JAVA_CLASS_PATH);
+//
+//            return buildClassPath.toString();
+//        }
+// 
+//        private File extractLibraries(Settings settings) {
+//            try {
+//                URL manifestURL = this.config.getServletContext().getResource("/META-INF/MANIFEST.MF");
+//                if (manifestURL == null) {
+//                    this.logger.fatalError("Unable to get Manifest");
+//                    return null;
+//                }
+//
+//                Manifest mf = new Manifest(manifestURL.openStream());
+//                Attributes attr = mf.getMainAttributes();
+//                String libValue = attr.getValue("Cocoon-Libs");
+//                if (libValue == null) {
+//                    this.logger.fatalError("Unable to get 'Cocoon-Libs' attribute from the Manifest");
+//                    return null;
+//                }
+//
+//                List libList = new ArrayList();
+//                for (StringTokenizer st = new StringTokenizer(libValue, " "); st.hasMoreTokens();) {
+//                    libList.add(st.nextToken());
+//                }
+//
+//                File root = new File(settings.getWorkDirectory(), "lib");
+//                root.mkdirs();
+//
+//                File[] oldLibs = root.listFiles();
+//                for (int i = 0; i < oldLibs.length; i++) {
+//                    String oldLib = oldLibs[i].getName();
+//                    if (!libList.contains(oldLib)) {
+//                        this.logger.debug("Removing old library " + oldLibs[i]);
+//                        oldLibs[i].delete();
+//                    }
+//                }
+//
+//                this.logger.warn("Extracting libraries into " + root);
+//                byte[] buffer = new byte[65536];
+//                for (Iterator i = libList.iterator(); i.hasNext();) {
+//                    String libName = (String) i.next();
+//
+//                    long lastModified = -1;
+//                    try {
+//                        lastModified = Long.parseLong(attr.getValue("Cocoon-Lib-" + libName.replace('.', '_')));
+//                    } catch (Exception e) {
+//                        this.logger.debug("Failed to parse lastModified: " + attr.getValue("Cocoon-Lib-" + libName.replace('.', '_')));
+//                    }
+//
+//                    File lib = new File(root, libName);
+//                    if (lib.exists() && lib.lastModified() != lastModified) {
+//                        this.logger.debug("Removing modified library " + lib);
+//                        lib.delete();
+//                    }
+//                    InputStream is = null;
+//                    OutputStream os = null;
+//                    try {
+//                        is = this.servletContext.getResourceAsStream("/WEB-INF/lib/" + libName);
+//                        if (is != null) {
+//                            this.getLogger().debug("Extracting " + libName);
+//                            os = new FileOutputStream(lib);
+//                            int count;
+//                            while ((count = is.read(buffer)) > 0) {
+//                                os.write(buffer, 0, count);
+//                            }
+//                        } else {
+//                            this.getLogger().warn("Skipping " + libName);
+//                        }
+//                    } finally {
+//                        if (os != null) os.close();
+//                        if (is != null) is.close();
+//                    }
+//
+//                    if (lastModified != -1) {
+//                        lib.setLastModified(lastModified);
+//                    }
+//                }
+//
+//                return root;
+//            } catch (IOException e) {
+//                this.logger.fatalError("Exception while processing Manifest file", e);
+//                return null;
+//            }
+//        }
+//
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/SettingsHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/SettingsHelper.java
new file mode 100644
index 0000000..9191203
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/SettingsHelper.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ * 
+ * Licensed 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.cocoon.servlet;
+
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletConfig;
+
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.util.StringUtils;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * This helper class initializes the {@link MutableSettings} object from the servlet
+ * configuration.
+ * 
+ * @version SVN $Id$
+ */
+public class SettingsHelper {
+
+    private SettingsHelper() {
+        //  no instantiation
+    }
+    
+    public static void fill(MutableSettings s, ServletConfig config) {
+        String value;
+
+        handleForceProperty(getInitParameter(config, "force-property"), s);
+
+        value = getInitParameter(config, "configurations");
+        if ( value != null ) {
+            s.setConfiguration(value);
+        } else if ( s.getConfiguration() == null ) {
+            s.setConfiguration("/WEB-INF/cocoon.xconf");
+        }
+
+        // upto 2.1.x the logging configuration was named "logkit-config"
+        // we still support this, but provide a new unbiased name as well
+        value = getInitParameter(config, "logkit-config");
+        if ( value != null ) {
+            s.setLoggingConfiguration("context:/" + value);
+        } else {
+            value = getInitParameter(config, "logging-config");
+            if ( value != null ) {
+                s.setLoggingConfiguration("context:/" + value);                
+            }
+        }
+
+        value = getInitParameter(config, "servlet-logger");
+        if ( value != null ) {
+            s.setEnvironmentLogger(value);
+        }
+
+        value = getInitParameter(config, "cocoon-logger");
+        if ( value != null ) {
+            s.setCocoonLogger(value);
+        }
+
+        value = getInitParameter(config, "log-level");
+        if ( value != null ) {
+            s.setBootstrapLogLevel(value);
+        }
+
+        value = getInitParameter(config, "logger-class");
+        if ( value != null ) {
+            s.setLoggerManagerClassName(value);
+        }
+
+        s.setReloadingEnabled(getInitParameterAsBoolean(config, "allow-reload", s.isReloadingEnabled(null)));
+
+        handleLoadClass(getInitParameter(config, "load-class"), s);
+
+        s.setEnableUploads(getInitParameterAsBoolean(config, "enable-uploads", s.isEnableUploads()));
+
+        value = getInitParameter(config, "upload-directory");
+        if ( value != null ) {
+            s.setUploadDirectory(value);
+        }
+
+        s.setAutosaveUploads(getInitParameterAsBoolean(config, "autosave-uploads", s.isAutosaveUploads()));
+
+        value = getInitParameter(config, "overwrite-uploads");
+        if ( value != null ) {
+            s.setOverwriteUploads(config.getInitParameter(value));
+        }
+
+        s.setMaxUploadSize(getInitParameterAsInteger(config, "upload-max-size", s.getMaxUploadSize()));
+        
+        value = getInitParameter(config, "cache-directory");
+        if ( value != null ) {
+            s.setCacheDirectory(value);
+        }
+
+        value = getInitParameter(config, "work-directory");
+        if ( value != null ) {
+            s.setWorkDirectory(value);
+        }
+
+        handleExtraClassPath(config.getInitParameter("extra-classpath"), s);
+
+        value = getInitParameter(config, "parent-service-manager");
+        if ( value != null ) {
+            s.setParentServiceManagerClassName(value);
+        }
+
+        value = getInitParameter(config, "show-time");
+        if ( value != null && value.equalsIgnoreCase("hide") ) {
+            s.setShowTime(true);
+            s.setHideShowTime(true);
+        } else {
+            s.setShowTime(getInitParameterAsBoolean(config, "show-time", false));
+            s.setHideShowTime(false);
+        }
+
+        s.setShowCocoonVersion(getInitParameterAsBoolean(config, "show-cocoon-version", s.isShowVersion()));
+
+        s.setManageExceptions(getInitParameterAsBoolean(config, "manage-exceptions", s.isManageExceptions()));
+
+        value = getInitParameter(config, "form-encoding");
+        if ( value != null ) {
+            s.setFormEncoding(value);
+        }
+    }
+    
+    /** Convenience method to access boolean servlet parameters */
+    protected static boolean getInitParameterAsBoolean(ServletConfig config, String name, boolean defaultValue) {
+        String value = getInitParameter(config, name);
+        if (value == null) {
+            return defaultValue;
+        }
+
+        return BooleanUtils.toBoolean(value);
+    }
+
+    protected static int getInitParameterAsInteger(ServletConfig config, String name, int defaultValue) {
+        String value = getInitParameter(config, name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return Integer.parseInt(value);
+    }
+    
+    private static void handleLoadClass(String param, MutableSettings s) {
+        if ( param == null ) {
+            return;
+        }
+        StringTokenizer tokenizer = new StringTokenizer(param, " \t\r\n\f;,", false);
+        while (tokenizer.hasMoreTokens()) {
+            final String value = tokenizer.nextToken().trim();
+            s.addToLoadClasses(value);
+        }
+    }
+
+    /**
+     * Handle the "force-property" parameter.
+     *
+     * If you need to force more than one property to load, then
+     * separate each entry with whitespace, a comma, or a semi-colon.
+     * Cocoon will strip any whitespace from the entry.
+     */
+    private static void handleForceProperty(String forceSystemProperty, MutableSettings s) {
+        if (forceSystemProperty != null) {
+            StringTokenizer tokenizer = new StringTokenizer(forceSystemProperty, " \t\r\n\f;,", false);
+
+            while (tokenizer.hasMoreTokens()) {
+                final String property = tokenizer.nextToken().trim();
+                if (property.indexOf('=') == -1) {
+                    continue;
+                }
+                try {
+                    String key = property.substring(0, property.indexOf('='));
+                    String value = property.substring(property.indexOf('=') + 1);
+                    if (value.indexOf("${") != -1) {
+                        value = StringUtils.replaceToken(value);
+                    }
+                    s.addToForceProperties(key, value);
+                } catch (Exception e) {
+                    // Do not throw an exception, because it is not a fatal error.
+                }
+            }
+        }
+    }
+
+    /**
+     * Retreives the "extra-classpath" attribute, that needs to be
+     * added to the class path.
+     */
+    private static void handleExtraClassPath(String extraClassPath, MutableSettings settings) {
+        if (extraClassPath != null) {
+            StringTokenizer st = new StringTokenizer(extraClassPath, SystemUtils.PATH_SEPARATOR, false);
+            while (st.hasMoreTokens()) {
+                String s = st.nextToken();
+                settings.addToExtraClasspaths(s);
+            }
+        }
+    }
+
+    /**
+     * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
+     * is empty.
+     */
+    private static String getInitParameter(ServletConfig config, String name) {
+        String result = config.getInitParameter(name);
+        if (result != null) {
+            result = result.trim();
+            if (result.length() == 0) {
+                result = null;
+            }
+        }
+
+        return result;
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartException.java
new file mode 100644
index 0000000..e74f4df
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+/**
+ * Exception thrown when on a parse error such as
+ * a malformed stream.
+ *
+ * @version $Id$
+ */
+public class MultipartException extends Exception {
+
+    /**
+     * Constructor MultipartException
+     */
+    public MultipartException() {
+        super();
+    }
+
+    /**
+     * Constructor MultipartException
+     *
+     * @param text
+     */
+    public MultipartException(String text) {
+        super(text);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartHttpServletRequest.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartHttpServletRequest.java
new file mode 100644
index 0000000..920ee29
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartHttpServletRequest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * Servlet request wrapper for multipart parser.
+ *
+ * @version $Id$
+ */
+public class MultipartHttpServletRequest extends HttpServletRequestWrapper {
+
+    /** The submitted parts */
+    private Hashtable values;
+
+    /**
+     * Create this wrapper around the given request and including the given
+     * parts.
+     */
+    public MultipartHttpServletRequest(HttpServletRequest request, Hashtable values) {
+        super(request);
+        this.values = values;
+    }
+
+    /**
+     * Cleanup eventually uploaded parts that were saved on disk
+     */
+    public void cleanup() throws IOException {
+        Enumeration e = getParameterNames();
+        while (e.hasMoreElements()) {
+            Object o = get( (String)e.nextElement() );
+            if (o instanceof Part) {
+                Part part = (Part)o;
+                if (part.disposeWithRequest()) {
+                    part.dispose();
+                }
+            }
+        }
+    }
+
+    /**
+     * Method get
+     *
+     * @param name
+     *
+     */
+    public Object get(String name) {
+        Object result = null;
+
+        if (values != null) {
+            result = values.get(name);
+
+            if (result instanceof Vector) {
+                if (((Vector) result).size() == 1) {
+                    return ((Vector) result).elementAt(0);
+                }
+                return result;
+            }
+        } else {
+            String[] array = this.getRequest().getParameterValues(name);
+            Vector vec = new Vector();
+
+            if (array != null) {
+                for (int i = 0; i < array.length; i++) {
+                    vec.addElement(array[i]);
+                }
+
+                if (vec.size() == 1) {
+                    result = vec.elementAt(0);
+                } else {
+                    result = vec;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Method getParameterNames
+     *
+     */
+    public Enumeration getParameterNames() {
+        if (values != null) {
+            return values.keys();
+        }
+        return this.getRequest().getParameterNames();
+    }
+
+    /**
+     * Method getParameter
+     *
+     * @param name
+     *
+     */
+    public String getParameter(String name) {
+        if (values != null) {
+            Object value = get(name);
+            String result = null;
+    
+            if (value != null) {
+                if (value instanceof Vector) {
+                    value = ((Vector) value).elementAt(0);
+                }
+    
+                result = value.toString();
+            }
+            return result;
+        } else {
+            return super.getParameter(name);
+        }
+    }
+
+    /**
+     * Method getParameterValues
+     *
+     * @param name
+     *
+     */
+    public String[] getParameterValues(String name) {
+        if (values != null) {
+            Object value = get(name);
+
+            if (value != null) {
+                if (value instanceof Vector) {
+                    String[] results = new String[((Vector)value).size()];
+                    for (int i=0;i<((Vector)value).size();i++) {
+                        results[i] = ((Vector)value).elementAt(i).toString();
+                    }
+                    return results;
+
+                }
+                return new String[]{value.toString()};
+            }
+
+            return null;
+        }
+        return this.getRequest().getParameterValues(name);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java
new file mode 100644
index 0000000..76dec82
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/MultipartParser.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.cocoon.util.NullOutputStream;
+
+/**
+ * This class is used to implement a multipart request wrapper.
+ * It will parse the http post stream and and fill it's hashtable with values.
+ *
+ * The hashtable will contain:
+ * Vector: inline part values
+ * FilePart: file part
+ *
+ * @version $Id$
+ */
+public class MultipartParser {
+
+    private final static int FILE_BUFFER_SIZE = 4096;
+
+    private static final int MAX_BOUNDARY_SIZE = 128;
+
+    private boolean saveUploadedFilesToDisk;
+
+    private File uploadDirectory = null;
+
+    private boolean allowOverwrite;
+
+    private boolean silentlyRename;
+    
+    private int maxUploadSize;
+
+    private String characterEncoding;
+    
+    private Hashtable parts;
+    
+    private boolean oversized = false;
+    
+    private int contentLength;
+    
+    /**
+     * Constructor, parses given request
+     *
+     * @param saveUploadedFilesToDisk Write fileparts to the uploadDirectory. If true the corresponding object
+     *              in the hashtable will contain a FilePartFile, if false a FilePartArray
+     * @param uploadDirectory The directory to write to if saveUploadedFilesToDisk is true.
+     * @param allowOverwrite Allow existing files to be overwritten.
+     * @param silentlyRename If file exists rename file (using filename+number).
+     * @param maxUploadSize The maximum content length accepted.
+     * @param characterEncoding The character encoding to be used.
+     */
+    public MultipartParser(boolean saveUploadedFilesToDisk,
+                           File uploadDirectory,
+                           boolean allowOverwrite,
+                           boolean silentlyRename,
+                           int maxUploadSize,
+                           String characterEncoding)
+    {
+        this.saveUploadedFilesToDisk = saveUploadedFilesToDisk;
+        this.uploadDirectory = uploadDirectory;
+        this.allowOverwrite = allowOverwrite;
+        this.silentlyRename = silentlyRename;
+        this.maxUploadSize = maxUploadSize;
+        this.characterEncoding = characterEncoding;
+    }
+
+    private void parseParts(int contentLength, String contentType, InputStream requestStream)
+    throws IOException, MultipartException {
+        this.contentLength = contentLength;
+        if (contentLength > this.maxUploadSize) {
+            this.oversized = true;
+        }
+
+        BufferedInputStream bufferedStream = new BufferedInputStream(requestStream);
+        PushbackInputStream pushbackStream = new PushbackInputStream(bufferedStream, MAX_BOUNDARY_SIZE);
+        TokenStream stream = new TokenStream(pushbackStream);
+
+        parseMultiPart(stream, getBoundary(contentType));
+
+    }
+    
+    public Hashtable getParts(int contentLength, String contentType, InputStream requestStream)
+    throws IOException, MultipartException {
+        this.parts = new Hashtable();
+        parseParts(contentLength, contentType, requestStream);
+        return this.parts;
+    }
+    
+    public Hashtable getParts(HttpServletRequest request) throws IOException, MultipartException {
+        this.parts = new Hashtable();
+        
+        // Copy all parameters coming from the request URI to the parts table.
+        // This happens when a form's action attribute has some parameters
+        Enumeration names = request.getParameterNames();
+        while(names.hasMoreElements()) {
+            String name = (String)names.nextElement();
+            String[] values = request.getParameterValues(name);
+            Vector v = new Vector(values.length);
+            for (int i = 0; i < values.length; i++) {
+                v.add(values[i]);
+            }
+            this.parts.put(name, v);
+        }
+        parseParts(request.getContentLength(), request.getContentType(), request.getInputStream());    
+        return this.parts;    
+    }
+    
+    /**
+     * Parse a multipart block
+     *
+     * @param ts
+     * @param boundary
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parseMultiPart(TokenStream ts, String boundary)
+            throws IOException, MultipartException {
+
+        ts.setBoundary(boundary.getBytes());
+        ts.read();    // read first boundary away
+        ts.setBoundary(("\r\n" + boundary).getBytes());
+
+        while (ts.getState() == TokenStream.STATE_NEXTPART) {
+            ts.nextPart();
+            parsePart(ts);
+        }
+
+        if (ts.getState() != TokenStream.STATE_ENDMULTIPART) {    // sanity check
+            throw new MultipartException("Malformed stream");
+        }
+    }
+
+    /**
+     * Parse a single part
+     *
+     * @param ts
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parsePart(TokenStream ts)
+            throws IOException, MultipartException {
+
+        Hashtable headers = new Hashtable();
+        headers = readHeaders(ts);
+        try {
+            if (headers.containsKey("filename")) {
+                if (!"".equals(headers.get("filename"))) {
+                    parseFilePart(ts, headers);
+                } else {
+                    // IE6 sends an empty part with filename="" for
+                    // empty upload fields. Just parse away the part
+                    byte[] buf = new byte[32];
+                    while(ts.getState() == TokenStream.STATE_READING)
+                        ts.read(buf);  
+                }
+            } else if (((String) headers.get("content-disposition"))
+                    .toLowerCase().equals("form-data")) {
+                parseInlinePart(ts, headers);
+            }
+
+            // FIXME: multipart/mixed parts are untested.
+            else if (((String) headers.get("content-disposition")).toLowerCase()
+                    .indexOf("multipart") > -1) {
+                parseMultiPart(new TokenStream(ts, MAX_BOUNDARY_SIZE),
+                        "--" + (String) headers.get("boundary"));
+                ts.read();    // read past boundary
+            } else {
+                throw new MultipartException("Unknown part type");
+            }
+        } catch (IOException e) {
+            throw new MultipartException("Malformed stream: " + e.getMessage());
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            throw new MultipartException("Malformed header");
+        }
+    }
+
+    /**
+     * Parse a file part
+     *
+     * @param in
+     * @param headers
+     *
+     * @throws IOException
+     * @throws MultipartException
+     */
+    private void parseFilePart(TokenStream in, Hashtable headers)
+            throws IOException, MultipartException {
+
+        byte[] buf = new byte[FILE_BUFFER_SIZE];
+        OutputStream out;
+        File file = null;
+
+        if (oversized) {
+            out = new NullOutputStream();
+        } else if (!saveUploadedFilesToDisk) {
+            out = new ByteArrayOutputStream();
+        } else {
+            String fileName = (String) headers.get("filename");
+            if(File.separatorChar == '\\')
+                fileName = fileName.replace('/','\\');
+            else
+                fileName = fileName.replace('\\','/');
+
+            String filePath = uploadDirectory.getPath() + File.separator;
+            fileName = new File(fileName).getName();
+            file = new File(filePath + fileName);
+
+            if (!allowOverwrite && !file.createNewFile()) {
+                if (silentlyRename) {
+                    int c = 0;
+                    do {
+                        file = new File(filePath + c++ + "_" + fileName);
+                    } while (!file.createNewFile());
+                } else {
+                    throw new MultipartException("Duplicate file '" + file.getName()
+                        + "' in '" + file.getParent() + "'");
+                }
+            }
+
+            out = new FileOutputStream(file);
+        }
+
+        int length = 0; // Track length for OversizedPart
+        try {
+            int read = 0;
+            while (in.getState() == TokenStream.STATE_READING) {
+                // read data
+                read = in.read(buf);
+                length += read;
+                out.write(buf, 0, read);
+            }
+        } catch (IOException ioe) {
+            // don't let incomplete file uploads pile up in the upload dir.
+            // this usually happens with aborted form submits containing very large files.
+            out.close();
+            out = null;
+            if ( file!=null ) file.delete();
+            throw ioe;
+        } finally {
+            if ( out!=null ) out.close();
+        }
+        
+        String name = (String)headers.get("name");
+        if (oversized) {
+            this.parts.put(name, new RejectedPart(headers, length, this.contentLength, this.maxUploadSize));
+        } else if (file == null) {
+            byte[] bytes = ((ByteArrayOutputStream) out).toByteArray();
+            this.parts.put(name, new PartInMemory(headers, new ByteArrayInputStream(bytes), bytes.length));
+        } else {
+            this.parts.put(name, new PartOnDisk(headers, file));
+        }
+    }
+
+    /**
+     * Parse an inline part
+     *
+     * @param in
+     * @param headers
+     *
+     * @throws IOException
+     */
+    private void parseInlinePart(TokenStream in, Hashtable headers)
+            throws IOException {
+
+        // Buffer incoming bytes for proper string decoding (there can be multibyte chars)
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        while (in.getState() == TokenStream.STATE_READING) {
+            int c = in.read();
+            if (c != -1) bos.write(c);
+        }
+        
+        String field = (String) headers.get("name");
+        Vector v = (Vector) this.parts.get(field);
+
+        if (v == null) {
+            v = new Vector();
+            this.parts.put(field, v);
+        }
+
+        v.add(new String(bos.toByteArray(), this.characterEncoding));
+    }
+
+    /**
+     * Read part headers
+     *
+     * @param in
+     *
+     * @throws IOException
+     */
+    private Hashtable readHeaders(TokenStream in) throws IOException {
+
+        Hashtable headers = new Hashtable();
+        String hdrline = readln(in);
+
+        while (!"".equals(hdrline)) {
+            StringTokenizer tokenizer = new StringTokenizer(hdrline);
+
+            headers.put(tokenizer.nextToken(" :").toLowerCase(),
+                    tokenizer.nextToken(" :;"));
+
+            // The extra tokenizer.hasMoreTokens() in headers.put
+            // handles the filename="" case IE6 submits for an empty
+            // upload field.
+            while (tokenizer.hasMoreTokens()) {
+                headers.put(tokenizer.nextToken(" ;=\""),
+                        tokenizer.hasMoreTokens()?tokenizer.nextToken("=\""):"");
+            }
+
+            hdrline = readln(in);
+        }
+
+        return headers;
+    }
+
+    /**
+     * Get boundary from contentheader
+     *
+     * @param hdr
+     *
+     */
+    private String getBoundary(String hdr) {
+
+        int start = hdr.toLowerCase().indexOf("boundary=");
+        if (start > -1) {
+            return "--" + hdr.substring(start + 9);
+        }
+        return null;
+    }
+
+    /**
+     * Read string until newline or end of stream
+     *
+     * @param in
+     *
+     * @throws IOException
+     */
+    private String readln(TokenStream in) throws IOException {
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        
+        int b = in.read();
+
+        while ((b != -1) && (b != '\r')) {
+            bos.write(b);
+            b = in.read();
+        }
+
+        if (b == '\r') {
+            in.read();    // read '\n'
+        }
+
+        return new String(bos.toByteArray(), this.characterEncoding);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/Part.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/Part.java
new file mode 100644
index 0000000..b6308c8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/Part.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.commons.io.IOUtils;
+import org.apache.excalibur.source.ModifiableSource;
+
+
+/**
+ * This abstract class represents a file part parsed from a http post stream. The concrete
+ * class, {@link PartOnDisk} or {@link PartInMemory} that is used depends on the upload configuration
+ * in <code>web.xml</code>.
+ * <p>
+ * If uploaded data size exceeds the maximum allowed upload size (also specified in <code>web.xml</code>),
+ * then an {@link RejectedPart} is used, from which no data can be obtained, but which gives some
+ * information on the rejected uploads.
+ *
+ * @version $Id$
+ */
+public abstract class Part implements Disposable {
+
+    private boolean disposeWithRequest = true;
+
+    /** Field headers */
+    protected Map headers;
+
+    protected Part(Map headers) {
+	    this.headers = headers;
+    }
+
+    /**
+     * Returns the part headers
+     */
+    public Map getHeaders() {
+        return headers;
+    }
+
+    /**
+     * Returns the filename
+     */
+    public abstract String getFileName();
+    
+    /**
+     * Returns the original filename
+     */
+    public String getUploadName(){
+        return (String) headers.get("filename");
+    }
+    
+    /**
+     * Returns the length of the file content
+     */
+    public abstract int getSize();
+    
+    /**
+     * Is this part a rejected part? Provided as an alternative to <code>instanceof RejectedPart</code>
+     * in places where it's not convenient such as flowscript.
+     * 
+     * @return <code>true</code> if this part was rejected
+     */
+    public boolean isRejected() {
+        return false;
+    }
+
+    /**
+     * Returns the mime type (or null if unknown)
+     */
+    public String getMimeType() {
+        return (String) headers.get("content-type");
+    }
+    
+    /**
+     * Do we want any temporary resource held by this part to be cleaned up when processing of
+     * the request that created it is finished? Default is <code>true</code>.
+     * 
+     * @return <code>true</code> if the part should be disposed with the request.
+     */
+    public boolean disposeWithRequest() {
+        return this.disposeWithRequest;
+    }
+    
+    /**
+     * Set the value of the <code>disposeWithRequest</code> flag (default is <code>true</code>).
+     * 
+     * @param dispose <code>true</code> if the part should be disposed after request processing
+     */
+    public void setDisposeWithRequest(boolean dispose) {
+        this.disposeWithRequest = dispose;
+    }
+    
+    /**
+     * Returns an InputStream containing the file data
+     * @throws IOException
+     */
+    public abstract InputStream getInputStream() throws IOException;
+
+    /**
+     * Convenience method to copy a part to a modifiable source.
+     * 
+     * @param source the modifiable source to write to
+     * @throws IOException
+     * @since 2.1.8
+     */
+    public void copyToSource(ModifiableSource source) throws IOException {
+        InputStream is = getInputStream();
+        OutputStream os = source.getOutputStream();
+        IOUtils.copy(is, os);
+        is.close();
+        os.close();
+    }
+    
+    /**
+     * Convenience method to copy a part to a file.
+     * 
+     * @param filename name of the file to write to
+     * @throws IOException
+     * @since 2.1.8
+     */
+    public void copyToFile(String filename) throws IOException {
+        InputStream is = getInputStream();
+        OutputStream os = new FileOutputStream(filename);
+        IOUtils.copy(is, os);
+        is.close();
+        os.close();
+    }
+    
+    /**
+     * Dispose any resources held by this part, such as a file or memory buffer.
+     * <p>
+     * Disposal occurs in all cases when the part is garbage collected, but calling it explicitely
+     * allows to cleanup resources more quickly.
+     */
+    public abstract void dispose();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java
new file mode 100644
index 0000000..c4a494d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartInMemory.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * This class represents a file part parsed from a http post stream.
+ *
+ * @version $Id$
+ */
+public class PartInMemory extends Part {
+
+    private InputStream in;
+
+    private int size;
+
+    /**
+     * Constructor PartInMemory
+     *
+     * @param headers
+     * @param in
+     * @param size
+     */
+    public PartInMemory(Map headers, InputStream in, int size) {
+        super(headers);
+        this.in = in;
+        this.size = size;
+    }
+
+    /**
+     * Returns the filename
+     */
+    public String getFileName() {
+        return (String) headers.get("filename");
+    }
+
+    /**
+     * Returns the filesize in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Returns a (ByteArray)InputStream containing the file data
+     *
+     * @throws IOException
+     */
+    public InputStream getInputStream() throws IOException {
+        if (this.in != null) {
+            return this.in;
+        } else {
+            throw new IllegalStateException("This part has already been disposed.");
+        }
+    }
+    
+    /**
+     * Clean the byte array content buffer holding part data
+     */
+    public void dispose() {
+        this.in = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java
new file mode 100644
index 0000000..27312aa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/PartOnDisk.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * This class represents a file part parsed from a http post stream.
+ *
+ * @version $Id$
+ */
+public class PartOnDisk extends Part {
+
+    /** Field file           */
+    private File file = null;
+    private int size;
+
+    /**
+     * Constructor PartOnDisk
+     *
+     * @param headers
+     * @param file
+     */
+    protected PartOnDisk(Map headers, File file) {
+        super(headers);
+        this.file = file;
+        
+        // Ensure the file will be deleted when we exit the JVM
+        this.file.deleteOnExit();
+        
+        this.size = (int) file.length();
+    }
+
+    /**
+     * Returns the file name
+     */
+    public String getFileName() {
+        return file.getName();
+    }
+
+    /**
+     * Returns the file size in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+
+    /**
+     * Returns the file
+     */
+    public File getFile() {
+        return file;
+    }
+
+    /**
+     * Returns a (ByteArray)InputStream containing the file data
+     *
+     * @throws IOException
+     */
+    public InputStream getInputStream() throws IOException {
+        if (this.file != null) {
+            return new FileInputStream(file);
+        }
+        throw new IllegalStateException("This part has already been disposed.");
+    }
+
+    /**
+     * Returns the filename
+     */
+    public String toString() {
+        return file.getPath();
+    }
+    
+    /**
+     * Delete the underlying file.
+     */
+    public void dispose() {
+        if (this.file != null) {
+            this.file.delete();
+            this.file = null;
+        }
+    }
+    
+    /**
+     * Ensures the underlying file has been deleted
+     */
+    public void finalize() throws Throwable {
+        // Ensure the file has been deleted
+        dispose();
+        
+        super.finalize();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java
new file mode 100644
index 0000000..40d327e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RejectedPart.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * An upload part that was rejected because request length exceeded the maximum upload size.
+ * 
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class RejectedPart extends Part {
+    
+    private int size;
+    public int contentLength;
+    public int maxContentLength;
+
+    public RejectedPart(Map headers, int partSize, int contentLength, int maxContentLength) {
+        super(headers);
+        this.size = partSize;
+        this.contentLength = contentLength;
+        this.maxContentLength = maxContentLength;
+    }
+
+    public String getFileName() {
+        return (String) headers.get("filename");
+    }
+
+    /**
+     * Get the size of this part.
+     * 
+     * @return the size in bytes
+     */
+    public int getSize() {
+        return this.size;
+    }
+    
+    /**
+     * Get the maximum allowed upload size. Not that this applies to the full request content length,
+     * including multipart boundaries and other form data values.
+     * <p>
+     * This means that an upload part can be rejected although it's individual size is (a bit) smaller
+     * than the maximum size. It is therefore advisable to use {@link #getContentLength()} to build
+     * error messages rather than {@link #getSize()}.
+     * 
+     * @return the maximum content length in bytes
+     */
+    public int getMaxContentLength() {
+        return this.maxContentLength;
+    }
+
+    /**
+     * Get the content length of the request that cause this part to be rejected.
+     * 
+     * @return the content length in bytes
+     */
+    public int getContentLength() {
+        return this.contentLength;
+    }
+    /**
+     * Always throw an <code>IOException</code> as this part was rejected.
+     */
+    public InputStream getInputStream() throws IOException {
+        throw new IOException("Multipart element '" + getFileName() + "' is too large (" +
+                this.size + " bytes) and was discarded.");
+    }
+
+    /**
+     * Always return <code>true</code>
+     */
+    public boolean isRejected() {
+        return true;
+    }
+
+    public void dispose() {
+        // nothing
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java
new file mode 100644
index 0000000..68b3870
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/RequestFactory.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * This is the interface of Request Wrapper in Cocoon.
+ *
+ * @version $Id$
+ */
+public class RequestFactory {
+
+    private boolean saveUploadedFilesToDisk;
+
+    private File uploadDirectory;
+
+    private boolean allowOverwrite;
+
+    private boolean silentlyRename;
+
+    private String defaultCharEncoding;
+    
+    private int maxUploadSize;
+    
+    public RequestFactory (boolean saveUploadedFilesToDisk, 
+                           File uploadDirectory, 
+                           boolean allowOverwrite, 
+                           boolean silentlyRename, 
+                           int maxUploadSize,
+                           String defaultCharEncoding) {
+       this.saveUploadedFilesToDisk = saveUploadedFilesToDisk;
+       this.uploadDirectory = uploadDirectory;
+       this.allowOverwrite = allowOverwrite;
+       this.silentlyRename = silentlyRename;
+       this.maxUploadSize = maxUploadSize;
+       this.defaultCharEncoding = defaultCharEncoding;
+       
+       if (saveUploadedFilesToDisk) {
+           // Empty the contents of the upload directory
+           File[] files = uploadDirectory.listFiles();
+           for (int i = 0; i < files.length; i++) {
+               files[i].delete();
+           }
+       }
+    }
+
+    /**
+     * If the request includes a "multipart/form-data", then wrap it with
+     * methods that allow easier connection to those objects since the servlet
+     * API doesn't provide those methods directly.
+     */
+    public HttpServletRequest getServletRequest(HttpServletRequest request) throws IOException, MultipartException {
+        HttpServletRequest req = request;
+        String contentType = request.getContentType();
+        
+        if ((contentType != null) && (contentType.toLowerCase().indexOf("multipart/form-data") > -1)) {
+ 
+            String charEncoding = request.getCharacterEncoding();
+            if (charEncoding == null || charEncoding.equals("")) {
+                charEncoding = this.defaultCharEncoding;
+            }
+            
+            MultipartParser parser = new MultipartParser(
+                    this.saveUploadedFilesToDisk, 
+                    this.uploadDirectory, 
+                    this.allowOverwrite, 
+                    this.silentlyRename, 
+                    this.maxUploadSize,
+                    charEncoding);
+                    
+            Hashtable parts = parser.getParts(request);
+            
+            req = new MultipartHttpServletRequest(request,parts);
+        }
+
+        return req;
+    }
+    
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/TokenStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/TokenStream.java
new file mode 100644
index 0000000..6f476d7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/servlet/multipart/TokenStream.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.servlet.multipart;
+
+import java.io.IOException;
+import java.io.PushbackInputStream;
+
+/**
+ * Utility class for MultipartParser. Divides the inputstream into parts
+ * separated by a given boundary.
+ *
+ * A newline is espected after each boundary and is parsed away.
+ * @version $Id$
+ */
+class TokenStream extends PushbackInputStream {
+
+    /**
+     * Initial state, no boundary has been set.
+     */
+    public static final int STATE_NOBOUNDARY = -1;
+
+    /**
+     * Fully read a part, now at the beginning of a new part
+     */
+    public static final int STATE_NEXTPART = -2;
+
+    /**
+     * Read last boundary, end of multipart block
+     */
+    public static final int STATE_ENDMULTIPART = -3;
+
+    /**
+     * End of stream, this should not happen
+     */
+    public static final int STATE_ENDOFSTREAM = -4;
+
+    /**
+     * Currently reading a part
+     */
+    public static final int STATE_READING = -5;
+
+    /** Field in           */
+    private PushbackInputStream in = null;
+
+    /** Field boundary           */
+    private byte[] boundary = null;
+
+    /** Field state           */
+    private int state = STATE_NOBOUNDARY;
+
+    /**
+     * Creates a new pushback token stream from in.
+     *
+     * @param in The input stream
+     */
+    public TokenStream(PushbackInputStream in) {
+        this(in,1);
+    }
+    
+    /**
+     * Creates a new pushback token stream from in.
+     *
+     * @param in The input stream
+     * @param size Size (in bytes) of the pushback buffer
+     */
+    public TokenStream(PushbackInputStream in, int size) {
+        super(in,size);
+        this.in = in;
+    }
+
+    /**
+     * Sets the boundary to scan for
+     *
+     * @param boundary A byte array containg the boundary
+     *
+     * @throws MultipartException
+     */
+    public void setBoundary(byte[] boundary) throws MultipartException {
+        this.boundary = boundary;
+        if (state == STATE_NOBOUNDARY) {
+            state = STATE_READING;
+        }
+    }
+
+    /**
+     * Start reading the next part in the stream. This method may only be called
+     * if state is STATE_NEXTPART. It will throw a MultipartException if not.
+     *
+     * @throws MultipartException
+     */
+    public void nextPart() throws MultipartException {
+        if (state != STATE_NEXTPART) {
+            throw new MultipartException("Illegal state");
+        }
+        state = STATE_READING;
+    }
+
+    /**
+     * Return the stream state
+     *
+     */
+    public int getState() {
+        return state;
+    }
+
+    /**
+     * Fill the ouput buffer until either it's full, the boundary has been reached or
+     * the end of the inputstream has been reached.
+     * When a boundary is reached it is entirely read away including trailing \r's and \n's.
+     * It will not be written to the output buffer.
+     * The stream state is updated after each call.
+     *
+     * @param out The output buffer
+     *
+     * @throws IOException
+     */
+    private int readToBoundary(byte[] out) throws IOException {
+        if (state != STATE_READING) {
+            return 0;
+        }
+        int boundaryIndex = 0;
+        int written = 0;
+        int b = in.read();
+
+        while (true) {
+            while ((byte) b != boundary[0]) {
+                if (b == -1) {
+                    state = STATE_ENDOFSTREAM;
+                    return written;
+                }
+                out[written++] = (byte) b;
+
+                if (written == out.length) {
+                    return written;
+                }
+                b = in.read();
+            }
+            boundaryIndex = 0;                         // we know the first byte matched
+            // check for boundary
+            while ((boundaryIndex < boundary.length)
+                    && ((byte) b == boundary[boundaryIndex])) {
+                b = in.read();
+                boundaryIndex++;
+            }
+
+            if (boundaryIndex == boundary.length) {    // matched boundary
+                if (b != -1) {
+                    if (b == '\r') {                   // newline, another part follows
+                        state = STATE_NEXTPART;
+                        in.read();
+                    } else if (b == '-') {             // hyphen, end of multipart
+                        state = STATE_ENDMULTIPART;
+                        in.read();                     // read next hyphen
+                        in.read();                     // read \r
+                        in.read();                     // read \n
+                    } else {                           // something else, error
+                        throw new IOException(
+                                "Unexpected character after boundary");
+                    }
+                } else {    // nothing after boundary, this shouldn't happen either
+                    state = STATE_ENDOFSTREAM;
+                }
+                return written;
+            }
+            // did not match boundary
+            // bytes skipped, write first skipped byte, push back the rest
+            if (b != -1) {                         // b may be -1
+                in.unread(b);                      // the non-matching byte
+            }
+            in.unread(boundary, 1,
+                    boundaryIndex - 1);          // unread skipped boundary data
+            out[written++] = boundary[0];
+            if (written == out.length) {
+                return written;
+            }
+            b = in.read();
+        }
+    }
+
+    /**
+     * @see java.io.InputStream#read(byte[])
+     *
+     * @param out
+     *
+     * @throws IOException
+     */
+    public int read(byte[] out) throws IOException {
+        if (state != STATE_READING) {
+            return 0;
+        }
+        return readToBoundary(out);
+    }
+
+    /**
+     * @see java.io.InputStream#read(byte[],int,int)
+     *
+     * @param out
+     * @param off
+     * @param len
+     *
+     * @throws IOException
+     */
+    public int read(byte[] out, int off, int len) throws IOException {
+        if ((off < 0) || (off >= out.length)) {
+            throw new IOException("Buffer offset outside buffer");
+        }
+        if (off + len >= out.length) {
+            throw new IOException("Buffer end outside buffer");
+        }
+        if (len < 0) {
+            throw new IOException("Length must be a positive integer");
+        }
+        byte[] buf = new byte[len];
+        int read = read(buf);
+        if (read > 0) {
+            System.arraycopy(buf, 0, out, off, read);
+        }
+        return read;
+    }
+
+    /**
+     * @see java.io.InputStream#read()
+     *
+     * @throws IOException
+     */
+    public int read() throws IOException {
+        byte[] buf = new byte[1];
+        int read = read(buf);
+
+        if (read == 0) {
+            return -1;
+        }
+        return buf[0];
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ComponentLocator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ComponentLocator.java
new file mode 100644
index 0000000..168c51e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ComponentLocator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.ProcessingException;
+
+
+/**
+ * TODO WORK IN PROGRESS!!
+ *
+ * This interface is the connection between the Cocoon core components
+ * and an optional application/sitemap container.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public interface ComponentLocator {
+
+    Object getComponent(String key) throws ProcessingException;
+
+    void release(Object component);
+
+    boolean hasComponent(String key);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ContentAggregator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ContentAggregator.java
new file mode 100644
index 0000000..4843c38
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ContentAggregator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.generation.Generator;
+
+/**
+ * A content aggregator is a special generator used to implement &lt;map:aggregate&gt;.
+ * It combines several parts into one big XML document which is streamed
+ * into the pipeline.
+ *
+ * @version $Id$
+ */
+public interface ContentAggregator extends Generator {
+
+    /**
+     * Set the root element. Please make sure that the parameters are not null!
+     */
+    public void setRootElement(String element, String namespace, String prefix);
+
+    /**
+     * Add a part. Please make sure that the parameters are not null!
+     */
+    public void addPart(String uri,
+                        String element,
+                        String namespace,
+                        String stripRootElement,
+                        String prefix);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/DefaultContentAggregator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/DefaultContentAggregator.java
new file mode 100644
index 0000000..c32473c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/DefaultContentAggregator.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.xml.ContentHandlerWrapper;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AggregatedValidity;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * This generator implements the sitemap content aggregation.
+ * It combines several parts into one big XML document which is streamed
+ * into the pipeline.
+ *
+ * @version $Id$
+ */
+public class DefaultContentAggregator extends ContentHandlerWrapper
+                                      implements Generator, CacheableProcessingComponent,
+                                                 Serviceable, ContentAggregator {
+
+    /** The root element of the aggregated content */
+    protected Element rootElement;
+
+    /** The aggregated parts */
+    protected ArrayList parts = new ArrayList();
+
+    /** Indicates the position in the stack of the root element of the aggregated content */
+    private int rootElementIndex;
+
+    /** The element used for the current part */
+    protected Element currentElement;
+
+    /** The SourceResolver */
+    protected SourceResolver resolver;
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    /** This object holds the part parts :) */
+    protected final class Part {
+        public String uri;
+        public Element element;
+        public Source source;
+        boolean stripRootElement;
+
+        public Part(String uri, Element element, String stripRoot) {
+            this.uri = uri;
+            this.element = element;
+            this.stripRootElement = BooleanUtils.toBoolean(stripRoot);
+        }
+    }
+
+    /** This object holds an element definition */
+    protected final class Element {
+        public String namespace;
+        public String prefix;
+        public String name;
+
+        public Element(String name, String namespace, String prefix) {
+            this.namespace = namespace;
+            this.prefix = prefix;
+            this.name = name;
+        }
+    }
+
+    /**
+     * Generates the content
+     */
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Generating aggregated content");
+        }
+        this.contentHandler.startDocument();
+        startElem(this.rootElement);
+
+        try {
+            for (int i = 0; i < this.parts.size(); i++) {
+                final Part part = (Part) this.parts.get(i);
+                this.rootElementIndex = part.stripRootElement ? -1 : 0;
+                if (part.element != null) {
+                    this.currentElement = part.element;
+                    startElem(part.element);
+                } else {
+                    this.currentElement = this.rootElement;
+                }
+
+                try {
+                    SourceUtil.parse(this.manager, part.source, this);
+                } finally {
+                    if (part.element != null) {
+                        endElem(part.element);
+                    }
+                }
+            }
+        } finally {
+            endElem(this.rootElement);
+            this.contentHandler.endDocument();
+        }
+        getLogger().debug("Finished aggregating content");
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public Serializable getKey() {
+        try {
+            StringBuffer buffer = new StringBuffer(64);
+            buffer.append("CA(")
+                    .append(this.rootElement.prefix).append(':')
+                    .append(this.rootElement.name).append('<')
+                    .append(this.rootElement.namespace).append(">)");
+
+            for (int i = 0; i < this.parts.size(); i++) {
+                final Part part = (Part) this.parts.get(i);
+                final Source source = part.source;
+
+                if (part.element == null) {
+                    buffer.append("P=")
+                            .append(part.stripRootElement).append(':')
+                            .append(source.getURI()).append(';');
+                } else {
+                    buffer.append("P=")
+                            .append(part.element.prefix).append(':')
+                            .append(part.element.name)
+                            .append('<').append(part.element.namespace).append(">:")
+                            .append(part.stripRootElement).append(':')
+                            .append(source.getURI()).append(';');
+                }
+            }
+
+            return buffer.toString();
+        } catch (Exception e) {
+            getLogger().error("Could not generateKey", e);
+            return null;
+        }
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        try {
+            AggregatedValidity v = new AggregatedValidity();
+            for (int i = 0; i < this.parts.size(); i++) {
+                final Source current = ((Part) this.parts.get(i)).source;
+                final SourceValidity sv = current.getValidity();
+
+                if (sv == null) {
+                    return null;
+                } else {
+                    v.add(sv);
+                }
+            }
+
+            return v;
+        } catch (Exception e) {
+            getLogger().error("Could not getValidity", e);
+            return null;
+        }
+    }
+
+    /**
+     * Set the root element. Please make sure that the parameters are not null!
+     */
+    public void setRootElement(String element, String namespace, String prefix) {
+        this.rootElement = new Element(element,
+                                       namespace,
+                                       prefix);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Root element='" + element +
+                              "' ns='" + namespace + "' prefix='" + prefix + "'");
+        }
+    }
+
+    /**
+     * Add a part. Please make sure that the parameters are not null!
+     */
+    public void addPart(String uri,
+                        String element,
+                        String namespace,
+                        String stripRootElement,
+                        String prefix) {
+        Element elem = null;
+        if (!element.equals("")) {
+            if (namespace.equals("")) {
+                elem = new Element(element,
+                                   this.rootElement.namespace,
+                                   this.rootElement.prefix);
+            } else {
+                elem = new Element(element,
+                                   namespace,
+                                   prefix);
+            }
+        }
+        this.parts.add(new Part(uri,
+                                elem,
+                                stripRootElement));
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Part uri='" + uri +
+                              "' element='" + element + "' ns='" + namespace +
+                              "' stripRootElement='" + stripRootElement + "' prefix='" + prefix + "'");
+        }
+    }
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     *
+     * <br>
+     * This method will simply call <code>setContentHandler(consumer)</code>
+     * and <code>setLexicalHandler(consumer)</code>.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        setContentHandler(consumer);
+        setLexicalHandler(consumer);
+    }
+
+    /**
+     * Recycle the producer by removing references
+     */
+    public void recycle() {
+        super.recycle();
+
+        this.rootElement = null;
+        for (int i = 0; i < this.parts.size(); i++) {
+            final Part current = (Part) this.parts.get(i);
+            if (current.source != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Releasing " + current.source);
+                }
+                this.resolver.release(current.source);
+            }
+        }
+        this.parts.clear();
+        this.currentElement = null;
+        this.resolver = null;
+    }
+
+    /**
+     * Set the <code>SourceResolver</code>, object model <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        this.resolver = resolver;
+        // get the Source for each part
+        try {
+            for (int i = 0; i < this.parts.size(); i++) {
+                final Part current = (Part) this.parts.get(i);
+                current.source = resolver.resolveURI(current.uri);
+            }
+        } catch (SourceException se) {
+            throw SourceUtil.handle("Unable to resolve source.", se);
+        }
+    }
+
+    /**
+     * Private method generating startElement event for the aggregated parts
+     * and the root element
+     */
+    private void startElem(Element element)
+    throws SAXException {
+        final String qname = (element.prefix.equals("")) ? element.name : element.prefix + ':' + element.name;
+        if (!element.namespace.equals("")) {
+            this.contentHandler.startPrefixMapping(element.prefix, element.namespace);
+        }
+        this.contentHandler.startElement(element.namespace, element.name, qname, XMLUtils.EMPTY_ATTRIBUTES);
+    }
+
+    /**
+     * Private method generating endElement event for the aggregated parts
+     * and the root element
+     */
+    private void endElem(Element element) throws SAXException {
+        final String qname = (element.prefix.equals("")) ? element.name : element.prefix + ':' + element.name;
+        this.contentHandler.endElement(element.namespace, element.name, qname);
+        if (!element.namespace.equals("")) {
+            this.contentHandler.endPrefixMapping(element.prefix);
+        }
+    }
+
+    /**
+     * Ignore start and end document events
+     */
+    public void startDocument() throws SAXException {
+    }
+
+    /**
+     * Ignore start and end document events
+     */
+    public void endDocument() throws SAXException {
+    }
+
+    /**
+     * Override startElement() event to add namespace and prefix
+     */
+    public void startElement(String namespaceURI, String localName, String raw, Attributes atts)
+    throws SAXException {
+        this.rootElementIndex++;
+        if (this.rootElementIndex == 0) {
+            getLogger().debug("Skipping root element start event.");
+            return;
+        }
+        if (namespaceURI == null || namespaceURI.equals("")) {
+            final String qname = this.currentElement.prefix.equals("") ? localName : this.currentElement.prefix + ':' + localName;
+            this.contentHandler.startElement(this.currentElement.namespace, localName, qname, atts);
+        } else {
+            this.contentHandler.startElement(namespaceURI, localName, raw, atts);
+        }
+    }
+
+    /**
+     * Override startElement() event to add namespace and prefix
+     */
+    public void endElement(String namespaceURI, String localName, String raw) throws SAXException {
+        this.rootElementIndex--;
+        if (this.rootElementIndex == -1) {
+            getLogger().debug("Skipping root element end event.");
+            return;
+        }
+        if (namespaceURI == null || namespaceURI.equals("")) {
+            final String qname = this.currentElement.prefix.equals("") ? localName : this.currentElement.prefix + ':' + localName;
+            this.contentHandler.endElement(this.currentElement.namespace, localName, qname);
+        } else {
+            this.contentHandler.endElement(namespaceURI, localName, raw);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEvent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEvent.java
new file mode 100644
index 0000000..09db793
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEvent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * @version $Id:$
+ * @since 2.2
+ */
+public class EnterSitemapEvent extends SitemapEvent {
+
+    public EnterSitemapEvent(Processor source, Environment env) {
+        super(source, env);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEventListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEventListener.java
new file mode 100644
index 0000000..371341a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/EnterSitemapEventListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+/**
+ * @version $Id:$
+ * @since 2.2
+ */
+public interface EnterSitemapEventListener extends SitemapListener {
+
+    void enteredSitemap(EnterSitemapEvent event);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ExecutionContext.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ExecutionContext.java
new file mode 100644
index 0000000..cf7ffad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/ExecutionContext.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
+
+/**
+ * This context contains information about the current statement that should
+ * be executed like the location in the sitemap etc.
+ *
+ * TODO - This is not finished yet!
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public interface ExecutionContext extends Locatable {
+    
+    /**
+     * Return the location of the statement in the sitemap.
+     */
+    Location getLocation();
+    
+    /**
+     * Return the component type
+     */
+    String getType();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEvent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEvent.java
new file mode 100644
index 0000000..ddb92a5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEvent.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ *
+ * @version $Id:$
+ * @since 2.2
+ */
+public class LeaveSitemapEvent extends SitemapEvent {
+
+    public LeaveSitemapEvent(Processor source, Environment env) {
+        super(source, env);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEventListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEventListener.java
new file mode 100644
index 0000000..9e1a2b6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LeaveSitemapEventListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+/**
+ *
+ * @version $Id:$
+ * @since 2.2
+ */
+public interface LeaveSitemapEventListener extends SitemapListener {
+
+    void leftSitemap(LeaveSitemapEvent event);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkGatherer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkGatherer.java
new file mode 100644
index 0000000..4b3de39
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkGatherer.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.xml.xlink.ExtendedXLinkPipe;
+
+import org.apache.excalibur.source.SourceValidity;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class LinkGatherer extends ExtendedXLinkPipe implements Transformer, CacheableProcessingComponent {
+    private List links;
+
+
+    /**
+     * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException,
+        SAXException, IOException {
+            this.links = (List)objectModel.get(Constants.LINK_COLLECTION_OBJECT);
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public java.io.Serializable getKey() {
+        return "1";
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+//      Whilst the cache does not store gathered links, this component must be non-cacheable
+//      return NOPValidity.SHARED_INSTANCE;
+        return null;
+    }
+
+    public void simpleLink(String href, String role, String arcrole, String title, String show, String actuate, String uri,
+        String name, String raw, Attributes attr) throws SAXException {
+            if (!this.links.contains(href)){
+                this.addLink(href);
+            }
+            super.simpleLink(href, role, arcrole, title, show, actuate, uri, name, raw, attr);
+    }
+
+    public void startLocator(String href, String role, String title, String label, String uri, String name, String raw,
+        Attributes attr) throws SAXException {
+            if (!this.links.contains(href)){
+                this.addLink(href);
+            }
+            super.startLocator(href, role, title, label, uri, name, raw, attr);
+    }
+    private void addLink(String href) {
+        if (href.length() == 0) return;
+        if (href.charAt(0) == '#') return;
+        if (href.indexOf("://") != -1) return;
+        if (href.startsWith("mailto:")) return;
+        if (href.startsWith("news:")) return;
+        if (href.startsWith("javascript:")) return;
+
+        int anchorPos = href.indexOf('#');
+        if (anchorPos == -1) {
+            this.links.add(href);
+        } else {
+            this.links.add(href.substring(0, anchorPos));
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkTranslator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkTranslator.java
new file mode 100644
index 0000000..8f2e57f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/LinkTranslator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.xml.xlink.ExtendedXLinkPipe;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @version $Id$
+ */
+public class LinkTranslator extends ExtendedXLinkPipe implements Transformer, CacheableProcessingComponent {
+    
+    private Map links;
+
+    /**
+     * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) 
+    throws ProcessingException, SAXException, IOException {
+        this.links = (Map)objectModel.get(Constants.LINK_OBJECT);
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public java.io.Serializable getKey() {
+        return "1";
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+
+    public void simpleLink(String href, String role, String arcrole, 
+                           String title, String show, String actuate, String uri,
+                           String name, String raw, Attributes attr) 
+    throws SAXException {
+        final String newHref = (String)this.links.get(href);
+        super.simpleLink((newHref != null) ? newHref : href, role, arcrole, title, show, actuate, uri, name, raw, attr);
+    }
+
+    public void startLocator(String href, String role, String title, 
+                             String label, String uri, String name, String raw,
+                             Attributes attr) 
+    throws SAXException {
+        final String newHref = (String)this.links.get(href);
+        super.startLocator((newHref != null) ? newHref : href, role, title, label, uri, name, raw, attr);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/NotifyingGenerator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/NotifyingGenerator.java
new file mode 100644
index 0000000..7a9cce9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/NotifyingGenerator.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.util.Map;
+import java.io.IOException;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.components.notification.Notifying;
+import org.apache.cocoon.components.notification.Notifier;
+import org.apache.cocoon.generation.AbstractGenerator;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Constants;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Generates an XML representation of the current notification.
+ *
+ * @version $Id$
+ */
+public class NotifyingGenerator extends AbstractGenerator {
+    
+    /**
+     * The <code>Notification</code> to report.
+     */
+    private Notifying notification;
+
+    public void setup(SourceResolver resolver, Map objectModel, String src,
+                      Parameters par) throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        this.notification  = (Notifying)objectModel.get(Constants.NOTIFYING_OBJECT);
+
+        if ( this.notification  == null) {
+            throw new ProcessingException("Expected Constants.NOTIFYING_OBJECT not found in object model");
+        }
+    }
+
+    /**
+     * Generate the notification information in XML format.
+     *
+     * @throws SAXException when there is a problem creating the
+     *      output SAX events.
+     */
+    public void generate() throws SAXException {
+        Notifier.notify(notification, this.contentHandler, "text/xml");
+    }
+
+    /**
+     * Recycle
+     */
+    public void recycle() {
+        super.recycle();
+        this.notification = null;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/PatternException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/PatternException.java
new file mode 100644
index 0000000..f3b3e19
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/PatternException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.avalon.framework.CascadingException;
+
+/**
+ * This exception is thrown by a <code>URIMatcher</code> or by a
+ * <code>URITranslator</code> when there's something wrong with the matching or
+ * translation patterns.
+ *
+ * @version $Id$
+ */
+public class PatternException extends CascadingException {
+
+    /**
+     * Construct a new <code>PatternException</code> instance.
+     */
+    public PatternException(String message) {
+        super(message, null);
+    }
+
+    /**
+     * Creates a new <code>PatternException</code> instance.
+     *
+     * @param ex an <code>Exception</code> value
+     */
+    public PatternException(Exception ex) {
+        super(ex.getMessage(), ex);
+    }
+
+    /**
+     * Construct a new <code>PatternException</code> that references
+     * a parent Exception.
+     */
+    public PatternException(String message, Throwable t) {
+        super(message, t);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/Sitemap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/Sitemap.java
new file mode 100644
index 0000000..ef14146
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/Sitemap.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.flow.Interpreter;
+
+/**
+ * TODO WORK IN PROGRESS!!
+ *
+ * This interface describes the current sitemap. The current sitemap is available using
+ * {@link org.apache.cocoon.core.Core#getCurrentSitemap()}.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public interface Sitemap {
+
+    /**
+     * Return the locator of the current sitemap.
+     * @return The current locator.
+     */
+    ComponentLocator getComponentLocator();
+
+    /**
+     * Return the current processor
+     */
+    Processor getProcessor();
+
+    /**
+     * Return the Interpreter for the given language. If no
+     * interpreter is found <code>null</code> is returned.
+     * @param language The language or <code>null</code> for the default interpreter.
+     * @return The interpreter or <code>null</code>.
+     */
+    Interpreter getInterpreter(String language);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapErrorHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapErrorHandler.java
new file mode 100644
index 0000000..3b8e251
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapErrorHandler.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.sitemap.ErrorHandlerHelper;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Class providing error handling capabilities to the pipeline
+ * as configured in the sitemap.
+ *
+ * @since 2.1.7
+ * @version $Id$
+ */
+public class SitemapErrorHandler {
+    /**
+     * Error handler helper of the pipeline node
+     */
+    private ErrorHandlerHelper handler;
+
+    /**
+     * Environment of the pipeline node
+     */
+    private Environment environment;
+
+    /**
+     * Sitemap invocation context
+     */
+    private InvokeContext context;
+
+    // Environment state
+    private String envPrefix;
+    private String envURI;
+
+    /**
+     * Construct error handler with everything needed to handle an error.
+     */
+    public SitemapErrorHandler(ErrorHandlerHelper handler,
+                               Environment environment,
+                               InvokeContext context) {
+        this.handler = handler;
+        this.environment = environment;
+        this.context = context;
+
+        this.envPrefix = environment.getURIPrefix();
+        this.envURI = environment.getURI();
+    }
+
+    /**
+     * Handle an error.
+     * @return true if error was handled.
+     */
+    public boolean handleError(Exception e) throws Exception {
+        // Restore environment state
+        this.environment.setURI(this.envPrefix, this.envURI);
+
+        return this.handler.invokeErrorHandler(e, this.environment, this.context);
+    }
+
+    /**
+     * Build error handling pipeline.
+     * @return error handling pipeline, or null if error was not handled.
+     */
+    public Processor.InternalPipelineDescription prepareErrorPipeline(Exception e) throws Exception {
+        // Restore environment state
+        this.environment.setURI(this.envPrefix, this.envURI);
+
+        return this.handler.prepareErrorHandler(e, this.environment, this.context);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapEvent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapEvent.java
new file mode 100644
index 0000000..d9b11e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapEvent.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.util.EventObject;
+
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.environment.Environment;
+
+/**
+ * Base interface for all sitemap events.
+ *
+ * @version $Id:$
+ * @since 2.2
+ */
+public abstract class SitemapEvent extends EventObject {
+
+    private final Environment environment;
+
+    /**
+     * @param source The current processor (sitemap)
+     * @param env    The environment describing the current request
+     */
+    public SitemapEvent(Processor source, Environment env) {
+        super(source);
+        this.environment = env;
+    }
+    
+    public Processor getSourceProcessor() {
+        return (Processor)this.getSource();
+    }
+    
+    public Environment getEnvironment() {
+        return this.environment;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapExecutor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapExecutor.java
new file mode 100644
index 0000000..b2d6a5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapExecutor.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.matching.PreparableMatcher;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.selection.SwitchSelector;
+
+/**
+ * The sitemap executor executes all sitemap statements, so it actually
+ * calls an action, adds a generator to the pipeline etc.
+ * By separating this functionality into a single object it is easier to
+ * plugin custom profiling or debugging tools.
+ *
+ * TODO - This is not finished yet!
+ * TODO - we should add invocation of a Redirector as well
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public interface SitemapExecutor {
+    
+    /** The component role */
+    String ROLE = SitemapExecutor.class.getName();
+    
+    public static class PipelineComponentDescription {
+        public String type;
+        public String source;
+        public Parameters parameters;
+        public Parameters hintParameters;
+        /** Mime-type for serializers and readers */
+        public String mimeType;
+    }
+    
+    /**
+     * Invoke an action and return the result.
+     */
+    Map invokeAction(ExecutionContext context,
+                     Map              objectModel, 
+                     Action           action, 
+                     Redirector       redirector, 
+                     SourceResolver   resolver, 
+                     String           source, 
+                     Parameters       parameters )
+    throws Exception;
+    
+    /**
+     * Invoke a match and return the result
+     */
+    Map invokeMatcher(ExecutionContext context,
+                      Map              objectModel,
+                      Matcher          matcher,
+                      String           pattern,
+                      Parameters       parameters )
+    throws PatternException;
+    
+    /**
+     * Invoke a match and return the result
+     */
+    Map invokePreparableMatcher(ExecutionContext context,
+                      Map               objectModel,
+                      PreparableMatcher matcher,
+                      String            pattern,
+                      Object            preparedPattern,
+                      Parameters        parameters )
+    throws PatternException;
+
+    /**
+     * Invoke a selector
+     * @param context
+     * @param objectModel
+     * @param selector
+     * @param expression
+     * @param parameters
+     * @return True if the selector did match.
+     */
+    boolean invokeSelector(ExecutionContext context,
+            Map               objectModel,
+            Selector selector, 
+            String expression, 
+            Parameters parameters);
+    
+    /**
+     * Invoke a switch selector
+     * @param context
+     * @param objectModel
+     * @param selector
+     * @param expression
+     * @param parameters
+     * @param selectorContext The context object for the switch selector
+     * @return True if the selector did match.
+     */
+    boolean invokeSwitchSelector(ExecutionContext context,
+                                 Map             objectModel,
+                                 SwitchSelector  selector, 
+                                 String expression, 
+                                 Parameters parameters,
+                                 Object selectorContext);
+
+    /**
+     * Push map of information on the context stack.
+     * @param context The execution context
+     * @param objectModel The object model
+     * @param key A key that can be used to identify this map (can be null)
+     * @param variables The variables as key/value pairs
+     * @return The variables that are used in the sitemap. The executor can
+     *         modify the set of available variables by returning a different
+     *         map.
+     */
+    Map pushVariables(ExecutionContext context, 
+                      Map              objectModel,
+                      String           key, 
+                      Map              variables);
+    
+    /**
+     * Pop a map of information from the context stack.
+     * @param context     The execution context
+     * @param objectModel The object model
+     */
+    void popVariables(ExecutionContext context,
+                      Map              objectModel);
+    
+    /**
+     * Enter a new sitemap
+     * @param context     The execution context
+     * @param objectModel The object model
+     * @param source The uri of the sitemap
+     */
+    void enterSitemap(ExecutionContext context, 
+                      Map              objectModel,
+                      String           source);
+
+    /**
+     * Leaves a sitemap.
+     */
+    void leaveSitemap(ExecutionContext context,
+                      Map              objectModel);
+
+    /**
+     * Add a generator
+     * @param context
+     * @param objectModel
+     * @param desc The descrption of the component
+     * @return The desc of the component to use
+     */
+    PipelineComponentDescription addGenerator(ExecutionContext context, 
+                                              Map              objectModel,
+                                              PipelineComponentDescription desc);
+
+    /**
+     * Add a transformer
+     * @param context
+     * @param objectModel
+     * @param desc The descrption of the component
+     * @return The desc of the component to use
+     */
+    PipelineComponentDescription addTransformer(ExecutionContext context, 
+                                                Map              objectModel,
+                                                PipelineComponentDescription desc);
+
+    /**
+     * Add a serializer
+     * @param context
+     * @param objectModel
+     * @param desc The descrption of the component
+     * @return The desc of the component to use
+     */
+    PipelineComponentDescription addSerializer(ExecutionContext context, 
+                                               Map              objectModel,
+                                               PipelineComponentDescription desc);
+
+    /**
+     * Add a reader
+     * @param context
+     * @param objectModel
+     * @param desc The descrption of the component
+     * @return The desc of the component to use
+     */
+    PipelineComponentDescription addReader(ExecutionContext context, 
+                                           Map              objectModel,
+                                           PipelineComponentDescription desc);
+
+    /**
+     * This informs the executor about a new pipeline section.
+     * @param context
+     * @param objectModel
+     * @param desc
+     * @return A (new) description for the pipeline component to use.
+     */
+    PipelineComponentDescription enteringPipeline(ExecutionContext context,
+                                                  Map              objectModel,
+                                                  PipelineComponentDescription desc);
+
+    /**
+     * Informs about a redirect.
+     * @return The uri to redirect to.
+     */
+    String redirectTo(ExecutionContext context,
+                      Map              objectModel,
+                      String           uri,
+                      boolean          createSession,
+                      boolean          global,
+                      boolean          permanent);
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapListener.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapListener.java
new file mode 100644
index 0000000..2d2da0e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapListener.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.util.EventListener;
+
+/**
+ * Base interface for all sitemap event listeners.
+ *
+ * @version $Id:$
+ * @since 2.2
+ */
+public interface SitemapListener extends EventListener {
+
+    // just a marker interface
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapModelComponent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapModelComponent.java
new file mode 100644
index 0000000..5a5270e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapModelComponent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * The SitemapModelComponent identifies the contract between the Sitemap and
+ * your pipeline components that create or transform information.  The types
+ * of components that fit within this umbrella are your Generators,
+ * Transformers, and your Readers.  It is very important to note that all
+ * components impementing this interface must be pooled or created on demand.
+ * This is due to the separation between the setup and the execution.  If you
+ * don't ensure every instance of the component is unique within a pipeline,
+ * or accross pipelines, then the setup process will start killing all the
+ * other setups and you will end up with serious race conditions.  It's not
+ * that they need synchronized keywords applied to the methods, its that the
+ * methods have to be called in a certain order.  This is by design.  If you
+ * really think about it, due to the SAX infrastructure we would still need to
+ * keep them synchronized because the order of SAX events affects the validity
+ * of your XML document.
+ * 
+ * @version $Id$
+ */
+public interface SitemapModelComponent {
+    /**
+     * The Sitemap will call the setup() method to prepare the component for
+     * use.  This is where you start the process of getting your information
+     * ready to generate your results.  See {@link org.apache.cocoon.environment.ObjectModelHelper} for help with the <code>objectModel</code>.
+     *
+     * @param resolver     The <code>SourceResolver</code> to find resources within your context.
+     * @param objectModel  A <code>java.util.Map</code> that contains the request and session information.
+     * @param src          The value of the "src" attribute in the sitemap.
+     * @param par          The sitemap parameters passed into your component.
+     *
+     * @throws SAXException if there is a problem reading a SAX stream.
+     * @throws IOException  if there is a problem reading files.
+     * @throws ProcessingException if there is any other unexpected problem.
+     */
+    void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) 
+    throws ProcessingException, SAXException, IOException;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapOutputComponent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapOutputComponent.java
new file mode 100644
index 0000000..a1295e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapOutputComponent.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The SitemapOutputComponents are responsible for taking the results of a
+ * pipeline to the end user.  Current examples are the Serializer and the
+ * Reader.  The Sitemap will terminate the pipeline when it encounters the
+ * first instance of a <code>SitemapOutputComponent</code>.  Just like the
+ * <code>SitemapModelComponent</code>, all implementations of this contract
+ * must be pooled for the same reasons.  The sitemap will query the output
+ * component for the mime type and whether the sitemap should set the content
+ * length in the response.  It will then provide the output component the
+ * <code>java.io.OutputStream</code> so you can send the bytes directly to the
+ * user.
+ * <p>
+ * It should be noted that there is no way to access any of the request,
+ * response, or context objects within a component that just implements this
+ * interface like the Serializer.  The idea is to keep things simple.  All your
+ * response attributes should have been already set, and the only
+ * responsibility at this point in time is to give the user what he wants--the
+ * rendered object (page/image/etc.).
+ * </p>
+ * 
+ * @version $Id$
+ */
+public interface SitemapOutputComponent {
+
+    /**
+     * Set the {@link OutputStream} where the requested resource should
+     * be serialized.
+     *
+     * @param out  The <code>OutputStream</code> target for the rendered results.
+     *
+     * @throws IOException if the stream can't be used.
+     */
+    void setOutputStream(OutputStream out) throws IOException;
+
+    /**
+     * Obtain the mime type for the results being serialized.  It helps
+     * responsible browsers to identify how to show the information to the
+     * user.
+     * <p>
+     * <strong>Warning:</strong>Microsoft Internet Explorer is a poor
+     * netizen and does not always respect this information.  I am talking
+     * about Microsoft's InternetExplorer.  It will first try to use the file
+     * extension of the resource to determine the mime type, and then if that
+     * fails it will fall back to respecting the mime type.  For that reason it
+     * is essential that you also practice good netizen habits and make the
+     * file extension and the mime type agree.  One example is the PDF
+     * document.  In order for Microsoft to treat a result set as a PDF
+     * document you must have the url end with ".pdf" as well as set the mime
+     * type to "application/pdf".  Internet Explorer will fail if you try to
+     * send the document "badhabit.xml?view=pdf" rendered as a PDF document.
+     * It is because the file extension ".xml" will be remapped to "text/xml"
+     * even if you set the mime type correctly.
+     * </p>
+     * <p>
+     * You may have some incorrectly configured servers that will work for one
+     * browser and not the other because the mime-type and file extension do
+     * not agree.  The world would be much simpler if all browsers blindly
+     * accepted the mime type.  Just be aware of this issue when you are
+     * creating your sitemap and serializing your results.
+     *
+     * @return the mime-type for the results.
+     */
+    String getMimeType();
+
+    /**
+     * Test if the component needs the content length set.
+     * <p>
+     * Most types of documents don't really care what the content length is,
+     * so it is usually safe to leave the results of this method to false.  It
+     * should be noted that the Adobe Acrobat Reader plugin for Microsoft
+     * Internet Explorer has a bug that wasn't fixed until version 7.  The bug
+     * prevents the PDF document from displaying correctly.  It will look like
+     * an empty document or something similar.  So the general rule of thumb
+     * for explicitly seting the content length is:
+     * </p>
+     * <ul>
+     * <li>If it is a PDF document, always set content length (might require
+     *     the document to be cached to get the number of bytes)</li>
+     * <li>If you are writing a Reader and you have the content lenght, set
+     *     it.</li>
+     * <li>Otherwise it is safe to return false here.</li>
+     * </ul>
+     *
+     * @return <code>true</code> if the content length needs to be set.
+     */
+    boolean shouldSetContentLength();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapParameters.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapParameters.java
new file mode 100644
index 0000000..661650d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/SitemapParameters.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap;
+
+import java.util.HashMap;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.util.location.Locatable;
+import org.apache.cocoon.util.location.Location;
+
+/**
+ * Extension to the Avalon Parameters to give location information
+ *
+ * @version $Id$
+ */
+public class SitemapParameters extends Parameters implements Locatable {
+    
+    private Location location = Location.UNKNOWN;
+    
+    public SitemapParameters(Location location) {
+        this.location = location;
+    }
+    
+    /**
+     * Get the location of the statement defining these parameters.
+     * 
+     * @since 2.1.8
+     * @see org.apache.cocoon.util.location.Locatable#getLocation()
+     */
+    public Location getLocation() {
+        return this.location;
+    }
+    
+    /**
+     * Get the location of a <code>Parameters</code> object, returning
+     * {@link Location#UNKNOWN} if no location could be found.
+     * 
+     * @param param
+     * @return the location
+     * @since 2.1.8
+     */
+    public static Location getLocation(Parameters param) {
+        Location loc = null;
+        if (param instanceof Locatable) {
+            loc = ((Locatable)param).getLocation();
+        }
+        return loc == null ? Location.UNKNOWN : loc;
+    }
+
+    /**
+     * @deprecated use {@link #getLocation(Parameters)}
+     */
+    public static String getStatementLocation(Parameters param) {
+        return getLocation(param).toString();
+    }    
+
+    /**
+     * For internal use only.
+     */
+    public static class LocatedHashMap extends HashMap implements Locatable {
+        private Location loc;
+
+        public Location getLocation() {
+            return this.loc;
+        }
+        
+        public LocatedHashMap(Location loc) {
+            this.loc = loc;
+        }
+
+        public LocatedHashMap(Location loc, int size) {
+            super(size);
+            this.loc = loc;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/AbstractVirtualSitemapComponent.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/AbstractVirtualSitemapComponent.java
new file mode 100644
index 0000000..541af0b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/AbstractVirtualSitemapComponent.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.sitemap.impl;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.SitemapSourceInfo;
+import org.apache.cocoon.components.pipeline.VirtualProcessingPipeline;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.components.treeprocessor.ProcessingNode;
+import org.apache.cocoon.components.treeprocessor.sitemap.VPCNode;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.wrapper.EnvironmentWrapper;
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.xml.sax.XMLizable;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * TODO List:
+ * <ul>
+ * <li>Refactor ProcessingPipelines implementations
+ * <li>Implement caching
+ * </ul>
+ */
+public abstract class AbstractVirtualSitemapComponent extends AbstractXMLPipe
+    implements SitemapModelComponent, Serviceable, Contextualizable, Configurable {
+
+    private ProcessingNode node;
+    private String sourceMapName;
+    private Map sourceMap = new HashMap();
+    private Set sources;
+    private VirtualProcessingPipeline pipeline;
+    // An environment containing a map with the souces from the calling environment
+    private EnvironmentWrapper mappedSourceEnvironment;
+    // An environment with the URI and URI prefix of the sitemap where the VPC is defined
+    private EnvironmentWrapper vpcEnvironment;
+
+    protected DefaultContext context;
+    protected SourceResolver resolver;
+    protected ServiceManager manager;
+
+    private class MyInvokeContext extends InvokeContext {
+        public MyInvokeContext(Logger logger) throws Exception {
+            super(true);
+            super.processingPipeline = new VirtualProcessingPipeline(AbstractVirtualSitemapComponent.this.context);
+            ((VirtualProcessingPipeline)super.processingPipeline).enableLogging(logger);
+        }
+    }
+
+    abstract protected String getTypeName();
+
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = (DefaultContext)context;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Release all resources.
+     */
+    public void recycle() {
+        // FIXME
+        // These are allready disposed, why?
+        //Iterator sources = this.sourceMap.values().iterator();
+        //while (sources.hasNext()) {
+        //    Source source = (Source)sources.next();
+        //    this.resolver.release(source);
+        //}
+        this.sourceMap.clear();
+        super.recycle();
+    }
+
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        String name = configuration.getAttribute("name");
+        this.sourceMapName =
+            Constants.CONTEXT_ENV_PREFIX + "-" + getTypeName() + "-source-map-" + name;
+        try {
+            this.node = (ProcessingNode)this.context.get(Constants.CONTEXT_VPC_PREFIX +
+                                                         getTypeName() + "-" + name);
+            this.sources = ((VPCNode)node).getSources();
+        } catch (Exception e) {
+            throw new ConfigurationException("Can not find VirtualPipelineComponent '" +
+                                             name + "' configuration");
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        this.resolver = resolver;
+
+        Environment env = EnvironmentHelper.getCurrentEnvironment();
+
+        // Hack to get an info object with the right uri for the
+        // current sitemap, there is no vpc protocol.
+        SitemapSourceInfo mappedSourceEnvironmentInfo =
+            SitemapSourceInfo.parseURI(env, "vpc:/");
+
+        this.mappedSourceEnvironment =
+            new EnvironmentWrapper(env, mappedSourceEnvironmentInfo, getLogger());
+        // place for resolved sources
+        this.mappedSourceEnvironment.setAttribute(this.sourceMapName, this.sourceMap);
+
+        MyInvokeContext invoker = null;
+
+        try {
+            // resolve the sources in the parameter map before switching context
+            Map resolvedParams = resolveParams(par, src);
+
+            // set up info object for VPC environment wrapper, would
+            // better be done in a constructor for the info.
+            SitemapSourceInfo vpcEnvironmentInfo = new SitemapSourceInfo();
+            vpcEnvironmentInfo.prefix = (String) this.context.get(Constants.CONTEXT_ENV_PREFIX);
+            vpcEnvironmentInfo.uri = (String) this.context.get(Constants.CONTEXT_ENV_URI);
+            vpcEnvironmentInfo.requestURI = vpcEnvironmentInfo.prefix + vpcEnvironmentInfo.uri;
+            vpcEnvironmentInfo.rawMode = false;
+
+            // set up the vpc environment
+            this.vpcEnvironment =
+                new EnvironmentWrapper(this.mappedSourceEnvironment,
+                                       vpcEnvironmentInfo, getLogger());
+
+            EnvironmentHelper.enterEnvironment(this.vpcEnvironment);
+
+            // set up invoker with sitemap params
+            invoker = new MyInvokeContext(getLogger());
+            invoker.enableLogging(getLogger());
+            invoker.service(this.manager);
+            invoker.pushMap(null, resolvedParams);
+
+            this.node.invoke(this.vpcEnvironment, invoker);
+            this.pipeline = (VirtualProcessingPipeline)invoker.getProcessingPipeline();
+        } catch (Exception e) {
+            throw new ProcessingException("Oops", e);
+        } finally {
+            if (invoker != null) {
+                invoker.popMap();
+                invoker.dispose();
+            }
+            // Restore context
+            EnvironmentHelper.leaveEnvironment();
+        }
+    }
+
+    protected VirtualProcessingPipeline getPipeline() {
+        return this.pipeline;
+    }
+
+    // An environment containing a map with the souces from the calling environment
+    protected EnvironmentWrapper getMappedSourceEnvironment() {
+        return this.mappedSourceEnvironment;
+    }
+
+    // An environment with the URI and URI prefix of the sitemap where the VPC is defined
+    protected EnvironmentWrapper getVPCEnvironment() {
+        return this.vpcEnvironment;
+    }
+
+    private Map resolveParams(Parameters par, String src)
+        throws ProcessingException, IOException {
+        HashMap map = new HashMap();
+
+        // resolve and map params
+        String[] names = par.getNames();
+        for(int i=0; i<names.length; i++) {
+            String name = names[i];
+            String value = par.getParameter(name, null);
+            if (this.sources.contains(name)) {
+                value = resolveAndMapSourceURI(name, value);
+            }
+            map.put(name, value);
+        }
+
+        // resolve and map src
+        if (src != null) {
+            map.put("src", resolveAndMapSourceURI("src", src));
+        }
+
+        return map;
+    }
+
+    private String resolveAndMapSourceURI(String name, String uri)
+        throws ProcessingException, IOException {
+
+        // Resolve the URI
+        Source src = null;
+        try {
+            src = this.resolver.resolveURI(uri);
+        } catch (SourceException se) {
+            throw SourceUtil.handle("Error during resolving of " + uri, se);
+        }
+
+        // Save the source
+        this.sourceMap.put(name, src);
+
+        // Create a new URI that refers to the source in the context
+        String mappedURI;
+        if (src instanceof XMLizable) {
+            mappedURI = "xmodule:environment-attr:" + this.sourceMapName + "#" + name;
+        } else {
+            mappedURI = "module:environment-attr:" + this.sourceMapName + "#" + name;
+        }
+
+        return mappedURI;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/ComponentManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/ComponentManager.java
new file mode 100644
index 0000000..0198d0c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/ComponentManager.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap.impl;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.sitemap.ComponentLocator;
+
+
+/**
+ * This is the connection between the Cocoon core components
+ * and an optional application/sitemap container.
+ *
+ * It acts as a service manager and as a component locator at the same time.
+ * A component manager is initialized with both, a service manager for a sitemap
+ * and an optional component locator for the sitemap. Each operation (lookup etc.)
+ * is first performed on the component locator. If the locator does not have
+ * the component in question, the service manager is asked.
+ *
+ * @since 2.2
+ * @version $Id$
+ */
+public class ComponentManager implements ServiceManager, ComponentLocator {
+
+    final protected ServiceManager serviceManager;
+    final protected ComponentLocator componentLocator;
+
+    public ComponentManager(final ServiceManager sm, final ComponentLocator cl) {
+        this.serviceManager = sm;
+        this.componentLocator = cl;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService(String key) {
+        boolean result = false;
+        if ( this.componentLocator != null ) {
+            result = this.componentLocator.hasComponent(key);
+        }
+        if ( !result ) {
+            result = this.serviceManager.hasService(key);
+        }
+        return result;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#release(java.lang.Object)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        // FIXME - we should optimize this
+        if ( this.componentLocator != null ) {
+            this.componentLocator.release(component);
+        }
+        this.serviceManager.release(component);
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#hasComponent(java.lang.String)
+     */
+    public boolean hasComponent(String key) {
+        return this.hasService(key);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup(String key) 
+    throws ServiceException {
+        try {
+            return this.doLookup(key);
+        } catch (ProcessingException se) {
+            throw new ServiceException("ComponentLocator", 
+                                       "Unable to lookup component for key: " + key, se);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.ComponentLocator#getComponent(java.lang.String)
+     */
+    public Object getComponent(String key) throws ProcessingException {
+        try {
+            return this.doLookup(key);
+        } catch (ServiceException se) {
+            throw new ProcessingException("Unable to lookup component for key: " + key, se);
+        }
+    }
+
+    protected Object doLookup(String key)
+    throws ProcessingException, ServiceException {
+        Object component = null;
+        if ( this.componentLocator != null ) {
+            if ( this.componentLocator.hasComponent(key) ) {
+                component = this.componentLocator.getComponent(key);
+            }
+        }
+        if ( component == null && this.serviceManager.hasService(key) ) {
+            component = this.serviceManager.lookup(key);
+        }
+        return component;
+    }
+    
+    public ServiceManager getServiceManager() {
+        if ( this.serviceManager instanceof ComponentManager ) {
+            return ((ComponentManager)this.serviceManager).getServiceManager();
+        }
+        return this.serviceManager;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/DefaultExecutor.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/DefaultExecutor.java
new file mode 100644
index 0000000..eeff9c9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/sitemap/impl/DefaultExecutor.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.sitemap.impl;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.matching.PreparableMatcher;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.selection.SwitchSelector;
+import org.apache.cocoon.sitemap.ExecutionContext;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+
+/**
+ * This is the default executor that does nothing but just executing the
+ * statements.
+ * TODO - This is not finished yet!
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public class DefaultExecutor 
+    implements SitemapExecutor {
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeAction(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.acting.Action, org.apache.cocoon.environment.Redirector, org.apache.cocoon.environment.SourceResolver, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokeAction(final ExecutionContext context,
+                            final Map              objectModel, 
+                            final Action           action, 
+                            final Redirector       redirector, 
+                            final SourceResolver   resolver, 
+                            final String           resolvedSource, 
+                            final Parameters       resolvedParams )
+    throws Exception {
+        return action.act(redirector, resolver, objectModel, 
+                resolvedSource, resolvedParams);        
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeMatcher(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.matching.Matcher, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokeMatcher(ExecutionContext context, 
+                             Map objectModel,
+                             Matcher matcher, 
+                             String pattern, 
+                             Parameters resolvedParams)
+    throws PatternException {
+        return matcher.match(pattern, objectModel, resolvedParams);
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokePreparableMatcher(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.matching.PreparableMatcher, java.lang.String, java.lang.Object, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokePreparableMatcher(ExecutionContext  context,
+                                       Map               objectModel,
+                                       PreparableMatcher matcher,
+                                       String            pattern,
+                                       Object            preparedPattern,
+                                       Parameters        resolvedParams )
+    throws PatternException {
+        return matcher.preparedMatch(preparedPattern, objectModel, resolvedParams);
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeSelector(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.selection.Selector, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public boolean invokeSelector(ExecutionContext context, Map objectModel,
+            Selector selector, String expression, Parameters parameters) {
+        return selector.select(expression, objectModel, parameters);
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeSwitchSelector(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.selection.SwitchSelector, java.lang.String, org.apache.avalon.framework.parameters.Parameters, Object)
+     */
+    public boolean invokeSwitchSelector(ExecutionContext context,
+            Map objectModel, SwitchSelector selector, String expression,
+            Parameters parameters, Object selectorContext) {
+        return selector.select(expression, selectorContext);
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#popVariables(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map)
+     */
+    public void popVariables(ExecutionContext context,
+                             Map              objectModel) {
+        // nothing to do
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#pushVariables(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, java.lang.String, java.util.Map)
+     */
+    public Map pushVariables(ExecutionContext context, 
+                             Map              objectModel,
+                             String key, Map variables) {
+        return variables;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#enterSitemap(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, java.lang.String)
+     */
+    public void enterSitemap(ExecutionContext context, Map objectModel, String source) {
+        // nothing to do
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addGenerator(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addGenerator(ExecutionContext context,
+            Map objectModel, PipelineComponentDescription desc) {
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addReader(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addReader(ExecutionContext context,
+            Map objectModel, PipelineComponentDescription desc) {
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addSerializer(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addSerializer(ExecutionContext context,
+            Map objectModel, PipelineComponentDescription desc) {
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addTransformer(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addTransformer(
+            ExecutionContext context, Map objectModel,
+            PipelineComponentDescription desc) {
+        return desc;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#leaveSitemap(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map)
+     */
+    public void leaveSitemap(ExecutionContext context, Map objectModel) {
+        // nothing to do
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#redirectTo(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, java.lang.String, boolean, boolean, boolean)
+     */
+    public String redirectTo(ExecutionContext context, Map objectModel, String uri, boolean createSession, boolean global, boolean permanent) {
+        return uri;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#enteringPipeline(org.apache.cocoon.sitemap.ExecutionContext, java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription enteringPipeline(ExecutionContext context, Map objectModel, PipelineComponentDescription desc) {
+        return desc;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractDOMTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractDOMTransformer.java
new file mode 100644
index 0000000..65aa5dc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractDOMTransformer.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * An Abstract DOM Transformer, for use when a transformer needs a DOM-based
+ * view of the document.
+ * Subclass this interface and implement <code>transform(Document doc)</code>.
+ * If you need a ServiceManager there is an instance variable
+ * <code>manager</code> for use.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractDOMTransformer extends AbstractTransformer
+        implements DOMBuilder.Listener, Serviceable, Disposable {
+
+    /**
+     *  The SAX entity resolver
+     */
+    protected SourceResolver resolver;
+
+    /**
+     *  The request object model
+     */
+    protected Map objectModel;
+
+    /**
+     *  The URI requested
+     */
+    protected String source;
+
+    /**
+     *  Parameters in the sitemap
+     */
+    protected Parameters parameters;
+
+    /**
+     * A <code>ServiceManager</code> which is available for use.
+     */
+    protected ServiceManager manager;
+
+    /**
+     * The <code>DOMBuilder</code> used to build DOM tree out of
+     *incoming SAX events.
+     */
+    protected DOMBuilder builder;
+
+
+    public AbstractDOMTransformer() {
+        super();
+        this.builder = new DOMBuilder(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     *
+     * If you wish to process the parameters, override this method, call
+     * <code>super()</code> and then add your code.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+            throws ProcessingException, SAXException, IOException {
+
+        this.resolver = resolver;
+        this.objectModel = objectModel;
+        this.source = src;
+        this.parameters = par;
+    }
+
+    /**
+     * Recycle the component.
+     */
+    public void recycle() {
+        this.resolver = null;
+        this.source = null;
+        this.objectModel = null;
+        this.parameters = null;
+        this.builder.recycle();
+        super.recycle();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.builder = null;
+        this.manager = null;
+    }
+
+    /**
+     * This method is called when the Document is finished.
+     * @param doc The DOM Document object representing this SAX stream
+     * @see org.apache.cocoon.xml.dom.DOMBuilder.Listener
+     */
+    public void notify(Document doc) throws SAXException {
+        // Call the user's transform method
+        Document newdoc = transform(doc);
+
+        // Now we stream the resulting DOM tree down the pipe
+        DOMStreamer s = new DOMStreamer(contentHandler, lexicalHandler);
+        s.stream(newdoc);
+    }
+
+    /**
+     * Transform the specified DOM, returning a new DOM to stream down the pipeline.
+     * @param doc The DOM Document representing the SAX stream
+     * @return A DOM Document to stream down the pipeline
+     */
+    protected abstract Document transform(Document doc);
+
+
+    //
+    // SAX Methods. Send incoming SAX events to the DOMBuilder.
+    //
+
+    public void setDocumentLocator(Locator locator) {
+        builder.setDocumentLocator(locator);
+    }
+
+    public void startDocument() throws SAXException {
+        builder.startDocument();
+    }
+
+    public void endDocument() throws SAXException {
+        builder.endDocument();
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        builder.startPrefixMapping(prefix, uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        builder.endPrefixMapping(prefix);
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+            throws SAXException {
+        builder.startElement(uri, loc, raw, a);
+    }
+
+    public void endElement(String uri, String loc, String raw)
+            throws SAXException {
+        builder.endElement(uri, loc, raw);
+    }
+
+    public void characters(char c[], int start, int len)
+            throws SAXException {
+        builder.characters(c, start, len);
+    }
+
+    public void ignorableWhitespace(char c[], int start, int len)
+            throws SAXException {
+        builder.ignorableWhitespace(c, start, len);
+    }
+
+    public void processingInstruction(String target, String data)
+            throws SAXException {
+        builder.processingInstruction(target, data);
+    }
+
+    public void skippedEntity(String name)
+            throws SAXException {
+        builder.skippedEntity(name);
+    }
+
+    public void startDTD(String name, String publicId, String systemId)
+            throws SAXException {
+        builder.startDTD(name, publicId, systemId);
+    }
+
+    public void endDTD()
+            throws SAXException {
+        builder.endDTD();
+    }
+
+    public void startEntity(String name)
+            throws SAXException {
+        builder.startEntity(name);
+    }
+
+    public void endEntity(String name)
+            throws SAXException {
+        builder.endEntity(name);
+    }
+
+    public void startCDATA()
+            throws SAXException {
+        builder.startCDATA();
+    }
+
+    public void endCDATA()
+            throws SAXException {
+        builder.endCDATA();
+    }
+
+    public void comment(char ch[], int start, int len)
+            throws SAXException {
+        builder.comment(ch, start, len);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractExtractionTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractExtractionTransformer.java
new file mode 100644
index 0000000..16afeba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractExtractionTransformer.java
@@ -0,0 +1,450 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+
+import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+
+/**
+ * This transformer sieves an incoming stream of xml
+ * and feeds a DOMBuilder with it.
+ *
+ * @version $Id$
+ */
+abstract public class AbstractExtractionTransformer extends AbstractTransformer {
+
+    protected DOMBuilder currentBuilder;
+
+    private Map prefixMap;
+
+    protected int extractLevel;
+
+
+    /** Setup the transformer. */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+            throws ProcessingException, SAXException, IOException {
+        extractLevel = 0;
+        prefixMap = new HashMap();
+    }
+
+    public void recycle() {
+        this.extractLevel = 0;
+        this.currentBuilder = null;
+        this.prefixMap = null;
+        super.recycle();
+    }
+
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startPrefixMapping(prefix,uri);
+            prefixMap.put(prefix,uri);
+        } else {
+            this.currentBuilder.startPrefixMapping(prefix,uri);
+        }
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     *
+     * @param prefix The prefix that was being mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endPrefixMapping(prefix);
+            prefixMap.remove(prefix);
+        } else {
+            this.currentBuilder.endPrefixMapping(prefix);
+        }
+    }
+
+
+    /**
+     * Receive notification of the beginning of an element. Uses
+     * startExtraction to determine whether to start
+     * extracting. Nested triggering tags result in only one document.
+     * * startExtractedDocument with the first node of the extracted
+     * Document.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
+        if (!startExtracting(uri, loc, raw, a)) {
+
+            if (extractLevel == 0) {
+                super.startElement(uri,loc,raw,a);
+            } else {
+                this.currentBuilder.startElement(uri,loc,raw,a);
+            }
+
+        } else {
+
+            extractLevel++;
+            if (this.getLogger().isDebugEnabled()) {
+                getLogger().debug("extractLevel now " + extractLevel + ".");
+            }
+
+            if (extractLevel != 1) {
+                this.currentBuilder.startElement(uri,loc,raw,a);
+            } else {
+
+                // setup new document
+                this.currentBuilder = new DOMBuilder();
+                this.currentBuilder.startDocument();
+                // setup namespaces
+                Iterator itt = prefixMap.entrySet().iterator();
+                while (itt.hasNext()) {
+                    Map.Entry entry = (Map.Entry)itt.next();
+                    this.currentBuilder.startPrefixMapping(
+                        (String)entry.getKey(),
+                        (String)entry.getValue()
+                    );
+                }
+                // start root node
+                startExtractingDocument(uri, loc, raw, a);
+
+            }
+
+        }
+    }
+
+
+    /**
+     * Receive notification of the end of an element. Uses
+     * endExtraction to determine whether to stop extracting or
+     * not. Calls endExtractedDocument with the extracted document.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endElement(uri,loc,raw);
+        } else {
+            if (endExtracting(uri, loc, raw)) {
+                extractLevel--;
+                if (this.getLogger().isDebugEnabled()) {
+                    getLogger().debug("extractLevel now " + extractLevel + ".");
+                }
+
+                if (extractLevel != 0) {
+                    this.currentBuilder.endElement(uri,loc,raw);
+                } else {
+
+                    // end root element
+                    endExtractingDocument(uri, loc, raw);
+                    // finish building the document. remove existing prefix mappings.
+                    Iterator itt = prefixMap.entrySet().iterator();
+                    while (itt.hasNext()) {
+                        Map.Entry entry = (Map.Entry) itt.next();
+                        this.currentBuilder.endPrefixMapping(
+                            (String)entry.getKey()
+                        );
+                    }
+                    this.currentBuilder.endDocument();
+
+                    handleExtractedDocument(this.currentBuilder.getDocument());
+
+                    if (this.getLogger().isDebugEnabled()) {
+                        getLogger().debug("Stored document.");
+                    }
+
+                }
+            } else {
+                this.currentBuilder.endElement(uri, loc, raw);
+            }
+        }
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.characters(c,start,len);
+        } else {
+            this.currentBuilder.characters(c,start,len);
+        }
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.ignorableWhitespace(c,start,len);
+        } else {
+            this.currentBuilder.ignorableWhitespace(c,start,len);
+        }
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if none was
+     *             supplied.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.processingInstruction(target,data);
+        } else {
+            this.currentBuilder.processingInstruction(target,data);
+        }
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity.  If it is a  parameter
+     *             entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.skippedEntity(name);
+        } else {
+            this.currentBuilder.skippedEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external DTD
+     *                 subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external DTD
+     *                 subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startDTD(name,publicId,systemId);
+        } else {
+            throw new SAXException(
+                "Recieved startDTD after beginning fragment extraction process."
+            );
+        }
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endDTD();
+        } else {
+            throw new SAXException(
+                "Recieved endDTD after beginning fragment extraction process."
+            );
+        }
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     * @param name The name of the entity. If it is a parameter entity, the
+     *             name will begin with '%'.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startEntity(name);
+        } else {
+            this.currentBuilder.startEntity(name);
+        }
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endEntity(name);
+        } else {
+            this.currentBuilder.endEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startCDATA();
+        } else {
+            this.currentBuilder.startCDATA();
+        }
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endCDATA();
+        } else {
+            this.currentBuilder.endCDATA();
+        }
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.comment(ch,start,len);
+        } else {
+            this.currentBuilder.comment(ch,start,len);
+        }
+    }
+
+
+
+    /**
+     * Receive notification of the beginning of an element and signal extraction start.
+     * 
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     * @return a <code>boolean</code> value to signal to start extracting
+     */
+    abstract boolean startExtracting(String uri, String loc, String raw, Attributes a);
+
+    /**
+     * Receive notification of the beginning of the extracted Document. Per default send
+     * startElement message to document builder. Override if necessary. Must override 
+     * {@link #endExtractingDocument(String, String, String)} as well. 
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     */
+    public void startExtractingDocument(String uri, String loc, String raw, Attributes a) throws SAXException{
+        this.currentBuilder.startElement(uri,loc,raw,a);
+    }
+
+    /**
+     * Receive notification of the end of an element and signal extraction end.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     * @return a <code>boolean</code> value to signal to stop extracting
+     */
+    abstract boolean endExtracting(String uri, String loc, String raw);
+
+    /**
+     * Receive notification of the end of the extracted Document. Per default, 
+     * send endElement message to document builder. Override if necessary.
+     * Must override
+     * {@link #startExtractingDocument(String, String, String, Attributes)}
+     * as well.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endExtractingDocument(String uri, String loc, String raw) throws SAXException{
+        this.currentBuilder.endElement(uri,loc,raw);
+    }
+
+    /**
+     * Receive notification of the end of the extracted Document.
+     *
+     * @param doc a <code>Document</code> value
+     */
+    abstract void handleExtractedDocument(Document doc);
+    
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java
new file mode 100644
index 0000000..669d696
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java
@@ -0,0 +1,1097 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.helpers.ParametersRecorder;
+import org.apache.cocoon.transformation.helpers.TextRecorder;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.cocoon.util.TraxErrorHandler;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.ImmutableAttributesImpl;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.SaxBuffer;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+
+import org.apache.excalibur.source.SourceParameters;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Stack;
+
+/**
+ * This class is the basis for all transformers. It provides various useful
+ * methods and hooks for implementing own custom transformers.
+ *
+ * <p>The basic behaviour of each transformer consists of the following four
+ * parts:</p>
+ * <ul>
+ * <li>Listen for specific events with a given namespace</li>
+ * <li>Collect information via these events</li>
+ * <li>Process the information</li>
+ * <li>Create new events from the processed information</li>
+ * </ul>
+ *
+ * <p>For all these four purposes the AbstractSAXTransformer offers some
+ * powerful methods and hooks:</p>
+ *
+ * <h3>Namespace handling</h3>
+ * By setting the instance variable namespaceURI to the namespace the
+ * events are filtered and only events with this namespace are send to
+ * the two hooks: <code>startTransformingElement</code> and
+ * <code>endTransformingElement</code>. It is possible to override the default
+ * namespace for the transformer by specifying the parameter "namespaceURI"
+ * in the pipeline. This avoids possible namespace collisions.
+ *
+ * <h3>Recording of information</h3>
+ * There are several methods for recording information, e.g. startRecording(),
+ * startTextRecording() etc. These methods collect information from the xml
+ * stream for further processing.
+ *
+ * <h3>Creating new events</h3>
+ * New events can be easily created with the <code>sendEvents()</code>
+ * method, the <code>sendStartElementEvent()</code> methods, the
+ * <code>sendEndElementEvent()</code> method or the
+ * <code>sendTextEvent()</code> method.
+ *
+ * <h3>Initialization</h3>
+ * Before the document is processed the <code>setupTransforming</code> hook
+ * is invoked.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractSAXTransformer extends AbstractTransformer
+                                             implements Serviceable, Configurable, Recyclable, Disposable {
+
+    /**
+     * Empty immutable attributes (for performance). Use them
+     * whenever creating an element with no attributes.
+     */
+    protected static final Attributes EMPTY_ATTRIBUTES = XMLUtils.EMPTY_ATTRIBUTES;
+
+    /**
+     * The trax <code>TransformerFactory</code> used by this transformer.
+     */
+    private SAXTransformerFactory tfactory;
+
+    /**
+     * Controlls SAX event handling.
+     * If set to true all whitespace events are ignored.
+     */
+    protected boolean ignoreWhitespaces;
+
+    /**
+     * Controlls SAX event handling.
+     * If set to true all characters events containing only whitespaces
+     * are ignored.
+     */
+    protected boolean ignoreEmptyCharacters;
+
+    /**
+     * Controlls SAX event handling.
+     * If this is incremented all events are not forwarded to the next
+     * pipeline component, but the hooks are still called.
+     */
+    protected int ignoreEventsCount;
+
+    /**
+     * Controlls SAX event handling.
+     * If this is greater than zero, the hooks are not called. Attention,
+     * make sure, that you decrement this counter properly as your hooks are
+     * not called anymore!
+     */
+    protected int ignoreHooksCount;
+
+    /**
+     * The namespace used by the transformer for the SAX events filtering.
+     * This either equals to the {@link #defaultNamespaceURI} or to the value
+     * set by the <code>namespaceURI</code> sitemap parameter for the pipeline.
+     * Must never be null.
+     */
+    protected String namespaceURI;
+
+    /**
+     * This is the default namespace used by the transformer.
+     * Implementations should set its value in the constructor.
+     * Must never be null.
+     */
+    protected String defaultNamespaceURI;
+
+    /**
+     * A stack for collecting information.
+     * The stack is important for collection information especially when
+     * the tags can be nested.
+     */
+    protected final Stack stack = new Stack();
+
+    /**
+     * The stack of current used recorders
+     */
+    protected final Stack recorderStack = new Stack();
+
+    /**
+     * The current Request object
+     */
+    protected Request request;
+
+    /**
+     * The current Response object
+     */
+    protected Response response;
+
+    /**
+     * The current Context object
+     */
+    protected Context context;
+
+    /**
+     * The current objectModel of the environment
+     */
+    protected Map objectModel;
+
+    /**
+     * The parameters specified in the sitemap
+     */
+    protected Parameters parameters;
+
+    /**
+     * The source attribute specified in the sitemap
+     */
+    protected String source;
+
+    /**
+     * The Avalon ServiceManager for getting Components
+     */
+    protected ServiceManager manager;
+
+    /**
+     * The SourceResolver for this request
+     */
+    protected SourceResolver resolver;
+
+    /**
+     * Are we already initialized for the current request?
+     */
+    private boolean isInitialized;
+
+    /**
+     * The namespaces and their prefixes
+     */
+    private final List namespaces = new ArrayList(5);
+
+    /**
+     * The current prefix for our namespace
+     */
+    private String ourPrefix;
+
+    /**
+     * Remove namespace prefixes for our namespace?
+     * @since 2.2
+     */
+    protected boolean removeOurNamespacePrefixes = false;
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * @see Configurable#configure(Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        String tFactoryClass = configuration.getChild("transformer-factory").getValue(null);
+        if (tFactoryClass != null) {
+            try {
+                this.tfactory = (SAXTransformerFactory) ClassUtils.newInstance(tFactoryClass);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using transformer factory " + tFactoryClass);
+                }
+            } catch (Exception e) {
+                throw new ConfigurationException("Cannot load transformer factory " + tFactoryClass, e);
+            }
+        } else {
+            // Standard TrAX behaviour
+            this.tfactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+        }
+        tfactory.setErrorListener(new TraxErrorHandler(getLogger()));
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(SourceResolver, Map, String, Parameters)
+     */
+    public void setup(SourceResolver resolver,
+                      Map            objectModel,
+                      String         src,
+                      Parameters     params)
+    throws ProcessingException, SAXException, IOException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Setup resolver=" + resolver +
+                              ", objectModel=" + objectModel +
+                              ", src=" + src +
+                              ", parameters=" + params);
+        }
+
+        // defaultNamespaceURI should never be null
+        if (this.defaultNamespaceURI == null) {
+            this.defaultNamespaceURI = "";
+        }
+        this.objectModel = objectModel;
+
+        this.request = ObjectModelHelper.getRequest(objectModel);
+        this.response = ObjectModelHelper.getResponse(objectModel);
+        this.context = ObjectModelHelper.getContext(objectModel);
+        this.resolver = resolver;
+        this.parameters = params;
+        this.source = src;
+        this.isInitialized = false;
+
+        // get the current namespace
+        this.namespaceURI = params.getParameter("namespaceURI",
+                                                this.defaultNamespaceURI);
+
+        this.ignoreHooksCount = 0;
+        this.ignoreEventsCount = 0;
+        this.ignoreWhitespaces = true;
+        this.ignoreEmptyCharacters = false;
+    }
+
+    /**
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        this.namespaceURI = null;
+        this.objectModel = null;
+        this.request = null;
+        this.response = null;
+        this.context = null;
+        this.resolver = null;
+        this.stack.clear();
+        this.recorderStack.clear();
+        this.parameters = null;
+        this.source = null;
+        this.namespaces.clear();
+        this.ourPrefix = null;
+
+        super.recycle();
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.manager = null;
+    }
+
+    //
+    // SAX ContentHandler methods
+    //
+
+    /**
+     * Process the SAX event.
+     * @see ContentHandler#setDocumentLocator
+     */
+    public void setDocumentLocator(Locator locator) {
+        if (this.ignoreEventsCount == 0) {
+            super.setDocumentLocator(locator);
+        }
+    }
+
+    /**
+     * Process the SAX event. A new document is processed. The hook method
+     * {@link #setupTransforming} is invoked.
+     * @see ContentHandler#startDocument
+     */
+    public void startDocument()
+    throws SAXException {
+        if (!this.isInitialized) {
+            try {
+                setupTransforming();
+            } catch (ProcessingException e) {
+                throw new SAXException("ProcessingException: " + e, e);
+            } catch (IOException e) {
+                throw new SAXException("IOException: " + e, e);
+            }
+            this.isInitialized = true;
+        }
+
+        if (this.ignoreEventsCount == 0) {
+            super.startDocument();
+        }
+    }
+
+    /**
+     * Process the SAX event. The processing of the document is finished.
+     * @see org.xml.sax.ContentHandler#endDocument
+     */
+    public void endDocument()
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.endDocument();
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see org.xml.sax.ContentHandler#startPrefixMapping
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        boolean isOurPrefix = false;
+        if (prefix != null) {
+            this.namespaces.add(new String[] {prefix, uri});
+        }
+        if (namespaceURI.equals(uri)) {
+            this.ourPrefix = prefix;
+            isOurPrefix = true;
+        }
+        if (this.ignoreEventsCount == 0) {
+            if ( !removeOurNamespacePrefixes || !isOurPrefix) {
+                super.startPrefixMapping(prefix, uri);
+            }
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see org.xml.sax.ContentHandler#endPrefixMapping
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        boolean isOurPrefix = false;
+        if (prefix != null) {
+            // Find and remove the namespace prefix
+            boolean found = false;
+            for (int i = this.namespaces.size() - 1; i >= 0; i--) {
+                final String[] prefixAndUri = (String[]) this.namespaces.get(i);
+                if (prefixAndUri[0].equals(prefix)) {
+                    this.namespaces.remove(i);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                throw new SAXException("Namespace for prefix '" + prefix + "' not found.");
+            }
+
+            if (prefix.equals(this.ourPrefix)) {
+                isOurPrefix = true;
+                // Reset our current prefix
+                this.ourPrefix = null;
+
+                // Now search if we have a different prefix for our namespace
+                for (int i = this.namespaces.size() - 1; i >= 0; i--) {
+                    final String[] prefixAndUri = (String[]) this.namespaces.get(i);
+                    if (namespaceURI.equals(prefixAndUri[1])) {
+                        this.ourPrefix = prefixAndUri[0];
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (this.ignoreEventsCount == 0) {
+            if ( !removeOurNamespacePrefixes || !isOurPrefix) {
+                super.endPrefixMapping(prefix);
+            }
+        }
+    }
+
+    /**
+     * Process the SAX event. The namespace of the event is checked.
+     * If it is the defined namespace for this transformer,
+     * the {@link #startTransformingElement} hook is called.
+     * @see org.xml.sax.ContentHandler#startElement
+     */
+    public void startElement(String uri,
+                             String name,
+                             String raw,
+                             Attributes attr)
+    throws SAXException {
+        if (namespaceURI.equals(uri) && ignoreHooksCount == 0) {
+            // this is our namespace:
+            try {
+                startTransformingElement(uri, name, raw, attr);
+            } catch (ProcessingException e) {
+                throw new SAXException("ProcessingException: " + e, e);
+            } catch (IOException e) {
+                throw new SAXException("IOException occured during processing: " + e, e);
+            }
+        } else {
+            if (ignoreEventsCount == 0) {
+                super.startElement(uri, name, raw, attr);
+            }
+        }
+    }
+
+    /**
+     * Process the SAX event. The namespace of the event is checked.
+     * If it is the defined namespace for this transformer,
+     * the {@link #endTransformingElement} hook is called.
+     * @see org.xml.sax.ContentHandler#endElement
+     */
+    public void endElement(String uri, String name, String raw)
+    throws SAXException {
+        if (namespaceURI.equals(uri) && this.ignoreHooksCount == 0) {
+            // this is our namespace:
+            try {
+                endTransformingElement(uri, name, raw);
+            } catch (ProcessingException e) {
+                throw new SAXException("ProcessingException: " + e, e);
+            } catch (IOException e) {
+                throw new SAXException("IOException occured during processing: " + e, e);
+            }
+        } else {
+            if (ignoreEventsCount == 0) {
+                super.endElement(uri, name, raw);
+            }
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see org.xml.sax.ContentHandler#characters
+     */
+    public void characters(char[] p0, int p1, int p2)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            if (this.ignoreEmptyCharacters) {
+                String value = new String(p0, p1, p2);
+                if (value.trim().length() > 0) {
+                    super.characters(p0, p1, p2);
+                }
+            } else {
+                super.characters(p0, p1, p2);
+            }
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see org.xml.sax.ContentHandler#ignorableWhitespace
+     */
+    public void ignorableWhitespace(char[] p0, int p1, int p2)
+    throws SAXException {
+        if (ignoreWhitespaces == false && ignoreEventsCount == 0) {
+            super.ignorableWhitespace(p0, p1, p2);
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see ContentHandler#processingInstruction
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.processingInstruction(target, data);
+        }
+    }
+
+    /**
+     * Process the SAX event.
+     * @see ContentHandler#skippedEntity
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.skippedEntity(name);
+        }
+    }
+
+    //
+    // SAX LexicalHandler methods
+    //
+
+    /**
+     * @see LexicalHandler#startDTD
+     */
+    public void startDTD(String name, String public_id, String system_id)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.startDTD(name, public_id, system_id);
+        }
+    }
+
+    /**
+     * @see LexicalHandler#endDTD
+     */
+    public void endDTD() throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.endDTD();
+        }
+    }
+
+    /**
+     * @see LexicalHandler#startEntity
+     */
+    public void startEntity (String name)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.startEntity(name);
+        }
+    }
+
+    /**
+     * @see LexicalHandler#endEntity
+     */
+    public void endEntity (String name)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.endEntity(name);
+        }
+    }
+
+    /**
+     * @see LexicalHandler#startCDATA
+     */
+    public void startCDATA() throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.startCDATA();
+        }
+    }
+
+    /**
+     * @see LexicalHandler#endCDATA
+     */
+    public void endCDATA() throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.endCDATA();
+        }
+    }
+
+    /**
+     * @see LexicalHandler#comment
+     */
+    public void comment(char ary[], int start, int length)
+    throws SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.comment(ary, start, length);
+        }
+    }
+
+
+    /*
+     * Recording of events.
+     * With this method all events are not forwarded to the next component in the pipeline.
+     * They are recorded to create a document fragment.
+     */
+
+    private LexicalHandler   originalLexicalHandler;
+    private ContentHandler   originalContentHandler;
+
+    /**
+     * Add a new recorder to the recording chain.
+     * Do not invoke this method directly.
+     */
+    protected void addRecorder(XMLConsumer recorder) {
+        if (this.recorderStack.empty()) {
+            // redirect if first (top) recorder
+            this.originalLexicalHandler = this.lexicalHandler;
+            this.originalContentHandler = this.contentHandler;
+        }
+        setContentHandler(recorder);
+        setLexicalHandler(recorder);
+        this.recorderStack.push(recorder);
+    }
+
+    /**
+     * Remove a recorder from the recording chain.
+     * Do not invoke this method directly.
+     */
+    protected Object removeRecorder() {
+        Object recorder = this.recorderStack.pop();
+        if (this.recorderStack.empty() == true) {
+            // undo redirect if no recorder any more
+            setContentHandler(originalContentHandler);
+            setLexicalHandler(originalLexicalHandler);
+            this.originalLexicalHandler = null;
+            this.originalContentHandler = null;
+        } else {
+            XMLConsumer next = (XMLConsumer) recorderStack.peek();
+            setContentHandler(next);
+            setLexicalHandler(next);
+        }
+
+        return recorder;
+    }
+
+    /**
+     * Start recording of SAX events.
+     * All incoming events are recorded and not forwarded. The resulting
+     * XMLizable can be obtained by the matching {@link #endSAXRecording} call.
+     * @since 2.1.5
+     */
+    public void startSAXRecording()
+    throws SAXException {
+        addRecorder(new SaxBuffer());
+        sendStartPrefixMapping();
+    }
+
+    /**
+     * Stop recording of SAX events.
+     * This method returns the resulting XMLizable.
+     * @since 2.1.5
+     */
+    public XMLizable endSAXRecording()
+    throws SAXException {
+        sendEndPrefixMapping();
+        return (XMLizable) removeRecorder();
+    }
+
+    /**
+     * Start recording of a text.
+     * No events forwarded, and all characters events
+     * are collected into a string.
+     */
+    public void startTextRecording()
+    throws SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start text recording");
+        }
+        addRecorder(new TextRecorder());
+        sendStartPrefixMapping();
+    }
+
+    /**
+     * Stop recording of text and return the recorded information.
+     * @return The String, trimmed.
+     */
+    public String endTextRecording()
+    throws SAXException {
+        sendEndPrefixMapping();
+
+        TextRecorder recorder = (TextRecorder) removeRecorder();
+        String text = recorder.getText();
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End text recording. Text=" + text);
+        }
+        return text;
+    }
+
+    /**
+     * Start recording of serialized xml
+     * All events are converted to an xml string which can be retrieved by
+     * endSerializedXMLRecording.
+     * @param format The format for the serialized output. If <CODE>null</CODE>
+     *               is specified, the default format is used.
+     */
+    public void startSerializedXMLRecording(Properties format)
+    throws SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start serialized XML recording. Format=" + format);
+        }
+        this.stack.push(format == null? XMLUtils.createPropertiesForXML(false): format);
+        startSAXRecording();
+    }
+
+    /**
+     * Return the serialized xml string.
+     * @return A string containing the recorded xml information, formatted by
+     * the properties passed to the corresponding startSerializedXMLRecording().
+     */
+    public String endSerializedXMLRecording()
+    throws SAXException, ProcessingException {
+        XMLizable xml = endSAXRecording();
+        String text = XMLUtils.serialize(xml, (Properties) this.stack.pop());
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End serialized XML recording. XML=" + text);
+        }
+        return text;
+    }
+
+    /**
+     * Start recording of parameters.
+     * All events are not forwarded and the incoming xml is converted to
+     * parameters. Each toplevel node is a parameter and its text subnodes
+     * form the value.
+     * The Parameters can eiter be retrieved by endParametersRecording().
+     */
+    public void startParametersRecording()
+    throws SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start parameters recording");
+        }
+        addRecorder(new ParametersRecorder());
+        sendStartPrefixMapping();
+    }
+
+    /**
+     * End recording of parameters
+     * If source is null a new parameters object is created, otherwise
+     * the parameters are added to this object.
+     * @param source An optional parameters object.
+     * @return The object containing all parameters.
+     */
+    public SourceParameters endParametersRecording(Parameters source)
+    throws SAXException {
+        sendEndPrefixMapping();
+
+        ParametersRecorder recorder = (ParametersRecorder) this.removeRecorder();
+        SourceParameters parameters = recorder.getParameters(source);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End parameters recording. Parameters=" + parameters);
+        }
+        return parameters;
+    }
+
+    /**
+     * End recording of parameters
+     * If source is null a new parameters object is created, otherwise
+     * the parameters are added to this object.
+     * @param source An optional parameters object.
+     * @return The object containing all parameters.
+     */
+    public SourceParameters endParametersRecording(SourceParameters source)
+    throws SAXException {
+        sendEndPrefixMapping();
+
+        ParametersRecorder recorder = (ParametersRecorder) removeRecorder();
+        SourceParameters parameters = recorder.getParameters(source);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End parameters recording. Parameters=" + parameters);
+        }
+        return parameters;
+    }
+
+    /**
+     * Start DOM DocumentFragment recording.
+     * All incoming events are recorded and not forwarded. The resulting
+     * DocumentFragment can be obtained by the matching {@link #endRecording} call.
+     */
+    public void startRecording()
+    throws SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start recording");
+        }
+        DOMBuilder builder = new DOMBuilder(this.tfactory);
+        addRecorder(builder);
+        builder.startDocument();
+        builder.startElement("", "cocoon", "cocoon", EMPTY_ATTRIBUTES);
+        sendStartPrefixMapping();
+    }
+
+    /**
+     * Stop DOM DocumentFragment recording.
+     * This method returns the resulting DocumentFragment, normalized.
+     */
+    public DocumentFragment endRecording()
+    throws SAXException {
+        sendEndPrefixMapping();
+
+        DOMBuilder builder = (DOMBuilder) removeRecorder();
+        builder.endElement("", "cocoon", "cocoon");
+        builder.endDocument();
+
+        // Create Document Fragment
+        final Document doc = builder.getDocument();
+        final DocumentFragment fragment = doc.createDocumentFragment();
+        final Node root = doc.getDocumentElement();
+
+        // Remove empty text nodes and collapse neighbouring text nodes
+        root.normalize();
+
+        // Move all nodes into the fragment
+        boolean space = true;
+        while (root.hasChildNodes()) {
+            Node child = root.getFirstChild();
+            root.removeChild(child);
+
+            // Leave out leading whitespace nodes
+            // FIXME: Why leading spaces are trimmed at all? Why not trailing spaces?
+            if (space && child.getNodeType() == Node.TEXT_NODE
+                    && child.getNodeValue().trim().length() == 0) {
+                continue;
+            }
+            space = false;
+
+            fragment.appendChild(child);
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            Object serializedXML = null;
+            try {
+                serializedXML = fragment == null? "null": XMLUtils.serializeNode(fragment);
+            } catch (ProcessingException ignore) {
+                serializedXML = fragment;
+            }
+            getLogger().debug("End recording. Fragment=" + serializedXML);
+        }
+
+        return fragment;
+    }
+
+    //
+    // Hooks
+    //
+
+    /**
+     * Setup the transformation of an xml document.
+     * This method is called just before the transformation (sending of sax events)
+     * starts. It should be used to initialize setup parameter depending on the
+     * object modell.
+     */
+    public void setupTransforming()
+    throws IOException, ProcessingException, SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("setupTransforming");
+        }
+        this.stack.clear();
+        this.recorderStack.clear();
+        this.ignoreWhitespaces = true;
+        this.ignoreEmptyCharacters = false;
+    }
+
+    /**
+     * Start processing elements of our namespace.
+     * This hook is invoked for each sax event with our namespace.
+     * @param uri The namespace of the element.
+     * @param name The local name of the element.
+     * @param raw The qualified name of the element.
+     * @param attr The attributes of the element.
+     */
+    public void startTransformingElement(String uri,
+                                         String name,
+                                         String raw,
+                                         Attributes attr)
+    throws ProcessingException, IOException, SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.startElement(uri, name, raw, attr);
+        }
+    }
+
+    /**
+     * Start processing elements of our namespace.
+     * This hook is invoked for each sax event with our namespace.
+     * @param uri The namespace of the element.
+     * @param name The local name of the element.
+     * @param raw The qualified name of the element.
+     */
+    public void endTransformingElement(String uri,
+                                       String name,
+                                       String raw)
+    throws ProcessingException, IOException, SAXException {
+        if (this.ignoreEventsCount == 0) {
+            super.endElement(uri, name, raw);
+        }
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The characters event for the given text is send to the next
+     * component in the current pipeline.
+     * @param text The string containing the information.
+     */
+    public void sendTextEvent(String text)
+    throws SAXException {
+        characters(text.toCharArray(), 0, text.length());
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The startElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has no namespace and no attributes
+     * @param localname The name of the event.
+     */
+    public void sendStartElementEvent(String localname)
+    throws SAXException {
+        startElement("", localname, localname, EMPTY_ATTRIBUTES);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The startElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has the namespace of the transformer,
+     * but not attributes
+     * @param localname The name of the event.
+     */
+    public void sendStartElementEventNS(String localname)
+    throws SAXException {
+        startElement(this.namespaceURI,
+                     localname, this.ourPrefix + ':' + localname, EMPTY_ATTRIBUTES);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The startElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has no namespace.
+     * @param localname The name of the event.
+     * @param attr The Attributes of the element
+     */
+    public void sendStartElementEvent(String localname, Attributes attr)
+    throws SAXException {
+        startElement("", localname, localname, attr);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The startElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has the namespace of the transformer.
+     * @param localname The name of the event.
+     * @param attr The Attributes of the element
+     */
+    public void sendStartElementEventNS(String localname, Attributes attr)
+    throws SAXException {
+        startElement(this.namespaceURI,
+                     localname, this.ourPrefix + ':' + localname, attr);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The endElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has no namespace.
+     * @param localname The name of the event.
+     */
+    public void sendEndElementEvent(String localname)
+    throws SAXException {
+        endElement("", localname, localname);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The endElement event for the given element is send
+     * to the next component in the current pipeline.
+     * The element has the namespace of the transformer.
+     * @param localname The name of the event.
+     */
+    public void sendEndElementEventNS(String localname)
+    throws SAXException {
+        endElement(this.namespaceURI,
+                   localname, this.ourPrefix + ':' + localname);
+    }
+
+    /**
+     * Send SAX events to the next pipeline component.
+     * The node is parsed and the events are send to
+     * the next component in the pipeline.
+     * @param node The tree to be included.
+     */
+    public void sendEvents(Node node)
+    throws SAXException {
+        IncludeXMLConsumer.includeNode(node, this, this);
+    }
+
+    /**
+     * Send SAX events for the <code>SourceParameters</code>.
+     * For each parametername/value pair an element is
+     * created with the name of the parameter and the content
+     * of this element is the value.
+     */
+    public void sendParametersEvents(SourceParameters pars)
+    throws SAXException {
+        if (pars != null) {
+            Iterator names = pars.getParameterNames();
+            while (names.hasNext()) {
+                final String currentName = (String)names.next();
+                Iterator values = pars.getParameterValues(currentName);
+                while (values.hasNext()) {
+                    final String currentValue = (String)values.next();
+                    sendStartElementEvent(currentName);
+                    sendTextEvent(currentValue);
+                    sendEndElementEvent(currentName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Send all start prefix mapping events to the current content handler
+     */
+    protected void sendStartPrefixMapping()
+    throws SAXException {
+        final int l = this.namespaces.size();
+        for (int i = 0; i < l; i++) {
+            String[] prefixAndUri = (String[]) this.namespaces.get(i);
+            super.contentHandler.startPrefixMapping(prefixAndUri[0], prefixAndUri[1]);
+        }
+    }
+
+    /**
+     * Send all end prefix mapping events to the current content handler
+     */
+    protected void sendEndPrefixMapping()
+    throws SAXException {
+        final int l = this.namespaces.size();
+        for (int i = 0; i < l; i++) {
+            String[] prefixAndUri = (String[]) this.namespaces.get(i);
+            super.contentHandler.endPrefixMapping(prefixAndUri[0]);
+        }
+    }
+
+    /**
+     * Find prefix mapping for the given namespace URI.
+     * @return Prefix mapping or null if no prefix defined
+     */
+    protected String findPrefixMapping(String uri) {
+        final int l = this.namespaces.size();
+        for (int i = 0; i < l; i++) {
+            String[] prefixAndUri = (String[]) this.namespaces.get(i);
+            if (prefixAndUri[1].equals(uri)) {
+                return prefixAndUri[0];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Helper method to get a modifiable attribute set.
+     */
+    protected AttributesImpl getMutableAttributes(Attributes a) {
+        if ( a instanceof AttributesImpl && !(a instanceof ImmutableAttributesImpl)) {
+            return (AttributesImpl)a;
+        }
+        return new AttributesImpl(a);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractTransformer.java
new file mode 100644
index 0000000..4a33c8b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AbstractTransformer.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.cocoon.xml.AbstractXMLPipe;
+
+/**
+ *
+ * @version $Id$
+ */
+
+public abstract class AbstractTransformer extends AbstractXMLPipe implements Transformer {}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AugmentTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AugmentTransformer.java
new file mode 100644
index 0000000..4c17037
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/AugmentTransformer.java
@@ -0,0 +1,134 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+* @cocoon.sitemap.component.documentation
+ * Augments all <code>href</code> attributes with the full path to
+ * the request. You can optionally specify the <code>mount</code>
+ * parameter.
+ * 
+ * @cocoon.sitemap.component.name   augment
+ * @cocoon.sitemap.component.logger sitemap.transformer.augment
+ * 
+ * @since October 10, 2001
+ * @version $Id$
+ */
+public class AugmentTransformer
+    extends AbstractTransformer {
+        
+    protected Map objectModel;
+    protected Request request;
+    protected String baseURI;
+  
+    public void setup(SourceResolver resolver,
+                      Map objectModel,
+                      String source,
+                      Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        this.objectModel = objectModel;
+        this.request = ObjectModelHelper.getRequest( this.objectModel );
+    
+        String mountPoint = parameters.getParameter("mount", null);
+        
+        StringBuffer uribuf = new StringBuffer();
+        boolean isSecure = this.request.isSecure();
+        int port = this.request.getServerPort();
+    
+        if (isSecure) {
+            uribuf.append("https://");
+        } else {
+            uribuf.append("http://");
+        }
+        uribuf.append(request.getServerName());
+    
+        if (isSecure) {
+            if (port != 443) {
+                uribuf.append(":").append(port);
+            }
+        } else {
+            if (port != 80) {
+                uribuf.append(":").append(port);
+            }
+        }
+        if (mountPoint == null) {
+            String requestedURI = this.request.getRequestURI();
+            requestedURI = requestedURI.substring(0, requestedURI.lastIndexOf("/"));
+            uribuf.append(requestedURI);
+            uribuf.append("/");
+        } else {
+            uribuf.append(request.getContextPath());
+            uribuf.append("/");
+            uribuf.append(mountPoint);
+        }
+        this.baseURI = uribuf.toString();
+    }
+
+    public void startElement(String uri,
+                             String name,
+                             String qname,
+                             Attributes attrs)
+    throws SAXException {
+        AttributesImpl newAttrs = null;
+    
+        for (int i = 0, size = attrs.getLength(); i < size; i++) {
+            String attrName = attrs.getLocalName(i);
+            if (attrName.equals("href")) {
+                String value = attrs.getValue(i);
+
+                // Don't touch the attribute if it's an absolute URL
+                if (value.startsWith("http:") || value.startsWith("https:")) {
+                    continue;
+                }
+
+                if (newAttrs == null) {
+                    newAttrs = new AttributesImpl(attrs);
+                }
+
+                String newValue = baseURI + value;
+                newAttrs.setValue(i, newValue);
+            }
+        }
+
+        if (newAttrs == null) {
+            super.startElement(uri, name, qname, attrs);
+        } else {
+            super.startElement(uri, name, qname, newAttrs);
+        }
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        this.objectModel = null;
+        this.request = null;
+        this.baseURI = null;
+        super.recycle();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/CIncludeTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/CIncludeTransformer.java
new file mode 100644
index 0000000..ee46ca3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/CIncludeTransformer.java
@@ -0,0 +1,712 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.helpers.IncludeCacheManager;
+import org.apache.cocoon.transformation.helpers.IncludeCacheManagerSession;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceParameters;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.xml.dom.DOMParser;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * This transformer triggers for the element <code>include</code> in the
+ * namespace "http://apache.org/cocoon/include/1.0".
+ * The <code>src</code> attribute contains the url which points to
+ * an xml resource which is include instead of the element.
+ * With the attributes <code>element</code>, <code>ns</code> and
+ * <code>prefix</code> it is possible to specify an element
+ * which surrounds the included content.
+ *
+ * @cocoon.sitemap.component.name   cinclude
+ * @cocoon.sitemap.component.logger sitemap.transformer.cinclude
+ * @cocoon.sitemap.component.documentation.caching
+ *               See documentation for further information.
+ *
+ * @cocoon.sitemap.component.pooling.max  16
+ *
+ * This transformer also supports a more verbose but flexible version:
+ * <cinclude:includexml xmlns:cinclude="http://apache.org/cocoon/include/1.0" ignoreErrors="false">
+ *     <cinclude:src>THE SRC URI</cinclude:src>
+ *     <!-- This is an optional configuration block -->
+ *     <cinclude:configuration>
+ *         <!-- For example if you want to make a HTTP POST -->
+ *         <cinclude:parameter>
+ *             <cinclude:name>method</cinclude:name>
+ *             <cinclude:value>POST</cinclude:value>
+ *         </cinclude:parameter>
+ *     </cinclude:configuration>
+ *     <!-- The following are optional parameters appended to the URI -->
+ *     <cinclude:parameters>
+ *         <cinclude:parameter>
+ *             <cinclude:name>a name</cinclude:name>
+ *             <cinclude:value>a value</cinclude:value>
+ *         </cinclude:parameter>
+ *         <!-- more can follow -->
+ *     </cinclude:parameters>
+ * </cinclude:includexml>
+ *
+ *
+ * This transformer also supports caching of the included content.
+ * Therefore it triggers for the element <code>cached-include</code> in the
+ * namespace "http://apache.org/cocoon/include/1.0".
+ * The <code>src</code> attribute contains the url which points to
+ * an xml resource which is include instead of the element.
+ * First, it works like the usual include command. But it can be
+ * configured with various parameters:
+ * The most important one is the <code>expires</code> parameter.
+ * If (and only if) this is set to a value greater than zero,
+ * all included content is cached for the given period of time.
+ * So if any other request includes the same URI, the content
+ * is fetched from the cache. The expires value is in seconds.
+ * Usually the content is cached in the usual store, but you
+ * can also define a writeable source with the <code>source</code> parameter,
+ * e.g. "file:/c:/temp". Then the cached content is written into this
+ * directory.
+ * With the optional <code>purge</code> set to <code>true</code>
+ * the cache is purged which means the cached content is regarded as
+ * invalid nevertheless if it has expired or not.
+ * With the optional parameter <code>parallel</code> the various
+ * included contents are processed (included) in parallel rather than
+ * in a series.
+ * With the optional parameter <code>preemptive</code> set to <code>true</code>
+ * a pre-emptive caching is activated. When a resource is requested with
+ * pre-emptive caching, this transformer always attempts to get the
+ * content from the cache. If the content is not in the cache, it is
+ * of course retrieved from the original source and cached.
+ * If the cached resource has expired, it is still provided. The cache
+ * is updated by a background task. This task has to be started
+ * beforehand.
+ *
+ * @version $Id$
+ */
+public class CIncludeTransformer extends AbstractSAXTransformer
+                                 implements Disposable, CacheableProcessingComponent {
+
+    public static final String CINCLUDE_NAMESPACE_URI = "http://apache.org/cocoon/include/1.0";
+    public static final String CINCLUDE_INCLUDE_ELEMENT = "include";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE = "src";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE = "element";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE = "select";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE = "ns";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE = "prefix";
+    public static final String CINCLUDE_INCLUDE_ELEMENT_STRIP_ROOT_ATTRIBUTE = "strip-root";
+
+    public static final String CINCLUDE_INCLUDEXML_ELEMENT    = "includexml";
+    public static final String CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE = "ignoreErrors";
+    public static final String CINCLUDE_SRC_ELEMENT           = "src";
+    public static final String CINCLUDE_CONFIGURATION_ELEMENT = "configuration";
+    public static final String CINCLUDE_PARAMETERS_ELEMENT    = "parameters";
+    public static final String CINCLUDE_PARAMETER_ELEMENT     = "parameter";
+    public static final String CINCLUDE_NAME_ELEMENT          = "name";
+    public static final String CINCLUDE_VALUE_ELEMENT         = "value";
+
+    public static final String CINCLUDE_CACHED_INCLUDE_ELEMENT = "cached-include";
+    protected static final String CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT = "cached-includep";
+
+    private static final int STATE_OUTSIDE   = 0;
+    private static final int STATE_INCLUDE   = 1;
+
+    /** The configuration of includexml */
+    protected Parameters configurationParameters;
+
+    /** The parameters for includexml */
+    protected SourceParameters resourceParameters;
+
+    /** The current state: STATE_ */
+    protected int state;
+
+    protected IncludeCacheManager cacheManager;
+
+    protected IncludeCacheManagerSession cachingSession;
+
+    protected boolean compiling;
+
+    protected IncludeXMLConsumer filter;
+
+    protected AttributesImpl srcAttributes = new AttributesImpl();
+
+    protected boolean supportCaching;
+
+    /** Remember the start time of the request for profiling */
+    protected long startTime;
+
+    /**
+     * Constructor
+     * Set the namespace
+     */
+    public CIncludeTransformer() {
+        this.defaultNamespaceURI = CINCLUDE_NAMESPACE_URI;
+        this.removeOurNamespacePrefixes = true;
+    }
+
+    /**
+     * Setup the component.
+     */
+    public void setup(SourceResolver resolver, Map objectModel,
+                      String source, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, source, parameters);
+        this.state = STATE_OUTSIDE;
+        if ( null != this.cacheManager ) {
+            this.cachingSession = this.cacheManager.getSession( this.parameters );
+        }
+        this.compiling = false;
+        this.supportCaching = parameters.getParameterAsBoolean("support-caching", false);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Starting, session " + this.cachingSession);
+            this.startTime = System.currentTimeMillis();
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        if (this.manager.hasService(IncludeCacheManager.ROLE)) {
+            this.cacheManager = (IncludeCacheManager) this.manager.lookup(IncludeCacheManager.ROLE);
+        } else {
+            getLogger().warn("The cinclude transformer cannot find the IncludeCacheManager. " +
+                             "Therefore caching is turned off for the include transformer.");
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (null != this.manager) {
+            this.manager.release(this.cacheManager);
+            this.manager = null;
+        }
+        super.dispose();
+    }
+
+    /**
+     * Recycle the component
+     */
+    public void recycle() {
+        if ( null != this.cachingSession ) {
+            this.cacheManager.terminateSession( this.cachingSession );
+        }
+        this.cachingSession = null;
+
+        this.configurationParameters = null;
+        this.resourceParameters = null;
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Finishing, time: " +
+                              (System.currentTimeMillis() - this.startTime));
+            this.startTime = 0;
+        }
+        this.filter = null;
+
+        super.recycle();
+    }
+
+    /**
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startTransformingElement(String uri, String name, String raw, Attributes attr)
+    throws ProcessingException ,IOException, SAXException {
+        // Element: include
+        if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
+            String stripRootValue = attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_STRIP_ROOT_ATTRIBUTE);
+            boolean stripRoot = StringUtils.equals(stripRootValue, "true");
+
+            processCIncludeElement(attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE),
+                                   attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE),
+                                   attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE),
+                                   attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE),
+                                   attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE),
+                                   stripRoot,
+                                   false);
+
+        // Element: includexml
+        } else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT)
+                   && this.state == STATE_OUTSIDE) {
+            this.state = STATE_INCLUDE;
+            String ignoreErrors = attr.getValue("", CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE);
+            if (ignoreErrors == null || ignoreErrors.length() == 0) {
+                ignoreErrors = "false";
+            }
+            this.stack.push(BooleanUtils.toBooleanObject(this.ignoreEmptyCharacters));
+            this.stack.push(BooleanUtils.toBooleanObject(this.ignoreWhitespaces));
+            this.stack.push(ignoreErrors);
+
+            this.ignoreEmptyCharacters = false;
+            this.ignoreWhitespaces = true;
+
+        // target
+        } else if (name.equals(CINCLUDE_SRC_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            this.startTextRecording();
+
+        // configparameters
+        } else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            stack.push("end");
+
+        // parameters
+        } else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            stack.push("end");
+
+        // parameter
+        } else if (name.equals(CINCLUDE_PARAMETER_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+
+        // parameter name
+        } else if (name.equals(CINCLUDE_NAME_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            this.startTextRecording();
+
+        // parameter value
+        } else if (name.equals(CINCLUDE_VALUE_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            this.startSerializedXMLRecording(XMLUtils.createPropertiesForXML(true));
+
+       } else if (name.equals(CINCLUDE_CACHED_INCLUDE_ELEMENT)) {
+
+           String src = processCIncludeElement(attr.getValue("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE),
+                                               null,
+                                               null,
+                                               null,
+                                               null,
+                                               false,
+                                               this.cacheManager != null);
+           if (this.compiling) {
+               this.srcAttributes.addAttribute("", CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE, CINCLUDE_SRC_ELEMENT, "CDATA", src);
+               super.startTransformingElement(uri,
+                                              CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT,
+                                              raw + "p",
+                                              this.srcAttributes);
+               this.srcAttributes.clear();
+           }
+        } else {
+            super.startTransformingElement(uri, name, raw, attr);
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endTransformingElement(String uri, String name, String raw)
+    throws ProcessingException, IOException, SAXException {
+        if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
+            // do nothing
+            return;
+
+        } else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            // Element: includexml
+
+            this.state = STATE_OUTSIDE;
+
+            final String resource = (String)stack.pop();
+
+            final boolean ignoreErrors = stack.pop().equals("true");
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Processing includexml element: src=" + resource
+                              + ", ignoreErrors=" + ignoreErrors
+                              + ", configuration=" + this.configurationParameters
+                              + ", parameters=" + this.resourceParameters);
+            }
+            Source source = null;
+
+            try {
+                source = SourceUtil.getSource(resource,
+                                              this.configurationParameters,
+                                              this.resourceParameters,
+                                              this.resolver);
+
+                XMLByteStreamCompiler serializer = null;
+                XMLByteStreamInterpreter deserializer = null;
+                try {
+                    if ( ignoreErrors ) {
+                        serializer = new XMLByteStreamCompiler();
+                        deserializer = new XMLByteStreamInterpreter();
+                        SourceUtil.toSAX(source, serializer, this.configurationParameters, true);
+                        deserializer.setConsumer( this.xmlConsumer );
+                        deserializer.deserialize( serializer.getSAXFragment() );
+                    } else {
+                        SourceUtil.toSAX(source, this.xmlConsumer, this.configurationParameters, true);
+                    }
+                } catch (ProcessingException pe) {
+                    if (!ignoreErrors) throw pe;
+                }
+            } catch (SourceException se) {
+                if (!ignoreErrors) throw SourceUtil.handle(se);
+            } catch (SAXException se) {
+                if (!ignoreErrors) throw se;
+            } catch (IOException ioe) {
+                if (!ignoreErrors) throw ioe;
+            } finally {
+                this.resolver.release(source);
+            }
+
+            // restore values
+            this.ignoreWhitespaces = ((Boolean)stack.pop()).booleanValue();
+            this.ignoreEmptyCharacters = ((Boolean)stack.pop()).booleanValue();
+
+        // src element
+        } else if (name.equals(CINCLUDE_SRC_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+
+            this.stack.push(this.endTextRecording());
+
+        } else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT)
+                   && this.state == STATE_INCLUDE) {
+            this.resourceParameters = new SourceParameters();
+            // Now get the parameters off the stack
+            String label = (String)stack.pop();
+            String key = null;
+            String value = null;
+            while (!label.equals("end")) {
+                if (label.equals("name")) key = (String)stack.pop();
+                if (label.equals("value")) value = (String)stack.pop();
+                if (key != null && value != null) {
+                    this.resourceParameters.setParameter(key, value);
+                    key = null;
+                    value = null;
+                }
+                label = (String)stack.pop();
+            }
+
+        } else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT) == true
+                 && this.state == STATE_INCLUDE) {
+            this.configurationParameters = new Parameters();
+            // Now get the parameters off the stack
+            String label = (String)stack.pop();
+            String key = null;
+            String value = null;
+            while (!label.equals("end")) {
+                if (label.equals("name")) key = (String)stack.pop();
+                if (label.equals("value")) value = (String)stack.pop();
+                if (key != null && value != null) {
+                    this.configurationParameters.setParameter(key, value);
+                    key = null;
+                    value = null;
+                }
+                label = (String)stack.pop();
+            }
+
+        } else if (name.equals(CINCLUDE_PARAMETER_ELEMENT) == true
+                   && this.state == STATE_INCLUDE) {
+
+        } else if (name.equals(CINCLUDE_NAME_ELEMENT) == true
+                   && this.state == STATE_INCLUDE) {
+            stack.push(this.endTextRecording());
+            stack.push("name");
+
+        // parameter value
+        } else if (name.equals(CINCLUDE_VALUE_ELEMENT) == true
+                   && this.state == STATE_INCLUDE) {
+            stack.push(this.endSerializedXMLRecording());
+            stack.push("value");
+
+        } else if (name.equals(CINCLUDE_CACHED_INCLUDE_ELEMENT)) {
+            if (this.compiling) {
+               super.endTransformingElement(uri,
+                                            CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT,
+                                            raw + "p");
+            }
+            // do nothing else
+        } else {
+            super.endTransformingElement(uri, name, raw);
+        }
+    }
+
+    protected String processCIncludeElement(String src, String element,
+                                            String select, String ns, String prefix,
+                                            boolean stripRoot,
+                                            boolean cache)
+    throws SAXException, IOException {
+
+        if (src == null) {
+            throw new SAXException("Missing 'src' attribute on cinclude:include element");
+        }
+
+        if (element == null) element="";
+        if (select == null) select="";
+        if (ns == null) ns="";
+        if (prefix == null) prefix="";
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Processing include element: src=" + src
+                          + ", element=" + element
+                          + ", select=" + select
+                          + ", ns=" + ns
+                          + ", prefix=" + prefix
+                          + ", stripRoot=" + stripRoot
+                          + ", caching=" + cache);
+        }
+
+        if (cache) {
+            src = this.cacheManager.load(src, this.cachingSession);
+
+            if (this.cachingSession.isParallel() && !this.cachingSession.isPreemptive()) {
+                if (!this.compiling) {
+                    this.compiling = true;
+                    this.startCompiledXMLRecording();
+                }
+            } else {
+                this.cacheManager.stream(src, this.cachingSession, this.filter);
+            }
+
+            return src;
+        }
+
+        // usual no caching stuff
+        if (!"".equals(element)) {
+            if (!ns.equals("")) {
+                super.startPrefixMapping(prefix, ns);
+            }
+            super.startElement(ns,
+                               element,
+                               (!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element),
+                               XMLUtils.EMPTY_ATTRIBUTES);
+        }
+
+        Source source = null;
+        try {
+            source = this.resolver.resolveURI(src);
+
+            if (!"".equals(select)) {
+
+
+                DOMParser parser = null;
+                XPathProcessor processor = null;
+
+                try {
+                    parser = (DOMParser)this.manager.lookup(DOMParser.ROLE);
+                    processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
+
+                    InputSource input = SourceUtil.getInputSource(source);
+
+                    Document document = parser.parseDocument(input);
+                    NodeList list = processor.selectNodeList(document, select);
+                    int length = list.getLength();
+                    for (int i=0; i<length; i++) {
+                          IncludeXMLConsumer.includeNode(list.item(i),
+                                               this.filter,
+                                               this.filter);
+                    }
+                } finally {
+                    this.manager.release(parser);
+                    this.manager.release(processor);
+                }
+            } else {
+                String mimeType = null;
+                if (null != this.configurationParameters) {
+                    mimeType = this.configurationParameters.getParameter("mime-type", mimeType);
+                }
+                if (this.compiling) {
+                    SourceUtil.toSAX(source, mimeType, new IncludeXMLConsumer(this.contentHandler, this.lexicalHandler));
+                } else {
+                    this.filter.setIgnoreRootElement(stripRoot);
+                    SourceUtil.toSAX(source, mimeType, this.filter);
+                }
+            }
+
+        } catch (SourceException se) {
+            throw new SAXException("Exception in CIncludeTransformer",se);
+        } catch (IOException e) {
+            throw new SAXException("CIncludeTransformer could not read resource", e);
+        } catch (ProcessingException e){
+            throw new SAXException("Exception in CIncludeTransformer",e);
+        } catch(ServiceException e) {
+            throw new SAXException(e);
+        } finally {
+            this.resolver.release(source);
+        }
+
+        if (!"".equals(element)) {
+            super.endElement(ns, element, (!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element));
+            if (!ns.equals("")) {
+                super.endPrefixMapping(prefix);
+            }
+        }
+        return src;
+    }
+
+    /**
+     * Start recording of compiled xml.
+     * The incomming SAX events are recorded and a compiled representation
+     * is created. These events are not forwarded to the next component in
+     * the pipeline.
+     */
+    protected void startCompiledXMLRecording()
+    throws SAXException {
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("BEGIN startCompiledXMLRecording");
+        }
+
+        this.addRecorder(new XMLByteStreamCompiler());
+
+        if (this.getLogger().isDebugEnabled()) {
+           this.getLogger().debug("END startCompiledXMLRecording");
+        }
+    }
+
+    /**
+     * Stop recording of compiled XML.
+     * @return The compiled XML.
+     */
+    protected Object endCompiledXMLRecording()
+    throws SAXException {
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("BEGIN endCompiledXMLRecording");
+        }
+
+        XMLByteStreamCompiler recorder = (XMLByteStreamCompiler)this.removeRecorder();
+        Object text = recorder.getSAXFragment();
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("END endCompiledXMLRecording text="+text);
+        }
+        return text;
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        this.filter = new MyFilter(this.xmlConsumer,
+                                   this);
+        super.startDocument();
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument() throws SAXException {
+        if ( this.compiling ) {
+            Object compiledXML = this.endCompiledXMLRecording();
+            XMLByteStreamInterpreter deserializer = new XMLByteStreamInterpreter();
+            deserializer.setConsumer(this.filter);
+            deserializer.deserialize(compiledXML);
+        }
+        super.endDocument();
+    }
+
+    /**
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
+     */
+    public Serializable getKey() {
+        if (this.supportCaching
+            && null != this.cacheManager
+            && this.cachingSession.getExpires() > 0) {
+            return "1";
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
+     */
+    public SourceValidity getValidity() {
+        if (this.supportCaching
+            && null != this.cacheManager
+            && this.cachingSession.getExpires() > 0
+            && !this.cachingSession.isPurging()) {
+            return this.cachingSession.getExpiresValidity();
+        }
+        return null;
+    }
+
+}
+
+final class MyFilter extends IncludeXMLConsumer {
+
+    private final CIncludeTransformer transformer;
+
+    /**
+     * This filter class post-processes the parallel fetching
+     * @param consumer
+     */
+    public MyFilter(XMLConsumer consumer,
+                    CIncludeTransformer transformer) {
+        super(consumer);
+        this.transformer = transformer;
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endElement(String uri, String local, String qName)
+    throws SAXException {
+        if (uri != null
+            && uri.equals(CIncludeTransformer.CINCLUDE_NAMESPACE_URI)
+            && local.equals(CIncludeTransformer.CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT)) {
+            // this is the placeholder element: do nothing
+        } else {
+            super.endElement(uri, local, qName);
+        }
+    }
+
+    /**
+     * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startElement(String uri,
+                                String local,
+                                String qName,
+                                Attributes attr)
+    throws SAXException {
+        if (uri != null
+            && uri.equals(CIncludeTransformer.CINCLUDE_NAMESPACE_URI)
+            && local.equals(CIncludeTransformer.CINCLUDE_CACHED_INCLUDE_PLACEHOLDER_ELEMENT)) {
+            // this is a placeholder
+            try {
+                final String src = attr.getValue("",CIncludeTransformer.CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE);
+                this.transformer.cacheManager.stream(src, this.transformer.cachingSession, this);
+            } catch (IOException ioe) {
+                throw new SAXException("IOException", ioe);
+            }
+        } else {
+            super.startElement(uri, local, qName, attr);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/EncodeURLTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/EncodeURLTransformer.java
new file mode 100644
index 0000000..7b469d2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/EncodeURLTransformer.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.util.ElementAttributeMatching;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.apache.regexp.RESyntaxException;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The encodeURL transformer emits encoded URLs.
+ * 
+ * @cocoon.sitemap.component.name   encodeurl
+ * @cocoon.sitemap.component.logger sitemap.transformer.encodeURL
+ * @cocoon.sitemap.component.documentation.caching
+ *               TBD
+ * 
+ * @cocoon.sitemap.component.pooling.max  32
+ * 
+ * The encodeURL transformer emits encoded URLs.
+ * <p>
+ *   This transformer applies encodeURL method to URLs.
+ *   You may want to use this transform to avoid doing the manually
+ *   encodeURL() calls.
+ * </p>
+ * <p>
+ *   Usually this transformer is appended as last transformer before
+ *   the serialization process. In this case it is possible to encode
+ *   URLs introduced in the generator, and xslt transformer phase.
+ * </p>
+ * <p>
+ *   You can specify which attributes hold URL values in order to restrict
+ *   URL rewriting to specific attributes only.
+ * </p>
+ * <p>
+ * Usage in a sitemap:
+ * </p>
+ * <pre><tt>
+ *   &lt;map:composition&gt;
+ *   ...
+ *     &lt;map:transformers&gt;
+ *     ...
+ *       &lt;map:transformer type=&quot;encodeURL&quot;
+ *         src=&quot;org.apache.cocoon.optional.transformation.EncodeURLTransformer&quot;&gt;
+ *         &lt;exclude-name&gt;img/@src|a/@href=.&amp;asterik;adserver&lt;/exclude-name&gt;
+ *         &lt;include-name&gt;.&amp;asterik;/@href|.&amp;asterik;/@src|.&amp;asterik;/@action&lt;/include-name&gt;
+ *       &lt;/map:transformer&gt;
+ *   ...
+ *   &lt;map:pipelines&gt;
+ *     &lt;map:pipeline&gt;
+ *       ...
+ *       &lt;map:transform type=&quot;encodeURL&quot;/&gt;
+ *       ...
+ * </pre></tt>
+ *
+ * @version $Id$
+ */
+public class EncodeURLTransformer
+  extends AbstractTransformer
+  implements Configurable, CacheableProcessingComponent {
+
+    /**
+     * Configuration name for specifying excluding patterns,
+     * ie exclude-name.
+     */
+    public final static String EXCLUDE_NAME = "exclude-name";
+
+    /**
+     * Configuration name for specifying including patterns,
+     * ie include-name.
+     */
+    public final static String INCLUDE_NAME = "include-name";
+
+    /**
+     * Configuration default exclude pattern,
+     * ie img/@src
+     */
+    public final static String EXCLUDE_NAME_DEFAULT = "img/@src";
+
+    /**
+     * Configuration default exclude pattern,
+     * ie .*\/@href|.*\/@action|frame/@src
+     */
+    public final static String INCLUDE_NAME_DEFAULT = ".*/@href|.*/@action|frame/@src";
+
+    private String includeNameConfigure = INCLUDE_NAME_DEFAULT;
+    private String excludeNameConfigure = EXCLUDE_NAME_DEFAULT;
+
+    private ElementAttributeMatching elementAttributeMatching;
+    private Response response;
+    private boolean isEncodeURLNeeded;
+    private Session session;
+
+    /**
+     * check if encoding of URLs is neccessary.
+     * 
+     * This is true if session object exists, and session-id   
+     * was provided from URL, or session is new.
+     * The result is stored in some instance variables
+     */
+    protected void checkForEncoding(Request request) {
+        this.session = request.getSession(false);
+        this.isEncodeURLNeeded = false;
+        
+        if ( null != this.session ) {
+            // do encoding if session id is from URL, or the session is new, 
+            // fixes BUG #13855, due to paint007@mc.duke.edu
+            if ( request.isRequestedSessionIdFromURL() || this.session.isNew()) {
+                this.isEncodeURLNeeded = true;
+            }
+        }
+    }
+
+    /**
+     * Setup the transformer.
+     * <p>
+     *   Setup include, and exclude patterns from the parameters
+     * </p>
+     *
+     * @param resolver source resolver
+     * @param objectModel sitemap objects
+     * @param parameters request parameters
+     *
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+
+        this.checkForEncoding(ObjectModelHelper.getRequest(objectModel));
+        
+        if (this.isEncodeURLNeeded) {
+            this.response = ObjectModelHelper.getResponse(objectModel);
+
+            // don't check if URL encoding is needed now, as
+            // a generator might create a new session 
+            final String includeName = parameters.getParameter(INCLUDE_NAME,
+                                                               this.includeNameConfigure);
+            final String excludeName = parameters.getParameter(EXCLUDE_NAME,
+                                                               this.excludeNameConfigure);
+            try {
+                this.elementAttributeMatching = new ElementAttributeMatching(includeName, excludeName);
+            } catch (RESyntaxException reex) {
+                final String message = "Cannot parse include-name: " + includeName + " " +
+                    "or exclude-name: " + excludeName + "!";
+                throw new ProcessingException(message, reex);
+            }
+        }
+    }
+
+
+    /**
+     * BEGIN SitemapComponent methods
+     *
+     * @param  configuration               Description of Parameter
+     * @exception  ConfigurationException  Description of Exception
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        Configuration child;
+
+        child = configuration.getChild(INCLUDE_NAME);
+        this.includeNameConfigure = child.getValue(INCLUDE_NAME_DEFAULT);
+
+        child = configuration.getChild(EXCLUDE_NAME);
+        this.excludeNameConfigure = child.getValue(EXCLUDE_NAME_DEFAULT);
+
+        if (this.includeNameConfigure == null) {
+            String message = "Configure " + INCLUDE_NAME + "!";
+            throw new ConfigurationException(message);
+        }
+        if (this.excludeNameConfigure == null) {
+            String message = "Configure " + EXCLUDE_NAME + "!";
+            throw new ConfigurationException(message);
+        }
+    }
+
+
+    /**
+     * Recycle resources of this transformer
+     */
+    public void recycle() {
+        super.recycle();
+        this.response = null;
+        this.session = null;
+        this.elementAttributeMatching = null;
+    }
+
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public java.io.Serializable getKey() {
+        if (this.isEncodeURLNeeded) {
+            return null;
+        } else {
+            return "1";
+        }
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        if (this.isEncodeURLNeeded) {
+            return null;
+        } else {
+            return NOPValidity.SHARED_INSTANCE;
+        }
+    }
+
+    /**
+     * Start parsing an element
+     *
+     * @param  uri               of the element
+     * @param  name              of the element
+     * @param  raw               name of the element
+     * @param  attributes        list
+     * @exception  SAXException  Description of Exception
+     */
+    public void startElement(String uri, String name, String raw, Attributes attributes)
+    throws SAXException {
+        if (this.isEncodeURLNeeded && this.elementAttributeMatching != null) {
+            String lname = name;
+            if (attributes != null && attributes.getLength() > 0) {
+                AttributesImpl new_attributes = new AttributesImpl(attributes);
+                for (int i = 0; i < new_attributes.getLength(); i++) {
+                    String attr_lname = new_attributes.getLocalName(i);
+
+                    String value = new_attributes.getValue(i);
+
+                    if (elementAttributeMatching.matchesElementAttribute(lname, attr_lname, value)) {
+                        // don't use simply this.response.encodeURL(value)
+                        // but be more smart about the url encoding
+                        final String new_value = this.encodeURL(value);
+                        if (getLogger().isDebugEnabled()) {
+                            this.getLogger().debug("element/@attribute matches: " + name + "/@" + attr_lname);
+                            this.getLogger().debug("encodeURL: " + value + " -> " + new_value);
+                        }
+                        new_attributes.setValue(i, new_value);
+                    }
+                }
+                // parent handles element using encoded attribute values
+                super.contentHandler.startElement(uri, name, raw, new_attributes);
+                return;
+            }
+        }
+        // no match, parent handles element as-is
+        super.contentHandler.startElement(uri, name, raw, attributes);
+    }
+
+    /**
+     * Do the URL rewriting.
+     * <p>
+     *   Check if <code>url</code> contains already the sessionid, some servlet-engines
+     *   just appends the session-id without checking if the sessionid is already present.
+     * </p>
+     *
+     * @param  url       the URL probably without sessionid.
+     * @return           String the original url inclusive the sessionid
+     */
+    private String encodeURL(String url) {
+        String encoded_url;
+        if (this.response != null) {
+            // As some servlet-engine does not check if url has been already rewritten
+            if (this.session != null && url.indexOf(this.session.getId()) > -1) {
+                // url contains already the session id encoded
+                encoded_url = url;
+            } else {
+                // do encode the session id
+                encoded_url = this.response.encodeURL(url);
+            }
+        } else {
+            encoded_url = url;
+        }
+        return encoded_url;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FilterTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FilterTransformer.java
new file mode 100644
index 0000000..86248fa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FilterTransformer.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The filter transformer can be used to let only an amount of elements through in
+ * a given block.
+ * 
+ * @cocoon.sitemap.component.name   filter
+ * @cocoon.sitemap.component.documentation.caching TBD
+ * @cocoon.sitemap.component.logger sitemap.transformer.filter
+ * 
+ * 
+ * The filter transformer can be used to let only an amount of elements through in
+ * a given block.
+ *
+ * <p>Usage in the sitemap:
+ *    &lt;map:transform type="filter"&gt;
+ *     &lt;map:parameter name="element-name" value="row"/&gt;
+ *     &lt;map:parameter name="count" value="5"/&gt;
+ *     &lt;map:parameter name="blocknr" value="3"/&gt;
+ *    &lt;/map:transform&gt;
+ *
+ * <p>Only the 3rd block will be shown, containing only 5 row elements.
+ *
+ * <p><b>Known limitation: behaviour of transformer when trigger elements are nested
+ * is not predictable.</b>
+ *
+ * @version $Id$
+ */
+public class FilterTransformer
+extends AbstractTransformer
+implements CacheableProcessingComponent {
+    
+    private static final String ELEMENT = "element-name";
+    private static final String COUNT = "count";
+    private static final String BLOCKNR = "blocknr";
+    private static final String BLOCK = "block";
+    private static final String BLOCKID = "id";
+    private static final int DEFAULT_COUNT = 10;
+    private static final int DEFAULT_BLOCK = 1;
+    
+    protected int counter;
+    protected int count;
+    protected int blocknr;
+    protected int currentBlocknr;
+    protected String elementName;
+    protected String parentName;
+    protected boolean skip;
+    protected boolean foundIt;
+    
+    /** BEGIN SitemapComponent methods **/
+    public void setup(SourceResolver resolver,
+    Map objectModel,
+    String source,
+    Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        this.counter=0;
+        this.currentBlocknr=0;
+        this.skip=false;
+        this.foundIt=false;
+        this.parentName=null;
+        this.elementName = parameters.getParameter(ELEMENT, "");
+        this.count = parameters.getParameterAsInteger(COUNT, DEFAULT_COUNT);
+        this.blocknr = parameters.getParameterAsInteger(BLOCKNR, DEFAULT_BLOCK);
+        if (this.elementName == null || this.elementName.equals("") || this.count == 0)  {
+            throw new ProcessingException("FilterTransformer: both "+ ELEMENT + " and " +
+            COUNT + " parameters need to be specified");
+        }
+    }
+    
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     * This method must be invoked before the generateValidity() method.
+     *
+     * @return The generated key or <code>0</code> if the component
+     *              is currently not cacheable.
+     */
+    public java.io.Serializable getKey() {
+        return this.elementName + '<' + this.count + '>' + this.blocknr;
+    }
+    
+    /**
+     * Generate the validity object.
+     * Before this method can be invoked the generateKey() method
+     * must be invoked.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+    
+    /** BEGIN SAX ContentHandler handlers **/
+    public void startElement(String uri, String name, String raw, Attributes attributes)
+    throws SAXException {
+        if (name.equalsIgnoreCase(elementName)) {
+            this.foundIt = true;
+            this.counter++;
+            if (this.counter <= (this.count*(this.blocknr)) && this.counter > (this.count*(this.blocknr-1))) {
+                this.skip = false;
+            } else  {
+                this.skip = true;
+            }
+            if (this.currentBlocknr != (int)Math.ceil((float)this.counter/this.count)) {
+                this.currentBlocknr = (int)Math.ceil((float)this.counter/this.count);
+                AttributesImpl attr = new AttributesImpl();
+                attr.addAttribute("", BLOCKID, BLOCKID, "CDATA", String.valueOf(this.currentBlocknr));
+                if (this.counter < this.count)  {
+                    super.contentHandler.startElement("", BLOCK, BLOCK, attr);
+                } else  {
+                    // fix Bugzilla Bug 13904, check if counter == 1
+                    // in this case there is no startElement("", BLOCK, BLOCK)
+                    // written, yet
+                    if (this.counter > 1) {
+                        super.contentHandler.endElement("", BLOCK, BLOCK);
+                    }
+                    super.contentHandler.startElement("", BLOCK, BLOCK, attr);
+                }
+            }
+        } else if (!this.foundIt)  {
+            this.parentName = name;
+        }
+        if (!this.skip)  {
+            super.contentHandler.startElement(uri,name,raw,attributes);
+        }
+    }
+    
+    public void endElement(String uri,String name,String raw)
+    throws SAXException  {
+        if (this.foundIt && name.equals(this.parentName)) {
+            // FIXME: VG: This will fail on XML like:
+            // <parent>
+            //   <element>
+            //     <parent>
+            super.contentHandler.endElement("", BLOCK, BLOCK);
+            super.contentHandler.endElement(uri, name, raw);
+            this.foundIt = false;
+            this.skip = false;
+        } else if (!this.skip)  {
+            super.contentHandler.endElement(uri,name,raw);
+        }
+    }
+    
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        if (!this.skip)  {
+            super.contentHandler.characters(c,start,len);
+        }
+    }
+    
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        if (!this.skip)  {
+            super.contentHandler.processingInstruction(target, data);
+        }
+    }
+    
+    public void startEntity(String name)
+    throws SAXException {
+        if (!this.skip)  {
+            super.lexicalHandler.startEntity(name);
+        }
+    }
+    
+    public void endEntity(String name)
+    throws SAXException {
+        if (!this.skip)  {
+            super.lexicalHandler.endEntity( name);
+        }
+    }
+    
+    public void startCDATA()
+    throws SAXException {
+        if (!this.skip)  {
+            super.lexicalHandler.startCDATA();
+        }
+    }
+    
+    public void endCDATA()
+    throws SAXException {
+        if (!this.skip)  {
+            super.lexicalHandler.endCDATA();
+        }
+    }
+    
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        if (!this.skip)  {
+            super.lexicalHandler.comment(ch, start, len);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FragmentExtractorTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FragmentExtractorTransformer.java
new file mode 100644
index 0000000..4f4767e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/FragmentExtractorTransformer.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.HashUtil;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.apache.excalibur.store.Store;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * The transformation half of the FragmentExtractor.
+ *
+ * This transformer recieves an incoming stream of xml and replaces
+ * fragments with an fragment extractor locator pointing to the fragments.
+ *
+ * The extracted fragments are identified by their element name and namespace URI.
+ * The default is to extract SVG images ("svg" elements in namespace
+ * "http://www.w3.org/2000/svg"), but this can be overriden in the configuration:
+ * <pre>
+ *   &lt;extract-uri&gt;http://my/namespace/uri&lt;/extract-uri&gt;
+ *   &lt;extract-element&gt;my-element&lt;/extract-element&gt;
+ * </pre>
+ *
+ * Fragment extractor locator format is following:
+ * <pre>
+ *   &lt;fe:fragment xmlns:fe="http://apache.org/cocoon/fragmentextractor/2.0" fragment-id="..."/&gt;
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class FragmentExtractorTransformer extends AbstractTransformer
+    implements CacheableProcessingComponent, Configurable, Serviceable, Disposable, Recyclable {
+
+    public static final String FE_URI = "http://apache.org/cocoon/fragmentextractor/2.0";
+
+    private static final String EXTRACT_URI_NAME = "extract-uri";
+    private static final String EXTRACT_ELEMENT_NAME = "extract-element";
+
+    private static final String EXTRACT_URI = "http://www.w3.org/2000/svg";
+    private static final String EXTRACT_ELEMENT = "svg";
+
+    private String extractURI;
+    private String extractElement;
+
+    /** The ServiceManager instance */
+    protected ServiceManager manager;
+
+    private XMLByteStreamCompiler serializer;
+
+    private Map prefixMap;
+
+    private int extractLevel;
+
+    private int fragmentID;
+
+    private String requestURI;
+
+    /**
+     * Configure this transformer.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        this.extractURI = conf.getChild(EXTRACT_URI_NAME).getValue(EXTRACT_URI);
+        this.extractElement = conf.getChild(EXTRACT_ELEMENT_NAME).getValue(EXTRACT_ELEMENT);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Extraction URI is " + this.extractURI);
+            getLogger().debug("Extraction element is " + this.extractElement);
+        }
+    }
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Recycle this component
+     */
+    public void recycle() {
+        this.serializer = null;
+        super.recycle();        
+    }
+
+    /**
+     * Release all resources.
+     */
+    public void dispose() {
+        recycle();
+        this.manager = null;
+    }
+
+    /**
+     * Setup the transformer.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        extractLevel = 0;
+        fragmentID = 0;
+        prefixMap = new HashMap();
+
+        this.requestURI = ObjectModelHelper.getRequest(objectModel).getSitemapURI();
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return "1"
+     */
+    public Serializable getKey() {
+        return "1";
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return NOPValidity object
+     *         - if the input is valid the output is valid as well.
+     */
+    public SourceValidity getValidity() {
+        return NOPValidity.SHARED_INSTANCE;
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startPrefixMapping(prefix, uri);
+            prefixMap.put(prefix, uri);
+        } else {
+            this.serializer.startPrefixMapping(prefix, uri);
+        }
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     *
+     * @param prefix The prefix that was being mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endPrefixMapping(prefix);
+            prefixMap.remove(prefix);
+        } else {
+            this.serializer.endPrefixMapping(prefix);
+        }
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        if (uri == null) uri = "";
+        if (this.extractURI.equals(uri) && this.extractElement.equals(loc)) {
+            extractLevel++;
+            fragmentID++;
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("extractLevel now " + extractLevel + ".");
+            }
+
+            this.serializer = new XMLByteStreamCompiler();
+
+            // Start the DOM document
+            this.serializer.startDocument();
+
+            Iterator itt = prefixMap.entrySet().iterator();
+            while (itt.hasNext()) {
+                Map.Entry entry = (Map.Entry)itt.next();
+                this.serializer.startPrefixMapping(
+                    (String)entry.getKey(),
+                    (String)entry.getValue()
+                );
+            }
+        }
+
+        if (extractLevel == 0) {
+            super.startElement(uri, loc, raw, a);
+        } else {
+            this.serializer.startElement(uri, loc, raw, a);
+        }
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endElement(uri, loc, raw);
+        } else {
+            this.serializer.endElement(uri, loc, raw);
+            if (uri == null) uri = "";
+            if (this.extractURI.equals(uri) && this.extractElement.equals(loc)) {
+                extractLevel--;
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("extractLevel now " + extractLevel + ".");
+                }
+
+                if (extractLevel == 0) {
+                    // finish building the fragment. remove existing prefix mappings.
+                    Iterator itt = prefixMap.entrySet().iterator();
+                    while (itt.hasNext()) {
+                        Map.Entry entry = (Map.Entry) itt.next();
+                        this.serializer.endPrefixMapping(
+                            (String)entry.getKey()
+                        );
+                    }
+                    this.serializer.endDocument();
+
+                    Store store = null;
+                    String id = Long.toHexString((hashCode()^HashUtil.hash(requestURI)) + fragmentID);
+                    try {
+                        store = (Store) this.manager.lookup(Store.TRANSIENT_STORE);
+                        store.store(id, this.serializer.getSAXFragment());
+                    } catch (ServiceException se) {
+                        throw new SAXException("Could not lookup for transient store.", se);
+                    } catch (IOException ioe) {
+                        throw new SAXException("Could not store fragment.", ioe);
+                    } finally {
+                        this.manager.release(store);
+                        this.manager.release(this.serializer);
+                        this.serializer = null;
+                    }
+
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Stored document " + id + ".");
+                    }
+
+                    // Insert ref.
+                    super.startPrefixMapping("fe", FE_URI);
+                    AttributesImpl atts = new AttributesImpl();
+                    atts.addAttribute("", "fragment-id", "fragment-id", "CDATA", id);
+                    super.startElement(FE_URI, "fragment", "fe:fragment", atts);
+                    super.endElement(FE_URI, "fragment", "fe:fragment");
+                    super.endPrefixMapping("fe");
+                }
+            }
+        }
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.characters(c, start, len);
+        } else {
+            this.serializer.characters(c, start, len);
+        }
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.ignorableWhitespace(c, start, len);
+        } else {
+            this.serializer.ignorableWhitespace(c, start, len);
+        }
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if none was
+     *             supplied.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.processingInstruction(target, data);
+        } else {
+            this.serializer.processingInstruction(target, data);
+        }
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity.  If it is a  parameter
+     *             entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.skippedEntity(name);
+        } else {
+            this.serializer.skippedEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external DTD
+     *                 subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external DTD
+     *                 subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startDTD(name, publicId, systemId);
+        } else {
+            throw new SAXException(
+                "Recieved startDTD after beginning fragment extraction process."
+            );
+        }
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endDTD();
+        } else {
+            throw new SAXException(
+                "Recieved endDTD after beginning fragment extraction process."
+            );
+        }
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     * @param name The name of the entity. If it is a parameter entity, the
+     *             name will begin with '%'.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startEntity(name);
+        } else {
+            this.serializer.startEntity(name);
+        }
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endEntity(name);
+        } else {
+            this.serializer.endEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.startCDATA();
+        } else {
+            this.serializer.startCDATA();
+        }
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.endCDATA();
+        } else {
+            this.serializer.endCDATA();
+        }
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        if (extractLevel == 0) {
+            super.comment(ch, start, len);
+        } else {
+            this.serializer.comment(ch, start, len);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/I18nTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/I18nTransformer.java
new file mode 100644
index 0000000..7461352
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/I18nTransformer.java
@@ -0,0 +1,2260 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.treeprocessor.variables.VariableExpressionTokenizer;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolver;
+import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.i18n.Bundle;
+import org.apache.cocoon.i18n.BundleFactory;
+import org.apache.cocoon.i18n.I18nUtils;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.xml.ParamSaxBuffer;
+import org.apache.cocoon.xml.SaxBuffer;
+
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Internationalization transformer is used to transform i18n markup into text
+ * based on a particular locale.
+ *
+ * @cocoon.sitemap.component.name   i18n
+ * @cocoon.sitemap.component.documentation.caching TBD
+ * @cocoon.sitemap.component.logger sitemap.transformer.i18n
+ *
+ * <h3>i18n transformer</h3>
+ * <p>The i18n transformer works by finding a translation for the user's locale
+ * in the configured catalogues. Locale is determined based on the request,
+ * session, or a cookie data. See {@link org.apache.cocoon.acting.LocaleAction}
+ * for details.</p>
+ *
+ * <p>For the passed local it then attempts to find a message catalogue that
+ * satisifies the locale, and uses it for for processing text replacement
+ * directed by i18n markup.</p>
+ *
+ * <p>Message catalogues are maintained in separate files, with a naming
+ * convention similar to that of {@link java.util.ResourceBundle}. I.e.
+ * <code>basename_locale</code>, where <i>basename</i> can be any name,
+ * and <i>locale</i> can be any locale specified using ISO 639/3166
+ * characters (eg. <code>en_AU</code>, <code>de_AT</code>, <code>es</code>).</p>
+ *
+ * <p><strong>NOTE:</strong> ISO 639 is not a stable standard; some of the
+ * language codes it defines (specifically, iw, ji, and in) have changed
+ * (see {@link java.util.Locale} for details).
+ *
+ * <h3>Message Catalogues</h3>
+ * <p>Catalogues are of the following format:
+ * <pre>
+ * &lt;?xml version="1.0"?&gt;
+ * &lt;!-- message catalogue file for locale ... --&gt;
+ * &lt;catalogue xml:lang=&quot;locale&quot;&gt;
+ *   &lt;message key="key"&gt;text &lt;i&gt;or&lt;/i&gt; markup&lt;/message&gt;
+ *   ....
+ * &lt;/catalogue&gt;
+ * </pre>
+ * Where <code>key</code> specifies a particular message for that
+ * language.
+ *
+ * <h3>Usage</h3>
+ * <p>Files to be translated contain the following markup:
+ * <pre>
+ * &lt;?xml version="1.0"?&gt;
+ * ... some text, translate &lt;i18n:text&gt;key&lt;/i18n:text&gt;
+ * </pre>
+ * At runtime, the i18n transformer will find a message catalogue for the
+ * user's locale, and will appropriately replace the text between the
+ * <code>&lt;i18n:text&gt;</code> markup, using the value between the tags as
+ * the lookup key.</p>
+ *
+ * <p>If the i18n transformer cannot find an appropriate message catalogue for
+ * the user's given locale, it will recursively try to locate a <i>parent</i>
+ * message catalogue, until a valid catalogue can be found.
+ * ie:
+ * <ul>
+ *  <li><strong>catalogue</strong>_<i>language</i>_<i>country</i>_<i>variant</i>.xml
+ *  <li><strong>catalogue</strong>_<i>language</i>_<i>country</i>.xml
+ *  <li><strong>catalogue</strong>_<i>language</i>.xml
+ *  <li><strong>catalogue</strong>.xml
+ * </ul>
+ * eg: Assuming a basename of <i>messages</i> and a locale of <i>en_AU</i>
+ * (no variant), the following search will occur:
+ * <ul>
+ *  <li><strong>messages</strong>_<i>en</i>_<i>AU</i>.xml
+ *  <li><strong>messages</strong>_<i>en</i>.xml
+ *  <li><strong>messages</strong>.xml
+ * </ul>
+ * This allows the developer to write a hierarchy of message catalogues,
+ * at each defining messages with increasing depth of variation.</p>
+ *
+ * <p>In addition, catalogues can be split across multiple locations. For example,
+ * there can be a default catalogue in one directory with a user or client specific
+ * catalogue in another directory. The catalogues will be searched in the order of
+ * the locations specified still following the locale ordering specified above.
+ * eg: Assuming a basename of <i>messages</i> and a locale of <i>en_AU</i>
+ * (no variant) and locations of <i>translations/client</i> and <i>translations</i>,
+ * the following search will occur:
+ * <ul>
+ *   <li><i>translations/client/</i><strong>messages</strong>_<i>en</i>_<i>AU</i>.xml
+ *   <li><i>translations/</i><strong>messages</strong>_<i>en</i>_<i>AU</i>.xml
+ *   <li><i>translations/client/</i><strong>messages</strong>_<i>en</i>.xml
+ *   <li><i>translations/</i><strong>messages</strong>_<i>en</i.xml
+ *   <li><i>translations/client/</i><strong>messages</strong>.xml
+ *   <li><i>translations/</i><strong>messages</strong>.xml
+ * </ul>
+ * </p>
+ *
+ * <p>The <code>i18n:text</code> element can optionally take an attribute
+ * <code>i18n:catalogue</code> to indicate which specific catalogue to use.
+ * The value of this attribute should be the id of the catalogue to use
+ * (see sitemap configuration).
+ *
+ * <h3>Sitemap configuration</h3>
+ * <pre>
+ * &lt;map:transformer name="i18n"
+ *     src="org.apache.cocoon.transformation.I18nTransformer"&gt;
+ *
+ *     &lt;catalogues default="someId"&gt;
+ *       &lt;catalogue id="someId" name="messages" [location="translations"]&gt;
+ *         [&lt;location&gt;translations/client&lt;/location&gt;]
+ *         [&lt;location&gt;translations&lt;/location&gt;]
+ *       &lt;/catalogue&gt;
+ *       ...
+ *     &lt;/catalogues&gt;
+ *     &lt;untranslated-text&gt;untranslated&lt;/untranslated-text&gt;
+ *     &lt;cache-at-startup&gt;true&lt;/cache-at-startup&gt;
+ * &lt;/map:transformer&gt;
+ * </pre>
+ * Where:
+ * <ul>
+ *  <li><strong>catalogues</strong>: container element in which the catalogues
+ *      are defined. It must have an attribute 'default' whose value is one
+ *      of the id's of the catalogue elements. (<i>mandatory</i>).
+ *  <li><strong>catalogue</strong>: specifies a catalogue. It takes 2 required
+ *      attributes: id (can be wathever you like) and name (base name of the catalogue).
+ *      The location (location of the message catalogue) is also required, but can be
+ *      specified either as an attribute or as one or more subelements, but not both.
+ *      If more than one location is specified the catalogues will be searched in the
+ *      order they appear in the configuration. The name and location can contain
+ *      references to inputmodules (same syntax as in other places in the
+ *      sitemap). They are resolved on each usage of the transformer, so they can
+ *      refer to e.g. request parameters. (<i>at least 1 catalogue
+ *      element required</i>).  After input module references are resolved the location
+ *      string can be the root of a URI. For example, specifying a location of
+ *      cocoon:/test with a name of messages and a locale of en_GB will cause the
+ *      sitemap to try to process cocoon:/test/messages_en_GB.xml,
+ *      cocoon:/test/messages_en.xml and cocoon:/test/messages.xml.
+ *  <li><strong>untranslated-text</strong>: text used for
+ *      untranslated keys (default is to output the key name).
+ *  <li><strong>cache-at-startup</strong>: flag whether to cache
+ *      messages at startup (false by default).
+ * </ul>
+ *
+ * <h3>Pipeline Usage</h3>
+ * <p>To use the transformer in a pipeline, simply specify it in a particular
+ * transform, and pass locale parameter:
+ * <pre>
+ * &lt;map:match pattern="file"&gt;
+ *   &lt;map:generate src="file.xml"/&gt;
+ *   &lt;map:transform type="i18n"&gt;
+ *     &lt;map:parameter name="locale" value="..."/&gt;
+ *   &lt;/map:transform&gt;
+ *   &lt;map:serialize/&gt;
+ * &lt;/map:match&gt;
+ * </pre>
+ * You can use {@link org.apache.cocoon.acting.LocaleAction} or any other
+ * way to provide transformer with a locale.</p>
+ *
+ * <p>If in certain pipeline, you want to use a different catalogue as the
+ * default catalogue, you can do so by specifying a parameter called
+ * <strong>default-catalogue-id</strong>.
+ *
+ * <p>The <strong>untranslated-text</strong> can also be overridden at the
+ * pipeline level by specifying it as a parameter.</p>
+ *
+ *
+ * <h3>i18n markup</h3>
+ *
+ * <p>For date, time and number formatting use the following tags:
+ * <ul>
+ *  <li><strong>&lt;i18n:date/&gt;</strong> gives localized date.</li>
+ *  <li><strong>&lt;i18n:date-time/&gt;</strong> gives localized date and time.</li>
+ *  <li><strong>&lt;i18n:time/&gt;</strong> gives localized time.</li>
+ *  <li><strong>&lt;i18n:number/&gt;</strong> gives localized number.</li>
+ *  <li><strong>&lt;i18n:currency/&gt;</strong> gives localized currency.</li>
+ *  <li><strong>&lt;i18n:percent/&gt;</strong> gives localized percent.</li>
+ * </ul>
+ * Elements <code>date</code>, <code>date-time</code> and <code>time</code>
+ * accept <code>pattern</code> and <code>src-pattern</code> attribute, with
+ * values of:
+ * <ul>
+ *  <li><code>short</code>
+ *  <li><code>medium</code>
+ *  <li><code>long</code>
+ *  <li><code>full</code>
+ * </ul>
+ * See {@link java.text.DateFormat} for more info on these values.</p>
+ *
+ * <p>Elements <code>date</code>, <code>date-time</code>, <code>time</code> and
+ * <code>number</code>, a different <code>locale</code> and
+ * <code>source-locale</code> can be specified:
+ * <pre>
+ * &lt;i18n:date src-pattern="short" src-locale="en_US" locale="de_DE"&gt;
+ *   12/24/01
+ * &lt;/i18n:date&gt;
+ * </pre>
+ * Will result in 24.12.2001.</p>
+ *
+ * <p>A given real <code>pattern</code> and <code>src-pattern</code> (not
+ * keywords <code>short, medium, long, full</code>) overrides any value
+ * specified by <code>locale</code> and <code>src-locale</code> attributes.</p>
+ *
+ * <p>Future work coming:
+ * <ul>
+ *  <li>Introduce new &lt;get-locale/&gt; element
+ *  <li>Move all formatting routines to I18nUtils
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class I18nTransformer extends AbstractTransformer
+                             implements CacheableProcessingComponent,
+                                        Serviceable, Configurable, Disposable {
+
+    /**
+     * The namespace for i18n is "http://apache.org/cocoon/i18n/2.1".
+     */
+    public static final String I18N_NAMESPACE_URI =
+            "http://apache.org/cocoon/i18n/2.1";
+
+    /**
+     * The old namespace for i18n is "http://apache.org/cocoon/i18n/2.0".
+     */
+    public static final String I18N_OLD_NAMESPACE_URI =
+            "http://apache.org/cocoon/i18n/2.0";
+
+    //
+    // i18n elements
+    //
+
+    /**
+     * <code>i18n:text</code> element is used to translate any text, with
+     * or without markup. Example:
+     * <pre>
+     *   &lt;i18n:text&gt;
+     *     This is &lt;strong&gt;translated&lt;/strong&gt; string.
+     *   &lt;/i18n:text&gt;
+     * </pre>
+     */
+    public static final String I18N_TEXT_ELEMENT            = "text";
+
+    /**
+     * <code>i18n:translate</code> element is used to translate text with
+     * parameter substitution. Example:
+     * <pre>
+     * &lt;i18n:translate&gt;
+     *   &lt;i18n:text&gt;This is translated string with {0} param&lt;/i18n:text&gt;
+     *   &lt;i18n:param&gt;1&lt;/i18n:param&gt;
+     * &lt;/i18n:translate&gt;
+     * </pre>
+     * The <code>i18n:text</code> fragment can include markup and parameters
+     * at any place. Also do parameters, which can include <code>i18n:text</code>,
+     * <code>i18n:date</code>, etc. elements (without keys only).
+     *
+     * @see #I18N_TEXT_ELEMENT
+     * @see #I18N_PARAM_ELEMENT
+     */
+    public static final String I18N_TRANSLATE_ELEMENT       = "translate";
+
+    /**
+     * <code>i18n:choose</code> element is used to translate elements in-place.
+     * The first <code>i18n:when</code> element matching the current locale
+     * is selected and the others are discarded.
+     *
+     * <p>To specify what to do if no locale matched, simply add a node with
+     * <code>locale="*"</code>. <em>Note that this element must be the last
+     * child of &lt;i18n:choose&gt;.</em></p>
+     * <pre>
+     * &lt;i18n:choose&gt;
+     *   &lt;i18n:when locale="en"&gt;
+     *     Good Morning
+     *   &lt;/en&gt;
+     *   &lt;i18n:when locale="fr"&gt;
+     *     Bonjour
+     *   &lt;/jp&gt;
+     *   &lt;i18n:when locale="jp"&gt;
+     *     Aligato?
+     *   &lt;/jp&gt;
+     *   &lt;i18n:otherwise&gt;
+     *     Sorry, i don't know how to say hello in your language
+     *   &lt;/jp&gt;
+     * &lt;i18n:translate&gt;
+     * </pre>
+     * <p>You can include any markup within <code>i18n:when</code> elements,
+     * with the exception of other <code>i18n:*</code> elements.</p>
+     *
+     * @see #I18N_IF_ELEMENT
+     * @see #I18N_LOCALE_ATTRIBUTE
+     * @since 2.1
+     */
+    public static final String I18N_CHOOSE_ELEMENT          = "choose";
+
+    /**
+     * <code>i18n:when</code> is used to test a locale.
+     * It can be used within <code>i18:choose</code> elements or alone.
+     * <em>Note: Using <code>locale="*"</code> here has no sense.</em>
+     * Example:
+     * <pre>
+     * &lt;greeting&gt;
+     *   &lt;i18n:when locale="en"&gt;Hello&lt;/i18n:when&gt;
+     *   &lt;i18n:when locale="fr"&gt;Bonjour&lt;/i18n:when&gt;
+     * &lt;/greeting&gt;
+     * </pre>
+     *
+     * @see #I18N_LOCALE_ATTRIBUTE
+     * @see #I18N_CHOOSE_ELEMENT
+     * @since 2.1
+     */
+    public static final String I18N_WHEN_ELEMENT            = "when";
+
+    /**
+     * <code>i18n:if</code> is used to test a locale. Example:
+     * <pre>
+     * &lt;greeting&gt;
+     *   &lt;i18n:if locale="en"&gt;Hello&lt;/i18n:when&gt;
+     *   &lt;i18n:if locale="fr"&gt;Bonjour&lt;/i18n:when&gt;
+     * &lt;/greeting&gt;
+     * </pre>
+     *
+     * @see #I18N_LOCALE_ATTRIBUTE
+     * @see #I18N_CHOOSE_ELEMENT
+     * @see #I18N_WHEN_ELEMENT
+     * @since 2.1
+     */
+    public static final String I18N_IF_ELEMENT            = "if";
+
+    /**
+     * <code>i18n:otherwise</code> is used to match any locale when
+     * no matching locale has been found inside an <code>i18n:choose</code>
+     * block.
+     *
+     * @see #I18N_CHOOSE_ELEMENT
+     * @see #I18N_WHEN_ELEMENT
+     * @since 2.1
+     */
+    public static final String I18N_OTHERWISE_ELEMENT       = "otherwise";
+
+    /**
+     * <code>i18n:param</code> is used with i18n:translate to provide
+     * substitution params. The param can have <code>i18n:text</code> as
+     * its value to provide multilungual value. Parameters can have
+     * additional attributes to be used for formatting:
+     * <ul>
+     *   <li><code>type</code>: can be <code>date, date-time, time,
+     *   number, currency, currency-no-unit or percent</code>.
+     *   Used to format params before substitution.</li>
+     *   <li><code>value</code>: the value of the param. If no value is
+     *   specified then the text inside of the param element will be used.</li>
+     *   <li><code>locale</code>: used only with <code>number, date, time,
+     *   date-time</code> types and used to override the current locale to
+     *   format the given value.</li>
+     *   <li><code>src-locale</code>: used with <code>number, date, time,
+     *   date-time</code> types and specify the locale that should be used to
+     *   parse the given value.</li>
+     *   <li><code>pattern</code>: used with <code>number, date, time,
+     *   date-time</code> types and specify the pattern that should be used
+     *   to format the given value.</li>
+     *   <li><code>src-pattern</code>: used with <code>number, date, time,
+     *   date-time</code> types and specify the pattern that should be used
+     *   to parse the given value.</li>
+     * </ul>
+     *
+     * @see #I18N_TRANSLATE_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_PARAM_ELEMENT           = "param";
+
+    /**
+     * This attribute affects a name to the param that could be used
+     * for substitution.
+     *
+     * @since 2.1
+     */
+    public static final String I18N_PARAM_NAME_ATTRIBUTE    = "name";
+
+    /**
+     * <code>i18n:date</code> is used to provide a localized date string.
+     * Allowed attributes are: <code>pattern, src-pattern, locale,
+     * src-locale</code>. Usage examples:
+     * <pre>
+     *  &lt;i18n:date src-pattern="short" src-locale="en_US" locale="de_DE"&gt;
+     *    12/24/01
+     *  &lt;/i18n:date&gt;
+     *
+     *  &lt;i18n:date pattern="dd/MM/yyyy" /&gt;
+     * </pre>
+     *
+     * If no value is specified then the current date will be used. E.g.:
+     * <pre>
+     *   &lt;i18n:date /&gt;
+     * </pre>
+     * Displays the current date formatted with default pattern for
+     * the current locale.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_DATE_ELEMENT            = "date";
+
+    /**
+     * <code>i18n:date-time</code> is used to provide a localized date and
+     * time string. Allowed attributes are: <code>pattern, src-pattern,
+     * locale, src-locale</code>. Usage examples:
+     * <pre>
+     *  &lt;i18n:date-time src-pattern="short" src-locale="en_US" locale="de_DE"&gt;
+     *    12/24/01 1:00 AM
+     *  &lt;/i18n:date&gt;
+     *
+     *  &lt;i18n:date-time pattern="dd/MM/yyyy hh:mm" /&gt;
+     * </pre>
+     *
+     * If no value is specified then the current date and time will be used.
+     * E.g.:
+     * <pre>
+     *  &lt;i18n:date-time /&gt;
+     * </pre>
+     * Displays the current date formatted with default pattern for
+     * the current locale.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_DATE_TIME_ELEMENT       = "date-time";
+
+    /**
+     * <code>i18n:time</code> is used to provide a localized time string.
+     * Allowed attributes are: <code>pattern, src-pattern, locale,
+     * src-locale</code>. Usage examples:
+     * <pre>
+     *  &lt;i18n:time src-pattern="short" src-locale="en_US" locale="de_DE"&gt;
+     *    1:00 AM
+     *  &lt;/i18n:time&gt;
+     *
+     * &lt;i18n:time pattern="hh:mm:ss" /&gt;
+     * </pre>
+     *
+     * If no value is specified then the current time will be used. E.g.:
+     * <pre>
+     *  &lt;i18n:time /&gt;
+     * </pre>
+     * Displays the current time formatted with default pattern for
+     * the current locale.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_TIME_ELEMENT            = "time";
+
+    /**
+     * <code>i18n:number</code> is used to provide a localized number string.
+     * Allowed attributes are: <code>pattern, src-pattern, locale, src-locale,
+     * type</code>. Usage examples:
+     * <pre>
+     *  &lt;i18n:number src-pattern="short" src-locale="en_US" locale="de_DE"&gt;
+     *    1000.0
+     *  &lt;/i18n:number&gt;
+     *
+     * &lt;i18n:number type="currency" /&gt;
+     * </pre>
+     *
+     * If no value is specifies then 0 will be used.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     */
+    public static final String I18N_NUMBER_ELEMENT      = "number";
+
+    /**
+     * Currency element name
+     */
+    public static final String I18N_CURRENCY_ELEMENT    = "currency";
+
+    /**
+     * Percent element name
+     */
+    public static final String I18N_PERCENT_ELEMENT     = "percent";
+
+    /**
+     * Integer currency element name
+     */
+    public static final String I18N_INT_CURRENCY_ELEMENT = "int-currency";
+
+    /**
+     * Currency without unit element name
+     */
+    public static final String I18N_CURRENCY_NO_UNIT_ELEMENT = "currency-no-unit";
+
+    /**
+     * Integer currency without unit element name
+     */
+    public static final String I18N_INT_CURRENCY_NO_UNIT_ELEMENT = "int-currency-no-unit";
+
+    //
+    // i18n general attributes
+    //
+
+    /**
+     * This attribute is used with i18n:text element to indicate the key of
+     * the according message. The character data of the element will be used
+     * if no message is found by this key. E.g.:
+     * <pre>
+     * &lt;i18n:text i18n:key="a_key"&gt;article_text1&lt;/i18n:text&gt;
+     * </pre>
+     */
+    public static final String I18N_KEY_ATTRIBUTE           = "key";
+
+    /**
+     * This attribute is used with <strong>any</strong> element (even not i18n)
+     * to translate attribute values. Should contain whitespace separated
+     * attribute names that should be translated:
+     * <pre>
+     * &lt;para title="first" name="article" i18n:attr="title name"/&gt;
+     * </pre>
+     * Attribute value considered as key in message catalogue.
+     */
+    public static final String I18N_ATTR_ATTRIBUTE          = "attr";
+
+    /**
+     * This attribute is used with <strong>any</strong> element (even not i18n)
+     * to evaluate attribute values. Should contain whitespace separated
+     * attribute names that should be evaluated:
+     * <pre>
+     * &lt;para title="first" name="{one} {two}" i18n:attr="name"/&gt;
+     * </pre>
+     * Attribute value considered as expression containing text and catalogue
+     * keys in curly braces.
+     */
+    public static final String I18N_EXPR_ATTRIBUTE          = "expr";
+
+    //
+    // i18n number and date formatting attributes
+    //
+
+    /**
+     * This attribute is used with date and number formatting elements to
+     * indicate the pattern that should be used to parse the element value.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_SRC_PATTERN_ATTRIBUTE   = "src-pattern";
+
+    /**
+     * This attribute is used with date and number formatting elements to
+     * indicate the pattern that should be used to format the element value.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_PATTERN_ATTRIBUTE       = "pattern";
+
+    /**
+     * This attribute is used with date and number formatting elements to
+     * indicate the locale that should be used to format the element value.
+     * Also used for in-place translations.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     * @see #I18N_WHEN_ELEMENT
+     */
+    public static final String I18N_LOCALE_ATTRIBUTE        = "locale";
+
+    /**
+     * This attribute is used with date and number formatting elements to
+     * indicate the locale that should be used to parse the element value.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_SRC_LOCALE_ATTRIBUTE    = "src-locale";
+
+    /**
+     * This attribute is used with date and number formatting elements to
+     * indicate the value that should be parsed and formatted. If value
+     * attribute is not used then the character data of the element will be used.
+     *
+     * @see #I18N_PARAM_ELEMENT
+     * @see #I18N_DATE_TIME_ELEMENT
+     * @see #I18N_DATE_ELEMENT
+     * @see #I18N_TIME_ELEMENT
+     * @see #I18N_NUMBER_ELEMENT
+     */
+    public static final String I18N_VALUE_ATTRIBUTE         = "value";
+
+    /**
+     * This attribute is used with <code>i18:param</code> to
+     * indicate the parameter type: <code>date, time, date-time</code> or
+     * <code>number, currency, percent, int-currency, currency-no-unit,
+     * int-currency-no-unit</code>.
+     * Also used with <code>i18:translate</code> to indicate inplace
+     * translations: <code>inplace</code>
+     * @deprecated since 2.1. Use nested tags instead, e.g.:
+     * &lt;i18n:param&gt;&lt;i18n:date/&gt;&lt;/i18n:param&gt;
+     */
+    public static final String I18N_TYPE_ATTRIBUTE          = "type";
+
+    /**
+     * This attribute is used to specify a different locale for the
+     * currency. When specified, this locale will be combined with
+     * the "normal" locale: e.g. the seperator symbols are taken from
+     * the normal locale but the currency symbol and possition will
+     * be taken from the currency locale.
+     * This enables to see a currency formatted for Euro but with US
+     * grouping and decimal char.
+     */
+    public static final String CURRENCY_LOCALE_ATTRIBUTE = "currency";
+
+    /**
+     * This attribute can be used on <code>i18n:text</code> to indicate the catalogue
+     * from which the key should be retrieved. This attribute is optional,
+     * if it is not mentioned the default catalogue is used.
+     */
+    public static final String I18N_CATALOGUE_ATTRIBUTE = "catalogue";
+
+    //
+    // Configuration parameters
+    //
+
+    /**
+     * This configuration parameter specifies the default locale to be used.
+     */
+    public static final String I18N_LOCALE      = "locale";
+
+    /**
+     * This configuration parameter specifies the id of the catalogue to be used as
+     * default catalogue, allowing to redefine the default catalogue on the pipeline
+     * level.
+     */
+    public static final String I18N_DEFAULT_CATALOGUE_ID = "default-catalogue-id";
+
+    /**
+     * This configuration parameter specifies the message that should be
+     * displayed in case of a not translated text (message not found).
+     */
+    public static final String I18N_UNTRANSLATED        = "untranslated-text";
+
+    /**
+     * This configuration parameter specifies if the message catalog should be
+     * cached at startup.
+     */
+    public static final String I18N_CACHE_STARTUP       = "cache-at-startup";
+
+    /**
+     * <code>fraction-digits</code> attribute is used with
+     * <code>i18:number</code> to
+     * indicate the number of digits behind the fraction
+     */
+    public static final String I18N_FRACTION_DIGITS_ATTRIBUTE = "fraction-digits";
+
+    //
+    // States of the transformer
+    //
+
+    private static final int STATE_OUTSIDE                       = 0;
+    private static final int STATE_INSIDE_TEXT                   = 10;
+    private static final int STATE_INSIDE_PARAM                  = 20;
+    private static final int STATE_INSIDE_TRANSLATE              = 30;
+    private static final int STATE_INSIDE_CHOOSE                 = 50;
+    private static final int STATE_INSIDE_WHEN                   = 51;
+    private static final int STATE_INSIDE_OTHERWISE              = 52;
+    private static final int STATE_INSIDE_DATE                   = 60;
+    private static final int STATE_INSIDE_DATE_TIME              = 61;
+    private static final int STATE_INSIDE_TIME                   = 62;
+    private static final int STATE_INSIDE_NUMBER                 = 63;
+
+    // All date-time related parameter types and element names
+    private static final Set dateTypes;
+
+    // All number related parameter types and element names
+    private static final Set numberTypes;
+
+    // Date pattern types map: short, medium, long, full
+    private static final Map datePatterns;
+
+    static {
+        // initialize date types set
+        HashSet set = new HashSet(5);
+        set.add(I18N_DATE_ELEMENT);
+        set.add(I18N_TIME_ELEMENT);
+        set.add(I18N_DATE_TIME_ELEMENT);
+        dateTypes = Collections.unmodifiableSet(set);
+
+        // initialize number types set
+        set = new HashSet(9);
+        set.add(I18N_NUMBER_ELEMENT);
+        set.add(I18N_PERCENT_ELEMENT);
+        set.add(I18N_CURRENCY_ELEMENT);
+        set.add(I18N_INT_CURRENCY_ELEMENT);
+        set.add(I18N_CURRENCY_NO_UNIT_ELEMENT);
+        set.add(I18N_INT_CURRENCY_NO_UNIT_ELEMENT);
+        numberTypes = Collections.unmodifiableSet(set);
+
+        // Initialize date patterns map
+        Map map = new HashMap(7);
+        map.put("SHORT", new Integer(DateFormat.SHORT));
+        map.put("MEDIUM", new Integer(DateFormat.MEDIUM));
+        map.put("LONG", new Integer(DateFormat.LONG));
+        map.put("FULL", new Integer(DateFormat.FULL));
+        datePatterns = Collections.unmodifiableMap(map);
+    }
+
+
+    //
+    // Global configuration variables
+    //
+
+    /**
+     * Component (service) manager
+     */
+    protected ServiceManager manager;
+
+    /**
+     * Message bundle loader factory component (service)
+     */
+    protected BundleFactory factory;
+
+    /**
+     * All catalogues (keyed by catalogue id). The values are instances
+     * of {@link CatalogueInfo}.
+     */
+    private Map catalogues;
+
+    /**
+     * Default (global) catalogue
+     */
+    private CatalogueInfo defaultCatalogue;
+
+    /**
+     * Default (global) untranslated message value
+     */
+    private String defaultUntranslated;
+
+    //
+    // Local configuration variables
+    //
+
+    protected Map objectModel;
+
+    /**
+     * Locale
+     */
+    protected Locale locale;
+
+    /**
+     * Catalogue (local)
+     */
+    private CatalogueInfo catalogue;
+
+    /**
+     * Current (local) untranslated message value
+     */
+    private String untranslated;
+
+    /**
+     * {@link SaxBuffer} containing the contents of {@link #untranslated}.
+     */
+    private ParamSaxBuffer untranslatedRecorder;
+
+    //
+    // Current state of the transformer
+    //
+
+    /**
+     * Current state of the transformer. Default value is STATE_OUTSIDE.
+     */
+    private int current_state;
+
+    /**
+     * Previous state of the transformer.
+     * Used in text translation inside params and translate elements.
+     */
+    private int prev_state;
+
+    /**
+     * The i18n:key attribute is stored for the current element.
+     * If no translation found for the key then the character data of element is
+     * used as default value.
+     */
+    private String currentKey;
+
+    /**
+     * Contains the id of the current catalogue if it was explicitely mentioned
+     * on an i18n:text element, otherwise it is null.
+     */
+    private String currentCatalogueId;
+
+    /**
+     * Character data buffer. used to concat chunked character data
+     */
+    private StringBuffer strBuffer;
+
+    /**
+     * A flag for copying the node when doing in-place translation
+     */
+    private boolean translate_copy;
+
+    // A flag for copying the _GOOD_ node and not others
+    // when doing in-place translation within i18n:choose
+    private boolean translate_end;
+
+    // Translated text. Inside i18n:translate, collects character events.
+    private ParamSaxBuffer tr_text_recorder;
+
+    // Current "i18n:text" events
+    private ParamSaxBuffer text_recorder;
+
+    // Current parameter events
+    private SaxBuffer param_recorder;
+
+    // Param count when not using i18n:param name="..."
+    private int param_count;
+
+    // Param name attribute for substitution.
+    private String param_name;
+
+    // i18n:param's hashmap for substitution
+    private HashMap indexedParams;
+
+    // Current parameter value (translated or not)
+    private String param_value;
+
+    // Date and number elements and params formatting attributes with values.
+    private HashMap formattingParams;
+
+    /**
+     * Returns the current locale setting of this transformer instance.
+     * @return current Locale object
+     */
+    public Locale getLocale() {
+        return this.locale;
+    }
+
+    /**
+     * Implemenation of CacheableProcessingComponents.
+     * Generates unique key for the current locale.
+     */
+    public java.io.Serializable getKey() {
+        // TODO: Key should be composed out of used catalogues locations, and locale.
+        //       Right now it is hardcoded only to default catalogue location.
+        StringBuffer key = new StringBuffer();
+        if (catalogue != null) {
+            key.append(catalogue.getLocation()[0]);
+        }
+        key.append("?");
+        if (locale != null) {
+            key.append(locale.getLanguage());
+            key.append("_");
+            key.append(locale.getCountry());
+            key.append("_");
+            key.append(locale.getVariant());
+        }
+        return key.toString();
+    }
+
+    /**
+     * Implementation of CacheableProcessingComponent.
+     * Generates validity object for this transformer or <code>null</code>
+     * if this instance is not cacheable.
+     */
+    public SourceValidity getValidity() {
+        // FIXME (KP): Cache validity should be generated by
+        // Bundle implementations.
+        return org.apache.excalibur.source.impl.validity.NOPValidity.SHARED_INSTANCE;
+    }
+
+    /**
+     * Look up the {@link BundleFactory} to be used.
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        try {
+            this.factory = (BundleFactory) manager.lookup(BundleFactory.ROLE);
+        } catch (ServiceException e) {
+            getLogger().debug("Failed to lookup <" + BundleFactory.ROLE + ">", e);
+            throw e;
+        }
+    }
+
+    /**
+     * Implementation of Configurable interface.
+     * Configure this transformer.
+     */
+    public void configure(Configuration conf) throws ConfigurationException {
+        // Read in the config options from the transformer definition
+        Configuration cataloguesConf = conf.getChild("catalogues", false);
+        if (cataloguesConf == null) {
+            throw new ConfigurationException("I18nTransformer requires <catalogues> configuration at " +
+                                             conf.getLocation());
+        }
+
+        // new configuration style
+        Configuration[] catalogueConfs = cataloguesConf.getChildren("catalogue");
+        catalogues = new HashMap(catalogueConfs.length + 3);
+        for (int i = 0; i < catalogueConfs.length; i++) {
+            String id = catalogueConfs[i].getAttribute("id");
+            String name = catalogueConfs[i].getAttribute("name");
+
+            String[] locations;
+            String location = catalogueConfs[i].getAttribute("location", null);
+            Configuration[] locationConf =
+                catalogueConfs[i].getChildren("location");
+            if (location != null) {
+                if (locationConf.length > 0) {
+                    String msg = "I18nTransformer: Location attribute cannot be " +
+                                 "specified with location elements";
+                    getLogger().error(msg);
+                    throw new ConfigurationException(msg);
+                }
+
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("name=" + name + ", location=" +
+                                      location);
+                }
+                locations = new String[1];
+                locations[0] = location;
+            } else {
+                if (locationConf.length == 0) {
+                    String msg = "I18nTransformer: A location attribute or location " +
+                                 "elements must be specified";
+                    getLogger().error(msg);
+                    throw new ConfigurationException(msg);
+                }
+
+                locations = new String[locationConf.length];
+                for (int j=0; j < locationConf.length; ++j) {
+                    locations[j] = locationConf[j].getValue();
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("name=" + name + ", location=" +
+                                          locations[j]);
+                    }
+                }
+            }
+
+            CatalogueInfo catalogueInfo;
+            try {
+                catalogueInfo = new CatalogueInfo(name, locations);
+            } catch (PatternException e) {
+                throw new ConfigurationException("I18nTransformer: Error in name or location " +
+                                                 "attribute on catalogue element with id " + id, e);
+            }
+            catalogues.put(id, catalogueInfo);
+        }
+
+        String defaultCatalogueId = cataloguesConf.getAttribute("default");
+        defaultCatalogue = (CatalogueInfo) catalogues.get(defaultCatalogueId);
+        if (defaultCatalogue == null) {
+            throw new ConfigurationException("I18nTransformer: Default catalogue id '" +
+                                             defaultCatalogueId + "' denotes a nonexisting catalogue");
+        }
+
+        // Obtain default text to use for untranslated messages
+        defaultUntranslated = conf.getChild(I18N_UNTRANSLATED).getValue(null);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default untranslated text is '" + defaultUntranslated + "'");
+        }
+    }
+
+    /**
+     * Setup current instance of transformer.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String source,
+                      Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+
+        this.objectModel = objectModel;
+
+        untranslated = parameters.getParameter(I18N_UNTRANSLATED, defaultUntranslated);
+        if (untranslated != null) {
+            untranslatedRecorder = new ParamSaxBuffer();
+            untranslatedRecorder.characters(untranslated.toCharArray(), 0, untranslated.length());
+        }
+
+        // Get current locale
+        String lc = parameters.getParameter(I18N_LOCALE, null);
+        Locale locale = I18nUtils.parseLocale(lc);
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Using locale '" + locale + "'");
+        }
+
+        // Initialize instance state variables
+        this.locale             = locale;
+        this.current_state      = STATE_OUTSIDE;
+        this.prev_state         = STATE_OUTSIDE;
+        this.currentKey        = null;
+        this.currentCatalogueId = null;
+        this.translate_copy     = false;
+        this.tr_text_recorder   = null;
+        this.text_recorder      = new ParamSaxBuffer();
+        this.param_count        = 0;
+        this.param_name         = null;
+        this.param_value        = null;
+        this.param_recorder     = null;
+        this.indexedParams      = new HashMap(3);
+        this.formattingParams   = null;
+        this.strBuffer          = null;
+
+        // give the catalogue variable its value -- first look if it's locally overridden
+        // and otherwise use the component-wide defaults.
+        String catalogueId = parameters.getParameter(I18N_DEFAULT_CATALOGUE_ID, null);
+        if (catalogueId != null) {
+            CatalogueInfo catalogueInfo = (CatalogueInfo) catalogues.get(catalogueId);
+            if (catalogueInfo == null) {
+                throw new ProcessingException("I18nTransformer: '" +
+                                              catalogueId +
+                                              "' is not an existing catalogue id.");
+            }
+            catalogue = catalogueInfo;
+        } else {
+            catalogue = defaultCatalogue;
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Default catalogue is " + catalogue.getName());
+        }
+    }
+
+
+    //
+    // Standard SAX event handlers
+    //
+
+    public void startElement(String uri, String name, String raw,
+                             Attributes attr)
+    throws SAXException {
+
+        // Handle previously buffered characters
+        if (current_state != STATE_OUTSIDE && strBuffer != null) {
+            i18nCharacters(strBuffer.toString());
+            strBuffer = null;
+        }
+
+        // Process start element event
+        if (I18nUtils.matchesI18nNamespace(uri)) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Starting i18n element: " + name);
+            }
+            startI18NElement(name, attr);
+        } else {
+            // We have a non i18n element event
+            if (current_state == STATE_OUTSIDE) {
+                super.startElement(uri, name, raw,
+                                   translateAttributes(name, attr));
+            } else if (current_state == STATE_INSIDE_PARAM) {
+                param_recorder.startElement(uri, name, raw, attr);
+            } else if (current_state == STATE_INSIDE_TEXT) {
+                text_recorder.startElement(uri, name, raw, attr);
+            } else if ((current_state == STATE_INSIDE_WHEN ||
+                    current_state == STATE_INSIDE_OTHERWISE)
+                    && translate_copy) {
+
+                super.startElement(uri, name, raw, attr);
+            }
+        }
+    }
+
+    public void endElement(String uri, String name, String raw)
+    throws SAXException {
+
+        // Handle previously buffered characters
+        if (current_state != STATE_OUTSIDE && strBuffer != null) {
+            i18nCharacters(strBuffer.toString());
+            strBuffer = null;
+        }
+
+        if (I18nUtils.matchesI18nNamespace(uri)) {
+            endI18NElement(name);
+        } else if (current_state == STATE_INSIDE_PARAM) {
+            param_recorder.endElement(uri, name, raw);
+        } else if (current_state == STATE_INSIDE_TEXT) {
+            text_recorder.endElement(uri, name, raw);
+        } else if (current_state == STATE_INSIDE_CHOOSE ||
+                (current_state == STATE_INSIDE_WHEN ||
+                current_state == STATE_INSIDE_OTHERWISE)
+                && !translate_copy) {
+
+            // Output nothing
+        } else {
+            super.endElement(uri, name, raw);
+        }
+    }
+
+    public void characters(char[] ch, int start, int len)
+    throws SAXException {
+
+        if (current_state == STATE_OUTSIDE ||
+                ((current_state == STATE_INSIDE_WHEN ||
+                current_state == STATE_INSIDE_OTHERWISE) && translate_copy)) {
+
+            super.characters(ch, start, len);
+        } else {
+            // Perform buffering to prevent chunked character data
+            if (strBuffer == null) {
+                strBuffer = new StringBuffer();
+            }
+            strBuffer.append(ch, start, len);
+        }
+    }
+
+    //
+    // i18n specific event handlers
+    //
+
+    private void startI18NElement(String name, Attributes attr)
+    throws SAXException {
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start i18n element: " + name);
+        }
+
+        if (I18N_TEXT_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE
+                    && current_state != STATE_INSIDE_PARAM
+                    && current_state != STATE_INSIDE_TRANSLATE) {
+
+                throw new SAXException(
+                        getClass().getName()
+                        + ": nested i18n:text elements are not allowed."
+                        + " Current state: " + current_state);
+            }
+
+            prev_state = current_state;
+            current_state = STATE_INSIDE_TEXT;
+
+            currentKey = attr.getValue("", I18N_KEY_ATTRIBUTE);
+            if (currentKey == null) {
+                // Try the namespaced attribute
+                currentKey = attr.getValue(I18N_NAMESPACE_URI, I18N_KEY_ATTRIBUTE);
+                if (currentKey == null) {
+                    // Try the old namespace
+                    currentKey = attr.getValue(I18N_OLD_NAMESPACE_URI, I18N_KEY_ATTRIBUTE);
+                }
+            }
+
+            currentCatalogueId = attr.getValue("", I18N_CATALOGUE_ATTRIBUTE);
+            if (currentCatalogueId == null) {
+                // Try the namespaced attribute
+                currentCatalogueId = attr.getValue(I18N_NAMESPACE_URI, I18N_CATALOGUE_ATTRIBUTE);
+            }
+
+            if (prev_state != STATE_INSIDE_PARAM) {
+                tr_text_recorder = null;
+            }
+
+            if (currentKey != null) {
+                tr_text_recorder = getMessage(currentKey, (ParamSaxBuffer)null);
+            }
+
+        } else if (I18N_TRANSLATE_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:translate element must be used "
+                        + "outside of other i18n elements. Current state: "
+                        + current_state);
+            }
+
+            prev_state = current_state;
+            current_state = STATE_INSIDE_TRANSLATE;
+        } else if (I18N_PARAM_ELEMENT.equals(name)) {
+            if (current_state != STATE_INSIDE_TRANSLATE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:param element can be used only inside "
+                        + "i18n:translate element. Current state: "
+                        + current_state);
+            }
+
+            param_name = attr.getValue(I18N_PARAM_NAME_ATTRIBUTE);
+            if (param_name == null) {
+                param_name = String.valueOf(param_count++);
+            }
+
+            param_recorder = new SaxBuffer();
+            setFormattingParams(attr);
+            current_state = STATE_INSIDE_PARAM;
+        } else if (I18N_CHOOSE_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:choose elements cannot be used"
+                        + "inside of other i18n elements.");
+            }
+
+            translate_copy = false;
+            translate_end = false;
+            prev_state = current_state;
+            current_state = STATE_INSIDE_CHOOSE;
+        } else if (I18N_WHEN_ELEMENT.equals(name) ||
+                I18N_IF_ELEMENT.equals(name)) {
+
+            if (I18N_WHEN_ELEMENT.equals(name) &&
+                    current_state != STATE_INSIDE_CHOOSE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:when elements are can be used only"
+                        + "inside of i18n:choose elements.");
+            }
+
+            if (I18N_IF_ELEMENT.equals(name) &&
+                    current_state != STATE_OUTSIDE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:if elements cannot be nested.");
+            }
+
+            String locale = attr.getValue(I18N_LOCALE_ATTRIBUTE);
+            if (locale == null)
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:" + name
+                        + " element cannot be used without 'locale' attribute.");
+
+            if ((!translate_end && current_state == STATE_INSIDE_CHOOSE)
+                    || current_state == STATE_OUTSIDE) {
+
+                // Perform soft locale matching
+                if (this.locale.toString().startsWith(locale)) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Locale matching: " + locale);
+                    }
+                    translate_copy = true;
+                }
+            }
+
+            prev_state = current_state;
+            current_state = STATE_INSIDE_WHEN;
+
+        } else if (I18N_OTHERWISE_ELEMENT.equals(name)) {
+            if (current_state != STATE_INSIDE_CHOOSE) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:otherwise elements are not allowed "
+                        + "only inside i18n:choose.");
+            }
+
+            getLogger().debug("Matching any locale");
+            if (!translate_end) {
+                translate_copy = true;
+            }
+
+            prev_state = current_state;
+            current_state = STATE_INSIDE_OTHERWISE;
+
+        } else if (I18N_DATE_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE
+                    && current_state != STATE_INSIDE_TEXT
+                    && current_state != STATE_INSIDE_PARAM) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:date elements are not allowed "
+                        + "inside of other i18n elements.");
+            }
+
+            setFormattingParams(attr);
+            prev_state = current_state;
+            current_state = STATE_INSIDE_DATE;
+        } else if (I18N_DATE_TIME_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE
+                    && current_state != STATE_INSIDE_TEXT
+                    && current_state != STATE_INSIDE_PARAM) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:date-time elements are not allowed "
+                        + "inside of other i18n elements.");
+            }
+
+            setFormattingParams(attr);
+            prev_state = current_state;
+            current_state = STATE_INSIDE_DATE_TIME;
+        } else if (I18N_TIME_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE
+                    && current_state != STATE_INSIDE_TEXT
+                    && current_state != STATE_INSIDE_PARAM) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:date elements are not allowed "
+                        + "inside of other i18n elements.");
+            }
+
+            setFormattingParams(attr);
+            prev_state = current_state;
+            current_state = STATE_INSIDE_TIME;
+        } else if (I18N_NUMBER_ELEMENT.equals(name)) {
+            if (current_state != STATE_OUTSIDE
+                    && current_state != STATE_INSIDE_TEXT
+                    && current_state != STATE_INSIDE_PARAM) {
+                throw new SAXException(
+                        getClass().getName()
+                        + ": i18n:number elements are not allowed "
+                        + "inside of other i18n elements.");
+            }
+
+            setFormattingParams(attr);
+            prev_state = current_state;
+            current_state = STATE_INSIDE_NUMBER;
+        }
+    }
+
+    // Get all possible i18n formatting attribute values and store in a Map
+    private void setFormattingParams(Attributes attr) {
+        // average number of attributes is 3
+        formattingParams = new HashMap(3);
+
+        String attr_value = attr.getValue(I18N_SRC_PATTERN_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_SRC_PATTERN_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_PATTERN_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_PATTERN_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_VALUE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_VALUE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_LOCALE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_LOCALE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(CURRENCY_LOCALE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(CURRENCY_LOCALE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_SRC_LOCALE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_SRC_LOCALE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_TYPE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_TYPE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_FRACTION_DIGITS_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_FRACTION_DIGITS_ATTRIBUTE, attr_value);
+        }
+    }
+
+    private void endI18NElement(String name) throws SAXException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End i18n element: " + name);
+        }
+
+        switch (current_state) {
+            case STATE_INSIDE_TEXT:
+                endTextElement();
+                break;
+
+            case STATE_INSIDE_TRANSLATE:
+                endTranslateElement();
+                break;
+
+            case STATE_INSIDE_CHOOSE:
+                endChooseElement();
+                break;
+
+            case STATE_INSIDE_WHEN:
+            case STATE_INSIDE_OTHERWISE:
+                endWhenElement();
+                break;
+
+            case STATE_INSIDE_PARAM:
+                endParamElement();
+                break;
+
+            case STATE_INSIDE_DATE:
+            case STATE_INSIDE_DATE_TIME:
+            case STATE_INSIDE_TIME:
+                endDate_TimeElement();
+                break;
+
+            case STATE_INSIDE_NUMBER:
+                endNumberElement();
+                break;
+        }
+    }
+
+    private void i18nCharacters(String textValue) throws SAXException {
+        // Trim text values to avoid parsing errors.
+        textValue = textValue.trim();
+        if (textValue.length() == 0) {
+            return;
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug( "i18n message text = '" + textValue + "'" );
+        }
+
+        char[] ch = textValue.toCharArray();
+        switch (current_state) {
+            case STATE_INSIDE_TEXT:
+                text_recorder.characters(ch, 0, ch.length);
+                break;
+
+            case STATE_INSIDE_PARAM:
+                param_recorder.characters(ch, 0, ch.length);
+                break;
+
+            case STATE_INSIDE_WHEN:
+            case STATE_INSIDE_OTHERWISE:
+                // Previously handeld to avoid the String() conversion.
+                break;
+
+            case STATE_INSIDE_TRANSLATE:
+                if(tr_text_recorder == null) {
+                    tr_text_recorder = new ParamSaxBuffer();
+                }
+                tr_text_recorder.characters(ch, 0, ch.length);
+                break;
+
+            case STATE_INSIDE_CHOOSE:
+                // No characters allowed. Send an exception ?
+                getLogger().debug("No characters allowed inside <i18n:choose> tags");
+                break;
+
+            case STATE_INSIDE_DATE:
+            case STATE_INSIDE_DATE_TIME:
+            case STATE_INSIDE_TIME:
+            case STATE_INSIDE_NUMBER:
+                if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null) {
+                    formattingParams.put(I18N_VALUE_ATTRIBUTE, textValue);
+                } else {
+                    // ignore the text inside of date element
+                }
+                break;
+
+            default:
+                throw new IllegalStateException(getClass().getName() +
+                                                " developer's fault: characters not handled. " +
+                                                "Current state: " + current_state);
+        }
+    }
+
+    // Translate all attributes that are listed in i18n:attr attribute
+    private Attributes translateAttributes(final String element, Attributes attr)
+    throws SAXException {
+        if (attr == null) {
+            return null;
+        }
+
+        AttributesImpl tempAttr = null;
+
+        // Translate all attributes from i18n:attr="name1 name2 ..."
+        // using their values as keys.
+        int attrIndex = attr.getIndex(I18N_NAMESPACE_URI, I18N_ATTR_ATTRIBUTE);
+        if (attrIndex == -1) {
+            // Try the old namespace
+            attrIndex = attr.getIndex(I18N_OLD_NAMESPACE_URI, I18N_ATTR_ATTRIBUTE);
+        }
+
+        if (attrIndex != -1) {
+            StringTokenizer st = new StringTokenizer(attr.getValue(attrIndex));
+
+            // Make a copy which we are going to modify
+            tempAttr = new AttributesImpl(attr);
+            // Remove the i18n:attr attribute - we don't need it anymore
+            tempAttr.removeAttribute(attrIndex);
+
+            // Iterate through listed attributes and translate them
+            while (st.hasMoreElements()) {
+                final String name = st.nextToken();
+
+                int index = tempAttr.getIndex(name);
+                if (index == -1) {
+                    getLogger().warn("Attribute " +
+                                     name + " not found in element <" + element + ">");
+                    continue;
+                }
+
+                String value = translateAttribute(element, name, tempAttr.getValue(index));
+                if (value != null) {
+                    // Set the translated value. If null, do nothing.
+                    tempAttr.setValue(index, value);
+                }
+            }
+
+            attr = tempAttr;
+        }
+
+        // Translate all attributes from i18n:expr="name1 name2 ..."
+        // using their values as keys.
+        attrIndex = attr.getIndex(I18N_NAMESPACE_URI, I18N_EXPR_ATTRIBUTE);
+        if (attrIndex != -1) {
+            StringTokenizer st = new StringTokenizer(attr.getValue(attrIndex));
+
+            if (tempAttr == null) {
+                tempAttr = new AttributesImpl(attr);
+            }
+            tempAttr.removeAttribute(attrIndex);
+
+            // Iterate through listed attributes and evaluate them
+            while (st.hasMoreElements()) {
+                final String name = st.nextToken();
+
+                int index = tempAttr.getIndex(name);
+                if (index == -1) {
+                    getLogger().warn("Attribute " +
+                                     name + " not found in element <" + element + ">");
+                    continue;
+                }
+
+                final StringBuffer translated = new StringBuffer();
+
+                // Evaluate {..} expression
+                VariableExpressionTokenizer.TokenReciever tr = new VariableExpressionTokenizer.TokenReciever () {
+                    private String catalogueName;
+
+                    public void addToken(int type, String value) {
+                        if (type == MODULE) {
+                            this.catalogueName = value;
+                        } else if (type == VARIABLE) {
+                            translated.append(translateAttribute(element, name, value));
+                        } else if (type == TEXT) {
+                            if (this.catalogueName != null) {
+                                translated.append(translateAttribute(element,
+                                                                     name,
+                                                                     this.catalogueName + ":" + value));
+                                this.catalogueName = null;
+                            } else if (value != null) {
+                                translated.append(value);
+                            }
+                        }
+                    }
+                };
+
+                try {
+                    VariableExpressionTokenizer.tokenize(tempAttr.getValue(index), tr);
+                } catch (PatternException e) {
+                    throw new SAXException(e);
+                }
+
+                // Set the translated value.
+                tempAttr.setValue(index, translated.toString());
+            }
+
+            attr = tempAttr;
+        }
+
+        // nothing to translate, just return
+        return attr;
+    }
+
+    /**
+     * Translate attribute value.
+     * Value can be prefixed with catalogue ID and semicolon.
+     * @return Translated text, untranslated text, or null.
+     */
+    private String translateAttribute(String element, String name, String key) {
+        // Check if the key contains a colon, if so the text before
+        // the colon denotes a catalogue ID.
+        int colonPos = key.indexOf(":");
+        String catalogueID = null;
+        if (colonPos != -1) {
+            catalogueID = key.substring(0, colonPos);
+            key = key.substring(colonPos + 1, key.length());
+        }
+
+        final SaxBuffer text = getMessage(catalogueID, key);
+        if (text == null) {
+            getLogger().warn("Translation not found for attribute " +
+                             name + " in element <" + element + ">");
+            return untranslated;
+        }
+        return text.toString();
+    }
+
+    private void endTextElement() throws SAXException {
+        switch (prev_state) {
+            case STATE_OUTSIDE:
+                if (tr_text_recorder == null) {
+                    if (currentKey == null) {
+                        // Use the text as key. Not recommended for large strings,
+                        // especially if they include markup.
+                        tr_text_recorder = getMessage(text_recorder.toString(), text_recorder);
+                    } else {
+                        // We have the key, but couldn't find a translation
+                        if (getLogger().isDebugEnabled()) {
+                            getLogger().debug("Translation not found for key '" + currentKey + "'");
+                        }
+
+                        // Use the untranslated-text only when the content of the i18n:text
+                        // element was empty
+                        if (text_recorder.isEmpty() && untranslatedRecorder != null) {
+                            tr_text_recorder = untranslatedRecorder;
+                        } else {
+                            tr_text_recorder = text_recorder;
+                        }
+                    }
+                }
+
+                if (tr_text_recorder != null) {
+                    tr_text_recorder.toSAX(this.contentHandler);
+                }
+
+                text_recorder.recycle();
+                tr_text_recorder = null;
+                currentKey = null;
+                currentCatalogueId = null;
+                break;
+
+            case STATE_INSIDE_TRANSLATE:
+                if (tr_text_recorder == null) {
+                    if (!text_recorder.isEmpty()) {
+                        tr_text_recorder = getMessage(text_recorder.toString(), text_recorder);
+                        if (tr_text_recorder == text_recorder) {
+                            // If the default value was returned, make a copy
+                            tr_text_recorder = new ParamSaxBuffer(text_recorder);
+                        }
+                    }
+                }
+
+                text_recorder.recycle();
+                break;
+
+            case STATE_INSIDE_PARAM:
+                // We send the translated text to the param recorder, after trying to translate it.
+                // Remember you can't give a key when inside a param, that'll be nonsense!
+                // No need to clone. We just send the events.
+                if (!text_recorder.isEmpty()) {
+                    getMessage(text_recorder.toString(), text_recorder).toSAX(param_recorder);
+                    text_recorder.recycle();
+                }
+                break;
+        }
+
+        current_state = prev_state;
+        prev_state = STATE_OUTSIDE;
+    }
+
+    // Process substitution parameter
+    private void endParamElement() throws SAXException {
+        String paramType = (String)formattingParams.get(I18N_TYPE_ATTRIBUTE);
+        if (paramType != null) {
+            // We have a typed parameter
+
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Param type: " + paramType);
+            }
+            if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null && param_value != null) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Put param value: " + param_value);
+                }
+                formattingParams.put(I18N_VALUE_ATTRIBUTE, param_value);
+            }
+
+            // Check if we have a date or a number parameter
+            if (dateTypes.contains(paramType)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Formatting date_time param: " + formattingParams);
+                }
+                param_value = formatDate_Time(formattingParams);
+            } else if (numberTypes.contains(paramType)) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Formatting number param: " + formattingParams);
+                }
+                param_value = formatNumber(formattingParams);
+            }
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Added substitution param: " + param_value);
+            }
+        }
+
+        param_value = null;
+        current_state = STATE_INSIDE_TRANSLATE;
+
+        if(param_recorder == null) {
+            return;
+        }
+
+        indexedParams.put(param_name, param_recorder);
+        param_recorder = null;
+    }
+
+    private void endTranslateElement() throws SAXException {
+        if (tr_text_recorder != null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("End of translate with params. " +
+                                  "Fragment for substitution : " + tr_text_recorder);
+            }
+            tr_text_recorder.toSAX(super.contentHandler, indexedParams);
+            tr_text_recorder = null;
+            text_recorder.recycle();
+        }
+
+        indexedParams.clear();
+        param_count = 0;
+        current_state = STATE_OUTSIDE;
+    }
+
+    private void endChooseElement() {
+        current_state = STATE_OUTSIDE;
+    }
+
+    private void endWhenElement() {
+        current_state = prev_state;
+        if (translate_copy) {
+            translate_copy = false;
+            translate_end = true;
+        }
+    }
+
+    private void endDate_TimeElement() throws SAXException {
+        String result = formatDate_Time(formattingParams);
+        switch(prev_state) {
+            case STATE_OUTSIDE:
+                super.contentHandler.characters(result.toCharArray(), 0,
+                                                result.length());
+                break;
+            case STATE_INSIDE_PARAM:
+                param_recorder.characters(result.toCharArray(), 0, result.length());
+                break;
+            case STATE_INSIDE_TEXT:
+                text_recorder.characters(result.toCharArray(), 0, result.length());
+                break;
+        }
+        current_state = prev_state;
+    }
+
+    // Helper method: creates Locale object from a string value in a map
+    private Locale getLocale(Map params, String attribute) {
+        // the specific locale value
+        String lc = (String)params.get(attribute);
+        return I18nUtils.parseLocale(lc, this.locale);
+    }
+
+    private String formatDate_Time(Map params) throws SAXException {
+        // Check that we have not null params
+        if (params == null) {
+            throw new IllegalArgumentException("Nothing to format");
+        }
+
+        // Formatters
+        SimpleDateFormat to_fmt;
+        SimpleDateFormat from_fmt;
+
+        // Date formatting styles
+        int srcStyle = DateFormat.DEFAULT;
+        int style = DateFormat.DEFAULT;
+
+        // Date formatting patterns
+        boolean realPattern = false;
+        boolean realSrcPattern = false;
+
+        // From locale
+        Locale srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+        // To locale
+        Locale loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+
+        // From pattern
+        String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE);
+        // To pattern
+        String pattern = (String)params.get(I18N_PATTERN_ATTRIBUTE);
+        // The date value
+        String value = (String)params.get(I18N_VALUE_ATTRIBUTE);
+
+        // A src-pattern attribute is present
+        if (srcPattern != null) {
+            // Check if we have a real pattern
+            Integer patternValue = (Integer)datePatterns.get(srcPattern.toUpperCase());
+            if (patternValue != null) {
+                srcStyle = patternValue.intValue();
+            } else {
+                realSrcPattern = true;
+            }
+        }
+
+        // A pattern attribute is present
+        if (pattern != null) {
+            Integer patternValue = (Integer)datePatterns.get(pattern.toUpperCase());
+            if (patternValue != null) {
+                style = patternValue.intValue();
+            } else {
+                realPattern = true;
+            }
+        }
+
+        // If we are inside of a typed param
+        String paramType = (String)formattingParams.get(I18N_TYPE_ATTRIBUTE);
+
+        // Initializing date formatters
+        if (current_state == STATE_INSIDE_DATE ||
+                I18N_DATE_ELEMENT.equals(paramType)) {
+
+            to_fmt = (SimpleDateFormat)DateFormat.getDateInstance(style, loc);
+            from_fmt = (SimpleDateFormat)DateFormat.getDateInstance(
+                    srcStyle,
+                    srcLoc
+            );
+        } else if (current_state == STATE_INSIDE_DATE_TIME ||
+                I18N_DATE_TIME_ELEMENT.equals(paramType)) {
+            to_fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance(
+                    style,
+                    style,
+                    loc
+            );
+            from_fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance(
+                    srcStyle,
+                    srcStyle,
+                    srcLoc
+            );
+        } else {
+            // STATE_INSIDE_TIME or param type='time'
+            to_fmt = (SimpleDateFormat)DateFormat.getTimeInstance(style, loc);
+            from_fmt = (SimpleDateFormat)DateFormat.getTimeInstance(
+                    srcStyle,
+                    srcLoc
+            );
+        }
+
+        // parsed date object
+        Date dateValue;
+
+        // pattern overwrites locale format
+        if (realSrcPattern) {
+            from_fmt.applyPattern(srcPattern);
+        }
+
+        if (realPattern) {
+            to_fmt.applyPattern(pattern);
+        }
+
+        // get current date and time by default
+        if (value == null) {
+            dateValue = new Date();
+        } else {
+            try {
+                dateValue = from_fmt.parse(value);
+            } catch (ParseException pe) {
+                throw new SAXException(
+                        this.getClass().getName()
+                        + "i18n:date - parsing error.", pe
+                );
+            }
+        }
+
+        // we have all necessary data here: do formatting.
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("### Formatting date: " + dateValue + " with localized pattern " +
+                              to_fmt.toLocalizedPattern() + " for locale: " + locale);
+        }
+        return to_fmt.format(dateValue);
+    }
+
+    private void endNumberElement() throws SAXException {
+        String result = formatNumber(formattingParams);
+        switch(prev_state) {
+            case STATE_OUTSIDE:
+                super.contentHandler.characters(result.toCharArray(), 0, result.length());
+                break;
+            case STATE_INSIDE_PARAM:
+                param_recorder.characters(result.toCharArray(), 0, result.length());
+                break;
+            case STATE_INSIDE_TEXT:
+                text_recorder.characters(result.toCharArray(), 0, result.length());
+                break;
+        }
+        current_state = prev_state;
+    }
+
+    private String formatNumber(Map params) throws SAXException {
+        if (params == null) {
+            throw new SAXException(
+                    this.getClass().getName()
+                    + ": i18n:number - error in element attributes."
+            );
+        }
+
+        // from pattern
+        String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE);
+        // to pattern
+        String pattern = (String)params.get(I18N_PATTERN_ATTRIBUTE);
+        // the number value
+        String value = (String)params.get(I18N_VALUE_ATTRIBUTE);
+
+        if (value == null) return "";
+        // type
+        String type = (String)params.get(I18N_TYPE_ATTRIBUTE);
+
+        // fraction-digits
+        int fractionDigits = -1;
+        try {
+            String fd = (String)params.get(I18N_FRACTION_DIGITS_ATTRIBUTE);
+            if (fd != null)
+                fractionDigits = Integer.parseInt(fd);
+        } catch (NumberFormatException nfe) {
+            getLogger().warn("Error in number format with fraction-digits", nfe);
+        }
+
+        // parsed number
+        Number numberValue;
+
+        // locale, may be switched locale
+        Locale loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+        Locale srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+        // currency locale
+        Locale currencyLoc = getLocale(params, CURRENCY_LOCALE_ATTRIBUTE);
+        // decimal and grouping locale
+        Locale dgLoc = null;
+        if (currencyLoc != null) {
+            // the reasoning here is: if there is a currency locale, then start from that
+            // one but take certain properties (like decimal and grouping seperation symbols)
+            // from the default locale (this happens further on).
+            dgLoc = loc;
+            loc = currencyLoc;
+        }
+
+        // src format
+        DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance(srcLoc);
+        int int_currency = 0;
+
+        // src-pattern overwrites locale format
+        if (srcPattern != null) {
+            from_fmt.applyPattern(srcPattern);
+        }
+
+        // to format
+        DecimalFormat to_fmt;
+        char dec = from_fmt.getDecimalFormatSymbols().getDecimalSeparator();
+        int decAt = 0;
+        boolean appendDec = false;
+
+        if (type == null || type.equals( I18N_NUMBER_ELEMENT )) {
+            to_fmt = (DecimalFormat)NumberFormat.getInstance(loc);
+            to_fmt.setMaximumFractionDigits(309);
+            for (int i = value.length() - 1;
+                 i >= 0 && value.charAt(i) != dec; i--, decAt++) {
+            }
+
+            if (decAt < value.length())to_fmt.setMinimumFractionDigits(decAt);
+            decAt = 0;
+            for (int i = 0; i < value.length() && value.charAt(i) != dec; i++) {
+                if (Character.isDigit(value.charAt(i))) {
+                    decAt++;
+                }
+            }
+
+            to_fmt.setMinimumIntegerDigits(decAt);
+            if (value.charAt(value.length() - 1) == dec) {
+                appendDec = true;
+            }
+        } else if (type.equals( I18N_CURRENCY_ELEMENT )) {
+            to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
+        } else if (type.equals( I18N_INT_CURRENCY_ELEMENT )) {
+            to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
+            int_currency = 1;
+            for (int i = 0; i < to_fmt.getMaximumFractionDigits(); i++) {
+                int_currency *= 10;
+            }
+        } else if ( type.equals( I18N_CURRENCY_NO_UNIT_ELEMENT ) ) {
+            DecimalFormat tmp = (DecimalFormat) NumberFormat.getCurrencyInstance( loc );
+            to_fmt = (DecimalFormat) NumberFormat.getInstance( loc );
+            to_fmt.setMinimumFractionDigits(tmp.getMinimumFractionDigits());
+            to_fmt.setMaximumFractionDigits(tmp.getMaximumFractionDigits());
+        } else if ( type.equals( I18N_INT_CURRENCY_NO_UNIT_ELEMENT ) ) {
+            DecimalFormat tmp = (DecimalFormat) NumberFormat.getCurrencyInstance( loc );
+            int_currency = 1;
+            for ( int i = 0; i < tmp.getMaximumFractionDigits(); i++ )
+                int_currency *= 10;
+            to_fmt = (DecimalFormat) NumberFormat.getInstance( loc );
+            to_fmt.setMinimumFractionDigits(tmp.getMinimumFractionDigits());
+            to_fmt.setMaximumFractionDigits(tmp.getMaximumFractionDigits());
+        } else if (type.equals( I18N_PERCENT_ELEMENT )) {
+            to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(loc);
+        } else {
+            throw new SAXException("&lt;i18n:number>: unknown type: " + type);
+        }
+
+        if(fractionDigits > -1) {
+            to_fmt.setMinimumFractionDigits(fractionDigits);
+            to_fmt.setMaximumFractionDigits(fractionDigits);
+        }
+
+        if(dgLoc != null) {
+            DecimalFormat df = (DecimalFormat)NumberFormat.getCurrencyInstance(dgLoc);
+            DecimalFormatSymbols dfsNew = df.getDecimalFormatSymbols();
+            DecimalFormatSymbols dfsOrig = to_fmt.getDecimalFormatSymbols();
+            dfsOrig.setDecimalSeparator(dfsNew.getDecimalSeparator());
+            dfsOrig.setMonetaryDecimalSeparator(dfsNew.getMonetaryDecimalSeparator());
+            dfsOrig.setGroupingSeparator(dfsNew.getGroupingSeparator());
+            to_fmt.setDecimalFormatSymbols(dfsOrig);
+        }
+
+        // pattern overwrites locale format
+        if (pattern != null) {
+            to_fmt.applyPattern(pattern);
+        }
+
+        if (value == null) {
+            numberValue = new Long(0);
+        } else {
+            try {
+                numberValue = from_fmt.parse(value);
+                if (int_currency > 0) {
+                    numberValue = new Double(numberValue.doubleValue() /
+                                             int_currency);
+                } else {
+                    // what?
+                }
+            } catch (ParseException pe) {
+                throw new SAXException(
+                        this.getClass().getName()
+                        + "i18n:number - parsing error.", pe
+                );
+            }
+        }
+
+        // we have all necessary data here: do formatting.
+        String result = to_fmt.format(numberValue);
+        if (appendDec) result = result + dec;
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("i18n:number result: " + result);
+        }
+        return result;
+    }
+
+    //-- Dictionary handling routines
+
+    /**
+     * Helper method to retrieve a message from the dictionary.
+     *
+     * @param catalogueID if not null, this catalogue will be used instead of the default one.
+     * @return SaxBuffer containing message, or null if not found.
+     */
+    private ParamSaxBuffer getMessage(String catalogueID, String key) {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Getting key " + key + " from catalogue " + catalogueID);
+        }
+
+        CatalogueInfo catalogue = this.catalogue;
+        if (catalogueID != null) {
+            catalogue = (CatalogueInfo)catalogues.get(catalogueID);
+            if (catalogue == null) {
+                if (getLogger().isWarnEnabled()) {
+                    getLogger().warn("Catalogue not found: " + catalogueID +
+                                     ", will not translate key " + key);
+                }
+                return null;
+            }
+        }
+
+        Bundle bundle = catalogue.getCatalogue();
+        if (bundle == null) {
+            // Can't translate
+            getLogger().debug("Untranslated key: '" + key + "'");
+            return null;
+        }
+
+        try {
+            return (ParamSaxBuffer) bundle.getObject(key);
+        } catch (MissingResourceException e)  {
+            getLogger().debug("Untranslated key: '" + key + "'");
+        }
+
+        return null;
+    }
+
+    /**
+     * Helper method to retrieve a message from the current dictionary.
+     * A default value is returned if message is not found.
+     *
+     * @return SaxBuffer containing message, or defaultValue if not found.
+     */
+    private ParamSaxBuffer getMessage(String key, ParamSaxBuffer defaultValue) {
+        SaxBuffer value = getMessage(currentCatalogueId, key);
+        if (value == null) {
+            return defaultValue;
+        }
+
+        return new ParamSaxBuffer(value);
+    }
+
+    public void recycle() {
+        this.untranslatedRecorder = null;
+        this.catalogue = null;
+        this.objectModel = null;
+
+        // Release catalogues which were selected for current locale
+        Iterator i = catalogues.values().iterator();
+        while (i.hasNext()) {
+            CatalogueInfo catalogueInfo = (CatalogueInfo) i.next();
+            catalogueInfo.releaseCatalog();
+        }
+
+        super.recycle();
+    }
+
+    public void dispose() {
+        if (manager != null) {
+            manager.release(factory);
+        }
+        factory = null;
+        manager = null;
+        catalogues = null;
+    }
+
+
+    /**
+     * Holds information about one catalogue. The location and name of the catalogue
+     * can contain references to input modules, and are resolved upon each transformer
+     * usage. It is important that releaseCatalog is called when the transformer is recycled.
+     */
+    private final class CatalogueInfo {
+        VariableResolver name;
+        VariableResolver[] locations;
+        String resolvedName;
+        String[] resolvedLocations;
+        Bundle catalogue;
+
+        public CatalogueInfo(String name, String[] locations) throws PatternException {
+            this.name = VariableResolverFactory.getResolver(name, manager);
+            this.locations = new VariableResolver[locations.length];
+            for (int i=0; i < locations.length; ++i) {
+                this.locations[i] = VariableResolverFactory.getResolver(locations[i], manager);
+            }
+        }
+
+        public String getName() {
+            try {
+                if (resolvedName == null) {
+                    resolve();
+                }
+            } catch (Exception e) {
+                // Ignore the error for now
+            }
+            return resolvedName;
+        }
+
+        public String[] getLocation() {
+            try {
+                if (resolvedName == null) {
+                    resolve();
+                }
+            } catch (Exception e) {
+                // Ignore the error for now
+            }
+            return resolvedLocations;
+        }
+
+        private void resolve() throws Exception {
+            if (resolvedLocations == null) {
+                resolvedLocations = new String[locations.length];
+                for (int i=0; i < resolvedLocations.length; ++i) {
+                    resolvedLocations[i] = locations[i].resolve(null, objectModel);
+                }
+            }
+            if (resolvedName == null) {
+                resolvedName = name.resolve(null, objectModel);
+            }
+        }
+
+        public Bundle getCatalogue() {
+            if (catalogue == null) {
+                try {
+                    resolve();
+                    catalogue = factory.select(resolvedLocations, resolvedName, locale);
+                } catch (Exception e) {
+                    getLogger().error("Error obtaining catalogue '" + getName() +
+                                      "' from  <" + getLocation() + "> for locale " +
+                                      locale, e);
+                }
+            }
+
+            return catalogue;
+        }
+
+        public void releaseCatalog() {
+            if (catalogue != null) {
+                factory.release(catalogue);
+            }
+            catalogue = null;
+            resolvedName = null;
+            resolvedLocations = null;
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/IncludeTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/IncludeTransformer.java
new file mode 100644
index 0000000..c06f38c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/IncludeTransformer.java
@@ -0,0 +1,1118 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.MultiSourceValidity;
+import org.apache.cocoon.components.thread.RunnableManager;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.transformation.helpers.NOPRecorder;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.NamespacesTable;
+import org.apache.cocoon.xml.SaxBuffer;
+import org.apache.cocoon.xml.XMLConsumer;
+
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceValidity;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+
+/**
+ * <p>A simple transformer including resolvable sources (accessed through
+ * Cocoon's {@link SourceResolver}) from its input.</p>
+ *
+ * <p>Inclusion is triggered by the <code>&lt;include ... /&gt;</code> element
+ * defined in the <code>http://apache.org/cocoon/include/1.0</code> namespace.</p>
+ *
+ * <p>Example:</p>
+ * <pre>
+ * &lt;i:include xmlns:i="http://apache.org/cocoon/include/1.0"
+ *               src="cocoon://path/to/include"/&gt;
+ * </pre>
+ *
+ * <p>An interesting feature of this {@link Transformer} is that it implements the
+ * {@link CacheableProcessingComponent} interface and provides full support for
+ * caching. In other words, if the input given to this transformer has not changed,
+ * and all of the included sources are (cacheable) and still valid, this transformer
+ * will not force a pipeline re-generation like the {@link CIncludeTransformer}.</p>
+ *
+ *
+ * <h3>Relative Source Resolution</h3>
+ * <p>Include sources which are specified using relative URI will be resolved
+ * relative to the source document location. This is consistent with
+ * {@link XIncludeTransformer} behavior, but differs from {@link CIncludeTransformer}.
+ *
+ *
+ * <h3>Parameters Passing</h3>
+ * <p>Parameters to be passed to the included sources can be specified in two ways:
+ * the first one is to encode them onto the source itelf, for example:</p>
+ *
+ * <pre>
+ * &lt;i:include xmlns:i="http://apache.org/cocoon/include/1.0"
+ *               src="cocoon://path/to/include?paramA=valueA&amp;paramB=valueB"/&gt;
+ * </pre>
+ *
+ * <p>Another approach allows the encoding of parameters to be done automatically by
+ * the transformer, so that one can easily pass parameter name or values containing
+ * the <code>&amp;</code> (amperstand) or <code>=</code> (equals) character, which are
+ * reserved characters in URIs. An example:</p>
+ *
+ * <pre>
+ * &lt;i:include xmlns:i="http://apache.org/cocoon/include/1.0"
+ *               src="cocoon://path/to/include"&gt;
+ *   &lt;i:parameter name="firstParameterName" value="firstParameterValue"/&gt;
+ *   &lt;i:parameter name="other&amp;Para=Name" value="other=Para&amp;Value"/&gt;
+ * &lt;/i:include&gt;
+ * </pre>
+ *
+ *
+ * <h3>Fallback Element</h3>
+ * <p>IncludeTransformer allows fallback element to be specified within
+ * include element. XML content of the fallback element will be included instead
+ * of source content if source inclusion caused an exception. Fallback element
+ * can have nested include elements. An example:</p>
+ *
+ * <pre>
+ * &lt;i:include xmlns:i="http://apache.org/cocoon/include/1.0"
+ *               src="cocoon://path/to/include"&gt;
+ *   &lt;i:fallback&gt;
+ *     <strong>The data is temporarily unavailable.</strong>
+ *     We are sorry for the trouble; please try again later.
+ *   &lt;/i:fallback&gt;
+ * &lt;/i:include&gt;
+ * </pre>
+ *
+ *
+ * <h3>Parallel Processing</h3>
+ * <p>Another feature of this {@link Transformer} is that it allows parallel processing
+ * of includes. By setting the optional parameter <code>parallel</code> to true,
+ * the various included contents are processed (included) in parallel threads rather
+ * than in series, in one thread. This parameter can be set in either the transformer
+ * definition (to affect all IncludeTransformer instances):</p>
+ * <pre>
+ *   &lt;parallel&gt;true&lt;/parallel&gt;
+ * </pre>
+ *
+ * <p>or in a pipeline itself (to only affect that instance of the IncludeTransformer):</p>
+ * <pre>
+ *   &lt;map:parameter name="parallel" value="true"/&gt;
+ * </pre>
+ * <p>By default, parallel processing is turned off.</p>
+ *
+ *
+ * <h3>Recursive Processing</h3>
+ * <p>This {@link Transformer} allows recursive processing of includes.
+ * By setting the optional parameter <code>recursive</code> to true,
+ * the various included contents are scanned for include elements, and processed
+ * in the same manner as incoming XML events. This parameter can be set in either
+ * the transformer definition (to affect all IncludeTransformer instances):</p>
+ * <pre>
+ *   &lt;recursive&gt;true&lt;/recursive&gt;
+ * </pre>
+ *
+ * <p>or in a pipeline itself (to only affect that instance of the IncludeTransformer):</p>
+ * <pre>
+ *   &lt;map:parameter name="recursive" value="true"/&gt;
+ * </pre>
+ * <p>This feature is similar to the XInclude processing. By default,
+ * recursive processing is turned off.</p>
+ *
+ *
+ * @cocoon.sitemap.component.documentation
+ * A simple transformer including resolvable sources (accessed through
+ * Cocoon's SourceResolver) from its input.
+ *
+ * @cocoon.sitemap.component.name include
+ * @cocoon.sitemap.component.logger sitemap.transformer.include
+ * @cocoon.sitemap.component.pooling.max 16
+ * @version $Id$
+ */
+public class IncludeTransformer extends AbstractTransformer
+                                implements Serviceable, Configurable,
+                                           Transformer, CacheableProcessingComponent {
+
+    /** <p>The namespace URI of the elements recognized by this transformer.</p> */
+    private static final String NS_URI = "http://apache.org/cocoon/include/1.0";
+
+    /** <p>The name of the element triggering inclusion of sources.</p> */
+    private static final String INCLUDE_ELEMENT = "include";
+
+    /** <p>The name of the element defining a fallback content.</p> */
+    private static final String FALLBACK_ELEMENT = "fallback";
+
+    /** <p>The name of the element defining an included subrequest parameter.</p> */
+    private static final String PARAMETER_ELEMENT = "parameter";
+
+    /** <p>The name of the attribute indicating the included source URI.</p> */
+    private static final String SRC_ATTRIBUTE = "src";
+
+    /** <p>The name of the mime type attribute containing the hint for the {@link org.apache.excalibur.xmlizer.XMLizer}.</p> */
+    private static final String MIME_ATTRIBUTE = "mime-type";
+
+    /** <p>The name of the parse attribute indicating type of included source processing: xml or text.</p> */
+    private static final String PARSE_ATTRIBUTE = "parse";
+
+    /** <p>The name of the attribute indicating the parameter name.</p> */
+    private static final String NAME_ATTRIBUTE = "name";
+
+    /** <p>The name of the attribute indicating the parameter name.</p> */
+    private static final String VALUE_ATTRIBUTE = "value";
+
+    /** <p>The encoding to use for parameter names and values.</p> */
+    private static final String ENCODING = "US-ASCII";
+
+    //
+    // Global configuration
+    //
+
+    /** The {@link ServiceManager} instance associated with this instance. */
+    private ServiceManager manager;
+
+    /** Configuration option controlling recursive includes processing */
+    private boolean defaultRecursive;
+
+    /** Configuration option controlling parallel (in multiple threads) includes processing */
+    private boolean defaultParallel;
+
+    /** Configuration option controlling parallel (in multiple threads) includes processing in the recursive includes */
+    private boolean defaultRecursiveParallel;
+
+    /** The name of the thread pool to use (for parallel processing). */
+    private String threadPool;
+
+    /** The default value to be appended to the caching key. */
+    private String defaultKey;
+
+    //
+    // Current configuration
+    //
+
+    /** The {@link SourceResolver} used to resolve included URIs. */
+    private SourceResolver resolver;
+
+    /** The {@link Environment} used within parallel threads */
+    private Environment environment;
+
+    /** The {@link Processor} used within parallel threads */
+    private Processor processor;
+
+    /** The value to be appended to the caching key. */
+    private String key;
+
+    //
+    // Current state
+    //
+
+    /** The {@link SourceValidity} instance associated with this request. */
+    private MultiSourceValidity validity;
+
+    /** A {@link NamespacesTable} used to filter namespace declarations. */
+    private NamespacesTable namespaces;
+
+    /** The {@link IncludeXMLPipe} which is doing all the work */
+    private final IncludeXMLPipe pipe;
+
+    /**
+     * <p>Create a new {@link IncludeTransformer} instance.</p>
+     */
+    public IncludeTransformer() {
+        pipe = new IncludeXMLPipe();
+    }
+
+    /**
+     * <p>Initialize own and {@link #pipe} loggers</p>
+     */
+    public void enableLogging(Logger logger) {
+        super.enableLogging(logger);
+        pipe.enableLogging(logger);
+    }
+
+    /**
+     * <p>Setup the {@link ServiceManager} available for this instance.</p>
+     *
+     * @see Serviceable#service(ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see Configurable#configure(Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        /* Read configuration nodes for recursive, parallel, recursive-parallel */
+        this.defaultRecursive = configuration.getChild("recursive").getValueAsBoolean(false);
+        this.defaultParallel = configuration.getChild("parallel").getValueAsBoolean(false);
+        this.defaultRecursiveParallel = configuration.getChild("recursive-parallel").getValueAsBoolean(false);
+        /* Read configuration node for thread pool name */
+        this.threadPool = configuration.getChild("thread-pool").getValue("default");
+        this.defaultKey = configuration.getChild("key").getValue(null);
+    }
+
+    /**
+     * <p>Setup this component instance in the context of its pipeline and
+     * current request.</p>
+     *
+     * @see Serviceable#service(ServiceManager)
+     */
+    public void setup(SourceResolver resolver, Map om, String src, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        /* Read sitemap parameters */
+        this.pipe.recursive = parameters.getParameterAsBoolean("recursive", this.defaultRecursive);
+        this.pipe.parallel = parameters.getParameterAsBoolean("parallel", this.defaultParallel);
+        this.pipe.recursiveParallel = parameters.getParameterAsBoolean("recursive-parallel", this.defaultRecursiveParallel);
+        this.key = parameters.getParameter("key", this.defaultKey);
+
+        /* Init transformer state */
+        if (this.pipe.parallel) {
+            this.environment = EnvironmentHelper.getCurrentEnvironment();
+            this.processor = EnvironmentHelper.getCurrentProcessor();
+        }
+        this.namespaces = new NamespacesTable();
+        this.resolver = resolver;
+        this.validity = null;
+
+        // Set root include pipe as consumer.
+        // Won't use setter methods here - they are overridden
+        super.xmlConsumer = pipe;
+        super.contentHandler = pipe;
+        super.lexicalHandler = pipe;
+    }
+
+    public void setConsumer(XMLConsumer consumer) {
+        pipe.setConsumer(consumer);
+    }
+
+    public void setContentHandler(ContentHandler handler) {
+        pipe.setContentHandler(handler);
+    }
+
+    public void setLexicalHandler(LexicalHandler handler) {
+        pipe.setLexicalHandler(handler);
+    }
+
+    /**
+     * <p>Recycle this component instance.</p>
+     *
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        this.namespaces = null;
+        this.validity = null;
+
+        /* Make sure all threads completed their work */
+        this.pipe.recycle();
+
+        // Resolver can be nulled out when all threads completed processing
+        // and released their Sources.
+        this.resolver = null;
+
+        super.recycle();
+    }
+
+
+    /**
+     * <p>Receive notification of the beginning of an XML document.</p>
+     *
+     * @see ContentHandler#startDocument
+     */
+    public void startDocument()
+    throws SAXException {
+        /* Make sure that we have a validity while processing */
+        getValidity();
+
+        super.startDocument();
+    }
+
+    /**
+     * <p>Receive notification of the end of an XML document.</p>
+     *
+     * @see ContentHandler#startDocument()
+     */
+    public void endDocument()
+    throws SAXException {
+        /* Make sure that the validity is "closed" at the end */
+        this.validity.close();
+
+        super.endDocument();
+    }
+
+    /**
+     * <p>Receive notification of the start of a prefix mapping.</p>
+     *
+     * <p>This transformer will remove all prefix mapping declarations for those
+     * prefixes associated with the <code>http://apache.org/cocoon/include/1.0</code>
+     * namespace.</p>
+     *
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
+     */
+    public void startPrefixMapping(String prefix, String nsuri)
+    throws SAXException {
+        if (NS_URI.equals(nsuri)) {
+            /* Skipping mapping for the current prefix as it's ours */
+            this.namespaces.addDeclaration(prefix, nsuri);
+        } else {
+            /* Map the current prefix, as we don't know it */
+            super.startPrefixMapping(prefix, nsuri);
+        }
+    }
+
+    /**
+     * <p>Receive notification of the end of a prefix mapping.</p>
+     *
+     * <p>This transformer will remove all prefix mapping declarations for those
+     * prefixes associated with the <code>http://apache.org/cocoon/include/1.0</code>
+     * namespace.</p>
+     *
+     * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        if (NS_URI.equals(this.namespaces.getUri(prefix))) {
+            /* Skipping unmapping for the current prefix as it's ours */
+            this.namespaces.removeDeclaration(prefix);
+        } else {
+            /* Unmap the current prefix, as we don't know it */
+            super.endPrefixMapping(prefix);
+        }
+    }
+
+    /**
+     * <p>Return the caching key associated with this transformation.</p>
+     *
+     * <p>When including <code>cocoon://</code> sources with dynamic
+     * content depending on environment (request parameters, session attributes,
+     * etc), it makes sense to provide such environment values to the transformer
+     * to be included into the key using <code>key</code> sitemap parameter.</p>
+     *
+     * @see CacheableProcessingComponent#getKey()
+     */
+    public Serializable getKey() {
+        /*
+         * In case of including "cocoon://" or other dynamic sources key
+         * ideally has to include ProcessingPipelineKey of the included
+         * "cocoon://" sources, but it's not possible as at this time
+         * we don't know yet which sources will get included into the
+         * response.
+         *
+         * Hence, javadoc recommends providing key using sitemap parameter.
+         */
+        return key == null? "I": "I" + key;
+    }
+
+    /**
+     * <p>Generate (or return) the {@link SourceValidity} instance used to
+     * possibly validate cached generations.</p>
+     *
+     * @return a <b>non null</b> {@link SourceValidity}.
+     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
+     */
+    public SourceValidity getValidity() {
+        if (validity == null) {
+            validity = new MultiSourceValidity(resolver, -1);
+        }
+        return validity;
+    }
+
+    /**
+     * Description of the include element
+     */
+    private class IncludeElement {
+        /** Parameter controlling recursive includes processing */
+        private boolean recursive;
+
+        /** Parameter controlling parallel (in multiple threads) includes processing */
+        private boolean parallel;
+
+        /** Parameter controlling parallel (in multiple threads) includes processing in recursive includes */
+        private boolean recursiveParallel;
+
+        /** The source base URI. */
+        private String base;
+
+        /** The source URI to be included declared in an src attribute of the include element. */
+        private String source;
+
+        /** The flag indicating whether source content has to be parsed into XML or included as text. */
+        private boolean parse;
+
+        /** The mime type hint to the {@link org.apache.excalibur.xmlizer.XMLizer} when parsing the source content. */
+        private String mimeType;
+
+        /** The buffer collecting fallback content. */
+        private SaxBuffer fallback;
+
+        /** A {@link Map} of the parameters to supply to the included source. */
+        private Map parameters;
+
+        /** The current parameter name captured. */
+        private String parameter;
+
+        /** The current parameter value (as a {@link StringBuffer}). */
+        private StringBuffer value;
+
+        /** Create include element */
+        private IncludeElement(String base, boolean parallel, boolean recursive, boolean recursiveParallel) {
+            this.base = base;
+            this.parallel = parallel;
+            this.recursive = recursive;
+            this.recursiveParallel = recursiveParallel;
+        }
+
+        /**
+         * Process element into the buffer.
+         * This can not be shared buffer, as it must be cleaned if fallback is invoked.
+         */
+        public void process(SaxBuffer buffer)
+        throws SAXException {
+            try {
+                process0(buffer, buffer);
+            } catch (SAXException e) {
+                buffer.recycle();
+                if (this.fallback == null) {
+                    throw e;
+                }
+
+                if (getLogger().isInfoEnabled()) {
+                    getLogger().info("Failed to load <" + this.source + ">, using fallback.", e);
+                }
+                // Stream fallback through IncludeXMLPipe
+                this.fallback.toSAX(new IncludeXMLPipe(getLogger(), buffer, buffer,
+                                                       recursive, recursiveParallel? parallel: false, recursiveParallel));
+            }
+        }
+
+        /** Load URI into the provided handlers, process fallback */
+        public void process(ContentHandler contentHandler, LexicalHandler lexicalHandler)
+        throws SAXException {
+            if (this.fallback != null) {
+                SaxBuffer buffer = new SaxBuffer();
+                process(buffer);
+                buffer.toSAX(contentHandler);
+            } else {
+                process0(contentHandler, lexicalHandler);
+            }
+        }
+
+        /** Load URI into the provided handlers. */
+        private void process0(ContentHandler contentHandler, LexicalHandler lexicalHandler)
+        throws SAXException {
+            Source source = null;
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Loading <" + this.source + ">");
+            }
+
+            // Setup this thread's environment
+            try {
+                if (base != null) {
+                    source = resolver.resolveURI(this.source, base, null);
+                } else {
+                    source = resolver.resolveURI(this.source);
+                }
+                if (validity != null) {
+                    synchronized (validity) {
+                        validity.addSource(source);
+                    }
+                }
+
+                // Include source
+                if (this.parse && recursive) {
+                    SourceUtil.toSAX(manager, source, this.mimeType,
+                                     new IncludeXMLPipe(getLogger(), contentHandler, lexicalHandler,
+                                                        recursive, recursiveParallel? parallel: false, recursiveParallel));
+                } else if (this.parse) {
+                    SourceUtil.toSAX(manager, source, this.mimeType,
+                                     new IncludeXMLConsumer(contentHandler, lexicalHandler));
+                } else {
+                    SourceUtil.toCharacters(source, "utf-8",
+                                            contentHandler);
+                }
+
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Loaded <" + this.source + ">");
+                }
+            } catch (SAXException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Failed to load <" + this.source + ">", e);
+                }
+
+                throw e;
+
+            } catch (ProcessingException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Failed to load <" + this.source + ">", e);
+                }
+
+                throw new SAXException(e);
+
+            } catch (IOException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Failed to load <" + this.source + ">", e);
+                }
+
+                throw new SAXException(e);
+
+            } finally {
+                if (source != null) {
+                    resolver.release(source);
+                }
+            }
+        }
+    }
+
+    /**
+     * XML pipe reacting on the elements in the include namespace.
+     */
+    private class IncludeXMLPipe extends AbstractXMLPipe {
+
+        //
+        // Configuration
+        //
+
+        /** Indicates whether this is root include pipe (owned by transformer) or a nested one */
+        private final boolean root;
+
+        /** Parameter controlling recursive includes processing */
+        private boolean recursive;
+
+        /** Parameter controlling parallel (in multiple threads) includes processing */
+        private boolean parallel;
+
+        /** Parameter controlling parallel (in multiple threads) includes processing in recursive includes */
+        private boolean recursiveParallel;
+
+        //
+        // Current state
+        //
+
+        /** Stack of {@link XMLConsumer}s */
+        private final Stack consumers = new Stack();
+
+        /** Current depth of nested elements in the include namespace */
+        private int depth;
+
+        /** Base URI used for the resolving included sources */
+        private String base;
+
+        /** The source to be included declared in an include element. */
+        private IncludeElement element;
+
+        /** If parallel processing is enabled, then this boolean tells us whether buffering has started yet. */
+        private boolean buffering;
+
+        /**
+         * <p>The IncludeBuffer that is used to buffering events if parallel
+         * processing is turned on.</p>
+         * <p>This object is also used as a lock for the thread counter <code>threads</code>.</p>
+         */
+        private SaxBuffer buffer;
+
+        /** Inclusion threads/tasks counter (if executing in parallel) */
+        private int threads;
+
+        /**
+         * <p>Create a new {@link IncludeXMLPipe} instance.</p>
+         */
+        public IncludeXMLPipe() {
+            root = true;
+        }
+
+        /**
+         * <p>Create a new {@link IncludeXMLPipe} instance.</p>
+         */
+        public IncludeXMLPipe(Logger logger, ContentHandler contentHandler, LexicalHandler lexicalHandler,
+                              boolean recursive, boolean parallel, boolean recursiveParallel) {
+            root = false;
+            enableLogging(logger);
+            setContentHandler(contentHandler);
+            setLexicalHandler(lexicalHandler);
+            this.recursive = recursive;
+            this.parallel = parallel;
+            this.recursiveParallel = recursiveParallel;
+        }
+
+        /**
+         * Finish processing.
+         */
+        public void recycle() {
+            if (this.buffering) {
+                // Wait for threads to complete and release Sources
+                waitForThreads();
+                this.buffering = false;
+                this.buffer = null;
+            }
+            this.threads = 0;
+
+            this.consumers.clear();
+            this.base = null;
+            this.element = null;
+
+            super.recycle();
+        }
+
+        /** Push current consumer into the stack, replace with new one */
+        private void push(XMLConsumer consumer) {
+            this.consumers.push(new Object[]{ super.xmlConsumer, super.contentHandler, super.lexicalHandler });
+            setConsumer(consumer);
+        }
+
+        /** Pop consumer from the stack, replace current one */
+        private void pop() {
+            Object[] consumer = (Object[]) this.consumers.pop();
+            if (consumer[0] != null) {
+                setConsumer((XMLConsumer) consumer[0]);
+            } else {
+                setContentHandler((ContentHandler) consumer[1]);
+                setLexicalHandler((LexicalHandler) consumer[2]);
+            }
+        }
+
+        //
+        // ContentHandler interface
+        //
+
+        public void setDocumentLocator(Locator locator) {
+            try {
+                if (locator != null && locator.getSystemId() != null) {
+                    Source source = resolver.resolveURI(locator.getSystemId());
+                    try {
+                        base = source.getURI();
+                    } finally {
+                        resolver.release(source);
+                    }
+                }
+            } catch (IOException e) {
+                getLogger().warn("Unable to resolve document base URI: <" + locator.getSystemId() + ">");
+            }
+
+            super.setDocumentLocator(locator);
+        }
+
+        /**
+         * <p>Receive notification of the beginning of an XML document.</p>
+         * @see ContentHandler#startDocument
+         */
+        public void startDocument() throws SAXException {
+            if (root) {
+                super.startDocument();
+            }
+        }
+
+        /**
+         * <p>Receive notification of the end of an XML document.</p>
+         * @see ContentHandler#startDocument
+         */
+        public void endDocument() throws SAXException {
+            /* This is the end of the line - process the buffered events */
+            if (this.buffering) {
+                pop();
+                this.buffer.toSAX(super.contentHandler);
+            }
+
+            if (root) {
+                super.endDocument();
+            }
+        }
+
+        /**
+         * <p>Receive notification of the start of an element.</p>
+         * @see ContentHandler#startElement
+         */
+        public void startElement(String uri, String localName, String qName, Attributes atts)
+        throws SAXException {
+
+            /* Check the namespace declaration */
+            if (NS_URI.equals(uri)) {
+
+                /*
+                 * Depth 0: Outside of any include tag
+                 * Depth 1: Must be Inside <include> tag
+                 * Depth 2: Inside <fallback> tag
+                 */
+                depth++;
+
+                /* Inclusion will not happen here but when we close this tag */
+                if (INCLUDE_ELEMENT.equals(localName) && depth == 1) {
+                    /* Check before we include (we don't want nested stuff) */
+                    if (element != null) {
+                        throw new SAXException("Element " + INCLUDE_ELEMENT + " nested in another one.");
+                    }
+                    element = new IncludeElement(this.base, this.parallel, this.recursive, this.recursiveParallel);
+
+                    /* Remember the source we are trying to include */
+                    element.source = atts.getValue(SRC_ATTRIBUTE);
+                    if (element.source == null || element.source.length() == 0) {
+                        throw new SAXException("Attribute '" + SRC_ATTRIBUTE + "' empty or missing.");
+                    }
+
+                    /* Defaults to 'xml' */
+                    String value = atts.getValue(PARSE_ATTRIBUTE);
+                    if (value == null || value.equals("xml")) {
+                        element.parse = true;
+                    } else if (value.equals("text")) {
+                        element.parse = false;
+                    } else {
+                        throw new SAXException("Attribute '" + PARSE_ATTRIBUTE + "' has invalid value.");
+                    }
+
+                    /* Defaults to 'text/xml' */
+                    element.mimeType = atts.getValue(MIME_ATTRIBUTE);
+                    if (!element.parse && element.mimeType != null) {
+                        throw new SAXException("Attribute '" + MIME_ATTRIBUTE + "' can't be specified for text inclusions.");
+                    } else if (element.mimeType == null) {
+                        element.mimeType = "text/xml";
+                    }
+
+                    /* Ignore nested content */
+                    push(new NOPRecorder(){});
+
+                    /* Done with this element */
+                    return;
+                }
+
+                /* If this is a fallback parameter, capture its content. */
+                if (FALLBACK_ELEMENT.equals(localName) && depth == 2) {
+                    /* Check if we are in the right context */
+                    if (element == null) {
+                        throw new SAXException("Element " + FALLBACK_ELEMENT + " specified outside of " + INCLUDE_ELEMENT + ".");
+                    }
+                    if (element.fallback != null) {
+                        throw new SAXException("Duplicate element " + FALLBACK_ELEMENT + ".");
+                    }
+
+                    /* Buffer fallback content */
+                    push(element.fallback = new SaxBuffer());
+
+                    /* Done with this element */
+                    return;
+                }
+
+                /* If this is a parameter, then make sure we prepare. */
+                if (PARAMETER_ELEMENT.equals(localName) && depth == 2) {
+                    /* Check if we are in the right context */
+                    if (element == null) {
+                        throw new SAXException("Element " + PARAMETER_ELEMENT + " specified outside of " + INCLUDE_ELEMENT + ".");
+                    }
+                    if (element.parameter != null) {
+                        throw new SAXException("Element " + PARAMETER_ELEMENT + " nested in another one.");
+                    }
+
+                    /* Get and process the parameter name */
+                    element.parameter = atts.getValue(NAME_ATTRIBUTE);
+                    if (element.parameter == null || element.parameter.length() == 0) {
+                        throw new SAXException("Attribute '" + NAME_ATTRIBUTE + "' empty or missing.");
+                    }
+
+                    /* Make some room for the parameter value */
+                    String value = atts.getValue(VALUE_ATTRIBUTE);
+                    if (value != null) {
+                        element.value = new StringBuffer(value);
+                    }
+
+                    /* Done with this element */
+                    return;
+                }
+
+                /* We don't have a clue of why we got here (wrong element?) */
+                if (depth < 2) {
+                    throw new SAXException("Element '" + localName + "' was not expected here.");
+                }
+            }
+
+            super.startElement(uri, localName, qName, atts);
+        }
+
+        /**
+         * <p>Receive notification of the end of an element.</p>
+         * @see ContentHandler#endElement
+         */
+        public void endElement(String uri, String localName, String qName)
+        throws SAXException {
+            /* Check the namespace declaration */
+            if (NS_URI.equals(uri)) {
+
+                /*
+                 * Depth 0: Outside of any include tag
+                 * Depth 1: Inside <include> tag
+                 * Depth 2: Inside <fallback> tag
+                 */
+                depth--;
+
+                /* Inclusion will happen here, when we close the include element */
+                if (INCLUDE_ELEMENT.equals(localName) && depth == 0) {
+                    /* End ignoring nested content */
+                    pop();
+
+                    /* Get the source discovered opening the element and include */
+                    if (element.parameters != null) {
+                        element.source = NetUtils.parameterize(element.source,
+                                                               element.parameters);
+                        element.parameters = null;
+                    }
+
+                    /* Check for parallel processing */
+                    if (this.parallel) {
+                        if (!this.buffering) {
+                            this.buffering = true;
+                            buffer = new SaxBuffer();
+                            push(buffer);
+                        }
+
+                        /* Process include element in separate thread */
+                        buffer.xmlizable(new IncludeBuffer(element));
+
+                    } else {
+                        /* Process include element inline */
+                        element.process(super.contentHandler, super.lexicalHandler);
+                    }
+
+                    /* We are done with this include element */
+                    this.element = null;
+                    return;
+                }
+
+                if (FALLBACK_ELEMENT.equals(localName) && depth == 1) {
+                    /* End buffering fallback content */
+                    pop();
+
+                    /* Done with this element */
+                    return;
+                }
+
+                /* Addition of parameters happens here (so that we can capture chars) */
+                if (PARAMETER_ELEMENT.equals(localName) && depth == 1) {
+                    String value = (element.value != null? element.value.toString(): "");
+
+                    /* Store the parameter name and value */
+                    try {
+                        /*
+                         * Note: the parameter name and value are URL encoded, so that
+                         * weird characters such as "&" or "=" (have special meaning)
+                         * are passed through flawlessly.
+                         */
+                        if (element.parameters == null) {
+                            element.parameters = new HashMap(5);
+                        }
+                        element.parameters.put(NetUtils.encode(element.parameter, ENCODING),
+                                               NetUtils.encode(value, ENCODING));
+                    } catch (UnsupportedEncodingException e) {
+                        throw new SAXException("Your platform does not support the " +
+                                               ENCODING + " encoding", e);
+                    }
+
+                    /* We are done with this parameter element */
+                    element.value = null;
+                    element.parameter = null;
+                    return;
+                }
+            }
+
+            /* This is not our namespace, pass the event on! */
+            super.endElement(uri, localName, qName);
+        }
+
+        /**
+         * <p>Receive notification of characters.</p>
+         * @see ContentHandler#characters
+         */
+        public void characters(char[] data, int offset, int length)
+        throws SAXException {
+            if (element != null && element.parameter != null) {
+                /* If we have a parameter value to add to, let's add this chunk */
+                if (element.value == null) {
+                    element.value = new StringBuffer();
+                }
+                element.value.append(data, offset, length);
+                return;
+            }
+
+            /* Forward */
+            super.characters(data, offset, length);
+        }
+
+        //
+        // Thread management
+        //
+
+        /**
+         * Increment active threads counter
+         */
+        int incrementThreads() {
+            synchronized (buffer) {
+                return ++threads;
+            }
+        }
+
+        /**
+         * Decrement active threads counter
+         */
+        void decrementThreads() {
+            synchronized (buffer) {
+                if (--threads <= 0) {
+                    buffer.notify();
+                }
+            }
+        }
+
+        /**
+         * Wait till there is no active threads
+         */
+        private void waitForThreads() {
+            synchronized (buffer) {
+                if (threads > 0) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug(threads + " threads in progress, waiting");
+                    }
+
+                    try {
+                        buffer.wait();
+                    } catch (InterruptedException ignored) { }
+                    // Don't continue waiting if interrupted.
+                }
+            }
+        }
+
+        /**
+         * Buffer for loading included source in separate thread.
+         * Streaming of the loaded buffer possible only when source is
+         * loaded completely. If loading is not complete, toSAX method
+         * will block.
+         */
+        private class IncludeBuffer extends SaxBuffer
+                                    implements Runnable {
+
+            private IncludeElement element;
+            private int thread;
+            private boolean finished;
+            private SAXException e;
+
+
+            public IncludeBuffer(IncludeElement element) {
+                this.element = element;
+
+                RunnableManager runnable = null;
+                try {
+                    runnable = (RunnableManager) IncludeTransformer.this.manager.lookup(RunnableManager.ROLE);
+                    runnable.execute(IncludeTransformer.this.threadPool, this);
+                } catch (final ServiceException e) {
+                    // In case we failed to spawn a thread
+                    throw new CascadingRuntimeException(e.getMessage(), e);
+                } finally {
+                    IncludeTransformer.this.manager.release(runnable);
+                }
+
+                // Increment active threads counter
+                this.thread = incrementThreads();
+            }
+
+            /**
+             * Load content of the source into this buffer.
+             */
+            public void run() {
+                try {
+                    Source source = null;
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Thread #" + thread + " loading <" + element.source + ">");
+                    }
+
+                    // Setup this thread's environment
+                    EnvironmentHelper.enterProcessor(processor, manager, environment);
+                    try {
+                        element.process(this);
+
+                    } catch (SAXException e) {
+                        this.e = e;
+
+                    } finally {
+                        if (source != null) {
+                            resolver.release(source);
+                        }
+                        EnvironmentHelper.leaveProcessor();
+                    }
+                } catch (ProcessingException e) {
+                    /* Unable to set thread's environment */
+                    this.e = new SAXException(e);
+
+                } finally {
+                    synchronized (this) {
+                        this.finished = true;
+                        notify();
+                    }
+
+                    // Make sure that active threads counter is decremented
+                    decrementThreads();
+                }
+
+                if (getLogger().isDebugEnabled()) {
+                    if (this.e == null) {
+                        getLogger().debug("Thread #" + thread + " loaded <" + element.source + ">");
+                    } else {
+                        getLogger().debug("Thread #" + thread + " failed to load <" + element.source + ">", this.e);
+                    }
+                }
+            }
+
+            /**
+             * Stream content of this buffer when it is loaded completely.
+             * This method blocks if loading is not complete.
+             */
+            public void toSAX(ContentHandler contentHandler)
+            throws SAXException {
+                synchronized (this) {
+                    if (!this.finished) {
+                        try {
+                            wait();
+                        } catch (InterruptedException ignored) { }
+                        // Don't continue waiting if interrupted.
+                    }
+                }
+
+                if (this.e != null) {
+                    throw this.e;
+                }
+
+                super.toSAX(contentHandler);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/JPathTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/JPathTransformer.java
new file mode 100644
index 0000000..410381a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/JPathTransformer.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.flow.WebContinuation;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.regexp.RE;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ *  Transformer implementation of the JPath XSP tag library.
+ *
+ * @cocoon.sitemap.component.name   jpath
+ * @cocoon.sitemap.component.logger sitemap.transformer.jpath
+ *
+ *
+ * <p>
+ *  This transformer (so far) supports the following jpath elements:
+ *
+ *   <ul>
+ *     <li>&lt;jpath:value-of select=".."/&gt; element.
+ *     <li>&lt;jpath:continuation/&gt; element.
+ *     <li>&lt;jpath:if test=".."&gt;..&lt;/jpath:if&gt; element.
+ *     <li>jpath:action attribute on all elements that implicitly replaces any
+ *         occurance of the string 'id' with the continuation id (useful when
+ *         writing form action attributes). eg:
+ *         <pre>&lt;form name="myform" jpath:action="../cont/id"&gt;..&lt;/form&gt;</pre>
+ *   </ul>
+ * </p>
+ *
+ * @version $Id$
+ */
+public class JPathTransformer extends AbstractSAXTransformer
+                              implements Initializable {
+
+    /** namespace constant */
+    public static final String JPATH_NAMESPACE_URI  = "http://apache.org/xsp/jpath/1.0";
+
+    /** jpath:action attribute constant */
+    public static final String JPATH_ACTION         = "jpath:action";
+
+    /** jpath:value-of element constant */
+    public static final String JPATH_VALUEOF        = "value-of";
+
+    /** jpath:value-of select attribute constant */
+    public static final String JPATH_VALUEOF_SELECT = "select";
+
+    /** jpath:continuation element constant */
+    public static final String JPATH_CONTINUATION   = "continuation";
+
+    /** jpath:continuation select attribute constant */
+    public static final String JPATH_CONTINUATION_SELECT = "select";
+
+    /** jpath:if element constant */
+    public static final String JPATH_IF             = "if";
+
+    /** jpath generic test attribute */
+    public static final String JPATH_TEST           = "test";
+
+    // web contination
+    private WebContinuation m_kont;
+
+    // regular expression for matching 'id' strings with jpath:action
+    private RE m_re;
+
+    // jxpath context
+    private JXPathContext m_jxpathContext;
+
+    // jpath:value-of variable cache
+    private Map m_cache;
+
+    /**
+     * Constructor. Set namespace.
+     */
+    public JPathTransformer() {
+        super.defaultNamespaceURI = JPATH_NAMESPACE_URI;
+    }
+
+    /**
+     * Initialize this transformer.
+     *
+     * @exception Exception if an error occurs
+     */
+    public void initialize() throws Exception {
+        m_re = new RE("id");
+        m_cache = new HashMap();
+    }
+
+    /**
+     * Setup this transformer
+     *
+     * @param resolver a {@link SourceResolver} instance
+     * @param objectModel the objectModel
+     * @param src <code>src</code> parameter
+     * @param parameters optional parameters
+     * @exception ProcessingException if an error occurs
+     * @exception SAXException if an error occurs
+     * @exception IOException if an error occurs
+     */
+    public void setup(SourceResolver resolver, Map objectModel,
+                      String src, Parameters parameters)
+        throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, parameters);
+
+        // setup the jpath transformer for this thread
+        Object bean = FlowHelper.getContextObject(objectModel);
+        m_kont = FlowHelper.getWebContinuation(objectModel);
+        m_jxpathContext = JXPathContext.newContext(bean);
+    }
+
+    /**
+     * Intercept startElement to ensure all &lt;jpath:action&gt; attributes
+     * are modified.
+     *
+     * @param uri a <code>String</code> value
+     * @param loc a <code>String</code> value
+     * @param raw a <code>String</code> value
+     * @param a an <code>Attributes</code> value
+     * @exception SAXException if an error occurs
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+        throws SAXException {
+
+        AttributesImpl impl = new AttributesImpl(a);
+        checkJPathAction(impl);
+
+        super.startElement(uri, loc, raw, impl);
+    }
+
+    /**
+     * Entry method for all elements in our namespace
+     *
+     * @param uri a <code>String</code> value
+     * @param name a <code>String</code> value
+     * @param raw a <code>String</code> value
+     * @param attr an <code>Attributes</code> value
+     * @exception ProcessingException if an error occurs
+     * @exception IOException if an error occurs
+     * @exception SAXException if an error occurs
+     */
+    public void startTransformingElement(
+        String uri, String name, String raw, Attributes attr
+    )
+        throws ProcessingException ,IOException, SAXException {
+
+        if (JPATH_VALUEOF.equals(name)) {
+            doValueOf(attr);
+        } else if (JPATH_CONTINUATION.equals(name)) {
+            doContinuation(attr);
+        } else if (JPATH_IF.equals(name)) {
+            doIf(attr);
+        } else {
+            super.startTransformingElement(uri, name, raw, attr);
+        }
+    }
+
+    /**
+     * Exit method for all elements in our namespace
+     *
+     * @param uri a <code>String</code> value
+     * @param name a <code>String</code> value
+     * @param raw a <code>String</code> value
+     * @exception ProcessingException if an error occurs
+     * @exception IOException if an error occurs
+     * @exception SAXException if an error occurs
+     */
+    public void endTransformingElement(
+        String uri, String name, String raw
+    )
+        throws ProcessingException, IOException, SAXException {
+
+        if (JPATH_VALUEOF.equals(name) ||
+            JPATH_CONTINUATION.equals(name)) {
+            return; // do nothing
+        } else if (JPATH_IF.equals(name)) {
+            finishIf();
+        } else {
+            super.endTransformingElement(uri, name, raw);
+        }
+    }
+
+    /**
+     * Helper method to check for the existance of an attribute named
+     * jpath:action. If existing the string 'id' is replaced with the
+     * continuation id.
+     *
+     * @param a an {@link AttributesImpl} instance
+     */
+    private void checkJPathAction(final AttributesImpl a) {
+
+        // check for jpath:action attribute
+        int idx = a.getIndex(JPATH_ACTION);
+
+        if (idx != -1 && JPATH_NAMESPACE_URI.equals(a.getURI(idx))) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("found jpath:action, adjusting");
+            }
+
+            String value = a.getValue(idx);
+
+            // REVISIT(MC): support for continuation level
+            String id = m_kont.getContinuation(0).getId();
+
+            a.removeAttribute(idx);
+            a.addAttribute(
+                "", "action", "action", "CDATA", m_re.subst(value, id)
+            );
+        }
+    }
+
+    /**
+     * Helper method for obtaining the value of a particular variable.
+     *
+     * @param variable variable name
+     * @return variable value as an <code>Object</code>
+     */
+    private Object getValue(final String variable) {
+
+        Object value;
+
+        if (m_cache.containsKey(variable)) {
+            value = m_cache.get(variable);
+        } else {
+            value = JXPathContext.compile(variable).getValue(m_jxpathContext);
+
+            if (value == null) {
+                if (getLogger().isWarnEnabled()) {
+                    final String msg =
+                        "Value for jpath variable '" + variable + "' does not exist";
+                    getLogger().warn(msg);
+                }
+            }
+
+            m_cache.put(variable, value);
+        }
+
+        return value;
+    }
+
+    /**
+     * Helper method to process a &lt;jpath:value-of select="."&gt; tag
+     *
+     * @param a an {@link Attributes} instance
+     * @exception SAXException if a SAX error occurs
+     * @exception ProcessingException if a processing error occurs
+     */
+    private void doValueOf(final Attributes a)
+        throws SAXException, ProcessingException {
+
+        final String select = a.getValue(JPATH_VALUEOF_SELECT);
+
+        if (null != select) {
+            sendTextEvent((String)getValue(select));
+        } else {
+            throw new ProcessingException(
+                "jpath:" + JPATH_VALUEOF + " specified without a select attribute"
+            );
+        }
+    }
+
+    /**
+     * Helper method to process a &lt;jpath:continuation select=""/&gt; element.
+     *
+     * @param a an <code>Attributes</code> value
+     * @exception SAXException if an error occurs
+     */
+    private void doContinuation(final Attributes a)
+        throws SAXException {
+
+        final String level = a.getValue(JPATH_CONTINUATION_SELECT);
+
+        final String id = (level != null)
+            ? m_kont.getContinuation(Integer.decode(level).intValue()).getId()
+            : m_kont.getContinuation(0).getId();
+
+        sendTextEvent(id);
+    }
+
+    /**
+     * Helper method to process a &lt;jpath:if test="..."&gt; element.
+     *
+     * @param a an <code>Attributes</code> value
+     * @exception SAXException if an error occurs
+     */
+    private void doIf(final Attributes a)
+        throws SAXException {
+
+        // handle nested jpath:if statements, if ignoreEventsCount is > 0, then
+        // we are processing a nested jpath:if statement for which the parent
+        // jpath:if test resulted in a false (ie. disallow subelements) result.
+
+        if (ignoreEventsCount > 0) {
+            ++ignoreEventsCount;
+            return;
+        }
+
+        // get the test variable
+        final Object value = getValue(a.getValue(JPATH_TEST));
+
+        final boolean isTrueBoolean =
+            value instanceof Boolean && ((Boolean)value).booleanValue() == true;
+        final boolean isNonNullNonBoolean =
+            value != null && !(value instanceof Boolean);
+
+        if (isTrueBoolean || isNonNullNonBoolean) {
+            // do nothing, allow all subelements
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("jpath:if results in allowing subelements");
+            }
+        } else {
+            // disallow all subelements
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("jpath:if results in disallowing subelements");
+            }
+            ++ignoreEventsCount;
+        }
+    }
+
+    /**
+     * Helper method to process a &lt;/jpath:if&gt; element.
+     *
+     * @exception SAXException if an error occurs
+     */
+    private void finishIf()
+        throws SAXException {
+
+        // end recording (and dump resulting document fragment) if we've reached
+        // the closing jpath:if tag for which the recording was started.
+        if (ignoreEventsCount > 0) {
+            --ignoreEventsCount;
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("jpath:if closed");
+        }
+    }
+
+    /**
+     * Release all held resources.
+     */
+    public void recycle() {
+        m_cache.clear();
+        m_kont = null;
+        m_jxpathContext = null;
+
+        super.recycle();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/LogTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/LogTransformer.java
new file mode 100644
index 0000000..26f5b8d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/LogTransformer.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The <code>LogTransformer</code> is a class that can be plugged into a pipeline
+ * to print the SAX events which passes thru this transformer in a readable form
+ * to a file.
+ * 
+ * @cocoon.sitemap.component.name  log
+ * @cocoon.sitemap.component.logger sitemap.transformer.log
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ *
+ * The <code>LogTransformer</code> is a class that can be plugged into a pipeline
+ * to print the SAX events which passes thru this transformer in a readable form
+ * to a file.
+ * <br>
+ * The file will be specified in a parameter tag in the sitemap pipeline to the
+ * transformer as follows:
+ * <p>
+ * <pre>
+ * &lt;map:transform type="log"&gt;
+ * &nbsp;&nbsp;&lt;map:parameter name="logfile" value="logfile.log"/&gt;
+ * &nbsp;&nbsp;&lt;map:parameter name="append" value="no"/&gt;
+ * &lt;/map:transform&gt;
+ * </pre>
+ * </p>
+ *
+ * Because the log file will be hardcoded into the sitemap this LOGTransformer will
+ * not be thread save!!
+ * <br>
+ * This transformations main purpose is debugging.
+ *
+ * @version $Id$
+ *
+ */
+public class LogTransformer
+  extends AbstractTransformer {
+
+    private static String lf = System.getProperty("line.separator", "\n");
+
+    /** log file */
+    private FileWriter logfile;
+
+    /**
+     * Setup
+     */
+    public void setup(SourceResolver resolver, Map objectModel,
+                      String src, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        final boolean append = parameters.getParameterAsBoolean("append", false);
+        final String  logfilename = parameters.getParameter("logfile", null);
+
+        // Check for null, use System.out if logfile is not specified.
+        this.logfile = null;
+        if ( null != logfilename ) {
+            Source source = null;
+            try {
+                source = resolver.resolveURI( logfilename );
+                final String systemId = source.getURI();
+                if ( systemId.startsWith("file:") ) {
+                    this.logfile = new FileWriter(systemId.substring(5), append );
+                } else {
+                    throw new ProcessingException("The logfile parameter must point to a file: " + logfilename);
+                }
+            } catch (SourceException se) {
+                throw SourceUtil.handle(se);
+            } finally {
+                resolver.release( source );
+            }
+        }
+
+        Date date = new Date();
+        StringBuffer logEntry = new StringBuffer();
+        logEntry.append ( "---------------------------- [" );
+        logEntry.append ( date.toString() );
+        logEntry.append ( "] ----------------------------" );
+        this.log("setup", logEntry.toString());
+    }
+
+    /**
+     * Recycle
+     */
+    public void recycle() {
+        super.recycle();
+        try {
+            if (this.logfile != null) logfile.close();
+        } catch (Exception e) {
+            this.getLogger().warn("LogTransformer.recycle()", e);
+        }
+        this.logfile = null;
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     */
+    public void setDocumentLocator(Locator locator) {
+        this.log("setDocumentLocator", locator != null ? "systemid="+locator.getSystemId()+",publicid="+locator.getPublicId() : "(locator is null)");
+        if (super.contentHandler!=null) {
+            super.contentHandler.setDocumentLocator(locator);
+        }
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument()
+    throws SAXException {
+        this.log("startDocument", "");
+        if (super.contentHandler!=null) {
+            super.contentHandler.startDocument();
+        }
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument()
+    throws SAXException {
+        this.log ("endDocument", "");
+        if (super.contentHandler!=null) {
+            super.contentHandler.endDocument();
+        }
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        this.log ("startPrefixMapping", "prefix="+prefix+",uri="+uri);
+        if (super.contentHandler!=null) {
+            super.contentHandler.startPrefixMapping(prefix,uri);
+        }
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        this.log ("endPrefixMapping", "prefix="+prefix);
+        if (super.contentHandler!=null) {
+            super.contentHandler.endPrefixMapping(prefix);
+        }
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        this.log ("startElement", "uri="+uri+",local="+loc+",raw="+raw);
+        for (int i = 0; i < a.getLength(); i++) {
+            this.log ("            ", new Integer(i+1).toString()
+                 +". uri="+a.getURI(i)
+                 +",local="+a.getLocalName(i)
+                 +",qname="+a.getQName(i)
+                 +",type="+a.getType(i)
+                 +",value="+a.getValue(i));
+        }
+        if (super.contentHandler!=null) {
+            super.contentHandler.startElement(uri,loc,raw,a);
+        }
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        this.log ("endElement", "uri="+uri+",local="+loc+",raw="+raw);
+        if (super.contentHandler!=null) {
+            super.contentHandler.endElement(uri,loc,raw);
+        }
+    }
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters(char ch[], int start, int len)
+    throws SAXException {
+        this.log ("characters", new String(ch,start,len));
+        if (super.contentHandler!=null) {
+            super.contentHandler.characters(ch,start,len);
+        }
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace(char ch[], int start, int len)
+    throws SAXException {
+        this.log ("ignorableWhitespace", new String(ch,start,len));
+        if (super.contentHandler!=null) {
+            super.contentHandler.ignorableWhitespace(ch,start,len);
+        }
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        log ("processingInstruction", "target="+target+",data="+data);
+        if (super.contentHandler!=null) {
+            super.contentHandler.processingInstruction(target,data);
+        }
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        this.log ("skippedEntity", "name="+name);
+        if (super.contentHandler!=null) {
+            super.contentHandler.skippedEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        this.log ("startDTD", "name="+name+",publicId="+publicId+",systemId="+systemId);
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.startDTD(name,publicId,systemId);
+        }
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+        this.log ("endDTD", "");
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.endDTD();
+        }
+    }
+
+    /**
+     * Report the beginning of an entity.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+        this.log ("startEntity", "name="+name);
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.startEntity(name);
+        }
+    }
+
+    /**
+     * Report the end of an entity.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+        this.log ("endEntity", "name="+name);
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.endEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+        this.log ("startCDATA", "");
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.startCDATA();
+        }
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+        this.log ("endCDATA", "");
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.endCDATA();
+        }
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        this.log ("comment", new String(ch,start,len));
+        if (super.lexicalHandler!=null) {
+            super.lexicalHandler.comment(ch,start,len);
+        }
+    }
+
+    /**
+     * Report to logfile.
+     */
+    private void log (String location, String description) {
+        final StringBuffer logEntry = new StringBuffer();
+        logEntry.append ( "[" );
+        logEntry.append ( location );
+        logEntry.append ( "] " );
+        logEntry.append ( description );
+        logEntry.append ( lf );
+        final String text = logEntry.toString();
+        if ( this.getLogger().isInfoEnabled() ) {
+            this.getLogger().info( text );
+        }
+        try {
+            if ( null != this.logfile ) {
+                this.logfile.write( text, 0, text.length());
+                this.logfile.flush();
+            } else {
+                System.out.println( text );
+            }
+        }
+        catch(IOException ioe) {
+            this.getLogger().debug("LogTransformer.log", ioe);
+        }
+    }
+
+    /**
+     *  Attempt to close the log file when the class is GC'd
+     */
+    public void destroy() {
+        try {
+            if (this.logfile != null) logfile.close();
+        } catch (Exception e) {getLogger().debug("LogTransformer.destroy()", e);}
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ReadDOMSessionTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ReadDOMSessionTransformer.java
new file mode 100644
index 0000000..0529d73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ReadDOMSessionTransformer.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * With this transformer, an object that is stored in the session, can be inserted
+ * in the SAX stream at a given position, using usual &lt;xsp:expr&gt; rules.
+ * Object can be DOM Node, XMLizable, or any other object supported by &lt;xsp:expr&gt;.
+ * 
+ * @cocoon.sitemap.component.name   readDOMsession
+ * @cocoon.sitemap.component.logger sitemap.transformer.readDOMsession
+ * 
+ * With this transformer, an object that is stored in the session, can be inserted
+ * in the SAX stream at a given position, using usual &lt;xsp:expr&gt; rules.
+ * Object can be DOM Node, XMLizable, or any other object supported by &lt;xsp:expr&gt;.
+ *
+ * Usage in sitemap:
+ * <pre>
+ *    &lt;map:transform type="read-session"&gt;
+ *      &lt;map:parameter name="attribute-name" value="companyInfo"/&gt;
+ *      &lt;map:parameter name="trigger-element" value="company"/&gt;
+ *      &lt;map:parameter name="position" value="after"/&gt;
+ *    &lt;/map:transform&gt;
+ * </pre>
+ *
+ * Where:
+ * <ul>
+ *  <li><b>attribute-name</b> is the name of the object in the session
+ *  <li><b>trigger-element</b> is the element that we need to insert the SAX events
+ *  <li><b>postion</b> is the actual place where the stream will be inserted, ie before, after or in
+ *  the trigger-element
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class ReadDOMSessionTransformer extends AbstractTransformer  {
+
+    public static final String ATTRIBUTE_NAME = "attribute-name";
+    public static final String TRIGGER_ELEMENT = "trigger-element";
+
+    /*
+      position where the sax events from the dom should be insterted
+      this can be: 'before', 'after' or 'in'
+    */
+    public static final String POSITION = "position";
+
+    Session session;
+    String attributeName;
+    String trigger;
+    String position;
+
+    /** BEGIN SitemapComponent methods **/
+    public void setup(SourceResolver resolver,
+                      Map objectModel,
+                      String source,
+                      Parameters parameters)
+            throws ProcessingException, SAXException, IOException {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        session = request.getSession(false);
+        if (session != null) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Session is available. ID=" + session.getId());
+            }
+            this.attributeName = parameters.getParameter(ATTRIBUTE_NAME, null);
+            if (this.attributeName == null) {
+                // Try old syntax
+                this.attributeName = parameters.getParameter("dom-name", null);
+            }
+
+            this.trigger = parameters.getParameter(TRIGGER_ELEMENT, null);
+            this.position = parameters.getParameter(POSITION, "in");
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug(ATTRIBUTE_NAME + "=" + attributeName + ", "
+                        + TRIGGER_ELEMENT + "=" + trigger + ", "
+                        + POSITION + "=" + position);
+            }
+        } else {
+            getLogger().warn("No session object: Nothing to do.");
+        }
+    }
+    /** END SitemapComponent methods **/
+
+    /** BEGIN SAX ContentHandler handlers **/
+    public void startElement(String uri, String name, String raw, Attributes attributes)
+            throws SAXException {
+        // Start streaming after certain startelement is encountered
+        if (name.equalsIgnoreCase(trigger)) {
+            getLogger().debug("Trigger encountered");
+            if ("before".equalsIgnoreCase(position))  {
+                stream();
+                super.contentHandler.startElement(uri,name,raw,attributes);
+            } else if ("in".equalsIgnoreCase(position))  {
+                super.contentHandler.startElement(uri,name,raw,attributes);
+                stream();
+            } else if ("after".equalsIgnoreCase(position))  {
+                super.contentHandler.startElement(uri,name,raw,attributes);
+            }
+        } else {
+            super.contentHandler.startElement(uri,name,raw,attributes);
+        }
+    }
+
+    public void endElement(String uri,String name,String raw)
+            throws SAXException  {
+        super.contentHandler.endElement(uri,name,raw);
+        if (name.equalsIgnoreCase(trigger)) {
+            if ("after".equalsIgnoreCase(position))  {
+                stream();
+            }
+        }
+    }
+    /** END SAX ContentHandler handlers **/
+
+    /** own methods **/
+    private void stream() throws SAXException  {
+        if (attributeName != null)  {
+            Object node = session.getAttribute(attributeName);
+            if (node != null)  {
+                getLogger().debug("Start streaming");
+                XMLUtils.valueOf(new IncludeXMLConsumer(super.xmlConsumer), node);
+            } else {
+                getLogger().error("No attribute " + attributeName + " in session");
+            }
+        } else {
+            getLogger().error("No "+ ATTRIBUTE_NAME + " parameter specified");
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/RoleFilterTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/RoleFilterTransformer.java
new file mode 100644
index 0000000..3bba217
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/RoleFilterTransformer.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Filter XML fragments based on a user's role.  This will help in
+ * the development of smart forms that must only show information to
+ * people who are logged in and have the correct role.  The Role is
+ * specified by the Request semantics.  You can specify multiple roles
+ * by using comma delimiting.
+ * 
+ * @cocoon.sitemap.component.name   role-filter
+ * @cocoon.sitemap.component.logger sitemap.transformer.role-filter
+ * 
+ * Filter XML fragments based on a user's role.  This will help in
+ * the development of smart forms that must only show information to
+ * people who are logged in and have the correct role.  The Role is
+ * specified by the Request semantics.  You can specify multiple roles
+ * by using comma delimiting.
+ *
+ * <pre>
+ *   &lt;root xmlns:roles="http://apache.org/cocoon/role-filter/1.0"&gt;
+ *     &lt;textbox name="identifier" roles:restricted="admin,boss"/&gt;
+ *     &lt;textbox name="name" roles:read-only="admin,boss"/&gt;
+ *   &lt;/root&gt;
+ * </pre>
+ *
+ * The previous example will only show the "identifier" textbox for the
+ * roles "admin" and "boss".  It will pass role:read-only="" if the
+ * roles "admin" or "boss" are accessing the page.  That way you can
+ * specify any special processing by testing for the read-only attribute.
+ * This filter does not care about the prefix, only the namespace URI.
+ * That means you can reassign the namespace to another prefix and all
+ * will work as expected.
+ *
+ * @version $Id$
+ */
+public class RoleFilterTransformer extends FilterTransformer {
+    private final static String URI = "http://apache.org/cocoon/role-filter/1.0";
+    private final static String RESTRICT = "restricted";
+    private final static String VIEW = "read-only";
+    Request request = null;
+
+    public RoleFilterTransformer() {
+    }
+
+    public final void setup(SourceResolver resolver, Map objectModel, String src, Parameters params)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, params);
+        this.request = ObjectModelHelper.getRequest(objectModel);
+    }
+
+    /**
+     * Disable caching
+     */
+    public java.io.Serializable getKey() {
+        return null;
+    }
+
+    public final void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        int roleIndex = a.getIndex(RoleFilterTransformer.URI, RoleFilterTransformer.RESTRICT);
+        int viewIndex = a.getIndex(RoleFilterTransformer.URI, RoleFilterTransformer.VIEW);
+        boolean propogate = true;
+        boolean readOnly = false;
+
+        if (roleIndex >= 0) {
+            String roleRestriction = a.getValue(roleIndex);
+            StringTokenizer roles = new StringTokenizer(roleRestriction, ",", false);
+            propogate = false;
+
+            while ((! propogate) && roles.hasMoreTokens()) {
+                if (request.isUserInRole(roles.nextToken())) {
+                    propogate = true;
+                }
+            }
+        }
+
+        if (! propogate) {
+            super.elementName = loc;
+        } else {
+            if (viewIndex >= 0) {
+                String viewRestriction = a.getValue(viewIndex);
+                StringTokenizer roles = new StringTokenizer(viewRestriction, ",", false);
+
+                while ((! readOnly) && roles.hasMoreTokens()) {
+                    if (request.isUserInRole(roles.nextToken())) {
+                        readOnly = true;
+                    }
+                }
+            }
+        }
+
+        super.startElement(uri, loc, raw,
+                this.copyAttributes(a, roleIndex, viewIndex, readOnly));
+    }
+
+    public final void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        super.endElement(uri, loc, raw);
+
+        if (! super.skip) {
+            super.elementName = "";
+        }
+    }
+
+    private final Attributes copyAttributes(final Attributes a, final int role,
+                                            final int view, boolean readOnly) {
+        if (role < 0 && view < 0) {
+            return a;
+        }
+
+        AttributesImpl attr = new AttributesImpl();
+        attr.setAttributes(a);
+        if (role >= 0) {
+            attr.removeAttribute(role);
+        }
+
+        if (view >= 0) {
+            if (readOnly) {
+                attr.setValue(view, "");
+            } else {
+                attr.removeAttribute(view);
+            }
+        }
+
+        return attr;
+    }
+
+    public void recycle() {
+        this.request = null;
+        super.recycle();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ServiceableTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ServiceableTransformer.java
new file mode 100644
index 0000000..8fea26f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/ServiceableTransformer.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.xml.sax.SAXException;
+
+/**
+ * This class can be used as a base class for own transformer implementations
+ * that need to lookup other components.
+ * 
+ * @version $Id$
+ */
+
+public abstract class ServiceableTransformer 
+    extends AbstractTransformer 
+    implements Serviceable, Disposable {
+
+    /** The current <code>SourceResolver</code>. */
+    protected SourceResolver resolver;
+    /** The current <code>Map</code> objectModel. */
+    protected Map objectModel;
+    /** The current <code>Parameters</code>. */
+    protected Parameters parameters;
+    /** The source URI associated with the request or <b>null</b>. */
+    protected String source;
+    /** The ServiceManager */
+    protected ServiceManager manager;
+    
+    /**
+     * Set the <code>SourceResolver</code>, object model <code>Map</code>,
+     * the source and sitemap <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        this.resolver = resolver;
+        this.objectModel = objectModel;
+        this.source = src;
+        this.parameters = par;
+    }
+
+    /**
+     * Recycle the generator by removing references
+     */
+    public void recycle() {
+        super.recycle();
+        this.resolver = null;
+        this.objectModel = null;
+        this.source = null;
+        this.parameters = null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        this.manager = null;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormInstanceExtractionTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormInstanceExtractionTransformer.java
new file mode 100644
index 0000000..59d367f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormInstanceExtractionTransformer.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.modules.output.OutputModule;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.dom.DocumentWrapper;
+
+import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * This transformer sieves an incoming stream of xml and extracts a
+ * document fragment from it depending on a given tag and stores the
+ * fragment using an OutputModule with a name based an attribute of
+ * another enclosing tag. Default configuration fires on
+ * &lt;form-instance/&gt; and uses @name of enclosing &lt;form/&gt;
+ * tag. Default OutputModule is request-attr. This is usefull in
+ * conjunction with the SimpleFormTransformer when setting the
+ * InputModule for it to a chain of request-param and request-attr so
+ * that the extracted form instance data is used only when no similar
+ * request parameter exists.
+ * 
+ * @cocoon.sitemap.component.name   simple-form-instance
+ * @cocoon.sitemap.component.logger sitemap.transformer.simple-form-instance
+ * 
+ * @version $Id$
+ */
+public class SimpleFormInstanceExtractionTransformer extends AbstractExtractionTransformer 
+    implements Configurable, Serviceable, Recyclable {
+
+    protected class ElementData {
+        public String uri = null;
+        public String loc = null;
+        public String raw = null;
+
+        public ElementData() {
+        }
+
+        public ElementData(String uri, String loc, String raw) {
+            this.uri = uri;
+            this.loc = loc;
+            this.raw =raw;
+        }
+
+        public boolean equals(String uri, String loc, String raw) {
+
+            if (!this.uri.equals(uri))
+                return false;
+            if (!this.loc.equals(loc))
+                return false;
+            if (!this.raw.equals(raw))
+                return false;
+            return true;
+        }
+
+    }
+
+    protected final static String OUTPUT_MODULE_SELECTOR = OutputModule.ROLE+"Selector";
+
+    ElementData startElement = null;
+    ElementData nameElement = null;
+    String qname = "name";
+
+    String instanceName = null;
+    boolean nameAsRoot = true;
+
+    String outputModuleName = "request-attr";
+    Configuration outputConf = null;
+
+    ServiceManager manager = null;
+    Map objectModel = null;
+
+    public void configure(Configuration config) throws ConfigurationException {
+        this.startElement = new ElementData();
+        this.startElement.uri = config.getChild("start").getAttribute("uri", "");
+        this.startElement.loc = config.getChild("start").getAttribute("local-name", "form-instance");
+        this.startElement.raw = config.getChild("start").getAttribute("raw-name", "form-instance");
+
+        this.nameElement = new ElementData();
+        this.nameElement.uri = config.getChild("name").getAttribute("uri", "");
+        this.nameElement.loc = config.getChild("name").getAttribute("local-name", "form");
+        this.nameElement.raw = config.getChild("name").getAttribute("raw-name", "form");
+        this.qname = config.getChild("name").getAttribute("name-attribute", "name");
+
+        this.nameAsRoot = config.getChild("name-as-root").getValueAsBoolean(this.nameAsRoot);
+
+        this.outputConf = config.getChild("output");
+        this.outputModuleName = this.outputConf.getAttribute("name",this.outputModuleName);
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /** Setup the transformer. */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+            throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, parameters);
+        this.objectModel = objectModel;
+    }
+
+    public void recycle() {
+        super.recycle();
+        this.instanceName = null;
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     * @return a <code>boolean</code> value to signal to start extracting
+     */
+    public boolean startExtracting(String uri, String loc, String raw, Attributes a) {
+        if (this.nameElement.equals(uri,loc,raw)) {
+            this.instanceName = a.getValue(this.qname);
+        }
+        boolean res = this.startElement.equals(uri,loc,raw);
+        return res;
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     * @return a <code>boolean</code> value to signal to stop extracting
+     */
+    public boolean endExtracting(String uri, String loc, String raw) {
+        boolean res = this.startElement.equals(uri,loc,raw);
+        return res;
+    }
+
+
+    /**
+     * Start root element and replace it with the instance name.
+     * @see org.apache.cocoon.transformation.AbstractExtractionTransformer#startExtractingDocument(String, String, String, Attributes)
+     */
+    public void startExtractingDocument(String uri, String loc, String raw, Attributes a) throws SAXException {
+        if (this.nameAsRoot) {
+            loc = this.instanceName;
+            if (uri != null && !uri.equals("")) {
+                int pos = raw.indexOf(':');
+                raw = raw.substring(0, pos+1) + this.instanceName;
+            } else {
+                raw = loc;
+            }
+        }
+        this.currentBuilder.startElement(uri,loc,raw,a);
+    }
+
+    /**
+     * End root element and replace it with the instance name.
+     * @see org.apache.cocoon.transformation.AbstractExtractionTransformer#endExtractingDocument(String, String, String)
+     */
+    public void endExtractingDocument(String uri, String loc, String raw) throws SAXException{
+        if(this.nameAsRoot){
+            loc = this.instanceName;
+            if (uri != null && !uri.equals("")) {
+                int pos = raw.indexOf(':');
+                raw = raw.substring(0, pos+1) + this.instanceName;
+            } else {
+                raw = loc;
+            }
+        }
+        this.currentBuilder.endElement(uri, loc, raw);
+    }
+
+
+    /**
+     * Receive notification of the end of the extracted Document.
+     *
+     * @param doc a <code>Document</code> value
+     */
+    public void handleExtractedDocument(Document doc) {
+        
+        ServiceSelector outputSelector = null;
+        OutputModule output = null;
+
+        try {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("wrote ['"+this.instanceName+"'] to "+output+" using "+outputConf);
+            outputSelector = (ServiceSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR);
+            if (outputSelector.isSelectable(this.outputModuleName)) {
+                output = (OutputModule) outputSelector.select(this.outputModuleName);
+            }
+            output.setAttribute(outputConf, this.objectModel, this.instanceName, new DocumentWrapper(doc));
+            output.commit(outputConf, this.objectModel);
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("wrote ['"+this.instanceName+"'] to "+output+" using "+outputConf);
+
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled())
+                getLogger().warn("Problem writing document data: "+e.getMessage());
+        } finally {
+            if (outputSelector != null) {
+                if (output != null) {
+                    outputSelector.release(output);
+                    output = null;
+                }
+                this.manager.release(outputSelector);
+            }
+        }
+        this.instanceName = null;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormTransformer.java
new file mode 100644
index 0000000..37072e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SimpleFormTransformer.java
@@ -0,0 +1,1203 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.acting.ValidatorActionResult;
+import org.apache.cocoon.transformation.helpers.FormValidatorHelper;
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.HashMap;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.commons.lang.BooleanUtils;
+
+import org.w3c.dom.DocumentFragment;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Eliminates the need for XSP to use FormValidatorAction or HTML forms.
+ * Caveat: Select options need a value attribute to work correctly.
+ *
+ * @cocoon.sitemap.component.name   simple-form
+ * @cocoon.sitemap.component.logger sitemap.transformer.simple-form
+ *
+ *
+ * <p>This transformer fills all HTML 4 form elements with values from
+ * an InputModule, e.g. request, with the same name. It handles select
+ * boxes, textareas, checkboxes, radio buttons, password and text
+ * fields, and buttons. Form elements and complete forms can be protected
+ * from substitution by adding an attribute fixed="true" to them.</p>
+ *
+ * <p>In addition, it handles FormValidatorAction results by
+ * selectively omitting &lt;error/&gt; elements. These elements need a
+ * "name" attribute corresponding to the name of the form element, and
+ * either a "when" or a "when-ge" attribute.</p>
+ *
+ * <p>An error element is send down the pipeline if validation results
+ * are available and either the results equals the "when" attribute or
+ * the result is greater or equal to the "when-ge" attribute.</p>
+ *
+ * <p>Names for validation results are "ok", "not-present", "error",
+ * "is-null", "too-small", "too-large", and "no-match" for the similar
+ * named values from ValidatorActionResult.</p>
+ *
+ * <p>There need not to be an "error" element for every form element,
+ * multiple error elements for the same form element may be
+ * present.</p>
+ *
+ * <p><em>Names of error elements are never augmented by prefix, suffix or
+ * form name.</em></p>
+ *
+ * <p>Page parts with multiple occurrences depending on the number of
+ * actual parameters can be enclosed in &lt;repeat on="expr" using="var"/&gt;
+ * elements. <em>expr</em> is used to determine the number of occurrences
+ * and <em>var</em> will be expanded with the ordinary number. Repeat elements
+ * can be nested.</p>
+ *
+ * <p>Example:</p>
+ * <pre>
+ *  <repeat on="mult" using="i"><input type="text" name="mult[${i}]"/></repeat>
+ * </pre>
+ * <p>Will include as many input elements as mult parameters are present. Adding
+ * the repeater variable to the elements name is necessary only with structured
+ * parameters or when they should be numbered. See also the <em>strip-number</em>
+ * configuration parameter.</p>
+ *
+ * <p>To use this transformer, add the following to your
+ * transformation pipeline: <pre>
+ *   &lt;map:transform type="simple-form"/&gt;
+ * </pre></p>
+ *
+ * <p>Configuration elements:
+ * <table>
+ *   <tr><td>input-module</td><td>(String) InputModule configuration,
+ *           defaults to an empty configuration and the "request-param" module</td></tr>
+ *   <tr><td>fixed-attribute</td><td>(String) Name of the attribute used to
+ *           indicate that this element should not be changed. ("fixed")</td></tr>
+ *   <tr><td>use-form-name</td><td>(boolean) Add the name of the form to the
+ *           name of form elements. Uses default Separator , if default separator is null
+ *           or empty, separator is set to "/". ("false")</td></tr>
+ *   <tr><td>use-form-name-twice</td><td>(boolean) Add the name of the form twice to the
+ *           name of form elements. This is useful when the form instance has no
+ *           all enclosing root tag and the form name is used instead <em>and</em> the
+ *           form name needs to be used to find the form data. Uses default Separator ,
+ *           if default separator is null or empty, separator is set to "/".("false")</td></tr>
+ *   <tr><td>separator</td><td>(String) Separator between form name and element name ("/")
+ *           </td></tr>
+ *   <tr><td>prefix</td><td>(String) Prefix to add to element name for value lookup. No
+ *           separator will be added between prefix and rest of the name. Default
+ *           is "", when use-form-name is set, defaults to separator.</td></tr>
+ *   <tr><td>suffix</td><td>(String) Added to the input element's name. No
+ *           separator will be added between rest of the name and suffix. ("")</td></tr>
+ *   <tr><td>ignore-validation</td><td>(boolean) If set to true, all error
+ *           tags are copied as is regardless of the validation results.("false")</td></tr>
+ *   <tr><td>decoration</td><td>(int) Length of decorations around repeat variable. Example:
+ *           when using JXPath based module, decoration would be "[" and "]", hence 1. (1)</td></tr>
+ *   <tr><td>strip-number</td><td>(boolean) If set to false, element names of repeated
+ *           elements will contain the expanded repeater variable. ("true")</td></tr>
+ * </table>
+ * </p>
+ *
+ * <p>Sitemap parameters:
+ * <table>
+ *   <tr><td>fixed</td><td>(boolean) Do not change values</td></tr>
+ *   <tr><td>prefix</td><td>(String) Added to the input element's name</td></tr>
+ *   <tr><td>suffix</td><td>(String) Added to the input element's name</td></tr>
+ *   <tr><td>input</td><td>(String) InputModule name</td></tr>
+ *   <tr><td>decoration</td><td>(int) Length of decorations around repeat variable.</td></tr>
+ *   <tr><td>strip-number</td><td>(boolean) Expanded repeater variable.</td></tr>
+ * </table>
+ * </p>
+ *
+ * <p>Example:<pre>
+ *     &lt;input name="user.name" size="50" maxlength="60"/&gt;
+ *     &lt;error name="user.name" when-ge="error"&gt;required&lt;/error&gt;
+ * </pre></p>
+ *
+ * @version $Id$
+ */
+public class SimpleFormTransformer extends AbstractSAXTransformer implements Recyclable {
+
+    /** strip numbers from repeated element name attributes */
+    private boolean stripNumber = true;
+
+    /** Symbolic names for elements */
+    /** unknown element */
+    private static final int ELEMENT_DEFAULT = 0;
+    /** input element */
+    private static final int ELEMENT_INPUT = 1;
+    /** select element */
+    private static final int ELEMENT_SELECT = 2;
+    /** option element */
+    private static final int ELEMENT_OPTION = 3;
+    /** textarea element */
+    private static final int ELEMENT_TXTAREA = 4;
+    /** error element */
+    private static final int ELEMENT_ERROR = 5;
+    /** form element */
+    private static final int ELEMENT_FORM = 6;
+    /** repeat element */
+    private static final int ELEMENT_REPEAT = 7;
+    /** default element as Integer (needed as default in org.apache.cocoon.util.HashMap.get()) */
+    private static final Integer defaultElement = new Integer(ELEMENT_DEFAULT);
+
+    /** input type unknown */
+    private static final int TYPE_DEFAULT = 0;
+    /** input type checkbox */
+    private static final int TYPE_CHECKBOX = 1;
+    /** input type radio */
+    private static final int TYPE_RADIO = 2;
+    /** default input type as Integer (needed as default in org.apache.cocoon.util.HashMap.get()) */
+    private static final Integer defaultType = new Integer(TYPE_DEFAULT);
+
+    protected static final String INPUT_MODULE_ROLE = InputModule.ROLE;
+    protected static final String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE + "Selector";
+
+    /** map element name string to symbolic name */
+    private static final HashMap elementNames;
+    /** map input type string to symbolic name */
+    private static final HashMap inputTypes;
+    /** map ValidatorActionResult to name string */
+    private static final HashMap validatorResults;
+    /** map name string to ValidatorActionResult */
+    private static final HashMap validatorResultLabel;
+
+    /** setup mapping tables */
+    static {
+        HashMap names = new HashMap();
+        names.put("input", new Integer(ELEMENT_INPUT));
+        names.put("select", new Integer(ELEMENT_SELECT));
+        names.put("option", new Integer(ELEMENT_OPTION));
+        names.put("textarea", new Integer(ELEMENT_TXTAREA));
+        names.put("error", new Integer(ELEMENT_ERROR));
+        names.put("form", new Integer(ELEMENT_FORM));
+        names.put("repeat", new Integer(ELEMENT_REPEAT));
+        elementNames = names;
+        names = null;
+
+        names = new HashMap();
+        names.put("checkbox", new Integer(TYPE_CHECKBOX));
+        names.put("radio", new Integer(TYPE_RADIO));
+        inputTypes = names;
+        names = null;
+
+        names = new HashMap();
+        names.put("ok", ValidatorActionResult.OK);
+        names.put("not-present", ValidatorActionResult.NOTPRESENT);
+        names.put("error", ValidatorActionResult.ERROR);
+        names.put("is-null", ValidatorActionResult.ISNULL);
+        names.put("too-small", ValidatorActionResult.TOOSMALL);
+        names.put("too-large", ValidatorActionResult.TOOLARGE);
+        names.put("no-match", ValidatorActionResult.NOMATCH);
+        validatorResultLabel = names;
+
+        names = new HashMap();
+        names.put(ValidatorActionResult.OK, "ok");
+        names.put(ValidatorActionResult.NOTPRESENT, "not-present");
+        names.put(ValidatorActionResult.ERROR, "error");
+        names.put(ValidatorActionResult.ISNULL, "is-null");
+        names.put(ValidatorActionResult.TOOSMALL, "too-small");
+        names.put(ValidatorActionResult.TOOLARGE, "too-large");
+        names.put(ValidatorActionResult.NOMATCH, "no-match");
+        validatorResults = names;
+        names = null;
+    }
+
+    /** current element's request parameter values */
+    protected Object[] values;
+
+    /** current request's validation results (all validated elements) */
+    protected Map validationResults;
+
+    /** Should we skip inserting values? */
+    private boolean fixed;
+    /** Is the complete document protected? */
+    private boolean documentFixed;
+
+    private String fixedName = "fixed";
+    private String prefix;
+    private String suffix;
+    private String defaultPrefix;
+    private String defaultSuffix;
+    private String separator;
+    private String formName;
+    private boolean useFormName;
+    private boolean useFormNameTwice;
+    private boolean ignoreValidation;
+    private int decorationSize = 1;
+
+    private String defaultInput = "request-param";
+    private Configuration defaultInputConf;
+    private Configuration inputConf;
+    private InputModule input;
+    private ServiceSelector inputSelector;
+    private String inputName;
+
+    /** Skip element's content only. Otherwise skip also surrounding element. */
+    protected boolean skipChildrenOnly;
+
+    /** Count nested repeat elements. */
+    protected int recordingCount;
+
+    /** List of {@link RepeaterStatus} elements keeping track of nested repeat blocks. */
+    protected List repeater;
+
+    /** Map of {@link ValueList} to track multiple parameters. */
+    protected Map formValues;
+
+
+    /**
+     * Keep track of repeater status.
+     */
+    protected class RepeaterStatus {
+        public String var = null;
+        public String expr = null;
+        public int count = 0;
+
+        public RepeaterStatus(String var, int count, String expr) {
+            this.var = var;
+            this.count = count;
+            this.expr = expr;
+        }
+
+        public String toString() {
+            return "[" + this.var + "," + this.expr + "," + this.count + "]";
+        }
+    }
+
+    /**
+     * Keep track of multiple values.
+     */
+    protected static class ValueList {
+        private int current = -1;
+        private Object[] values = null;
+
+        public ValueList(Object[] values) {
+            this.values = values;
+            this.current = (values != null && values.length > 0 ? 0 : -1);
+        }
+
+        public Object getNext() {
+            Object result = null;
+            if (this.values != null) {
+                if (this.current < this.values.length) {
+                    result = this.values[this.current++];
+                }
+            }
+            return result;
+        }
+    }
+
+
+    /**
+     * Constructor. Set the namespace.
+     */
+    public SimpleFormTransformer() {
+        super.defaultNamespaceURI = "";
+    }
+
+    /** set per instance variables to defaults */
+    private void reset() {
+        this.skipChildrenOnly = false;
+        this.values = null;
+        this.validationResults = null;
+        this.documentFixed = false;
+        this.fixed = false;
+        this.formName = null;
+        this.recordingCount = 0;
+        this.repeater = new LinkedList();
+        this.formValues = new HashMap();
+
+        if (this.inputSelector != null) {
+            if (this.input != null)
+                this.inputSelector.release(this.input);
+            this.manager.release(this.inputSelector);
+        }
+    }
+
+    /**
+     * Avalon Configurable Interface
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+        super.configure(config);
+
+        this.defaultInputConf = config.getChild("input-module");
+        this.defaultInput = this.defaultInputConf.getAttribute("name", this.defaultInput);
+        this.separator = config.getChild("separator").getValue(this.separator);
+        this.defaultPrefix = config.getChild("prefix").getValue(this.defaultPrefix);
+        this.defaultSuffix = config.getChild("suffix").getValue(this.defaultSuffix);
+        this.fixedName = config.getChild("fixed-attribute").getValue(this.fixedName);
+        this.useFormName = config.getChild("use-form-name").getValueAsBoolean(this.useFormName);
+        this.useFormNameTwice =
+            config.getChild("use-form-name-twice").getValueAsBoolean(this.useFormNameTwice);
+        this.useFormName = this.useFormName || this.useFormNameTwice;
+        if (this.useFormName) {
+            this.separator =
+                (this.separator == null || this.separator.equals("") ? "/" : this.separator);
+            this.defaultPrefix = this.separator;
+        }
+        this.ignoreValidation =
+            config.getChild("ignore-validation").getValueAsBoolean(this.ignoreValidation);
+        this.decorationSize = config.getChild("decoration").getValueAsInteger(this.decorationSize);
+        this.stripNumber = config.getChild("strip-number").getValueAsBoolean(this.stripNumber);
+    }
+
+    /**
+     * Read sitemap parameters and set properties accordingly.
+     */
+    private void evaluateParameters() {
+        this.documentFixed = this.parameters.getParameterAsBoolean("fixed", false);
+        this.fixed = this.documentFixed;
+        this.prefix = this.parameters.getParameter("prefix", this.defaultPrefix);
+        this.suffix = this.parameters.getParameter("suffix", this.defaultSuffix);
+        this.inputName = this.parameters.getParameter("input", null);
+        this.decorationSize =
+            this.parameters.getParameterAsInteger("decoration", this.decorationSize);
+        this.stripNumber = this.parameters.getParameterAsBoolean("strip-number", this.stripNumber);
+    }
+
+    /**
+     * Setup the next round.
+     * The instance variables are initialised.
+     * @param resolver The current SourceResolver
+     * @param objectModel The objectModel of the environment.
+     * @param src The value of the src attribute in the sitemap.
+     * @param par The parameters from the sitemap.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+        throws ProcessingException, SAXException, IOException {
+
+        this.reset();
+
+        super.setup(resolver, objectModel, src, par);
+
+        if (request == null) {
+            getLogger().debug("no request object");
+            throw new ProcessingException("no request object");
+        }
+        this.evaluateParameters();
+        this.setupInputModule();
+
+    }
+
+    /**
+     * Setup and obtain reference to the input module.
+     */
+    private void setupInputModule() {
+        this.inputConf = null;
+        if (this.ignoreValidation) {
+            this.validationResults = null;
+        } else {
+            this.validationResults = FormValidatorHelper.getResults(this.objectModel);
+        }
+
+        if (this.inputName == null) {
+            this.inputName = this.defaultInput;
+            this.inputConf = this.defaultInputConf;
+        }
+
+        try {
+            // obtain input module
+            this.inputSelector = (ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR);
+            if (this.inputName != null
+                && this.inputSelector != null
+                && this.inputSelector.isSelectable(this.inputName)) {
+                this.input = (InputModule) this.inputSelector.select(this.inputName);
+                if (!(this.input instanceof ThreadSafe
+                    && this.inputSelector instanceof ThreadSafe)) {
+                    this.inputSelector.release(this.input);
+                    this.manager.release(this.inputSelector);
+                    this.input = null;
+                    this.inputSelector = null;
+                }
+            } else {
+                if (this.inputName != null)
+                    if (getLogger().isErrorEnabled())
+                        getLogger().error(
+                            "A problem occurred setting up '"
+                                + this.inputName
+                                + "': Selector is "
+                                + (this.inputSelector != null ? "not " : "")
+                                + "null, Component is "
+                                + (this.inputSelector != null
+                                    && this.inputSelector.isSelectable(this.inputName)
+                                        ? "known"
+                                        : "unknown"));
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled())
+                getLogger().warn(
+                    "A problem occurred setting up '" + this.inputName + "': " + e.getMessage());
+        }
+    }
+
+    /**
+     *  Recycle this component.
+     */
+    public void recycle() {
+        reset();
+        super.recycle();
+    }
+
+    /**
+     * Generate string representation of attributes. For debug only.
+     */
+    protected String printAttributes(Attributes attr) {
+        StringBuffer sb = new StringBuffer();
+        sb.append('[');
+        for (int i = 0; i < attr.getLength(); i++) {
+            sb.append('@').append(attr.getLocalName(i)).append("='").append(
+                attr.getValue(i)).append(
+                "' ");
+        }
+        sb.append(']');
+        return sb.toString();
+    }
+
+    /**
+     * Handle input elements that may have a "checked" attributes,
+     * i.e. checkbox and radio.
+     */
+    protected void startCheckableElement(
+        String aName,
+        String uri,
+        String name,
+        String raw,
+        AttributesImpl attributes)
+        throws SAXException {
+
+        // @fixed and this.fixed already considered in startInputElement
+        this.values = this.getValues(aName);
+        String checked = attributes.getValue("checked");
+        String value = attributes.getValue("value");
+        boolean found = false;
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startCheckableElement "
+                    + name
+                    + " attributes "
+                    + this.printAttributes(attributes));
+        if (this.values != null) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("replacing");
+            for (int i = 0; i < this.values.length; i++) {
+                if (this.values[i].equals(value)) {
+                    found = true;
+                    if (checked == null) {
+                        attributes.addAttribute("", "checked", "checked", "CDATA", "");
+                    }
+                    break;
+                }
+            }
+            if (!found && checked != null) {
+                attributes.removeAttribute(attributes.getIndex("checked"));
+            }
+        }
+        this.relayStartElement(uri, name, raw, attributes);
+    }
+
+    /**
+     * Handle input elements that may don't have a "checked"
+     * attributes, e.g. text, password, button.
+     */
+    protected void startNonCheckableElement(
+        String aName,
+        String uri,
+        String name,
+        String raw,
+        AttributesImpl attributes)
+        throws SAXException {
+
+        // @fixed and this.fixed already considered in startInputElement
+        Object fValue = this.getNextValue(aName);
+        String value = attributes.getValue("value");
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startNonCheckableElement "
+                    + name
+                    + " attributes "
+                    + this.printAttributes(attributes));
+        if (fValue != null) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("replacing");
+            if (value != null) {
+                attributes.setValue(attributes.getIndex("value"), String.valueOf(fValue));
+            } else {
+                attributes.addAttribute("", "value", "value", "CDATA", String.valueOf(fValue));
+            }
+        }
+        this.relayStartElement(uri, name, raw, attributes);
+    }
+
+    /**
+     * Handle input elements. Calls startCheckableElement or
+     * startNonCheckableElement.
+     */
+    protected void startInputElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        // @value = request.getParameterValues(@name)
+        String aName = getName(attr.getValue("name"));
+        String fixed = attr.getValue(this.fixedName);
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startInputElement " + name + " attributes " + this.printAttributes(attr));
+        if (aName == null || this.fixed || (fixed != null && BooleanUtils.toBoolean(fixed))) {
+            this.relayStartElement(uri, name, raw, attr);
+
+        } else {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("replacing");
+
+            attr = this.normalizeAttributes(attr);
+
+            AttributesImpl attributes = null;
+            if (attr instanceof AttributesImpl) {
+                attributes = (AttributesImpl) attr;
+            } else {
+                attributes = new AttributesImpl(attr);
+            }
+            String type = attributes.getValue("type");
+            switch (((Integer) inputTypes.get(type, defaultType)).intValue()) {
+                case TYPE_CHECKBOX :
+                case TYPE_RADIO :
+                    this.startCheckableElement(aName, uri, name, raw, attributes);
+                    break;
+
+                case TYPE_DEFAULT :
+                    this.startNonCheckableElement(aName, uri, name, raw, attributes);
+                    break;
+            }
+            this.values = null;
+        }
+    }
+
+    /**
+     * Handle select elements. Sets up some instance variables for
+     * following option elements.
+     */
+    protected void startSelectElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        // this.values = request.getParameterValues(@name)
+        String aName = getName(attr.getValue("name"));
+        String fixed = attr.getValue(this.fixedName);
+        this.values = null;
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startSelectElement " + name + " attributes " + this.printAttributes(attr));
+        if (aName != null && !(this.fixed || (fixed != null && BooleanUtils.toBoolean(fixed)))) {
+            if (attr.getIndex("multiple") > -1) {
+                this.values = this.getValues(aName);
+            } else {
+                Object val = this.getNextValue(aName);
+                if (val != null) {
+                    this.values = new Object[1];
+                    this.values[0] = val;
+                } else {
+                    this.values = null;
+                }
+            }
+            attr = this.normalizeAttributes(attr);
+        }
+        this.relayStartElement(uri, name, raw, attr);
+    }
+
+    /**
+     * Handle option elements. Uses instance variables set up by
+     * startSelectElement. Relies on option having a "value"
+     * attribute, i.e. does not check following characters if "value"
+     * is not present.
+     */
+    protected void startOptionElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        // add @selected if @value in request.getParameterValues(@name)
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startOptionElement " + name + " attributes " + this.printAttributes(attr));
+        if (this.values == null || this.fixed) {
+            this.relayStartElement(uri, name, raw, attr);
+        } else {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("replacing");
+            AttributesImpl attributes = null;
+            if (attr instanceof AttributesImpl) {
+                attributes = (AttributesImpl) attr;
+            } else {
+                attributes = new AttributesImpl(attr);
+            }
+            String selected = attributes.getValue("selected");
+            String value = attributes.getValue("value");
+            boolean found = false;
+
+            for (int i = 0; i < this.values.length; i++) {
+                if (this.values[i].equals(value)) {
+                    found = true;
+                    if (selected == null) {
+                        attributes.addAttribute("", "selected", "selected", "CDATA", "");
+                    }
+                    break;
+                }
+            }
+            if (!found && selected != null) {
+                attributes.removeAttribute(attributes.getIndex("selected"));
+            }
+
+            this.relayStartElement(uri, name, raw, attributes);
+        }
+    }
+
+    /**
+     * Handles textarea elements. Skips nested events if request
+     * parameter with same name exists.
+     */
+    protected void startTextareaElement(String uri, String name, String raw, Attributes attributes)
+        throws SAXException {
+
+        String aName = getName(attributes.getValue("name"));
+        String fixed = attributes.getValue(this.fixedName);
+        Object value = null;
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startTextareaElement " + name + " attributes " + this.printAttributes(attributes));
+        if (aName != null) {
+            value = this.getNextValue(aName);
+        }
+        if (value == null || this.fixed || (fixed != null && BooleanUtils.toBoolean(fixed))) {
+            this.relayStartElement(uri, name, raw, attributes);
+        } else {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("replacing");
+            this.relayStartElement(uri, name, raw, this.normalizeAttributes(attributes));
+            String valString = String.valueOf(value);
+            this.characters(valString.toCharArray(), 0, valString.length());
+            // well, this doesn't really work out nicely. do it the hard way.
+            if (this.ignoreEventsCount == 0)
+                this.skipChildrenOnly = true;
+            this.ignoreEventsCount++;
+        }
+    }
+
+    /**
+     * Handle error elements. If validation results are available,
+     * compares validation result for parameter with the same name as
+     * the "name" attribute with the result names is "when" and
+     * "when-ge". Drops element and all nested events when error
+     * condition is not met.
+     */
+    protected void startErrorElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        if (getLogger().isDebugEnabled())
+            getLogger().debug(
+                "startErrorElement " + name + " attributes " + this.printAttributes(attr));
+        if (this.ignoreValidation) {
+            this.relayStartElement(uri, name, raw, attr);
+        } else if (this.validationResults == null || this.fixed) {
+            this.relayStartElement(true, false, uri, name, raw, attr);
+        } else {
+            String aName = attr.getValue("name");
+            if (aName == null) {
+                this.relayStartElement(uri, name, raw, attr);
+            } else {
+                ValidatorActionResult validation =
+                    FormValidatorHelper.getParamResult(this.objectModel, aName);
+                String when = attr.getValue("when");
+                String when_ge = attr.getValue("when-ge");
+
+                if ((when != null && when.equals(validatorResults.get(validation)))
+                    || (when_ge != null
+                        && validation.ge(
+                            (ValidatorActionResult) validatorResultLabel.get(
+                                when_ge,
+                                ValidatorActionResult.MAXERROR)))) {
+                    AttributesImpl attributes = null;
+                    if (attr instanceof AttributesImpl) {
+                        attributes = (AttributesImpl) attr;
+                    } else {
+                        attributes = new AttributesImpl(attr);
+                    }
+                    // remove attributes not meant for client
+                    attributes.removeAttribute(attributes.getIndex("name"));
+                    if (when != null)
+                        attributes.removeAttribute(attributes.getIndex("when"));
+                    if (when_ge != null)
+                        attributes.removeAttribute(attributes.getIndex("when-ge"));
+                    this.relayStartElement(uri, name, raw, this.normalizeAttributes(attributes));
+                } else {
+                    this.relayStartElement(true, true, uri, name, raw, attr);
+                }
+            }
+        }
+    }
+
+    /**
+     * Start processing a form element. Sets protection indicator if attribute
+     * "fixed" is present and either "true" or "yes". Removes attribute "fixed"
+     * if present.
+     * @param uri The namespace of the element.
+     * @param name The local name of the element.
+     * @param raw The qualified name of the element.
+     * @param attr The attributes of the element.
+     */
+    protected void startFormElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        String fixed = attr.getValue(this.fixedName);
+        if (this.useFormName) {
+            this.formName = attr.getValue("name");
+        }
+        if (fixed == null) {
+            this.relayStartElement(uri, name, raw, attr);
+        } else {
+            if (!this.fixed && BooleanUtils.toBoolean(fixed)) {
+                this.fixed = true;
+            }
+            // remove attributes not meant for client
+            AttributesImpl attributes = null;
+            if (attr instanceof AttributesImpl) {
+                attributes = (AttributesImpl) attr;
+            } else {
+                attributes = new AttributesImpl(attr);
+            }
+            attributes.removeAttribute(attributes.getIndex(this.fixedName));
+            this.relayStartElement(uri, name, raw, this.normalizeAttributes(attributes));
+        }
+    }
+
+    /**
+     * Start recording repeat element contents and push repeat expression and
+     * variable to repeater stack. Only start recording, if no other recorder is
+     * currently running.
+     *
+     * @param uri
+     * @param name
+     * @param raw
+     * @param attr
+     * @throws SAXException
+     */
+    protected void startRepeatElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        if (this.recordingCount == 0) {
+            if (!(this.fixed || BooleanUtils.toBoolean(attr.getValue(this.fixedName)))) {
+                RepeaterStatus status =
+                    new RepeaterStatus("${" + attr.getValue("using") + "}", 0, attr.getValue("on"));
+                this.repeater.add(status);
+                this.startRecording();
+                this.recordingCount++;
+            } else {
+                this.relayStartElement(uri, name, raw, attr);
+            }
+        } else {
+            this.relayStartElement(uri, name, raw, attr);
+            this.recordingCount++;
+        }
+    }
+
+    /**
+     * Stop recording repeat contents and replay required number of times.
+     * Stop only if outmost repeat element is ending.
+     *
+     * @param uri
+     * @param name
+     * @param raw
+     * @throws SAXException
+     */
+    protected void endRepeatElement(String uri, String name, String raw) throws SAXException {
+        this.recordingCount--;
+        if (this.recordingCount == 0) {
+            DocumentFragment fragment = this.endRecording();
+            RepeaterStatus status = (RepeaterStatus) this.repeater.get(this.repeater.size() - 1);
+            Object[] vals = this.getValues(this.getName(status.expr));
+            int count = (vals != null ? vals.length : 0);
+            for (status.count = 1; status.count <= count; status.count++) {
+                DOMStreamer streamer = new DOMStreamer(this, this);
+                streamer.stream(fragment);
+            }
+            this.repeater.remove(this.repeater.size() - 1);
+        } else {
+            this.relayEndElement(uri, name, raw);
+            if (this.recordingCount < 0) {
+                this.recordingCount = 0;
+            }
+        }
+    }
+
+    /**
+     * Start processing elements of our namespace.
+     * This hook is invoked for each sax event with our namespace.
+     * @param uri The namespace of the element.
+     * @param name The local name of the element.
+     * @param raw The qualified name of the element.
+     * @param attr The attributes of the element.
+     */
+    public void startTransformingElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+
+        if (this.ignoreEventsCount == 0 && this.recordingCount == 0) {
+            switch (((Integer) elementNames.get(name, defaultElement)).intValue()) {
+                case ELEMENT_INPUT :
+                    this.startInputElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_SELECT :
+                    this.startSelectElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_OPTION :
+                    this.startOptionElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_TXTAREA :
+                    this.startTextareaElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_ERROR :
+                    this.startErrorElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_FORM :
+                    this.startFormElement(uri, name, raw, attr);
+                    break;
+
+                case ELEMENT_REPEAT :
+                    this.startRepeatElement(uri, name, raw, attr);
+                    break;
+
+                default :
+                    this.relayStartElement(uri, name, raw, attr);
+            }
+
+        } else if (this.recordingCount > 0) {
+            switch (((Integer) elementNames.get(name, defaultElement)).intValue()) {
+                case ELEMENT_REPEAT :
+                    this.startRepeatElement(uri, name, raw, attr);
+                    break;
+
+                default :
+                    this.relayStartElement(uri, name, raw, attr);
+            }
+        } else {
+            this.relayStartElement(uri, name, raw, attr);
+        }
+    }
+
+    /**
+     * Start processing elements of our namespace.
+     * This hook is invoked for each sax event with our namespace.
+     * @param uri The namespace of the element.
+     * @param name The local name of the element.
+     * @param raw The qualified name of the element.
+     */
+    public void endTransformingElement(String uri, String name, String raw) throws SAXException {
+
+        if (this.ignoreEventsCount > 0) {
+            this.relayEndElement(uri, name, raw);
+        } else if (this.recordingCount > 0) {
+            switch (((Integer) elementNames.get(name, defaultElement)).intValue()) {
+                case ELEMENT_REPEAT :
+                    this.endRepeatElement(uri, name, raw);
+                    break;
+
+                default :
+                    this.relayEndElement(uri, name, raw);
+            }
+        } else {
+            switch (((Integer) elementNames.get(name, defaultElement)).intValue()) {
+                case ELEMENT_SELECT :
+                    this.values = null;
+                    this.relayEndElement(uri, name, raw);
+                    break;
+                case ELEMENT_INPUT :
+                case ELEMENT_OPTION :
+                case ELEMENT_TXTAREA :
+                case ELEMENT_ERROR :
+                    this.relayEndElement(uri, name, raw);
+                    break;
+                case ELEMENT_FORM :
+                    this.fixed = this.documentFixed;
+                    this.formName = null;
+                    this.relayEndElement(uri, name, raw);
+                    break;
+
+                case ELEMENT_REPEAT :
+                    this.endRepeatElement(uri, name, raw);
+                    break;
+
+                default :
+                    this.relayEndElement(uri, name, raw);
+            }
+        }
+    }
+
+    /**
+     * Remove extra information from element's attributes. Currently only removes
+     * the repeater variable from the element's name attribute if present.
+     *
+     * @param attr
+     * @return modified attributes
+     */
+    private Attributes normalizeAttributes(Attributes attr) {
+        Attributes result = attr;
+        if (this.stripNumber && this.repeater.size() > 0) {
+            String name = attr.getValue("name");
+            if (name != null) {
+                for (Iterator i = this.repeater.iterator(); i.hasNext();) {
+                    RepeaterStatus status = (RepeaterStatus) i.next();
+                    int pos = name.indexOf(status.var);
+                    if (pos >= 0) {
+                        AttributesImpl attributes;
+                        if (result instanceof AttributesImpl) {
+                            attributes = (AttributesImpl) result;
+                        } else {
+                            attributes = new AttributesImpl(result);
+                        }
+                        name =
+                            name.substring(0, pos - this.decorationSize)
+                                + name.substring(pos + status.var.length() + this.decorationSize);
+                        attributes.setValue(attributes.getIndex("name"), name);
+                        result = attributes;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Generate the "real" name of an element for value lookup.
+     * @param name
+     * @return "real" name.
+     */
+    private String getName(String name) {
+        String result = name;
+        if (this.useFormName && this.formName != null) {
+            if (this.separator != null) {
+                if (this.useFormNameTwice) {
+                    result =
+                        this.formName + this.separator + this.formName + this.separator + result;
+                } else {
+                    result = this.formName + this.separator + result;
+                }
+            } else {
+                if (this.useFormNameTwice) {
+                    result = this.formName + result;
+                } else {
+                    // does this make sense ?
+                    result = this.formName + this.formName + result;
+                }
+            }
+        }
+        if (this.prefix != null) {
+            result = this.prefix + result;
+        }
+        if (this.suffix != null) {
+            result = result + this.prefix;
+        }
+        if (this.repeater.size() > 0) {
+            for (Iterator i = this.repeater.iterator(); i.hasNext();) {
+                RepeaterStatus status = (RepeaterStatus) i.next();
+                int pos = result.indexOf(status.var);
+                if (pos != -1) {
+                    result =
+                        result.substring(0, pos)
+                            + status.count
+                            + result.substring(pos + status.var.length());
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Obtain values from used InputModule if not done already and return the
+     * next value. If no more values exist, returns null.
+     *
+     * @param name
+     */
+    private Object getNextValue(String name) {
+        Object result = null;
+        if (this.formValues.containsKey(name)) {
+            ValueList vList = (ValueList) this.formValues.get(name);
+            result = vList.getNext();
+        } else {
+            ValueList vList = new ValueList(this.getValues(name));
+            result = vList.getNext();
+            this.formValues.put(name, vList);
+        }
+        return result;
+    }
+
+    /**
+     * Obtain values from the used InputModule.
+     */
+    private Object[] getValues(String name) {
+        Object[] values = null;
+        ServiceSelector iputSelector = null;
+        InputModule iput = null;
+        try {
+            if (this.input != null) {
+                // input module is thread safe
+                // thus we still have a reference to it
+                values = input.getAttributeValues(name, this.inputConf, objectModel);
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug("cached module " + this.input
+                                      + " attribute " + name
+                                      + " returns " + values);
+            } else {
+                // input was not thread safe
+                // so acquire it again
+                iputSelector = (ServiceSelector)this.manager.lookup(INPUT_MODULE_SELECTOR);
+                if (this.inputName != null
+                    && iputSelector != null
+                    && iputSelector.isSelectable(this.inputName)) {
+
+                    iput = (InputModule) iputSelector.select(this.inputName);
+                }
+                if (iput != null) {
+                    values = iput.getAttributeValues(name, this.inputConf, objectModel);
+                }
+                if (getLogger().isDebugEnabled())
+                    getLogger().debug(
+                        "fresh module " + iput + " attribute " + name + " returns " + values);
+            }
+        } catch (Exception e) {
+            if (getLogger().isWarnEnabled())
+                getLogger().warn(
+                    "A problem occurred acquiring a value from '"
+                        + this.inputName
+                        + "' for '"
+                        + name
+                        + "': "
+                        + e.getMessage());
+        } finally {
+            // release components if necessary
+            if (iputSelector != null) {
+                if (iput != null)
+                    iputSelector.release(iput);
+                this.manager.release(iputSelector);
+            }
+        }
+
+        return values;
+    }
+
+    /**
+     * Calls the super's method startTransformingElement.
+     *
+     * @param uri
+     * @param name
+     * @param raw
+     * @param attr
+     * @throws SAXException
+     */
+    protected void relayStartElement(String uri, String name, String raw, Attributes attr)
+        throws SAXException {
+        this.relayStartElement(false, false, uri, name, raw, attr);
+    }
+
+    /**
+     * Calls the super's method startTransformingElement and increments the
+     * ignoreEventsCount if skip is true. Increment can be done either before
+     * invoking super's method, so that the element itself is skipped, or afterwards,
+     * so that only the children are skipped.
+     *
+     * @param skip
+     * @param skipChildrenOnly
+     * @param uri
+     * @param name
+     * @param raw
+     * @param attr
+     * @throws SAXException
+     */
+    protected void relayStartElement(
+        boolean skip,
+        boolean skipChildrenOnly,
+        String uri,
+        String name,
+        String raw,
+        Attributes attr)
+        throws SAXException {
+
+        try {
+            if (this.ignoreEventsCount > 0) {
+                this.ignoreEventsCount++;
+                super.startTransformingElement(uri, name, raw, attr);
+            } else {
+                if (skip)
+                    this.skipChildrenOnly = skipChildrenOnly;
+                if (skip && !skipChildrenOnly)
+                    this.ignoreEventsCount++;
+                super.startTransformingElement(uri, name, raw, attr);
+                if (skip && skipChildrenOnly)
+                    this.ignoreEventsCount++;
+            }
+        } catch (ProcessingException e) {
+            throw new SAXException(e);
+        } catch (IOException e) {
+            throw new SAXException(e);
+        }
+    }
+
+    /**
+     * Calls the super's method endTransformingElement and decrements the
+     * ignoreEventsCount if larger than zero.
+     *
+     * @param uri
+     * @param name
+     * @param raw
+     * @throws SAXException
+     */
+    protected void relayEndElement(String uri, String name, String raw) throws SAXException {
+
+        if (this.ignoreEventsCount == 1 && this.skipChildrenOnly)
+            this.ignoreEventsCount--;
+        try {
+            super.endTransformingElement(uri, name, raw);
+        } catch (ProcessingException e) {
+            throw new SAXException(e);
+        } catch (IOException e) {
+            throw new SAXException(e);
+        } catch (Exception e) {
+            getLogger().error("exception", e);
+        }
+
+        if (this.ignoreEventsCount > 0)
+            this.ignoreEventsCount--;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java
new file mode 100644
index 0000000..ffe0f8f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java
@@ -0,0 +1,852 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.cocoon.xml.dom.DOMUtil;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.xml.dom.DOMParser;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * This transformer allows you to output to a ModifiableSource.
+ *
+ * @cocoon.sitemap.component.name   sourcewriting
+ * @cocoon.sitemap.component.logger sitemap.transformer.write-source
+ *
+ * This transformer allows you to output to a ModifiableSource.
+ *
+ * <p>Definition:</p>
+ * <pre>
+ * &lt;map:transformer     name="tofile"     src="org.apache.cocoon.transformation.SourceWritingTransformer"&gt;
+ *   &lt;!-- 'xml' is the default Serializer (if your Source needs one, like for instance FileSource) --&gt;
+ *   &lt;map:parameter name="serializer" value="xml"/&gt;
+ * &lt;/map:transformer/&gt;
+ * </pre>
+ *
+ * <p>Invocation:</p>
+ * <pre>
+ * &lt;map:transform type="tofile"&gt;
+ *   &lt;map:parameter name="serializer" value="xml"/&gt;   &lt;!-- you can optionally override the serializer here --&gt;
+ * &lt;/map:transform&gt;
+ * </pre>
+ *
+ * <p>The Tags:</p>
+ * <pre>
+ * &lt;source:write create="[true]|false"&gt; - replaces the entire content of an existing asset, if @create is 'true' (default), a new asset will be created if one does not already exist.
+ *     &lt;source:source&gt;The System ID of the asset to be written to&lt;/source:source&gt; - eg: "docs/blah.xml" or "context://blah.xml" etc.
+ *     &lt;source:path&gt;[Optional] XPath to specify how your content is wrapped&lt;/source:path&gt; - eg: "doc" (your content is placed inside a &lt;doc/&gt; root tag). NOTE: if this value is omitted, your content MUST have only ONE top-level node.
+ *     &lt;source:fragment&gt;The XML Fragment to be written&lt;/source:fragment&gt; - eg: "&lt;foo&gt;&lt;bar id="dogcow"/&gt;&lt;/foo&gt;" or "&lt;foo/&gt;&lt;bar&gt;&lt;dogcow/&gt;&lt;bar/&gt;" etc. NOTE: the second example type, can only be used when the &lt;source:path/&gt; tag has been specified.
+ * &lt;source:write&gt;
+ *
+ * &lt;source:insert create="[true]|false" overwrite="[true]|false"&gt; - inserts content into an existing asset, if @create is 'true' (default), a new asset will be created if one does not already exist. If @overwrite is set to 'true' the data is only inserted if the node specified by the 'replacePath' does not exists.
+ *     &lt;source:source&gt;The System ID of the asset to be written to&lt;/source:source&gt; - eg: "docs/blah.xml" or "context://blah.xml" etc.
+ *     &lt;source:path&gt;XPath specifying the node into which the content is inserted&lt;/source:path&gt; - eg: "doc" (your content is appended as the last child of the &lt;doc/&gt; root tag), or "doc/section[3]". NOTE: this tag is required in &lt;source:insert/&gt; unlike &lt;source:write/&gt; where it is optional.
+ *     &lt;source:replace&gt;[Optional] XPath (relative to &lt;source:path/&gt;) to the node that is replaced by your new content&lt;/source:replace&gt; - eg: "foo/bar/dogcow/@status='cut'" (is equivalent to this in XSLT: select="foo[bar/dogcow/@status='cut']").
+ *     &lt;source:reinsert&gt;[Optional] The XPath (relative to &lt;source:replace/&gt;) to backup the overwritten node to&lt;/source:reinsert&gt; - eg: "foo/versions" or "/doc/versions/foo". NOTE: If specified and a node is replaced, all children of this replaced node will be reinserted at the given path.
+ *     &lt;source:fragment&gt;The XML Fragment to be written&lt;/source:fragment&gt; - eg: "&lt;foo&gt;&lt;bar id="dogcow"/&gt;&lt;/foo&gt;" or "&lt;foo/&gt;&lt;bar&gt;&lt;dogcow/&gt;&lt;bar/&gt;" etc.
+ * &lt;source:insert&gt;
+ *
+ * &lt;source:delete &gt; - deletes an existing asset.
+ *     &lt;source:source&gt;The System ID of the asset to be deleted&lt;/source:source&gt; - eg: "docs/blah.xml" or "context://blah.xml" etc.
+ *     &lt;source:path&gt;[Ignored] XPath to specify how your content is wrapped&lt;/source:path&gt;
+ *     &lt;source:fragment&gt;[Ignored]The XML Fragment to be written&lt;/source:fragment&gt;
+ * &lt;source:delete&gt;
+ * </pre>
+ *
+ *
+ * <p>Input XML document example (write):</p>
+ * <pre>
+ * &lt;page&gt;
+ *   ...
+ *   &lt;source:write xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+ *     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;
+ *     &lt;source:fragment&gt;&lt;page&gt;
+ *       &lt;title&gt;Hello World&lt;/title&gt;
+ *       &lt;content&gt;
+ *         &lt;p&gt;This is my first paragraph.&lt;/p&gt;
+ *       &lt;/content&gt;
+ *     &lt;/page&gt;&lt;/source:fragment&gt;
+ *   &lt;/source:write&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ * <p>Input XML document example (insert at end):</p>
+ * <pre>
+ * &lt;page&gt;
+ *   ...
+ *   &lt;source:insert xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+ *     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;
+ *     &lt;source:path&gt;page/content&lt;/source:path&gt;
+ *     &lt;source:fragment&gt;
+ *       &lt;p&gt;This paragraph gets &lt;emp&gt;inserted&lt;/emp&gt;.&lt;/p&gt;
+ *       &lt;p&gt;With this one, at the end of the content.&lt;/p&gt;
+ *     &lt;/source:fragment&gt;
+ *   &lt;/source:insert&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ * <p>Input XML document example (insert at beginning):</p>
+ * <pre>
+ * &lt;page&gt;
+ *   ...
+ *   &lt;source:insert&gt;
+ *     &lt;source:source&gt;context://doc/editable/my.xml&lt;/source:source&gt;
+ *     &lt;source:path&gt;page&lt;/source:path&gt;
+ *     &lt;source:replace&gt;content&lt;/source:replace&gt;
+ *     &lt;source:reinsert&gt;content&lt;/source:reinsert&gt;
+ *     &lt;source:fragment&gt;
+ *       &lt;content&gt;
+ *         &lt;p&gt;This new paragraph gets inserted &lt;emp&gt;before&lt;/emp&gt; the other ones.&lt;/p&gt;
+ *       &lt;/content&gt;
+ *     &lt;/source:fragment&gt;
+ *    &lt;source:insert&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ * <p>Input XML document example (replace):</p>
+ * <pre>
+ * &lt;page&gt;
+ *   ...
+ *   &lt;source:insert xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+ *     &lt;source:source&gt;context://doc/editable/my.xml"&lt;/source:source&gt;
+ *     &lt;source:path&gt;page/content&lt;/source:path&gt;
+ *     &lt;source:replace&gt;p[1]&lt;/source:replace&gt;
+ *     &lt;source:fragment&gt;
+ *       &lt;p&gt;This paragraph &lt;emp&gt;replaces&lt;/emp&gt; the first paragraph.&lt;/p&gt;
+ *     &lt;/source:fragment&gt;
+ *   &lt;/source:insert&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ * <p>Output XML document example:</p>
+ * <pre>
+ * &lt;page&gt;
+ *   ...
+ *   &lt;sourceResult xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+ *     &lt;action&gt;new|overwritten|none&lt;/action&gt;
+ *     &lt;behaviour&gt;write|insert&lt;behaviour&gt;
+ *     &lt;execution&gt;success|failure&lt;/execution&gt;
+ *     &lt;serializer&gt;xml&lt;/serializer&gt;
+ *     &lt;source&gt;file:/source/specific/path/to/context/doc/editable/my.xml&lt;/source&gt;
+ *   &lt;/sourceResult&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ *
+ * The XPath specification is very complicated. So here is an example for the sitemap:
+ * <pre>
+ * &lt;page xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
+ *   ...
+ * &lt;source:insert&gt;
+ *   &lt;source:source&gt;sitemap.xmap&lt;/source:source&gt;
+ *   &lt;source:path&gt;/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="sitemap"]/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="components"]/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="generators"]&lt;/source:path&gt;
+ *   &lt;source:fragment&gt;
+ *	  	&lt;generator name="file" xmln="http://apache.org/cocoon/sitemap/1.0"&gt;
+ *			&lt;test/&gt;
+ *		&lt;/generator&gt;
+ *   &lt;/source:fragment&gt;
+ *   &lt;source:replace&gt;*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="generator" and attribute::name="file"]&lt;/source:replace&gt;
+ * &lt;/source:insert&gt;
+ *   ...
+ * &lt;/page&gt;
+ * </pre>
+ *
+ * <p>This insert replaces (if it exists) the file generator definition with a new one.
+ * As the sitemap uses namespaces the XPath for the generator is rather complicated.
+ * Due to this it is necessary that the node specified by path exists if namespaces
+ * are used! Otherwise a node with the name * would be created...</p>
+ *
+ *  <p>The create attribute of insert. If this is set
+ *  to true (default is true), the file is created if it does not exists.
+ *  If it is set to false, it is not created, making insert a real insert.
+ *  create is only usable for files!</p>
+ *  <p>In addition the overwrite attribute is used to check if replacing is allowed.
+ *  If overwrite is true (the default) the node is replaced. If it is false
+ *  the node is not inserted if the replace node is available.</p>
+ *
+ *  <p>[JQ] - the way I understand this, looking at the code:
+ *  <pre>
+ *   if 'replace' is not specified, your 'fragment' is appended as a child of 'path'.
+ *   if 'replace' is specified and it exists and 'overwrite' is true, your 'fragment' is inserted in 'path', before 'replace' and then 'replace' is deleted.
+ *   if 'replace' is specified and it exists and 'overwrite' is false, no action occurs.
+ *   if 'replace' is specified and it does not exist and 'overwrite' is true, your 'fragment' is appended as a child of 'path'.
+ *   if 'replace' is specified and it does not exist and 'overwrite' is false, your 'fragment' is appended as a child of 'path'.
+ *   if 'reinsert' is specified and it does not exist, no action occurs.
+ *  </pre></p>
+ *
+ * The &lt;source:reinsert&gt; option can be used to
+ * reinsert a replaced node at a given path in the new fragment.
+ *
+ * <b>
+ * TODO: Use the serializer instead of the XMLUtils for inserting of fragments<br/>
+ * TODO: Add a &lt;source:before/&gt; tag.
+ * </b>
+ *
+ * @version $Id$
+ */
+public class SourceWritingTransformer extends AbstractSAXTransformer
+                                      implements Disposable {
+
+    public static final String SWT_URI = "http://apache.org/cocoon/source/1.0";
+    public static final String DEFAULT_SERIALIZER = "xml";
+
+    /** incoming elements */
+    public static final String WRITE_ELEMENT = "write";
+    public static final String INSERT_ELEMENT = "insert";
+    public static final String PATH_ELEMENT = "path";
+    public static final String FRAGMENT_ELEMENT = "fragment";
+    public static final String REPLACE_ELEMENT = "replace";
+    public static final String DELETE_ELEMENT = "delete";
+    public static final String SOURCE_ELEMENT = "source";
+    public static final String REINSERT_ELEMENT = "reinsert";
+    /** outgoing elements */
+    public static final String RESULT_ELEMENT = "sourceResult";
+    public static final String EXECUTION_ELEMENT = "execution";
+    public static final String BEHAVIOUR_ELEMENT = "behaviour";
+    public static final String ACTION_ELEMENT = "action";
+    public static final String MESSAGE_ELEMENT = "message";
+    public static final String SERIALIZER_ELEMENT = "serializer";
+    /** main (write or insert) tag attributes */
+    public static final String SERIALIZER_ATTRIBUTE = "serializer";
+    public static final String CREATE_ATTRIBUTE = "create";
+    public static final String OVERWRITE_ATTRIBUTE = "overwrite";
+    /** results */
+    public static final String RESULT_FAILED = "failed";
+    public static final String RESULT_SUCCESS = "success";
+    public static final String ACTION_NONE = "none";
+    public static final String ACTION_NEW = "new";
+    public static final String ACTION_OVER = "overwritten";
+    public static final String ACTION_DELETE = "deleted";
+    /** The current state */
+    private static final int STATE_OUTSIDE  = 0;
+    private static final int STATE_INSERT   = 1;
+    private static final int STATE_PATH     = 3;
+    private static final int STATE_FRAGMENT = 4;
+    private static final int STATE_REPLACE  = 5;
+    private static final int STATE_FILE     = 6;
+    private static final int STATE_REINSERT = 7;
+    private static final int STATE_WRITE    = 8;
+    private static final int STATE_DELETE = 9;
+    private int state;
+    private int parent_state;
+
+    /** The configured serializer name */
+    protected String configuredSerializerName;
+
+    /** The XPath processor */
+    protected XPathProcessor xpathProcessor;
+
+    /**
+     * Constructor. Set the namespace.
+     */
+    public SourceWritingTransformer() {
+        super.defaultNamespaceURI = SWT_URI;
+    }
+
+    /**
+     * Get the current <code>Configuration</code> instance used by this
+     * <code>Configurable</code>.
+     */
+    public void configure(Configuration configuration)
+    throws ConfigurationException {
+        super.configure(configuration);
+        this.configuredSerializerName = configuration.getChild(SERIALIZER_ATTRIBUTE).getValue(DEFAULT_SERIALIZER);
+    }
+
+    /**
+     * Get the <code>Parameter</code> called "serializer" from the
+     * <code>Transformer</code> invocation.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+
+        this.configuredSerializerName = par.getParameter(SERIALIZER_ATTRIBUTE,
+                                                         this.configuredSerializerName);
+        this.state = STATE_OUTSIDE;
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param name The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param attr The attributes attached to the element. If there are no
+     *            attributes, it shall be an empty Attributes object.
+     */
+    public void startTransformingElement(String uri, String name, String raw, Attributes attr)
+    throws SAXException, IOException, ProcessingException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Start transforming element. uri=" + uri +
+                              ", name=" + name + ", raw=" + raw + ", attr=" + attr);
+        }
+
+        // Element: insert
+        if (this.state == STATE_OUTSIDE
+            && (name.equals(INSERT_ELEMENT) || name.equals(WRITE_ELEMENT))) {
+
+            this.state = (name.equals(INSERT_ELEMENT) ? STATE_INSERT : STATE_WRITE);
+            this.parent_state = this.state;
+            if (attr.getValue(CREATE_ATTRIBUTE) != null
+                && attr.getValue(CREATE_ATTRIBUTE).equals("false")) {
+                this.stack.push("false");
+            } else {
+                this.stack.push("true"); // default value
+            }
+            if (attr.getValue(OVERWRITE_ATTRIBUTE) != null
+                && attr.getValue(OVERWRITE_ATTRIBUTE).equals("false")) {
+                this.stack.push("false");
+            } else {
+                this.stack.push("true"); // default value
+            }
+            this.stack.push(attr.getValue(SERIALIZER_ATTRIBUTE));
+            this.stack.push("END");
+
+        // Element: delete
+        } else if (this.state == STATE_OUTSIDE && name.equals(DELETE_ELEMENT)) {
+            this.state = STATE_DELETE;
+            this.parent_state = state;
+            this.stack.push("END");
+        // Element: file
+        } else if (name.equals(SOURCE_ELEMENT)
+                   && (this.state == STATE_INSERT || this.state == STATE_WRITE || this.state == STATE_DELETE)) {
+            this.state = STATE_FILE;
+            this.startTextRecording();
+
+        // Element: path
+        } else if (name.equals(PATH_ELEMENT)
+                   && (this.state == STATE_INSERT || this.state == STATE_WRITE || this.state == STATE_DELETE)) {
+            this.state = STATE_PATH;
+            this.startTextRecording();
+
+        // Element: replace
+        } else if (name.equals(REPLACE_ELEMENT)
+                   && this.state == STATE_INSERT) {
+            this.state = STATE_REPLACE;
+            this.startTextRecording();
+
+        // Element: fragment
+        } else if (name.equals(FRAGMENT_ELEMENT)
+                   &&  (this.state == STATE_INSERT || this.state == STATE_WRITE || this.state == STATE_DELETE)) {
+            this.state = STATE_FRAGMENT;
+            this.startRecording();
+
+        // Element: reinsert
+        } else if (name.equals(REINSERT_ELEMENT)
+                   && this.state == STATE_INSERT) {
+            this.state = STATE_REINSERT;
+            this.startTextRecording();
+
+        } else {
+            super.startTransformingElement(uri, name, raw, attr);
+        }
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param name The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endTransformingElement(String uri, String name, String raw)
+    throws SAXException, IOException, ProcessingException {
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("End transforming element. uri=" + uri +
+                              ", name=" + name + ", raw=" + raw);
+        }
+
+        if ((name.equals(INSERT_ELEMENT) && this.state == STATE_INSERT)
+            || (name.equals(WRITE_ELEMENT) && this.state == STATE_WRITE)) {
+
+            // get the information from the stack
+            DocumentFragment fragment  = null;
+            String tag;
+            String sourceName    = null;
+            String path        = (this.state == STATE_INSERT ? null : "/");
+                                 // source:write's path can be empty
+            String replacePath = null;
+            String reinsert    = null;
+            do {
+                tag = (String)this.stack.pop();
+                if (tag.equals("PATH")) {
+                    path = (String)this.stack.pop();
+                } else if (tag.equals("FILE")) {
+                    sourceName = (String)this.stack.pop();
+                } else if (tag.equals("FRAGMENT")) {
+                    fragment = (DocumentFragment)this.stack.pop();
+                } else if (tag.equals("REPLACE")) {
+                    replacePath = (String)this.stack.pop();
+                } else if (tag.equals("REINSERT")) {
+                    reinsert = (String)this.stack.pop();
+                }
+            } while ( !tag.equals("END") );
+
+            final String localSerializer = (String)this.stack.pop();
+            final boolean overwrite = this.stack.pop().equals("true");
+            final boolean create = this.stack.pop().equals("true");
+
+            this.insertFragment(sourceName,
+                                    path,
+                                    fragment,
+                                    replacePath,
+                                    create,
+                                    overwrite,
+                                    reinsert,
+                                    localSerializer,
+                                    name);
+
+            this.state = STATE_OUTSIDE;
+
+        // Element: delete
+        } else if (name.equals(DELETE_ELEMENT) && this.state == STATE_DELETE) {
+            String sourceName = null;
+            String tag;
+            do {
+                tag = (String)this.stack.pop();
+                if (tag.equals("FILE")) {
+                    sourceName = (String)this.stack.pop();
+                } else if (tag.equals("FRAGMENT")) {
+                    //Get rid of it
+                    this.stack.pop();
+                }
+            } while ( !tag.equals("END"));
+
+            this.deleteSource(sourceName);
+            this.state = STATE_OUTSIDE;
+        // Element: file
+        } else if (name.equals(SOURCE_ELEMENT) && this.state == STATE_FILE) {
+            this.state = this.parent_state;
+            this.stack.push(this.endTextRecording());
+            this.stack.push("FILE");
+
+        // Element: path
+        } else if (name.equals(PATH_ELEMENT) && this.state == STATE_PATH) {
+            this.state = this.parent_state;
+            this.stack.push(this.endTextRecording());
+            this.stack.push("PATH");
+
+        // Element: replace
+        } else if (name.equals(REPLACE_ELEMENT) && this.state == STATE_REPLACE) {
+            this.state = this.parent_state;
+            this.stack.push(this.endTextRecording());
+            this.stack.push("REPLACE");
+
+        // Element: fragment
+        } else if (name.equals(FRAGMENT_ELEMENT) && this.state == STATE_FRAGMENT) {
+            this.state = this.parent_state;
+            this.stack.push(this.endRecording());
+            this.stack.push("FRAGMENT");
+
+        // Element: reinsert
+        } else if (name.equals(REINSERT_ELEMENT) && this.state == STATE_REINSERT) {
+            this.state = this.parent_state;
+            this.stack.push(this.endTextRecording());
+            this.stack.push("REINSERT");
+
+        // default
+        } else {
+            super.endTransformingElement(uri, name, raw);
+        }
+    }
+
+    /**
+     * Deletes a source
+     * @param systemID
+     */
+    private void deleteSource(String systemID) throws ProcessingException, IOException, SAXException {
+        Source source = null;
+        try {
+            source = resolver.resolveURI(systemID);
+            if (!(source instanceof ModifiableSource)) {
+                throw new ProcessingException("Source '" + systemID + "' is not writeable.");
+            }
+
+            ((ModifiableSource)source).delete();
+            reportResult("none",
+                         "delete",
+                         "source deleted successfully",
+                         systemID,
+                         RESULT_SUCCESS,
+                         ACTION_DELETE);
+        } catch (SourceException se) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("FAIL exception: " + se, se);
+            }
+            reportResult("none",
+                         "delete",
+                         "unable to delete source: " + se.getMessage(),
+                         systemID,
+                         RESULT_FAILED,
+                         ACTION_DELETE);
+        } finally {
+            resolver.release(source);
+        }
+    }
+
+    /**
+     * Insert a fragment into a file.
+     * The file is loaded by the resource connector.
+     *
+     * @param systemID The name of the xml file.
+     * @param path   The XPath specifying the node under which the data is inserted
+     * @param fragment The data to be inserted.
+     * @param replacePath Optional XPath relative to <CODE>path</CODE>. This path
+     *                    can specify a node which will be removed if it exists.
+     *                    So insertFragment can be used as a replace utility.
+     * @param create      If the file does not exists and this is set to
+     *                    <CODE>false</CODE> nothing is inserted. If it is set
+     *                    to <CODE>true</CODE> the file is created and the data
+     *                    is inserted.
+     * @param overwrite   If this is set to <CODE>true</CODE> the data is only
+     *                    inserted if the node specified by the <CODE>replacePath</CODE>
+     *                    does not exists.
+     * @param reinsertPath If specified and a node is replaced , all children of
+     *                     this replaced node will be reinserted at the given path.
+     * @param localSerializer  The serializer used to serialize the XML
+     * @param tagname     The name of the tag that triggered me 'insert' or 'write'
+     */
+    protected void insertFragment(String systemID,
+                                  String path,
+                                  DocumentFragment fragment,
+                                  String replacePath,
+                                  boolean create,
+                                  boolean overwrite,
+                                  String  reinsertPath,
+                                  String  localSerializer,
+                                  String  tagname)
+    throws SAXException, IOException, ProcessingException {
+        // no sync req
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Insert fragment. systemID=" + systemID +
+                              ", path=" + path +
+                              ", replace=" + replacePath +
+                              ", create=" + create +
+                              ", overwrite=" + overwrite +
+                              ", reinsert=" + reinsertPath +
+                              ", fragment=" + (fragment == null ? "null" : XMLUtils.serializeNode(fragment)));
+        }
+
+        // test parameter
+        if (systemID == null) {
+            throw new ProcessingException("insertFragment: systemID is required.");
+        }
+        if (path == null) {
+            throw new ProcessingException("insertFragment: path is required.");
+        }
+        if (path.startsWith("/")) {
+            path = path.substring(1);
+        }
+        if (fragment == null) {
+            throw new ProcessingException("insertFragment: fragment is required.");
+        }
+
+        // first: read the source as a DOM
+        Source source = null;
+        Document resource = null;
+        boolean failed = true;
+        boolean exists = false;
+        String message = "";
+        String target = systemID;
+        try {
+            source = this.resolver.resolveURI(systemID);
+            if (! (source instanceof ModifiableSource)) {
+                throw new ProcessingException("Source '" + systemID + "' is not writeable.");
+            }
+            ModifiableSource ws = (ModifiableSource) source;
+            exists = ws.exists();
+            target = source.getURI();
+
+            // Insert?
+            if (exists && this.state == STATE_INSERT) {
+                message = "content inserted at: " + path;
+                resource = SourceUtil.toDOM(source);
+                // import the fragment
+                Node importNode = resource.importNode(fragment, true);
+                // get the node
+                Node parent = DOMUtil.selectSingleNode(resource, path, this.xpathProcessor);
+
+                // replace?
+                if (replacePath != null) {
+                    try {
+                        Node replaceNode = DOMUtil.getSingleNode(parent, replacePath, this.xpathProcessor);
+                        // now get the parent of this node until it is the parent node for insertion
+                        while (replaceNode != null && !replaceNode.getParentNode().equals(parent)) {
+                           replaceNode = replaceNode.getParentNode();
+                        }
+
+                        if (replaceNode != null) {
+                            if (overwrite) {
+                                if (parent.getNodeType() == Node.DOCUMENT_NODE) {
+                                    // replacing of the document element is not allowed
+                                    resource = newDocument();
+                                    resource.appendChild(resource.importNode(importNode, true));
+                                    parent = resource;
+                                    replaceNode = resource.importNode(replaceNode, true);
+                                } else {
+                                    parent.replaceChild(importNode, replaceNode);
+                                }
+                                message += ", replacing: " + replacePath;
+                                if (reinsertPath != null) {
+                                    Node insertAt = DOMUtil.getSingleNode(parent, reinsertPath, this.xpathProcessor);
+                                    if (insertAt != null) {
+                                        while (replaceNode.hasChildNodes()) {
+                                            insertAt.appendChild(replaceNode.getFirstChild());
+                                        }
+                                    } else { // reinsert point null
+                                        message = "replace failed, could not find your reinsert path: " + reinsertPath;
+                                        resource = null;
+                                    }
+                                }
+                            } else { // overwrite was false
+                                message = "replace failed, no overwrite allowed.";
+                                resource = null;
+                            }
+                        } else { // specified replaceNode was not found
+                            parent.appendChild(importNode);
+                        }
+                    } catch (javax.xml.transform.TransformerException sax) {
+                        throw new ProcessingException("TransformerException: " + sax, sax);
+                    }
+                } else { // no replace path, just do an insert at end
+                    parent.appendChild(importNode);
+                }
+
+            // Create?
+            } else if (create) {
+                // Create new document
+                resource = newDocument();
+
+                // Import the fragment
+                Node importNode = resource.importNode(fragment, true);
+
+                if (path.equals("")) {
+                    // Parent node is document itself
+                    NodeList nodes = importNode.getChildNodes();
+                    for (int i = 0; i < nodes.getLength();) {
+                        Node node = nodes.item(i);
+                        switch (node.getNodeType()) {
+                            case Node.ELEMENT_NODE:
+                                // May throw exception if fragment has more than one element
+                                resource.appendChild(node);
+                                break;
+
+                            case Node.DOCUMENT_TYPE_NODE:
+                            case Node.PROCESSING_INSTRUCTION_NODE:
+                            case Node.COMMENT_NODE:
+                                resource.appendChild(node);
+                                break;
+
+                            default:
+                                // Ignore all other nodes
+                                i++;
+                                break;
+                        }
+                    }
+                    message = "entire source overwritten";
+
+                } else {
+                    // Get the parent node
+                    Node parent = DOMUtil.selectSingleNode(resource, path, this.xpathProcessor);
+                    // Add a fragment
+                    parent.appendChild(importNode);
+                    message = "content appended to: " + path;
+                }
+
+            // Oops: Document does not exist and create is not allowed.
+            } else {
+                message = "create not allowed";
+                resource = null;/**/
+            }
+
+
+            // Write source
+            if (resource != null) {
+                resource.normalize();
+                // use serializer
+                if (localSerializer == null) {
+                    localSerializer = this.configuredSerializerName;
+                }
+
+                if (localSerializer != null) {
+                    // Lookup the Serializer
+                    ServiceSelector selector = null;
+                    Serializer serializer = null;
+                    OutputStream oStream = null;
+                    try {
+                        selector = (ServiceSelector)manager.lookup(Serializer.ROLE + "Selector");
+                        serializer = (Serializer)selector.select(localSerializer);
+                        oStream = ws.getOutputStream();
+                        serializer.setOutputStream(oStream);
+                        DOMStreamer streamer = new DOMStreamer(serializer);
+                        streamer.stream(resource);
+                    } finally {
+                        if (oStream != null) {
+                            oStream.flush();
+                            try {
+                                oStream.close();
+                                failed = false;
+                            } catch (Throwable t) {
+                                if (getLogger().isDebugEnabled()) {
+                                    getLogger().debug("FAIL (oStream.close) exception"+t, t);
+                                }
+                                throw new ProcessingException("Could not process your document.", t);
+                            } finally {
+                                if (selector != null) {
+                                    selector.release(serializer);
+                                    this.manager.release(selector);
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("ERROR: No serializer");
+                    }
+                    //throw new ProcessingException("No serializer specified for writing to source " + systemID);
+                    message = "That source requires a serializer, please add the appropirate tag to your code.";
+                }
+            }
+        } catch (DOMException de) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("FAIL exception: "+de, de);
+            }
+            message = "There was a problem manipulating your document: " + de;
+        } catch (ServiceException ce) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("FAIL exception: "+ce, ce);
+            }
+            message = "There was a problem looking up a component: " + ce;
+        } catch (SourceException se) {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("FAIL exception: "+se, se);
+            }
+            message = "There was a problem resolving that source: [" + systemID + "] : " + se;
+        } finally {
+            this.resolver.release(source);
+        }
+
+        // Report result
+        String result = (failed) ? RESULT_FAILED : RESULT_SUCCESS;
+        String action = ACTION_NONE;
+        if (!failed) {
+            action = (exists) ? ACTION_OVER : ACTION_NEW;
+        }
+
+        reportResult(localSerializer, tagname, message, target, result, action);
+    }
+
+    private void reportResult(String localSerializer,
+                                String tagname,
+                                String message,
+                                String target,
+                                String result,
+                                String action)
+    throws SAXException {
+        sendStartElementEvent(RESULT_ELEMENT);
+            sendStartElementEvent(EXECUTION_ELEMENT);
+                sendTextEvent(result);
+            sendEndElementEvent(EXECUTION_ELEMENT);
+            sendStartElementEvent(MESSAGE_ELEMENT);
+                sendTextEvent(message);
+            sendEndElementEvent(MESSAGE_ELEMENT);
+            sendStartElementEvent(BEHAVIOUR_ELEMENT);
+                sendTextEvent(tagname);
+            sendEndElementEvent(BEHAVIOUR_ELEMENT);
+            sendStartElementEvent(ACTION_ELEMENT);
+                sendTextEvent(action);
+            sendEndElementEvent(ACTION_ELEMENT);
+            sendStartElementEvent(SOURCE_ELEMENT);
+                sendTextEvent(target);
+            sendEndElementEvent(SOURCE_ELEMENT);
+            if (localSerializer != null) {
+                sendStartElementEvent(SERIALIZER_ELEMENT);
+                    sendTextEvent(localSerializer);
+                sendEndElementEvent(SERIALIZER_ELEMENT);
+            }
+        sendEndElementEvent(RESULT_ELEMENT);
+    }
+
+    private Document newDocument() throws SAXException, ServiceException {
+        DOMParser parser = (DOMParser) this.manager.lookup(DOMParser.ROLE);
+        try {
+            return parser.createDocument();
+        } finally {
+            this.manager.release(parser);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        super.service(manager);
+        this.xpathProcessor = (XPathProcessor) this.manager.lookup(XPathProcessor.ROLE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if (this.manager != null) {
+            this.manager.release(this.xpathProcessor);
+            this.xpathProcessor = null;
+        }
+        super.dispose();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TeeTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TeeTransformer.java
new file mode 100644
index 0000000..36b1ce0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TeeTransformer.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.ClassUtils;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * @cocoon.sitemap.component.name tee
+ * @cocoon.sitemap.component.logger sitemap.transformer.tee
+ * @cocoon.sitemap.component.pooling.max  16
+ * 
+ * The Teetransformer serializes SAX events as-is to the {@link org.apache.excalibur.source.ModifiableSource}
+ * specified by its <code>src</code> parameter. 
+ * It does not in any way change the events. 
+ * <p/>
+ * This transformer works just like the unix "tee" command and is useful for debugging
+ * received XML streams.
+ * <p/>
+ * Usage:<br>
+ * <pre>
+ * &lt;map:transform type="tee" src="url"/&gt;
+ * </pre>
+ * 
+ * @version $Id$
+ */
+public class TeeTransformer extends AbstractSAXTransformer {
+
+    /** the serializer */
+    private TransformerHandler serializer;
+
+    /** the transformer factory to use */
+    private SAXTransformerFactory transformerFactory;
+
+    /** the resolver */
+    private SourceResolver resolver;
+    
+    private OutputStream os;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.cocoon.sitemap.SitemapModelComponent#setup(org.apache.cocoon.environment.SourceResolver,
+     *      java.util.Map, java.lang.String,
+     *      org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+        throws ProcessingException, SAXException, IOException {
+
+        super.setup(resolver, objectModel, src, parameters);
+
+        Source source = null;
+        try {
+            this.resolver = resolver;
+            source = this.resolver.resolveURI(src);
+            String systemId = source.getURI();
+            if (!(source instanceof ModifiableSource)) {
+                throw new ProcessingException("Source '" + systemId + "' is not writeable.");
+            }
+            this.serializer = this.transformerFactory.newTransformerHandler();
+            os = ((ModifiableSource) source).getOutputStream();
+            this.serializer.setResult(new StreamResult(os));
+        } catch (SourceException e) {
+            throw SourceUtil.handle(e);
+        } catch (TransformerConfigurationException e) {
+            throw new ProcessingException(e);
+        } catch (TransformerFactoryConfigurationError error) {
+            throw new ProcessingException(error.getException());
+        } finally {
+            if (source != null) {
+                this.resolver.release(source);
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException {
+        String tFactoryClass = configuration.getChild("transformer-factory").getValue(null);
+        if (tFactoryClass != null) {
+            try {
+                this.transformerFactory = (SAXTransformerFactory) ClassUtils
+                    .newInstance(tFactoryClass);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("Using transformer factory " + tFactoryClass);
+                }
+            } catch (Exception e) {
+                throw new ConfigurationException(
+                    "Cannot load transformer factory " + tFactoryClass, e);
+            }
+        } else {
+            this.transformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+
+        }
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     */
+    public void setDocumentLocator(Locator locator) {
+        super.contentHandler.setDocumentLocator(locator);
+        this.serializer.setDocumentLocator(locator);
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument() throws SAXException {
+        super.contentHandler.startDocument();
+        this.serializer.startDocument();
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument() throws SAXException {
+        super.contentHandler.endDocument();
+        this.serializer.endDocument();
+        if (os != null) {
+            try {
+                os.close();
+            } catch (IOException e) {
+                throw new CascadingRuntimeException("Error closing output stream.", e);
+            }
+        }
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     */
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        super.contentHandler.startPrefixMapping(prefix, uri);
+        this.serializer.startPrefixMapping(prefix, uri);
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     */
+    public void endPrefixMapping(String prefix) throws SAXException {
+        super.contentHandler.endPrefixMapping(prefix);
+        this.serializer.endPrefixMapping(prefix);
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
+        super.contentHandler.startElement(uri, loc, raw, a);
+        this.serializer.startElement(uri, loc, raw, a);
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement(String uri, String loc, String raw) throws SAXException {
+        super.contentHandler.endElement(uri, loc, raw);
+        this.serializer.endElement(uri, loc, raw);
+    }
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters(char ch[], int start, int len) throws SAXException {
+        super.contentHandler.characters(ch, start, len);
+        this.serializer.characters(ch, start, len);
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace(char ch[], int start, int len) throws SAXException {
+        super.contentHandler.ignorableWhitespace(ch, start, len);
+        this.serializer.ignorableWhitespace(ch, start, len);
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction(String target, String data) throws SAXException {
+        super.contentHandler.processingInstruction(target, data);
+        this.serializer.processingInstruction(target, data);
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     */
+    public void skippedEntity(String name) throws SAXException {
+        super.contentHandler.skippedEntity(name);
+        this.serializer.skippedEntity(name);
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     */
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        super.lexicalHandler.startDTD(name, publicId, systemId);
+        this.serializer.startDTD(name, publicId, systemId);
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD() throws SAXException {
+        super.lexicalHandler.endDTD();
+        this.serializer.endDTD();
+    }
+
+    /**
+     * Report the beginning of an entity.
+     */
+    public void startEntity(String name) throws SAXException {
+        super.lexicalHandler.startEntity(name);
+        this.serializer.startEntity(name);
+    }
+
+    /**
+     * Report the end of an entity.
+     */
+    public void endEntity(String name) throws SAXException {
+        super.lexicalHandler.endEntity(name);
+        this.serializer.endEntity(name);
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA() throws SAXException {
+        super.lexicalHandler.startCDATA();
+        this.serializer.startCDATA();
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA() throws SAXException {
+        super.lexicalHandler.endCDATA();
+        this.serializer.endCDATA();
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     */
+    public void comment(char ch[], int start, int len) throws SAXException {
+        super.lexicalHandler.comment(ch, start, len);
+        this.serializer.comment(ch, start, len);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     */
+    public void recycle() {
+        super.recycle();
+        this.serializer = null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/Transformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/Transformer.java
new file mode 100644
index 0000000..26ce215
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/Transformer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.cocoon.sitemap.SitemapModelComponent;
+import org.apache.cocoon.xml.XMLPipe;
+
+/**
+ * A transformer is the zero to several intermediate points in a pipeline.
+ * It "transforms" incoming XML arriving as SAX events from the pipeline
+ * and sends modified XML as SAX events down the pipeline.
+ *
+ * @version $Id$
+ */
+public interface Transformer extends XMLPipe, SitemapModelComponent {
+
+    String ROLE = Transformer.class.getName();
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TransformerFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TransformerFactory.java
new file mode 100644
index 0000000..ec02543
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TransformerFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+/**
+ * A transformer factory is the factory of {@link Transformer}s.
+ *
+ * <p>Regular TransformerFactory implementation should be
+ * {@link org.apache.avalon.framework.thread.ThreadSafe} component
+ * serving as a factory of lightweight {@link Transformer} objects.</p>
+ *
+ * <p><strong>NOTE:</strong> Only Disposable interface is applicable to
+ * the Transformer instance returned by the {@link #getInstance()}.</p>
+
+ * @since 2.2
+ * @version $Id$
+ */
+public interface TransformerFactory {
+
+    String ROLE = Transformer.ROLE;
+
+    /**
+     * Instance of the Transformer created by the TransformerFactory
+     */
+    interface Instance extends Transformer {
+
+        /**
+         * @return TransformerFactory which created this Transformer instance
+         */
+        TransformerFactory getFactory();
+    }
+
+    /**
+     * Create an instance of the Transformer
+     */
+    Instance getInstance();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TraxTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TraxTransformer.java
new file mode 100644
index 0000000..3c9a9ee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/TraxTransformer.java
@@ -0,0 +1,612 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.xslt.TraxErrorListener;
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.exception.NestableRuntimeException;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.xml.xslt.XSLTProcessor;
+import org.apache.excalibur.xml.xslt.XSLTProcessorException;
+import org.xml.sax.SAXException;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * The stylesheet processor
+ *
+ * @cocoon.sitemap.component.name   xslt
+ * @cocoon.sitemap.component.logger sitemap.transformer.xslt
+ * @cocoon.sitemap.component.documentation.caching
+ *               Uses the last modification date of the xslt document for validation
+ *
+ * @cocoon.sitemap.component.pooling.max  32
+ * <p>
+ * This Transformer is used to transform the incoming SAX stream using
+ * a TrAXProcessor. Use the following sitemap declarations to define, configure
+ * and parameterize it:
+ * </p>
+ * <b>In the map:sitemap/map:components/map:transformers:</b><br>
+ * <pre>
+ * &lt;map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"&gt;<br>
+ *   &lt;use-request-parameters&gt;false&lt;/use-request-parameters&gt;
+ *   &lt;use-browser-capabilities-db&gt;false&lt;/use-browser-capabilities-db&gt;
+ *   &lt;use-session-info&gt;false&lt;/use-session-info&gt;
+ *   &lt;xslt-processor-role&gt;xslt&lt;/xslt-processor-role&gt;
+ *   &lt;transformer-factory&gt;org.apache.xalan.processor.TransformerFactoryImpl&lt;/transformer-factory&gt;
+ *   &lt;check-includes&gt;true&lt;/check-includes&gt;
+ * &lt;/map:transformer&gt;
+ * </pre>
+ *
+ * The &lt;use-request-parameter&gt; configuration forces the transformer to make all
+ * request parameters available in the XSLT stylesheet. Note that this has
+ * implications for caching of the generated output of this transformer.<br>
+ * This property is false by default.
+ * <p>
+ * The &lt;use-cookies&gt; configuration forces the transformer to make all
+ * cookies from the request available in the XSLT stylesheets.
+ * Note that this has implications for caching of the generated output of this
+ * transformer.<br>
+ * This property is false by default.
+ * <p>
+ * The &lt;use-session-info&gt; configuration forces the transformer to make all
+ * of the session information available in the XSLT stylesheetas.<br>
+ * These infos are (boolean values are "true" or "false" strings: session-is-new,
+ * session-id-from-cookie, session-id-from-url, session-valid, session-id.<br>
+ * This property is false by default.
+ *
+ * <p>Note that this has implications for caching of the generated output of
+ * this transformer.<br>
+ *
+ *
+ * The &lt;xslt-processor-role&gt; configuration allows to specify the TrAX processor (defined in
+ * the cocoon.xconf) that will be used to obtain the XSLT processor. This allows to have
+ * several XSLT processors in the configuration (e.g. Xalan, XSLTC, Saxon, ...) and choose
+ * one or the other depending on the needs of stylesheet specificities.<br>
+ * If no processor is specified, this transformer will use the XSLT implementation
+ * that Cocoon uses internally.
+ *
+ * The &lt;transformer-factory&gt; configuration allows to specify the TrAX transformer factory
+ * implementation that will be used to obtain the XSLT processor. This is only useful for
+ * compatibility reasons. Please configure the XSLT processor in the cocoon.xconf properly
+ * and use the xslt-processor-role configuration mentioned above.
+ *
+ * The &lt;check-includes&gt; configuration specifies if the included stylesheets are
+ * also checked for changes during caching. If this is set to true (default), the
+ * included stylesheets are also checked for changes; if this is set to false, only
+ * the main stylesheet is checked. Setting this to false improves the performance,
+ * and should be used whenever no includes are in the stylesheet. However, if
+ * you have includes, you have to be careful when changing included stylesheets
+ * as the changes might not take effect immediately. You should touch the main
+ * stylesheet as well.
+ *
+ * <p>
+ * <b>In a map:sitemap/map:pipelines/map:pipeline:</b><br>
+ * <pre>
+ * &lt;map:transform type="xslt" src="stylesheets/yours.xsl"&gt;<br>
+ *   &lt;parameter name="myparam" value="myvalue"/&gt;
+ * &lt;/map:transform&gt;
+ * </pre>
+ * All &lt;parameter&gt; declarations will be made available in the XSLT stylesheet as
+ * xsl:variables.
+ *
+ * @version SVN $Id$
+ */
+public class TraxTransformer extends AbstractTransformer
+implements Serviceable, Configurable, CacheableProcessingComponent, Disposable {
+
+    /** The service manager instance (protected because used by subclasses) */
+    protected ServiceManager manager;
+
+    /** The object model (protected because used by subclasses) */
+    protected Map objectModel;
+
+    /** Logicsheet parameters (protected because used by subclasses) */
+    protected Map logicSheetParameters;
+
+    /** Should we make the request parameters available in the stylesheet? (default is off) */
+    private boolean useParameters = false;
+    private boolean _useParameters = false;
+
+    /** Should we make the cookies available in the stylesheet? (default is off) */
+    private boolean useCookies = false;
+    private boolean _useCookies = false;
+
+    /** Should we info about the session available in the stylesheet? (default is off) */
+    private boolean useSessionInfo = false;
+    private boolean _useSessionInfo = false;
+
+    /** Do we check included stylesheets for changes? */
+    private boolean checkIncludes = true;
+
+    /** The trax TransformerHandler */
+    protected TransformerHandler transformerHandler;
+
+    /** The validity of the Transformer */
+    protected SourceValidity transformerValidity;
+
+    /** The Source */
+    private Source inputSource;
+    /** The parameters */
+    private Parameters par;
+    /** The source resolver */
+    private SourceResolver resolver;
+
+    /** Default source, used to create specialized transformers by configuration */
+    private String defaultSrc;
+
+    /** The XSLTProcessor */
+    private XSLTProcessor xsltProcessor;
+
+    /** Did we finish the processing (is endDocument() called) */
+    private boolean finishedDocument = false;
+
+    /** Xalan's DTMManager.getIncremental() method. See recycle() method to see what we need this for. */
+    private Method xalanDtmManagerGetIncrementalMethod;
+
+    /** Exception that might occur during setConsumer */
+    private SAXException exceptionDuringSetConsumer;
+
+    /** The error listener used by the stylesheet */
+    private TraxErrorListener errorListener;
+
+    /**
+     * Configure this transformer.
+     */
+    public void configure(Configuration conf)
+    throws ConfigurationException {
+        Configuration child;
+
+        child = conf.getChild("use-request-parameters");
+        this.useParameters = child.getValueAsBoolean(false);
+        this._useParameters = this.useParameters;
+
+        child = conf.getChild("use-cookies");
+        this.useCookies = child.getValueAsBoolean(false);
+        this._useCookies = this.useCookies;
+
+        child = conf.getChild("use-session-info");
+        this.useSessionInfo = child.getValueAsBoolean(false);
+        this._useSessionInfo = this.useSessionInfo;
+
+        child = conf.getChild("transformer-factory");
+        // traxFactory is null, if transformer-factory config is unspecified
+        final String traxFactory = child.getValue(null);
+
+        child = conf.getChild("xslt-processor-role");
+        String xsltProcessorRole = child.getValue(XSLTProcessor.ROLE);
+        if (!xsltProcessorRole.startsWith(XSLTProcessor.ROLE)) {
+            xsltProcessorRole = XSLTProcessor.ROLE + '/' + xsltProcessorRole;
+        }
+
+        child = conf.getChild("check-includes");
+        this.checkIncludes = child.getValueAsBoolean(this.checkIncludes);
+
+        child = conf.getChild("default-src",false);
+        if(child!=null) {
+            this.defaultSrc = child.getValue();
+        }
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Use parameters is " + this.useParameters);
+            getLogger().debug("Use cookies is " + this.useCookies);
+            getLogger().debug("Use session info is " + this.useSessionInfo);
+            getLogger().debug("Use TrAX Processor " + xsltProcessorRole);
+            getLogger().debug("Check for included stylesheets is " + this.checkIncludes);
+            if (traxFactory != null) {
+                getLogger().debug("Use TrAX Transformer Factory " + traxFactory);
+            } else {
+                getLogger().debug("Use default TrAX Transformer Factory.");
+            }
+            getLogger().debug("Default source = " + this.defaultSrc);
+        }
+
+        try {
+            this.xsltProcessor = (XSLTProcessor) this.manager.lookup(xsltProcessorRole);
+            if (traxFactory != null) {
+                this.xsltProcessor.setTransformerFactory(traxFactory);
+            }
+        } catch (ServiceException e) {
+            throw new ConfigurationException("Cannot load XSLT processor", e);
+        }
+
+        try {
+            // see the recyle() method to see what we need this for
+            Class dtmManagerClass = Class.forName("org.apache.xml.dtm.DTMManager");
+            xalanDtmManagerGetIncrementalMethod = dtmManagerClass.getMethod("getIncremental", null);
+        } catch (ClassNotFoundException e) {
+            // do nothing -- user does not use xalan, so we don't need the dtm manager
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Was not able to get getIncremental method from Xalan's DTMManager.", e);
+        }
+    }
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Set the <code>SourceResolver</code>, the <code>Map</code> with
+     * the object model, the source and sitemap
+     * <code>Parameters</code> used to process the request.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+    throws SAXException, ProcessingException, IOException {
+
+        if(src==null && defaultSrc!=null) {
+            if(getLogger().isDebugEnabled()) {
+                getLogger().debug("src is null, using default source " + defaultSrc);
+            }
+            src = defaultSrc;
+        }
+
+        if (src == null) {
+            throw new ProcessingException("Stylesheet URI can't be null");
+        }
+
+        this.par = par;
+        this.objectModel = objectModel;
+        this.resolver = resolver;
+        try {
+            this.inputSource = resolver.resolveURI(src);
+        } catch (SourceException se) {
+            throw SourceUtil.handle("Unable to resolve " + src, se);
+        }
+        _useParameters = par.getParameterAsBoolean("use-request-parameters", this.useParameters);
+        _useCookies = par.getParameterAsBoolean("use-cookies", this.useCookies);
+        _useSessionInfo = par.getParameterAsBoolean("use-session-info", this.useSessionInfo);
+        final boolean _checkIncludes = par.getParameterAsBoolean("check-includes", this.checkIncludes);
+
+        if (getLogger().isDebugEnabled()) {
+            getLogger().debug("Using stylesheet: '" + this.inputSource.getURI() + "' in " + this);
+            getLogger().debug("Use parameters is " + this._useParameters);
+            getLogger().debug("Use cookies is " + this._useCookies);
+            getLogger().debug("Use session info is " + this._useSessionInfo);
+            getLogger().debug("Check for included stylesheets is " + _checkIncludes);
+        }
+
+        // Get a Transformer Handler if we check for includes
+        // If we don't check the handler is get during setConsumer()
+        try {
+            if ( _checkIncludes ) {
+                XSLTProcessor.TransformerHandlerAndValidity handlerAndValidity =
+                        this.xsltProcessor.getTransformerHandlerAndValidity(this.inputSource, null);
+                this.transformerHandler = handlerAndValidity.getTransfomerHandler();
+                this.transformerValidity = handlerAndValidity.getTransfomerValidity();
+            } else {
+                this.transformerValidity = this.inputSource.getValidity();
+            }
+        } catch (XSLTProcessorException se) {
+            throw new ProcessingException("Unable to get transformer handler for " + this.inputSource.getURI(), se);
+        }
+    }
+
+    /**
+     * Generate the unique key.
+     * This key must be unique inside the space of this component.
+     *
+     * @return The generated key hashes the src
+     */
+    public Serializable getKey() {
+        Map map = getLogicSheetParameters();
+        if (map == null) {
+            return this.inputSource.getURI();
+        }
+
+        StringBuffer sb = new StringBuffer();
+        sb.append(this.inputSource.getURI());
+        Set entries = map.entrySet();
+        for(Iterator i=entries.iterator(); i.hasNext();){
+            sb.append(';');
+            Map.Entry entry = (Map.Entry)i.next();
+            sb.append(entry.getKey());
+            sb.append('=');
+            sb.append(entry.getValue());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Generate the validity object.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        //
+        // VG: Key is generated using parameter/value pairs,
+        // so this information does not need to be verified again
+        // (if parameter added/removed or value changed, key should
+        // change also), only stylesheet's validity is included.
+        //
+        return this.transformerValidity;
+    }
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+
+        if ( this.transformerHandler == null ) {
+            try {
+                this.transformerHandler = this.xsltProcessor.getTransformerHandler(this.inputSource);
+            } catch (XSLTProcessorException se) {
+                // the exception will be thrown during startDocument()
+                this.exceptionDuringSetConsumer =
+                   new SAXException("Unable to get transformer handler for " + this.inputSource.getURI(), se);
+                return;
+            }
+        }
+        final Map map = getLogicSheetParameters();
+        if (map != null) {
+            final javax.xml.transform.Transformer transformer = this.transformerHandler.getTransformer();
+            final Iterator iterator = map.entrySet().iterator();
+            while (iterator.hasNext()) {
+                final Map.Entry entry = (Entry) iterator.next();
+                transformer.setParameter((String)entry.getKey(), entry.getValue());
+            }
+        }
+
+        super.setContentHandler(this.transformerHandler);
+        super.setLexicalHandler(this.transformerHandler);
+
+        if (this.transformerHandler instanceof LogEnabled) {
+        	((LogEnabled)this.transformerHandler).enableLogging(getLogger());
+        }
+        // According to TrAX specs, all TransformerHandlers are LexicalHandlers
+        final SAXResult result = new SAXResult(consumer);
+        result.setLexicalHandler(consumer);
+        this.transformerHandler.setResult(result);
+
+        this.errorListener = new TraxErrorListener(getLogger(), this.inputSource.getURI());
+        this.transformerHandler.getTransformer().setErrorListener(this.errorListener);
+    }
+
+    /**
+     * Get the parameters for the logicsheet
+     */
+    protected Map getLogicSheetParameters() {
+        if (this.logicSheetParameters != null) {
+            return this.logicSheetParameters;
+        }
+        HashMap map = null;
+        if (par != null) {
+            String[] params = par.getNames();
+            if (params != null) {
+                for(int i = 0; i < params.length; i++) {
+                    String name = params[i];
+                    if (isValidXSLTParameterName(name)) {
+                        String value = par.getParameter(name,null);
+                        if (value != null) {
+                            if (map == null) {
+                                map = new HashMap(params.length);
+                            }
+                            map.put(name,value);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (this._useParameters) {
+            Request request = ObjectModelHelper.getRequest(objectModel);
+
+            Enumeration parameters = request.getParameterNames();
+            if (parameters != null) {
+                while (parameters.hasMoreElements()) {
+                    String name = (String) parameters.nextElement();
+                    if (isValidXSLTParameterName(name)) {
+                        String value = request.getParameter(name);
+                        if (map == null) {
+                            map = new HashMap();
+                        }
+                        map.put(name,value);
+                    }
+                }
+            }
+        }
+
+        if (this._useSessionInfo) {
+            final Request request = ObjectModelHelper.getRequest(objectModel);
+            if (map == null) {
+                map = new HashMap(6);
+            }
+
+            final Session session = request.getSession(false);
+            if (session != null) {
+                map.put("session-available", "true");
+                map.put("session-is-new", BooleanUtils.toStringTrueFalse(session.isNew()));
+                map.put("session-id-from-cookie", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdFromCookie()));
+                map.put("session-id-from-url", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdFromURL()));
+                map.put("session-valid", BooleanUtils.toStringTrueFalse(request.isRequestedSessionIdValid()));
+                map.put("session-id", session.getId());
+            } else {
+                map.put("session-available", "false");
+            }
+        }
+
+        if (this._useCookies) {
+            Request request = ObjectModelHelper.getRequest(objectModel);
+            Cookie cookies[] = request.getCookies();
+            if (cookies != null) {
+                for (int i = 0; i < cookies.length; i++) {
+                    String name = cookies[i].getName();
+                    if (isValidXSLTParameterName(name)) {
+                        String value = cookies[i].getValue();
+                        if (map == null) {
+                            map = new HashMap(cookies.length);
+                        }
+                        map.put(name,value);
+                    }
+                }
+            }
+        }
+        this.logicSheetParameters = map;
+        return this.logicSheetParameters;
+    }
+
+    /**
+     * Test if the name is a valid parameter name for XSLT
+     */
+    static boolean isValidXSLTParameterName(String name) {
+        if (name.length() == 0) {
+            return false;
+        }
+
+        char c = name.charAt(0);
+        if (!(Character.isLetter(c) || c == '_')) {
+            return false;
+        }
+
+        for (int i = name.length()-1; i > 1; i--) {
+            c = name.charAt(i);
+            if (!(Character.isLetterOrDigit(c) ||
+                    c == '-' ||
+                    c == '_' ||
+                    c == '.')) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Disposable
+     */
+    public void dispose() {
+        if ( this.manager != null ) {
+            this.manager.release(this.xsltProcessor);
+            this.xsltProcessor = null;
+            this.manager = null;
+        }
+    }
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        this.objectModel = null;
+        if (this.inputSource != null) {
+            this.resolver.release(this.inputSource);
+            this.inputSource = null;
+        }
+        this.resolver = null;
+        this.par = null;
+        if (!this.finishedDocument && transformerHandler != null) {
+            // This situation will only occur if an exception occured during pipeline execution.
+            // If Xalan is used in incremental mode, it is important that endDocument is called, otherwise
+            // the thread on which it runs the transformation will keep waiting.
+            // However, calling endDocument will cause the pipeline to continue executing, and thus the
+            // serializer will write output to the outputstream after what's already there (the error page),
+            // see also bug 13186.
+            if (xalanDtmManagerGetIncrementalMethod != null
+                && transformerHandler.getClass().getName().equals("org.apache.xalan.transformer.TransformerHandlerImpl")) {
+                try {
+                    final boolean incremental = ((Boolean)xalanDtmManagerGetIncrementalMethod.invoke(null, null)).booleanValue();
+                    if (incremental) {
+                        super.endDocument();
+                    }
+                } catch (Exception ignore) {}
+            }
+        }
+        this.finishedDocument = true;
+        this.logicSheetParameters = null;
+        this.transformerHandler = null;
+        this.transformerValidity = null;
+        this.exceptionDuringSetConsumer = null;
+        this.errorListener = null;
+        super.recycle();
+    }
+
+    /**
+     * Fix for stopping hanging threads of Xalan
+     */
+    public void endDocument()
+    throws SAXException {
+        try {
+            super.endDocument();
+        } catch(Exception e) {
+            
+            Throwable realEx = this.errorListener.getThrowable();
+            if (realEx == null) realEx = e;
+            
+            if (realEx instanceof RuntimeException) {
+                throw (RuntimeException)realEx;
+            }
+            
+            if (realEx instanceof SAXException) {
+                throw (SAXException)realEx;
+            }
+            
+            if (realEx instanceof Error) {
+                throw (Error)realEx;
+            }
+            
+            throw new NestableRuntimeException(realEx);
+        }
+        this.finishedDocument = true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        // did an exception occur during setConsumer?
+        // if so, throw it here
+        if ( this.exceptionDuringSetConsumer != null ) {
+            throw this.exceptionDuringSetConsumer;
+        }
+        this.finishedDocument = false;
+        super.startDocument();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/VirtualPipelineTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/VirtualPipelineTransformer.java
new file mode 100644
index 0000000..00ef8d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/VirtualPipelineTransformer.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.sitemap.impl.AbstractVirtualSitemapComponent;
+import org.apache.cocoon.xml.XMLConsumer;
+
+import org.xml.sax.SAXException;
+
+public class VirtualPipelineTransformer extends AbstractVirtualSitemapComponent
+    implements Transformer {
+
+    /** Exception that might occur during setConsumer */
+    private SAXException exceptionDuringSetConsumer;
+
+    protected String getTypeName() {
+        return "transformer";
+    }
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     * And set up the internal pipeline for processing.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        // Should use SourceResolver and context of the this
+        // components' sitemap, not caller sitemap
+        try {
+            EnvironmentHelper.enterEnvironment(this.getVPCEnvironment());
+            this.getPipeline().prepareInternal(this.getVPCEnvironment());
+        } catch (Exception e) {
+            this.exceptionDuringSetConsumer =
+                new SAXException("VirtualPipelineTransformer: couldn't create internal pipeline ", e);
+            return;
+        } finally {
+            EnvironmentHelper.leaveEnvironment();
+        }
+
+        try {
+            // Remove the current environment before calling next pipeline component
+            XMLConsumer outConsumer =
+                EnvironmentHelper.createPopEnvironmentConsumer(consumer);
+            // Call the internal VPC transformer pipeline
+            XMLConsumer transformConsumer =
+                this.getPipeline().getXMLConsumer(this.getMappedSourceEnvironment(),
+                                                  outConsumer);
+            // Add the current environment
+            XMLConsumer inConsumer =
+                EnvironmentHelper.createPushEnvironmentConsumer(transformConsumer,
+                                                                this.getMappedSourceEnvironment());
+            super.setConsumer(inConsumer);
+        } catch (ProcessingException e) {
+            this.exceptionDuringSetConsumer =
+                new SAXException("VirtualPipelineSerializer: couldn't get xml consumer from the pipeline ", e);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument() throws SAXException {
+        // did an exception occur during setConsumer?
+        // if so, throw it here
+        if ( this.exceptionDuringSetConsumer != null ) {
+            throw this.exceptionDuringSetConsumer;
+        }
+        super.startDocument();
+    }
+ }
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/WriteDOMSessionTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/WriteDOMSessionTransformer.java
new file mode 100644
index 0000000..314d187
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/WriteDOMSessionTransformer.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Make a DOM object from SAX events and write it to the session.
+ * 
+ * @cocoon.sitemap.component.name   writeDOMsession
+ * @cocoon.sitemap.component.logger sitemap.transformer.writeDOMsession
+ * 
+ * 
+ * Make a DOM object from SAX events and write it to the session.
+ *
+ * Usage in sitemap:
+ *    &lt;map:transform type="writeDOMsession"&gt;
+ *      &lt;map:parameter name="dom-name" value="content"/&gt;
+ *      &lt;map:parameter name="dom-root-element" value="companies"/&gt;
+ *    &lt;/map:transform&gt;
+ *
+ * Where:
+ *   dom-name is the name for the DOM object in the session
+ *   dom-root-element is the trigger that will be the root element of the DOM
+ *
+ * @version $Id$
+ */
+
+public class WriteDOMSessionTransformer
+  extends AbstractTransformer {
+
+    public static final String DOM_NAME = "dom-name";
+    public static final String DOM_ROOT_ELEMENT = "dom-root-element";
+
+    private boolean buildDom = false;
+    private boolean sessionAvailable = false;
+
+    private Session session;
+    private DOMBuilder builder;
+
+    private String DOMName;
+    private String rootElement;
+    private Map storedPrefixMap;
+
+    /**
+     * Recyclable
+     */
+    public void recycle() {
+        super.recycle();
+        this.session = null;
+        this.builder = null;
+        this.buildDom = false;
+        this.sessionAvailable = false;
+    }
+
+    /** BEGIN SitemapComponent methods **/
+
+    public void setup(SourceResolver resolver, Map objectModel,
+                      String source, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+      getLogger().debug("WriteSessionTransformer: setup");
+      Request request = ObjectModelHelper.getRequest(objectModel);
+      session = request.getSession(false);
+      if (session != null) {
+        DOMName = parameters.getParameter(WriteDOMSessionTransformer.DOM_NAME,null);
+        rootElement = parameters.getParameter(WriteDOMSessionTransformer.DOM_ROOT_ELEMENT,null);
+        if (DOMName!=null && rootElement!=null)  {
+          //only now we know it is usefull to store something in the session
+          getLogger().debug("WriteSessionTransformer: "+WriteDOMSessionTransformer.DOM_NAME + "=" +
+                            DOMName + "; " + WriteDOMSessionTransformer.DOM_ROOT_ELEMENT + "=" +
+                            rootElement);
+          sessionAvailable = true;
+                    storedPrefixMap = new HashMap();
+        } else  {
+          getLogger().error("WriteSessionTransformer: need " + WriteDOMSessionTransformer.DOM_NAME +
+                            " and " + WriteDOMSessionTransformer.DOM_ROOT_ELEMENT + " parameters");
+        }
+      } else  {
+        getLogger().error("WriteSessionTransformer: no session object");
+      }
+    }
+
+    /** END SitemapComponent methods **/
+
+    /** BEGIN SAX ContentHandler handlers **/
+
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+      super.startPrefixMapping(prefix,uri);
+      if (buildDom)  {
+        builder.startPrefixMapping(prefix,uri);
+      } else {
+                storePrefixMapping(prefix,uri);
+            }
+    }
+
+    public void startElement(String uri, String name, String raw, Attributes attributes)
+    throws SAXException {
+        //only build the DOM tree if session is available
+        if (name.equalsIgnoreCase(rootElement) && sessionAvailable)  {
+          getLogger().debug("WriteSessionTransformer: start building DOM tree");
+          buildDom = true;
+          builder = new DOMBuilder();
+          builder.startDocument();
+                    launchStoredMappings();
+          builder.startElement(uri,name,raw,attributes);
+        } else if (buildDom)  {
+          builder.startElement(uri,name,raw,attributes);
+        }
+        super.contentHandler.startElement(uri,name,raw,attributes);
+    }
+
+    public void endElement(String uri, String name, String raw)
+    throws SAXException {
+        if (name.equalsIgnoreCase(rootElement) && sessionAvailable) {
+          buildDom = false;
+          builder.endElement(uri,name,raw);
+          builder.endDocument();
+          getLogger().debug("WriteSessionTransformer: putting DOM tree in session object");
+          session.setAttribute(DOMName,builder.getDocument().getFirstChild());
+          getLogger().debug("WriteSessionTransformer: DOM tree is in session object");
+        } else if (buildDom)  {
+          builder.endElement(uri,name,raw);
+        }
+        super.contentHandler.endElement(uri,name,raw);
+    }
+
+
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        if (buildDom)  {
+          builder.characters(c,start,len);
+        }
+        super.contentHandler.characters(c,start,len);
+    }
+
+    public void startCDATA()
+    throws SAXException  {
+      if (buildDom)  {
+        builder.startCDATA();
+      }
+      super.lexicalHandler.startCDATA();
+    }
+
+    public void endCDATA()
+    throws SAXException {
+      if (buildDom)  {
+        builder.endCDATA();
+      }
+      super.lexicalHandler.endCDATA();
+    }
+
+    /** END SAX ContentHandler handlers **/
+
+      protected void storePrefixMapping(String prefix, String uri) {
+           storedPrefixMap.put(prefix,uri);
+    }
+
+      protected void launchStoredMappings()
+        throws SAXException {
+            Iterator it = storedPrefixMap.keySet().iterator();
+                while(it.hasNext()) {
+                    String pre = (String)it.next();
+                    String uri = (String)storedPrefixMap.get(pre);
+                    getLogger().debug("WriteSessionTransformer: launching prefix mapping[ pre: "+pre+" uri: "+uri+" ]");
+                    builder.startPrefixMapping(pre,uri);
+                }
+        }
+
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
new file mode 100644
index 0000000..4ad0dcc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/XIncludeTransformer.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Serializable; 
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.CascadingException;
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.caching.CacheableProcessingComponent; 
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.source.impl.MultiSourceValidity; 
+import org.apache.cocoon.components.xpointer.XPointer;
+import org.apache.cocoon.components.xpointer.XPointerContext;
+import org.apache.cocoon.components.xpointer.parser.ParseException;
+import org.apache.cocoon.components.xpointer.parser.XPointerFrameworkParser;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.XMLBaseSupport;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity; 
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * @cocoon.sitemap.component.documentation
+ * Implementation of an XInclude transformer.
+ * 
+ * @cocoon.sitemap.component.name   xinclude
+ * @cocoon.sitemap.component.logger sitemap.transformer.xinclude
+ * 
+ * @cocoon.sitemap.component.pooling.max  16
+ * 
+ * Implementation of an XInclude transformer. It supports xml:base attributes,
+ * XPointer fragment identifiers (see the xpointer package to see what exactly is
+ * supported), fallback elements, and does xinclude processing on the included content
+ * and on the content of fallback elements (with loop inclusion detection).
+ *
+ * @version $Id$
+ */
+public class XIncludeTransformer extends AbstractTransformer implements Serviceable, CacheableProcessingComponent { 
+    protected SourceResolver resolver;
+    protected ServiceManager manager;
+    private XIncludePipe xIncludePipe;
+
+    public static final String XMLBASE_ATTRIBUTE = "base";
+
+    public static final String XINCLUDE_NAMESPACE_URI = "http://www.w3.org/2001/XInclude";
+    public static final String XINCLUDE_INCLUDE_ELEMENT = "include";
+    public static final String XINCLUDE_FALLBACK_ELEMENT = "fallback";
+    public static final String XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE = "href";
+    public static final String XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE = "parse";
+
+    private static final String XINCLUDE_CACHE_KEY = "XInclude"; 
+
+    /** The {@link SourceValidity} instance associated with this request. */ 
+    private MultiSourceValidity validity; 
+
+    public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters)
+            throws ProcessingException, SAXException, IOException {
+        this.resolver = resolver;
+        this.validity = new MultiSourceValidity(resolver, MultiSourceValidity.CHECK_ALWAYS); 
+        this.xIncludePipe = new XIncludePipe(); 
+        this.xIncludePipe.enableLogging(getLogger());
+        this.xIncludePipe.init(null);
+        super.setContentHandler(xIncludePipe);
+        super.setLexicalHandler(xIncludePipe);
+    }
+
+    public void setConsumer(XMLConsumer consumer) {
+        xIncludePipe.setConsumer(consumer);
+    }
+
+    public void setContentHandler(ContentHandler handler) {
+        xIncludePipe.setContentHandler(handler);
+    }
+
+    public void setLexicalHandler(LexicalHandler handler) {
+        xIncludePipe.setLexicalHandler(handler);
+    }
+
+    public void service(ServiceManager manager) {
+        this.manager = manager;
+    }
+
+    /** Key to be used for caching */ 
+    public Serializable getKey() { 
+        return XINCLUDE_CACHE_KEY; 
+    } 
+
+    /** Get the validity for this transform */ 
+    public SourceValidity getValidity() { 
+        return this.validity; 
+    } 
+
+    public void recycle()
+    {
+        // Reset all variables to initial state.
+        this.resolver = null;
+        this.validity = null; 
+        this.xIncludePipe = null;
+        super.recycle();
+    }
+
+    /**
+     * XMLPipe that processes XInclude elements. To perform XInclude processing on included content,
+     * this class is instantiated recursively.
+     */
+    private class XIncludePipe extends AbstractXMLPipe {
+        /** Helper class to keep track of xml:base attributes */
+        private XMLBaseSupport xmlBaseSupport;
+        /** Element nesting level when inside an xi:include element. */
+        private int xIncludeLevel = 0;
+        /** Should the content of the fallback element be inserted when it is encountered? */
+        private boolean useFallback = false;
+        /** Element nesting level when inside the fallback element. */
+        private int fallbackLevel;
+        /** In case {@link #useFallback} = true, then this should contain the exception that caused fallback to be needed. */
+        private Exception fallBackException;
+        /**
+         * Locator of the current stream, stored here so that it can be restored after
+         * another document send its content to the consumer.
+         */
+        private Locator locator;
+        /**
+         * Value of the href attribute of the xi:include element that caused the creation of the this
+         * XIncludePipe. Used to detect loop inclusions.
+         * */
+        private String href;
+        private XIncludePipe parent;
+
+        public void init(String uri) {
+            this.href = uri;
+            this.xmlBaseSupport = new XMLBaseSupport(resolver, getLogger());
+        }
+
+        public void setParent(XIncludePipe parent) {
+            this.parent = parent;
+        }
+
+        public XIncludePipe getParent() {
+            return parent;
+        }
+
+        public String getHref() {
+            return href;
+        }
+
+        public void endDocument() throws SAXException { 
+            // We won't be getting any more sources so mark the MultiSourceValidity as finished. 
+            validity.close(); 
+            super.endDocument(); 
+        } 
+
+        public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException {
+            if (xIncludeLevel == 1 && useFallback && XINCLUDE_NAMESPACE_URI.equals(uri) && XINCLUDE_FALLBACK_ELEMENT.equals(name)) {
+                fallbackLevel++;
+
+                // don't need these anymore
+                useFallback = false;
+                fallBackException = null;
+
+                return;
+            } else if (xIncludeLevel > 0 && fallbackLevel < 1) {
+                xIncludeLevel++;
+                return;
+            } else if (xIncludeLevel > 0 && fallbackLevel > 0) {
+                fallbackLevel++;
+            }
+
+            xmlBaseSupport.startElement(uri, name, raw, attr);
+            if (XINCLUDE_NAMESPACE_URI.equals(uri)) {
+                if (XINCLUDE_INCLUDE_ELEMENT.equals(name)) {
+                    String href = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_HREF_ATTRIBUTE);
+                    if (href == null) {
+                        throw new SAXException(raw + " must have a 'href' attribute at " + getLocation());
+                    }
+
+                    String parse = attr.getValue("",XINCLUDE_INCLUDE_ELEMENT_PARSE_ATTRIBUTE);
+
+                    if (null == parse) parse="xml";
+                    xIncludeLevel++;
+
+                    try {
+                        processXIncludeElement(href, parse);
+                    } catch (ProcessingException e) {
+                        getLogger().debug("Rethrowing exception", e);
+                        throw new SAXException(e);
+                    } catch (IOException e) {
+                        getLogger().debug("Rethrowing exception", e);
+                        throw new SAXException(e);
+                    }
+                    return;
+                }
+
+                throw new SAXException("Unknown XInclude element " + raw + " at " + getLocation());
+
+            } else {
+                super.startElement(uri,name,raw,attr);
+            }
+        }
+
+        public void endElement(String uri, String name, String raw) throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1) {
+                xIncludeLevel--;
+                if (xIncludeLevel == 0)
+                    xmlBaseSupport.endElement(uri, name, raw);
+                if (xIncludeLevel == 0 && useFallback) {
+                    // an error was encountered but a fallback element was not found: throw the error now
+                    useFallback = false;
+                    Exception localFallBackException = fallBackException;
+                    fallBackException = null;
+                    fallbackLevel = 0;
+                    getLogger().error("Exception occured during xinclude processing, and did not find a fallback element.", localFallBackException);
+                    throw new SAXException("Exception occured during xinclude processing, and did not find a fallback element.", localFallBackException);
+                }
+                return;
+            }
+
+            if (fallbackLevel > 0) {
+                fallbackLevel--;
+                if (fallbackLevel == 0)
+                    return;
+            }
+
+            xmlBaseSupport.endElement(uri, name, raw);
+            super.endElement(uri,name,raw);
+        }
+
+        public void startPrefixMapping(String prefix, String uri)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.startPrefixMapping(prefix, uri);
+        }
+
+        public void endPrefixMapping(String prefix)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.endPrefixMapping(prefix);
+        }
+
+        public void characters(char c[], int start, int len)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.characters(c, start, len);
+        }
+
+        public void ignorableWhitespace(char c[], int start, int len)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.ignorableWhitespace(c, start, len);
+        }
+
+        public void processingInstruction(String target, String data)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.processingInstruction(target, data);
+        }
+
+        public void skippedEntity(String name)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.skippedEntity(name);
+        }
+
+        public void startEntity(String name)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.startEntity(name);
+        }
+
+        public void endEntity(String name)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.endEntity(name);
+        }
+
+        public void startCDATA()
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.startCDATA();
+        }
+
+        public void endCDATA()
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.endCDATA();
+        }
+
+        public void comment(char ch[], int start, int len)
+                throws SAXException {
+            if (xIncludeLevel > 0 && fallbackLevel < 1)
+                return;
+            super.comment(ch, start, len);
+        }
+
+        public void setDocumentLocator(Locator locator) {
+            try {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("setDocumentLocator called " + locator.getSystemId());
+                }
+
+                // When using SAXON to serialize a DOM tree to SAX, a locator is passed with a "null" system id
+                if (locator.getSystemId() != null) {
+                    Source source = resolver.resolveURI(locator.getSystemId());
+                    try {
+                        xmlBaseSupport.setDocumentLocation(source.getURI());
+                        // only for the "root" XIncludePipe, we'll have to set the href here, in the other cases
+                        // the href is taken from the xi:include href attribute
+                        if (href == null)
+                            href = source.getURI();
+                    } finally {
+                        resolver.release(source);
+                    }
+                }
+            } catch (Exception e) {
+                throw new CascadingRuntimeException("Error in XIncludeTransformer while trying to resolve base URL for document", e);
+            }
+            this.locator = locator;
+            super.setDocumentLocator(locator);
+        }
+
+        protected void processXIncludeElement(String href, String parse)
+        throws SAXException,ProcessingException,IOException {
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Processing XInclude element: href="+href+", parse="+parse);
+            }
+
+            Source url = null;
+            String suffix = "";
+            try {
+                int fragmentIdentifierPos = href.indexOf('#');
+                if (fragmentIdentifierPos != -1) {
+                    suffix = href.substring(fragmentIdentifierPos + 1);
+                    href = href.substring(0, fragmentIdentifierPos);
+                }
+
+                // an empty href is a reference to the current document -- this can be different than the current base
+                if (href.equals("")) {
+                    if (this.href == null)
+                        throw new SAXException("XIncludeTransformer: encountered empty href (= href pointing to the current document) but the location of the current document is unknown.");
+                    int fragmentIdentifierPos2 = this.href.indexOf('#');
+                    if (fragmentIdentifierPos2 != -1)
+                        href = this.href.substring(0, fragmentIdentifierPos2);
+                    else
+                        href = this.href;
+                }
+
+                url = xmlBaseSupport.makeAbsolute(href);
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("URL: " + url.getURI() + "\nSuffix: " + suffix);
+                }
+
+                // add the source to the SourceValidity 
+                validity.addSource(url); 
+ 
+                // check loop inclusion
+                String canonicURI = url.getURI() + (suffix.length() > 0 ? "#" + suffix: "");
+                if (isLoopInclusion(canonicURI))
+                    throw new ProcessingException("Detected loop inclusion of " + canonicURI);
+
+                if (parse.equals("text")) {
+                    getLogger().debug("Parse type is text");
+                    InputStream is = null;
+                    InputStreamReader isr = null;
+                    Reader reader = null;
+                    try {
+                        is = url.getInputStream();
+                        isr = new InputStreamReader(is);
+                        reader = new BufferedReader(isr);
+                        int read;
+                        char ary[] = new char[1024 * 4];
+                        if (reader != null) {
+                            while ((read = reader.read(ary)) != -1) {
+                                super.characters(ary,0,read);
+                            }
+                        }
+                    } finally {
+                        if (reader != null) reader.close();
+                        if (isr != null) reader.close();
+                        if (is != null) is.close();
+                    }
+                } else if (parse.equals("xml")) {
+                    XIncludePipe subPipe = new XIncludePipe();
+                    subPipe.enableLogging(getLogger());
+                    subPipe.init(canonicURI);
+                    subPipe.setConsumer(xmlConsumer);
+                    subPipe.setParent(this);
+
+                    getLogger().debug("Parse type is XML");
+                    try {
+                        if (suffix.length() > 0) {
+                            XPointer xpointer;
+                            xpointer = XPointerFrameworkParser.parse(NetUtils.decodePath(suffix));
+                            XPointerContext context = new XPointerContext(suffix, url, subPipe, getLogger(), manager);
+                            xpointer.process(context);
+                        } else {
+                            SourceUtil.toSAX(url, new IncludeXMLConsumer(subPipe));
+                        }
+                        // restore locator on the consumer
+                        if (locator != null)
+                            xmlConsumer.setDocumentLocator(locator);
+                    } catch (ResourceNotFoundException e) {
+                        useFallback = true;
+                        fallBackException = new CascadingException("Resource not found: " + url.getURI());
+                        getLogger().error("xIncluded resource not found: " + url.getURI(), e);
+                    } catch (ParseException e) {
+                        // this exception is thrown in case of an invalid xpointer expression
+                        useFallback = true;
+                        fallBackException = new CascadingException("Error parsing xPointer expression", e);
+                        fallBackException.fillInStackTrace();
+                        getLogger().error("Error parsing XPointer expression, will try to use fallback.", e);
+                    } catch(SAXException e) {
+                        getLogger().error("Error in processXIncludeElement", e);
+                        throw e;
+                    } catch(ProcessingException e) {
+                        getLogger().error("Error in processXIncludeElement", e);
+                        throw e;
+                    } catch(MalformedURLException e) {
+                        useFallback = true;
+                        fallBackException = e;
+                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
+                    } catch(IOException e) {
+                        useFallback = true;
+                        fallBackException = e;
+                        getLogger().error("Error processing an xInclude, will try to use fallback.", e);
+                    }
+                }
+            } catch (SourceException se) {
+                throw SourceUtil.handle(se);
+            } finally {
+                if (url != null) {
+                    resolver.release(url);
+                }
+            }
+        }
+
+        public boolean isLoopInclusion(String uri) {
+            if (uri.equals(this.href)) {
+                return true;
+            }
+
+            XIncludePipe parent = getParent();
+            while (parent != null) {
+                if (uri.equals(parent.getHref())) {
+                    return true;
+                }
+                parent = parent.getParent();
+            }
+            return false;
+        }
+
+        private String getLocation() {
+            if (this.locator == null) {
+                return "unknown location";
+            } else {
+                return this.locator.getSystemId() + ":" + this.locator.getColumnNumber() + ":" + this.locator.getLineNumber();
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/DefaultIncludeCacheManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/DefaultIncludeCacheManager.java
new file mode 100644
index 0000000..94e3cb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/DefaultIncludeCacheManager.java
@@ -0,0 +1,455 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CachedResponse;
+
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.sax.XMLByteStreamInterpreter;
+import org.apache.cocoon.components.sax.XMLTeePipe;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.components.thread.RunnableManager;
+import org.apache.cocoon.environment.CocoonRunnable;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.store.Store;
+import org.xml.sax.SAXException;
+import EDU.oswego.cs.dl.util.concurrent.CountDown;
+
+/**
+ * Default implementation of a {@link IncludeCacheManager}.
+ * 
+ * This implementation requires a configuration, if preemptive
+ * loading is used:
+ * &lt;parameter name="preemptive-loader-url" value="some url"/&gt;
+ * 
+ * This is a url inside cocoon, that contains the preemptive loader
+ * url; it must be specified absolute (with http://...)
+ * If this loader cannot be started, only an error is logged into the
+ * log, so actually cached content is never updated!
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public final class DefaultIncludeCacheManager
+    extends AbstractLogEnabled
+    implements IncludeCacheManager, 
+                ThreadSafe, 
+                Serviceable, 
+                Disposable,
+                Parameterizable {
+
+    private ServiceManager manager;
+    
+    private SourceResolver   resolver;
+    
+    private Store            store;
+    
+    private IncludeCacheStorageProxy defaultCacheStorage;
+    
+    private String            preemptiveLoaderURI;
+    
+    /**
+     * @see IncludeCacheManager#getSession(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public IncludeCacheManagerSession getSession(Parameters pars) {
+        String sourceURI = pars.getParameter("source", null);
+        IncludeCacheManagerSession session;
+        if ( null == sourceURI ) {
+            session = new IncludeCacheManagerSession(pars, this.defaultCacheStorage);
+        } else {
+            Source source = null;
+            try {
+                source = this.resolver.resolveURI(sourceURI);
+                IncludeCacheStorageProxy proxy = new ModifiableSourceIncludeCacheStorageProxy(this.resolver, source.getURI(), this.getLogger());
+                session = new IncludeCacheManagerSession(pars, proxy);
+            } catch (Exception local) {
+                session = new IncludeCacheManagerSession(pars, this.defaultCacheStorage);
+                this.getLogger().warn("Error creating writeable source.", local);
+            } finally {
+                this.resolver.release(source);
+            }
+        }
+        if (session.isPreemptive()) {
+            if ( null == this.preemptiveLoaderURI ) {
+                this.getLogger().error("Preemptive loading is turned off because the preemptive-loader-url is not configured.");
+                session.setPreemptive(false);
+            } else {
+                if ( !PreemptiveLoader.getInstance().alive ) {
+
+                    if (this.getLogger().isDebugEnabled()) {
+                        this.getLogger().debug("Booting preemptive loader: " + this.preemptiveLoaderURI);
+                    }
+                    PreemptiveBooter thread = new PreemptiveBooter( this.preemptiveLoaderURI );
+                    try
+                    {
+                        final RunnableManager runnableManager = (RunnableManager)this.manager.lookup( RunnableManager.ROLE );
+                        runnableManager.execute( thread );
+                        this.manager.release( runnableManager );
+                    }
+                    catch( final ServiceException se )
+                    {
+                        getLogger().error( "Cannot lookup RunnableManager", se );
+                    }
+                }
+            }
+        } 
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Creating cache manager session: " + session);
+        }
+        return session;
+    }
+
+    /**
+     * @see IncludeCacheManager#load(java.lang.String, IncludeCacheManagerSession)
+     */
+    public String load(String uri,
+                        IncludeCacheManagerSession session) 
+    throws IOException, SourceException {
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Load " + uri + " for session " + session);
+        }
+        
+        // first make the URI absolute
+        if ( uri.indexOf("://") == -1) {
+            final Source source = session.resolveURI(uri, this.resolver);
+            uri = source.getURI();
+        }
+        
+        // if we are not processing in parallel (or do preemptive)
+        // then we don't have to do anything in this method - everything
+        // is done in the stream method.
+        
+        // if we are processing in parallel (and not preemptive) then....
+        if ( session.isParallel() && !session.isPreemptive()) {
+            
+            // first look-up if we have a valid stored response
+            IncludeCacheStorageProxy storage = session.getCacheStorageProxy();
+            CachedResponse response = (CachedResponse)storage.get(uri);
+            if ( null != response) {
+                SourceValidity[] validities = response.getValidityObjects();
+                
+                // if we are valid and do not purging
+                if ( !session.isPurging() 
+                      && validities[0].isValid() == SourceValidity.VALID) {
+                    if (this.getLogger().isDebugEnabled()) {
+                        this.getLogger().debug("Using cached response for parallel processing.");
+                    }
+                    session.add(uri, response.getResponse());
+                    return uri;
+                } else {
+                    // response is not used
+                    storage.remove(uri);
+                }
+            }
+
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("Starting parallel thread for loading " + uri);
+            }
+            // now we start a parallel thread, this thread gets all required avalon components
+            // so it does not have to lookup them by itself
+            try {
+                XMLByteStreamCompiler serializer = new XMLByteStreamCompiler();
+                Source source = session.resolveURI(uri, this.resolver);
+
+                LoaderThread loader = new LoaderThread(source, serializer);
+                final RunnableManager runnableManager = (RunnableManager)this.manager.lookup( RunnableManager.ROLE );
+                session.add(uri, loader);
+                runnableManager.execute( new CocoonRunnable(loader) );
+                this.manager.release( runnableManager );
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Thread started for " + uri);
+                }
+            } catch (ServiceException ce) {
+                throw new SourceException("Unable to lookup thread pool, RunnableManager, or xml serializer.", ce);
+            } catch (Exception e) {
+                throw new SourceException("Unable to get pooled thread.", e);
+            }
+        }
+        return uri;
+    }
+
+    /**
+     * @see IncludeCacheManager#stream(java.lang.String, IncludeCacheManagerSession, XMLConsumer)
+     */
+    public void stream(String uri,
+                        IncludeCacheManagerSession session,
+                        XMLConsumer handler) 
+    throws IOException, SourceException, SAXException {
+
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Stream " + uri + " for session " + session);
+        }
+
+        // if we are processing in parallel (and not preemptive) then....
+        if ( session.isParallel() && !session.isPreemptive()) {
+            
+            // get either the cached content or the pooled thread
+            Object object = session.get(uri);
+            
+            if ( null == object ) {
+                // this should never happen!
+                throw new SAXException("No pooled thread found for " + uri);
+            }
+            byte[] result;
+            
+            // is this a pooled thread?
+            if (object instanceof LoaderThread) {
+                LoaderThread loader = (LoaderThread)object;
+                
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Waiting for pooled thread to finish loading.");
+                }
+
+                // wait for it
+                loader.join();
+
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Pooled thread finished loading.");
+                }
+                
+                // did an exception occur? Then reraise it
+                if ( null != loader.exception) {
+                    if ( loader.exception instanceof SAXException ) {
+                        throw (SAXException)loader.exception;
+                    } else if (loader.exception instanceof SourceException ) {
+                        throw (SourceException)loader.exception;
+                    } else if (loader.exception instanceof IOException) {
+                        throw (IOException)loader.exception;
+                    } else {
+                        throw new SAXException("Exception.", loader.exception);
+                    }
+                }
+                
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Streaming from pooled thread.");
+                }
+                result = loader.content;
+
+                // cache the response (remember preemptive is off)
+                if (session.getExpires() > 0) {
+                    SourceValidity[] validities = new SourceValidity[1];
+                    validities[0] = session.getExpiresValidity();
+                    CachedResponse response = new CachedResponse(validities, result);
+                    session.getCacheStorageProxy().put(uri, response);
+                }
+            } else {
+                if (this.getLogger().isDebugEnabled()) {
+                    this.getLogger().debug("Streaming from cached response.");
+                }
+
+                // use the response from the cache
+                result = (byte[])object;
+            }
+            
+            // stream the content
+            XMLByteStreamInterpreter deserializer = new XMLByteStreamInterpreter();
+            deserializer.setConsumer(handler);
+            deserializer.deserialize(result);
+            return;
+            
+        } else {
+            // we are not processing parallel
+            
+            // first: test for a cached response
+            IncludeCacheStorageProxy storage = session.getCacheStorageProxy();
+            CachedResponse response = (CachedResponse)storage.get(uri);
+            if ( null != response) {
+                SourceValidity[] validities = response.getValidityObjects();
+                // if purging is turned off and either the cached response is valid or
+                // we are loading preemptive, then use the cached response
+                if ( !session.isPurging() 
+                      && (session.isPreemptive() || validities[0].isValid() == SourceValidity.VALID)) {
+
+                    // stream the content                    
+                    if (this.getLogger().isDebugEnabled()) {
+                        this.getLogger().debug("Streaming from cached response.");
+                    }
+                    XMLByteStreamInterpreter deserializer =  new XMLByteStreamInterpreter();
+                    deserializer.setConsumer(handler);
+                    deserializer.deserialize(response.getResponse());
+                    
+                    // load preemptive if the response is not valid
+                    if ( session.getExpires() > 0
+                         && session.isPreemptive() 
+                         && validities[0].isValid() != SourceValidity.VALID) {
+                        if (this.getLogger().isDebugEnabled()) {
+                            this.getLogger().debug("Add uri to preemptive loader list " + uri);
+                        }
+                        if (!PreemptiveLoader.getInstance().alive) {
+                            this.getLogger().error("Preemptive loader has not started yet.");
+                        }
+                        PreemptiveLoader.getInstance().add(session.getCacheStorageProxy(), uri, session.getExpires());
+                    }
+                    return;
+ 
+                } else {
+                    // cached response is not valid
+                    storage.remove(uri);
+                }
+            }
+        }
+
+        // we are not processing in parallel and have no (valid) cached response
+        XMLByteStreamCompiler serializer = null;
+        try {
+            final Source source = session.resolveURI(uri, this.resolver);
+            
+            // stream directly (and cache the response)
+            if (this.getLogger().isDebugEnabled()) {
+                this.getLogger().debug("Streaming directly from source.");
+            }
+            if (session.getExpires() > 0) {
+                serializer = new XMLByteStreamCompiler();
+                XMLTeePipe tee = new XMLTeePipe(handler, serializer);
+                
+                SourceUtil.toSAX(source, tee);
+                
+                SourceValidity[] validities = new SourceValidity[1];
+                validities[0] = session.getExpiresValidity();
+                CachedResponse response = new CachedResponse(validities,
+                                                             (byte[])serializer.getSAXFragment());
+                session.getCacheStorageProxy().put(uri, response);
+            } else {
+                SourceUtil.toSAX(source, handler);
+            }
+            
+        } catch (ProcessingException pe) {
+            throw new SAXException("ProcessingException", pe);
+        }
+    }
+
+    /**
+     * @see IncludeCacheManager#terminateSession(IncludeCacheManagerSession)
+     */
+    public void terminateSession(IncludeCacheManagerSession session) {
+        if (this.getLogger().isDebugEnabled()) {
+            this.getLogger().debug("Terminating cache manager session " + session);
+        }
+        session.cleanup(this.resolver);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        // stop preemptive loader (if running)
+        PreemptiveLoader.getInstance().stop();
+        if ( null != this.manager ) {
+            this.manager.release( this.resolver);
+            this.manager.release(this.store);
+            this.store = null;
+            this.resolver = null;
+            this.manager = null;
+            this.defaultCacheStorage = null;
+        }
+    }
+
+    /**
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+        this.preemptiveLoaderURI = parameters.getParameter("preemptive-loader-url", null);
+        if ( null != this.preemptiveLoaderURI 
+             && this.preemptiveLoaderURI.indexOf("://") == -1) {
+            throw new ParameterException("The preemptive-loader-url must be absolute: " + this.preemptiveLoaderURI);
+        }
+        final String storeRole = parameters.getParameter("use-store", Store.ROLE);
+        try {
+            this.store = (Store)this.manager.lookup(storeRole);
+        } catch (ServiceException e) {
+            throw new ParameterException("Unable to lookup store with role " + storeRole, e);
+        }
+        this.defaultCacheStorage = new StoreIncludeCacheStorageProxy(this.store, this.getLogger());
+    }
+    
+    final private static class LoaderThread implements Runnable {
+        
+        private final Source source;
+        private final XMLByteStreamCompiler serializer;
+        private final CountDown finished;
+        Exception exception;
+        byte[]    content;
+        
+        public LoaderThread(Source source, 
+                            XMLByteStreamCompiler serializer) {
+            this.source = source;
+            this.serializer = serializer;
+            this.finished = new CountDown( 1 );
+        }
+        
+        public void run() {
+            try {
+                SourceUtil.toSAX(this.source, this.serializer);
+                this.content = (byte[])this.serializer.getSAXFragment();
+            } catch (Exception local) {
+                this.exception = local;
+            } finally {
+                this.finished.release();
+            }
+        }
+        
+        void join() {
+            try {
+                this.finished.acquire();
+            } catch ( final InterruptedException ie) {
+                // ignore
+            }
+        }
+    }
+    
+    final private static class PreemptiveBooter implements Runnable {
+    
+        private final String uri;
+    
+        public PreemptiveBooter( final String uri )
+        {
+            this.uri = uri;
+        }
+        
+        public void run() {
+            try {
+                URL url = new URL(this.uri);
+                url.getContent();
+            } catch (Exception ignore) {
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/FormValidatorHelper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/FormValidatorHelper.java
new file mode 100644
index 0000000..4666e48
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/FormValidatorHelper.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
+import org.apache.excalibur.source.Source;
+
+import org.apache.cocoon.acting.AbstractValidatorAction;
+import org.apache.cocoon.acting.ConfigurationHelper;
+import org.apache.cocoon.acting.ValidatorActionResult;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+
+import org.apache.avalon.framework.logger.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The <code>ValidatorActionResult</code> object helper
+ *
+ * @version $Id$
+ */
+public class FormValidatorHelper {
+
+    private static Map configurations = new HashMap();
+
+    /**
+     * these make it easier for the xsl
+     */
+
+    String current_descriptor = null;
+    boolean current_reloadable = true;
+    Logger current_logger = null;
+    String current_constraint_set = null;
+    String current_parameter = null;
+    SourceResolver current_resolver = null;
+
+    public FormValidatorHelper(String descriptor, boolean reloadable,
+                                  Logger logger, SourceResolver resolver) {
+        current_descriptor = descriptor;
+        current_reloadable = reloadable;
+        current_logger = logger;
+        current_resolver = resolver;
+    }
+
+    public FormValidatorHelper(String descriptor, boolean reloadable,
+                                  Logger logger, SourceResolver resolver,
+                                  String constraintset) {
+        current_descriptor = descriptor;
+        current_reloadable = reloadable;
+        current_logger = logger;
+        current_resolver = resolver;
+        current_constraint_set = constraintset;
+    }
+
+    /**
+     * keep track of current parameter context
+     */
+    public void setParameter(String parameter) {
+        current_parameter = parameter;
+    }
+
+    /**
+     * keep track of current constraint-set context
+     * (probably this is not needed?)
+     */
+    public void setConstraintSet(String constraintset) {
+        current_constraint_set = constraintset;
+    }
+
+    /**
+     * Get the specified attribute
+     *
+     * @param objectModel The Map objectModel
+     * @param name The parameter name
+     */
+    public static Object getAttribute(Map objectModel, String name) {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        return request.getAttribute(name);
+    }
+
+    /**
+     * Extracts the validation results from the request attribute
+     *
+     * @param objectModel The Map objectModel
+     * @return Map with ValidatorActionResults
+     * @see org.apache.cocoon.acting.ValidatorActionResult
+     */
+    public static Map getResults(Map objectModel) {
+        Request request = ObjectModelHelper.getRequest(objectModel);
+        return (Map) request.getAttribute(AbstractValidatorAction.FORMVALIDATOR_PATH);
+    }
+
+
+    /**
+     * Extracts the validation results from the request attribute
+     * for a specific request parameter
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @see org.apache.cocoon.acting.ValidatorActionResult
+     */
+    public static ValidatorActionResult getParamResult(Map objectModel,
+                                                       String name) {
+        ValidatorActionResult result = ValidatorActionResult.NOTPRESENT;
+        Map param_result = getResults(objectModel);
+        if (param_result != null) {
+            result = (ValidatorActionResult) param_result.get(name);
+        }
+        return (result != null? result : ValidatorActionResult.NOTPRESENT);
+    }
+
+    /**
+     * Extracts the validation results from the request attribute
+     * for the context's current request parameter
+     *
+     * @param objectModel The Map objectModel
+     * @see org.apache.cocoon.acting.ValidatorActionResult
+     */
+    public ValidatorActionResult getParamResult(Map objectModel) {
+        ValidatorActionResult result = ValidatorActionResult.NOTPRESENT;
+        Map param_result = getResults(objectModel);
+        if (param_result != null) {
+            result = (ValidatorActionResult) param_result.get(current_parameter);
+        }
+        return (result != null? result : ValidatorActionResult.NOTPRESENT);
+    }
+
+
+    /**
+     * Test whether the validation returned no error for this
+     * parameter.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true only if the parameter was validated and the validation
+     * did not return an error.
+     */
+    public static boolean isOK(Map objectModel, String name) {
+        return getParamResult(objectModel, name).equals(ValidatorActionResult.OK);
+    }
+
+    /**
+     * Test whether the validation returned no error for the
+     * context's current parameter.
+     *
+     * @param objectModel The Map objectModel
+     * @return true only if the parameter was validated and the validation
+     * did not return an error.
+     */
+    public boolean isOK(Map objectModel) {
+        return isOK(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validation returned an error for this
+     * parameter.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was either not validated or the validation
+     * returned an error.
+     */
+    public static boolean isError(Map objectModel, String name) {
+        return getParamResult(objectModel, name).ge(ValidatorActionResult.ERROR);
+    }
+
+    /**
+     * Test whether the validation returned an error for the
+     * context's current parameter.
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was either not validated or the validation
+     * returned an error.
+     */
+    public boolean isError(Map objectModel) {
+        return isError(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validated parameter was null but wasn't allowed to.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was validated and the validation
+     * returned an error because the parameter was null but wasn't allowd to.
+     */
+    public static boolean isNull(Map objectModel, String name) {
+        return getParamResult(objectModel, name).equals(ValidatorActionResult.ISNULL);
+    }
+
+    /**
+     * Test whether the context's current parameter as validated was null but
+     * wasn't allowed to.
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was validated and the validation
+     * returned an error because the parameter was null but wasn't allowd to.
+     */
+    public boolean isNull(Map objectModel) {
+        return isNull(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validated parameter was too small.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was validated and the validation
+     * returned an error because either its value or its length was
+     * too small.
+     */
+    public static boolean isTooSmall(Map objectModel, String name) {
+        boolean ok = getParamResult(objectModel, name).equals(ValidatorActionResult.TOOSMALL);
+
+        if (!ok) {
+            ok = isNull(objectModel, name);
+        }
+
+        return ok;
+    }
+
+    /**
+     * Test whether the context's current parameter was too small.
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was validated and the validation
+     * returned an error because either its value or its length was
+     * too small.
+     */
+    public boolean isTooSmall(Map objectModel) {
+        return isTooSmall(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validated parameter was too large.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was validated and the validation
+     * returned an error because either its value or its length was
+     * too large.
+     */
+    public static boolean isTooLarge(Map objectModel, String name) {
+        return (getParamResult(objectModel, name) == ValidatorActionResult.TOOLARGE);
+    }
+
+    /**
+     * Test whether the context's current parameter was too large.
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was validated and the validation
+     * returned an error because either its value or its length was
+     * too large.
+     */
+    public boolean isTooLarge(Map objectModel) {
+        return isTooLarge(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validated parameter wasn't matched by the requested
+     * regular expression.
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was validated and the validation
+     * returned an error because its value wasn't matched by the requested
+     * regular expression.
+     */
+    public static boolean isNoMatch(Map objectModel, String name) {
+        return getParamResult(objectModel, name).equals(ValidatorActionResult.NOMATCH);
+    }
+
+    /**
+     * Test whether the context's current parameter wasn't matched by the requested
+     * regular expression.
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was validated and the validation
+     * returned an error because its value wasn't matched by the requested
+     * regular expression.
+     */
+    public boolean isNoMatch(Map objectModel) {
+        return isNoMatch(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Test whether the validated parameter wasn't validated
+     *
+     * @param objectModel The Map objectModel
+     * @param name Request parameter's name
+     * @return true if the parameter was not validated.
+     */
+    public static boolean isNotPresent(Map objectModel, String name) {
+        return getParamResult(objectModel, name).equals(ValidatorActionResult.NOTPRESENT);
+    }
+
+    /**
+     * Test whether the context's current parameter wasn't validated
+     *
+     * @param objectModel The Map objectModel
+     * @return true if the parameter was not validated.
+     */
+    public boolean isNotPresent(Map objectModel) {
+        return isNotPresent(objectModel, current_parameter);
+    }
+
+
+    /**
+     * Set up the complementary configuration file.  Please note that
+     * multiple Actions can share the same configurations.  By using
+     * this approach, we can limit the number of config files.
+     * Also note that the configuration file does not have to be a file.
+     *
+     * This is based on the similar named functions in
+     * org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
+     * with the addition of reloadable configuration files, reloadable
+     * flagg, manager, and logger  parameter.
+     *
+     * @param descriptor URL of descriptor.xml file @see org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
+     * @param resolver
+     * @param reloadable set to <code>true</code> if changes of
+     * <code>descriptor</code> should trigger a reload. Note that this
+     * only works if <code>Source</code> is able to determine the
+     * modification time @see org.apache.cocoon.environment.Source
+     * @param logger used to send debug and error messages to
+     * @return up-to-date configuration, either (re)loaded or cached.
+     */
+
+    protected static Configuration getConfiguration(String descriptor, SourceResolver resolver,
+                                                    boolean reloadable, Logger logger)
+            throws ConfigurationException {
+
+        if (descriptor == null) {
+            throw new ConfigurationException("The form descriptor is not set!");
+        }
+
+        ConfigurationHelper conf = null;
+        synchronized (FormValidatorHelper.configurations) {
+            Source source = null;
+            try {
+                source = resolver.resolveURI(descriptor);
+                conf = (ConfigurationHelper) FormValidatorHelper.configurations.get(source.getURI());
+                if (conf == null || (reloadable && conf.lastModified != source.getLastModified())) {
+                    logger.debug("(Re)Loading " + descriptor);
+
+                    if (conf == null) {
+                        conf = new ConfigurationHelper();
+                    }
+
+                    SAXConfigurationHandler builder = new SAXConfigurationHandler();
+                    SourceUtil.toSAX(source, builder);
+
+                    conf.lastModified = source.getLastModified();
+                    conf.configuration = builder.getConfiguration();
+
+                    FormValidatorHelper.cacheConfiguration(source.getURI(), conf);
+                } else {
+                    logger.debug("Using cached configuration for " + descriptor);
+                }
+            } catch (Exception e) {
+                logger.error("Could not configure Database mapping environment", e);
+                throw new ConfigurationException("Error trying to load configurations for resource: " + source.getURI());
+            } finally {
+                resolver.release(source);
+            }
+        }
+
+        return conf.configuration;
+    }
+
+    /**
+     * Cache the configuration so that we can use it later.
+     */
+    private static void cacheConfiguration(String descriptor, ConfigurationHelper conf) {
+        synchronized (FormValidatorHelper.configurations) {
+            FormValidatorHelper.configurations.put(descriptor, conf);
+        }
+    }
+
+    /**
+     * Iterate over a set of configurations and return the one whose
+     * name matches the given one.
+     *
+     * @param conf set of configurations
+     * @param name name of configuration
+     * @param logger
+     * @return specified configuration or <code>null</code> if not found.
+     */
+    protected static Configuration getConfigurationByName(Configuration[] conf,
+                                                          String name,
+                                                          Logger logger
+                                                          ) {
+        int j = 0;
+        boolean found = false;
+        String setname = null;
+        for (j = 0; j < conf.length; j++) {
+            setname = conf[j].getAttribute("name", "");
+            if (name.trim().equals(setname.trim())) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            logger.debug("FormValidatorHelper.getConfigurationByName: configuration " + name + " not found.");
+            return null;
+        }
+        return conf[j];
+    }
+
+    /**
+     * Get an attribute for a parameter as specified in
+     * descriptor.xml.
+     *
+     * @param descriptor URL of descriptor.xml file @see org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
+     * @param resolver
+     * @param reloadable set to <code>true</code> if changes of
+     * <code>descriptor</code> should trigger a reload. Note that this
+     * only works if <code>Source</code> is able to determine the
+     * modification time @see org.apache.cocoon.environment.Source
+     * @param logger used to send debug and error messages to
+     * @param attribute attribute name
+     * @return attribute value or <code>null</code>
+     */
+    public static String getParameterAttributes(String descriptor,
+                                                SourceResolver resolver,
+                                                boolean reloadable,
+                                                String constraintset,
+                                                String parameter,
+                                                String attribute,
+                                                Logger logger
+                                                ) {
+        try {
+            Configuration conf = getConfiguration(descriptor, resolver, reloadable, logger);
+            Configuration[] desc = conf.getChildren("parameter");
+            Configuration[] csets = conf.getChildren("constraint-set");
+
+            Configuration cset = getConfigurationByName(csets, constraintset, logger);
+
+            Configuration[] set = cset.getChildren("validate");
+            Configuration constraints = getConfigurationByName(set, parameter, logger);
+            Configuration descr = getConfigurationByName(desc, parameter, logger);
+            return constraints.getAttribute(attribute, descr.getAttribute(attribute, ""));
+        } catch (Exception e) {
+            logger.debug("FormValidatorHelper.getParameterAttributes Exception " + e);
+        }
+        
+        return "";
+    }
+
+
+    /**
+     * Get an attribute for the context's current parameter as specified in
+     * descriptor.xml.
+     *
+     * @param attribute attribute name
+     * @return attribute value or <code>null</code>
+     */
+    public String getParameterAttribute(String attribute) {
+        return FormValidatorHelper.getParameterAttributes(current_descriptor,
+                current_resolver,
+                current_reloadable,
+                current_constraint_set,
+                current_parameter,
+                attribute,
+                current_logger);
+    }
+
+    /**
+     * Get an attribute for a parameter as specified in
+     * descriptor.xml.
+     *
+     * @param attribute attribute name
+     * @return attribute value or <code>null</code>
+     */
+    public String getParameterAttribute(String parameter, String attribute) {
+        return FormValidatorHelper.getParameterAttributes(current_descriptor,
+                current_resolver,
+                current_reloadable,
+                current_constraint_set,
+                parameter,
+                attribute,
+                current_logger);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManager.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManager.java
new file mode 100644
index 0000000..22c31bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManager.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.excalibur.source.SourceException;
+import org.xml.sax.SAXException;
+
+/**
+ * The include cache manager is a component that can manage included content.
+ * It can eiter load them in parallel or pre-emptive and cache the content
+ * for a given period of time.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public interface IncludeCacheManager {
+
+    /** Avalon role */
+    String ROLE = IncludeCacheManager.class.getName();
+    
+    /**
+     * Create a session for this request.
+     * This should be invoked first and only one per request. It is required
+     * to terminate the session with {@link #terminateSession(IncludeCacheManagerSession)}
+     * @param pars The configuration
+     * @return CacheManagerSession The session that should be used with all other commands.
+     */
+    IncludeCacheManagerSession getSession(Parameters pars);
+    
+    /**
+     * This informs the manager that a URI should be "loaded".
+     * @param uri     The URI to load (maybe relative)
+     * @param session The corresponding session created by {@link #getSession(Parameters)}
+     * @return String The absolute URI that must be used for {@link #stream(String, IncludeCacheManagerSession, XMLConsumer)}
+     * @throws IOException
+     * @throws SourceException
+     */
+    String load(String  uri, 
+                IncludeCacheManagerSession session)
+    throws IOException, SourceException;
+              
+    /**
+     * Stream the content of the absolute URI.
+     * Depending on the configuration and state of the cache, the
+     * content is either taken from the cache, fetched etc.
+     * @param uri     The absolute URI returned by {@link #load(String, IncludeCacheManagerSession)}
+     * @param session The current session
+     * @param handler The receiver of the SAX events
+     * @throws IOException
+     * @throws SourceException
+     * @throws SAXException
+     */
+    void stream(String uri,
+                 IncludeCacheManagerSession session,
+                 XMLConsumer handler)
+    throws IOException, SourceException, SAXException;
+                 
+    /**
+     * Terminate the session. This method must be executed at the end of the
+     * request.
+     * @param session The caching session.
+     */
+    void terminateSession(IncludeCacheManagerSession session);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManagerSession.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManagerSession.java
new file mode 100644
index 0000000..5f5cf78
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheManagerSession.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.ExpiresValidity;
+
+/**
+ * This object encapsulates a "caching session". A caching session has the
+ * duration of one single request.
+ * This object is used by the {@link IncludeCacheManager} and holds all required
+ * configuration for performing the caching of this request.
+ * 
+ * The session can be configured during construction with the following parameters:
+ * - purge (boolean/false) : Turn on/off purging the cache
+ * - preemptive (boolean/false) : Turn on/off preemptive caching
+ * - parallel (boolean/false) : Turn on/off parallel processing
+ * - expires (long/0) : The lifetime of the cached content
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public final class IncludeCacheManagerSession {
+
+    /** The expires information */
+    private long expires;
+    
+    /** Should we purge the cache */
+    private boolean purge;
+    
+    /** Should we load preemptive */
+    private boolean preemptive;
+    
+    /** Should we process everything in parallel */
+    private boolean parallel;
+
+    /** The used {@link IncludeCacheStorageProxy} */
+    private IncludeCacheStorageProxy storage;
+    
+    /** The list of all threads */
+    private Map threadList;
+    
+    /** Cache the expires validity object */
+    private SourceValidity validity;
+    
+    /** Cache the source objects */
+    private Map sourceList = new HashMap(10);
+    
+    /**
+     * Constructor
+     * @param configuration The parameters configuring this session
+     * @param proxy         The proxy used to cache the data
+     */
+    IncludeCacheManagerSession(Parameters configuration, 
+                        IncludeCacheStorageProxy proxy) {
+        this.expires = configuration.getParameterAsLong("expires", 0);
+        this.purge = configuration.getParameterAsBoolean("purge", false);    
+        this.preemptive = configuration.getParameterAsBoolean("preemptive", false);
+        this.parallel = configuration.getParameterAsBoolean("parallel", false);
+        this.storage = proxy;    
+    }
+    
+    /**
+     * Get the used storage proxy
+     */
+    IncludeCacheStorageProxy getCacheStorageProxy() {
+        return this.storage;
+    }
+
+    /**
+     * Get the expiration information
+     */
+    public long getExpires() {
+        return this.expires;
+    }
+
+    public SourceValidity getExpiresValidity() {
+        if ( this.expires > 0 && this.validity == null) {
+            this.validity = new ExpiresValidity( this.expires * 1000 ); // milliseconds
+        }
+        return this.validity;
+    }
+    
+    /**
+     * Is the cache purged?
+     */
+    public boolean isPurging() {
+        return this.purge;
+    }
+
+    /**
+     * Do we use preemptive caching?
+     */
+    public boolean isPreemptive() {
+        return this.preemptive;
+    }
+
+    /**
+     * Do we process the includes in parallel?
+     */
+    public boolean isParallel() {
+        return this.parallel;
+    }
+
+    /**
+     * Add another object to the thread list
+     * @param uri    The absolute URI
+     * @param object The thread
+     */
+    void add(String uri, Object object) {
+        if ( null == this.threadList ) {
+            this.threadList = new HashMap(10);
+        }
+        this.threadList.put(uri, object);
+    }
+    
+    /**
+     * Get the thread object.
+     * @param uri     The URI
+     * @return Object The thread.
+     */
+    Object get(String uri) {
+        if ( null != this.threadList ) {
+            return this.threadList.get( uri );
+        }
+        return null;
+    }
+    
+    /**
+     * Turn off/on preemptive caching
+     */
+    void setPreemptive(boolean value) {
+        this.preemptive = value;
+    }
+    
+    /**
+     * Lookup a source object and cache it
+     * @param uri     Absolute URI
+     * @return Source The source obejct
+     */
+    public Source resolveURI(String uri, SourceResolver resolver) 
+    throws IOException {
+        Source source = (Source)this.sourceList.get(uri);
+        if ( null == source ) {
+            source = resolver.resolveURI( uri );
+            this.sourceList.put( source.getURI(), source );
+        }
+        return source;
+    }
+    
+    /**
+     * Cleanup
+     * @param resolver The source resolver to release cached sources
+     */
+    void cleanup(SourceResolver resolver) {
+        Iterator iter = this.sourceList.values().iterator();
+        while ( iter.hasNext() ) {
+            final Source source = (Source) iter.next();
+            resolver.release( source );   
+        }
+    }
+    
+    /**
+     * Print a representation of this object
+     */
+    public String toString() {
+        return "CacheManagerSession(" + this.hashCode() + ") -" +
+                " expires: " + this.expires +
+                " parallel: " + this.parallel + 
+                " preemptive: " + this.preemptive +
+                " purge: " + this.purge;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheStorageProxy.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheStorageProxy.java
new file mode 100644
index 0000000..6365e00
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/IncludeCacheStorageProxy.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A CacheStorageProxy is an interface object between the {@link IncludeCacheManager}
+ * and the real store caching the content.
+ * Currently you can use the {@link StoreIncludeCacheStorageProxy} that uses the
+ * usual store or the {@link ModifiableSourceIncludeCacheStorageProxy} that
+ * uses a configured source.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public interface IncludeCacheStorageProxy {
+
+    /**
+     * Get the cached content for the given URI.
+     * @param uri Absolute URI specifying the content
+     * @return Serializable
+     */
+    Serializable get(String uri);
+    
+    /**
+     * Put the content into the cache for the given URI.
+     * @param uri Absolute URI specifying the content
+     * @param object The content
+     * @throws IOException
+     */
+    void put(String uri, Serializable object)
+    throws IOException;
+    
+    /**
+     * Remove the cached content for the given URI
+     * @param uri Absolute URI specifying the content
+     */
+    void remove(String uri);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ModifiableSourceIncludeCacheStorageProxy.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ModifiableSourceIncludeCacheStorageProxy.java
new file mode 100644
index 0000000..9e79a34
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ModifiableSourceIncludeCacheStorageProxy.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.CascadingIOException;
+import org.apache.cocoon.util.HashUtil;
+import org.apache.excalibur.source.ModifiableSource;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+
+/**
+ * This is the interface between the {@link IncludeCacheManager} and a
+ * {@link Source} object that stores the cached content in a directory
+ * manner.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public final class ModifiableSourceIncludeCacheStorageProxy
+    implements IncludeCacheStorageProxy {
+
+    private SourceResolver resolver;
+    private String         parentURI;
+    private Logger         logger;
+    
+    /**
+     * Constructor
+     * @param resolver   For source resolving
+     * @param parentURI  The "directory"
+     * @param logger     A logger for debugging
+     */
+    public ModifiableSourceIncludeCacheStorageProxy(SourceResolver resolver,
+                                             String         parentURI,
+                                             Logger         logger) {
+        this.resolver = resolver;
+        this.parentURI= parentURI;
+        this.logger = logger;
+    }
+    
+    /**
+     * Calculate the URI for a child
+     * @param uri     Child URI
+     * @return String Absolute URI
+     */
+    private String getURI(String uri) {
+        final long hash = HashUtil.hash(uri);
+        final StringBuffer buffer = new StringBuffer(this.parentURI);
+        buffer.append('/');
+        if (hash < 0) {
+            buffer.append('M').append(hash * -1);
+        } else {
+            buffer.append(hash);
+        }
+        buffer.append(".cxml");
+        return buffer.toString();
+    }
+    
+    /**
+     * @see IncludeCacheStorageProxy#get(java.lang.String)
+     */
+    public Serializable get(String uri) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("WSCProxy: Getting content for " + uri);
+        }
+
+        Source child = null;
+        Serializable result = null;
+        try {
+            child = this.resolver.resolveURI(this.getURI(uri));
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("WSCProxy: Resolved to " + child.getURI());
+            }
+
+            if (child.exists()) {
+                InputStream is = child.getInputStream();
+                ObjectInputStream ois = new ObjectInputStream(is);
+                result = (Serializable)ois.readObject();
+                ois.close();
+            }
+        } catch (Exception ignore) {
+        } finally {
+            this.resolver.release( child );
+        }
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("WSCProxy: Result for " + uri + " : " + (result == null ? "Not in cache" : "Found"));
+        }
+        return result;
+    }
+
+    /**
+     * @see IncludeCacheStorageProxy#put(java.lang.String, java.io.Serializable)
+     */
+    public void put(String uri, Serializable object) 
+    throws IOException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("WSCProxy: Storing content for " + uri);
+        }
+        Source child = null;
+        try {
+            child = this.resolver.resolveURI(this.getURI(uri));
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("WSCProxy: Resolved to " + child.getURI());
+            }
+
+            OutputStream os;
+            if (child instanceof ModifiableSource) {
+                os = ((ModifiableSource)child).getOutputStream();
+            } else {
+                throw new IOException("Source " + uri + " is not writeable.");
+            }
+            ObjectOutputStream oos = new ObjectOutputStream(os);
+            oos.writeObject(object);
+            oos.flush();
+            oos.close();
+        } catch (IOException io) {
+            throw io;
+        } catch (Exception ignore) {
+            throw new CascadingIOException("Exception.", ignore);
+        } finally {
+            this.resolver.release( child );
+        }
+    }
+
+    /**
+     * @see IncludeCacheStorageProxy#remove(java.lang.String)
+     */
+    public void remove(String uri) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("WSCProxy: Removing content for " + uri);
+        }
+        Source child = null;
+        try {
+            child = this.resolver.resolveURI(this.getURI(uri));
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("WSCProxy: Resolved to " + child.getURI());
+            }
+
+            if (child instanceof ModifiableSource) {
+                ((ModifiableSource)child).delete();
+            } else {
+                throw new IOException("Source " + uri + " is not writeable.");
+            }
+        } catch (Exception ignore) {
+        } finally {
+            this.resolver.release( child );
+        }
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof ModifiableSourceIncludeCacheStorageProxy) {
+            return this.parentURI.equals(((ModifiableSourceIncludeCacheStorageProxy)object).parentURI);
+        }
+        return false;
+    }
+
+    /**
+     * Generate a hash code
+     */
+    public int hashCode() {
+        return this.parentURI.hashCode();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/NOPRecorder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/NOPRecorder.java
new file mode 100644
index 0000000..7e2d352
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/NOPRecorder.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import org.apache.cocoon.xml.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * The base class for all recorders. Simply does nothing
+ *
+ * @version $Id$
+*/
+public abstract class NOPRecorder
+implements ContentHandler, LexicalHandler, XMLConsumer {
+
+    public NOPRecorder() {
+    }
+
+    public void setDocumentLocator(Locator locator) {
+    }
+
+    public void startDocument()
+    throws SAXException {
+    }
+
+    public void endDocument()
+    throws SAXException {
+    }
+
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+    }
+
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+    }
+
+    public void startElement(String namespace, String name, String raw,
+                         Attributes attr)
+    throws SAXException {
+    }
+
+    public void endElement(String namespace, String name, String raw)
+    throws SAXException {
+    }
+
+    public void characters(char ary[], int start, int length)
+    throws SAXException {
+    }
+
+    public void ignorableWhitespace(char ary[], int start, int length)
+    throws SAXException {
+    }
+
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+    }
+
+    public void skippedEntity(String name)
+    throws SAXException {
+    }
+
+    public void startDTD(String name, String public_id, String system_id)
+    throws SAXException {
+    }
+
+    public void endDTD() throws SAXException {
+    }
+
+    public void startEntity(String name) throws SAXException {
+    }
+
+    public void endEntity(String name) throws SAXException {
+    }
+
+    public void startCDATA() throws SAXException {
+    }
+
+    public void endCDATA() throws SAXException {
+    }
+
+    public void comment(char ary[], int start, int length)
+    throws SAXException {
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ParametersRecorder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ParametersRecorder.java
new file mode 100644
index 0000000..2c7120d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/ParametersRecorder.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.excalibur.source.SourceParameters;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.util.Iterator;
+
+
+/**
+ * This class records SAX Events and generates Parameters from them
+ * The xml is flat and consists of elements which all have exactly one text node:
+ * <parone>value_one<parone>
+ * <partwo>value_two<partwo>
+ *
+ * @version $Id$
+ */
+public final class ParametersRecorder
+extends NOPRecorder {
+
+    private SourceParameters parameters;
+    private String     key;
+    private StringBuffer buffer;
+
+    /**
+     * If source is null a new Parameters object is created
+     * Otherwise they are joined.
+     */
+    public ParametersRecorder() {
+        super();
+        this.parameters = new SourceParameters();
+    }
+
+    public SourceParameters getParameters(Parameters source) {
+        if (source != null) {
+            String[] names = source.getNames();
+//            Iterator names = source.getParameterNames();
+            if (names != null) {
+                String currentParameterName;
+                for(int i=0; i<names.length; i++) {
+                    currentParameterName = names[i];
+//                while (names.hasNext() == true) {
+//                    currentParameterName = (String)names.next();
+                    this.parameters.setParameter(currentParameterName, source.getParameter(currentParameterName, ""));
+                }
+            }
+        }
+        return parameters;
+    }
+
+    public SourceParameters getParameters(SourceParameters source) {
+        if (source != null) {
+            Iterator iter = source.getParameterNames();
+            Iterator valuesIter;
+            String value, parName;
+            while (iter.hasNext() == true) {
+                parName = (String)iter.next();
+                valuesIter = source.getParameterValues(parName);
+                while (valuesIter.hasNext() == true) {
+                    value = (String)valuesIter.next();
+                    this.parameters.setParameter(parName, value);
+                }
+            }
+        }
+        return parameters;
+    }
+
+    public void startElement(String namespace, String name, String raw,
+                         Attributes attr)
+    throws SAXException {
+        if (this.key == null) {
+            this.key = name;
+            this.buffer = new StringBuffer();
+        }
+    }
+
+    public void endElement(String namespace, String name, String raw)
+    throws SAXException {
+        if (this.key != null && this.key.equals(name) == true) {
+            String value = this.buffer.toString().trim();
+            if (value.length() > 0) {
+                this.parameters.setParameter(this.key, value);
+            }
+            this.buffer = null;
+            this.key = null;
+        }
+    }
+
+    public void characters(char ary[], int start, int length)
+    throws SAXException {
+        if (this.key != null && this.buffer != null) {
+            String value = new String(ary, start, length).trim();
+            if (value.length() > 0) {
+                buffer.append(value);
+            } else {
+                buffer.append(' ');
+            }
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java
new file mode 100644
index 0000000..a11d3ba
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.ExpiresValidity;
+
+/**
+ * The preemptive loader is a singleton that runs in the background
+ * and loads content into the cache.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public final class PreemptiveLoader {
+
+    private static final PreemptiveLoader instance = new PreemptiveLoader();
+    
+    /** The list of proxies currently used for caching */
+    private Map   cacheStorageProxyMap = new HashMap(20);
+    /** The list of URIs to load */
+    private List  loadList = new ArrayList(50);
+    /** Is this thread still alive? */
+    boolean alive = false;
+    
+    /**
+     * Return singleton.
+     * @return PreemptiveLoader
+     */
+    static PreemptiveLoader getInstance() {
+        return instance;
+    }
+    
+    /**
+     * Add a new task
+     * @param proxy   The cache to store the content
+     * @param uri     The absolute URI to load
+     * @param expires The expires information used for the cache
+     */
+    public void add(IncludeCacheStorageProxy proxy, String uri, long expires) {
+        boolean addItem = true;
+        List uriList = (List)this.cacheStorageProxyMap.get(proxy);
+        if ( null == uriList ) {
+             uriList = new ArrayList(50);
+             this.cacheStorageProxyMap.put(proxy, uriList);
+        } else {
+            synchronized (uriList) {
+                // nothing to do: uri is alredy in list
+               if (uriList.contains(uri)) {
+                   addItem = false;
+               } 
+            }
+        }
+        if ( addItem ) {
+            uriList.add(uri);
+            this.loadList.add(new Object[] {proxy, uri, new Long(expires), uriList});
+        }
+
+        synchronized (this.cacheStorageProxyMap) {
+            this.cacheStorageProxyMap.notify();
+        }
+    }
+    
+    /**
+     * Start the preemptive loading
+     * @param manager   A component manager
+     * @param resolver  A source resolver
+     * @param logger    A logger
+     */
+    public void process(SourceResolver  resolver,
+                        Logger          logger) {
+        this.alive = true;
+        if (logger.isDebugEnabled()) {
+            logger.debug("PreemptiveLoader: Starting preemptive loading");
+        }
+
+        while (this.alive) {
+            while (this.loadList.size() > 0) {
+                Object[] object = (Object[])this.loadList.get(0);
+                final String uri = (String)object[1];
+                this.loadList.remove(0);
+                synchronized (object[3]) {
+                    ((List)object[3]).remove(uri);
+                }
+                
+                Source source = null;
+                XMLByteStreamCompiler serializer = null;
+
+                try {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("PreemptiveLoader: Loading " + uri);
+                    }
+
+                    source = resolver.resolveURI(uri);
+                    serializer = new XMLByteStreamCompiler();
+                
+                    SourceUtil.toSAX(source, serializer);
+                
+                    SourceValidity[] validities = new SourceValidity[1];
+                    validities[0] = new ExpiresValidity(((Long)object[2]).longValue() * 1000); // milliseconds!
+                    CachedResponse response = new CachedResponse(validities,
+                                                                 (byte[])serializer.getSAXFragment());
+                    ((IncludeCacheStorageProxy)object[0]).put(uri, response);
+                     
+                } catch (Exception ignore) {
+                    // all exceptions are ignored!
+                } finally {
+                    resolver.release( source );
+                }
+                if (logger.isDebugEnabled()) {
+                    logger.debug("PreemptiveLoader: Finished loading " + uri);
+                }
+            }
+            synchronized (this.cacheStorageProxyMap) {
+                try {
+                    this.cacheStorageProxyMap.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        if (logger.isDebugEnabled()) {
+            logger.debug("PreemptiveLoader: Finished preemptive loading");
+        }
+    }
+    
+    /**
+     * Stop the loading. 
+     * The loader stops when all tasks from the queue are processed.
+     */
+    synchronized public void stop() {
+        this.alive = false;
+        synchronized (this.cacheStorageProxyMap) {
+            this.cacheStorageProxyMap.notify();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoaderAction.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoaderAction.java
new file mode 100644
index 0000000..6659f10
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/PreemptiveLoaderAction.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.acting.ServiceableAction;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * This action starts the preemptive loader and runs forever.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public class PreemptiveLoaderAction 
+    extends ServiceableAction
+    implements ThreadSafe {
+
+    /**
+     * This action starts the preemptive loading
+     * It runs forever and is stopped by the {@link DefaultIncludeCacheManager}.
+     * @see org.apache.cocoon.acting.Action#act(Redirector, SourceResolver, Map, String, Parameters)
+     */
+    public Map act(Redirector redirector,
+                    SourceResolver resolver,
+                    Map objectModel,
+                    String source,
+                    Parameters parameters)
+    throws Exception {
+        PreemptiveLoader loader = PreemptiveLoader.getInstance();
+        if (!loader.alive) {
+            loader.process(resolver, this.getLogger());
+            return EMPTY_MAP;
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/StoreIncludeCacheStorageProxy.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/StoreIncludeCacheStorageProxy.java
new file mode 100644
index 0000000..79a85cb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/StoreIncludeCacheStorageProxy.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.helpers;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.excalibur.store.Store;
+
+/**
+ * This is the interface between the {@link IncludeCacheManager} and the usual
+ * store.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public final class StoreIncludeCacheStorageProxy
+    implements IncludeCacheStorageProxy {
+
+    private Store  store;
+    
+    private Logger logger;
+    
+    /**
+     * Constructor
+     * @param store  The store for the cached content
+     * @param logger A logger for debugging
+     */
+    public StoreIncludeCacheStorageProxy(Store store, Logger logger) {
+        this.store = store;
+        this.logger = logger;
+    }
+    
+    /** A string representation for a key */
+    private String getKey(String uri) {
+        return "DCS:" + uri;
+    }
+    
+    /**
+     * @see IncludeCacheStorageProxy#get(java.lang.String)
+     */
+    public Serializable get(String uri) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("StoreProxy: Getting content for " + uri);
+        }
+
+        Serializable result = (Serializable)this.store.get(this.getKey(uri));
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("StoreProxy: Result for " + uri + " : " + (result == null ? "Not in cache" : "Found"));
+        }
+        return result;
+    }
+
+    /**
+     * @see IncludeCacheStorageProxy#put(java.lang.String, java.io.Serializable)
+     */
+    public void put(String uri, Serializable object) 
+    throws IOException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("StoreProxy: Storing content for " + uri);
+        }
+        this.store.store(this.getKey(uri), object);
+    }
+
+    /**
+     * @see IncludeCacheStorageProxy#remove(java.lang.String)
+     */
+    public void remove(String uri) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("StoreProxy: Removing content for " + uri);
+        }
+        this.store.remove(this.getKey(uri));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/TextRecorder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/TextRecorder.java
new file mode 100644
index 0000000..48f7022
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/helpers/TextRecorder.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation.helpers;
+
+/**
+ * This class records all character SAX events and creates a string
+ * from them.
+ *
+ * @version $Id$
+ */
+public final class TextRecorder extends NOPRecorder {
+
+    /**
+     * Buffer collecting all character events.
+     */
+    private StringBuffer buffer;
+
+    public TextRecorder() {
+        super();
+        this.buffer = new StringBuffer();
+    }
+
+    public void characters(char ary[], int start, int length) {
+        this.buffer.append(ary, start, length);
+    }
+
+    /**
+     * @return Recorded text so far, trimmed.
+     */
+    public String getText() {
+        return this.buffer.toString().trim();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/ItemGroup.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/ItemGroup.java
new file mode 100644
index 0000000..5cd564a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/ItemGroup.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.pagination;
+
+/**
+ * Container class for the immutable pagination rules for each page.
+ *
+ * @version $Id$
+ */
+public class ItemGroup {
+    
+    private String name;
+    private String elementName;
+    private String elementURI;
+    
+    public ItemGroup (String name, String elementURI, String elementName) {
+        this.name = name;
+        this.elementURI = elementURI;
+        this.elementName = elementName;
+    }
+    
+    public boolean match(String elementName, String elementURI) {
+        return (this.elementName.equals(elementName) && this.elementURI.equals(elementURI));
+    }
+
+    public boolean match(String elementURI) {
+        return this.elementURI.equals(elementURI);
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public String getElementURI() {
+        return this.elementURI;
+    }
+    
+    public String getElementName() {
+        return this.elementName;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/PageRules.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/PageRules.java
new file mode 100644
index 0000000..9273b73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/PageRules.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation.pagination;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Container class for the immutable pagination rules for each page.
+ *
+ * @version $Id$
+ */
+public class PageRules {
+
+    public String elementName;
+    public String elementURI;
+    public int elementCount = 0;
+    public int charCount = 0;
+    public int unitLinks = 0;
+    private List rangeLinks = new ArrayList();
+
+    public boolean match(String element, String namespace) {
+        boolean elementMatches = ((this.elementName!=null) &&
+                                  this.elementName.equals(element));
+
+        if (this.elementURI==null) {
+            return elementMatches;
+        } else {
+            return elementMatches && this.elementURI.equals(namespace);
+        }
+    }
+
+    public boolean match(String namespace) {
+        return ((this.elementURI!=null) &&
+                (this.elementURI.equals(namespace)));
+    }
+
+    public Integer[] getRangeLinks() {
+        return (Integer[]) this.rangeLinks.toArray(new Integer[this.rangeLinks.size()]);
+    }
+
+    public void addRangeLink(Integer rangeLink) {
+        this.rangeLinks.add(rangeLink);
+    }
+
+    public void addRangeLink(int rangeLink) {
+        this.addRangeLink(new Integer(rangeLink));
+    }
+
+    public void addRangeLink(String rangeLink) {
+        this.addRangeLink(new Integer(rangeLink));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Pagesheet.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Pagesheet.java
new file mode 100644
index 0000000..e9bc08c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Pagesheet.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation.pagination;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cocoon.Modifiable;
+import org.apache.cocoon.util.ResizableContainer;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Interprets the pagesheet rules to perform pagination.
+ *
+ * <pre>
+ * FIXME (SM): this code sucks! It was done to show the concept of
+ *             rule driven pagination (which I find very nice) but
+ *             it needs major refactoring in order to be sufficiently
+ *             stable to allow any input to enter without breaking
+ *             SAX well-formness. I currently don't have the time to make
+ *             it any better (along with implementing the char-based rule
+ *             that is mostly useful for text documents) but if you want
+ *             to blast the code and rewrite it better, you'll make me happy :)
+ * </pre>
+ *
+ * @version $Id$
+ */
+
+/*
+
+This is an example pagesheet to show the power of this:
+
+  <?xml version="1.0"?>
+  <pagesheet xmlns="http://apache.org/cocoon/paginate/1.0">
+   <items>
+    <group name="pictures" element="file" namespace="http://apache.org/cocoon/directory/2.0"/>
+   </items>
+   <rules page="1">
+    <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
+     <link type="unit" num="2"/>
+     <link type="range" value="10"/>
+   </rules>
+   <rules>
+    <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
+     <link type="unit" num="5"/>
+     <link type="range" value="20"/>
+   </rules>
+   <rules>
+     <count type="element" name="file" namespace="http://apache.org/cocoon/directory/2.0" num="16"/>
+     <link type="unit" num="5"/>
+     <link type="range" value="2"/>
+     <link type="range" value="5"/>
+     <link type="range" value="10"/>
+     <link type="range" value="20"/>
+     <link type="range" value="100"/>
+   </rules>
+  </pagesheet>
+
+which indicates that:
+
+ 1) there is one item group called "picture" and each item is given by the
+    element "file" of the namespace "http://apache.org/cocoon/directory/2.0".
+
+ 2) for the first page, the pagination rules indicate that there are two unit
+    links (two above and two below, so linking to page -2 -1 0 +1 +2) and
+    range links have value 10 (so they link to page -10 and +10).
+
+ 3) for the rest of the pages, there are three unit links (-3 -2 -1 0 +1 +2 +3)
+    and range goes 20 (so +20 and -20).
+
+ 4) if more than one ranges are defined, range links will be created in sequence
+
+ 5) range links will be from big to small (eg. 20, 10, then 5) for backward links,
+    range links will be from small to big (eg. 5, 10, then 20) for forward links
+
+ 6) range link(s) will have an attribute 'range' to indicate the range size
+
+*/
+public class Pagesheet extends DefaultHandler implements Cloneable, Modifiable {
+
+    // Used only during parsing of pagesheet document
+    private int level = 0;
+    private int pg = 0;
+    private long lastModified;
+    private PageRules rules;
+
+    // Loaded pagesheet information
+    ResizableContainer pageRules;
+
+    Map itemGroupsPerName;
+    Map itemGroupsPerElement;
+    Map itemListsPerName;
+    Map itemListsPerElement;
+
+    // Runtime information
+    private ResizableContainer pages;
+    private Page currentPage = null;
+    private int pageCounter = 1;
+    private int elementCounter = 0;
+    private int descendant = 0;
+
+    private static class Page {
+        public int elementStart;
+        public int elementEnd;
+        public int characters;
+
+        public Page(PageRules rules, int elementStart) {
+            this.elementStart = elementStart;
+
+            if (rules.elementCount>0) {
+                this.elementEnd = this.elementStart+rules.elementCount-1;
+            } else {
+                this.elementEnd = this.elementStart+1;
+            }
+        }
+
+        public boolean validInPage(int elementCounter) {
+            return (this.elementStart<=elementCounter) &&
+                   (elementCounter<=this.elementEnd);
+        }
+    }
+
+    private static class ItemList extends ArrayList {
+        public ItemList(int capacity) {
+            super(capacity);
+        }
+
+        public void addItem(int page) {
+            this.add(new Integer(page));
+        }
+
+        public int getPageForItem(int item) {
+            Integer i = (Integer) this.get(item-1);
+
+            return (i==null) ? 0 : i.intValue();
+        }
+
+        public boolean valid(int item) {
+            return (item==this.size());
+        }
+    }
+
+
+    public Pagesheet() {
+        this.pages = new ResizableContainer(2);
+    }
+
+    private Pagesheet(ResizableContainer rules, Map itemGroupsPerName,
+                      Map itemGroupsPerElement) {
+        this.pageRules = rules;
+        this.itemGroupsPerName = itemGroupsPerName;
+        this.itemGroupsPerElement = itemGroupsPerElement;
+
+        this.pages = new ResizableContainer(5);
+
+        if ((this.itemGroupsPerName!=null) &&
+            (this.itemGroupsPerElement!=null)) {
+            this.itemListsPerName = new HashMap(itemGroupsPerName.size());
+            this.itemListsPerElement = new HashMap(itemGroupsPerName.size());
+
+            Iterator iter = itemGroupsPerName.values().iterator();
+
+            for (; iter.hasNext(); ) {
+                ItemGroup group = (ItemGroup) iter.next();
+                ItemList list = new ItemList(10);
+
+                this.itemListsPerName.put(group.getName(), list);
+                this.itemListsPerElement.put(group.getElementURI()+
+                                             group.getElementName(), list);
+            }
+        }
+    }
+
+    // --------------- interprets the pagesheet document ----------------
+
+    public void startPrefixMapping(String prefix,
+                                   String uri) throws SAXException {
+        if ( !uri.equals(Paginator.PAGINATE_URI)) {
+            throw new SAXException("The pagesheet's namespace is not supported.");
+        }
+    }
+
+    public void startElement(String uri, String loc, String raw,
+                             Attributes a) throws SAXException {
+        level++;
+        switch (level) {
+            case 1 :
+                if (loc.equals("pagesheet")) {
+                    // This object represents pagesheet
+                    return;
+                }
+                break;
+
+            case 2 :
+                if (loc.equals("rules")) {
+                    if (this.pageRules == null) {
+                        this.pageRules = new ResizableContainer(2);
+                    }
+                    String key = a.getValue("page");
+
+                    if (key!=null) {
+                        try {
+                            pg = Integer.parseInt(key);
+                        } catch (NumberFormatException e) {
+                            throw new SAXException("Syntax error: the attribute 'rules/@page' must contain a number");
+                        }
+                    } else {
+                        pg = 0;
+                    }
+                    rules = new PageRules();
+                    return;
+                } else if (loc.equals("items")) {
+                    if (this.itemGroupsPerName==null) {
+                        this.itemGroupsPerName = new HashMap(2);
+                    }
+                    if (this.itemGroupsPerElement==null) {
+                        this.itemGroupsPerElement = new HashMap(2);
+                    }
+                    return;
+                }
+                break;
+
+            case 3 :
+                if (loc.equals("count")) {
+                    rules.elementName = a.getValue("name");
+                    rules.elementURI = a.getValue("namespace");
+
+                    if (a.getValue("type").equals("element")) {
+                        try {
+                            rules.elementCount = Integer.parseInt(a.getValue("num"));
+                        } catch (NumberFormatException e) {
+                            throw new SAXException("Syntax error: the attribute 'count/@num' must contain a number");
+                        }
+                    } else if (a.getValue("type").equals("chars")) {
+                        try {
+                            rules.charCount = Integer.parseInt(a.getValue("num"));
+                        } catch (NumberFormatException e) {
+                            throw new SAXException("Syntax error: the attribute 'count/@num' must contain a number.");
+                        }
+                    } else {
+                        throw new SAXException("Syntax error: count type not supported.");
+                    }
+                    return;
+                } else if (loc.equals("link")) {
+                    if (a.getValue("type").equals("unit")) {
+                        try {
+                            rules.unitLinks = Integer.parseInt(a.getValue("num"));
+                        } catch (NumberFormatException e) {
+                            throw new SAXException("Syntax error: the attribute 'link/@num' must contain a number.");
+                        }
+                    } else if (a.getValue("type").equals("range")) {
+                        try {
+                            rules.addRangeLink(a.getValue("value"));
+                        } catch (NumberFormatException e) {
+                            throw new SAXException("Syntax error: the attribute 'link/@value' must contain a number.");
+                        }
+                    } else {
+                        throw new SAXException("Syntax error: link type not supported.");
+                    }
+                    return;
+                } else if (loc.equals("group")) {
+                    String name = a.getValue("name");
+
+                    if (name==null) {
+                        throw new SAXException("Syntax error: the attribute 'group/@name' must be present.");
+                    }
+                    String elementName = a.getValue("element");
+
+                    if (elementName==null) {
+                        throw new SAXException("Syntax error: the attribute 'group/@element' must be present.");
+                    }
+                    String elementURI = a.getValue("namespace");
+                    ItemGroup group = new ItemGroup(name, elementURI,
+                                                    elementName);
+
+                    this.itemGroupsPerName.put(name, group);
+                    this.itemGroupsPerElement.put(elementURI+elementName,
+                                                  group);
+                    return;
+                }
+        }
+        throw new SAXException("Syntax error: element "+raw+
+                               " is not recognized or is misplaced.");
+    }
+
+    public void endElement(String uri, String loc,
+                           String raw) throws SAXException {
+        level--;
+        if (loc.equals("rules")) {
+            pageRules.set(pg, rules);
+        }
+    }
+
+    public void endDocument() throws SAXException {
+        if (pageRules.size() == 0) {
+            throw new SAXException("Pagesheet must contain at least a set of pagination rules.");
+        }
+        if (pageRules.get(0) == null) {
+            throw new SAXException("Pagesheet must contain the global pagination rules.");
+        }
+    }
+
+    // --------------- process the received element events ----------------
+
+    public void processStartElement(String uri, String name) {
+        PageRules rules = getPageRules(pageCounter);
+
+        if (rules.match(name, uri)) {
+            elementCounter++;
+            descendant++;
+
+            if (currentPage==null) {
+                currentPage = new Page(rules, 1);
+            }
+
+            if (elementCounter>currentPage.elementEnd) {
+                /*System.out.println(">>>> "+pageCounter+
+                                   ": Starting new page!!! >>> "+
+                                   elementCounter);*/
+                pageCounter++;
+                currentPage = new Page(rules, currentPage.elementEnd+1);
+            }
+
+            pages.set(pageCounter, currentPage);
+        }
+
+        if (itemGroupsPerElement!=null) {
+            String qname = uri+name;
+            ItemGroup group = (ItemGroup) this.itemGroupsPerElement.get(qname);
+
+            if ((group!=null) && (group.match(uri))) {
+                ItemList list = (ItemList) this.itemListsPerElement.get(qname);
+
+                if (list!=null) {
+                    list.addItem(pageCounter);
+                }
+            }
+        }
+    }
+
+    public void processEndElement(String uri, String name) {
+        PageRules rules = getPageRules(pageCounter);
+
+        if (rules.match(name, uri)) {
+            descendant--;
+
+            if ((rules.charCount>0) &&
+                (currentPage.characters>rules.charCount)) {
+                // We are over character limit. Flip the page.
+                // System.out.println(">>>> " + pageCounter + ": Flipping page!!!");
+                currentPage.elementEnd = elementCounter;
+            } else if (rules.elementCount==0) {
+                // No limit on elements is specified, and limit on characters is not reached yet.
+                currentPage.elementEnd++;
+            }
+        }
+    }
+
+    public void processCharacters(char[] ch, int index, int len) {
+        if (descendant>0) {
+            // Count amount of characters in the currect page.
+            // System.out.println(">>>> " + pageCounter + ": " + new String(ch, index, len) + " (" + len + " bytes)");
+            currentPage.characters += len;
+        }
+    }
+
+    // --------------- return the pagination information ----------------
+
+    public boolean isInPage(int page, int item, String itemGroup) {
+        return ((descendant==0) || valid(page, item, itemGroup));
+    }
+
+    public int getTotalPages() {
+        return pageCounter;
+    }
+
+    public int getTotalItems(String itemGroup) {
+        if (this.itemListsPerName==null) {
+            return 0;
+        }
+        ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);
+
+        return (list==null) ? 0 : list.size();
+    }
+
+    public int getPageForItem(int item, String itemGroup) {
+        if (this.itemListsPerName==null) {
+            return 0;
+        }
+        ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);
+
+        return (list==null) ? 0 : list.getPageForItem(item);
+    }
+
+    public int itemCount(String elementURI, String elementName) {
+        if (this.itemListsPerElement==null) {
+            return 0;
+        }
+        ItemList list = (ItemList) this.itemListsPerElement.get(elementURI+
+                            elementName);
+
+        return (list==null) ? 0 : list.size();
+    }
+
+    public String getItemGroupName(String elementURI, String elementName) {
+        if (this.itemListsPerElement==null) {
+            return null;
+        }
+        return ((ItemGroup) this.itemGroupsPerElement.get(elementURI+
+            elementName)).getName();
+    }
+
+    // ---------------- miscellaneous methods ----------------------------
+
+    private boolean valid(int page, int item, String itemGroup) {
+        if (item==0) {
+            Page p = (Page) pages.get(page);
+
+            return (p!=null) && (p.validInPage(elementCounter));
+        } else {
+            if (this.itemListsPerElement==null) {
+                return false;
+            }
+            ItemList list = (ItemList) this.itemListsPerName.get(itemGroup);
+
+            return (list!=null) && (list.valid(item));
+        }
+    }
+
+    public PageRules getPageRules(int page) {
+        PageRules p = (PageRules) pageRules.get(page);
+
+        return (p!=null) ? p : (PageRules) pageRules.get(0);
+    }
+
+    public void setLastModified(long lastModified) {
+        this.lastModified = lastModified;
+    }
+
+    public boolean modifiedSince(long date) {
+        return (this.lastModified == 0 || date!=this.lastModified);
+    }
+
+    public Object clone() {
+        return new Pagesheet(pageRules, itemGroupsPerName,
+                             itemGroupsPerElement);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.java
new file mode 100644
index 0000000..979f3fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.java
@@ -0,0 +1,629 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation.pagination;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.CacheableProcessingComponent;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.transformation.AbstractTransformer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.impl.validity.AggregatedValidity;
+import org.apache.excalibur.source.impl.validity.TimeStampValidity;
+import org.apache.excalibur.store.Store;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * A paginating transformer.
+ *
+ * @version $Id$
+ */
+public class Paginator extends AbstractTransformer
+  implements Serviceable, Disposable, CacheableProcessingComponent {
+
+    public static final String PAGINATE_URI = "http://apache.org/cocoon/paginate/1.0";
+    public static final String PAGINATE_PREFIX = "page";
+    public static final String PAGINATE_PREFIX_TOKEN = PAGINATE_PREFIX + ":";
+
+    private ServiceManager manager;
+    private SAXParser parser;
+    private Store store;
+    private SourceResolver resolver;
+    private Source inputSource;
+    private int page;
+    private int item;
+    private String itemGroup;
+    private String requestURI;
+    private Request request;
+    private Pagesheet pagesheet;
+    private int level;
+    private boolean prefixMapping;
+
+    /**
+     * Set the current <code>ServiceManager</code> instance used by this
+     * <code>Serviceable</code>.
+     *
+     * @param  manager  Description of the Parameter
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        try {
+            this.manager = manager;
+            getLogger().debug("Looking up "+SAXParser.ROLE);
+            this.parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+
+            getLogger().debug("Looking up " + Store.TRANSIENT_STORE);
+            this.store = (Store) manager.lookup(Store.TRANSIENT_STORE);
+        } catch (Exception e) {
+            getLogger().error("Could not find component", e);
+        }
+    }
+
+    /**
+     * Dispose this component.
+     */
+    public void dispose() {
+        if (this.parser!=null) {
+            this.manager.release(this.parser);
+        } else {
+            this.parser = null;
+        }
+        if (this.store!=null) {
+            this.manager.release(this.store);
+        } else {
+            this.store = null;
+        }
+    }
+
+    /**
+     * Setup the transformer.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src,
+                      Parameters par)
+                        throws ProcessingException, SAXException,
+                               IOException {
+
+        if (src == null) {
+            throw new ProcessingException("I need the paginate instructions (pagesheet) to continue. Set the 'src' attribute.");
+        }
+
+        try {
+            this.level = 0;
+            this.prefixMapping = false;
+            this.resolver = resolver;
+            this.inputSource = resolver.resolveURI(src);
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Using pagesheet: '"+
+                                  this.inputSource.getURI()+"' in "+this+
+                                  ", last modified: "+
+                                  this.inputSource.getLastModified());
+            }
+            this.page = par.getParameterAsInteger("page", 1);
+            this.item = par.getParameterAsInteger("item", 0);
+            this.itemGroup = par.getParameter("item-group", "");
+            if (getLogger().isDebugEnabled()) {
+                getLogger().debug("Paginating with [page = "+this.page+
+                                  ", item = "+this.item+", item-group = "+
+                                  this.itemGroup+"]");
+            }
+
+            this.request = ObjectModelHelper.getRequest(objectModel);
+            this.requestURI = request.getRequestURI();
+
+            // Get the pagesheet factory from the Store if available,
+            // otherwise load it and put it into the store for further request
+            if (store!=null) {
+                pagesheet = (Pagesheet) store.get(src);
+            }
+
+            // If not in the store or if pagesheet has changed, loads and stores it
+            if ((pagesheet==null) ||
+                pagesheet.modifiedSince(inputSource.getLastModified())) {
+                pagesheet = new Pagesheet();
+                pagesheet.setLastModified(inputSource.getLastModified());
+                parser.parse(new InputSource(inputSource.getInputStream()),
+                             pagesheet);
+                if (store!=null) {
+                    store.store(src, pagesheet);
+                }
+            }
+
+            // Clone it in order to avoid concurrency collisions since the
+            // implementation is not reentrant.
+            this.pagesheet = (Pagesheet) this.pagesheet.clone();
+        } catch (SourceException se) {
+            throw new ProcessingException("Could not retrieve source '" +
+                                          src + "'", se);
+        }
+    }
+
+    public void recycle() {
+        if (null != this.inputSource) {
+            this.resolver.release(this.inputSource);
+            this.inputSource = null;
+        }
+        this.resolver = null;
+        super.recycle();
+    }
+
+    /**
+     * Generate the unique key. This key must be unique inside the space of
+     * this component. This method must be invoked before the
+     * generateValidity() method.
+     *
+     * @return The generated key or <code>null</code> if the component is
+     *         currently not cacheable.
+     */
+    public Serializable getKey() {
+        if (this.inputSource.getLastModified()!=0) {
+            return this.inputSource.getURI()+page;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Generate the validity object. Before this method can be invoked the
+     * generateKey() method must be invoked.
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    public SourceValidity getValidity() {
+        if (this.inputSource.getLastModified()!=0) {
+            AggregatedValidity validity = new AggregatedValidity();
+
+            validity.add(new TimeStampValidity(page));
+            validity.add(this.inputSource.getValidity());
+            return validity;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the
+     *            element has no Namespace URI or if Namespace processing is not being
+     *            performed.
+     * @param loc The local name (without prefix), or the empty
+     *            string if Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty
+     *            string if raw names are not available.
+     * @param a The attributes attached to the element. If there
+     *          are no attributes, it shall be an empty Attributes object.
+     */
+    public void startElement(String uri, String loc, String raw,
+                             Attributes a) throws SAXException {
+        if ( !prefixMapping) {
+            super.startPrefixMapping(PAGINATE_PREFIX, PAGINATE_URI);
+            this.prefixMapping = true;
+        }
+        level++;
+        pagesheet.processStartElement(uri, loc);
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            int itemCount = pagesheet.itemCount(uri, loc);
+
+            if (itemCount>0) {
+                String itemGroup = pagesheet.getItemGroupName(uri, loc);
+                AttributesImpl atts = new AttributesImpl(a);
+
+                atts.addAttribute(PAGINATE_URI, "item",
+                                  PAGINATE_PREFIX_TOKEN+"item", "CDATA",
+                                  String.valueOf(itemCount));
+                atts.addAttribute(PAGINATE_URI, "item-group",
+                                  PAGINATE_PREFIX_TOKEN+"item-group",
+                                  "CDATA", itemGroup);
+                super.startElement(uri, loc, raw, atts);
+            } else {
+                super.startElement(uri, loc, raw, a);
+            }
+        }
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the
+     *            element has no Namespace URI or if Namespace processing is not being
+     *            performed.
+     * @param loc The local name (without prefix), or the empty
+     *            string if Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty
+     *            string if raw names are not available.
+     */
+    public void endElement(String uri, String loc,
+                           String raw) throws SAXException {
+        level--;
+
+        // Prevent infinite recursive loop.
+        if (PAGINATE_URI.equals(uri)) {
+            super.endElement(uri, loc, raw);
+            return;
+        }
+
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            if (level==0) {
+                if (item==0) {
+                    int totalPages = pagesheet.getTotalPages();
+                    PageRules rules = pagesheet.getPageRules(page);
+
+                    Integer[] rangeLinks = rules.getRangeLinks();
+                    int unitLinks = rules.unitLinks;
+                    int currentPage = page;
+
+                    // call add paginate
+                    addPaginateTags(rangeLinks, unitLinks, currentPage,
+                                    totalPages, requestURI, this);
+
+                } else {
+                    int totalItems = pagesheet.getTotalItems(itemGroup);
+                    AttributesImpl atts = new AttributesImpl();
+
+                    atts.addAttribute("", "current", "current", "CDATA",
+                                      String.valueOf(item));
+                    atts.addAttribute("", "total", "total", "CDATA",
+                                      String.valueOf(totalItems));
+                    atts.addAttribute("", "current-uri", "current-uri",
+                                      "CDATA", requestURI);
+                    atts.addAttribute("", "clean-uri", "clean-uri",
+                                      "CDATA", cleanURI(requestURI, item));
+                    atts.addAttribute("", "page", "page", "CDATA",
+                                      String.valueOf(pagesheet.getPageForItem(item,
+                                          itemGroup)));
+                    super.startElement(PAGINATE_URI, "item",
+                                       PAGINATE_PREFIX_TOKEN+"item", atts);
+                    if (item>1) {
+                        atts.clear();
+                        atts.addAttribute("", "type", "type", "CDATA",
+                                          "prev");
+                        atts.addAttribute("", "uri", "uri", "CDATA",
+                                          encodeURI(requestURI, item,
+                                                    item-1));
+                        super.startElement(PAGINATE_URI, "link",
+                                           PAGINATE_PREFIX_TOKEN+"link",
+                                           atts);
+                        super.endElement(PAGINATE_URI, "link",
+                                         PAGINATE_PREFIX_TOKEN+"link");
+                    }
+                    if (item<=totalItems) {
+                        atts.clear();
+                        atts.addAttribute("", "type", "type", "CDATA",
+                                          "next");
+                        atts.addAttribute("", "uri", "uri", "CDATA",
+                                          encodeURI(requestURI, item,
+                                                    item+1));
+                        super.startElement(PAGINATE_URI, "link",
+                                           PAGINATE_PREFIX_TOKEN+"link",
+                                           atts);
+                        super.endElement(PAGINATE_URI, "link",
+                                         PAGINATE_PREFIX_TOKEN+"link");
+                    }
+                    super.endElement(PAGINATE_URI, "item",
+                                     PAGINATE_PREFIX_TOKEN+"item");
+                }
+
+                super.endPrefixMapping(PAGINATE_PREFIX);
+            }
+
+            super.endElement(uri, loc, raw);
+        }
+
+        pagesheet.processEndElement(uri, loc);
+    }
+
+    public static void addPaginateTags(Integer[] rangeLinks, int unitLinks,
+                                       int currentPage, int totalPages,
+                                       String requestURI,
+                                       AbstractTransformer saxTransformer)
+                                         throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+
+        atts.addAttribute("", "current", "current", "CDATA",
+                          String.valueOf(currentPage));
+        atts.addAttribute("", "total", "total", "CDATA",
+                          String.valueOf(totalPages));
+        atts.addAttribute("", "current-uri", "current-uri", "CDATA",
+                          requestURI);
+        atts.addAttribute("", "clean-uri", "clean-uri", "CDATA",
+                          Paginator.cleanURI(requestURI, currentPage));
+        saxTransformer.startElement(Paginator.PAGINATE_URI, "page",
+                                    Paginator.PAGINATE_PREFIX_TOKEN+"page",
+                                    atts);
+
+        for (int i = rangeLinks.length-1; i>-1; i--) {
+            int rangeLink = rangeLinks[i].intValue();
+
+            if ((rangeLink>0) && (currentPage-rangeLink>=1)) {
+                atts.clear();
+                atts.addAttribute("", "type", "type", "CDATA", "prev");
+                atts.addAttribute("", "range", "range", "CDATA",
+                                  rangeLinks[i].toString());
+                atts.addAttribute("", "uri", "uri", "CDATA",
+                                  Paginator.encodeURI(requestURI,
+                                                      currentPage,
+                                                      currentPage-rangeLink));
+                atts.addAttribute("", "page", "page", "CDATA",
+                                  String.valueOf(currentPage-rangeLink));
+                saxTransformer.startElement(Paginator.PAGINATE_URI,
+                                            "range-link",
+                                            Paginator.PAGINATE_PREFIX_TOKEN+
+                                            "range-link", atts);
+                saxTransformer.endElement(Paginator.PAGINATE_URI,
+                                          "range-link",
+                                          Paginator.PAGINATE_PREFIX_TOKEN+
+                                          "range-link");
+            }
+        }
+
+        for (int i = currentPage-unitLinks; i<currentPage; i++) {
+            if (i>0) {
+                atts.clear();
+                atts.addAttribute("", "type", "type", "CDATA", "prev");
+                atts.addAttribute("", "uri", "uri", "CDATA",
+                                  Paginator.encodeURI(requestURI,
+                                                      currentPage, i));
+                atts.addAttribute("", "page", "page", "CDATA",
+                                  String.valueOf(i));
+                saxTransformer.startElement(Paginator.PAGINATE_URI, "link",
+                                            Paginator.PAGINATE_PREFIX_TOKEN+
+                                            "link", atts);
+                saxTransformer.endElement(Paginator.PAGINATE_URI, "link",
+                                          Paginator.PAGINATE_PREFIX_TOKEN+
+                                          "link");
+            }
+        }
+        for (int i = currentPage+1; i<=currentPage+unitLinks; i++) {
+            if (i<=totalPages) {
+                atts.clear();
+                atts.addAttribute("", "type", "type", "CDATA", "next");
+                atts.addAttribute("", "uri", "uri", "CDATA",
+                                  Paginator.encodeURI(requestURI,
+                                                      currentPage, i));
+                atts.addAttribute("", "page", "page", "CDATA",
+                                  String.valueOf(i));
+                saxTransformer.startElement(Paginator.PAGINATE_URI, "link",
+                                            Paginator.PAGINATE_PREFIX_TOKEN+
+                                            "link", atts);
+                saxTransformer.endElement(Paginator.PAGINATE_URI, "link",
+                                          Paginator.PAGINATE_PREFIX_TOKEN+
+                                          "link");
+            }
+        }
+
+        for (int i = 0; i<rangeLinks.length; i++) {
+            int rangeLink = rangeLinks[i].intValue();
+
+            if ((rangeLink>0) && (currentPage+rangeLink<=totalPages)) {
+                atts.clear();
+                atts.addAttribute("", "type", "type", "CDATA", "next");
+                atts.addAttribute("", "range", "range", "CDATA",
+                                  rangeLinks[i].toString());
+                atts.addAttribute("", "uri", "uri", "CDATA",
+                                  Paginator.encodeURI(requestURI,
+                                                      currentPage,
+                                                      currentPage+rangeLink));
+                atts.addAttribute("", "page", "page", "CDATA",
+                                  String.valueOf(currentPage+rangeLink));
+                saxTransformer.startElement(Paginator.PAGINATE_URI,
+                                            "range-link",
+                                            Paginator.PAGINATE_PREFIX_TOKEN+
+                                            "range-link", atts);
+                saxTransformer.endElement(Paginator.PAGINATE_URI,
+                                          "range-link",
+                                          Paginator.PAGINATE_PREFIX_TOKEN+
+                                          "range-link");
+            }
+        }
+
+        saxTransformer.endElement(Paginator.PAGINATE_URI, "page",
+                                  Paginator.PAGINATE_PREFIX_TOKEN+"page");
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void characters(char c[], int start, int len) throws SAXException {
+        pagesheet.processCharacters(c, start, len);
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.characters(c, start, len);
+        }
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void ignorableWhitespace(char c[], int start,
+                                    int len) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.ignorableWhitespace(c, start, len);
+        }
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if none
+     *             was supplied.
+     */
+    public void processingInstruction(String target,
+                                      String data) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.processingInstruction(target, data);
+        }
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity. If it is a
+     *             parameter entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.skippedEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external
+     *                 DTD subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external
+     *                 DTD subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId,
+                         String systemId) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.startDTD(name, publicId, systemId);
+        } else {
+            throw new SAXException("Recieved startDTD not in page.");
+        }
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD() throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.endDTD();
+        } else {
+            throw new SAXException("Recieved endDTD not in page.");
+        }
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     *@param name The name of the entity. If it is a parameter
+     *            entity, the name will begin with '%'.
+     */
+    public void startEntity(String name) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.startEntity(name);
+        }
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.endEntity(name);
+        }
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA() throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.startCDATA();
+        }
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA() throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.endCDATA();
+        }
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len) throws SAXException {
+        if (pagesheet.isInPage(page, item, itemGroup)) {
+            super.comment(ch, start, len);
+        }
+    }
+
+    /**
+     * Removes the pagination encoding from the URI by removing the page number
+     * and the previous and next character.
+     */
+    public static String cleanURI(String uri, int current) {
+        String currentS = String.valueOf(current);
+        int index = uri.lastIndexOf(currentS);
+
+        if (index==-1) {
+            return uri;
+        } else {
+            return uri.substring(0, index-1)+
+                   uri.substring(index+currentS.length()+1);
+        }
+    }
+
+    /**
+     * Encode the next page in the given URI. First tries to use the existing
+     * encoding by replacing the current page number, but if the current
+     * encoding is not found it appends "(xx)" to the filename (before the file
+     * extention, if any) where "xx" is the next page value.
+     */
+    public static String encodeURI(String uri, int current, int next) {
+        String currentS = String.valueOf(current);
+        String nextS = String.valueOf(next);
+        int index = uri.lastIndexOf(currentS);
+
+        if (index==-1) {
+            index = uri.lastIndexOf('.');
+            if (index==-1) {
+                return uri+"("+nextS+")";
+            } else {
+                return uri.substring(0, index)+"("+nextS+")."+
+                       uri.substring(index+1);
+            }
+        } else {
+            return uri.substring(0, index)+nextS+
+                   uri.substring(index+currentS.length());
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.xconf b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.xconf
new file mode 100644
index 0000000..e5bee25
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/transformation/pagination/Paginator.xconf
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xconf xpath="/cocoon" unless="component[@role='org.apache.cocoon.transformation.pagination.Paginator']">
+
+    <!-- ======================= Paginator =========================== -->
+  <component 
+     class="org.apache.cocoon.transformation.pagination.Paginator" 
+     role="org.apache.cocoon.transformation.pagination.Paginator"
+     logger="core.paginator"/>
+     
+</xconf>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/BufferedOutputStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/BufferedOutputStream.java
new file mode 100644
index 0000000..9564863
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/BufferedOutputStream.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This class is like the {@link java.io.BufferedOutputStream} but it
+ * extends it with a logic to count the number of bytes written to
+ * the output stream.
+ * 
+ * @version $Id$
+ * @since   2.1
+ */
+public final class BufferedOutputStream extends FilterOutputStream {
+    
+    protected byte buf[];
+
+    protected int count;
+    
+    /**
+     * Creates a new buffered output stream to write data to the 
+     * specified underlying output stream with a default 8192-byte
+     * buffer size.
+     *
+     * @param   out   the underlying output stream.
+     */
+    public BufferedOutputStream(OutputStream out) {
+        this(out, 8192);
+    }
+
+    /**
+     * Creates a new buffered output stream to write data to the 
+     * specified underlying output stream with the specified buffer 
+     * size. 
+     *
+     * @param   out    the underlying output stream.
+     * @param   size   the buffer size.
+     * @exception IllegalArgumentException if size <= 0.
+     */
+    public BufferedOutputStream(OutputStream out, int size) {
+        super(out);
+        if (size <= 0) {
+            throw new IllegalArgumentException("Buffer size <= 0");
+        }
+        this.buf = new byte[size];
+    }
+
+    /**
+     * Writes the specified byte to this buffered output stream. 
+     *
+     * @param      b   the byte to be written.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void write(int b) throws IOException {
+        if (this.count >= this.buf.length) {
+            this.incBuffer();
+        }
+        this.buf[count++] = (byte)b;
+    }
+
+    /**
+     * Writes <code>len</code> bytes from the specified byte array 
+     * starting at offset <code>off</code> to this buffered output stream.
+     *
+     * <p> Ordinarily this method stores bytes from the given array into this
+     * stream's buffer, flushing the buffer to the underlying output stream as
+     * needed.  If the requested length is at least as large as this stream's
+     * buffer, however, then this method will flush the buffer and write the
+     * bytes directly to the underlying output stream.  Thus redundant
+     * <code>BufferedOutputStream</code>s will not copy data unnecessarily.
+     *
+     * @param      b     the data.
+     * @param      off   the start offset in the data.
+     * @param      len   the number of bytes to write.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void write(byte b[], int off, int len) throws IOException {
+        while (len > buf.length - count) {
+            this.incBuffer();
+        }
+        System.arraycopy(b, off, buf, count, len);
+        count += len;
+    }
+
+    /**
+     * Flushes this buffered output stream. 
+     * We don't flush here, flushing is done during closing.
+     *
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void flush() throws IOException {
+        // nothing
+    }
+
+    /**
+     * Closes this buffered output stream.
+     * Flush before closing.
+     *
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public void close() throws IOException {
+        realFlush();
+        super.close ();
+    }
+
+    /**
+     * Flushes this buffered output stream. 
+     */
+    public void realFlush() throws IOException {
+        this.writeBuffer();
+        this.out.flush();
+    }
+    
+    /**
+     * Write the buffer
+     */
+    private void writeBuffer() 
+    throws IOException {
+        if (this.count > 0) {
+            this.out.write(this.buf, 0, this.count);
+            this.clearBuffer();
+        }
+    }
+
+    /**
+     * Increment the buffer
+     */
+    private void incBuffer() {
+        // currently we double the buffer size
+        // this is not so fast but is a very simple logic
+        byte[] newBuf = new byte[this.buf.length * 2];
+        System.arraycopy(this.buf, 0, newBuf, 0, this.buf.length);
+        this.buf = newBuf;
+    }
+    
+    /**
+     * Clear/reset the buffer
+     */
+    public void clearBuffer() {
+        this.count = 0;
+    }
+
+    /**
+     * Return the size of the current buffer
+     */
+    public int getCount() {
+        return this.count;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ByteRange.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ByteRange.java
new file mode 100644
index 0000000..298e653
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ByteRange.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+/**
+ * @version $Id$
+ */
+final public class ByteRange {
+
+    
+    private final long start;
+    private final long end;
+
+    
+    public ByteRange(long start, long end) {
+        this.start = start;
+        this.end = end;
+    }
+
+    
+    public ByteRange(String string) throws NumberFormatException {
+        string = string.trim();
+        int dashPos = string.indexOf('-');
+        int length = string.length();
+        if (string.indexOf(',') != -1) {
+            throw new NumberFormatException("Simple ByteRange String contains a comma.");
+        }
+        if (dashPos > 0) {
+            this.start = Integer.parseInt(string.substring(0, dashPos));
+        } else {
+            this.start = Long.MIN_VALUE;
+        }
+        if (dashPos < length - 1) {
+            this.end = Integer.parseInt(string.substring(dashPos + 1, length));
+        } else {
+            this.end = Long.MAX_VALUE;
+        }
+        if (this.start > this.end) {
+            throw new NumberFormatException("Start value is greater than end value.");
+        }
+    }
+
+    
+    public long getStart() {
+        return this.start;
+    }
+
+    
+    public long getEnd() {
+        return this.end;
+    }
+
+    
+    public long length() {
+        return this.end - this.start + 1;
+    }
+
+    
+    public ByteRange intersection(ByteRange range) {
+        if (range.end < this.start || this.end < range.start) {
+            return null;
+        } else {
+            long start = (this.start > range.start) ? this.start : range.start;
+            long end = (this.end < range.end) ? this.end : range.end;
+            return new ByteRange(start, end);
+        }
+    }
+
+
+    public String toString() {
+        return this.start + "-" + this.end;
+    }
+
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ClassUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ClassUtils.java
new file mode 100644
index 0000000..2c3dd5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ClassUtils.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * A collection of class management utility methods.
+ *
+ * @version $Id$
+ */
+public class ClassUtils {
+
+    /**
+     * Create a new instance given a class name
+     *
+     * @param className A class name
+     * @return A new instance
+     * @exception Exception If an instantiation error occurs
+     */
+    public static Object newInstance(String className) throws Exception {
+        return ClassUtils.loadClass(className).newInstance();
+    }
+
+    /**
+     * Load a class given its name.
+     * BL: We wan't to use a known ClassLoader--hopefully the heirarchy
+     *     is set correctly.
+     *
+     * @param className A class name
+     * @return The class pointed to by <code>className</code>
+     * @exception ClassNotFoundException If a loading error occurs
+     */
+    public static Class loadClass(String className) throws ClassNotFoundException {
+        return ClassUtils.getClassLoader().loadClass(className);
+    }
+
+    /**
+     * Return a resource URL.
+     * BL: if this is command line operation, the classloading issues
+     *     are more sane.  During servlet execution, we explicitly set
+     *     the ClassLoader.
+     *
+     * @return The context classloader.
+     * @exception MalformedURLException If a loading error occurs
+     */
+    public static URL getResource(String resource) throws MalformedURLException {
+        return ClassUtils.getClassLoader().getResource(resource);
+    }
+
+    /**
+     * Return the context classloader.
+     * BL: if this is command line operation, the classloading issues
+     *     are more sane.  During servlet execution, we explicitly set
+     *     the ClassLoader.
+     *
+     * @return The context classloader.
+     */
+    public static ClassLoader getClassLoader() {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Deprecation.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Deprecation.java
new file mode 100644
index 0000000..70752a5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Deprecation.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.commons.lang.enums.ValuedEnum;
+
+/**
+ * This class provides a special static "deprecation" logger.
+ * All deprecated code should use this logger to log messages into the 
+ * deprecation logger. This makes it easier for users to find out if they're 
+ * using deprecated stuff.
+ * <p>
+ * Additionally, it is possible to set the forbidden level of deprecation messages (default
+ * is to forbid ERROR, i.e. allow up to WARN). Messages equal to or above the forbidden level
+ * will lead to throwing a {@link DeprecationException}. Setting the forbidden level to
+ * FATAL_ERROR allows running legacy applications using deprecated features (tolerant mode), and
+ * setting the forbidden level to DEBUG will run in strict mode, forbidding all deprecations.
+ * <p>
+ * Note that according to the above, issuing a fatalError log always raises an exception, and
+ * can therefore be used when detecting old features that have been totally removed.
+ *
+ * @version $Id$
+ */
+public class Deprecation {
+    
+    /**
+     * The deprecation logger.
+     */
+    public static final Logger logger = new LoggerWrapper(new ConsoleLogger());
+    
+    private static final int DEBUG_VALUE = 0;
+    private static final int INFO_VALUE = 1;
+    private static final int WARN_VALUE = 2;
+    private static final int ERROR_VALUE = 3;
+    private static final int FATAL_VALUE = 3;
+    private static final int FATAL_ERROR_VALUE = 4;
+    
+    /**
+     * Debug deprecation messages indicate features that are no more considered "current"
+     * or "best practice", but for which no removal is currently foreseen.
+     */
+    public static final LogLevel DEBUG = new LogLevel("DEBUG", DEBUG_VALUE);
+
+    /**
+     * Info deprecation messages indicate features that are no more considered "current"
+     * or "best practice", and that will probably be removed in future releases.
+     */
+    public static final LogLevel INFO = new LogLevel("INFO", INFO_VALUE);
+
+    /**
+     * Warning deprecation messages indicate features that will be removed in the next major
+     * version (e.g. 2.1.x --> 2.2.0). Such features should not be used if the application is
+     * planned to be migrated to newer Cocoon versions.
+     */
+    public static final LogLevel WARN = new LogLevel("WARN", WARN_VALUE);
+
+    /**
+     * Error deprecation messages indicate features that will be removed in the next minor
+     * version (e.g. 2.1.6 --> 2.1.7). Although still functional, users are stronly invited to
+     * not use them.
+     */
+    public static final LogLevel ERROR = new LogLevel("ERROR", ERROR_VALUE);
+
+    /**
+     * Fatal error deprecation messages indicate features that used to exist but have been removed
+     * in the current version. Logging such a message always throws a {@link DeprecationException}.
+     */
+    public static final LogLevel FATAL_ERROR = new LogLevel("FATAL_ERROR", FATAL_ERROR_VALUE);
+    
+    public static final class LogLevel extends ValuedEnum {
+        private LogLevel(String text, int value) {
+            super(text, value);
+        }
+        
+        public static LogLevel getLevel(String level) {
+            return (LogLevel)ValuedEnum.getEnum(LogLevel.class, level);
+        }
+    }
+
+    public static void setLogger(Logger newLogger) {
+        // Note: the "logger" attribute is not of type LoggerWrapper so that it appears
+        // as a standard Logger in the javadocs.
+        ((LoggerWrapper)logger).setLogger(newLogger);
+    }
+    
+    public static void setForbiddenLevel(LogLevel level) {
+        // If null, reset to the default level
+        if (level == null) {
+            level = ERROR;
+        }
+        ((LoggerWrapper)logger).setForbiddenLevel(level);
+    }
+    
+    /**
+     * Wraps a logger, and throws an DeprecatedException if the message level is
+     * higher than the allowed one.
+     */
+    private static class LoggerWrapper implements Logger {
+        
+        private Logger realLogger;
+        // up to warn is allowed
+        private int forbiddenLevel = ERROR_VALUE;
+        
+        public LoggerWrapper(Logger logger) {
+            this.realLogger = logger;
+        }
+        
+        public void setLogger(Logger logger) {
+            // Unwrap a wrapped logger
+            while(logger instanceof LoggerWrapper) {
+                logger = ((LoggerWrapper)logger).realLogger;
+            }
+            this.realLogger = logger;
+        }
+        
+        public void setForbiddenLevel(LogLevel level) {
+            this.forbiddenLevel = level.getValue();
+        }
+        
+        private void throwException(int level, String message) {
+            if (level >= this.forbiddenLevel) {
+                throw new DeprecationException(message);
+            }
+        }
+        
+        private boolean isThrowingException(int level) {
+            return level >= this.forbiddenLevel;
+        }
+        
+        public void debug(String message) {
+            realLogger.debug(message);
+            throwException(DEBUG_VALUE, message);
+        }
+        public void debug(String message, Throwable thr) {
+            realLogger.debug(message, thr);
+            throwException(DEBUG_VALUE, message);
+        }
+        public void info(String message) {
+            realLogger.info(message);
+            throwException(INFO_VALUE, message);
+        }
+        public void info(String message, Throwable thr) {
+            realLogger.info(message, thr);
+            throwException(INFO_VALUE, message);
+        }
+        public void warn(String message) {
+            realLogger.warn(message);
+            throwException(WARN_VALUE, message);
+        }
+        public void warn(String message, Throwable thr) {
+            realLogger.warn(message, thr);
+            throwException(WARN_VALUE, message);
+        }
+        public void error(String message) {
+            realLogger.error(message);
+            throwException(ERROR_VALUE, message);
+        }
+        public void error(String message, Throwable thr) {
+            realLogger.error(message, thr);
+            throwException(ERROR_VALUE, message);
+        }
+        public void fatalError(String message) {
+            realLogger.fatalError(message);
+            throwException(FATAL_VALUE, message);
+        }
+        public void fatalError(String message, Throwable thr) {
+            realLogger.fatalError(message, thr);
+            throwException(FATAL_VALUE, message);
+        }
+        public boolean isDebugEnabled() {
+            // Enable level also if it is set to throw an exception, so that
+            // logging the message occurs, and then throws it.
+            return isThrowingException(DEBUG_VALUE) || realLogger.isDebugEnabled();
+        }
+        public boolean isInfoEnabled() {
+            return isThrowingException(INFO_VALUE) || realLogger.isInfoEnabled();
+        }
+        public boolean isWarnEnabled() {
+            return isThrowingException(WARN_VALUE) || realLogger.isWarnEnabled();
+        }
+        public boolean isErrorEnabled() {
+            return isThrowingException(ERROR_VALUE) || realLogger.isErrorEnabled();
+        }
+        public boolean isFatalErrorEnabled() {
+            return true;
+        }
+        public Logger getChildLogger(String message) {
+            return realLogger.getChildLogger(message);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/DeprecationException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/DeprecationException.java
new file mode 100644
index 0000000..be83cb2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/DeprecationException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+
+/**
+ * An exception that indicates unauthorized use of a deprecated feature, or an
+ * attempt to use a old feature that has been removed.
+ * 
+ * @version $Id$
+ */
+public class DeprecationException extends RuntimeException {
+    public DeprecationException(String message) {
+        super(message);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ElementAttributeMatching.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ElementAttributeMatching.java
new file mode 100644
index 0000000..7f3e4ff
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ElementAttributeMatching.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+/**
+ * A helper class for matching element names, and attribute names.
+ * <p/>
+ * For given include-name, exclude-name decide if element-attribute pair
+ * matches. This class defines the precedence and matching algorithm.
+ * </p>
+ * This was originally part of the EncodeURLTransformer, moved
+ * here to make it more reusable.
+ *
+ * @version $Id$
+ */
+public class ElementAttributeMatching {
+    /**
+     * Regular expression of including patterns
+     */
+    protected RE includeNameRE;
+    /**
+     * Regular expression of excluding patterns
+     */
+    protected RE excludeNameRE;
+
+
+    /**
+     * Constructor for the ElementAttributeMatching object
+     *
+     * @param includeName Description of Parameter
+     * @param excludeName Description of Parameter
+     * @throws org.apache.regexp.RESyntaxException
+     *          Description of Exception
+     */
+    public ElementAttributeMatching(String includeName, String excludeName) throws RESyntaxException {
+        includeNameRE = new RE(includeName, RE.MATCH_CASEINDEPENDENT);
+        excludeNameRE = new RE(excludeName, RE.MATCH_CASEINDEPENDENT);
+    }
+
+
+    /**
+     * Return true iff element_name attr_name pair is not matched by exclude-name,
+     * but is matched by include-name
+     *
+     * @param element_name
+     * @param attr_name
+     * @param value used to canonicalize the elemtn/attribute name
+     * @return boolean true iff value of attribute_name should get rewritten, else
+     *         false.
+     */
+    public boolean matchesElementAttribute(String element_name, String attr_name, String value) {
+        final String element_attr_name = canonicalizeElementAttribute(element_name, attr_name, value);
+
+        if (excludeNameRE != null && includeNameRE != null) {
+            return !matchesExcludesElementAttribute(element_attr_name) &&
+                    matchesIncludesElementAttribute(element_attr_name);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Build a single string from element name, attribute and value, for pattern matching.
+     */
+    private String canonicalizeElementAttribute(String element_name, String attr_name, String value) {
+        return element_name + "/@" + attr_name + "=" + value;
+    }
+
+    /**
+     * @return true element_attr_name is matched by exclude-name.
+     */
+    private boolean matchesExcludesElementAttribute(String element_attr_name) {
+        return excludeNameRE.match(element_attr_name);
+    }
+
+    /**
+     * @return true element_attr_name is matched by include-name.
+     */
+    private boolean matchesIncludesElementAttribute(String element_attr_name) {
+        return includeNameRE.match(element_attr_name);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/EnumerationFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/EnumerationFactory.java
new file mode 100644
index 0000000..8d405f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/EnumerationFactory.java
@@ -0,0 +1,212 @@
+/*
+* Copyright 1999-2005 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+//----------------------------------------------------------------------
+// This software is provided as is in the hope that it might be found
+// useful.
+// You may use and modify it freely provided you keep this copyright
+// notice unchanged and mark modifications appropriately.
+//
+// Bug reports and proposals for improvements are welcome. Please send
+// them to the eMail address below.
+//
+// Christoph Karl Walter Grein
+// Hauptstr. 42
+// D-86926 Greifenberg
+// Germany
+//
+// eMail: Christ-Usch.Grein@T-Online.de
+//
+// Copyright (c) 1998 Christoph Karl Walter Grein
+//----------------------------------------------------------------------
+
+//====================================================================
+// Author    Christoph Grein <Christ-Usch.Grein@T-Online.de>
+// Version   1.1
+// Date      7 February 1998
+//====================================================================
+// A factory for the creation of enumeration types (missing in Java).
+// The same operations are provided as for Ada, only representation
+// specification is missing (which does not seem to make much sense
+// in Java).
+//
+// The idea behind this implementation model is the following:
+//
+// Each enumeration object [or literal as called in Ada] is internally
+// represented by its position number [like in Ada] starting with 0
+// for the first one. For external representation, an image string
+// may also be defined.
+// All operations on enumerations (order relations between objects,
+// iterators [in the Ada sense for getting the successor and predeces-
+// sor of an object]) are implemented on the internal position number.
+//
+// Implementing the Ada 'Pos attribute as a function getPos () is
+// straight forward as is the implementation of 'Image as a function
+// toString () [*], whereas their reverse operations 'Val and 'Value
+// present a bit of a problem.
+// In order to be able to access all objects created for the given
+// class, we define a vector and let the constructors add each object
+// upon creation to this vector. Thus each object's position number
+// is also its vector index. So getVal [Ada's 'Val] simply returns
+// the object stored at the given place; getObject [Ada's 'Value]
+// loops thru the vector until it finds the object with the given
+// string.
+//
+// [*] The name toString has deliberately been chosen because of
+// Java's convention of calling an operation with this name whenever
+// an object's name appears in string context.
+//
+// There is one last point to take care of. An enumeration class has
+// only a fixed number of objects, so we must inhibit the creation of
+// new objects (with the "new" operator) outside of the enumeration
+// class. However, in order to make this EnumerationFactory class
+// work, the constructors need to be public. Therefore we set up the
+// requirement that upon derivation from class EnumerationFactory all
+// objects be created in the derivation class (using all capital
+// letters according to Java's convention) and the constructors be
+// made private.
+//
+// For this class at work, see the example classes EnumerationExample
+// and Test_EnumerationExample, which present a few objects and opera-
+// tions on them.
+//
+// Comments and improvements are welcome, see e-mail address above.
+//====================================================================
+// History:
+// Author Version   Date    Reason for Change
+//  C.G.   1.0  03.02.1998
+//  C.G.   1.1  07.02.1998  getObject returns null if nothing found
+//====================================================================
+
+package org.apache.cocoon.util;
+
+import java.util.Vector;
+
+/**
+ * A factory for the creation of enumeration types (missing in Java).
+ * The same operations are provided as for Ada, only representation
+ * specification is missing (which does not seem to make much sense
+ * in Java).
+ * Enumeration classes are to be derived from this class thereby
+ * making the constructors private to inhibit creation outside of
+ * the derived class.
+ *
+ * @author Christoph Grein
+ * @version $Id$
+ */
+public class EnumerationFactory {
+
+    private static Vector allObjects =  // must be here JDK 1.1.3
+                    new Vector (0, 1);  // empty, increment by 1
+
+    private int pos;
+    private String image;
+
+    /**
+     * Constructors with and without a string representation (image).
+     * Make constructors private upon derivation.
+     * Be careful: No check is made that the image string is unique!
+     * @param image
+     */
+    public EnumerationFactory(String image) {
+        this.pos = allObjects.size();
+        this.image = image;
+        allObjects.addElement(this);
+    }
+
+    public EnumerationFactory() {
+        this ("");
+    }
+
+    //--------------------------------------------------------------------------
+    // Order relations:
+
+    /**
+     * Order relations Object.op (OtherObject) representing the relation
+     * Object op OtherObject.
+     * @param e the right operand
+     */
+    public boolean lt(EnumerationFactory e) {                   // "<"
+        return this.getPos() < e.getPos();
+    }
+
+    public boolean le(EnumerationFactory e) {                   // "<="
+        return this.getPos() <= e.getPos();
+    }
+
+    public boolean gt(EnumerationFactory e) {                   // ">"
+        return this.getPos() > e.getPos();
+    }
+
+    public boolean ge(EnumerationFactory e) {                   // ">="
+        return this.getPos() >= e.getPos ();
+    }
+
+    // "==" and "equals" are inherited.
+
+    //--------------------------------------------------------------------------
+    // Numeric representation:
+
+    public int getPos() {                                          // Ada'Pos
+        return pos;
+    }
+
+    /**
+     * Access to the numeric representation.
+     * @param value the numeric value
+     */
+    public static EnumerationFactory getVal(int value) {           // Ada'Val
+        return (EnumerationFactory)allObjects.elementAt(value);
+    }
+
+    //--------------------------------------------------------------------------
+    // Iterator:
+
+    public static EnumerationFactory getFirst() {                  // Ada'First
+        return getVal(0);
+    }
+
+    public static EnumerationFactory getLast() {                   // Ada'Last
+        return getVal(allObjects.size() - 1);
+    }
+
+    public EnumerationFactory getNext () {                          // Ada'Succ
+        return getVal(this.getPos() + 1);
+    }
+
+    public EnumerationFactory getPrev () {                          // Ada'Pred
+        return getVal(this.getPos() - 1);
+    }
+
+    //--------------------------------------------------------------------------
+    // String representation:
+
+    public String toString() {                                     // Ada'Image
+        return image;
+    }
+
+    public static EnumerationFactory getObject(String image) {     // Ada'Value
+        EnumerationFactory found;
+        // Linear search seems good enough because there presumably
+        // will not be too many literals.
+        for (int i = 0 ; i < allObjects.size() ; i++) {
+            found = (EnumerationFactory) allObjects.elementAt(i);
+            if (found.toString().equals(image)) {
+                return found;
+            }
+        }
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/FileFormatException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/FileFormatException.java
new file mode 100644
index 0000000..dbf4cd3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/FileFormatException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import org.apache.avalon.framework.CascadingException;
+
+/**
+ * @version $Id$
+ */
+public class FileFormatException extends CascadingException {
+    public FileFormatException(String s) {
+        super(s);
+    }
+
+    public FileFormatException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashMap.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashMap.java
new file mode 100644
index 0000000..82b3cef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashMap.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util;
+
+import java.util.Map;
+
+/**
+ * Extended Version of {@link java.util.HashMap} that provides an extended
+ * get method accpeting a default value. The default value is returned if
+ * the map does not contain a value for the provided key.
+ *
+ * @version $Id$
+ */
+public class HashMap extends java.util.HashMap {
+
+    public HashMap () {
+        super();
+    }
+
+    public HashMap ( int initialCapacity ) {
+        super(initialCapacity);
+    }
+
+    public HashMap ( int initialCapacity, float loadFactor ) {
+        super(initialCapacity, loadFactor);
+    }
+
+    public HashMap ( Map t) {
+        super(t);
+    }
+
+    /**
+     * Get method extended by default object to be returned when key
+     * is not found.
+     *
+     * @param key key to look up
+     * @param _default default value to return if key is not found
+     * @return value that is associated with key
+     */
+    public Object get( Object key, Object _default ) {
+        if (this.containsKey(key)) {
+            return this.get(key);
+        }
+        return _default;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashUtil.java
new file mode 100644
index 0000000..53928b5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/HashUtil.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+/**
+ * A very efficient java hash algorithm, based on the BuzHash algoritm
+ * by Robert Uzgalis (see http://www.serve.net/buz/hash.adt/java.000.html
+ * for more information).
+ * BuzHash is Copyright (c)1996 Robert Uzgalis, All Rights Reserved.
+ * Used with kind permission of the author
+ *
+ * @author <a href="mailto:buz@zis.com">Robert Uzgalis</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version $Id$
+ */
+public final class HashUtil {
+
+    private static long initial_hash = 0xe12398c6d9ae3b8aL; // initial values
+
+    private static long mix_master[/* 0:255 */] = {
+/* 000 */ 0x4476081a7043a46fL, 0x45768b8a6e7eac19L, 0xebd556c1cf055952L,
+/* */ 0x72ed2da1bf010101L, 0x3ff2030b128e8a64L,
+/* 005 */ 0xcbc330238adcfef2L, 0x737807fe42e20c6cL, 0x74dabaedb1095c58L,
+/* */ 0x968f065c65361d67L, 0xd3f4018ac7a4b199L,
+/* 010 */ 0x954b389b52f24df2L, 0x2f97a9d8d0549327L, 0xb9bea2b49a3b180fL,
+/* */ 0xaf2f42536b21f2ebL, 0x85d991663cff1325L,
+/* 015 */ 0xb9e1260207b575b9L, 0xf3ea88398a23b7e2L, 0xfaf8c83ffbd9091dL,
+/* */ 0x4274fe90834dbdf9L, 0x3f20b157b68d6313L,
+/* 020 */ 0x68b48972b6d06b93L, 0x694837b6eba548afL, 0xeecb51d1acc917c9L,
+/* */ 0xf1c633f02dffbcfaL, 0xa6549ec9d301f3b5L,
+/* 025 */ 0x451dc944f1663592L, 0x446d6acef6ce9e4fL, 0x1c8a5b3013206f02L,
+/* */ 0x5908ca36f2dc50f7L, 0x4fd55d3f3e880a87L,
+/* 030 */ 0xa03a8dbeabbf065dL, 0x3ccbbe078fabcb6dL, 0x1da53a259116f2d0L,
+/* */ 0xfb27a96fcb9af152L, 0x50aba242e85aec09L,
+/* 035 */ 0x24d4e414fc4fc987L, 0x83971844a9ce535eL, 0xc26a3fdeb849398eL,
+/* */ 0xc2380d044d2e70d8L, 0xab418aa8ae19b18fL,
+/* 040 */ 0xd95b6b9247d5ebeaL, 0x8b3b2171fdc60511L, 0xe15cd0ae3fcc44afL,
+/* */ 0x5a4e27f914a68f17L, 0x377bd28ca09aafdcL,
+/* 045 */ 0xbbeb9828594a3294L, 0x7c8df263ae1de1b9L, 0xba0a48a5fd1c1dd0L,
+/* */ 0x57cc1b8818b98ee6L, 0x8c570975d357dabcL,
+/* 050 */ 0x76bdcd6f2e8826aaL, 0x529b15b6ec4055f1L, 0x9147c7a54c34f8a9L,
+/* */ 0x2f96a7728170e402L, 0xe46602f455eca72eL,
+/* 055 */ 0x22834c4dd1bde03fL, 0x2644cf5a25e368ffL, 0x907c6de90b120f4aL,
+/* */ 0xadfe8ba99028f728L, 0xa85199ae14df0433L,
+/* 060 */ 0x2d749b946dd3601eL, 0x76e35457aa052772L, 0x90410bf6e427f736L,
+/* */ 0x536ad04d13e35041L, 0x8cc0d76769b76914L,
+/* 065 */ 0xae0249f6e3b3c01cL, 0x1bdfd075307d6fafL, 0xd8e04f70c221deccL,
+/* */ 0x4ab23622a4281a5dL, 0x37a5613da2fcaba7L,
+/* 070 */ 0x19a56203666d4a9fL, 0x158ffab502c4be93L, 0x0bee714e332ecb2fL,
+/* */ 0x69b71a59f6f74ab0L, 0x0fc7fc622f1dfe8fL,
+/* 075 */ 0x513966de7152a6f9L, 0xc16fae9cc2ea9be7L, 0xb66f0ac586c1899eL,
+/* */ 0x11e124aee3bdefd7L, 0x86cf5a577512901bL,
+/* 080 */ 0x33f33ba6994a1fbdL, 0xde6c4d1d3d47ff0dL, 0x6a99220dc6f78e66L,
+/* */ 0x2dc06ca93e2d25d2L, 0x96413b520134d573L,
+/* 085 */ 0xb4715ce8e1023afaL, 0xe6a75900c8c66c0aL, 0x6448f13ad54c12edL,
+/* */ 0xb9057c28cf6689f0L, 0xf4023daf67f7677aL,
+/* 090 */ 0x877c2650767b9867L, 0xb7ea587dcd5b2341L, 0xc048cf111733f9bcL,
+/* */ 0x112012c15bc867bfL, 0xc95f52b1d9418811L,
+/* 095 */ 0xa47e624ee7499083L, 0x26928606df9b12e8L, 0x5d020462ec3e0928L,
+/* */ 0x8bbde651f6d08914L, 0xd5db83db758e524aL,
+/* 100 */ 0x3105e355c000f455L, 0xdd7fe1b81a786c79L, 0x1f3a818c8e012db1L,
+/* */ 0xd902de819d7b42faL, 0x4200e63325cda5f0L,
+/* 105 */ 0x0e919cdc5fba9220L, 0x5360dd54605a11e1L, 0xa3182d0e6cb23e6cL,
+/* */ 0x13ee462c1b483b87L, 0x1b1b6087b997ee22L,
+/* 110 */ 0x81c36d0b877f7362L, 0xc24879932c1768d4L, 0x1faa756e1673f9adL,
+/* */ 0x61651b24d11fe93dL, 0x30fe3d9304e1cde4L,
+/* 115 */ 0x7be867c750747250L, 0x973e52c7005b5db6L, 0x75d6b699bbaf4817L,
+/* */ 0x25d2a9e97379e196L, 0xe65fb599aca98701L,
+/* 120 */ 0x6ac27960d24bde84L, 0xdfacc04c9fabbcb6L, 0xa46cd07f4a97882bL,
+/* */ 0x652031d8e59a1fd8L, 0x1185bd967ec7ce10L,
+/* 125 */ 0xfc9bd84c6780f244L, 0x0a0c59872f61b3ffL, 0x63885727a1c71c95L,
+/* */ 0x5e88b4390b2d765cL, 0xf0005ccaf988514dL,
+/* 130 */ 0x474e44280a98e840L, 0x32de151c1411bc42L, 0x2c4b86d5aa4482c2L,
+/* */ 0xccd93deb2d9d47daL, 0x3743236ff128a622L,
+/* 135 */ 0x42ed2f2635ba5647L, 0x99c74afd18962dbdL, 0x2d663bb870f6d242L,
+/* */ 0x7912033bc7635d81L, 0xb442862f43753680L,
+/* 140 */ 0x94b1a5400aeaab4cL, 0x5ce285fe810f2220L, 0xe8a7dbe565d9c0b1L,
+/* */ 0x219131af78356c94L, 0x7b3a80d130f27e2fL,
+/* 145 */ 0xbaa5d2859d16b440L, 0x821cfb6935771070L, 0xf68cfb6ee9bc2336L,
+/* */ 0x18244132e935d2fdL, 0x2ed0bda1f4720cffL,
+/* 150 */ 0x4ed48cdf6975173cL, 0xfd37a7a2520e2405L, 0x82c102b2a9e73ce2L,
+/* */ 0xadac6517062623a7L, 0x5a1294d318e26104L,
+/* 155 */ 0xea84fe65c0e4f061L, 0x4f96f8a9464cfee9L, 0x9831dff8ccdc534aL,
+/* */ 0x4ca927cd0f192a14L, 0x030900b294b71649L,
+/* 160 */ 0x644b263b9aeb0675L, 0xa601d4e34647e040L, 0x34d897eb397f1004L,
+/* */ 0xa6101c37f4ec8dfcL, 0xc29d2a8bbfd0006bL,
+/* 165 */ 0xc6b07df8c5b4ed0fL, 0xce1b7d92ba6bccbeL, 0xfa2f99442e03fe1bL,
+/* */ 0xd8863e4c16f0b363L, 0x033b2cccc3392942L,
+/* 170 */ 0x757dc33522d6cf9cL, 0xf07b1ff6ce55fec5L, 0x1569e75f09b40463L,
+/* */ 0xfa33fa08f14a310bL, 0x6eb79aa27bbcf76bL,
+/* 175 */ 0x157061207c249602L, 0x25e5a71fc4e99555L, 0x5df1fe93de625355L,
+/* */ 0x235b56090c1aa55dL, 0xe51068613eaced91L,
+/* 180 */ 0x45bd47b893b9ff1eL, 0x6595e1798d381f2dL, 0xc9b5848cbcdb5ba8L,
+/* */ 0x65985146ff7792bcL, 0x4ab4a17bf05a19a0L,
+/* 185 */ 0xfd94f4ca560ffb0cL, 0xcf9bad581a68fa68L, 0x92b4f0b502b1ce1aL,
+/* */ 0xbcbec0769a610474L, 0x8dbd31ded1a0fecbL,
+/* 190 */ 0xdd1f5ed9f90e8533L, 0x61c1e6a523f84d95L, 0xf24475f383c110c4L,
+/* */ 0xdb2dffa66f90588dL, 0xac06d88e9ee04455L,
+/* 195 */ 0xa215fc47c40504baL, 0x86d7caebfee93369L, 0x9eaec31985804099L,
+/* */ 0x0fba2214abe5d01bL, 0x5a32975a4b3865d6L,
+/* 200 */ 0x8cceebc98a5c108fL, 0x7e12c4589654f2dcL, 0xa49ad49fb0d19772L,
+/* */ 0x3d142dd9c406152bL, 0x9f13589e7be2b8a5L,
+/* 205 */ 0x5e8dbac1892967adL, 0xcc23b93a6308e597L, 0x1ef35f5fe874e16aL,
+/* */ 0x63ae9cc08d2e274fL, 0x5bbabee56007fc05L,
+/* 210 */ 0xabfd72994230fc39L, 0x9d71a13a99144de1L, 0xd9daf5aa8dcc89b3L,
+/* */ 0xe145ec0514161bfdL, 0x143befc2498cd270L,
+/* 215 */ 0xa8e192557dbbd9f8L, 0xcbeda2445628d7d0L, 0x997f0a93205d9ea4L,
+/* */ 0x01014a97f214ebfaL, 0x70c026ffd1ebedafL,
+/* 220 */ 0xf8737b1b3237002fL, 0x8afcbef3147e6e5eL, 0x0e1bb0684483ebd3L,
+/* */ 0x4cbad70ae9b05aa6L, 0xd4a31f523517c363L,
+/* 225 */ 0xdb0f057ae8e9e8a2L, 0x400894a919d89df6L, 0x6a626a9b62defab3L,
+/* */ 0xf907fd7e14f4e201L, 0xe10e4a5657c48f3fL,
+/* 230 */ 0xb17f9f54b8e6e5dcL, 0x6b9e69045fa6d27aL, 0x8b74b6a41dc3078eL,
+/* */ 0x027954d45ca367f9L, 0xd07207b8fdcbb7ccL,
+/* 235 */ 0xf397c47d2f36414bL, 0x05e4e8b11d3a034fL, 0x36adb3f7122d654fL,
+/* */ 0x607d9540eb336078L, 0xb639118e3a8b9600L,
+/* 240 */ 0xd0a406770b5f1484L, 0x3cbee8213ccfb7c6L, 0x467967bb2ff89cf1L,
+/* */ 0xb115fe29609919a6L, 0xba740e6ffa83287eL,
+/* 245 */ 0xb4e51be9b694b7cdL, 0xc9a081c677df5aeaL, 0x2e1fbcd8944508ccL,
+/* */ 0xf626e7895581fbb8L, 0x3ce6e9b5728a05cbL,
+/* 250 */ 0x46e87f2664a31712L, 0x8c1dc526c2f6acfaL, 0x7b4826726e560b10L,
+/* */ 0x2966e0099d8d7ce1L, 0xbb0dd5240d2b2adeL, 0x0d527cc60bbaa936L
+};
+
+    /**
+     * This is buzhash the hash function on which most other Hash methods
+     * are built.
+     */
+    private static long buzhash (StringBuffer arg) {
+        /* Hash StringBuffer */
+        long h = initial_hash;
+        for ( int i=0; i<arg.length(); ++i )
+            h = (h<<1) ^ (h>>>63) ^
+                mix_master[ ( arg.charAt(i) ^ (arg.charAt(i)>>>8) ) & 0xff ];
+        return h;
+    }
+
+    /**
+     * This is buzhash the hash function on which most other Hash methods
+     * are built.
+     */
+    private static long buzhash (String arg) {
+        /* Hash StringBuffer */
+        long h = initial_hash;
+        for ( int i=0; i<arg.length(); ++i )
+            h = (h<<1) ^ (h>>>63) ^
+                mix_master[ ( arg.charAt(i) ^ (arg.charAt(i)>>>8) ) & 0xff ];
+        return h;
+    }
+
+    /**
+     * Hash a String.
+     *
+     * @param arg The String to be hashed
+     * @return The hash for the input.
+     */
+    public static long hash(String arg) {
+        // Make Hash from String
+        return buzhash( arg );
+    }
+
+    /**
+     * Hash a String.
+     *
+     * @param arg The String represented by the StringBuffer to be hashed
+     * @return The hash for the input.
+     */
+    public static long hash(StringBuffer arg) {
+        // Make Hash from StringBuffer
+        return buzhash( arg );
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/IOUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/IOUtils.java
new file mode 100644
index 0000000..1b11281
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/IOUtils.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Locale;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log.Hierarchy;
+
+/**
+ * A collection of <code>File</code>, <code>URL</code> and filename
+ * utility methods
+ *
+ * @version $Id$
+ */
+public class IOUtils {
+
+    // **********************
+    // Serialize Methods
+    // **********************
+
+    /**
+     * Dump a <code>String</code> to a text file.
+     *
+     * @param file The output file
+     * @param string The string to be dumped
+     * @exception IOException IO Error
+     * @deprecated To be removed in cocoon 2.3
+     */
+    public static void serializeString(File file, String string)
+    throws IOException {
+        serializeString(file, string, null);
+    }
+
+    /**
+     * Dump a <code>String</code> to a text file.
+     *
+     * @param file The output file
+     * @param string The string to be dumped
+     * @param encoding The encoding for the output file or null for default platform encoding
+     * @exception IOException IO Error
+     * @deprecated To be removed in cocoon 2.3
+     */
+    public static void serializeString(File file, String string, String encoding)
+    throws IOException {
+        final Writer fw =
+                (encoding == null)?
+                new FileWriter(file):
+                new OutputStreamWriter(new FileOutputStream(file), encoding);
+        try {
+            fw.write(string);
+            fw.flush();
+        } finally {
+            if (fw != null) fw.close();
+        }
+    }
+
+    /**
+     * Load a text file contents as a <code>String<code>.
+     * This method does not perform enconding conversions
+     *
+     * @param file The input file
+     * @return The file contents as a <code>String</code>
+     * @exception IOException IO Error
+     */
+    public static String deserializeString(File file)
+    throws IOException {
+        int len;
+        char[] chr = new char[4096];
+        final StringBuffer buffer = new StringBuffer();
+        final FileReader reader = new FileReader(file);
+        try {
+            while ((len = reader.read(chr)) > 0) {
+                buffer.append(chr, 0, len);
+            }
+        } finally {
+            if (reader != null) reader.close();
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * This method serializes an object to an output stream.
+     *
+     * @param file The output file
+     * @param object The object to be serialized
+     * @exception IOException IOError
+     * @deprecated To be removed in cocoon 2.3
+     */
+    public static void serializeObject(File file, Object object)
+    throws IOException {
+        FileOutputStream fos = new FileOutputStream(file);
+        try {
+            ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos));
+            oos.writeObject(object);
+            oos.flush();
+        } finally {
+            if (fos != null) fos.close();
+        }
+    }
+
+    /**
+     * This method deserializes an object from an input stream.
+     *
+     * @param file The input file
+     * @return The deserialized object
+     * @exception IOException IOError
+     * @deprecated To be removed in cocoon 2.3
+     */
+    public static Object deserializeObject(File file)
+    throws IOException, ClassNotFoundException {
+        FileInputStream fis = new FileInputStream(file);
+        Object object = null;
+        try {
+            ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(fis));
+            object = ois.readObject();
+        } finally {
+            if (fis != null) fis.close();
+        }
+        return object;
+    }
+
+  /**
+   * These are java keywords as specified at the following URL (sorted alphabetically).
+   * http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#229308
+   */
+  static final String keywords[] =
+  {
+      "abstract",  "boolean",     "break",    "byte",         "case",
+      "catch",     "char",        "class",    "const",        "continue",
+      "default",   "do",          "double",   "else",         "extends",
+      "final",     "finally",     "float",    "for",          "goto",
+      "if",        "implements",  "import",   "instanceof",   "int",
+      "interface", "long",        "native",   "new",          "package",
+      "private",   "protected",   "public",   "return",       "short",
+      "static",    "strictfp",    "super",    "switch",       "synchronized",
+      "this",      "throw",       "throws",   "transient",    "try",
+      "void",      "volatile",    "while"
+  };
+
+  /** Collator for comparing the strings */
+  static final Collator englishCollator = Collator.getInstance(Locale.ENGLISH);
+
+  /** Use this character as suffix */
+  static final char keywordSuffix = '_';
+
+  /**
+   * checks if the input string is a valid java keyword.
+   * @return boolean true/false
+   */
+  private static boolean isJavaKeyword(String keyword) {
+    return (Arrays.binarySearch(keywords, keyword, englishCollator) >= 0);
+  }
+
+  // **********************
+  // File Methods
+  // **********************
+
+  /**
+   * Return a modified filename suitable for replicating directory
+   * structures below the store's base directory. The following
+   * conversions are performed:
+   * <ul>
+   * <li>Path separators are converted to regular directory names</li>
+   * <li>File path components are transliterated to make them valid (?)
+   *     programming language identifiers. This transformation may well
+   *     generate collisions for unusual filenames.</li>
+   * </ul>
+   * @return The transformed filename
+   */
+  public static String normalizedFilename(String filename) {
+    if ("".equals(filename)) {
+        return "";
+    }
+    filename = (File.separatorChar == '\\') ? filename.replace('/','\\') : filename.replace('\\','/');
+    String[] path = StringUtils.split(filename, File.separator);
+    int start = (path[0].length() == 0) ? 1 : 0;
+
+    StringBuffer buffer = new StringBuffer();
+    for (int i = start; i < path.length; i++) {
+
+      if (i > start) {
+        buffer.append(File.separator);
+      }
+
+      if (path[i].equals("..")) {
+        int lio;
+        for (lio = buffer.length() - 2; lio >= 0; lio--) {
+          if (buffer.substring(lio).startsWith(File.separator)) {
+            break;
+          }
+        }
+        if (lio >= 0) {
+          buffer.setLength(lio);
+        }
+      } else {
+        char[] chars = path[i].toCharArray();
+
+        if (chars.length < 1 || !Character.isLetter(chars[0])) {
+          buffer.append('_');
+        }
+
+        for (int j = 0; j < chars.length; j++) {
+          if (org.apache.cocoon.util.StringUtils.isAlphaNumeric(chars[j])) {
+            buffer.append(chars[j]);
+          } else {
+            buffer.append('_');
+          }
+        }
+
+        // Append the suffix if necessary.
+        if(isJavaKeyword(path[i]))
+          buffer.append(keywordSuffix);
+      }
+
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Remove file information from a filename returning only its path
+   * component
+   *
+   * @param filename The filename
+   * @return The path information
+   * @deprecated To be removed in cocoon 2.3
+   */
+  public static String pathComponent(String filename) {
+    int i = filename.lastIndexOf(File.separator);
+    return (i > -1) ? filename.substring(0, i) : filename;
+  }
+
+  /**
+   * Remove path information from a filename returning only its file
+   * component
+   *
+   * @param filename The filename
+   * @return The filename sans path information
+   * @deprecated To be removed in cocoon 2.3
+   */
+  public static String fileComponent(String filename) {
+    int i = filename.lastIndexOf(File.separator);
+    return (i > -1) ? filename.substring(i + 1) : filename;
+  }
+
+  /**
+   * Strip a filename of its <i>last</i> extension (the portion
+   * immediately following the last dot character, if any)
+   *
+   * @param filename The filename
+   * @return The filename sans extension
+   * @deprecated To be removed in cocoon 2.3
+   */
+  public static String baseName(String filename) {
+    int i = filename.lastIndexOf('.');
+    return (i > -1) ? filename.substring(0, i) : filename;
+  }
+
+  /**
+   * Get the complete filename corresponding to a (typically relative)
+   * <code>File</code>.
+   * This method accounts for the possibility of an error in getting
+   * the filename's <i>canonical</i> path, returning the io/error-safe
+   * <i>absolute</i> form instead
+   *
+   * @param file The file
+   * @return The file's absolute filename
+   */
+  public static String getFullFilename(File file) {
+    try {
+      return file.getCanonicalPath();
+    } catch (Exception e) {
+      Hierarchy.getDefaultHierarchy().getLoggerFor("cocoon").debug("IOUtils.getFullFilename", e);
+      return file.getAbsolutePath();
+    }
+  }
+
+  /**
+   * Return the path within a base directory
+   */
+  public static String getContextFilePath(String directoryPath, String filePath) {
+      try
+      {
+          File directory = new File(directoryPath);
+          File file = new File(filePath);
+
+          directoryPath = directory.getCanonicalPath();
+          filePath = file.getCanonicalPath();
+
+          // If the context directory does not have a File.separator
+          // at the end then add one explicitly
+          if(!directoryPath.endsWith(File.separator)){
+            directoryPath += File.separator;
+          }
+
+          // If the context dir contains both kinds of separator
+          // then standardize on using the File.separator
+          if ((directoryPath.indexOf('/') !=-1) && (directoryPath.indexOf('\\') !=-1)) {
+            directoryPath = directoryPath.replace('\\', File.separator.charAt(0));
+            directoryPath = directoryPath.replace('/', File.separator.charAt(0));
+          }
+
+          // If the file path contains both kinds of separator
+          // then standardize on using the File.separator
+          if ((filePath.indexOf('/') !=-1) && (filePath.indexOf('\\') !=-1)) {
+            filePath = filePath.replace('\\', File.separator.charAt(0));
+            filePath = filePath.replace('/', File.separator.charAt(0));
+          }
+
+          if (filePath.startsWith(directoryPath)) {
+              filePath = filePath.substring(directoryPath.length());
+          }
+      } catch (Exception e){
+          Hierarchy.getDefaultHierarchy().getLoggerFor("cocoon").debug("IOUtils.getContextFilePath", e);
+      }
+
+      return filePath;
+  }
+
+  /**
+   * Return a file with the given filename creating the necessary
+   * directories if not present.
+   *
+   * @param filename The file
+   * @return The created File instance
+   */
+  public static File createFile(File destDir, String filename) {
+    File file = new File(destDir, filename);
+    File parent = file.getParentFile();
+    if (parent != null) parent.mkdirs();
+    return file;
+  }
+
+  /**
+   * Returns a byte array from the given object.
+   *
+   * @param object to convert
+   * @return byte array from the object
+   * @deprecated To be removed in cocoon 2.3
+   */
+  public static byte[] objectToBytes(Object object) throws IOException {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ObjectOutputStream os = new ObjectOutputStream(baos);
+    os.writeObject(object);
+    return baos.toByteArray();
+  }
+
+  /**
+   * Returns a object from the given byte array.
+   *
+   * @param bytes array to convert
+   * @return object
+   * @deprecated To be removed in cocoon 2.3
+   */
+  public static Object bytesToObject(byte[] bytes) throws IOException, ClassNotFoundException {
+    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+    ObjectInputStream is = new ObjectInputStream(bais);
+    return is.readObject();
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageProperties.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageProperties.java
new file mode 100644
index 0000000..ea0b979
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageProperties.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+/**
+ * @version $Id$
+ */
+final public class ImageProperties {
+    final public int width;
+    final public int height;
+    final public char[] comment;
+    final public String type;
+
+    public ImageProperties(int width, int height, char[] comment, String type) {
+        this.width = width;
+        this.height = height;
+        this.comment = comment;
+        this.type = type;
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(type).append(" ").append(width).append("x").append(height);
+        if (comment != null) {
+            sb.append(" (").append(comment).append(")");
+        }
+        return (sb.toString());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageUtils.java
new file mode 100644
index 0000000..111ffd7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ImageUtils.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+
+/**
+ * @version $Id$
+ */
+final public class ImageUtils {
+
+    final public static ImageProperties getImageProperties(File file) throws FileNotFoundException, IOException, FileFormatException {
+        String type = MIMEUtils.getMIMEType(file);
+
+        if ("image/gif".equals(type)) {
+             return (getGifProperties(file));
+        }
+        else if ("image/jpeg".equals(type)) {
+            return (getJpegProperties(file));
+        }
+        else {
+            return (null);
+        }
+    }
+
+    final public static ImageProperties getJpegProperties(File file) throws FileNotFoundException, IOException, FileFormatException {
+        BufferedInputStream in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(file));
+
+            // check for "magic" header
+            byte[] buf = new byte[2];
+            int count = in.read(buf, 0, 2);
+            if (count < 2) {
+                throw new FileFormatException("Not a valid Jpeg file!");
+            }
+            if ((buf[0]) != (byte) 0xFF || (buf[1]) != (byte) 0xD8) {
+                throw new FileFormatException("Not a valid Jpeg file!");
+            }
+
+            int width = 0;
+            int height = 0;
+            char[] comment = null;
+
+            boolean hasDims = false;
+            boolean hasComment = false;
+            int ch = 0;
+
+            while (ch != 0xDA && !(hasDims && hasComment)) {
+                /* Find next marker (JPEG markers begin with 0xFF) */
+                while (ch != 0xFF) {
+                    ch = in.read();
+                }
+                /* JPEG markers can be padded with unlimited 0xFF's */
+                while (ch == 0xFF) {
+                    ch = in.read();
+                }
+                /* Now, ch contains the value of the marker. */
+
+                int length = 256 * in.read();
+                length += in.read();
+                if (length < 2) {
+                    throw new FileFormatException("Not a valid Jpeg file!");
+                }
+                /* Now, length contains the length of the marker. */
+
+                if (ch >= 0xC0 && ch <= 0xC3) {
+                    in.read();
+                    height = 256 * in.read();
+                    height += in.read();
+                    width = 256 * in.read();
+                    width += in.read();
+                    for (int foo = 0; foo < length - 2 - 5; foo++) {
+                        in.read();
+                    }
+                    hasDims = true;
+                }
+                else if (ch == 0xFE) {
+                    // that's the comment marker
+                    comment = new char[length-2];
+                    for (int foo = 0; foo < length - 2; foo++)
+                        comment[foo] = (char) in.read();
+                    hasComment = true;
+                }
+                else {
+                    // just skip marker
+                    for (int foo = 0; foo < length - 2; foo++) {
+                        in.read();
+                    }
+                }
+            }
+            return (new ImageProperties(width, height, comment, "jpeg"));
+
+        }
+        finally {
+            if (in != null) {
+                try {
+                    in.close();
+                }
+                catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    final public static ImageProperties getGifProperties(File file) throws FileNotFoundException, IOException, FileFormatException {
+        BufferedInputStream in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(file));
+            byte[] buf = new byte[10];
+            int count = in.read(buf, 0, 10);
+            if (count < 10) {
+                throw new FileFormatException("Not a valid Gif file!");
+            }
+            if ((buf[0]) != (byte) 'G' || (buf[1]) != (byte) 'I' || (buf[2]) != (byte) 'F') {
+                throw new FileFormatException("Not a valid Gif file!");
+            }
+
+            int w1 = (buf[6] & 0xff) | (buf[6] & 0x80);
+            int w2 = (buf[7] & 0xff) | (buf[7] & 0x80);
+            int h1 = (buf[8] & 0xff) | (buf[8] & 0x80);
+            int h2 = (buf[9] & 0xff) | (buf[9] & 0x80);
+
+            int width = w1 + (w2 << 8);
+            int height = h1 + (h2 << 8);
+
+            return (new ImageProperties(width, height, null,"gif"));
+
+        }
+        finally {
+            if (in != null) {
+                try {
+                    in.close();
+                }
+                catch (IOException e) {
+                }
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/JMXUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/JMXUtils.java
new file mode 100644
index 0000000..ed907bb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/JMXUtils.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation
+ * Licensed  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.cocoon.util;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.components.ComponentInfo;
+
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+
+/**
+ * Utility methods for JMX
+ *
+ * @version $Id$
+ * 
+ * @since 2.2
+ */
+public class JMXUtils {
+    //~ Static fields/initializers ----------------------------------------------------------------------
+
+    /** The {@link MBeanServer} first found */
+    private static MBeanServer mbeanServer = getInitialMBeanServer();
+
+    //~ Constructors ------------------------------------------------------------------------------------
+
+    /**
+     * Private c'tor: its a Utility class
+     */
+    private JMXUtils() {
+        super();
+    }
+
+    //~ Methods -----------------------------------------------------------------------------------------
+
+    /**
+     * Find a JMX domain name at various places
+     *
+     * @param pJmxDomain Default JMX domain name
+     * @param serviceManager The ServiceManager used
+     *
+     * @return The JMX domain name
+     */
+    public static String findJmxDomain(final String pJmxDomain,
+                                       final ServiceManager serviceManager) {
+        // try to find a JMX domain name first from this component configuration give as parameter
+        String jmxDomain = pJmxDomain;
+
+        if(jmxDomain == null) {
+            // next from the CoreServiceManager managing this component
+            if((serviceManager != null) && serviceManager instanceof CoreServiceManager) {
+                // next from the CoreServiceManager managing this component
+                jmxDomain = ((CoreServiceManager)serviceManager).getJmxDefaultDomain();
+            } else {
+                // otherwise use default one
+                jmxDomain = CoreServiceManager.JMX_DEFAULT_DOMAIN_NAME;
+            }
+        }
+
+        return jmxDomain;
+    }
+
+    /**
+     * Find or construct a JMX object name at various places (excluding the JMX domain)
+     *
+     * @param pJmxName Default JMX object name
+     * @param pClassName Class name to use if JMX object name has to be constructed
+     *
+     * @return The JMX obejct name (excluding the JMX domain name
+     */
+    public static String findJmxName(final String pJmxName,
+                                     final String pClassName) {
+        String jmxName = pJmxName;
+        final String className = ((pClassName == null) ? "unknown" : pClassName);
+
+        if(jmxName == null) {
+            // otherwise construct one from the service class name
+            final StringBuffer sb = new StringBuffer();
+            final List groups = new ArrayList();
+            int i = className.indexOf('.');
+            int j = 0;
+
+            while(i > 0) {
+                groups.add(className.substring(j, i));
+                j = i + 1;
+                i = className.indexOf('.', i + 1);
+            }
+
+            groups.add(className.substring(j));
+
+            for(i = 0; i < (groups.size() - 1); i++) {
+                sb.append("group");
+
+                if(i > 0) {
+                    sb.append(i);
+                }
+
+                sb.append('=');
+                sb.append(groups.get(i));
+                sb.append(',');
+            }
+
+            sb.append("item=").append(groups.get(groups.size() - 1));
+            jmxName = sb.toString();
+        }
+
+        return jmxName;
+    }
+
+    /**
+     * generate a default JMX object name (excluding JMX domain name) from a FQCN
+     *
+     * @param clazz The class name
+     *
+     * @return The generated JMX object name (excluding JMX domain name)
+     */
+    public static String genDefaultJmxName(final Class clazz) {
+        return genDefaultJmxName(clazz.getName());
+    }
+
+    /**
+     * generate a default JMX object name (excluding JMX domain name) from a FQCN
+     *
+     * @param className The class name
+     *
+     * @return The generated JMX object name (excluding JMX domain name)
+     */
+    public static String genDefaultJmxName(final String className) {
+        final StringBuffer nameBuf = new StringBuffer();
+        final List groups = new ArrayList();
+        int i = className.indexOf('.');
+        int j = 0;
+
+        while(i > 0) {
+            groups.add(className.substring(j, i));
+            j = i + 1;
+            i = className.indexOf('.', i + 1);
+        }
+
+        groups.add(className.substring(j));
+
+        for(i = 0; i < (groups.size() - 1); i++) {
+            nameBuf.append("group");
+
+            if(i > 0) {
+                nameBuf.append(i);
+            }
+
+            nameBuf.append('=');
+            nameBuf.append(groups.get(i));
+            nameBuf.append(',');
+        }
+
+        nameBuf.append("item=").append(groups.get(groups.size() - 1));
+
+        return nameBuf.toString();
+    }
+
+    /**
+     * Get the ev. found {@link MBeanServer}
+     *
+     * @return DOCUMENT ME!
+     */
+    public static MBeanServer getMBeanServer() {
+        return JMXUtils.mbeanServer;
+    }
+
+    /**
+     * Setup a component for possible JMX managability
+     *
+     * @param bean The bean to estabilsh JMX for
+     * @param info The component info
+     *
+     * @return DOCUMENT ME!
+     */
+    public static ObjectInstance setupJmxFor(final Object bean,
+                                             final ComponentInfo info) {
+        return setupJmxFor(bean, info, new ConsoleLogger(ConsoleLogger.LEVEL_INFO));
+    }
+
+    /**
+     * Setup a component for possible JMX managability
+     *
+     * @param bean The bean to estabilsh JMX for
+     * @param info The component info
+     * @param logger The Logger
+     */
+    public static ObjectInstance setupJmxFor(final Object bean,
+                                             final ComponentInfo info,
+                                             final Logger logger) {
+        if(getMBeanServer() != null) {
+            final Class beanClass = bean.getClass();
+            final String beanClassName = beanClass.getName();
+            final String mbeanClassName = beanClassName + "MBean";
+            ObjectName on = null;
+
+            try {
+                // try to find a MBean for bean
+                final Class mbeanClass = beanClass.getClassLoader().loadClass(mbeanClassName);
+                Constructor ctor = null;
+                Object mbean = null;
+
+                try {
+                    ctor = mbeanClass.getConstructor(new Class[] {beanClass, ComponentInfo.class});
+                    mbean = ctor.newInstance(new Object[] {bean, info});
+                } catch(final Exception e) {
+                    // ignore this
+                }
+
+                if(ctor == null) {
+                    ctor = mbeanClass.getConstructor(new Class[] {beanClass});
+                    mbean = ctor.newInstance(new Object[] {bean});
+                }
+
+                // see if MBean supplies some JMX ObjectName parts
+                final String mBeanSuppliedJmxDomain = callGetter(mbean, "getJmxDomain", logger);
+                final String mBeanSuppliedJmxName = callGetter(mbean, "getJmxName", logger);
+                final String mBeanSuppliedJmxNameAdditions =
+                    callGetter(mbean, "getJmxNameAddition", logger);
+
+                // construct a JMX ObjectName instance
+                final StringBuffer objectNameBuf = new StringBuffer();
+
+                if(mBeanSuppliedJmxDomain != null) {
+                    objectNameBuf.append(mBeanSuppliedJmxDomain);
+                } else {
+                    objectNameBuf.append(info.getJmxDomain());
+                }
+
+                objectNameBuf.append(':');
+
+                if(mBeanSuppliedJmxName != null) {
+                    objectNameBuf.append(mBeanSuppliedJmxName);
+                } else if(info.getConfiguration()
+                              .getAttribute(CoreServiceManager.JMX_NAME_ATTR_NAME, null) != null) {
+                    objectNameBuf.append(info.getConfiguration()
+                                             .getAttribute(CoreServiceManager.JMX_NAME_ATTR_NAME, null));
+                } else {
+                    // if we do not have the name parts we'll construct one from the bean class name           
+                    objectNameBuf.append(genDefaultJmxName(beanClass));
+                }
+
+                if(mBeanSuppliedJmxNameAdditions != null) {
+                    objectNameBuf.append(',');
+                    objectNameBuf.append(mBeanSuppliedJmxNameAdditions);
+                }
+
+                on = new ObjectName(objectNameBuf.toString());
+
+                int instance = 1;
+
+                while(mbeanServer.isRegistered(on)) {
+                    instance++;
+                    on = new ObjectName(objectNameBuf.toString() + ",instance=" + instance);
+                }
+
+                return mbeanServer.registerMBean(mbean, on);
+            } catch(final ClassNotFoundException cnfe) {
+                // happens if a component doesn't have a MBean to support it for management
+                if(logger.isDebugEnabled()) {
+                    logger.debug("Class " + beanClass.getName() +
+                                 " doesn't have a supporting MBean called " + mbeanClassName);
+                }
+            } catch(final NoSuchMethodException nsme) {
+                logger.warn("MBean " + mbeanClassName +
+                            " doesn't have a constructor that accepts an instance of " +
+                            info.getServiceClassName(), nsme);
+            } catch(final InvocationTargetException ite) {
+                logger.warn("Cannot invoke constructor on class " + mbeanClassName, ite);
+            } catch(final InstantiationException ie) {
+                logger.warn("Cannot instantiate class " + mbeanClassName, ie);
+            } catch(final IllegalAccessException iae) {
+                logger.warn("Cannot access class " + mbeanClassName, iae);
+            } catch(final MalformedObjectNameException mone) {
+                logger.warn("Invalid ObjectName '" + on + "' for MBean " + mbeanClassName, mone);
+            } catch(final InstanceAlreadyExistsException iaee) {
+                logger.warn("Instance for MBean " + mbeanClassName + "already exists", iaee);
+            } catch(final NotCompliantMBeanException ncme) {
+                logger.warn("Not compliant MBean " + mbeanClassName, ncme);
+            } catch(final MBeanRegistrationException mre) {
+                logger.warn("Cannot register MBean " + mbeanClassName, mre);
+            } catch(final SecurityException se) {
+                logger.warn("Instantiation of MBean " + mbeanClassName +
+                            " is prevented by a SecurityManager", se);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Call a getter method on a bean
+     *
+     * @param mbean The bean to call a method from
+     * @param name The name of the method to call
+     * @param logger Logger for diagnostic messages
+     *
+     * @return DOCUMENT ME!
+     */
+    private static String callGetter(final Object mbean,
+                                     final String name,
+                                     final Logger logger) {
+        final Method[] methods = mbean.getClass().getMethods();
+
+        for(int i = 0; i < methods.length; i++) {
+            if(methods[i].getName().equals(name)) {
+                try {
+                    return methods[i].invoke(mbean, null).toString();
+                } catch(final Exception e) {
+                    logger.warn("Method '" + name + "' cannot be accessed on MBean " +
+                                mbean.getClass().getName());
+
+                    return null;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Try to find a JMX Agent (MBeanServer)
+     *
+     * @return The first MBeanServer found or null
+     */
+    private static MBeanServer getInitialMBeanServer() {
+        final List servers = MBeanServerFactory.findMBeanServer(null);
+
+        if(servers.size() > 0) {
+            return (MBeanServer)servers.get(0);
+        }
+
+        return null;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/MIMEUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/MIMEUtils.java
new file mode 100644
index 0000000..ca37e24
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/MIMEUtils.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * A collection of <code>File</code>, <code>URL</code> and filename
+ * utility methods.
+ *
+ * @version $Id$
+ */
+public class MIMEUtils {
+
+    private static final String MIME_MAPPING_FILE = "org/apache/cocoon/util/mime.types";
+
+    /** Default extensions for MIME types. */
+    final private static Map extMap = new HashMap();
+    /** MIME types for extensions. */
+    final private static Map mimeMap = new HashMap();
+
+    /**
+     * Load the MIME type mapping
+     */
+    static {
+        try {
+            final InputStream is = MIMEUtils.class.getClassLoader().getResourceAsStream(MIME_MAPPING_FILE);
+            if (null == is) {
+                throw new RuntimeException("Cocoon cannot load MIME type mappings from " + MIME_MAPPING_FILE);
+            }
+            loadMimeTypes(new InputStreamReader(is), extMap, mimeMap);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Cocoon cannot load MIME type mappings from " + MIME_MAPPING_FILE);
+        }
+    }
+
+    /**
+     * Return the MIME type for a given file.
+     *
+     * @param file File.
+     * @return MIME type.
+     */
+    public static String getMIMEType(final File file)
+            throws FileNotFoundException, IOException {
+        BufferedInputStream in = null;
+
+        try {
+            in = new BufferedInputStream(new FileInputStream(file));
+            byte[] buf = new byte[3];
+            int count = in.read(buf, 0, 3);
+
+            if (count < 3) {
+                return (null);
+            }
+
+            if ((buf[0]) == (byte)'G' && (buf[1]) == (byte)'I' && (buf[2]) == (byte)'F') {
+                return ("image/gif");
+            }
+
+            if ((buf[0]) == (byte)0xFF && (buf[1]) == (byte)0xD8) {
+                return ("image/jpeg");
+            }
+
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        final String name = file.getName();
+        int index = name.lastIndexOf(".");
+        String fileExt = ".";
+        if (index != -1) {
+            fileExt = name.substring(index);
+        }
+        return getMIMEType(fileExt);
+    }
+
+    /**
+     * Return the MIME type for a given filename extension.
+     *
+     * @param ext Filename extension.
+     *
+     * @return MIME type.
+     */
+    public static String getMIMEType(final String ext) {
+        return (String)mimeMap.get(ext);
+    }
+
+    /**
+     * Return the default filename extension for a given MIME type.
+     *
+     * @param type MIME type.
+     *
+     * @return Filename extension.
+     */
+    public static String getDefaultExtension(final String type) {
+        return (String)extMap.get(type);
+    }
+
+    /**
+     * Parses a <code>mime.types</code> file, and generates mappings between
+     * MIME types and extensions.
+     * For example, if a line contains:
+     * <pre>text/html   html htm</pre>
+     * Then 'html' will be the default extension for text/html, and both 'html'
+     * and 'htm' will have MIME type 'text/html'.
+     * Lines starting with '#' are treated as comments and ignored.  If an
+     * extension is listed for two MIME types, the first will be chosen.
+     *
+     * @param in Reader of bytes from <code>mime.types</code> file content
+     * @param extMap Empty map of default extensions, keyed by MIME type. Will
+     * be filled in by this method.
+     * @param mimeMap Empty map of MIME types, keyed by extension.  Will be
+     * filled in by this method.
+     */
+    public static void loadMimeTypes(Reader in, Map extMap, Map mimeMap) throws IOException {
+        BufferedReader br = new BufferedReader(in);
+        String line;
+        while ((line = br.readLine()) != null) {
+            if (line.startsWith("#")) {
+                continue;
+            }
+            if (line.trim().equals("")) {
+                continue;
+            }
+            StringTokenizer tok = new StringTokenizer(line, " \t");
+            String mimeType = tok.nextToken();
+            if (tok.hasMoreTokens()) {
+                String defaultExt = tok.nextToken();
+                if (!extMap.containsKey(mimeType)) {
+                    extMap.put(mimeType, "." + defaultExt);
+                }
+                if (!mimeMap.containsKey("." + defaultExt)) {
+                    mimeMap.put("." + defaultExt, mimeType);
+                }
+                while (tok.hasMoreTokens()) {
+                    String ext = tok.nextToken();
+                    if (!mimeMap.containsKey("." + ext)) {
+                        mimeMap.put("." + ext, mimeType);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NetUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NetUtils.java
new file mode 100644
index 0000000..33c460d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NetUtils.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import org.apache.cocoon.environment.Request;
+import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.SourceParameters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.BitSet;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * A collection of <code>File</code>, <code>URL</code> and filename
+ * utility methods
+ *
+ * @version $Id$
+ */
+public class NetUtils {
+
+    /**
+     * Array containing the safe characters set as defined by RFC 1738
+     */
+    private static BitSet safeCharacters;
+
+    private static final char[] hexadecimal =
+    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+     'A', 'B', 'C', 'D', 'E', 'F'};
+
+    static {
+        safeCharacters = new BitSet(256);
+        int i;
+        // 'lowalpha' rule
+        for (i = 'a'; i <= 'z'; i++) {
+            safeCharacters.set(i);
+        }
+        // 'hialpha' rule
+        for (i = 'A'; i <= 'Z'; i++) {
+            safeCharacters.set(i);
+        }
+        // 'digit' rule
+        for (i = '0'; i <= '9'; i++) {
+            safeCharacters.set(i);
+        }
+
+        // 'safe' rule
+        safeCharacters.set('$');
+        safeCharacters.set('-');
+        safeCharacters.set('_');
+        safeCharacters.set('.');
+        safeCharacters.set('+');
+
+        // 'extra' rule
+        safeCharacters.set('!');
+        safeCharacters.set('*');
+        safeCharacters.set('\'');
+        safeCharacters.set('(');
+        safeCharacters.set(')');
+        safeCharacters.set(',');
+
+        // special characters common to http: file: and ftp: URLs ('fsegment' and 'hsegment' rules)
+        safeCharacters.set('/');
+        safeCharacters.set(':');
+        safeCharacters.set('@');
+        safeCharacters.set('&');
+        safeCharacters.set('=');
+    }
+
+    /**
+     * Decode a path.
+     *
+     * <p>Interprets %XX (where XX is hexadecimal number) as UTF-8 encoded bytes.
+     * <p>The validity of the input path is not checked (i.e. characters that were not encoded will
+     * not be reported as errors).
+     * <p>This method differs from URLDecoder.decode in that it always uses UTF-8 (while URLDecoder
+     * uses the platform default encoding, often ISO-8859-1), and doesn't translate + characters to spaces.
+     *
+     * @param path the path to decode
+     * @return the decoded path
+     */
+    public static String decodePath(String path) {
+        StringBuffer translatedPath = new StringBuffer(path.length());
+        byte[] encodedchars = new byte[path.length() / 3];
+        int i = 0;
+        int length = path.length();
+        int encodedcharsLength = 0;
+        while (i < length) {
+            if (path.charAt(i) == '%') {
+                // we must process all consecutive %-encoded characters in one go, because they represent
+                // an UTF-8 encoded string, and in UTF-8 one character can be encoded as multiple bytes
+                while (i < length && path.charAt(i) == '%') {
+                    if (i + 2 < length) {
+                        try {
+                            byte x = (byte)Integer.parseInt(path.substring(i + 1, i + 3), 16);
+                            encodedchars[encodedcharsLength] = x;
+                        } catch (NumberFormatException e) {
+                            throw new IllegalArgumentException("NetUtils.decodePath: " +
+                                                               "Illegal hex characters in pattern %" + path.substring(i + 1, i + 3));
+                        }
+                        encodedcharsLength++;
+                        i += 3;
+                    } else {
+                        throw new IllegalArgumentException("NetUtils.decodePath: " +
+                                                           "% character should be followed by 2 hexadecimal characters.");
+                    }
+                }
+                try {
+                    String translatedPart = new String(encodedchars, 0, encodedcharsLength, "UTF-8");
+                    translatedPath.append(translatedPart);
+                } catch (UnsupportedEncodingException e) {
+                    // the situation that UTF-8 is not supported is quite theoretical, so throw a runtime exception
+                    throw new RuntimeException("Problem in decodePath: UTF-8 encoding not supported.");
+                }
+                encodedcharsLength = 0;
+            } else {
+                // a normal character
+                translatedPath.append(path.charAt(i));
+                i++;
+            }
+        }
+        return translatedPath.toString();
+    }
+
+    /**
+     * Encode a path as required by the URL specification (<a href="http://www.ietf.org/rfc/rfc1738.txt">
+     * RFC 1738</a>). This differs from <code>java.net.URLEncoder.encode()</code> which encodes according
+     * to the <code>x-www-form-urlencoded</code> MIME format.
+     *
+     * @param path the path to encode
+     * @return the encoded path
+     */
+    public static String encodePath(String path) {
+       // stolen from org.apache.catalina.servlets.DefaultServlet ;)
+
+        /**
+         * Note: This code portion is very similar to URLEncoder.encode.
+         * Unfortunately, there is no way to specify to the URLEncoder which
+         * characters should be encoded. Here, ' ' should be encoded as "%20"
+         * and '/' shouldn't be encoded.
+         */
+
+        int maxBytesPerChar = 10;
+        StringBuffer rewrittenPath = new StringBuffer(path.length());
+        ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
+        OutputStreamWriter writer = null;
+        try {
+            writer = new OutputStreamWriter(buf, "UTF8");
+        } catch (Exception e) {
+            e.printStackTrace();
+            writer = new OutputStreamWriter(buf);
+        }
+
+        for (int i = 0; i < path.length(); i++) {
+            int c = path.charAt(i);
+            if (safeCharacters.get(c)) {
+                rewrittenPath.append((char)c);
+            } else {
+                // convert to external encoding before hex conversion
+                try {
+                    writer.write(c);
+                    writer.flush();
+                } catch(IOException e) {
+                    buf.reset();
+                    continue;
+                }
+                byte[] ba = buf.toByteArray();
+                for (int j = 0; j < ba.length; j++) {
+                    // Converting each byte in the buffer
+                    byte toEncode = ba[j];
+                    rewrittenPath.append('%');
+                    int low = (toEncode & 0x0f);
+                    int high = ((toEncode & 0xf0) >> 4);
+                    rewrittenPath.append(hexadecimal[high]);
+                    rewrittenPath.append(hexadecimal[low]);
+                }
+                buf.reset();
+            }
+        }
+        return rewrittenPath.toString();
+    }
+
+    /**
+     * Returns the path of the given resource.
+     *
+     * @param uri The URI of the resource
+     * @return the resource path
+     */
+    public static String getPath(String uri) {
+        int i = uri.lastIndexOf('/');
+        if (i > -1) {
+            return uri.substring(0, i);
+        }
+        i = uri.indexOf(':');
+        return (i > -1) ? uri.substring(i + 1, uri.length()) : "";
+    }
+
+    /**
+     * Remove path and file information from a filename returning only its
+     * extension  component
+     *
+     * @param uri The filename
+     * @return The filename extension (with starting dot!) or null if filename extension is not found
+     */
+    public static String getExtension(String uri) {
+        int dot = uri.lastIndexOf('.');
+        if (dot > -1) {
+            uri = uri.substring(dot);
+            int slash = uri.lastIndexOf('/');
+            if (slash > -1) {
+                return null;
+            } else {
+                int sharp = uri.lastIndexOf('#');
+                if (sharp > -1) {
+                    // uri starts with dot already
+                    return uri.substring(0, sharp);
+                } else {
+                    int mark = uri.lastIndexOf('?');
+                    if (mark > -1) {
+                        // uri starts with dot already
+                        return uri.substring(0, mark);
+                    } else {
+                        return uri;
+                    }
+                }
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Absolutize a relative resource path on the given absolute base path.
+     *
+     * @param path The absolute base path
+     * @param resource The relative resource path
+     * @return The absolutized resource path
+     */
+    public static String absolutize(String path, String resource) {
+        if (StringUtils.isEmpty(path)) {
+            return resource;
+        } else if (StringUtils.isEmpty(resource)) {
+            return path;
+        } else if (resource.charAt(0) == '/') {
+            // Resource path is already absolute
+            return resource;
+        }
+
+        boolean slash = (path.charAt(path.length() - 1) == '/');
+        
+        StringBuffer b = new StringBuffer(path.length() + 1 + resource.length());
+        b.append(path);
+        if (!slash) {
+            b.append('/');
+        } 
+        b.append(resource);
+        return b.toString();
+    }
+
+    /**
+     * Relativize an absolute resource on a given absolute path.
+     *
+     * @param path The absolute path
+     * @param absoluteResource The absolute resource
+     * @return the resource relative to the given path
+     */
+    public static String relativize(String path, String absoluteResource) {
+        if (StringUtils.isEmpty(path)) {
+            return absoluteResource;
+        }
+
+        if (path.charAt(path.length() - 1) != '/') {
+            path += "/";
+        }
+
+        if (absoluteResource.startsWith(path)) {
+            // resource is direct descentant
+            return absoluteResource.substring(path.length());
+        } else {
+            // resource is not direct descendant
+            int index = StringUtils.indexOfDifference(path, absoluteResource);
+            if (index > 0 && path.charAt(index-1) != '/') {
+                index = path.substring(0, index).lastIndexOf('/');
+                index++;
+            }
+            String pathDiff = path.substring(index);
+            String resource = absoluteResource.substring(index);
+            int levels = StringUtils.countMatches(pathDiff, "/");
+            StringBuffer b = new StringBuffer(levels * 3 + resource.length());
+            for (int i = 0; i < levels; i++) {
+                b.append("../");
+            }
+            b.append(resource);
+            return b.toString();
+        }
+    }
+
+    /**
+     * Normalize a uri containing ../ and ./ paths.
+     *
+     * @param uri The uri path to normalize
+     * @return The normalized uri
+     */
+    public static String normalize(String uri) {
+        if ("".equals(uri)) {
+            return uri;
+        }
+        int leadingSlashes = 0;
+        for (leadingSlashes = 0 ; leadingSlashes < uri.length()
+                && uri.charAt(leadingSlashes) == '/' ; ++leadingSlashes) {}
+        boolean isDir = (uri.charAt(uri.length() - 1) == '/');
+        StringTokenizer st = new StringTokenizer(uri, "/");
+        LinkedList clean = new LinkedList();
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if ("..".equals(token)) {
+                if (! clean.isEmpty() && ! "..".equals(clean.getLast())) {
+                    clean.removeLast();
+                    if (! st.hasMoreTokens()) {
+                        isDir = true;
+                    }
+                } else {
+                    clean.add("..");
+                }
+            } else if (! ".".equals(token) && ! "".equals(token)) {
+                clean.add(token);
+            }
+        }
+        StringBuffer sb = new StringBuffer();
+        while (leadingSlashes-- > 0) {
+            sb.append('/');
+        }
+        for (Iterator it = clean.iterator() ; it.hasNext() ; ) {
+            sb.append(it.next());
+            if (it.hasNext()) {
+                sb.append('/');
+            }
+        }
+        if (isDir && sb.length() > 0 && sb.charAt(sb.length() - 1) != '/') {
+            sb.append('/');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Remove parameters from a uri.
+     * Resulting Map will have either String for single value attributes,
+     * or String arrays for multivalue attributes.
+     * 
+     * @param uri The uri path to deparameterize.
+     * @param parameters The map that collects parameters.
+     * @return The cleaned uri
+     */
+    public static String deparameterize(String uri, Map parameters) {
+        int i = uri.lastIndexOf('?');
+        if (i == -1) {
+            return uri;
+        }
+
+        String[] params = StringUtils.split(uri.substring(i + 1), '&');
+        for (int j = 0; j < params.length; j++) {
+            String p = params[j];
+            int k = p.indexOf('=');
+            if (k == -1) {
+                break;
+            }
+            String name = p.substring(0, k);
+            String value = p.substring(k + 1);
+            Object values = parameters.get(name);
+            if (values == null) {
+                parameters.put(name, value);
+            } else if (values.getClass().isArray()) {
+                String[] v1 = (String[])values;
+                String[] v2 = new String[v1.length + 1];
+                System.arraycopy(v1, 0, v2, 0, v1.length);
+                v2[v1.length] = value;
+                parameters.put(name, v2);
+            } else {
+                parameters.put(name, new String[]{values.toString(), value});
+            }
+        }
+        return uri.substring(0, i);
+    }
+
+    /**
+     * Add parameters stored in the Map to the uri string.
+     * Map can contain Object values which will be converted to the string,
+     * or Object arrays, which will be treated as multivalue attributes.
+     * 
+     * @param uri The uri to add parameters into
+     * @param parameters The map containing parameters to be added
+     * @return The uri with added parameters
+     */
+    public static String parameterize(String uri, Map parameters) {
+        if (parameters.size() == 0) {
+            return uri;
+        }
+        
+        StringBuffer buffer = new StringBuffer(uri);
+        if (uri.indexOf('?') == -1) {
+            buffer.append('?');
+        } else {
+            buffer.append('&');
+        }
+        
+        for (Iterator i = parameters.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry)i.next();
+            if (entry.getValue().getClass().isArray()) {
+                Object[] value = (Object[])entry.getValue();
+                for (int j = 0; j < value.length; j++) {
+                    if (j > 0) {
+                        buffer.append('&');
+                    }
+                    buffer.append(entry.getKey());
+                    buffer.append('=');
+                    buffer.append(value[j]);
+                }
+            } else {
+                buffer.append(entry.getKey());
+                buffer.append('=');
+                buffer.append(entry.getValue());
+            }
+            if (i.hasNext()) {
+                buffer.append('&');
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Create new <code>SourceParameters</code> with the same
+     * parameters as the current request
+     */
+    public static SourceParameters createParameters(Request request) {
+        final SourceParameters pars = new SourceParameters();
+
+        if (null != request) {
+            final Enumeration names = request.getParameterNames();
+            while (names.hasMoreElements()) {
+                final String current = (String)names.nextElement();
+                final String[] values = request.getParameterValues(current);
+                if (null != values) {
+                    for(int i=0; i < values.length; i++) {
+                        pars.setParameter(current, values[i]);
+                    }
+                }
+            }
+        }
+
+        return pars;
+    }
+
+    /**
+     * Remove any authorisation details from a URI
+     */
+    public static String removeAuthorisation(String uri) {
+        if (uri.indexOf("@")!=-1 && (uri.startsWith("ftp://") || uri.startsWith("http://"))) {
+            return uri.substring(0, uri.indexOf(":")+2)+uri.substring(uri.indexOf("@")+1);
+        }
+        return uri;
+    }
+
+    /**
+     * Pass through to the {@link java.net.URLEncoder}. If running under JDK &lt; 1.4,
+     * default encoding will always be used.
+     */
+    public static String encode(String s, String enc) throws UnsupportedEncodingException {
+        return URLEncoder.encode(s, enc);
+    }
+
+    /**
+     * Pass through to the {@link java.net.URLDecoder}. If running under JDK &lt; 1.4,
+     * default encoding will always be used.
+     */
+    public static String decode(String s, String enc) throws UnsupportedEncodingException {
+        return URLDecoder.decode(s, enc);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NullOutputStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NullOutputStream.java
new file mode 100644
index 0000000..42f732f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/NullOutputStream.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.OutputStream;
+
+/**
+ * @version $Id$
+ *
+ * @since 2.1.4
+ */
+public final class NullOutputStream extends OutputStream {
+
+    public void write(byte b[]) {
+    }
+
+    public void write(byte b[], int off, int len) {
+    }
+
+    public void write(int b) {
+    }
+
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/PostInputStream.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/PostInputStream.java
new file mode 100644
index 0000000..ea5669a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/PostInputStream.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+/**
+ * The class PostInputStream is a wrapper for InputStream associated with POST message.
+ * It allows to control read operation, restricting the number of bytes read to the value returned by getContentLen() method.
+ *
+ * @version $Id$
+ */
+
+public class PostInputStream extends InputStream {
+
+    /**
+    * Class name
+    */
+    public static final String CLASS = PostInputStream.class.getName();
+
+    /** The real InputStream object */
+    private InputStream m_inputStream = null;
+
+    /** The length of InputStream */
+    private int m_contentLen = 0;
+
+    /** The number of bytes read */
+    protected int m_bytesRead = 0;
+
+
+    /**
+    * Creates a PostInputStream
+    */
+    public PostInputStream() {
+        super();
+    }
+    /**
+    * Creates a <code>PostInputStream</code> based on a real InputStream object with the specified
+    * post message body length. Saves its  argument, the input stream
+    * <code>m_inputStream</code>, for later use.
+    *
+    * @param   input     the underlying input stream.
+    * @param   len   the post message body length.
+    * @exception IllegalArgumentException  len <= 0.
+    */
+
+    public PostInputStream(final InputStream input, final int len) throws IllegalArgumentException {
+        super();
+        init(input, len );
+    }
+    /**
+    * Sets the underlying input stream and contentLen value .
+    *
+    * @param input the input stream; can not be null.
+    * @param len the post message body length.
+    *
+    * @throws IllegalArgumentException
+    */
+    protected void init(final InputStream input, final int len) throws IllegalArgumentException {
+        if (len <= 0) {
+            throw new IllegalArgumentException("contentLen <= 0 ");
+        }
+        this.m_inputStream = input;
+        this.m_contentLen = len;
+    }
+
+    /**
+    * Sets the underlying input stream and contentLen value .
+    *
+    * @param input the input stream; can not be null.
+    * @param len the post message body length.
+    *
+    * @throws IOException
+    */
+    public synchronized void setInputStream(final InputStream input, final int len) throws IOException {
+        if (m_inputStream != null) {
+            close();
+        }
+        init(input, len);
+    }
+    /**
+    * Returns the underlying input stream.
+    *
+    * @return inputStream the underlying InputStream.
+    */
+    public InputStream getInputStream() {
+        return( m_inputStream );
+    }
+
+    /**
+    * Returns the post message body length.
+    *
+    * @return m_contentLen;
+    */
+
+    public int getContentLen() {
+        return( m_contentLen );
+    }
+
+    /**
+    * Reads the next byte from the input stream.  If the end of the stream has been reached, this method returns -1.
+    *
+    * @return the next byte or -1 if at the end of the stream.
+    *
+    * @throws IOException
+    */
+    public synchronized int read() throws IOException {
+
+        checkOpen();
+        if (m_bytesRead == m_contentLen) {
+            return -1;
+        }
+        int byt =  m_inputStream.read();
+        if (byt != -1) {
+           m_bytesRead++;
+        }
+        return byt;
+    }
+
+    /**
+    * Reads bytes from this byte-input stream into the specified byte array,
+    * starting at the given offset.
+    *
+    * <p> This method implements the general contract of the corresponding
+    * <code>{@link InputStream#read(byte[], int, int) read}</code> method of
+    * the <code>{@link InputStream}</code> class.
+    * This method delegetes the read operation to the underlying InputStream implementation class but it
+    * controlls the number of bytes read from the stream. In the remote situation the underlying InputStream has no knowledge of
+    * the length of the stream and the notion of the "end" is undefined. This wrapper class has a knowledge of the
+    * length of data send by the requestor by the means of contentLength. This method returns the number of bytes read and
+    * accumulates the total number of bytes read in m_bytesRead. When the m_bytesRead is equal to the specified contentLength
+    * value the method returns returns -1 to signal the end of data.
+    *
+    * @param buffer the byte array to read into; can not be null.
+    * @param offset the starting offset in the byte array.
+    * @param len the maximum number of bytes to read.
+    *
+    * @return     the number of bytes read, or <code>-1</code> if the end of
+    *             the stream has been reached.
+    * @exception  IOException  if an I/O error occurs.
+    */
+
+    public synchronized int read(byte[] buffer, int offset, int len) throws IOException {
+        checkOpen();
+        if (m_bytesRead == m_contentLen) {
+            return -1;
+        }
+        int available = Math.min( available(), len );
+        int num = m_inputStream.read( buffer, offset, available );
+        if (num > 0) {
+            m_bytesRead += num;
+        }
+        return num;
+    }
+
+    public synchronized int read(byte[] buffer) throws IOException {
+
+        return read( buffer, 0, buffer.length);
+    }
+
+
+    /**
+    * Checks to see if this stream is closed; if it is, an IOException is thrown.
+    *
+    * @throws IOException
+    */
+    protected void checkOpen() throws IOException {
+        if (m_inputStream == null) {
+            throw new IOException("InputStream closed");
+        }
+    }
+
+    /**
+         * See the general contract of the <code>skip</code>
+     * method of <code>InputStream</code>.
+     * Delegates execution to the underlying InputStream implementation class.
+     * Checks to see if this stream is closed; if it is, an IOException is thrown.
+     * @param      n   the number of bytes to be skipped.
+     * @return     the actual number of bytes skipped.
+     * @exception  IOException  if an I/O error occurs.
+     */
+    public synchronized long skip(long n) throws IOException {
+        checkOpen();
+        if ( m_bytesRead == m_contentLen )
+        {
+            return ( 0 );
+        }
+        else
+        {
+            return ( m_inputStream.skip( n ) );
+        }
+
+    }
+
+    /**
+    * Returns the number of bytes available from this input stream that can be read without the stream blocking.
+    * Delegates execution to the underlying InputStream implementation class.
+    * @return available the number of available bytes.
+    *
+    * @throws IOException
+    */
+    public synchronized int available() throws IOException {
+        checkOpen();
+        int avail = m_inputStream.available();
+        return (avail == 0 ? (m_contentLen - m_bytesRead) : avail);
+    }
+
+    /**
+    * Tests if this input stream supports the <code>mark</code>
+    * and <code>reset</code> methods. The <code>markSupported</code>
+    * method of <code>BufferedInputStream</code> returns
+    * <code>false</code>.
+    *
+    * @return  a <code>boolean</code> indicating if this stream type supports
+    *          the <code>mark</code> and <code>reset</code> methods.
+    * @see     java.io.InputStream#mark(int)
+    * @see     java.io.InputStream#reset()
+    */
+    public boolean markSupported() {
+        return false;
+    }
+
+    /**
+    * Closes this input stream by closing the underlying stream and marking this one as closed.
+    *
+    * @throws IOException
+    */
+    public synchronized void close() throws IOException {
+        if (m_inputStream == null) {
+            return;
+        }
+        m_inputStream.close();
+        m_inputStream = null;
+        m_contentLen = 0;
+        m_bytesRead = 0;
+    }
+
+    /**
+    * Returns a String representation of this.
+    *
+    * @return string the String representation of this.
+    */
+    public String toString() {
+        return new StringBuffer(getClass().getName())
+                .append("[inputStream=").append(m_inputStream)
+                .append(",  contentLen=").append(m_contentLen)
+                .append("bytesRead=").append(m_bytesRead)
+                .append("]").toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ReflectionUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ReflectionUtils.java
new file mode 100644
index 0000000..5d077d8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ReflectionUtils.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ *
+ */
+public final class ReflectionUtils {
+
+	public interface Matcher {
+        boolean matches(final String pName);
+    }
+	    
+    public interface Indexer {
+        void put(final Map pMap, final String pKey, final Object pObject);
+    }
+	    
+    private static DefaultIndexer defaultIndexer = new DefaultIndexer();
+    private static DefaultMatcher defaultMatcher = new DefaultMatcher();
+	    
+    private static class DefaultMatcher implements Matcher {
+        public boolean matches(final String pName) {
+            return pName.startsWith("do");
+        }
+    }
+	    
+    private static class DefaultIndexer implements Indexer {
+        public void put(final Map pMap, final String pKey, final Object pObject) {
+
+            // doAction -> action
+            final String name = Character.toLowerCase(pKey.charAt(2)) + pKey.substring(3);
+
+            System.out.println("reflecting " + name);
+            pMap.put(name, pObject);
+        }
+    }
+	    
+    public static Map discoverFields(
+            final Class pClazz,
+            final Matcher pMatcher
+            ) {
+        
+        return discoverFields(pClazz, pMatcher, defaultIndexer);
+    }
+
+    public static Map discoverFields(
+            final Class pClazz
+            ) {
+        
+        return discoverFields(pClazz, defaultMatcher, defaultIndexer);
+    }
+    
+    public static Map discoverFields(
+            final Class pClazz,
+            final Matcher pMatcher,
+            final Indexer pIndexer
+            ) {
+        
+        System.out.println("discovering fields on " + pClazz.getName());
+        
+        final Map result = new HashMap();
+
+        Class current = pClazz;
+        do {
+            final Field[] fields = current.getDeclaredFields();
+            for (int i = 0; i < fields.length; i++) {
+                final String fname = fields[i].getName();
+                if (pMatcher.matches(fname)) {
+                    pIndexer.put(result, fname, fields[i]);
+                }
+            }
+            current = current.getSuperclass();
+        } while(current != null);
+     
+        return result;
+    }    
+
+    
+    public static Map discoverMethods(
+            final Class pClazz,
+            final Matcher pMatcher
+            ) {
+        
+        return discoverMethods(pClazz, pMatcher, defaultIndexer);
+    }
+
+    public static Map discoverMethods(
+            final Class pClazz
+            ) {
+        
+        return discoverMethods(pClazz, defaultMatcher, defaultIndexer);
+    }
+    
+    public static Map discoverMethods(
+            final Class pClazz,
+            final Matcher pMatcher,
+            final Indexer pIndexer
+            ) {
+        
+        System.out.println("discovering methods on " + pClazz.getName());
+        
+        final Map result = new HashMap();
+
+        Class current = pClazz;
+        do {
+            final Method[] methods = current.getDeclaredMethods();
+            for (int i = 0; i < methods.length; i++) {
+                final String mname = methods[i].getName();
+                if (pMatcher.matches(mname)) {
+                    pIndexer.put(result, mname, methods[i]);
+                }
+            }
+            current = current.getSuperclass();
+        } while(current != null);
+     
+        return result;
+    }    
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ResizableContainer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ResizableContainer.java
new file mode 100644
index 0000000..35c7c34
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/ResizableContainer.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+/**
+ * Add-only Container class.
+ *
+ * @version $Id$
+ */
+public class ResizableContainer {
+
+    private int pointer = -1;
+    private int size = 0;
+    private Object[] container;
+
+    public ResizableContainer(int initialCapacity){
+        this.container = new Object[initialCapacity];
+    }
+
+    public void add(Object o) {
+        set(++pointer,o);
+    }
+    
+    public void set(int index, Object o) {
+        adjustPointer(index);
+        ensureCapacity(index+1);
+        container[index] = o;
+        size++;
+    }
+    
+    public Object get(int index) {
+        return (index < container.length) ? container[index] : null; 
+    }    
+
+    public int size() {
+        return size;
+    }
+
+    private void adjustPointer(int newPointer) {
+        this.pointer = Math.max(this.pointer, newPointer);
+    }
+    
+    private void ensureCapacity(int minCapacity) {
+        int oldCapacity = container.length;
+        if (oldCapacity < minCapacity) {
+            Object[] oldContainer = container;
+            int newCapacity = (oldCapacity * 3)/2 + 1;
+            if (newCapacity < minCapacity) {
+                newCapacity = minCapacity;
+            }
+            container = new Object[newCapacity];
+            System.arraycopy(oldContainer, 0, container, 0, oldContainer.length);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/StringUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/StringUtils.java
new file mode 100644
index 0000000..487b3f4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/StringUtils.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+/**
+ * A collection of <code>String</code> handling utility methods.
+ *
+ * @version $Id$
+ */
+public class StringUtils {
+
+    /**
+     * Split a string as an array using whitespace as separator
+     *
+     * @param line The string to be split
+     * @return An array of whitespace-separated tokens
+     */
+    public static String[] split(String line) {
+        return split(line, " \t\n\r");
+    }
+
+    /**
+     * Split a string as an array using a given set of separators
+     *
+     * @param line The string to be split
+     * @param delimiter A string containing token separators
+     * @return An array of token
+     */
+    public static String[] split(String line, String delimiter) {
+        return Tokenizer.tokenize(line, delimiter, false);
+    }
+
+    /**
+     * Tests whether a given character is alphabetic, numeric or
+     * underscore
+     *
+     * @param c The character to be tested
+     * @return whether the given character is alphameric or not
+     */
+    public static boolean isAlphaNumeric(char c) {
+        return c == '_' ||
+            (c >= 'a' && c <= 'z') ||
+            (c >= 'A' && c <= 'Z') ||
+            (c >= '0' && c <= '9');
+    }
+
+    /**
+     * Replaces tokens in input with Value present in System.getProperty
+     */
+    public static String replaceToken(String s) {
+        int startToken = s.indexOf("${");
+        int endToken = s.indexOf("}",startToken);
+        String token = s.substring(startToken+2,endToken);
+        StringBuffer value = new StringBuffer();
+        value.append(s.substring(0,startToken));
+        value.append(System.getProperty(token));
+        value.append(s.substring(endToken+1));
+        return value.toString();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Tokenizer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Tokenizer.java
new file mode 100644
index 0000000..9ad7417
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/Tokenizer.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Replacement for StringTokenizer in java.util, because of bug in the
+ * Sun's implementation.
+ *
+ * @author <A HREF="mailto:moravek@pobox.sk">Peter Moravek</A>
+ * @version $Id$
+ */
+public class Tokenizer implements Enumeration {
+
+  /**
+   * Constructs a string tokenizer for the specified string. All characters
+   * in the delim argument are the delimiters for separating tokens.
+   * If the returnTokens flag is true, then the delimiter characters are
+   * also returned as tokens. Each delimiter is returned as a string of
+   * length one. If the flag is false, the delimiter characters are skipped
+   * and only serve as separators between tokens.
+   *
+   * @param str           a string to be parsed
+   * @param delim         the delimiters
+   * @param returnTokens  flag indicating whether to return the delimiters
+   *                      as tokens
+   */
+  public Tokenizer(String str, String delim, boolean returnTokens) {
+    this.str = str;
+    this.delim = delim;
+    this.returnTokens = returnTokens;
+
+    max = str.length();
+  }
+
+  /**
+   * Constructs a string tokenizer for the specified string. The characters
+   * in the delim argument are the delimiters for separating tokens.
+   * Delimiter characters themselves will not be treated as tokens.
+   *
+   * @param str          a string to be parsed
+   * @param delim        the delimiters
+   */
+  public Tokenizer(String str, String delim) {
+    this(str, delim, false);
+  }
+
+  /**
+   * Constructs a string tokenizer for the specified string. The character
+   * in the delim argument is the delimiter for separating tokens.
+   * Delimiter character themselves will not be treated as token.
+   *
+   * @param str          a string to be parsed
+   * @param delim        the delimiter
+   */
+  public Tokenizer(String str, char delim) {
+    this(str, String.valueOf(delim), false);
+  }
+
+  /**
+   * Constructs a string tokenizer for the specified string. The tokenizer
+   * uses the default delimiter set, which is " \t\n\r\f": the space
+   * character, the tab character, the newline character, the carriage-return
+   * character, and the form-feed character. Delimiter characters themselves
+   * will not be treated as tokens.
+   *
+   * @param str          a string to be parsed
+   */
+  public Tokenizer(String str) {
+    this(str, DEFAULT_DELIMITERS, false);
+  }
+
+  /**
+   * Tests if there are more tokens available from this tokenizer's string.
+   * If this method returns true, then a subsequent call to nextToken with
+   * no argument will successfully return a token.
+   *
+   * @return true if and only if there is at least one token in the string
+   * after the current position; false otherwise.
+   */
+  public boolean hasMoreTokens() {
+    return ((current < max) ? (true) :
+      (((current == max) && (max == 0
+        || (returnTokens && delim.indexOf(str.charAt(previous)) >= 0)))));
+  }
+
+  /**
+   * Returns the next token from this string tokenizer.
+   *
+   * @return the next token from this string tokenizer
+   *
+   * @exception NoSuchElementException  if there are no more tokens in this
+   *                                    tokenizer's string
+   */
+  public String nextToken() throws NoSuchElementException {
+    if (current == max
+      && (max == 0
+      || (returnTokens && delim.indexOf(str.charAt(previous)) >= 0))) {
+
+      current++;
+      return new String();
+    }
+
+    if (current >= max)
+      throw new NoSuchElementException();
+
+    int start = current;
+    String result = null;
+
+    if (delim.indexOf(str.charAt(start)) >= 0) {
+      if (previous == -1 || (returnTokens && previous != current
+        && delim.indexOf(str.charAt(previous)) >= 0)) {
+
+        result = new String();
+      }
+      else if (returnTokens)
+        result = str.substring(start, ++current);
+
+      if (!returnTokens)
+        current++;
+    }
+
+    previous = start;
+    start = current;
+
+    if (result == null)
+      while (current < max && delim.indexOf(str.charAt(current)) < 0)
+        current++;
+
+    return result == null ? str.substring(start, current) : result;
+  }
+
+  /**
+   * Returns the next token in this string tokenizer's string. First, the
+   * set of characters considered to be delimiters by this Tokenizer
+   * object is changed to be the characters in the string delim.
+   * Then the next token in the string after the current position is
+   * returned. The current position is advanced beyond the recognized token.
+   * The new delimiter set remains the default after this call.
+   *
+   * @param delim the new delimiters
+   *
+   * @return the next token, after switching to the new delimiter set
+   *
+   * @exception NoSuchElementException  if there are no more tokens in this
+   *                                    tokenizer's string.
+   */
+  public String nextToken(String delim) throws NoSuchElementException {
+    this.delim = delim;
+    return nextToken();
+  }
+
+  /**
+   * Returns the same value as the hasMoreTokens method. It exists so that
+   * this class can implement the Enumeration interface.
+   *
+   * @return true if there are more tokens; false otherwise.
+   */
+  public boolean hasMoreElements() {
+    return hasMoreTokens();
+  }
+
+  /**
+   * Returns the same value as the nextToken method, except that its
+   * declared return value is Object rather than String. It exists so that
+   * this class can implement the Enumeration interface.
+   *
+   * @return the next token in the string
+   *
+   * @exception NoSuchElementException  if there are no more tokens in this
+   *                                    tokenizer's string
+   */
+  public Object nextElement() {
+    return nextToken();
+  }
+
+  /**
+   * Calculates the number of times that this tokenizer's nextToken method
+   * can be called before it generates an exception. The current position
+   * is not advanced.
+   *
+   * @return  the number of tokens remaining in the string using the
+   *          current delimiter set
+   */
+  public int countTokens() {
+    int curr = current;
+    int count = 0;
+
+    for (int i = curr; i < max; i++) {
+      if (delim.indexOf(str.charAt(i)) >= 0)
+        count++;
+
+      curr++;
+    }
+
+    return count + (returnTokens ? count : 0) + 1;
+  }
+
+  /**
+   * Resets this tokenizer's state so the tokenizing starts from the begin.
+   */
+  public void reset() {
+    previous = -1;
+    current = 0;
+  }
+
+  /**
+   * Constructs a string tokenizer for the specified string. All characters
+   * in the delim argument are the delimiters for separating tokens.
+   * If the returnTokens flag is true, then the delimiter characters are
+   * also returned as tokens. Each delimiter is returned as a string of
+   * length one. If the flag is false, the delimiter characters are skipped
+   * and only serve as separators between tokens. Then tokenizes the str
+   * and return an String[] array with tokens.
+   *
+   * @param str           a string to be parsed
+   * @param delim         the delimiters
+   * @param returnTokens  flag indicating whether to return the delimiters
+   *                      as tokens
+   *
+   * @return array with tokens
+   */
+  public static String[] tokenize(String str, String delim,
+    boolean returnTokens) {
+
+    Tokenizer tokenizer = new Tokenizer(str, delim, returnTokens);
+    String[] tokens = new String[tokenizer.countTokens()];
+
+    int i = 0;
+    while (tokenizer.hasMoreTokens()) {
+      tokens[i] = tokenizer.nextToken();
+      i++;
+    }
+
+    return tokens;
+  }
+
+  /**
+   * Default delimiters " \t\n\r\f":
+   * the space character, the tab character, the newline character,
+   * the carriage-return character, and the form-feed character.
+   */
+  public static final String DEFAULT_DELIMITERS = " \t\n\r\f";
+
+  /**
+   * String to tokenize.
+   */
+  private String str = null;
+
+  /**
+   * Delimiters.
+   */
+  private String delim = null;
+
+  /**
+   * Flag indicating whether to return the delimiters as tokens.
+   */
+  private boolean returnTokens = false;
+
+  /**
+   * Previous token start.
+   */
+  private int previous = -1;
+
+  /**
+   * Current position in str string.
+   */
+  private int current = 0;
+
+  /**
+   * Maximal position in str string.
+   */
+  private int max = 0;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/TraxErrorHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/TraxErrorHandler.java
new file mode 100644
index 0000000..a0b771e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/TraxErrorHandler.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util;
+
+import org.apache.avalon.framework.logger.Logger;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+/**
+ * This ErrorListener simply logs the exception and in
+ * case of an fatal-error the exception is rethrown.
+ * Warnings and errors are ignored.
+ *
+ * @version $Id$
+ */
+public class TraxErrorHandler implements ErrorListener {
+
+    private StringBuffer warnings = new StringBuffer("Errors in XSLT transformation:\n");
+    private Logger logger = null;
+
+    public TraxErrorHandler( Logger logger ) {
+        this.logger = logger;
+    }
+
+    public void warning( TransformerException exception )
+            throws TransformerException
+    {
+        final String message = getMessage( exception );
+        if ( this.logger != null ) {
+            this.logger.warn( message );
+        } else {
+            System.out.println( "WARNING: " + message );
+        }
+        warnings.append("Warning: ");
+        warnings.append(message);
+        warnings.append("\n");
+    }
+
+    public void error( TransformerException exception )
+            throws TransformerException
+    {
+        final String message = getMessage( exception );
+        if ( this.logger != null ) {
+            this.logger.error( message, exception );
+        } else {
+            System.out.println( "ERROR: " + message );
+        }
+        warnings.append("Error: ");
+        warnings.append(message);
+        warnings.append("\n");
+    }
+
+    public void fatalError( TransformerException exception )
+            throws TransformerException
+    {
+        final String message = getMessage( exception );
+        if ( this.logger != null ) {
+            this.logger.fatalError( message, exception );
+        } else {
+            System.out.println( "FATAL-ERROR: " + message );
+        }
+        warnings.append("Fatal: ");
+        warnings.append(message);
+        warnings.append("\n");
+        try {
+            throw new TransformerException(warnings.toString());
+        } finally {
+            warnings = new StringBuffer();
+        }
+    }
+
+    private String getMessage( TransformerException exception ) {
+
+        SourceLocator locator = exception.getLocator();
+        if ( null != locator ) {
+            String id = ( locator.getPublicId() != locator.getPublicId() )
+                    ? locator.getPublicId()
+                    : ( null != locator.getSystemId() )
+                    ? locator.getSystemId() : "SystemId Unknown";
+            return "File " + id
+                    + "; Line " + locator.getLineNumber()
+                    + "; Column " + locator.getColumnNumber()
+                    + "; " + exception.getMessage();
+        }
+        return exception.getMessage();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/DOMFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/DOMFactory.java
new file mode 100644
index 0000000..d4c700c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/DOMFactory.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.jxpath;
+
+import org.apache.commons.jxpath.AbstractFactory;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.Pointer;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * A <a href="http://jakarta.apache.org/commons/jxpath">JXPath</a> <code>AbstractFactory</code>
+ * that creates DOM elements.
+ *
+ * @version $Id$
+ */
+
+public class DOMFactory extends AbstractFactory {
+
+    /**
+     * Return <b>false</b> if this factory cannot create the requested object.
+     */
+    public boolean createObject(
+        JXPathContext context,
+        Pointer pointer,
+        Object parent,
+        String name,
+        int index) 
+    {
+         //FIXME: JXPath automatically creates attributes if the element already exists,
+         //but does not call this method if the element does not exit 
+
+        addDOMElement((Node) parent, index, name);
+        
+        return true;
+    }
+
+    private void addDOMElement(Node parent, int index, String tag) {
+        int pos = tag.indexOf(':');
+        String prefix = null;
+        if (pos != -1) {
+            prefix = tag.substring(0, pos);
+        }
+        String uri = null;
+        
+        Node child = parent.getFirstChild();
+        int count = 0;
+        while (child != null) {
+            if (child.getNodeName().equals(tag)) {
+                count++;
+            }
+            child = child.getNextSibling();
+        }
+
+        Document doc = parent.getOwnerDocument();
+        
+        if (doc != null) {
+            uri = getNamespaceURI((Element)parent, prefix);
+        } else {
+            if (parent instanceof Document) {
+                doc = (Document)parent;
+                if (prefix != null) {
+                    throw new RuntimeException("Cannot map non-null prefix " +
+                        "when creating a document element");    
+                }
+            } else { // Shouldn't happen (must be a DocumentType object)
+                throw new RuntimeException("Node of class " +
+                    parent.getClass().getName() + " has null owner document " +
+                    "but is not a Document"); 
+            }
+
+        }
+
+        // Keep inserting new elements until we have index + 1 of them
+        while (count <= index) {
+            Node newElement = doc.createElementNS(uri, tag);
+            parent.appendChild(newElement);
+            count++;
+        }
+    }
+    
+    public String getNamespaceURI(Element element, String prefix) {
+        Node tmp = element;
+        String nsAttr = prefix == null ? "xmlns" : "xmlns:" + prefix;
+        
+        while (tmp != null && tmp.getNodeType() == Node.ELEMENT_NODE) {
+            element = (Element)tmp;
+            
+            // First test element prefixes
+            if (prefix == null) {
+                if (element.getPrefix() == null) {
+                    return element.getNamespaceURI();
+                }
+            } else if(prefix.equals(element.getPrefix())) {
+                return element.getNamespaceURI();
+            }
+            
+            // Note: stupid DOM api returns "" when an attribute doesn't exist, so we use the Attr node.
+            Attr nsAttrNode = ((Element)tmp).getAttributeNode(nsAttr);
+            if (nsAttrNode != null) {
+                return nsAttrNode.getValue();
+            }
+            tmp = tmp.getParentNode();
+        }
+        return null;
+    }
+
+    public boolean declareVariable(JXPathContext context, String name) {
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/NamespacesTablePointer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/NamespacesTablePointer.java
new file mode 100644
index 0000000..b206220
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/jxpath/NamespacesTablePointer.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util.jxpath;
+
+import org.apache.cocoon.xml.NamespacesTable;
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.model.NodeIterator;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+
+/**
+ * A JXPath <code>Pointer</code> that tracks namespaces defined by a {@link NamespacesTable}.
+ * This class is to be used to inform JXPath of the namespaces declared in a host environment
+ * (e.g. JXTemplateGenerator) using
+ * <a href="http://jakarta.apache.org/commons/jxpath/apidocs/org/apache/commons/jxpath/JXPathContext.html#setNamespaceContextPointer(org.apache.commons.jxpath.Pointer)">JXPathContext.setNamespaceContextPointer()</a>.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class NamespacesTablePointer extends NodePointer {
+    
+    private NamespacesTable namespaces;
+
+    public NamespacesTablePointer(NamespacesTable namespaces) {
+        super(null);
+        this.namespaces = namespaces;
+    }
+
+    public String getNamespaceURI(String prefix) {
+        return namespaces.getUri(prefix);
+    }
+
+    protected String getDefaultNamespaceURI() {
+        return namespaces.getUri("");
+    }
+
+    public NodeIterator namespaceIterator() {
+        return null;
+    }
+    
+    //-------------------------------------------------------------------------
+    // Dummy implementation of abstract methods
+    //-------------------------------------------------------------------------
+
+    public boolean isLeaf() {
+        return true;
+    }
+
+    public boolean isCollection() {
+        return false;
+    }
+
+    public int getLength() {
+        return 0;
+    }
+
+    public QName getName() {
+        return null;
+    }
+
+    public Object getBaseValue() {
+        return null;
+    }
+
+    public Object getImmediateNode() {
+        return null;
+    }
+
+    public void setValue(Object value) {
+        // ignore
+    }
+
+    public int compareChildNodePointers(NodePointer arg0, NodePointer arg1) {
+        return -1;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Locatable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Locatable.java
new file mode 100644
index 0000000..46092b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Locatable.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+/**
+ * A interface that should be implemented by objects knowning their location (i.e. where they
+ * have been created from).
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public interface Locatable {
+    /**
+     * Get the location of this object
+     * 
+     * @return the location
+     */
+    Location getLocation();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatableException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatableException.java
new file mode 100644
index 0000000..8e40dca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatableException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+/**
+ * Extension of {@link Locatable} for exceptions.
+ * <p>
+ * In order to dump location information in the stacktrace, the <code>getMessage()</code> method of
+ * a {@link Locatable} exception should return a concatenation of the raw message (given in the
+ * constructor) and the exception's location, e.g. "<code>foo failed (file.xml:12:3)</code>". However,
+ * {@link Locatable}-aware classes will want to handle the raw message (i.e. "<code>foo failed</code>")
+ * and location separately. This interface gives access to the raw message.
+ * <p>
+ * <strong>Note:</strong> care should be taken for locatable exceptions to use only immutable and
+ * serializable implementations of {@link Location}
+ * 
+ * @see org.apache.cocoon.util.location.LocationImpl#get(Location)
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public interface LocatableException extends Locatable {
+    
+    /**
+     * Get the raw message of the exception (the one used in the constructor)
+     * 
+     * @return the raw message
+     */
+    public String getRawMessage();
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedException.java
new file mode 100644
index 0000000..a694a43
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedException.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util.location;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang.exception.NestableException;
+
+/**
+ * A cascading and located <code>Exception</code>. It is also {@link MultiLocatable} to easily build
+ * stack traces.
+ *
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocatedException extends NestableException
+                              implements LocatableException, MultiLocatable {
+
+    private List locations;
+
+    public LocatedException(String message) {
+        this(message, null, null);
+    }
+
+    public LocatedException(String message, Throwable cause) {
+        this(message, cause, null);
+    }
+
+    public LocatedException(String message, Location location) {
+        this(message, null, location);
+    }
+
+    public LocatedException(String message, Throwable cause, Location location) {
+        super(message, cause);
+        ensureCauseChainIsSet(cause);
+        addCauseLocations(this, cause);
+        addLocation(location);
+    }
+
+    /**
+     * Crawl the cause chain and ensure causes are properly set using {@ link Throwable#initCause}.
+     * This is needed because some exceptions (e.g. SAXException) don't have a {@ link Throwable#getCause}
+     * that is used to print stacktraces.
+     */
+    public static void ensureCauseChainIsSet(Throwable thr) {
+        // Loop either until null or encountering exceptions that use this method.
+        while (thr != null && !(thr instanceof LocatedRuntimeException) && !(thr instanceof LocatedException)) {
+            Throwable parent = ExceptionUtils.getCause(thr);
+            if (thr.getCause() == null && parent != null) {
+                thr.initCause(parent);
+            }
+            thr = parent;
+        }
+    }
+
+    /**
+     * Add to the location stack all locations of an exception chain. This allows to have all possible
+     * location information in the stacktrace, as some exceptions like SAXParseException don't output
+     * their location in printStackTrace().
+     * <p>
+     * Traversal of the call chain stops at the first <code>Locatable</code> exception which is supposed
+     * to handle the loction of its causes by itself.
+     * <p>
+     * This method is static as a convenience for {@link LocatedRuntimeException other implementations}
+     * of locatable exceptions.
+     *
+     * @param self the current locatable exception
+     * @param cause a cause of <code>self</code>
+     */
+    public static void addCauseLocations(MultiLocatable self, Throwable cause) {
+        if (cause == null || cause instanceof Locatable) {
+            // Locatable handles its location itself
+            return;
+        }
+        // Add parent location first
+        addCauseLocations(self, ExceptionUtils.getCause(cause));
+        // then ourselve's
+        Location loc = LocationUtils.getLocation(cause);
+        if (LocationUtils.isKnown(loc)) {
+            // Get the exception's short name
+            String name = cause.getClass().getName();
+            int pos = name.lastIndexOf('.');
+            if (pos != -1) {
+                name = name.substring(pos+1);
+            }
+            loc = new LocationImpl("[" + name + "]", loc.getURI(), loc.getLineNumber(), loc.getColumnNumber());
+            self.addLocation(loc);
+        }
+    }
+
+    public Location getLocation() {
+        return locations == null ? null : (Location)locations.get(0);
+    }
+
+    public List getLocations() {
+        return locations == null ? Collections.EMPTY_LIST : locations;
+    }
+
+    public String getRawMessage() {
+        return super.getMessage();
+    }
+
+    /**
+     * Standard way of building the message of a {@link LocatableException}, as a Java-like
+     * stack trace of locations.
+     *
+     * @param message the exception's message, given by <code>super.getMessage()</code> (can be null)
+     * @param locations the location list (can be null)
+     *
+     * @return the message, or <code>null</code> no message and locations were given.
+     */
+    public static String getMessage(String message, List locations) {
+        if (locations == null || locations.isEmpty()) {
+            return message;
+        }
+
+        // Produce a Java-like stacktrace with locations
+        StringBuffer buf = message == null ? new StringBuffer() : new StringBuffer(message);
+        for (int i = 0; i < locations.size(); i++) {
+            buf.append("\n\tat ").append(LocationUtils.toString((Location)locations.get(i)));
+        }
+        return buf.toString();
+    }
+
+    public String getMessage() {
+        return getMessage(super.getMessage(), locations);
+    }
+
+    public void addLocation(Location loc) {
+        if (LocationUtils.isUnknown(loc))
+            return;
+
+        if (locations == null) {
+            this.locations = new ArrayList(1); // Start small
+        }
+        locations.add(LocationImpl.get(loc));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java
new file mode 100644
index 0000000..29686c8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocatedRuntimeException.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.exception.NestableRuntimeException;
+
+/**
+ * A cascading and located <code>RuntimeException</code>. It is also {@link MultiLocatable} to easily build
+ * location stack traces.
+ * <p>
+ * If a <code>LocatedRuntimeException</code> is built with a location and a cause which is also a
+ * <code>LocatedRuntimeException</code>, then the default behavior is to add the location to the cause
+ * exception and immediately rethrow the cause. This avoids exception nesting and builds a location
+ * stack.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocatedRuntimeException extends NestableRuntimeException implements LocatableException, MultiLocatable {
+    
+    private List locations;
+
+    public LocatedRuntimeException(String message) {
+        this(message, null, null, true);
+    }
+    
+    public LocatedRuntimeException(String message, Throwable cause) throws LocatedRuntimeException {
+        this(message, cause, null, true);
+    }
+    
+    public LocatedRuntimeException(String message, Location location) {
+        this(message, null, location, true);
+    }
+    
+    public LocatedRuntimeException(String message, Throwable cause, Location location) throws LocatedRuntimeException {
+        this(message, cause, location, true);
+    }
+
+    public LocatedRuntimeException(String message, Throwable cause, Location location, boolean rethrowLocated)
+        throws LocatedRuntimeException {
+        super(message, cause);
+        if (rethrowLocated && cause instanceof LocatedRuntimeException) {
+            LocatedRuntimeException lreCause = (LocatedRuntimeException)cause;
+            lreCause.addLocation(location);
+            // Rethrow the cause
+            throw lreCause;
+        }
+
+        LocatedException.ensureCauseChainIsSet(cause);
+        LocatedException.addCauseLocations(this, cause);
+        addLocation(location);
+    }
+
+    public Location getLocation() {
+        return locations == null ? null : (Location)locations.get(0);
+    }
+
+    public List getLocations() {
+        return locations == null ? Collections.EMPTY_LIST : locations;
+    }
+
+    public String getRawMessage() {
+        return super.getMessage();
+    }
+
+    public String getMessage() {
+        return LocatedException.getMessage(super.getMessage(), locations);
+    }
+    
+    public void addLocation(Location loc) {
+        if (LocationUtils.isUnknown(loc))
+            return;
+
+        if (locations == null) {
+            this.locations = new ArrayList(1); // Start small
+        }
+        locations.add(LocationImpl.get(loc));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Location.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Location.java
new file mode 100644
index 0000000..97812ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/Location.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+
+/**
+ * A location in a resource. The location is composed of the URI of the resource, and 
+ * the line and column numbers within that resource (when available), along with a description.
+ * <p>
+ * Locations are mostly provided by {@link Locatable}s objects.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public interface Location {
+    
+    /**
+     * Constant for unknown locations.
+     */
+    public static final Location UNKNOWN = LocationImpl.UNKNOWN;
+    
+    /**
+     * Get the description of this location
+     * 
+     * @return the description (can be <code>null</code>)
+     */
+    public String getDescription();
+    
+    /**
+     * Get the URI of this location
+     * 
+     * @return the URI (<code>null</code> if unknown).
+     */
+    public String getURI();
+    /**
+     * Get the line number of this location
+     * 
+     * @return the line number (<code>-1</code> if unknown)
+     */
+    public int getLineNumber();
+    
+    /**
+     * Get the column number of this location
+     * 
+     * @return the column number (<code>-1</code> if unknown)
+     */
+    public int getColumnNumber();
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationAttributes.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationAttributes.java
new file mode 100644
index 0000000..6386a74
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationAttributes.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * A class to handle location information stored in attributes.
+ * These attributes are typically setup using {@link org.apache.cocoon.util.location.LocationAttributes.Pipe}
+ * which augments the SAX stream with additional attributes, e.g.:
+ * <pre>
+ * &lt;root xmlns:loc="http://apache.org/cocoon/location"
+ *       loc:src="file://path/to/file.xml"
+ *       loc:line="1" loc:column="1"&gt;
+ *   &lt;foo loc:src="file://path/to/file.xml" loc:line="2" loc:column="3"/&gt;
+ * &lt;/root&gt;
+ * </pre>
+ * 
+ * @see org.apache.cocoon.util.location.LocationAttributes.Pipe
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocationAttributes {
+    /** Prefix for the location namespace */
+    public static final String PREFIX = "loc";
+    /** Namespace URI for location attributes */
+    public static final String URI = "http://apache.org/cocoon/location";
+
+    /** Attribute name for the location URI */
+    public static final String SRC_ATTR  = "src";
+    /** Attribute name for the line number */
+    public static final String LINE_ATTR = "line";
+    /** Attribute name for the column number */
+    public static final String COL_ATTR  = "column";
+
+    /** Attribute qualified name for the location URI */
+    public static final String Q_SRC_ATTR  = "loc:src";
+    /** Attribute qualified name for the line number */
+    public static final String Q_LINE_ATTR = "loc:line";
+    /** Attribute qualified name for the column number */
+    public static final String Q_COL_ATTR  = "loc:column";
+    
+    // Private constructor, we only have static methods
+    private LocationAttributes() {
+        // Nothing
+    }
+    
+    /**
+     * Add location attributes to a set of SAX attributes.
+     * 
+     * @param locator the <code>Locator</code> (can be null)
+     * @param attrs the <code>Attributes</code> where locator information should be added
+     */
+    public static Attributes addLocationAttributes(Locator locator, Attributes attrs) {
+        if (locator == null || attrs.getIndex(URI, SRC_ATTR) != -1) {
+            // No location information known, or already has it
+            return attrs;
+        }
+        
+        // Get an AttributeImpl so that we can add new attributes.
+        AttributesImpl newAttrs = attrs instanceof AttributesImpl ?
+            (AttributesImpl)attrs : new AttributesImpl(attrs);
+
+        newAttrs.addAttribute(URI, SRC_ATTR, Q_SRC_ATTR, "CDATA", locator.getSystemId());
+        newAttrs.addAttribute(URI, LINE_ATTR, Q_LINE_ATTR, "CDATA", Integer.toString(locator.getLineNumber()));
+        newAttrs.addAttribute(URI, COL_ATTR, Q_COL_ATTR, "CDATA", Integer.toString(locator.getColumnNumber()));
+        
+        return newAttrs;
+    }
+    
+    /**
+     * Returns the {@link Location} of an element (SAX flavor).
+     * 
+     * @param attrs the element's attributes that hold the location information
+     * @param description a description for the location (can be null)
+     * @return a {@link Location} object
+     */
+    public static Location getLocation(Attributes attrs, String description) {
+        String src = attrs.getValue(URI, SRC_ATTR);
+        if (src == null) {
+            return Location.UNKNOWN;
+        }
+        
+        return new LocationImpl(description, src, getLine(attrs), getColumn(attrs));
+    }
+
+    /**
+     * Returns the location of an element (SAX flavor). If the location is to be kept
+     * into an object built from this element, consider using {@link #getLocation(Attributes, String)}
+     * and the {@link Locatable} interface.
+     * 
+     * @param attrs the element's attributes that hold the location information
+     * @return a location string as defined by {@link Location#toString()}.
+     */
+    public static String getLocationString(Attributes attrs) {
+        String src = attrs.getValue(URI, SRC_ATTR);
+        if (src == null) {
+            return LocationUtils.UNKNOWN_STRING;
+        }
+        
+        return src + ":" + attrs.getValue(URI, LINE_ATTR) + ":" + attrs.getValue(URI, COL_ATTR);
+    }
+    
+    /**
+     * Returns the URI of an element (SAX flavor)
+     * 
+     * @param attrs the element's attributes that hold the location information
+     * @return the element's URI or "<code>[unknown location]</code>" if <code>attrs</code>
+     *         has no location information.
+     */
+    public static String getURI(Attributes attrs) {
+        String src = attrs.getValue(URI, SRC_ATTR);
+        return src != null ? src : LocationUtils.UNKNOWN_STRING;
+    }
+    
+    /**
+     * Returns the line number of an element (SAX flavor)
+     * 
+     * @param attrs the element's attributes that hold the location information
+     * @return the element's line number or <code>-1</code> if <code>attrs</code>
+     *         has no location information.
+     */
+    public static int getLine(Attributes attrs) {
+        String line = attrs.getValue(URI, LINE_ATTR);
+        return line != null ? Integer.parseInt(line) : -1;
+    }
+    
+    /**
+     * Returns the column number of an element (SAX flavor)
+     * 
+     * @param attrs the element's attributes that hold the location information
+     * @return the element's column number or <code>-1</code> if <code>attrs</code>
+     *         has no location information.
+     */
+    public static int getColumn(Attributes attrs) {
+        String col = attrs.getValue(URI, COL_ATTR);
+        return col != null ? Integer.parseInt(col) : -1;
+    }
+    
+    /**
+     * Returns the {@link Location} of an element (DOM flavor).
+     * 
+     * @param elem the element that holds the location information
+     * @param description a description for the location (if <code>null</code>, the element's name is used)
+     * @return a {@link Location} object
+     */
+    public static Location getLocation(Element elem, String description) {
+        Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+        if (srcAttr == null) {
+            return Location.UNKNOWN;
+        }
+
+        return new LocationImpl(description == null ? elem.getNodeName() : description,
+                srcAttr.getValue(), getLine(elem), getColumn(elem));
+    }
+    
+    /**
+     * Same as <code>getLocation(elem, null)</code>.
+     */
+    public static Location getLocation(Element elem) {
+        return getLocation(elem, null);
+    }
+   
+
+    /**
+     * Returns the location of an element that has been processed by this pipe (DOM flavor).
+     * If the location is to be kept into an object built from this element, consider using
+     * {@link #getLocation(Element)} and the {@link Locatable} interface.
+     * 
+     * @param elem the element that holds the location information
+     * @return a location string as defined by {@link Location#toString()}.
+     */
+    public static String getLocationString(Element elem) {
+        Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+        if (srcAttr == null) {
+            return LocationUtils.UNKNOWN_STRING;
+        }
+        
+        return srcAttr.getValue() + ":" + elem.getAttributeNS(URI, LINE_ATTR) + ":" + elem.getAttributeNS(URI, COL_ATTR);
+    }
+    
+    /**
+     * Returns the URI of an element (DOM flavor)
+     * 
+     * @param elem the element that holds the location information
+     * @return the element's URI or "<code>[unknown location]</code>" if <code>elem</code>
+     *         has no location information.
+     */
+    public static String getURI(Element elem) {
+        Attr attr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+        return attr != null ? attr.getValue() : LocationUtils.UNKNOWN_STRING;
+    }
+
+    /**
+     * Returns the line number of an element (DOM flavor)
+     * 
+     * @param elem the element that holds the location information
+     * @return the element's line number or <code>-1</code> if <code>elem</code>
+     *         has no location information.
+     */
+    public static int getLine(Element elem) {
+        Attr attr = elem.getAttributeNodeNS(URI, LINE_ATTR);
+        return attr != null ? Integer.parseInt(attr.getValue()) : -1;
+    }
+
+    /**
+     * Returns the column number of an element (DOM flavor)
+     * 
+     * @param elem the element that holds the location information
+     * @return the element's column number or <code>-1</code> if <code>elem</code>
+     *         has no location information.
+     */
+    public static int getColumn(Element elem) {
+        Attr attr = elem.getAttributeNodeNS(URI, COL_ATTR);
+        return attr != null ? Integer.parseInt(attr.getValue()) : -1;
+    }
+    
+    /**
+     * Remove the location attributes from a DOM element.
+     * 
+     * @param elem the element to remove the location attributes from.
+     * @param recurse if <code>true</code>, also remove location attributes on descendant elements.
+     */
+    public static void remove(Element elem, boolean recurse) {
+        elem.removeAttributeNS(URI, SRC_ATTR);
+        elem.removeAttributeNS(URI, LINE_ATTR);
+        elem.removeAttributeNS(URI, COL_ATTR);
+        if (recurse) {
+            NodeList children = elem.getChildNodes();
+            for (int i = 0; i < children.getLength(); i++) {
+                Node child = children.item(i);
+                if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    remove((Element)child, recurse);
+                }
+            }
+        }
+    }
+
+    /**
+     * A SAX filter that adds the information available from the <code>Locator</code> as attributes.
+     * The purpose of having location as attributes is to allow this information to survive transformations
+     * of the document (an XSL could copy these attributes over) or conversion of SAX events to a DOM.
+     * <p>
+     * The location is added as 3 attributes in a specific namespace to each element.
+     * <pre>
+     * &lt;root xmlns:loc="http://apache.org/cocoon/location"
+     *       loc:src="file://path/to/file.xml"
+     *       loc:line="1" loc:column="1"&gt;
+     *   &lt;foo loc:src="file://path/to/file.xml" loc:line="2" loc:column="3"/&gt;
+     * &lt;/root&gt;
+     * </pre>
+     * <strong>Note:</strong> Although this adds a lot of information to the serialized form of the document,
+     * the overhead in SAX events is not that big, as attribute names are interned, and all <code>src</code>
+     * attributes point to the same string.
+     * 
+     * @see org.apache.cocoon.util.location.LocationAttributes
+     * @since 2.1.8
+     */
+    public static class Pipe implements ContentHandler {
+        
+        private Locator locator;
+        
+        private ContentHandler nextHandler;
+        
+        /**
+         * Create a filter. It has to be chained to another handler to be really useful.
+         */
+        public Pipe() {
+        }
+
+        /**
+         * Create a filter that is chained to another handler.
+         * @param next the next handler in the chain.
+         */
+        public Pipe(ContentHandler next) {
+            nextHandler = next;
+        }
+
+        public void setDocumentLocator(Locator locator) {
+            this.locator = locator;
+            nextHandler.setDocumentLocator(locator);
+        }
+        
+        public void startDocument() throws SAXException {
+            nextHandler.startDocument();
+            nextHandler.startPrefixMapping(LocationAttributes.PREFIX, LocationAttributes.URI);
+        }
+        
+        public void endDocument() throws SAXException {
+            endPrefixMapping(LocationAttributes.PREFIX);
+            nextHandler.endDocument();
+        }
+
+        public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
+            // Add location attributes to the element
+            nextHandler.startElement(uri, loc, raw, LocationAttributes.addLocationAttributes(locator, attrs));
+        }
+
+        public void endElement(String arg0, String arg1, String arg2) throws SAXException {
+            nextHandler.endElement(arg0, arg1, arg2);
+        }
+
+        public void startPrefixMapping(String arg0, String arg1) throws SAXException {
+            nextHandler.startPrefixMapping(arg0, arg1);
+        }
+
+        public void endPrefixMapping(String arg0) throws SAXException {
+            nextHandler.endPrefixMapping(arg0);
+        }
+
+        public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
+            nextHandler.characters(arg0, arg1, arg2);
+        }
+
+        public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
+            nextHandler.ignorableWhitespace(arg0, arg1, arg2);
+        }
+
+        public void processingInstruction(String arg0, String arg1) throws SAXException {
+            nextHandler.processingInstruction(arg0, arg1);
+        }
+
+        public void skippedEntity(String arg0) throws SAXException {
+            nextHandler.skippedEntity(arg0);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationImpl.java
new file mode 100644
index 0000000..7466c83
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationImpl.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.ObjectUtils;
+
+/**
+ * A simple immutable and serializable implementation of {@link Location}.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public class LocationImpl implements Location, Serializable {
+    private final String uri;
+    private final int line;
+    private final int column;
+    private final String description;
+    
+    // Package private: outside this package, use Location.UNKNOWN.
+    static final LocationImpl UNKNOWN = new LocationImpl(null, null, -1, -1);
+
+    /**
+     * Build a location for a given URI, with unknown line and column numbers.
+     * 
+     * @param uri the resource URI
+     */
+    public LocationImpl(String description, String uri) {
+        this(description, uri, -1, -1);
+    }
+
+    /**
+     * Build a location for a given URI and line and columb numbers.
+     * 
+     * @param uri the resource URI
+     * @param line the line number (starts at 1)
+     * @param column the column number (starts at 1)
+     */
+    public LocationImpl(String description, String uri, int line, int column) {
+        if (uri == null || uri.length() == 0) {
+            this.uri = null;
+            this.line = -1;
+            this.column = -1;
+        } else {
+            this.uri = uri;
+            this.line = line;
+            this.column = column;
+        }
+        
+        if (description != null && description.length() == 0) {
+            description = null;
+        }
+        this.description = description;
+    }
+    
+    /**
+     * Copy constructor.
+     * 
+     * @param location the location to be copied
+     */
+    public LocationImpl(Location location) {
+        this(location.getDescription(), location.getURI(), location.getLineNumber(), location.getColumnNumber());
+    }
+    
+    /**
+     * Create a location from an existing one, but with a different description
+     */
+    public LocationImpl(String description, Location location) {
+        this(description, location.getURI(), location.getLineNumber(), location.getColumnNumber());
+    }
+    
+    /**
+     * Obtain a <code>LocationImpl</code> from a {@link Location}. If <code>location</code> is
+     * already a <code>LocationImpl</code>, it is returned, otherwise it is copied.
+     * <p>
+     * This method is useful when an immutable and serializable location is needed, such as in locatable
+     * exceptions.
+     * 
+     * @param location the location
+     * @return an immutable and serializable version of <code>location</code>
+     */
+    public static LocationImpl get(Location location) {
+        if (location instanceof LocationImpl) {
+            return (LocationImpl)location;
+        } else if (location == null) {
+            return UNKNOWN;
+        } else {
+            return new LocationImpl(location);
+        }
+    }
+    
+    /**
+     * Get the description of this location
+     * 
+     * @return the description (can be <code>null</code>)
+     */
+    public String getDescription() {
+        return this.description;
+    }
+    
+    /**
+     * Get the URI of this location
+     * 
+     * @return the URI (<code>null</code> if unknown).
+     */
+    public String getURI() {
+        return this.uri;
+    }
+
+    /**
+     * Get the line number of this location
+     * 
+     * @return the line number (<code>-1</code> if unknown)
+     */
+    public int getLineNumber() {
+        return this.line;
+    }
+    
+    /**
+     * Get the column number of this location
+     * 
+     * @return the column number (<code>-1</code> if unknown)
+     */
+    public int getColumnNumber() {
+        return this.column;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (obj instanceof Location) {
+            Location other = (Location)obj;
+            return this.line == other.getLineNumber() && this.column == other.getColumnNumber()
+                   && ObjectUtils.equals(this.uri, other.getURI())
+                   && ObjectUtils.equals(this.description, other.getDescription());
+        }
+        
+        return false;
+    }
+    
+    public int hashCode() {
+        int hash = line ^ column;
+        if (uri != null) hash ^= uri.hashCode();
+        if (description != null) hash ^= description.hashCode();
+        
+        return hash;
+    }
+    
+    public String toString() {
+        return LocationUtils.toString(this);
+    }
+    
+    /**
+     * Ensure serialized unknown location resolve to {@link Location#UNKNOWN}.
+     */
+    private Object readResolve() {
+        return this.equals(Location.UNKNOWN) ? Location.UNKNOWN : this;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationUtils.java
new file mode 100644
index 0000000..a98e96b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/LocationUtils.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Location-related utility methods.
+ *
+ * @version $Id$
+ * @since 2.1.8
+ */
+public class LocationUtils {
+    
+    /**
+     * The string representation of an unknown location: "<code>[unknown location]</code>".
+     */
+    public static final String UNKNOWN_STRING = "[unknown location]";
+    
+    private static List finders = new ArrayList();
+    
+    /**
+     * An finder or object locations
+     *
+     * @since 2.1.8
+     */
+    public interface LocationFinder {
+        /**
+         * Get the location of an object
+         * @param obj the object for which to find a location
+         * @param description and optional description to be added to the object's location
+         * @return the object's location or <code>null</code> if object's class isn't handled
+         *         by this finder.
+         */
+        Location getLocation(Object obj, String description);
+    }
+
+    private LocationUtils() {
+        // Forbid instanciation
+    }
+    
+    /**
+     * Builds a string representation of a location, in the
+     * "<code><em>descripton</em> - <em>uri</em>:<em>line</em>:<em>column</em></code>"
+     * format (e.g. "<code>foo - file://path/to/file.xml:3:40</code>"). For {@link Location#UNKNOWN an unknown location}, returns
+     * {@link #UNKNOWN_STRING}.
+     * 
+     * @return the string representation
+     */
+    public static String toString(Location location) {
+        StringBuffer result = new StringBuffer();
+
+        String description = location.getDescription();
+        if (description != null) {
+            result.append(description).append(" - ");
+        }
+
+        String uri = location.getURI();
+        if (uri != null) {
+            result.append(uri).append(':').append(location.getLineNumber()).append(':').append(location.getColumnNumber());
+        } else {
+            result.append(UNKNOWN_STRING);
+        }
+        
+        return result.toString();
+    }
+
+    /**
+     * Parse a location string of the form "<code><em>uri</em>:<em>line</em>:<em>column</em></code>" (e.g.
+     * "<code>path/to/file.xml:3:40</code>") to a Location object. Additionally, a description may
+     * also optionally be present, separated with an hyphen (e.g. "<code>foo - path/to/file.xml:3.40</code>").
+     * 
+     * @param text the text to parse
+     * @return the location (possibly <code>null</code> if text was null or in an incorrect format)
+     */
+    public static LocationImpl parse(String text) throws IllegalArgumentException {
+        if (text == null || text.length() == 0) {
+            return null;
+        }
+
+        // Do we have a description?
+        String description;
+        int uriStart = text.lastIndexOf(" - "); // lastIndexOf to allow the separator to be in the description
+        if (uriStart > -1) {
+            description = text.substring(0, uriStart);
+            uriStart += 3; // strip " - "
+        } else {
+            description = null;
+            uriStart = 0;
+        }
+        
+        try {
+            int colSep = text.lastIndexOf(':');
+            if (colSep > -1) {
+                int column = Integer.parseInt(text.substring(colSep + 1));
+                
+                int lineSep = text.lastIndexOf(':', colSep - 1);
+                if (lineSep > -1) {
+                    int line = Integer.parseInt(text.substring(lineSep + 1, colSep));
+                    return new LocationImpl(description, text.substring(uriStart, lineSep), line, column);
+                }
+            } else {
+                // unkonwn?
+                if (text.endsWith(UNKNOWN_STRING)) {
+                    return LocationImpl.UNKNOWN;
+                }
+            }
+        } catch(Exception e) {
+            // Ignore: handled below
+        }
+        
+        return LocationImpl.UNKNOWN;
+    }
+
+    /**
+     * Checks if a location is known, i.e. it is not null nor equal to {@link Location#UNKNOWN}.
+     * 
+     * @param location the location to check
+     * @return <code>true</code> if the location is known
+     */
+    public static boolean isKnown(Location location) {
+        return location != null && !Location.UNKNOWN.equals(location);
+    }
+
+    /**
+     * Checks if a location is unknown, i.e. it is either null or equal to {@link Location#UNKNOWN}.
+     * 
+     * @param location the location to check
+     * @return <code>true</code> if the location is unknown
+     */
+    public static boolean isUnknown(Location location) {
+        return location == null || Location.UNKNOWN.equals(location);
+    }
+
+    /**
+     * Add a {@link LocationFinder} to the list of finders that will be queried for an object's
+     * location by {@link #getLocation(Object, String)}.
+     * <p>
+     * <b>Important:</b> LocationUtils internally stores a weak reference to the finder. This
+     * avoids creating strong links between the classloader holding this class and the finder's
+     * classloader, which can cause some weird memory leaks if the finder's classloader is to
+     * be reloaded. Therefore, you <em>have</em> to keep a strong reference to the finder in the
+     * calling code, e.g.:
+     * <pre>
+     *   private static LocationUtils.LocationFinder myFinder =
+     *       new LocationUtils.LocationFinder() {
+     *           public Location getLocation(Object obj, String desc) {
+     *               ...
+     *           }
+     *       };
+     *
+     *   static {
+     *       LocationUtils.addFinder(myFinder);
+     *   }
+     * </pre>
+     * 
+     * @param finder the location finder to add
+     */
+    public static void addFinder(LocationFinder finder) {
+        if (finder == null) {
+            return;
+        }
+
+        synchronized(LocationFinder.class) {
+            // Update a clone of the current finder list to avoid breaking
+            // any iteration occuring in another thread.
+            List newFinders = new ArrayList(finders);
+            newFinders.add(new WeakReference(finder));
+            finders = newFinders;
+        }
+    }
+    
+    /**
+     * Get the location of an object. Some well-known located classes built in the JDK are handled
+     * by this method. Handling of other located classes can be handled by adding new location finders.
+     * 
+     * @param obj the object of which to get the location
+     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+     */
+    public static Location getLocation(Object obj) {
+        return getLocation(obj, null);
+    }
+    
+    /**
+     * Get the location of an object. Some well-known located classes built in the JDK are handled
+     * by this method. Handling of other located classes can be handled by adding new location finders.
+     * 
+     * @param obj the object of which to get the location
+     * @param description an optional description of the object's location, used if a Location object
+     *        has to be created.
+     * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+     */
+    public static Location getLocation(Object obj, String description) {
+        if (obj instanceof Locatable) {
+            return ((Locatable)obj).getLocation();
+        }
+        
+        // Check some well-known locatable exceptions
+        if (obj instanceof SAXParseException) {
+            SAXParseException spe = (SAXParseException)obj;
+            if (spe.getSystemId() != null) {
+                return new LocationImpl(description, spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+        
+        if (obj instanceof TransformerException) {
+            TransformerException ex = (TransformerException)obj;
+            SourceLocator locator = ex.getLocator();
+            if (locator != null && locator.getSystemId() != null) {
+                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+        
+        if (obj instanceof Locator) {
+            Locator locator = (Locator)obj;
+            if (locator.getSystemId() != null) {
+                return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+            } else {
+                return Location.UNKNOWN;
+            }
+        }
+
+        List currentFinders = finders; // Keep the current list
+        int size = currentFinders.size();
+        for (int i = 0; i < size; i++) {
+            WeakReference ref = (WeakReference)currentFinders.get(i);
+            LocationFinder finder = (LocationFinder)ref.get();
+            if (finder == null) {
+                // This finder was garbage collected: update finders
+                synchronized(LocationFinder.class) {
+                    // Update a clone of the current list to avoid breaking current iterations
+                    List newFinders = new ArrayList(finders);
+                    newFinders.remove(ref);
+                    finders = newFinders;
+                }
+            }
+            
+            Location result = finder.getLocation(obj, description);
+            if (result != null) {
+                return result;
+            }
+        }
+
+        return Location.UNKNOWN;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/MultiLocatable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/MultiLocatable.java
new file mode 100644
index 0000000..de9bc2e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/MultiLocatable.java
@@ -0,0 +1,39 @@
+package org.apache.cocoon.util.location;
+
+import java.util.List;
+
+/**
+ * An extension of {@link Location} for classes that can hold a list of locations.
+ * It will typically be used to build location stacks.
+ * <p>
+ * The <em>first</em> location of the collection returned by {@link #getLocations()} should be
+ * be identical to the result of {@link org.apache.cocoon.util.location.Locatable#getLocation()}.
+ * <p>
+ * If the list of locations designates a call stack, then its first element should be the deepmost
+ * location of this stack. This is consistent with the need for <code>getLocation()</code> to
+ * return the most precise location.
+ * 
+ * @since 2.1.8
+ * @version $Id$
+ */
+public interface MultiLocatable extends Locatable {
+    
+    /**
+     * Return the list of locations.
+     * 
+     * @return a list of locations, possibly empty but never null.
+     */
+    public List getLocations();
+    
+    /**
+     * Add a location to the current list of locations.
+     * <p>
+     * Implementations are free to filter locations that can be added (e.g. {@link Location#UNKNOWN}),
+     * and there is therefore no guarantee that the given location will actually be added to the list.
+     * Filtered locations are silently ignored.
+     * 
+     * @param location the location to be added.
+     */
+    public void addLocation(Location location);
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/package.html
new file mode 100644
index 0000000..840814b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/location/package.html
@@ -0,0 +1,3 @@
+<html>
+  <body>Classes and utilities used to track location information.</body>
+</html>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java
new file mode 100644
index 0000000..dd36425
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonLogFormatter.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util.log;
+
+import org.apache.avalon.framework.logger.LogKitLogger;
+
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.util.location.LocatedException;
+
+import org.apache.commons.lang.ClassUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang.time.FastDateFormat;
+import org.apache.log.ContextMap;
+import org.apache.log.LogEvent;
+import org.apache.log.Logger;
+
+import java.util.Map;
+
+/**
+ * An extended pattern formatter. New patterns defined by this class are:
+ * <ul>
+ * <li><code>class</code>: Outputs the name of the class that has logged the
+ *     message. The optional <code>short</code> subformat removes the
+ *     package name. Warning: This pattern works only if formatting occurs in
+ *     the same thread as the call to Logger, i.e. it won't work with
+ *     <code>AsyncLogTarget</code>.</li>
+ * <li><code>uri</code>: Outputs the request URI.</li>
+ * <li><code>query</code>: Outputs the request query string</li>
+ * <li><code>thread</code>: Outputs the name of the current thread (first element
+ *     on the context stack).</li>
+ * <li><code>host</code>: Outputs the request host header.<li>
+ * <li><code>rootThrowable</code>: Outputs the root throwable message and
+ *     stacktrace.<li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class CocoonLogFormatter extends ExtensiblePatternFormatter
+{
+    /**
+     * The constant defining the default stack depth when
+     * none other is specified.
+     */
+    public static final int DEFAULT_STACK_DEPTH = 8;
+
+    protected final static int     TYPE_CLASS  = MAX_TYPE + 1;
+    protected final static int     TYPE_URI    = MAX_TYPE + 2;
+    protected final static int     TYPE_THREAD = MAX_TYPE + 3;
+    protected final static int     TYPE_HOST   = MAX_TYPE + 4;
+    protected final static int     TYPE_QUERY  = MAX_TYPE + 5;
+    protected final static int     TYPE_ROOTTHROWABLE = MAX_TYPE + 6;
+
+    protected final static String  TYPE_CLASS_STR       = "class";
+    protected final static String  TYPE_CLASS_SHORT_STR = "short";
+
+    protected final static String  TYPE_URI_STR         = "uri";
+    protected final static String  TYPE_THREAD_STR      = "thread";
+    protected final static String  TYPE_HOST_STR        = "host";
+    protected final static String  TYPE_QUERY_STR       = "query";
+    protected final static String  TYPE_ROOTTHROWABLE_STR = "rootThrowable";
+
+    private static final String DEFAULT_TIME_PATTERN = "(yyyy-MM-dd) HH:mm.ss:SSS";
+    private static final FastDateFormat dateFormatter = FastDateFormat.getInstance(DEFAULT_TIME_PATTERN);
+
+    /**
+     * Hack to get the call stack as an array of classes. The
+     * SecurityManager class provides it as a protected method, so
+     * change it to public through a new method !
+     */
+    static class CallStack extends SecurityManager {
+        /**
+         * Returns the current execution stack as an array of classes.
+         * The length of the array is the number of methods on the execution
+         * stack. The element at index 0 is the class of the currently executing
+         * method, the element at index 1 is the class of that method's caller,
+         * and so on.
+         *
+         * @return current execution stack as an array of classes.
+         */
+        public Class[] get() {
+            return getClassContext();
+        }
+    }
+
+    /**
+     * The class that we will search for in the call stack
+     * (Avalon logging abstraction)
+     */
+    private final Class logkitClass = LogKitLogger.class;
+
+    /**
+     * The class that we will search for in the call stack
+     * (LogKit logger)
+     */
+    private final Class loggerClass = Logger.class;
+
+    /**
+     * The SecurityManager implementation which gives us access to
+     * the stack frame
+     */
+    private CallStack callStack;
+
+    public CocoonLogFormatter() {
+        try {
+            this.callStack = new CallStack();
+        } catch (SecurityException e) {
+            // Ignore security exception
+        }
+    }
+
+    protected int getTypeIdFor(String type) {
+        // Search for new patterns defined here, or else delegate
+        // to the parent class
+        if (type.equalsIgnoreCase(TYPE_CLASS_STR)) {
+            return TYPE_CLASS;
+        } else if (type.equalsIgnoreCase(TYPE_URI_STR)) {
+            return TYPE_URI;
+        } else if (type.equalsIgnoreCase(TYPE_THREAD_STR)) {
+            return TYPE_THREAD;
+        } else if (type.equalsIgnoreCase(TYPE_HOST_STR)) {
+            return TYPE_HOST;
+        } else if (type.equalsIgnoreCase(TYPE_QUERY_STR)) {
+            return TYPE_QUERY;
+        } else if (type.equalsIgnoreCase(TYPE_ROOTTHROWABLE_STR)) {
+            return TYPE_ROOTTHROWABLE;
+        } else {
+            return super.getTypeIdFor(type);
+        }
+    }
+
+    protected String formatPatternRun(LogEvent event, PatternRun run) {
+        // Format new patterns defined here, or else delegate to
+        // the parent class
+        switch (run.m_type) {
+            case TYPE_CLASS:
+                return getClass(run.m_format);
+            case TYPE_URI:
+                return getURI(event.getContextMap());
+            case TYPE_THREAD:
+                return getThread(event.getContextMap());
+            case TYPE_HOST:
+                return getHost(event.getContextMap());
+            case TYPE_QUERY:
+                return getQueryString(event.getContextMap());
+            case TYPE_ROOTTHROWABLE:
+                Throwable thr = event.getThrowable();
+                Throwable root = ExceptionUtils.getRootCause(thr); // Can be null if no cause
+                return getStackTrace(root == null ? thr : root, run.m_format);
+        }
+        return super.formatPatternRun(event, run);
+    }
+
+    /**
+     * Finds the class that has called Logger.
+     */
+    private String getClass(String format) {
+        if (this.callStack != null) {
+            Class[] stack = this.callStack.get();
+
+            // Traverse the call stack in reverse order until we find a Logger
+            for (int i = stack.length - 1; i >= 0; i--) {
+                if (this.logkitClass.isAssignableFrom(stack[i]) ||
+                    this.loggerClass.isAssignableFrom(stack[i])) {
+                    // Found: the caller is the previous stack element
+                    String className = stack[i + 1].getName();
+                    // Handle optional format
+                    if (TYPE_CLASS_SHORT_STR.equalsIgnoreCase(format)) {
+                        className = ClassUtils.getShortClassName(className);
+                    }
+                    return className;
+                }
+            }
+        }
+
+        // No callStack: can occur when running under SecurityManager, or
+        // no logger found in call stack: can occur with AsyncLogTarget
+        // where formatting takes place in a different thread.
+        return "Unknown-Class";
+    }
+
+    /**
+     * Find the URI that is being processed.
+     */
+    private String getURI(ContextMap ctxMap) {
+        // Get URI from the the object model.
+        if (ctxMap != null) {
+            final Object context = ctxMap.get("objectModel");
+            if (context != null && context instanceof Map) {
+                // Get the request
+                final Request request = ObjectModelHelper.getRequest((Map) context);
+                if (request != null) {
+                    return request.getRequestURI();
+                }
+            }
+        }
+
+        return "Unknown-URI";
+    }
+
+    /**
+     * Find request query string
+     */
+    private String getQueryString(ContextMap ctxMap) {
+        if (ctxMap != null) {
+            final Object context = ctxMap.get("objectModel");
+            if (context != null && context instanceof Map) {
+                // Get the request
+                final Request request = ObjectModelHelper.getRequest((Map) context);
+                if (request != null) {
+                    final String queryString = request.getQueryString();
+                    if (queryString != null) {
+                        return "?" + queryString;
+                    }
+                }
+            }
+        }
+        return "";
+    }
+
+    /**
+     * Find the host header of the request that is being processed.
+     */
+    private String getHost(ContextMap ctxMap) {
+        // Get URI from the the object model.
+        if (ctxMap != null) {
+            final Object context = ctxMap.get("objectModel");
+            if (context != null && context instanceof Map) {
+                // Get the request
+                final Request request = ObjectModelHelper.getRequest((Map) context);
+                if (request != null) {
+                    return request.getHeader("host");
+                }
+            }
+        }
+
+        return "Unknown-Host";
+    }
+
+    /**
+     * Find the thread that is logged this event.
+     */
+    private String getThread(ContextMap ctxMap) {
+        // Get thread name from the context.
+        if (ctxMap != null) {
+            final String threadName = (String) ctxMap.get("threadName");
+            if (threadName != null) {
+                return threadName;
+            }
+        }
+
+        return "Unknown-Thread";
+    }
+
+    /**
+     * Utility method to format stack trace so that CascadingExceptions are
+     * formatted with all nested exceptions.
+     *
+     * <p>FIXME: copied from AvalonFormatter, to be removed if ExtensiblePatternFormatter
+     * replaces PatternFormatter.</p>
+     *
+     * @param throwable the throwable instance
+     * @param format ancilliary format parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getStackTrace(final Throwable throwable, final String format) {
+        if (throwable != null) {
+            LocatedException.ensureCauseChainIsSet(throwable);
+            return ExceptionUtils.getStackTrace(throwable);
+            //return ExceptionUtil.printStackTrace(throwable, m_stackDepth);
+        }
+
+        return null;
+    }
+
+    /**
+     * Utility method to format time.
+     *
+     * @param time the time
+     * @param pattern ancilliary pattern parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getTime(final long time, String pattern) {
+        if (pattern == null || DEFAULT_TIME_PATTERN.equals(pattern)) {
+            return dateFormatter.format(time);
+        }
+        return FastDateFormat.getInstance(pattern).format(time);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonStreamTargetFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonStreamTargetFactory.java
new file mode 100644
index 0000000..3190646
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonStreamTargetFactory.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.log;
+
+import org.apache.avalon.excalibur.logger.factory.StreamTargetFactory;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.log.format.Formatter;
+
+/**
+ * TargetFactory for {@link org.apache.log.output.io.StreamTarget}.
+ *
+ * This factory is able to create different StreamTargets according to the following
+ * configuration syntax:
+ * <pre>
+ * &lt;stream id="foo"&gt;
+ *  &lt;stream&gt;<i>stream-context-name</i>&lt;/stream&gt;
+ *  &lt;format type="<i>raw|pattern|extended|xml|cocoon</i>"&gt;<i>pattern to be used if needed</i>&lt;/format&gt;
+ * &lt;/stream&gt;
+ * </pre>
+ *
+ * <p>The "stream-context-name" is the name of an <code>java.io.OutputStream</code> that
+ * is fetched in the context. This context contains two predefined streams :
+ * <li>"<code>System.out</code>" for the system output stream,</li>
+ * <li>"<code>System.err</code>" for the system error stream.</li>
+ * </p>
+ *
+ * <p>The syntax of "format" is the same as in <code>CocoonTargetFactory</code>.</p>
+ *
+ * @version $Id$
+ */
+public class CocoonStreamTargetFactory
+    extends StreamTargetFactory {
+        
+    //Format of default Cocoon formatter
+    private static final String CFORMAT =
+        "%7.7{priority} %{time}   [%8.8{category}] (%{uri}) %{thread}/%{class:short}: %{message}\\n%{throwable}";
+
+    //Format of default Cocoon XML formatter
+    private static final String XFORMAT =
+        "priority time category uri thread class message throwable";
+
+    protected Formatter getFormatter(final Configuration conf) {
+        final String type = conf.getAttribute("type", "unknown");
+
+        if ("cocoon".equals(type)) {
+            final CocoonLogFormatter formatter = new CocoonLogFormatter();
+            final String format = conf.getValue(CFORMAT);
+            formatter.setFormat(format);
+            return formatter;
+        } else if ("xml".equals(type)) {
+            final XMLCocoonLogFormatter formatter = new XMLCocoonLogFormatter();
+            final String format = conf.getValue(XFORMAT);
+            formatter.setTypes(format);
+            return formatter;
+        }
+
+        // default formatter
+        return super.getFormatter(conf);
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonTargetFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonTargetFactory.java
new file mode 100644
index 0000000..5e91146
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/CocoonTargetFactory.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.log;
+
+import org.apache.avalon.excalibur.logger.factory.FileTargetFactory;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.log.format.Formatter;
+
+/**
+ * CocoonTargetFactory class.
+ *
+ * This factory is able to create different LogTargets specific to Cocoon
+ * according to the following configuration syntax:
+ *
+ * <pre>
+ * &lt;file id="foo"&gt;
+ *  &lt;filename&gt;${context-key}/real-name/...&lt;/filename&gt;
+ *  &lt;format type="raw|pattern|extended|xml|cocoon"&gt;pattern to be used if needed&lt;/format&gt;
+ *  &lt;append&gt;true|false&lt;/append&gt;
+ *  &lt;rotation type="revolving|unique" init="5" max="10"&gt;
+ *   &lt;or&gt;
+ *    &lt;size&gt;10000000&lt;/size&gt;
+ *    &lt;time&gt;24:00:00&lt;/time&gt;
+ *    &lt;time&gt;12:00:00&lt;/time&gt;
+ *   &lt;/or&gt;
+ *  &lt;/rotate&gt;
+ * &lt;/file&gt;
+ * </pre>
+ *
+ * <p>Some explanations about the Elements used in the configuration:</p>
+ * <dl>
+ *  <dt>&lt;filename&gt;</dt>
+ *  <dd>
+ *   This denotes the name of the file to log to. It can be constructed
+ *   out of entries in the passed Context object as ${context-key}.
+ *   This element is required.
+ *  </dd>
+ *  <dt>&lt;format&gt;</dt>
+ *  <dd>
+ *   The type attribute of the pattern element denotes the type of
+ *   Formatter to be used and according to it the pattern to use for.
+ *   This elements defaults to:
+ *   <p>
+ *    %7.7{priority} %{time}   [%8.8{category}] (%{uri}) %{thread}/%{class:short}: %{message}\\n%{throwable}
+ *   </p>
+ *  </dd>
+ *  <dt>&lt;append&gt;<dt>
+ *  <dd>
+ *   If the log file should be deleted every time the logger is creates
+ *   (normally at the start of the applcation) or not and thus the log
+ *   entries will be appended. This elements defaults to false.
+ *  </dd>
+ *  <dt>&lt;rotation&gt;</dt>
+ *  <dd>
+ *   This is an optional element.
+ *   The type attribute determines which FileStrategy to user
+ *   (revolving=RevolvingFileStrategy, unique=UniqueFileStrategy).
+ *   The required init and max attribute are used to determine the initial and
+ *   maximum rotation to use on a type="revolving" attribute.
+ *  </dd>
+ *  <dt>&lt;or&gt;</dt>
+ *  <dd>uses the OrRotateStrategy to combine the children</dd>
+ *  <dt>&lt;size&gt;</dt>
+ *  <dd>
+ *   The number of bytes if no suffix used or kilo bytes (1024) if suffixed with
+ *   'k' or mega bytes (1024k) if suffixed with 'm' when a file rotation should
+ *   occur. It doesn't make sense to specify more than one.
+ *  </dd>
+ *  <dt>&lt;time&gt;</dt>
+ *  <dd>
+ *   The time as HH:MM:SS when a rotation should occur. If you like to rotate
+ *   a logfile more than once a day put an &lt;or&gt; element immediately after the
+ *   &lt;rotation&gt; element and specify the times (and one size, too) inside the
+ *   &lt;or&gt; element.
+ *  </dd>
+ * </dl>
+ *
+ * @version $Id$
+ */
+public class CocoonTargetFactory
+    extends FileTargetFactory
+{
+    //Format of default Cocoon formatter
+    private static final String CFORMAT =
+        "%7.7{priority} %{time}   [%8.8{category}] (%{uri}) %{thread}/%{class:short}: %{message}\\n%{throwable}";
+
+    //Format of default Cocoon XML formatter
+    private static final String XFORMAT =
+        "priority time category uri thread class message throwable";
+
+    protected Formatter getFormatter(final Configuration conf) {
+        final String type = conf.getAttribute("type", "unknown");
+
+        if ("cocoon".equals(type)) {
+            final CocoonLogFormatter formatter = new CocoonLogFormatter();
+            final String format = conf.getValue(CFORMAT);
+            formatter.setFormat(format);
+            return formatter;
+        } else if ("xml".equals(type)) {
+            final XMLCocoonLogFormatter formatter = new XMLCocoonLogFormatter();
+            final String format = conf.getValue(XFORMAT);
+            formatter.setTypes(format);
+            return formatter;
+        }
+        // default formatter
+        return super.getFormatter(conf);
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/ExtensiblePatternFormatter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/ExtensiblePatternFormatter.java
new file mode 100644
index 0000000..602eb96
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/ExtensiblePatternFormatter.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.log;
+
+import java.io.StringWriter;
+import java.util.Stack;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.log.LogEvent;
+import org.apache.log.Priority;
+import org.apache.log.format.Formatter;
+import org.apache.log.util.DefaultErrorHandler;
+
+/**
+ * A refactoring of <code>org.apache.log.format.PatternFormatter</code> that
+ * can be extended.
+ * This formater formats the LogEntries according to a input pattern string.
+ *
+ * The format of each pattern element can be %[+|-]#.#{field:subformat}
+ *
+ * The +|- indicates left or right justify.
+ * The #.# indicates the minimum and maximum size of output.
+ * 'field' indicates which field is to be output and must be one of
+ *  properties of LogEvent
+ * 'subformat' indicates a particular subformat and is currently unused.
+ *
+ * @version $Id$
+ */
+public class ExtensiblePatternFormatter
+    implements Formatter
+{
+    protected final static int         TYPE_TEXT            = 1;
+    protected final static int         TYPE_CATEGORY        = 2;
+    protected final static int         TYPE_MESSAGE         = 4;
+    protected final static int         TYPE_TIME            = 5;
+    protected final static int         TYPE_RELATIVE_TIME   = 6;
+    protected final static int         TYPE_THROWABLE       = 7;
+    protected final static int         TYPE_PRIORITY        = 8;
+
+    /**
+     * The maximum value used for TYPEs. Subclasses can define their own TYPEs
+     * starting at <code>MAX_TYPE + 1</code>.
+     */
+    protected final static int         MAX_TYPE             = 8;
+
+    protected final static String      TYPE_CATEGORY_STR      = "category";
+    protected final static String      TYPE_MESSAGE_STR       = "message";
+    protected final static String      TYPE_TIME_STR          = "time";
+    protected final static String      TYPE_RELATIVE_TIME_STR = "rtime";
+    protected final static String      TYPE_THROWABLE_STR     = "throwable";
+    protected final static String      TYPE_PRIORITY_STR      = "priority";
+
+    protected static class PatternRun {
+        public String    m_data;
+        public boolean   m_rightJustify;
+        public int       m_minSize;
+        public int       m_maxSize;
+        public int       m_type;
+        public String    m_format;
+    }
+
+    protected PatternRun m_formatSpecification[];
+
+    /**
+     * Extract and build a pattern from input string.
+     *
+     * @param stack the stack on which to place patterns
+     * @param pattern the input string
+     * @param index the start of pattern run
+     * @return the number of characters in pattern run
+     */
+    protected int addPatternRun(final Stack stack, final char pattern[], int index) {
+        final PatternRun run = new PatternRun();
+        final int start = index++;
+
+        // first check for a +|- sign
+        if ('+' == pattern[index]) {
+            index++;
+        } else if ('-' == pattern[index]) {
+            run.m_rightJustify = true;
+            index++;
+        }
+
+        if (Character.isDigit(pattern[index])) {
+            int total = 0;
+            while (Character.isDigit(pattern[index])) {
+                total = total * 10 + (pattern[index] - '0');
+                index++;
+            }
+            run.m_minSize = total;
+        }
+
+        //check for . sign indicating a maximum is to follow
+        if (index < pattern.length && '.' == pattern[index]) {
+            index++;
+            if (Character.isDigit(pattern[index])) {
+                int total = 0;
+                while (Character.isDigit(pattern[index])) {
+                    total = total * 10 + (pattern[ index ] - '0');
+                    index++;
+                }
+                run.m_maxSize = total;
+            }
+        }
+
+        if (index >= pattern.length || '{' != pattern[index]) {
+            throw new IllegalArgumentException(
+                    "Badly formed pattern at character " + index );
+        }
+
+        int typeStart = index;
+
+        while (index < pattern.length &&
+               pattern[index]!= ':' && pattern[index] != '}' ) {
+            index++;
+        }
+
+        int typeEnd = index - 1;
+
+        final String type = new String(pattern, typeStart + 1, typeEnd - typeStart);
+
+        run.m_type = getTypeIdFor( type );
+
+        if (index < pattern.length && pattern[index] == ':' ) {
+            index++;
+            while (index < pattern.length && pattern[index] != '}' ) {
+                index++;
+            }
+            final int length = index - typeEnd - 2;
+
+            if (0 != length) {
+                run.m_format = new String(pattern, typeEnd + 2, length);
+            }
+        }
+
+        if (index >= pattern.length || '}' != pattern[index]) {
+            throw new IllegalArgumentException(
+                    "Unterminated type in pattern at character " + index );
+        }
+        index++;
+        stack.push( run );
+        return index - start;
+    }
+
+    /**
+     * Extract and build a text run  from input string.
+     * It does special handling of '\n' and '\t' replaceing
+     * them with newline and tab.
+     *
+     * @param stack the stack on which to place runs
+     * @param pattern the input string
+     * @param index the start of the text run
+     * @return the number of characters in run
+     */
+    protected int addTextRun( final Stack stack, final char pattern[], int index ) {
+        final PatternRun run = new PatternRun();
+        final int start = index;
+        boolean escapeMode = false;
+
+        if ('%' == pattern[index]) {
+            index++;
+        }
+        final StringBuffer sb = new StringBuffer();
+        while (index < pattern.length && pattern[index] != '%') {
+            if (escapeMode) {
+                if ('n' == pattern[ index ]) {
+                    sb.append( SystemUtils.LINE_SEPARATOR );
+                } else if ('t' == pattern[ index ]) {
+                    sb.append( '\t' );
+                } else {
+                    sb.append( pattern[ index ] );
+                }
+                escapeMode = false;
+            } else if ('\\' == pattern[ index ]) {
+                escapeMode = true;
+            } else {
+                sb.append( pattern[ index ] );
+            }
+            index++;
+        }
+        run.m_data = sb.toString();
+        run.m_type = TYPE_TEXT;
+        stack.push(run);
+        return index - start;
+    }
+
+    /**
+     * Utility to append a string to buffer given certain constraints.
+     *
+     * @param sb the StringBuffer
+     * @param minSize the minimum size of output (0 to ignore)
+     * @param maxSize the maximum size of output (0 to ignore)
+     * @param rightJustify true if the string is to be right justified in it's box.
+     * @param output the input string
+     */
+    protected void append(final StringBuffer sb, final int minSize, final int maxSize,
+            final boolean rightJustify, final String output) {
+        if (output.length() < minSize) {
+            if (rightJustify) {
+                sb.append(StringUtils.leftPad(output, minSize));
+            } else {
+                sb.append(StringUtils.rightPad(output, minSize));
+            }
+        } else if (maxSize > 0) {
+            if (rightJustify) {
+                sb.append(StringUtils.right(output, maxSize));
+            } else {
+                sb.append(StringUtils.left(output, maxSize));
+            }
+        } else {
+            sb.append(output);
+        }
+    }
+
+    /**
+     * Format the event according to the pattern.
+     *
+     * @param event the event
+     * @return the formatted output
+     */
+    public String format(final LogEvent event) {
+        final StringBuffer sb = new StringBuffer();
+
+        for( int i = 0; i < m_formatSpecification.length; i++ ) {
+            final PatternRun run =  m_formatSpecification[i];
+            //treat text differently as it doesn't need min/max padding
+            if (run.m_type == TYPE_TEXT) {
+                sb.append(run.m_data);
+            } else {
+                final String data = formatPatternRun(event, run);
+                if (null != data) {
+                    append(sb, run.m_minSize, run.m_maxSize, run.m_rightJustify, data);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Formats a single pattern run (can be extended in subclasses).
+     *
+     * @param  run the pattern run to format.
+     * @return the formatted result.
+     */
+    protected String formatPatternRun( final LogEvent event, final PatternRun run )
+    {
+        String str = null;
+
+        switch (run.m_type)
+        {
+            case TYPE_RELATIVE_TIME:
+                str = getTime( event.getRelativeTime(), run.m_format );
+                break;
+            case TYPE_TIME:
+                str = getTime( event.getTime(), run.m_format );
+                break;
+            case TYPE_THROWABLE:
+                str = getStackTrace( event.getThrowable(), run.m_format );
+                break;
+            case TYPE_MESSAGE:
+                str = getMessage( event.getMessage(), run.m_format );
+                break;
+            case TYPE_CATEGORY:
+                str = getCategory( event.getCategory(), run.m_format );
+                break;
+            case TYPE_PRIORITY:
+                str = getPriority( event.getPriority(), run.m_format );
+                break;
+            default:
+                new DefaultErrorHandler().error("Unknown Pattern specification." + run.m_type, null, null);
+        }
+        return str;
+    }
+
+    /**
+     * Utility method to format category.
+     *
+     * @param category the category string
+     * @param format ancilliary format parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getCategory(final String category, final String format) {
+        return category;
+    }
+
+    /**
+     * Get formatted priority string.
+     */
+    protected String getPriority(final Priority priority, final String format) {
+        return priority.getName();
+    }
+
+    /**
+     * Correct a context string by replacing '.''s with a '_'.
+     *
+     * @param context the un-fixed context
+     * @return the fixed context
+     */
+    protected final String fix(final String context) {
+        return context.replace( '.', '_' );
+    }
+
+    /**
+     * Utility method to format message.
+     *
+     * @param message the message string
+     * @param format ancilliary format parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getMessage(final String message, final String format) {
+        return message;
+    }
+
+    /**
+     * Utility method to format stack trace.
+     *
+     * @param throwable the throwable instance
+     * @param format ancilliary format parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getStackTrace(final Throwable throwable, final String format) {
+        if (null != throwable) {
+            final StringWriter sw = new StringWriter();
+            throwable.printStackTrace(new java.io.PrintWriter(sw));
+            return sw.toString();
+        }
+        return "";
+    }
+
+    /**
+     * Utility method to format time.
+     *
+     * @param time the time
+     * @param format ancilliary format parameter - allowed to be null
+     * @return the formatted string
+     */
+    protected String getTime(final long time, final String format) {
+        return Long.toString(time);
+    }
+
+    /**
+     * Retrieve the type-id for a particular string.
+     *
+     * @param type the string
+     * @return the type-id
+     */
+    protected int getTypeIdFor(final String type) {
+        if (type.equalsIgnoreCase(TYPE_CATEGORY_STR)) {
+            return TYPE_CATEGORY;
+        } else if (type.equalsIgnoreCase(TYPE_MESSAGE_STR)) {
+            return TYPE_MESSAGE;
+        } else if (type.equalsIgnoreCase(TYPE_PRIORITY_STR)) {
+            return TYPE_PRIORITY;
+        } else if (type.equalsIgnoreCase(TYPE_TIME_STR)) {
+            return TYPE_TIME;
+        } else if (type.equalsIgnoreCase(TYPE_RELATIVE_TIME_STR)) {
+            return TYPE_RELATIVE_TIME;
+        } else if (type.equalsIgnoreCase(TYPE_THROWABLE_STR)) {
+            return TYPE_THROWABLE;
+        } else {
+            throw new IllegalArgumentException( "Unknown Type in pattern - " + type );
+        }
+    }
+
+    /**
+     * Parse the input pattern and build internal data structures.
+     *
+     * @param patternString the pattern
+     */
+    protected void parse(final String patternString) {
+        final Stack stack = new Stack();
+        final int size = patternString.length();
+        final char pattern[] = new char[size];
+        int index = 0;
+
+        patternString.getChars(0, size, pattern, 0);
+        while (index < size) {
+            if (pattern[index] == '%' &&
+                !(index != size - 1 && pattern[index + 1] == '%' )) {
+                index += addPatternRun(stack, pattern, index);
+            } else {
+                index +=  addTextRun(stack, pattern, index);
+            }
+        }
+        final int elementCount = stack.size();
+        m_formatSpecification = new PatternRun[elementCount];
+
+        for (int i = 0; i < elementCount; i++) {
+            m_formatSpecification[i] = (PatternRun) stack.elementAt(i);
+        }
+    }
+
+    /**
+     * Set the string description that the format is extracted from.
+     *
+     * @param format the string format
+     */
+    public void setFormat(final String format) {
+        parse(format);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/XMLCocoonLogFormatter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/XMLCocoonLogFormatter.java
new file mode 100644
index 0000000..16c2c59
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/XMLCocoonLogFormatter.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.log;
+
+import org.apache.avalon.framework.CascadingThrowable;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.commons.lang.ClassUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.log.ContextMap;
+import org.apache.log.LogEvent;
+import org.apache.log.Logger;
+import org.apache.log.format.Formatter;
+
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * A refactoring of <code>org.apache.log.format.PatternFormatter</code>
+ * and <code>org.apache.cocoon.util.log.CocoonLogFormatter</code> for
+ * producing XML format.
+ * This formater formats the LogEntries according to given input types. Each
+ * log entry is inside a &lt;log-entry&gt; element and each information is
+ * inside an own element.
+ *
+ * <ul>
+ * <li><code>class</code> : outputs the name of the class that has logged the
+ *     message. The optional <code>short</code> subformat removes the
+ *     package name. Warning : this pattern works only if formatting occurs in
+ *     the same thread as the call to Logger, i.e. it won't work with
+ *     <code>AsyncLogTarget</code>. The class name is embeded by a &lt;class&gt;
+ *     element.</li>
+ * <li><code>thread</code> : outputs the name of the current thread (first element
+ *     on the context stack). The thread name is surrounded by a &lt;thread&gt;
+ *     element.</li>
+ * <li><code>uri</code> : outputs the request URI (&lt;uri&gt;).<li>
+ * <li><code>category</code> : outputs the log category (&lt;category&gt;).<li>
+ * <li><code>message</code> : outputs the message (&lt;message&gt;).<li>
+ * <li><code>time</code> : outputs the time (&lt;time&gt;).<li>
+ * <li><code>rtime</code> : outputs the relative time (&lt;relative-time&gt;).<li>
+ * <li><code>throwable</code> : outputs the exception (&lt;throwable&gt;).<li>
+ * <li><code>priority</code> : outputs the priority (&lt;priority&gt;).<li>
+ * <li><code>host</code> : outputs the request host header (&lt;priority&gt;).<li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class XMLCocoonLogFormatter implements Formatter {
+
+    protected final static String  TYPE_CLASS_STR       = "class";
+    protected final static String  TYPE_CLASS_SHORT_STR = "short";
+
+    protected final static int         TYPE_REQUEST_URI     = 0;
+    protected final static int         TYPE_CATEGORY        = 1;
+    protected final static int         TYPE_MESSAGE         = 2;
+    protected final static int         TYPE_TIME            = 3;
+    protected final static int         TYPE_RELATIVE_TIME   = 4;
+    protected final static int         TYPE_THROWABLE       = 5;
+    protected final static int         TYPE_PRIORITY        = 6;
+    protected final static int         TYPE_CLASS        = 7;
+    protected final static int         TYPE_CLASS_SHORT        = 8;
+    protected final static int         TYPE_THREAD        = 9;
+    protected final static int         TYPE_HOST          = 10;
+
+    public final static String[] typeStrings = new String[] {"uri", // 0
+         "category",  // 1
+         "message",   // 2
+         "time",      // 3
+         "rtime",     // 4
+         "throwable", // 5
+         "priority",  // 6
+         "class",    // 7
+         "class:short", // 8
+         "thread",   // 9
+         "host"};   // 10
+
+    protected final SimpleDateFormat dateFormatter = new SimpleDateFormat("(yyyy-MM-dd) HH:mm.ss:SSS");
+
+    protected int[] types;
+
+    /**
+     * Format the event according to the pattern.
+     *
+     * @param event the event
+     * @return the formatted output
+     */
+    public String format( final LogEvent event ) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("<log-entry>").append(SystemUtils.LINE_SEPARATOR);
+        final String value = this.getRequestId(event.getContextMap());
+        if (value != null) {
+            sb.append("<request-id>").append(value).append("</request-id>").append(SystemUtils.LINE_SEPARATOR);
+        }
+        for(int i = 0; i < this.types.length; i++) {
+            switch(this.types[i]) {
+                case TYPE_REQUEST_URI:
+                    sb.append("<uri>");
+                    sb.append(this.getURI(event.getContextMap()));
+                    sb.append("</uri>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_CLASS:
+                    sb.append("<class>");
+                    sb.append(this.getClass(TYPE_CLASS));
+                    sb.append("</class>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_CLASS_SHORT:
+                    sb.append("<class>");
+                    sb.append(this.getClass(TYPE_CLASS_SHORT));
+                    sb.append("</class>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_THREAD:
+                    sb.append("<thread>");
+                    sb.append(this.getThread(event.getContextMap()));
+                    sb.append("</thread>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_RELATIVE_TIME:
+                    sb.append("<relative-time>");
+                    sb.append(event.getRelativeTime());
+                    sb.append("</relative-time>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_TIME:
+                    sb.append("<time>");
+                    sb.append(dateFormatter.format(new Date(event.getTime())));
+                    sb.append("</time>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_THROWABLE:
+                    Throwable throwable = event.getThrowable();
+                    if (throwable != null) {
+                        sb.append("<throwable><![CDATA[").append(SystemUtils.LINE_SEPARATOR);
+                        while (throwable != null) {
+                            final StringWriter sw = new StringWriter();
+                            throwable.printStackTrace( new java.io.PrintWriter( sw ) );
+                            sb.append(sw.toString());
+                            if (throwable instanceof CascadingThrowable ) {
+                                throwable = ((CascadingThrowable)throwable).getCause();
+                            } else {
+                                throwable = null;
+                            }
+                        }
+                        sb.append(SystemUtils.LINE_SEPARATOR).append("]]> </throwable>").append(SystemUtils.LINE_SEPARATOR);
+                    }
+                    break;
+                case TYPE_MESSAGE:
+                    sb.append("<message><![CDATA[").append(SystemUtils.LINE_SEPARATOR);
+                    sb.append(event.getMessage());
+                    sb.append(SystemUtils.LINE_SEPARATOR).append("]]> </message>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_CATEGORY:
+                    sb.append("<category>");
+                    sb.append(event.getCategory());
+                    sb.append("</category>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_PRIORITY:
+                    sb.append("<priority>");
+                    sb.append(event.getPriority().getName());
+                    sb.append("</priority>").append(SystemUtils.LINE_SEPARATOR);
+                    break;
+                case TYPE_HOST:
+                    sb.append("<host>");
+                    sb.append(getHost(event.getContextMap()));
+                    sb.append("</host>");
+                    break;
+            }
+        }
+        sb.append("</log-entry>");
+        sb.append(SystemUtils.LINE_SEPARATOR);
+        return sb.toString();
+    }
+
+    /**
+     * Find the URI that is being processed.
+     */
+    private String getURI(ContextMap ctxMap) {
+        String result = "Unknown-URI";
+
+        // Get URI from the the object model.
+        if (ctxMap != null) {
+            Object context = ctxMap.get("objectModel");
+            if (context != null &&context instanceof Map) {
+                // Get the request
+                Request request = ObjectModelHelper.getRequest((Map)context);
+                if (request != null) {
+                    result = request.getRequestURI();
+                }
+            }
+        }
+        return result;
+    }
+
+    private String getHost(ContextMap ctxMap) {
+        String result = "Unknown-host";
+
+        if (ctxMap != null) {
+            Object context = ctxMap.get("objectModel");
+            if (context != null && context instanceof Map) {
+                // Get the request
+                Request request = ObjectModelHelper.getRequest((Map)context);
+                if (request != null) {
+                    result = request.getHeader("host");
+                }
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Find the request id that is being processed.
+     */
+    private String getRequestId(ContextMap ctxMap) {
+        String result = null;
+
+        // Get URI from the the object model.
+        if (ctxMap != null) {
+            Object context = ctxMap.get("request-id");
+            if (context != null) {
+                result = context.toString();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Finds the class that has called Logger.
+     */
+    private String getClass(int format) {
+
+        Class[] stack = this.callStack.get();
+
+        // Traverse the call stack in reverse order until we find a Logger
+        for (int i = stack.length-1; i >= 0; i--) {
+            if (this.loggerClass.isAssignableFrom(stack[i])) {
+
+                // Found : the caller is the previous stack element
+                String className = stack[i+1].getName();
+
+                // Handle optional format
+                if (format  == TYPE_CLASS_SHORT) {
+                    className = ClassUtils.getShortClassName(className);
+                }
+                return className;
+            }
+        }
+
+        // No Logger found in call stack : can occur with AsyncLogTarget
+        // where formatting takes place in a different thread.
+        return "Unknown-class";
+    }
+
+    /**
+     * Find the thread that is logged this event.
+     */
+    private String getThread(ContextMap ctxMap) {
+        if (ctxMap != null && ctxMap.get("threadName") != null) {
+            return (String)ctxMap.get("threadName");
+        } else {
+            return "Unknown-thread";
+        }
+    }
+
+    /**
+     * Retrieve the type-id for a particular string.
+     *
+     * @param type the string
+     * @return the type-id
+     */
+    protected int getTypeIdFor(final String type) {
+        for (int index = 0; index < typeStrings.length; index++) {
+            if (type.equalsIgnoreCase(typeStrings[index])) {
+                return index;
+            }
+        }
+        throw new IllegalArgumentException( "Unknown Type - " + type );
+    }
+
+    /**
+     * Set the types from an array of strings.
+     */
+    public void setTypes(String[] typeStrings) {
+        if (typeStrings != null) {
+            this.types = new int[typeStrings.length];
+            for (int i = 0; i < typeStrings.length; i++) {
+                this.types[i] = this.getTypeIdFor(typeStrings[i]);
+            }
+        } else {
+            this.types = new int[0];
+        }
+    }
+
+    /**
+     * Set the types from a whitespace separated string
+     */
+    public void setTypes(String typeString) {
+        if (typeString == null) {
+            this.types = new int[0];
+        } else {
+            // this is not the best implementation, but it works...
+            StringTokenizer st = new StringTokenizer(typeString);
+            this.types = new int[st.countTokens()];
+            for (int i = 0; i < this.types.length; i++) {
+                this.types[i] = this.getTypeIdFor(st.nextToken());
+            }
+        }
+    }
+
+    /** The class that we will search for in the call stack */
+    private Class loggerClass = Logger.class;
+    private CallStack callStack = new CallStack();
+
+    /**
+     * Hack to get the call stack as an array of classes. The
+     * SecurityManager class provides it as a protected method, so
+     * change it to public through a new method !
+     */
+    static public class CallStack extends SecurityManager
+    {
+        /**
+         * Returns the current execution stack as an array of classes.
+         * The length of the array is the number of methods on the execution
+         * stack. The element at index 0 is the class of the currently executing
+         * method, the element at index 1 is the class of that method's caller,
+         * and so on.
+         *
+         * @return current execution stack as an array of classes.
+         */
+        public Class[] get() {
+            return getClassContext();
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/package.html b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/package.html
new file mode 100644
index 0000000..9bd546b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/log/package.html
@@ -0,0 +1,25 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+ <title>LogKit related utilities</title>
+</head>
+<body>
+ <h1>LogKit related utilities</h1>
+ <p>
+ </p>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/mime.types b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/mime.types
new file mode 100644
index 0000000..d720136
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/util/mime.types
@@ -0,0 +1,28 @@
+# MIME type mappings
+text/plain  txt text
+text/html   html htm
+text/xml    xml
+text/css    css
+text/rtf    rtf
+application/rtf rtf
+text/vnd.wap.wml    wml
+image/jpeg  jpeg jpg jpe
+image/png   png
+image/gif   gif
+image/tiff  tiff tif
+image/svg+xml   svg svgz
+image/svg-xml   svg
+application/pdf pdf
+model/vrml  wrl
+application/smil    smil
+text/javascript js
+application/x-javascript    js
+text/vbscript   vbs
+application/zip zip
+video/mpeg  mpeg mpg mpe
+video/quicktime mov
+audio/midi  mid
+audio/mpeg  mp3
+text/x-vcard    vcf
+text/rdf    rdf
+application/octet-stream
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractDOMFragment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractDOMFragment.java
new file mode 100644
index 0000000..fe4b54c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractDOMFragment.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+/**
+ * Abstract implementation of {@link XMLFragment} for objects that are more
+ * easily represented as a DOM.
+ *
+ * <p>The {@link #toSAX} method is implemented by streaming (using a
+ * {@link DOMStreamer}) the results of the {@link #toDOM(Node)} that must be
+ * implemented by concrete subclasses.</p>
+ *
+ * @version $Id$
+ */
+public abstract class AbstractDOMFragment implements XMLFragment {
+
+    /**
+     * Generates SAX events representing the object's state by serializing the
+     * result of <code>toDOM()</code>.
+     */
+    public void toSAX(ContentHandler handler) throws SAXException {
+        // The ServiceManager is unknown here : use JAXP to create a document
+        DocumentBuilder builder;
+        try {
+            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new SAXException("Couldn't get a DocumentBuilder", e);
+        }
+
+        Document doc = builder.newDocument();
+
+        // Create a DocumentFragment that will hold the results of toDOM()
+        // (which can create several top-level elements)
+        Node df = doc.createDocumentFragment();
+
+        // Build the DOM representation of this object
+        try {
+            toDOM(df);
+        } catch(Exception e) {
+            throw new SAXException("Exception while converting object to DOM", e);
+        }
+
+        // Stream the document fragment
+        handler.startDocument();
+        new DOMStreamer(handler).stream(df);
+        handler.endDocument();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractSAXFragment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractSAXFragment.java
new file mode 100644
index 0000000..f38f965
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractSAXFragment.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+
+/**
+ * Abstract implementation of {@link XMLFragment} for objects that are more
+ * easily represented as SAX events.
+ *
+ * <p>The {@link #toDOM} method is implemented by piping in a {@link DOMBuilder}
+ * the results of {@link #toSAX(ContentHandler)} that must be implemented by concrete
+ * subclasses.</p>
+ *
+ * @version $Id$
+ */
+public abstract class AbstractSAXFragment implements XMLFragment {
+
+    /**
+     * Appends children representing the object's state to the given node
+     * by using the results of <code>toSAX()</code>.
+     */
+    public void toDOM(Node node) throws Exception {
+        toSAX(new DOMBuilder(node));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLConsumer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLConsumer.java
new file mode 100644
index 0000000..0d3763a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLConsumer.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * This abstract class provides default implementation of the methods specified
+ * by the <code>XMLConsumer</code> interface.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractXMLConsumer extends AbstractLogEnabled implements XMLConsumer {
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     *
+     * @param locator An object that can return the location of any SAX
+     *                document event.
+     */
+    public void setDocumentLocator(Locator locator) {
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument()
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument()
+    throws SAXException {
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     *
+     * @param prefix The prefix that was being mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void characters(char ch[], int start, int len)
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * @param ch The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void ignorableWhitespace(char ch[], int start, int len)
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if none was
+     *             supplied.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity.  If it is a  parameter
+     *             entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external DTD
+     *                 subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external DTD
+     *                 subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     * @param name The name of the entity. If it is a parameter entity, the
+     *             name will begin with '%'.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+    }
+
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java
new file mode 100644
index 0000000..28e6d95
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLPipe.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * This class provides a bridge class to connect to existing content
+ * handlers and lexical handlers.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractXMLPipe extends AbstractXMLProducer
+                                      implements XMLPipe {
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     *
+     * @param locator An object that can return the location of any SAX
+     *                document event.
+     */
+    public void setDocumentLocator(Locator locator) {
+        contentHandler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument()
+    throws SAXException {
+        contentHandler.startDocument();
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument()
+    throws SAXException {
+        contentHandler.endDocument();
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     *
+     * @param prefix The Namespace prefix being declared.
+     * @param uri The Namespace URI the prefix is mapped to.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        contentHandler.startPrefixMapping(prefix, uri);
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     *
+     * @param prefix The prefix that was being mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        contentHandler.endPrefixMapping(prefix);
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     * @param a The attributes attached to the element. If there are no
+     *          attributes, it shall be an empty Attributes object.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        contentHandler.startElement(uri, loc, raw, a);
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     *
+     * @param uri The Namespace URI, or the empty string if the element has no
+     *            Namespace URI or if Namespace
+     *            processing is not being performed.
+     * @param loc The local name (without prefix), or the empty string if
+     *            Namespace processing is not being performed.
+     * @param raw The raw XML 1.0 name (with prefix), or the empty string if
+     *            raw names are not available.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        contentHandler.endElement(uri, loc, raw);
+    }
+
+    /**
+     * Receive notification of character data.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void characters(char c[], int start, int len)
+    throws SAXException {
+        contentHandler.characters(c, start, len);
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     *
+     * @param c The characters from the XML document.
+     * @param start The start position in the array.
+     * @param len The number of characters to read from the array.
+     */
+    public void ignorableWhitespace(char c[], int start, int len)
+    throws SAXException {
+        contentHandler.ignorableWhitespace(c, start, len);
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     *
+     * @param target The processing instruction target.
+     * @param data The processing instruction data, or null if none was
+     *             supplied.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        contentHandler.processingInstruction(target, data);
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity.  If it is a  parameter
+     *             entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        contentHandler.skippedEntity(name);
+    }
+
+    /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external DTD
+     *                 subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external DTD
+     *                 subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        lexicalHandler.startDTD(name, publicId, systemId);
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+        lexicalHandler.endDTD();
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     * @param name The name of the entity. If it is a parameter entity, the
+     *             name will begin with '%'.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+        lexicalHandler.startEntity(name);
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+        lexicalHandler.endEntity(name);
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+        lexicalHandler.startCDATA();
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+        lexicalHandler.endCDATA();
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        lexicalHandler.comment(ch, start, len);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLProducer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLProducer.java
new file mode 100644
index 0000000..83d38ac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AbstractXMLProducer.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * This abstract class provides default implementation of the methods specified
+ * by the <code>XMLProducer</code> interface.
+ *
+ * @version $Id$
+ */
+public abstract class AbstractXMLProducer extends AbstractLogEnabled
+                                          implements XMLProducer, Recyclable {
+    
+    protected static final ContentHandler EMPTY_CONTENT_HANDLER = new DefaultHandler();
+
+    /** The <code>XMLConsumer</code> receiving SAX events. */
+    protected XMLConsumer xmlConsumer;
+
+    /** The <code>ContentHandler</code> receiving SAX events. */
+    protected ContentHandler contentHandler = EMPTY_CONTENT_HANDLER;
+
+    /** The <code>LexicalHandler</code> receiving SAX events. */
+    protected LexicalHandler lexicalHandler = DefaultLexicalHandler.NULL_HANDLER;
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     * <br>
+     * This method will simply call <code>setContentHandler(consumer)</code>
+     * and <code>setLexicalHandler(consumer)</code>.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        this.xmlConsumer = consumer;
+        setContentHandler(consumer);
+        setLexicalHandler(consumer);
+    }
+
+    /**
+     * Set the <code>ContentHandler</code> that will receive XML data.
+     * <br>
+     * Subclasses may retrieve this <code>ContentHandler</code> instance
+     * accessing the protected <code>super.contentHandler</code> field.
+     */
+    public void setContentHandler(ContentHandler handler) {
+        this.contentHandler = handler;
+    }
+
+    /**
+     * Set the <code>LexicalHandler</code> that will receive XML data.
+     * <br>
+     * Subclasses may retrieve this <code>LexicalHandler</code> instance
+     * accessing the protected <code>super.lexicalHandler</code> field.
+     */
+    public void setLexicalHandler(LexicalHandler handler) {
+        this.lexicalHandler = handler;
+    }
+
+    /**
+     * Recycle the producer by removing references, and resetting handlers to
+     * null (empty) implementations.
+     */
+    public void recycle() {
+        this.xmlConsumer = null;
+        this.contentHandler = EMPTY_CONTENT_HANDLER;
+        this.lexicalHandler = DefaultLexicalHandler.NULL_HANDLER;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributeTypes.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributeTypes.java
new file mode 100644
index 0000000..d39f8e8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributeTypes.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+/**
+ * Insert the type's description here.
+ * 
+ * @version $Id$
+ */
+public interface AttributeTypes {
+
+    String CDATA = "CDATA";
+    String ENTITY = "ENTITY";
+    String ENTITIES = "ENTITIES";
+    String ID = "ID";
+    String IDREF = "IDREF";
+    String IDREFS = "IDREFS";
+    String NAME = "NAME";
+    String NAMES = "NAMES";
+    String NMTOKEN = "NMTOKEN";
+    String NMTOKENS = "NMTOKENS";
+    String NOTATION = "NOTATION";
+    String NUMBER = "NUMBER";
+    String NUMBERS = "NUMBERS";
+    String NUTOKEN = "NUTOKEN";
+    String NUTOKENS = "NUTOKENS";
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributesImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributesImpl.java
new file mode 100644
index 0000000..ea88bad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/AttributesImpl.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+
+/**
+ * A helper Class creating SAX Attributes
+ * 
+ * @version $Id$
+ */
+public class AttributesImpl extends org.xml.sax.helpers.AttributesImpl {
+
+    /**
+     * Constructor
+     */
+    public AttributesImpl() {
+        super();
+    }
+
+    /**
+     *  Constructor
+     */
+    public AttributesImpl(Attributes attr) {
+        super(attr);
+    }
+
+	/**
+	 * Add an attribute of type CDATA with empty Namespace to the end of the list.
+	 *
+	 * <p>For the sake of speed, this method does no checking
+	 * to see if the attribute is already in the list: that is
+	 * the responsibility of the application.</p>
+	 *
+	 * @param localName The local name.
+	 * @param value The attribute value.
+	 */
+	public void addCDATAAttribute(String localName, String value) {
+		addAttribute("", localName, localName, AttributeTypes.CDATA, value);
+	}
+    
+    /**
+     * Add an attribute of type CDATA with the namespace to the end of the list.
+     *
+     * <p>For the sake of speed, this method does no checking
+     * to see if the attribute is already in the list: that is
+     * the responsibility of the application.</p>
+     *
+     * @param namespace The namespace.
+     * @param localName The local name.
+     * @param value The attribute value.
+     */
+    public void addCDATAAttribute(String namespace, String localName, String value) {
+        addAttribute(namespace, localName, localName, AttributeTypes.CDATA, value);
+    }
+
+    /**
+	 * Add an attribute of type CDATA to the end of the list.
+	 *
+	 * <p>For the sake of speed, this method does no checking
+	 * to see if the attribute is already in the list: that is
+	 * the responsibility of the application.</p>
+	 *
+	 * @param uri The Namespace URI, or the empty string if
+	 *        none is available or Namespace processing is not
+	 *        being performed.
+	 * @param localName The local name, or the empty string if
+	 *        Namespace processing is not being performed.
+	 * @param qName The qualified (prefixed) name, or the empty string
+	 *        if qualified names are not available.
+	 * @param value The attribute value.
+	 */
+	public void addCDATAAttribute(String uri,
+                            		String localName,
+                            		String qName,
+                            		String value) {
+		addAttribute(uri, localName, qName, AttributeTypes.CDATA, value);
+	}
+    
+    /**
+     * Remove an attribute
+     */
+    public void removeAttribute(String localName) {
+        final int index = this.getIndex(localName);
+        if ( index != -1 ) {
+            this.removeAttribute(index);
+        }
+    }
+
+    /**
+     * Remove an attribute
+     */
+    public void removeAttribute(String uri, String localName) {
+        final int index = this.getIndex(uri, localName);
+        if ( index != -1 ) {
+            this.removeAttribute(index);
+        }
+    }
+}
+  
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ContentHandlerWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ContentHandlerWrapper.java
new file mode 100644
index 0000000..de94ef6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ContentHandlerWrapper.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class is an utility class &quot;wrapping&quot; around a SAX version 2.0
+ * <code>ContentHandler</code> and forwarding it those events received throug
+ * its <code>XMLConsumers</code> interface.
+ * <br>
+ *
+ * @version $Id$
+ */
+public class ContentHandlerWrapper extends AbstractXMLConsumer implements Recyclable {
+
+    /** The current <code>ContentHandler</code>. */
+    protected ContentHandler contentHandler;
+
+    /** The optional <code>LexicalHandler</code> */
+    protected LexicalHandler lexicalHandler;
+
+    /**
+     * Create a new <code>ContentHandlerWrapper</code> instance.
+     */
+    public ContentHandlerWrapper() {
+        super();
+     }
+
+    /**
+     * Create a new <code>ContentHandlerWrapper</code> instance.
+     */
+    public ContentHandlerWrapper(ContentHandler contentHandler) {
+        this();
+        this.setContentHandler(contentHandler);
+    }
+
+    /**
+     * Create a new <code>ContentHandlerWrapper</code> instance.
+     */
+    public ContentHandlerWrapper(ContentHandler contentHandler,
+                                 LexicalHandler lexicalHandler) {
+        this();
+        this.setContentHandler(contentHandler);
+        this.setLexicalHandler(lexicalHandler);
+    }
+
+    /**
+     * Set the <code>ContentHandler</code> that will receive XML data.
+     *
+     * @exception IllegalStateException If the <code>ContentHandler</code>
+     *                                  was already set.
+     */
+    public void setContentHandler(ContentHandler contentHandler)
+    throws IllegalStateException {
+        if (this.contentHandler!=null) throw new IllegalStateException();
+        this.contentHandler=contentHandler;
+    }
+
+    /**
+     * Set the <code>LexicalHandler</code> that will receive XML data.
+     *
+     * @exception IllegalStateException If the <code>LexicalHandler</code>
+     *                                  was already set.
+     */
+    public void setLexicalHandler(LexicalHandler lexicalHandler)
+    throws IllegalStateException {
+        if (this.lexicalHandler!=null) throw new IllegalStateException();
+        this.lexicalHandler=lexicalHandler;
+    }
+
+    public void recycle () {
+        this.contentHandler = null;
+        this.lexicalHandler = null;
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     */
+    public void setDocumentLocator (Locator locator) {
+        if (this.contentHandler==null) return;
+        else this.contentHandler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument ()
+    throws SAXException {
+        if (this.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        this.contentHandler.startDocument();
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument ()
+    throws SAXException {
+        this.contentHandler.endDocument();
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        if (this.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        this.contentHandler.startPrefixMapping(prefix, uri);
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        this.contentHandler.endPrefixMapping(prefix);
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        this.contentHandler.startElement(uri, loc, raw, a);
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        this.contentHandler.endElement(uri, loc, raw);
+    }
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters(char ch[], int start, int len)
+    throws SAXException {
+        this.contentHandler.characters(ch,start,len);
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace(char ch[], int start, int len)
+    throws SAXException {
+        this.contentHandler.ignorableWhitespace(ch,start,len);
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        this.contentHandler.processingInstruction(target,data);
+    }
+
+    /**
+     * Receive notification of a skipped entity.
+     *
+     * @param name The name of the skipped entity.  If it is a  parameter
+     *             entity, the name will begin with '%'.
+     */
+    public void skippedEntity(String name)
+    throws SAXException {
+        this.contentHandler.skippedEntity(name);
+    }
+
+        /**
+     * Report the start of DTD declarations, if any.
+     *
+     * @param name The document type name.
+     * @param publicId The declared public identifier for the external DTD
+     *                 subset, or null if none was declared.
+     * @param systemId The declared system identifier for the external DTD
+     *                 subset, or null if none was declared.
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.startDTD(name, publicId, systemId);
+    }
+
+    /**
+     * Report the end of DTD declarations.
+     */
+    public void endDTD()
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.endDTD();
+    }
+
+    /**
+     * Report the beginning of an entity.
+     *
+     * @param name The name of the entity. If it is a parameter entity, the
+     *             name will begin with '%'.
+     */
+    public void startEntity(String name)
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.startEntity(name);
+    }
+
+    /**
+     * Report the end of an entity.
+     *
+     * @param name The name of the entity that is ending.
+     */
+    public void endEntity(String name)
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.endEntity(name);
+    }
+
+    /**
+     * Report the start of a CDATA section.
+     */
+    public void startCDATA()
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.startCDATA();
+    }
+
+    /**
+     * Report the end of a CDATA section.
+     */
+    public void endCDATA()
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.endCDATA();
+    }
+
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        if (this.lexicalHandler != null)
+            this.lexicalHandler.comment(ch, start, len);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DefaultLexicalHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DefaultLexicalHandler.java
new file mode 100644
index 0000000..68c0881
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DefaultLexicalHandler.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * Default implementation of SAX's <code>LexicalHandler</code> interface. Empty implementation
+ * of all methods so that you only have to redefine the ones of interest.
+ *
+ * @version $Id$
+ */
+public class DefaultLexicalHandler implements LexicalHandler {
+    
+    /**
+     * Shared instance that can be used when lexical events should be ignored.
+     */
+    public static final LexicalHandler NULL_HANDLER = new DefaultLexicalHandler();
+
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        // nothing
+    }
+
+    public void endDTD() throws SAXException {
+        // nothing
+    }
+
+    public void startEntity(String name) throws SAXException {
+        // nothing
+    }
+
+    public void endEntity(String name) throws SAXException {
+        // nothing
+    }
+
+    public void startCDATA() throws SAXException {
+        // nothing
+    }
+
+    public void endCDATA() throws SAXException {
+        // nothing
+    }
+
+    public void comment(char[] ch, int start, int length) throws SAXException {
+        // nothing
+    }
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerAdapter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerAdapter.java
new file mode 100644
index 0000000..060d33a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerAdapter.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class is an utility class &quot;adapting&quot; a SAX version 1.0
+ * <code>DocumentHandler</code>, to SAX version 2 <code>ContentHandler</code>.
+ * <br>
+ * This class fully supports XML namespaces, converting <code>xmlns</code> and
+ * <code>xmlns:...</code> element attributes into appropriate
+ * <code>startPrefixMapping(...)</code> and <code>endPrefixMapping(...)</code>
+ * calls.
+ *
+ * @version $Id$
+ */
+public class DocumentHandlerAdapter extends AbstractXMLProducer
+implements DocumentHandler {
+
+    /** The element-oriented namespace-uri stacked mapping table. */
+    private Hashtable stackedNS=new Hashtable();
+    /** The current namespaces table. */
+    private NamespacesTable namespaces=new NamespacesTable();
+    /** The current stack depth.*/
+    private int stack=0;
+
+    /**
+     * Create a new <code>DocumentHandlerAdapter</code> instance.
+     */
+    public DocumentHandlerAdapter() {
+        super();
+    }
+
+    /**
+     * Create a new <code>DocumentHandlerAdapter</code> instance.
+     */
+    public DocumentHandlerAdapter(XMLConsumer consumer) {
+        this();
+        super.setConsumer(consumer);
+    }
+
+    /**
+     * Create a new <code>DocumentHandlerAdapter</code> instance.
+     */
+    public DocumentHandlerAdapter(ContentHandler content) {
+        this();
+        super.setContentHandler(content);
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     */
+    public void setDocumentLocator (Locator locator) {
+        if (super.contentHandler==null) return;
+        else super.contentHandler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument ()
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        super.contentHandler.startDocument();
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument ()
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        super.contentHandler.endDocument();
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement (String name, AttributeList a)
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        // Check for namespace declarations (two loops because we're not sure
+        // about attribute ordering.
+        AttributesImpl a2=new AttributesImpl();
+        Vector nslist=new Vector();
+        for (int x=0; x<a.getLength(); x++) {
+            String att=a.getName(x);
+            String uri=a.getValue(x);
+            if (att.equals("xmlns") || att.startsWith("xmlns:")) {
+                String pre="";
+                if (att.length()>5) pre=att.substring(6);
+                this.namespaces.addDeclaration(pre,uri);
+                nslist.addElement(pre);
+                super.contentHandler.startPrefixMapping(pre,uri);
+            }
+        }
+        if (nslist.size()>0) this.stackedNS.put(new Integer(this.stack),nslist);
+        // Resolve the element namespaced name
+        NamespacesTable.Name w=this.namespaces.resolve(null,name,null,null);
+        // Second loop through attributes to fill AttributesImpl
+        for (int x=0; x<a.getLength(); x++) {
+            String att=a.getName(x);
+            if (att.equals("xmlns") || att.startsWith("xmlns:")) continue;
+            // We have something different from a namespace declaration
+            NamespacesTable.Name k=this.namespaces.resolve(null,att,null,null);
+            String val=a.getValue(x);
+            String typ=a.getType(x);
+            String uri=k.getPrefix().length()==0?"":k.getUri();
+            a2.addAttribute(uri,k.getLocalName(),k.getQName(),typ,val);
+        }
+        // Notify the contentHandler
+        super.contentHandler.startElement(w.getUri(),w.getLocalName(),
+                                          w.getQName(),a2);
+        // Forward on the stack
+        this.stack++;
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement (String name)
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+            // Get back on the stack
+            this.stack--;
+        // Notify the contentHandler
+        NamespacesTable.Name w=this.namespaces.resolve(null,name,null,null);
+        super.contentHandler.endElement(w.getUri(),w.getLocalName(),
+                                        w.getQName());
+        // Undeclare namespaces
+        Vector nslist=(Vector)this.stackedNS.remove(new Integer(this.stack));
+        if (nslist==null) return;
+        if (nslist.size()==0) return;
+        Enumeration e=nslist.elements();
+        while (e.hasMoreElements()) {
+            String prefix=(String)e.nextElement();
+            NamespacesTable.Declaration d=namespaces.removeDeclaration(prefix);
+            super.contentHandler.endPrefixMapping(d.getPrefix());
+        }
+    }
+
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters (char ch[], int start, int len)
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        super.contentHandler.characters(ch,start,len);
+    }
+
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace (char ch[], int start, int len)
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        super.contentHandler.ignorableWhitespace(ch,start,len);
+    }
+
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction (String target, String data)
+        throws SAXException {
+        if (super.contentHandler==null)
+            throw new SAXException("ContentHandler not set");
+        super.contentHandler.processingInstruction(target,data);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerWrapper.java
new file mode 100644
index 0000000..6b9e2db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/DocumentHandlerWrapper.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributeListImpl;
+
+import java.util.Vector;
+
+/**
+ * This class is an utility class &quot;wrapping&quot; around a SAX version 1.0
+ * <code>DocumentHandler</code> and forwarding it those events received throug
+ * its <code>XMLConsumers</code> interface.
+ * <br>
+ * This class fully supports XML namespaces, converting
+ * <code>startPrefixMapping(...)</code> and <code>endPrefixMapping(...)</code>
+ * calls into appropriate <code>xmlns</code> and <code>xmlns:...</code> element
+ * attributes.
+ *
+ * @version $Id$
+ */
+public class DocumentHandlerWrapper extends AbstractXMLConsumer implements LogEnabled /*, Recyclable*/ {
+
+    protected Logger log;
+
+    /** The current namespaces table. */
+    private NamespacesTable namespaces=new NamespacesTable();
+    /** The vector of namespaces declarations to include in the next element. */
+    private Vector undecl=new Vector();
+
+    /** The current <code>DocumentHandler</code>. */
+    protected DocumentHandler documentHandler=null;
+
+    /**
+     * Create a new <code>DocumentHandlerWrapper</code> instance.
+     */
+    public DocumentHandlerWrapper() {
+        super();
+     }
+
+    /**
+     * Create a new <code>DocumentHandlerWrapper</code> instance.
+     */
+    public DocumentHandlerWrapper(DocumentHandler document) {
+        this();
+        this.setDocumentHandler(document);
+    }
+
+    /**
+     * Provide component with a logger.
+     * 
+     * @param logger the logger
+     */
+    public void enableLogging(Logger logger) {
+        if (this.log == null) {
+            this.log = logger;
+        }
+    }
+
+    /**
+     * Implementation of the recycle method
+     */
+    public void recycle() {
+        this.documentHandler = null;
+    }
+
+    /**
+     * Set the <code>DocumentHandler</code> that will receive XML data.
+     *
+     * @exception IllegalStateException If the <code>DocumentHandler</code>
+     *                                  was already set.
+     */
+    public void setDocumentHandler(DocumentHandler document)
+    throws IllegalStateException {
+        if (this.documentHandler!=null) throw new IllegalStateException();
+        this.documentHandler=document;
+    }
+
+    /**
+     * Receive an object for locating the origin of SAX document events.
+     */
+    public void setDocumentLocator (Locator locator) {
+        if (this.documentHandler==null) return;
+        else this.documentHandler.setDocumentLocator(locator);
+    }
+
+    /**
+     * Receive notification of the beginning of a document.
+     */
+    public void startDocument ()
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        this.documentHandler.startDocument();
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     */
+    public void endDocument ()
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        this.documentHandler.endDocument();
+    }
+
+    /**
+     * Begin the scope of a prefix-URI Namespace mapping.
+     */
+    public void startPrefixMapping(String prefix, String uri)
+    throws SAXException {
+        this.undecl.addElement(this.namespaces.addDeclaration(prefix,uri));
+    }
+
+    /**
+     * End the scope of a prefix-URI mapping.
+     */
+    public void endPrefixMapping(String prefix)
+    throws SAXException {
+        if (namespaces.removeDeclaration(prefix)==null)
+            throw new SAXException("Namespace prefix \""+prefix+
+                                   "\" never declared");
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        NamespacesTable.Name name=this.namespaces.resolve(uri,raw,null,loc);
+        // Create the AttributeList
+        AttributeListImpl a2=new AttributeListImpl();
+        // Set the xmlns:...="..." attributes
+        if (this.undecl.size()>0) {
+            for (int x=0; x<this.undecl.size(); x++) {
+                NamespacesTable.Declaration dec=null;
+                dec=(NamespacesTable.Declaration)this.undecl.elementAt(x);
+                String aname="xmlns";
+                if (dec.getPrefix().length()>0) aname="xmlns:"+dec.getPrefix();
+                a2.addAttribute(aname,"CDATA",dec.getUri());
+            }
+            this.undecl.clear();
+        }
+        // Set the real attributes
+        for (int x=0; x<a.getLength(); x++) {
+            NamespacesTable.Name aname=namespaces.resolve(a.getURI(x),
+                                                          a.getQName(x),
+                                                          null,
+                                                          a.getLocalName(x));
+            a2.addAttribute(aname.getQName(),a.getType(x),a.getValue(x));
+        }
+        // Call the document handler startElement() method.
+        this.documentHandler.startElement(name.getQName(),a2);
+    }
+
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement(String uri, String loc, String raw)
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        NamespacesTable.Name name=this.namespaces.resolve(uri,raw,null,loc);
+        this.documentHandler.endElement(name.getQName());
+    }
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters(char ch[], int start, int len)
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        this.documentHandler.characters(ch,start,len);
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace(char ch[], int start, int len)
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        this.documentHandler.ignorableWhitespace(ch,start,len);
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction(String target, String data)
+    throws SAXException {
+        if (this.documentHandler==null)
+            throw new SAXException("DocumentHandler not set");
+        this.documentHandler.processingInstruction(target,data);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/EmbeddedXMLPipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/EmbeddedXMLPipe.java
new file mode 100644
index 0000000..b560bb4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/EmbeddedXMLPipe.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * This class implements a ContentHandler for embedding a full SAX
+ * event stream into an existing stream of SAX events. An instance of
+ * this class will pass unmodified all the SAX events to the linked
+ * ContentHandler, but it will ignore the startDocument/endDocument
+ * and startDTD/endDTD events, as well as all comment events within
+ * the DTD.
+ *
+ * @version $Id$
+ */
+public class EmbeddedXMLPipe extends AbstractXMLPipe {
+
+    private boolean inDTD;
+
+    /**
+     * Creates an EmbeddedXMLPipe that writes into the given XMLConsumer.
+     */
+    public EmbeddedXMLPipe(XMLConsumer consumer) {
+        setConsumer(consumer);
+    }
+
+    /**
+     * Creates an EmbeddedXMLPipe that writes into the given ContentHandler.
+     */
+    public EmbeddedXMLPipe(ContentHandler handler) {
+        setContentHandler(handler);
+        if (handler instanceof LexicalHandler) {
+            setLexicalHandler((LexicalHandler) handler);
+        }
+    }
+
+    /**
+     * Creates an EmbeddedXMLPipe that writes into the given ContentHandler.
+     */
+    public EmbeddedXMLPipe(ContentHandler contentHandler, LexicalHandler lexicalHandler) {
+        setContentHandler(contentHandler);
+        setLexicalHandler(lexicalHandler);
+    }
+
+    /**
+     * Ignore the <code>startDocument</code> event: this method does nothing.
+     *
+     * @exception SAXException if an error occurs
+     */
+    public void startDocument() throws SAXException {
+    }
+
+    /**
+     * Ignore the <code>endDocument</code> event: this method does nothing.
+     *
+     * @exception SAXException if an error occurs
+     */
+    public void endDocument() throws SAXException {
+    }
+
+    /**
+     * Ignore the <code>startDTD</code> event: this method does nothing.
+     *
+     * @exception SAXException if an error occurs
+     */
+    public void startDTD(String name, String publicId, String systemId)
+    throws SAXException {
+        // Ignored
+        this.inDTD = true;
+    }
+
+    /**
+     * Ignore the <code>endDTD</code> event: this method does nothing.
+     *
+     * @exception SAXException if an error occurs
+     */
+    public void endDTD() throws SAXException {
+        // Ignored
+        this.inDTD = false;
+    }
+
+    /**
+     * Ignore all <code>comment</code> events if between
+     * startDTD/endDTD events.
+     *
+     * @exception SAXException if an error occurs
+     */
+    public void comment(char ch[], int start, int len)
+    throws SAXException {
+        if (!inDTD) {
+            super.comment(ch, start, len);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ImmutableAttributesImpl.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ImmutableAttributesImpl.java
new file mode 100644
index 0000000..427a823
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ImmutableAttributesImpl.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+
+/**
+ * Immutable attributes
+ *
+ * @version $Id$
+ */
+public class ImmutableAttributesImpl extends AttributesImpl {
+
+    public ImmutableAttributesImpl() {
+        super();
+    }
+
+    public ImmutableAttributesImpl(Attributes attrs) {
+        super(attrs);
+    }
+
+    public void clear() {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void removeAttribute(int index) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setLocalName(int index, String localName) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setQName(int index, String qName) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setType(int index, String type) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setURI(int index, String uri) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setValue(int index, String value) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setAttributes(Attributes atts) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void setAttribute(int index, String uri, String localName, String qName, String type, String value) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+
+    public void addAttribute(String uri, String localName, String qName, String type, String value) {
+        throw new UnsupportedOperationException("immutable attributes");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/IncludeXMLConsumer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/IncludeXMLConsumer.java
new file mode 100644
index 0000000..121143c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/IncludeXMLConsumer.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.w3c.dom.Node;
+
+/**
+ * A special purpose <code>XMLConsumer</code> which can:
+ * <ul>
+ * <li>Trim empty characters if
+ *     {@link #setIgnoreEmptyCharacters(boolean) ignoreEmptyCharacters} is set.
+ * <li>Ignore root element if
+ *     {@link #setIgnoreRootElement(boolean) ignoreRootElement} is set.
+ * <li>Ignore startDocument, endDocument events.
+ * <li>Ignore startDTD, endDTD, and all comments within DTD.
+ * </ul>
+ *
+ * <p>It is more complicated version of {@link EmbeddedXMLPipe} which, except
+ * being used to include other files into the SAX events stream, can perform
+ * optional operations described above.</p>
+ *
+ * @see EmbeddedXMLPipe
+ * @version $Id$
+ */
+public class IncludeXMLConsumer implements XMLConsumer {
+
+    /** The TrAX factory for serializing xml */
+    private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+
+    private final ContentHandler contentHandler;
+    private final LexicalHandler lexicalHandler;
+
+    private boolean ignoreEmptyCharacters;
+    private boolean ignoreRootElement;
+    private int     ignoreRootElementCount;
+    private boolean inDTD;
+
+    /**
+     * Constructor
+     */
+    public IncludeXMLConsumer (XMLConsumer consumer) {
+        this.contentHandler = consumer;
+        this.lexicalHandler = consumer;
+    }
+
+    /**
+     * Constructor
+     */
+    public IncludeXMLConsumer (ContentHandler contentHandler, LexicalHandler lexicalHandler) {
+        this.contentHandler = contentHandler;
+        this.lexicalHandler = lexicalHandler;
+    }
+
+    /**
+     * Constructor
+     */
+    public IncludeXMLConsumer (ContentHandler contentHandler) {
+        this.contentHandler = contentHandler;
+        this.lexicalHandler = contentHandler instanceof LexicalHandler ? (LexicalHandler)contentHandler : null;
+    }
+
+    /**
+     * Utility method to stream a DOM node into the provided content handler,
+     * lexical handler.
+     *
+     * @param node The DOM Node to be included
+     * @param contentHandler The SAX ContentHandler receiving the information
+     * @param lexicalHandler The SAX LexicalHandler receiving the information (optional)
+     */
+    public static void includeNode(Node           node,
+                                   ContentHandler contentHandler,
+                                   LexicalHandler lexicalHandler)
+    throws SAXException {
+        if (node != null) {
+            if (node.getNodeType() == Node.TEXT_NODE){
+                String value = node.getNodeValue();
+                contentHandler.characters(value.toCharArray(), 0, value.length());
+            } else {
+                try {
+                    IncludeXMLConsumer filter = new IncludeXMLConsumer(contentHandler, lexicalHandler);
+                    Transformer transformer = FACTORY.newTransformer();
+                    DOMSource source = new DOMSource(node);
+                    SAXResult result = new SAXResult(filter);
+                    result.setLexicalHandler(filter);
+                    transformer.transform(source, result);
+                } catch (TransformerConfigurationException e) {
+                    throw new SAXException("TransformerConfigurationException", e);
+                } catch (TransformerException e) {
+                    throw new SAXException("TransformerException", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Control SAX event handling.
+     * If set to <code>true</code> all empty characters events are ignored.
+     * The default is <code>false</code>.
+     */
+    public void setIgnoreEmptyCharacters(boolean value) {
+        this.ignoreEmptyCharacters = value;
+    }
+
+    /**
+     * Control SAX event handling.
+     * If set to <code>true</code> the root element is ignored.
+     * The default is <code>false</code>.
+     */
+    public void setIgnoreRootElement(boolean value) {
+        this.ignoreRootElement = value;
+        this.ignoreRootElementCount = 0;
+    }
+
+    //
+    // ContentHandler interface
+    //
+
+    public void setDocumentLocator(Locator loc) {
+        this.contentHandler.setDocumentLocator(loc);
+    }
+
+    public void startDocument() throws SAXException {
+        // Ignored
+    }
+
+    public void endDocument() throws SAXException {
+        // Ignored
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        this.contentHandler.startPrefixMapping(prefix, uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        this.contentHandler.endPrefixMapping(prefix);
+    }
+
+    public void startElement(String uri, String local, String qName, Attributes attr) throws SAXException {
+        if (this.ignoreRootElement == false ||
+            this.ignoreRootElementCount > 0) {
+            this.contentHandler.startElement(uri,local,qName,attr);
+        }
+        this.ignoreRootElementCount++;
+    }
+
+    public void endElement(String uri, String local, String qName) throws SAXException {
+        this.ignoreRootElementCount--;
+        if (!this.ignoreRootElement  || this.ignoreRootElementCount > 0) {
+            this.contentHandler.endElement(uri, local, qName);
+        }
+    }
+
+    public void characters(char[] ch, int start, int end) throws SAXException {
+        if (this.ignoreEmptyCharacters) {
+            String text = new String(ch, start, end).trim();
+            if (text.length() > 0) {
+                this.contentHandler.characters(text.toCharArray(), 0, text.length());
+            }
+        } else {
+            this.contentHandler.characters(ch, start, end);
+        }
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int end) throws SAXException {
+        if (!this.ignoreEmptyCharacters) {
+            this.contentHandler.ignorableWhitespace(ch, start, end);
+        }
+    }
+
+    public void processingInstruction(String name, String value) throws SAXException {
+        this.contentHandler.processingInstruction(name, value);
+    }
+
+    public void skippedEntity(String ent) throws SAXException {
+        this.contentHandler.skippedEntity(ent);
+    }
+
+    //
+    // LexicalHandler interface
+    //
+
+    public void startDTD(String name, String public_id, String system_id)
+    throws SAXException {
+        // Ignored
+        this.inDTD = true;
+    }
+
+    public void endDTD() throws SAXException {
+        // Ignored
+        this.inDTD = false;
+    }
+
+    public void startEntity(String name) throws SAXException {
+        if (lexicalHandler != null) {
+            lexicalHandler.startEntity(name);
+        }
+    }
+
+    public void endEntity(String name) throws SAXException {
+        if (lexicalHandler != null) {
+            lexicalHandler.endEntity(name);
+        }
+    }
+
+    public void startCDATA() throws SAXException {
+        if (lexicalHandler != null) {
+            lexicalHandler.startCDATA();
+        }
+    }
+
+    public void endCDATA() throws SAXException {
+        if (lexicalHandler != null) {
+            lexicalHandler.endCDATA();
+        }
+    }
+
+    public void comment(char ary[], int start, int length) throws SAXException {
+        if (!inDTD && lexicalHandler != null) {
+            lexicalHandler.comment(ary,start,length);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingContentHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingContentHandler.java
new file mode 100644
index 0000000..1916361
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingContentHandler.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ContentHandler;
+
+/**
+ * Logging content handler logs all events going through to the logger.
+ *
+ * @version $Id$
+ */
+public class LoggingContentHandler extends AbstractLogEnabled implements ContentHandler {
+
+    /**
+     * All debug messages from this handler are prefixed with this id.
+     */
+    String id;
+
+    /** The current <code>ContentHandler</code>. */
+    ContentHandler contentHandler;
+
+    /**
+     * Creates new <code>LoggingContentHandler</code> with specified
+     * <code>id</code> and destination <code>contentHandler</code>.
+     */
+    public LoggingContentHandler(String id, ContentHandler contentHandler) {
+        this.id = id;
+        this.contentHandler = contentHandler;
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        log("setDocumentLocator", "");
+        contentHandler.setDocumentLocator(locator);
+    }
+
+    public void startDocument() throws SAXException {
+        log("startDocument", "");
+        this.contentHandler.startDocument();
+    }
+
+    public void endDocument() throws SAXException {
+        log ("endDocument", "");
+        this.contentHandler.endDocument();
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        log ("startPrefixMapping", "prefix="+prefix+",uri="+uri);
+        this.contentHandler.startPrefixMapping(prefix,uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        log ("endPrefixMapping", "prefix="+prefix);
+        this.contentHandler.endPrefixMapping(prefix);
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a)
+    throws SAXException {
+        log ("startElement", "uri="+uri+",local="+loc+",raw="+raw);
+        for (int i = 0; i < a.getLength(); i++) {
+            log ("            ", Integer.toString(i + 1)
+                 + ". uri=" + a.getURI(i)
+                 + ",local=" + a.getLocalName(i)
+                 + ",qname=" + a.getQName(i)
+                 + ",type=" + a.getType(i)
+                 + ",value=" + a.getValue(i));
+        }
+        this.contentHandler.startElement(uri,loc,raw,a);
+    }
+
+
+    public void endElement(String uri, String loc, String qname) throws SAXException {
+        log ("endElement", "uri="+uri+",local="+loc+",qname="+qname);
+        this.contentHandler.endElement(uri,loc,qname);
+    }
+
+    public void characters(char ch[], int start, int len) throws SAXException {
+        log ("characters", new String(ch,start,len));
+        this.contentHandler.characters(ch,start,len);
+    }
+
+    public void ignorableWhitespace(char ch[], int start, int len) throws SAXException {
+        log ("ignorableWhitespace", new String(ch,start,len));
+        this.contentHandler.ignorableWhitespace(ch,start,len);
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        log ("processingInstruction", "target="+target+",data="+data);
+        this.contentHandler.processingInstruction(target,data);
+    }
+
+    public void skippedEntity(String name) throws SAXException {
+        log ("skippedEntity", "name="+name);
+        this.contentHandler.skippedEntity(name);
+    }
+
+    private void log(String location, String description) {
+        StringBuffer logEntry = new StringBuffer();
+        logEntry.append(id);
+        logEntry.append("[");
+        logEntry.append(location);
+        logEntry.append("] ");
+        logEntry.append(description);
+        logEntry.append("\n");
+        getLogger().debug(logEntry.toString());
+        // System.out.print(logEntry.toString());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingEntityResolver.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingEntityResolver.java
new file mode 100644
index 0000000..2c45d51
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/LoggingEntityResolver.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Logging entity resolver to assist in caching.
+ *
+ * @version $Id$
+ */
+public class LoggingEntityResolver extends AbstractLogEnabled implements EntityResolver {
+
+  protected EntityResolver resolver;
+  protected Set dependencies;
+
+  public LoggingEntityResolver(EntityResolver resolver) {
+    this.resolver = resolver;
+    dependencies = new HashSet();
+  }
+
+  public InputSource resolveEntity(String public_id, String system_id) throws SAXException,IOException {
+    InputSource input_source = resolver.resolveEntity(public_id,system_id);
+    dependencies.add(input_source);
+    getLogger().debug("Dependency: "+input_source.getSystemId());
+    return input_source;
+  }
+
+  public Set getDependencies() {
+    return Collections.unmodifiableSet(dependencies);
+  }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/NamespacesTable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/NamespacesTable.java
new file mode 100644
index 0000000..fed5159
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/NamespacesTable.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Keeps track of namespaces declarations and resolve namespaces names.
+ * <p>
+ * This class also provides a very convenient and safe way of handling
+ * namespace declarations in SAX pipes. It also allows to filter duplicate namespace
+ * declarations that too often clutter up XML documents that went through
+ * several transformations, and avoid useless namespace declarations that aren't followed
+ * by element events.
+ * <p>
+ * Usage example in a SAX pipe:
+ * <pre>
+ *   NamespacesTable namespaces = new NamespacesTable();
+ *   ContentHandler nextHandler;
+ *
+ *   public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ *       namespaces.addDeclaration(prefix, uri);
+ *   }
+ *
+ *   public void startElement(...) throws SAXException {
+ *       // automatically start mappings for this scope
+ *       namespaces.enterScope(nextHandler);
+ *       nextHandler.startElement(...);
+ *   }
+ *
+ *   public void endElement(...) throws SAXException {
+ *       nextHandler.endElement(...);
+ *       // automatically end mappings for this scope
+ *       namespaces.leaveScope(nextHandler);
+ *   }
+ *
+ *   public void endPrefixMapping(String prefix) throws SAXException {
+ *       // Ignore, it is handled by leaveScope()
+ *   }
+ * </pre>
+ *
+ * @version $Id$
+ */
+public class NamespacesTable {
+    /** The last namespace declaration. */
+    private Entry lastEntry;
+    
+    /** The entry that start the prefix mappings for the scope that's about to be entered
+     * or was just left.
+     */
+    private Entry lastDeclaredEntry;
+
+    private boolean usesScopes = false;
+
+    /**
+     * Construct a new <code>NamespacesTable</code> instance.
+     */
+    public NamespacesTable() {
+        clear();
+    }
+
+    /**
+     * Clear and reinitialize this namespace table before reuse.
+     *
+     * @since 2.1.8
+     */
+    public void clear() {
+        this.lastEntry = Entry.create("","");
+        this.addDeclaration("xml", "http://www.w3.org/XML/1998/namespace");
+        // Lock this scope
+        this.lastEntry.closedScopes = 1;
+    }
+
+    /**
+     * Declare a new namespace prefix-uri mapping.
+     *
+     * @return The newly added <code>Declaration</code>.
+     */
+    public Declaration addDeclaration(String prefix, String uri) {
+        // Find a previous declaration of the same prefix
+        Entry dup = this.lastEntry;
+        while (dup != null && !dup.prefix.equals(prefix)) {
+            dup = dup.previous;
+        }
+
+        if (dup != null) {
+            if (usesScopes && dup.uri.equals(uri)) {
+                return dup;
+            }
+            dup.overriden = true;
+        }
+
+        Entry e = Entry.create(prefix, uri);
+        e.previous = this.lastEntry;
+        e.overrides = dup;
+        this.lastEntry = e;
+        // this always starts the declared prefix chain
+        this.lastDeclaredEntry = e;
+        return e;
+    }
+
+    /**
+     * Undeclare a namespace prefix-uri mapping. If the prefix was previously declared
+     * mapping another URI, its value is restored.
+     * <p>
+     * When using {@link #enterScope()}/{@link #leaveScope()}, this method does nothing and always
+     * returns <code>null</code>, as declaration removal is handled in {@link #leaveScope()}.
+     *
+     * @return the removed <code>Declaration</code> or <b>null</b>.
+     */
+    public Declaration removeDeclaration(String prefix) {
+        if (usesScopes) {
+            // Automatically handled in leaveScope
+            return null; // or throw and IllegalStateException if enterScope(handler) was used?
+        }
+
+        Entry current = this.lastEntry;
+        Entry afterCurrent = null;
+        while(current != null) {
+            if (current.closedScopes > 0) {
+                // Don't undeclare mappings not declared in this scope
+                return null;
+            }
+
+            if (current.prefix.equals(prefix)) {
+                // Got it
+                // Remove it from the chain
+                if (afterCurrent != null) {
+                    afterCurrent.previous = current.previous;
+                }
+                // And report closed scopes on the previous entry
+                current.previous.closedScopes += current.closedScopes;
+                Entry overrides = current.overrides;
+                if (overrides != null) {
+                    // No more overriden
+                    overrides.overriden = false;
+                }
+
+                if (this.lastDeclaredEntry == current) {
+                    if (current.previous.closedScopes == 0) {
+                        this.lastDeclaredEntry = current.previous;
+                    } else {
+                        this.lastDeclaredEntry = null;
+                    }
+                }
+
+                if (this.lastEntry == current) {
+                    this.lastEntry = current.previous;
+                }
+
+                return current;
+            }
+
+            afterCurrent = current;
+            current = current.previous;
+        }
+
+        // Not found
+        return null;
+    }
+
+    /**
+     * Enter a new scope. This starts a new, empty list of declarations for the new scope.
+     * <p>
+     * Typically called in a SAX handler <em>before</em> sending a <code>startElement()</code>
+     * event.
+     *
+     * @since 2.1.8
+     */
+    public void enterScope() {
+        this.usesScopes = true;
+        this.lastEntry.closedScopes++;
+        this.lastDeclaredEntry = null;
+    }
+
+    /**
+     * Start all declared mappings of the current scope and enter a new scope.  This starts a new,
+     * empty list of declarations for the new scope.
+     * <p>
+     * Typically called in a SAX handler <em>before</em> sending a <code>startElement()</code>
+     * event.
+     *
+     * @param handler the handler that will receive startPrefixMapping events.
+     * @throws SAXException
+     * @since 2.1.8
+     */
+    public void enterScope(ContentHandler handler) throws SAXException {
+        this.usesScopes = true;
+        Entry current = this.lastEntry;
+        while (current != null && current.closedScopes == 0) {
+            handler.startPrefixMapping(current.prefix, current.uri);
+            current = current.previous;
+        }
+        this.lastEntry.closedScopes++;
+        this.lastDeclaredEntry = null;
+    }
+
+    /**
+     * Leave a scope. The namespace declarations that occured before the corresponding
+     * <code>enterScope()</code> are no more visible using the resolution methods, but
+     * still available using {@link #getCurrentScopeDeclarations()} until the next call
+     * to {@link #addDeclaration(String, String)} or {@link #enterScope()}.
+     * <p>
+     * Typically called in a SAX handler <em>after</em> sending a <code>endElement()</code>
+     * event.
+     *
+     * @since 2.1.8
+     */
+    public void leaveScope() {
+        Entry current = this.lastEntry;
+
+        // Purge declarations that were added but not included in a scope
+        while (current.closedScopes == 0) {
+            current = current.previous;
+        }
+
+        current.closedScopes--;
+
+        if (current.closedScopes == 0) {
+            this.lastDeclaredEntry = current;
+        } else {
+            // More than one scope closed here: no local declarations
+            this.lastDeclaredEntry = null;
+        }
+
+        while (current != null && current.closedScopes == 0) {
+            Entry overrides = current.overrides;
+            if (overrides != null) {
+                // No more overriden
+                overrides.overriden = false;
+            }
+            current = current.previous;
+        }
+        this.lastEntry = current;
+    }
+
+    /**
+     * Leave a scope. The namespace declarations that occured before the corresponding
+     * <code>enterScope()</code> are no more visible using the resolution methods, but
+     * still available using {@link #getCurrentScopeDeclarations()} until the next call
+     * to {@link #addDeclaration(String, String)} or {@link #enterScope()}.
+     * <p>
+     * Typically called in a SAX handler <em>after</em> sending a <code>endElement()</code>
+     * event.
+     *
+     * @param handler the handler that will receive endPrefixMapping events.
+     * @throws SAXException
+     * @since 2.1.8
+     */
+    public void leaveScope(ContentHandler handler) throws SAXException {
+        Entry current = this.lastEntry;
+        
+        // Purge declarations that were added but not included in a scope
+        while (current.closedScopes == 0) {
+            current = current.previous;
+        }
+
+        current.closedScopes--;
+
+        if (current.closedScopes == 0) {
+            this.lastDeclaredEntry = current;
+        } else {
+            // More than one scope closed here: no local declarations
+            this.lastDeclaredEntry = null;
+        }
+
+        while (current != null && current.closedScopes == 0) {
+            handler.endPrefixMapping(current.prefix);
+            Entry overrides = current.overrides;
+            if (overrides != null) {
+                // No more overriden
+                overrides.overriden = false;
+            }
+            current = current.previous;
+        }
+
+        this.lastEntry = current;
+    }
+
+    private static final Declaration[] NO_DECLS = new Declaration[0];
+
+    /**
+     * Get the declarations that were declared within the current scope.
+     *
+     * @return the declarations (possibly empty, but never null)
+     * @since 2.1.8
+     */
+    public Declaration[] getCurrentScopeDeclarations() {
+        int count = 0;
+        Entry current = this.lastDeclaredEntry;
+        while (current != null && current.closedScopes == 0) {
+            count++;
+            current = current.previous;
+        }
+
+        if (count == 0) return NO_DECLS;
+
+        Declaration[] decls = new Declaration[count];
+        count = 0;
+        current = this.lastDeclaredEntry;
+        while (current != null && current.closedScopes == 0) {
+            decls[count++] = current;
+            current = current.previous;
+        }
+        return decls;
+    }
+
+    /**
+     * Return the URI associated with the given prefix or <b>null</b> if the
+     * prefix was not mapped.
+     */
+    public String getUri(String prefix) {
+        Entry current = this.lastEntry;
+        while (current != null) {
+            if (current.prefix.equals(prefix)) {
+                return current.uri;
+            }
+            current = current.previous;
+        }
+
+        // Not found
+        return null;
+    }
+
+    /**
+     * Return an array with all prefixes currently mapped to the specified URI.
+     * <br>
+     * The array length might be <b>zero</b> if no prefixes are associated with
+     * the specified uri.
+     *
+     * @return A <b>non-null</b> <code>String</code> array.
+     */
+    public String[] getPrefixes(String uri) {
+
+        Entry current=this.lastEntry;
+        int count=0;
+        while (current!=null) {
+            if(!current.overriden && current.uri.equals(uri))
+                count++;
+            current=current.previous;
+        }
+        if (count==0) return(new String[0]);
+
+        String prefixes[]=new String[count];
+        count=0;
+        current = this.lastEntry;
+        while (current!=null) {
+            if(!current.overriden && current.uri.equals(uri))
+                prefixes[count++] = current.prefix;
+            current = current.previous;
+        }
+        return prefixes;
+    }
+
+
+    /**
+     * Return one of the prefixes currently mapped to the specified URI or
+     * <b>null</b>.
+     */
+    public String getPrefix(String uri) {
+        Entry current = this.lastEntry;
+        while (current != null) {
+            if(!current.overriden && current.uri.equals(uri))
+                return current.prefix;
+            current = current.previous;
+        }
+        return null;
+    }
+
+    /**
+     * Resolve a namespace-aware name against the current namespaces
+     * declarations.
+     *
+     * @param uri The namespace URI or <b>null</b> if not known.
+     * @param raw The raw (complete) name or <b>null</b> if not known.
+     * @param prefix The namespace prefix or <b>null</b> if not known.
+     * @param local The local name or <b>null</b> if not known.
+     * @return A <b>non-null</b> <code>Name</code>.
+     * @exception SAXException If the name cannot be resolved.
+     */
+    public Name resolve(String uri, String raw, String prefix, String local)
+    throws SAXException {
+        if (uri==null) uri="";
+        if (raw==null) raw="";
+        if (prefix==null) prefix="";
+        if (local==null) local="";
+        // Start examining the URI
+        if (raw.length()>0) {
+            // The raw name was specified
+            int pos=raw.indexOf(':');
+            if (pos>0) {
+                // We have a namespace prefix:local separator
+                String pre=raw.substring(0,pos);
+                String loc=raw.substring(pos+1);
+                if (prefix.length()==0) prefix=pre;
+                else if (!prefix.equals(pre))
+                    throw new SAXException("Raw/Prefix mismatch");
+                if (local.length()==0) local=loc;
+                else if (!local.equals(loc))
+                    throw new SAXException("Raw/Local Name mismatch");
+            } else {
+                // We don't have a prefix:local separator
+                if (prefix.length()>0)
+                    throw new SAXException("Raw Name/Prefix mismatch");
+                if (local.length()==0) local=raw;
+                else if (!local.equals(raw))
+                    throw new SAXException("Raw Name/Local Name mismatch");
+            }
+        } else {
+            // The raw name was not specified
+            if (local.length()==0) throw new SAXException("No Raw/Local Name");
+            if (prefix.length()==0) raw=local;
+            else raw=prefix+':'+local;
+        }
+        // We have resolved and checked data between the raw, local, and
+        // prefix... We have to doublecheck the namespaces.
+        if (uri.length()>0) {
+            // We have a URI and a prefix, check them
+            if ((prefix.length()>0) &&  (!uri.equals(this.getUri(prefix)))) {
+                throw new SAXException("URI/Prefix mismatch [" + prefix + "," + uri + "]");
+            } else {
+                String temp=this.getPrefix(uri);
+                if (temp==null) throw new SAXException("URI not declared");
+                else if (temp.length()>0) {
+                    prefix=temp;
+                    raw=prefix+':'+local;
+                }
+            }
+        } else {
+            // We don't have a URI, check if we can find one from the prefix.
+            String temp=this.getUri(prefix);
+            if (temp==null) throw new SAXException("Prefix not declared");
+            else uri=temp;
+        }
+        NameImpl name=new NameImpl();
+        if (uri.length() > 0) name.uri=uri;
+        else name.uri=null;
+        name.raw=raw;
+        name.prefix=prefix;
+        name.local=local;
+        return(name);
+    }
+
+    /** The internal entry structure for this table. */
+    private static class Entry implements Declaration {
+        /** The URI string. */
+        protected String uri="";
+        /** The prefix string. */
+        protected String prefix="";
+        /** The previous declaration. */
+        protected Entry previous;
+        protected Entry overrides;
+        protected int closedScopes = 0;
+        protected boolean overriden = false;
+
+        /** Create a new namespace declaration. */
+        protected static Entry create(String prefix, String uri) {
+            // Create a new entry
+            Entry e = new Entry();
+            // Set the prefix string.
+            if (prefix != null) e.prefix=prefix;
+            // Set the uri string.
+            if (uri != null) e.uri=uri;
+            // Return the entry
+            return e;
+        }
+
+        /** Return the namespace URI. */
+        public String getUri() { return this.uri; }
+        /** Return the namespace prefix. */
+        public String getPrefix() { return this.prefix; }
+    }
+
+    /** The default namespace-aware name declaration implementation */
+    private static class NameImpl implements Name {
+        /** The namespace URI. */
+        protected String uri;
+        /** The namespace prefix. */
+        protected String prefix;
+        /** The namespace local name. */
+        protected String local;
+        /** The namespace raw name. */
+        protected String raw;
+
+        /** Return the namespace URI. */
+        public String getUri() { return this.uri; }
+        /** Return the namespace prefix. */
+        public String getPrefix() { return this.prefix; }
+        /** Return the namespace local name. */
+        public String getLocalName() { return this.local; }
+        /** Return the namespace raw name. */
+        public String getQName() { return this.raw; }
+    }
+
+    /**
+     * A namespace-aware name. (This interface is used in conjunction
+     * with <code>NamespacesTable</code>).
+     */
+    public interface Name {
+        /** Return the namespace URI. */
+        String getUri();
+        /** Return the namespace prefix. */
+        String getPrefix();
+        /** Return the namespace local name. */
+        String getLocalName();
+        /** Return the namespace raw name. */
+        String getQName();
+    }
+
+    /**
+     * A namespace declaration. (This interface is used in conjunction
+     * with <code>NamespacesTable</code>).
+     */
+    public interface Declaration {
+        /** Return the namespace URI. */
+        String getUri();
+        /** Return the namespace prefix. */
+        String getPrefix();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java
new file mode 100644
index 0000000..f5fc775
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/ParamSaxBuffer.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.io.Writer;
+import java.io.IOException;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+
+/**
+ * Modification of the SAX buffer with parameterization capabilities.
+ *
+ * Any <code>{name}</code> expression inside of the character events can be
+ * replaced by the content of another SaxBuffer if it is present in the map
+ * passed to the {@link #toSAX(ContentHandler, Map)} method.
+ *
+ * @version $Id$
+ */
+public class ParamSaxBuffer extends SaxBuffer {
+
+   /**
+    * If ch (in characters()) contains an unmatched '{' then
+    * we save the chars from '{' onward in previous_ch.
+    * Next call to characters() prepends the saved chars to ch before processing
+    * (and sets previous_ch to null).
+    */
+    private char[] previous_ch = null;
+
+    /**
+     * Creates empty SaxBuffer
+     */
+    public ParamSaxBuffer() {
+    }
+
+    /**
+     * Creates copy of another SaxBuffer
+     */
+    public ParamSaxBuffer(SaxBuffer saxBuffer) {
+        super(saxBuffer);
+    }
+
+    /**
+     * Parses text and extracts <code>{name}</code> parameters for later
+     * substitution.
+     */
+    public void characters(char ch[], int start, int length) throws SAXException {
+
+        if (previous_ch != null) {
+            // prepend char's from previous_ch to ch
+            char[] buf = new char[length + previous_ch.length];
+            System.arraycopy(previous_ch, 0, buf, 0, previous_ch.length);
+            System.arraycopy(ch, start, buf, previous_ch.length, length);
+            ch = buf;
+            start = 0;
+            length += previous_ch.length;
+            previous_ch = null;
+        }
+
+        final int end = start + length;
+        for (int i = start; i < end; i++) {
+            if (ch[i] == '{') {
+                // Send any collected characters so far
+                if (i > start) {
+                    addBit(new Characters(ch, start, i - start));
+                }
+
+                // Find closing brace, and construct parameter name
+                StringBuffer name = new StringBuffer();
+                int j = i + 1;
+                for (; j < end; j++) {
+                    if (ch[j] == '}') {
+                        break;
+                    }
+                    name.append(ch[j]);
+                }
+                if (j == end) {
+                    // '{' without a closing '}'
+                    // save char's from '{' in previous_ch in case the following call to characters()
+                    // provides the '}'
+                    previous_ch = new char[end - i];
+                    System.arraycopy(ch, i, previous_ch, 0, end - i);
+                    break;
+                }
+                addBit(new Parameter(name.toString()));
+
+                // Continue processing
+                i = j;
+                start = j + 1;
+                continue;
+            }
+        }
+
+        // Send any tailing characters
+        if (start < end) {
+            addBit(new Characters(ch, start, end - start));
+        }
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+        flushChars();
+        super.endElement(namespaceURI, localName, qName);
+    }
+
+    public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
+        flushChars();
+        super.ignorableWhitespace(ch, start, length);
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        flushChars();
+        super.processingInstruction(target, data);
+    }
+
+    public void startDocument() throws SAXException {
+        flushChars();
+        super.startDocument();
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+        flushChars();
+        super.startElement(namespaceURI, localName, qName, atts);
+    }
+
+    public void endDocument() throws SAXException {
+        flushChars();
+        super.endDocument();
+    }
+
+    public void comment(char ch[], int start, int length) throws SAXException {
+        flushChars();
+        super.comment(ch, start, length);
+    }
+
+    public void endDTD() throws SAXException {
+        flushChars();
+        super.endDTD();
+    }
+
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        flushChars();
+        super.startDTD(name, publicId, systemId);
+    }
+
+    private void flushChars() {
+        // Handle saved chars (in case we had a '{' with no matching '}').
+        if (previous_ch != null) {
+            addBit(new Characters(previous_ch, 0, previous_ch.length));
+            previous_ch = null;
+        }
+    }
+
+    /**
+     * @param parameters map containing SaxBuffers
+     */
+    public void toSAX(ContentHandler contentHandler, Map parameters) throws SAXException {
+        for (Iterator i = bits(); i.hasNext();) {
+            SaxBit saxbit = (SaxBit)i.next();
+            if (saxbit instanceof Parameter) {
+                ((Parameter)saxbit).send(contentHandler, parameters);
+            } else {
+                saxbit.send(contentHandler);
+            }
+        }
+    }
+
+
+    final static class Parameter implements SaxBit {
+        private final String name;
+
+        public Parameter(String name) {
+            this.name = name;
+        }
+
+        public void send(ContentHandler contentHandler) {
+        }
+
+        public void send(ContentHandler contentHandler, Map parameters) throws SAXException {
+            SaxBuffer value = (SaxBuffer)parameters.get(name);
+            if (value != null) {
+                value.toSAX(contentHandler);
+            }
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[Parameter] name=" + name);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/RedundantNamespacesFilter.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/RedundantNamespacesFilter.java
new file mode 100644
index 0000000..9706140
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/RedundantNamespacesFilter.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * A SAX filter that strips out redundant namespace declarations.
+ *
+ * <p>
+ * It handles both duplicate declarations (i.e. a namespace already declared by a
+ * parent element) and empty namespaces scopes (i.e. start/stopPrefixMapping with
+ * no element inbetween) that can be produced by some components (e.g. JXTG or
+ * BrowserUpdateTransformer). Such empty scopes confuse the Xalan serializer which
+ * then produces weird namespace declarations (<code>xmlns:%@$#^@#="%@$#^@#"</code>).
+ *
+ * <p>
+ * This is a the most simple use of {@link NamespacesTable}.
+ *
+ * @version $Id$
+ */
+public class RedundantNamespacesFilter extends AbstractXMLPipe {
+
+    /** Layered storage for all namespace declarations */
+    private NamespacesTable ns = new NamespacesTable();
+
+    /**
+     * No-arg constructor. Requires an explicit call to
+     * <code>setConsumer()</code>.
+     */
+    public RedundantNamespacesFilter() {
+        // Nothing
+    }
+
+    /**
+     * Creates a filter directly linked to its consumer
+     *
+     * @param consumer
+     *            the SAX stream consumer
+     */
+    public RedundantNamespacesFilter(XMLConsumer consumer) {
+        setConsumer(consumer);
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        // Just declare it: duplicate declarations are ignorede by NamespacesTable
+        ns.addDeclaration(prefix, uri);
+    }
+
+    public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
+        // Declare namespaces for this scope, if any
+        ns.enterScope(this.contentHandler);
+        super.startElement(uri, loc, raw, a);
+    }
+
+    public void endElement(String uri, String loc, String raw) throws SAXException {
+        super.endElement(uri, loc, raw);
+        ns.leaveScope(this.contentHandler);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        ns.removeDeclaration(prefix);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/SaxBuffer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/SaxBuffer.java
new file mode 100644
index 0000000..160ba93
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/SaxBuffer.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+import org.xml.sax.ext.LexicalHandler;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.avalon.excalibur.pool.Recyclable;
+
+import java.io.Serializable;
+import java.io.Writer;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Collections;
+
+/**
+ * A class that can record SAX events and replay them later.
+ *
+ * <p>Compared to {@link org.apache.cocoon.components.sax.XMLByteStreamCompiler},
+ * this class is many times faster at sending out the recorded SAX events since
+ * it doesn't need to convert between byte and char representations etc.
+ * On the other hand, its data structure is more complex then a simple byte array,
+ * making XMLByteStreamCompiler better in case the recorded SAX should be stored long-term.
+ *
+ * <p>Use this class if you need to frequently generate smaller amounts of SAX events,
+ * or replay a set of recorded start events immediately.</p>
+ *
+ * <p>Both {@link ContentHandler} and {@link LexicalHandler} are supported, the only
+ * exception is that the setDocumentLocator event is not recorded.</p>
+ *
+ * @version $Id$
+ */
+public class SaxBuffer extends AbstractSAXFragment
+                       implements XMLConsumer, Recyclable, Serializable {
+
+    /**
+     * Stores list of {@link SaxBit} objects.
+     */
+    protected List saxbits;
+
+    /**
+     * Creates empty SaxBuffer
+     */
+    public SaxBuffer() {
+        this.saxbits = new ArrayList();
+    }
+
+    /**
+     * Creates SaxBuffer based on the provided bits list.
+     */
+    public SaxBuffer(List bits) {
+        this.saxbits = bits;
+    }
+
+    /**
+     * Creates copy of another SaxBuffer
+     */
+    public SaxBuffer(SaxBuffer saxBuffer) {
+        this.saxbits = new ArrayList(saxBuffer.saxbits);
+    }
+
+    //
+    // ContentHandler Interface
+    //
+
+    public void skippedEntity(String name) throws SAXException {
+        saxbits.add(new SkippedEntity(name));
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        // Don't record this event
+    }
+
+    public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
+        saxbits.add(new IgnorableWhitespace(ch, start, length));
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        saxbits.add(new PI(target, data));
+    }
+
+    public void startDocument() throws SAXException {
+        saxbits.add(StartDocument.SINGLETON);
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+        saxbits.add(new StartElement(namespaceURI, localName, qName, atts));
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        saxbits.add(new EndPrefixMapping(prefix));
+    }
+
+    public void characters(char ch[], int start, int length) throws SAXException {
+        saxbits.add(new Characters(ch, start, length));
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+        saxbits.add(new EndElement(namespaceURI, localName, qName));
+    }
+
+    public void endDocument() throws SAXException {
+        saxbits.add(EndDocument.SINGLETON);
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        saxbits.add(new StartPrefixMapping(prefix, uri));
+    }
+
+    //
+    // LexicalHandler Interface
+    //
+
+    public void endCDATA() throws SAXException {
+        saxbits.add(EndCDATA.SINGLETON);
+    }
+
+    public void comment(char ch[], int start, int length) throws SAXException {
+        saxbits.add(new Comment(ch, start, length));
+    }
+
+    public void startEntity(String name) throws SAXException {
+        saxbits.add(new StartEntity(name));
+    }
+
+    public void endDTD() throws SAXException {
+        saxbits.add(EndDTD.SINGLETON);
+    }
+
+    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+        saxbits.add(new StartDTD(name, publicId, systemId));
+    }
+
+    public void startCDATA() throws SAXException {
+        saxbits.add(StartCDATA.SINGLETON);
+    }
+
+    public void endEntity(String name) throws SAXException {
+        saxbits.add(new EndEntity(name));
+    }
+
+    //
+    // Public Methods
+    //
+
+    /**
+     * Add a bit containing XMLizable object
+     */
+    public void xmlizable(XMLizable xml) {
+        saxbits.add(new XMLizableBit(xml));
+    }
+
+    /**
+     * @return true if buffer is empty
+     */
+    public boolean isEmpty() {
+        return saxbits.isEmpty();
+    }
+
+    /**
+     * @return unmodifiable list of SAX bits
+     */
+    public List getBits() {
+        return Collections.unmodifiableList(saxbits);
+    }
+
+    /**
+     * Stream this buffer into the provided content handler.
+     * If contentHandler object implements LexicalHandler, it will get lexical
+     * events as well.
+     */
+    public void toSAX(ContentHandler contentHandler) throws SAXException {
+        for (Iterator i = saxbits.iterator(); i.hasNext();) {
+            SaxBit saxbit = (SaxBit)i.next();
+            saxbit.send(contentHandler);
+        }
+    }
+
+    /**
+     * @return String value of the buffer
+     */
+    public String toString() {
+        // NOTE: This method is used in i18n XML bundle implementation
+        final StringBuffer value = new StringBuffer();
+        for (Iterator i = saxbits.iterator(); i.hasNext();) {
+            final SaxBit saxbit = (SaxBit) i.next();
+            if (saxbit instanceof Characters) {
+                ((Characters) saxbit).toString(value);
+            }
+        }
+
+        return value.toString();
+    }
+
+    /**
+     * Clear this buffer
+     */
+    public void recycle() {
+        saxbits.clear();
+    }
+
+    /**
+     * Dump buffer contents into the provided writer.
+     */
+    public void dump(Writer writer) throws IOException {
+        Iterator i = saxbits.iterator();
+        while (i.hasNext()) {
+            final SaxBit saxbit = (SaxBit) i.next();
+            saxbit.dump(writer);
+        }
+        writer.flush();
+    }
+
+    //
+    // Implementation Methods
+    //
+
+    /**
+     * Adds a SaxBit to the bits list
+     */
+    protected final void addBit(SaxBit bit) {
+        saxbits.add(bit);
+    }
+
+    /**
+     * Iterates through the bits list
+     */
+    protected final Iterator bits() {
+        return saxbits.iterator();
+    }
+
+    /**
+     * SaxBit is a representation of the SAX event. Every SaxBit is immutable object.
+     */
+    interface SaxBit {
+        public void send(ContentHandler contentHandler) throws SAXException;
+        public void dump(Writer writer) throws IOException;
+    }
+
+    public final static class StartDocument implements SaxBit, Serializable {
+        public static final StartDocument SINGLETON = new StartDocument();
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.startDocument();
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartDocument]\n");
+        }
+    }
+
+    public final static class EndDocument implements SaxBit, Serializable {
+        public static final EndDocument SINGLETON = new EndDocument();
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.endDocument();
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndDocument]\n");
+        }
+    }
+
+    public final static class PI implements SaxBit, Serializable {
+        public final String target;
+        public final String data;
+
+        public PI(String target, String data) {
+            this.target = target;
+            this.data = data;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.processingInstruction(target, data);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[ProcessingInstruction] target=" + target + ",data=" + data + "\n");
+        }
+    }
+
+    public final static class StartDTD implements SaxBit, Serializable {
+        public final String name;
+        public final String publicId;
+        public final String systemId;
+
+        public StartDTD(String name, String publicId, String systemId) {
+            this.name = name;
+            this.publicId = publicId;
+            this.systemId = systemId;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).startDTD(name, publicId, systemId);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartDTD] name=" + name + ",publicId=" + publicId + ",systemId=" + systemId + "\n");
+        }
+    }
+
+    public final static class EndDTD implements SaxBit, Serializable {
+        public static final EndDTD SINGLETON = new EndDTD();
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).endDTD();
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndDTD]\n");
+        }
+    }
+
+    public final static class StartEntity implements SaxBit, Serializable {
+        public final String name;
+
+        public StartEntity(String name) {
+            this.name = name;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).startEntity(name);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartEntity] name=" + name + "\n");
+        }
+    }
+
+    public final static class EndEntity implements SaxBit, Serializable {
+        public final String name;
+
+        public EndEntity(String name) {
+            this.name = name;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).endEntity(name);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndEntity] name=" + name + "\n");
+        }
+    }
+
+    public final static class SkippedEntity implements SaxBit, Serializable {
+        public final String name;
+
+        public SkippedEntity(String name) {
+            this.name = name;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.skippedEntity(name);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[SkippedEntity] name=" + name + "\n");
+        }
+    }
+
+    public final static class StartPrefixMapping implements SaxBit, Serializable {
+        public final String prefix;
+        public final String uri;
+
+        public StartPrefixMapping(String prefix, String uri) {
+            this.prefix = prefix;
+            this.uri = uri;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.startPrefixMapping(prefix, uri);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartPrefixMapping] prefix=" + prefix + ",uri=" + uri + "\n");
+        }
+    }
+
+    public final static class EndPrefixMapping implements SaxBit, Serializable {
+        public final String prefix;
+
+        public EndPrefixMapping(String prefix) {
+            this.prefix = prefix;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.endPrefixMapping(prefix);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndPrefixMapping] prefix=" + prefix + "\n");
+        }
+    }
+
+    public final static class StartElement implements SaxBit, Serializable {
+        public final String namespaceURI;
+        public final String localName;
+        public final String qName;
+        public final Attributes attrs;
+
+        public StartElement(String namespaceURI, String localName, String qName, Attributes attrs) {
+            this.namespaceURI = namespaceURI;
+            this.localName = localName;
+            this.qName = qName;
+            this.attrs = new org.xml.sax.helpers.AttributesImpl(attrs);
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.startElement(namespaceURI, localName, qName, attrs);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartElement] namespaceURI=" + namespaceURI + ",localName=" + localName + ",qName=" + qName + "\n");
+            for (int i = 0; i < attrs.getLength(); i++) {
+                writer.write("      [Attribute] namespaceURI=" + attrs.getURI(i) + ",localName=" + attrs.getLocalName(i) + ",qName=" + attrs.getQName(i) + ",type=" + attrs.getType(i) + ",value=" + attrs.getValue(i) + "\n");
+            }
+        }
+    }
+
+    public final static class EndElement implements SaxBit, Serializable {
+        public final String namespaceURI;
+        public final String localName;
+        public final String qName;
+
+        public EndElement(String namespaceURI, String localName, String qName) {
+            this.namespaceURI = namespaceURI;
+            this.localName = localName;
+            this.qName = qName;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.endElement(namespaceURI, localName, qName);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndElement] namespaceURI=" + namespaceURI + ",localName=" + localName + ",qName=" + qName + "\n");
+        }
+    }
+
+    public final static class Characters implements SaxBit, Serializable {
+        public final char[] ch;
+
+        public Characters(char[] ch, int start, int length) {
+            // make a copy so that we don't hold references to a potentially large array we don't control
+            this.ch = new char[length];
+            System.arraycopy(ch, start, this.ch, 0, length);
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.characters(ch, 0, ch.length);
+        }
+
+        public void toString(StringBuffer value) {
+            value.append(ch);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[Characters] ch=" + new String(ch) + "\n");
+        }
+    }
+
+    public final static class Comment implements SaxBit, Serializable {
+        public final char[] ch;
+
+        public Comment(char[] ch, int start, int length) {
+            // make a copy so that we don't hold references to a potentially large array we don't control
+            this.ch = new char[length];
+            System.arraycopy(ch, start, this.ch, 0, length);
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).comment(ch, 0, ch.length);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[Comment] ch=" + new String(ch) + "\n");
+        }
+    }
+
+    public final static class StartCDATA implements SaxBit, Serializable {
+        public static final StartCDATA SINGLETON = new StartCDATA();
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).startCDATA();
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[StartCDATA]\n");
+        }
+    }
+
+    public final static class EndCDATA implements SaxBit, Serializable {
+        public static final EndCDATA SINGLETON = new EndCDATA();
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            if (contentHandler instanceof LexicalHandler)
+                ((LexicalHandler)contentHandler).endCDATA();
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[EndCDATA]\n");
+        }
+    }
+
+    public final static class IgnorableWhitespace implements SaxBit, Serializable {
+        public final char[] ch;
+
+        public IgnorableWhitespace(char[] ch, int start, int length) {
+            // make a copy so that we don't hold references to a potentially large array we don't control
+            this.ch = new char[length];
+            System.arraycopy(ch, start, this.ch, 0, length);
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            contentHandler.ignorableWhitespace(ch, 0, ch.length);
+        }
+
+        public void dump(Writer writer) throws IOException {
+            writer.write("[IgnorableWhitespace] ch=" + new String(ch) + "\n");
+        }
+    }
+
+    public final static class XMLizableBit implements SaxBit, Serializable {
+        public final XMLizable xml;
+
+        public XMLizableBit(XMLizable xml) {
+            this.xml = xml;
+        }
+
+        public void send(ContentHandler contentHandler) throws SAXException {
+            this.xml.toSAX(new EmbeddedXMLPipe(contentHandler));
+        }
+
+        public void dump(Writer writer) throws IOException {
+            if (xml instanceof SaxBuffer) {
+                writer.write("[XMLizable] Begin nested SaxBuffer\n");
+                ((SaxBuffer)xml).dump(writer);
+                writer.write("[XMLizable] End nested SaxBuffer\n");
+            } else {
+                writer.write("[XMLizable] xml=" + xml + "\n");
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/StringXMLizable.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/StringXMLizable.java
new file mode 100644
index 0000000..b1a8b73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/StringXMLizable.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.StringReader;
+
+/**
+ * XMLizable a String
+ * 
+ * @since 2.1.7
+ */
+public class StringXMLizable implements XMLizable {
+    private String data;
+
+    public StringXMLizable(String data) {
+        this.data = data;
+    }
+
+    public void toSAX(ContentHandler contentHandler) throws SAXException {
+        SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+        parserFactory.setNamespaceAware(true);
+        SAXParser parser = null;
+        try {
+            parser = parserFactory.newSAXParser();
+        } catch (ParserConfigurationException e) {
+            throw new SAXException("Error creating SAX parser.", e);
+        }
+        parser.getXMLReader().setContentHandler(contentHandler);
+        InputSource is = new InputSource(new StringReader(data));
+        try {
+            parser.getXMLReader().parse(is);
+        } catch (IOException e) {
+            throw new SAXException(e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLBaseSupport.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLBaseSupport.java
new file mode 100644
index 0000000..83565f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLBaseSupport.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.avalon.framework.logger.Logger;
+
+import java.util.Stack;
+import java.util.Collections;
+import java.io.IOException;
+
+/**
+ * Helper class for handling xml:base attributes.
+ *
+ * <p>Usage:
+ * <ul>
+ *  <li>set location of the containing document by calling {@link #setDocumentLocation(String)}.
+ *      This is usually done when getting setDocumentLocator SAX event.
+ *  <li>forward each startElement and endElement event to this object.
+ *  <li>to resolve a relative URL against the current base, call {@link #makeAbsolute(String)}.
+ * </ul>
+ *
+ * <p>External entities are not yet taken into account when determing the current base.
+ */
+public class XMLBaseSupport {
+    public static final String XMLBASE_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
+    public static final String XMLBASE_ATTRIBUTE = "base";
+
+    /** Increased on each startElement, decreased on each endElement. */
+    private int level = 0;
+    /**
+     * The stack contains an instance of {@link BaseInfo} for each XML element
+     * that contained an xml:base attribute (not for the other elements).
+     */
+    private Stack bases = new Stack();
+    private SourceResolver resolver;
+    private Logger logger;
+
+    public XMLBaseSupport(SourceResolver resolver, Logger logger) {
+        this.resolver = resolver;
+        this.logger = logger;
+    }
+
+    public void setDocumentLocation(String loc) throws SAXException {
+        // -2 is used as level to avoid this BaseInfo to be ever popped of the stack
+        bases.push(new BaseInfo(loc, -2));
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes attrs) throws SAXException {
+        level++;
+        String base = attrs.getValue(XMLBASE_NAMESPACE_URI, XMLBASE_ATTRIBUTE);
+        if (base != null) {
+            Source baseSource = null;
+            String baseUrl;
+            try {
+                baseSource = resolve(getCurrentBase(), base);
+                baseUrl = baseSource.getURI();
+            } finally {
+                if (baseSource != null) {
+                    resolver.release(baseSource);
+                }
+            }
+            bases.push(new BaseInfo(baseUrl, level));
+        }
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName) {
+        if (getCurrentBaseLevel() == level)
+            bases.pop();
+        level--;
+    }
+
+    /**
+     * Warning: do not forget to release the source returned by this method.
+     */
+    private Source resolve(String baseURI, String location) throws SAXException {
+        try {
+            Source source;
+            if (baseURI != null) {
+                source = resolver.resolveURI(location, baseURI, Collections.EMPTY_MAP);
+            } else {
+                source = resolver.resolveURI(location);
+            }
+            if (logger.isDebugEnabled()) {
+                logger.debug("XMLBaseSupport: resolved location " + location +
+                             " against base URI " + baseURI + " to " + source.getURI());
+            }
+            return source;
+        } catch (IOException e) {
+            throw new SAXException("XMLBaseSupport: problem resolving uri.", e);
+        }
+    }
+
+    /**
+     * Makes the given path absolute based on the current base URL. Do not forget to release
+     * the returned source object!
+     * @param spec any URL (relative or absolute, containing a scheme or not)
+     */
+    public Source makeAbsolute(String spec) throws SAXException {
+        return resolve(getCurrentBase(), spec);
+    }
+
+    private String getCurrentBase() {
+        if (bases.size() > 0) {
+            BaseInfo baseInfo = (BaseInfo)bases.peek();
+            return baseInfo.getUrl();
+        }
+        return null;
+    }
+
+    private int getCurrentBaseLevel() {
+        if (bases.size() > 0) {
+            BaseInfo baseInfo = (BaseInfo)bases.peek();
+            return baseInfo.getLevel();
+        }
+        return -1;
+    }
+
+    private static final class BaseInfo {
+        private String url;
+        private int level;
+
+        public BaseInfo(String url, int level) {
+            this.url = url;
+            this.level = level;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+
+        public int getLevel() {
+            return level;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLConsumer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLConsumer.java
new file mode 100644
index 0000000..9ed2de8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLConsumer.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+/**
+ * This interfaces identifies classes that consume XML data, receiving
+ * notification of SAX events.
+ * <p>
+ * An XMLConsumer is also a SAX ContentHandler and a SAX LexicalHandler.  That
+ * means the XMLConsumer has to respect all the contracts with the SAX
+ * interfaces.  SAX stands for Serialized API for XML.  A document start, and
+ * each element start must be matched by the corresponding element end or
+ * document end.  So why does Cocoon use SAX instead of manipulating a DOM?
+ * For two main reasons: performance and scalability.  A DOM tree is much more
+ * heavy on system memory than successive calls to an API.  SAX events can be
+ * sent as soon as they are read from the originating XML, the parsing and
+ * processing can happen essentially at the same time.
+ * </p>
+ * <p>
+ * Most people's needs will be handled just fine with the ContentHandler
+ * interface, as that declares your namespaces.  However if you need lexical
+ * support to resolve entity names and such, you need the LexicalHandler
+ * interface.  The AbstractXMLConsumer base class can make implementing this
+ * interface easier so that you only need to override the events you intend to
+ * do anything with.
+ * </p>
+ *
+ * @version $Id$
+ */
+public interface XMLConsumer extends org.apache.excalibur.xml.sax.XMLConsumer {
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLFragment.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLFragment.java
new file mode 100644
index 0000000..6544da6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLFragment.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import org.w3c.dom.Node;
+
+/**
+ * This interface must be implemented by classes willing
+ * to provide an XML representation of their current state.
+ *
+ * <p>This interface exists in both Cocoon 1 and Cocoon 2 and to ensure
+ * a minimal compatibility between the two versions.</p>
+ *
+ * <p>Cocoon 2 only objects can implement the SAX-only <code>XMLizable</code>
+ * interface.</p>
+ *
+ * @version $Id$
+ */
+public interface XMLFragment extends org.apache.excalibur.xml.sax.XMLizable {
+
+    /**
+     * Appends children representing the object's state to the given node.
+     */
+    void toDOM(Node node) throws Exception;
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLMulticaster.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLMulticaster.java
new file mode 100644
index 0000000..1060541
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLMulticaster.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * @version $Id$
+ */
+public final class XMLMulticaster implements XMLConsumer {
+
+    /**
+     * The XMLMulticaster forwards incomming sax events to a list of
+     * receiving objects.
+     */
+    private ContentHandler[] contentHandlerList;
+    private LexicalHandler[] lexicalHandlerList;
+
+    /**
+     * Create a new XMLMulticaster with two consumers
+     */
+    public XMLMulticaster(XMLConsumer firstConsumer, XMLConsumer secondConsumer) {
+        this.contentHandlerList = new ContentHandler[] {firstConsumer, secondConsumer};
+        this.lexicalHandlerList = new LexicalHandler[] {firstConsumer, secondConsumer};
+    }
+
+    /**
+     * Create a new XMLMulticaster from two contentHandler/lexicalHandler pairs
+     */
+    public XMLMulticaster(ContentHandler firstContentHandler,
+                          LexicalHandler firstLexicalHandler,
+                          ContentHandler secondContentHandler,
+                          LexicalHandler secondLexicalHandler) {
+        this.contentHandlerList = new ContentHandler[] {firstContentHandler, secondContentHandler};
+        this.lexicalHandlerList = new LexicalHandler[] {firstLexicalHandler, secondLexicalHandler};
+    }
+
+    public XMLMulticaster(ContentHandler[] chList,
+                          LexicalHandler[] lhList) {
+        this.contentHandlerList = chList;
+        this.lexicalHandlerList = lhList;
+    }
+
+    public void startDocument() throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++) {
+            this.contentHandlerList[i].startDocument();
+        }
+    }
+
+    public void endDocument() throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++) {
+                this.contentHandlerList[i].endDocument();
+        }
+    }
+
+    public void startPrefixMapping(java.lang.String prefix, java.lang.String uri) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].startPrefixMapping(prefix, uri);
+    }
+
+    public void endPrefixMapping(java.lang.String prefix) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].endPrefixMapping(prefix);
+    }
+
+    public void startElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName, Attributes atts) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].startElement(namespaceURI, localName, qName, atts);
+    }
+
+    public void endElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].endElement(namespaceURI, localName, qName);
+    }
+
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].characters(ch, start, length);
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].ignorableWhitespace(ch, start, length);
+    }
+
+    public void processingInstruction(java.lang.String target, java.lang.String data) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].processingInstruction(target, data);
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].setDocumentLocator(locator);
+    }
+
+    public void skippedEntity(java.lang.String name) throws SAXException {
+        for(int i=0; i<this.contentHandlerList.length; i++)
+                this.contentHandlerList[i].skippedEntity(name);
+    }
+
+    public void startDTD(String name, String public_id, String system_id)
+                        throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].startDTD(name, public_id, system_id);
+    }
+
+    public void endDTD() throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].endDTD();
+    }
+
+    public void startEntity(String name) throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                 this.lexicalHandlerList[i].startEntity(name);
+    }
+
+    public void endEntity(String name) throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].endEntity(name);
+    }
+
+    public void startCDATA() throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].startCDATA();
+    }
+
+    public void endCDATA() throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].endCDATA();
+    }
+
+    public void comment(char ary[], int start, int length)
+                        throws SAXException {
+        for(int i=0; i<this.lexicalHandlerList.length; i++)
+            if (this.lexicalHandlerList[i] != null)
+                this.lexicalHandlerList[i].comment(ary, start, length);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLPipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLPipe.java
new file mode 100644
index 0000000..d418c2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLPipe.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+/**
+ * The XMLPipe is both an XMLProducer and an XMLConsumer.  All the Transformers
+ * implement this interface for example.  By having an XMLPipe interface, we
+ * can chain more than one pipeline component together.  What this means is
+ * that Cocoon will honor all the XMLProducer contracts in a pipeline first.
+ * The SAX pipeline will be completely assembled before any SAX calls are
+ * issued.  Cocoon does not want any stray calls to get lost.  There can be
+ * zero or more XMLPipes in a pipeline, but there must always be at least one
+ * XMLProducer and XMLConsumer pair.
+ * <p>
+ * Because an XMLPipe is both a source and a sink for SAX events, the basic
+ * contract that you need to worry about is that you must forward any SAX
+ * events on that you are not intercepting and transforming.  As you receive
+ * your startDocument event, pass it on to the XMLConsumer you received as part
+ * of the XMLProducer side of the contract.  An example ASCII art will help
+ * make it a bit more clear:
+ * </p>
+ * <pre>
+ * XMLProducer -&gt; (XMLConsumer)XMLPipe(XMLProducer) -&gt; XMLConsumer
+ * </pre>
+ * <p>
+ * A typical example would be using the FileGenerator (an XMLProducer), sending
+ * events to an XSLTTransformer (an XMLPipe), which then sends events to an
+ * HTMLSerializer (an XMLConsumer).  The XSLTTransformer acts as an XMLConsumer
+ * to the FileGenerator, and also acts as an XMLProducer to the HTMLSerializer.
+ * It is still the responsibility of the XMLPipe component to ensure that the
+ * XML passed on to the next component is valid--provided the XML received from
+ * the previous component is valid.  In layman's terms it means if you don't
+ * intend to alter the input, just pass it on.  In most cases we just want to
+ * transform a small snippet of XML.  For example, inserting a snippet of XML
+ * based on an embedded element in a certain namespace.  Anything that doesn't
+ * belong to the namespace you are worried about should be passed on as is.
+ * </p>
+ *
+ * @version $Id$
+ */
+public interface XMLPipe extends XMLConsumer, XMLProducer {}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLProducer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLProducer.java
new file mode 100644
index 0000000..9d1093d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLProducer.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+/**
+ * This interfaces identifies classes that produce XML data, sending SAX
+ * events to the configured <code>XMLConsumer</code>.
+ * <p>
+ * The XMLProducer is comprised of only one method to give the component the
+ * next element of the pipeline.  Cocoon calls the <code>setConsumer()</code>
+ * method with the reference to the next XMLConsumer in the pipeline.  The
+ * approach allows the XMLProducer to call the different SAX related methods on
+ * the XMLConsumer without knowing ahead of time what that consumer will be.
+ * The design is very simple and very powerful in that it allows Cocoon to
+ * daisy chain several components in any order and then execute the pipeline.
+ * </p>
+ * <p>
+ * Any producer can be paired with any consumer and we have a pipeline.  The
+ * core design is very powerful and allows the end user to mix and match
+ * sitemap components as they see fit.  Cocoon will always call
+ * <code>setConsumer()</code> on every XMLProducer in a pipeline or it will
+ * throw an exception saying that the pipeline is invalid (i.e. there is no
+ * serializer for the pipeline).  The only contract that the XMLProducer has to
+ * worry about is that it must always make calls to the XMLConsumer passed in
+ * through the <code>setConsumer()</code> method.
+ * </p>
+ *
+ * @version $Id$
+ */
+public interface XMLProducer {
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     *
+     * @param consumer  The XMLConsumer target for SAX events.
+     */
+    void setConsumer(XMLConsumer consumer);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLUtils.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLUtils.java
new file mode 100644
index 0000000..f98b6c6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/XMLUtils.java
@@ -0,0 +1,683 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * XML utility methods.
+ *
+ * @version $Id$
+ */
+public class XMLUtils {
+
+    /**
+     * Empty attributes immutable object.
+     */
+    public static final Attributes EMPTY_ATTRIBUTES = new ImmutableAttributesImpl();
+
+    private static final SAXTransformerFactory FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
+    private static final Properties XML_FORMAT = createDefaultPropertiesForXML(false);
+    private static final Properties XML_FORMAT_NODECL = createDefaultPropertiesForXML(true);
+
+
+    // FIXME: parent parameter not used anymore
+    // Using parent because some dom implementations like jtidy are bugged,
+    // cannot get parent or delete child
+    public static void stripDuplicateAttributes(Node node, Node parent) {
+
+        // The output depends on the type of the node
+        switch(node.getNodeType()) {
+        case Node.DOCUMENT_NODE: {
+            Document doc = (Document)node;
+            Node child = doc.getFirstChild();
+            while(child != null) {
+                stripDuplicateAttributes(child, node);
+                child = child.getNextSibling();
+            }
+            break;
+        }
+
+        case Node.ELEMENT_NODE: {
+            Element elt = (Element) node;
+            NamedNodeMap attrs = elt.getAttributes();
+
+            ArrayList nodesToRemove = new ArrayList();
+            int nodesToRemoveNum = 0;
+
+            for (int i = 0; i < attrs.getLength(); i++) {
+                final Node a = attrs.item(i);
+
+                for (int j = 0; j < attrs.getLength(); j++) {
+                    final Node b = attrs.item(j);
+
+                    //if there are two attributes with same name
+                    if (i != j && (a.getNodeName().equals(b.getNodeName()))) {
+                        nodesToRemove.add(b);
+                        nodesToRemoveNum++;
+                    }
+                }
+            }
+
+            for (int i = 0; i < nodesToRemoveNum; i++) {
+                Attr nodeToDelete = (Attr) nodesToRemove.get(i);
+                Element nodeToDeleteParent = (Element) node; // nodeToDelete.getParentNode();
+                nodeToDeleteParent.removeAttributeNode(nodeToDelete);
+            }
+
+            nodesToRemove.clear();
+
+            Node child = elt.getFirstChild();
+            while (child != null) {
+                stripDuplicateAttributes(child, node);
+                child = child.getNextSibling();
+            }
+
+            break;
+        }
+
+        default:
+            //do nothing
+            break;
+        }
+    }
+
+    /**
+     * Get an <code>XMLConsumer</code> from a <code>ContentHandler</code> and
+     * a <code>LexicalHandler</code>. If the content handler is already an
+     * <code>XMLConsumer</code>, it is returned as is, otherwise it is wrapped
+     * in an <code>XMLConsumer</code> with the lexical handler.
+     *
+     * @param ch the content handler, which should not be <code>null</code>
+     * @param lh the lexical handler, which can be <code>null</code>
+     * @return an <code>XMLConsumer</code> for <code>ch</code> an <code>lh</code>
+     */
+    public static XMLConsumer getConsumer(ContentHandler ch, LexicalHandler lh) {
+        if (ch instanceof XMLConsumer) {
+            return (XMLConsumer)ch;
+        } else {
+            if (lh == null && ch instanceof LexicalHandler) {
+                lh = (LexicalHandler)ch;
+            }
+            return new ContentHandlerWrapper(ch, lh);
+        }
+    }
+
+    /**
+     * Get an <code>XMLConsumer</code> from <code>ContentHandler</code>. If the
+     * content handler is already an <code>XMLConsumer</code>, it is returned as
+     * is, otherwise it is wrapped in an <code>XMLConsumer</code>.
+     *
+     * @param ch the content handler, which should not be <code>null</code>
+     * @return an <code>XMLConsumer</code> for <code>ch</code>
+     */
+    public static XMLConsumer getConsumer(ContentHandler ch) {
+        return getConsumer(ch, null);
+    }
+
+    /**
+     * Method for static initializer
+     */
+    private static Properties createDefaultPropertiesForXML(boolean omitXMLDeclaration) {
+        final Properties format = new Properties();
+        format.put(OutputKeys.METHOD, "xml");
+        format.put(OutputKeys.OMIT_XML_DECLARATION, (omitXMLDeclaration ? "yes" : "no"));
+        format.put(OutputKeys.INDENT, "yes");
+        return format;
+    }
+
+    /**
+     * Create a new properties set for serializing xml.
+     * The omit xml declaration property can be controlled by the flag.
+     *
+     * <ul>
+     * <li>Method: xml
+     * <li>Omit xml declaration: according to the flag
+     * <li>Indent: yes
+     * </ul>
+     */
+    public static Properties createPropertiesForXML(boolean omitXMLDeclaration) {
+        /* Properties passed as parameters to the Properties constructor become "default properties".
+            But Xalan does not use the default properties, so they are lost.
+            Therefore, we must promote them to "set properties".
+         */
+         Properties propertiesForXML = new Properties(omitXMLDeclaration? XML_FORMAT_NODECL: XML_FORMAT);
+         for (Enumeration e = propertiesForXML.propertyNames(); e.hasMoreElements(); ) {
+             String propertyName = (String)e.nextElement();
+             propertiesForXML.setProperty(propertyName, propertiesForXML.getProperty(propertyName, ""));
+         }
+         return propertiesForXML;
+    }
+
+    /**
+     * Serialize a DOM node into a string using format created by
+     * <code>createPropertiesForXML(false)</code>.
+     *
+     * @see #createPropertiesForXML
+     */
+    public static String serializeNode(Node node)
+    throws ProcessingException {
+        // Don't create new properties as we do not intend to modify defaults.
+        return serializeNode(node, XML_FORMAT);
+    }
+
+    /**
+     * Serialize a DOM node into a string.
+     * If the node is null the empty string is returned.
+     *
+     * @param format The format of the output to be used by SAX transformer.
+     * @see OutputKeys
+     */
+    public static String serializeNode(Node node, Properties format)
+    throws ProcessingException {
+
+        try {
+            if (node == null) {
+                return "";
+            }
+
+            StringWriter writer = new StringWriter();
+            TransformerHandler transformerHandler;
+            transformerHandler = FACTORY.newTransformerHandler();
+            transformerHandler.getTransformer().setOutputProperties(format);
+            transformerHandler.setResult(new StreamResult(writer));
+            if (node.getNodeType() != Node.DOCUMENT_NODE) {
+                transformerHandler.startDocument();
+            }
+            DOMStreamer domStreamer = new DOMStreamer(transformerHandler, transformerHandler);
+            domStreamer.stream(node);
+            if (node.getNodeType() != Node.DOCUMENT_NODE) {
+                transformerHandler.endDocument();
+            }
+
+            return writer.toString();
+        } catch (TransformerException e) {
+            throw new ProcessingException("TransformerException: " + e, e);
+        } catch (SAXException e) {
+            throw new ProcessingException("SAXException while streaming DOM node to SAX: " + e, e);
+        }
+    }
+
+    /**
+     * Serialize a XMLizable into a string.
+     * If the object is null the empty string is returned.
+     *
+     * @param format The format of the output to be used by SAX transformer.
+     * @see OutputKeys
+     */
+    public static String serialize(org.apache.excalibur.xml.sax.XMLizable xml, Properties format)
+    throws ProcessingException {
+        
+        try {
+            if (xml == null) {
+                return "";
+            }
+
+            StringWriter writer = new StringWriter();
+            TransformerHandler transformerHandler;
+            transformerHandler = FACTORY.newTransformerHandler();
+            transformerHandler.getTransformer().setOutputProperties(format);
+            transformerHandler.setResult(new StreamResult(writer));
+            transformerHandler.startDocument();
+            xml.toSAX(new EmbeddedXMLPipe(transformerHandler));
+            transformerHandler.endDocument();
+
+            return writer.toString();
+        } catch (TransformerException e) {
+            throw new ProcessingException("TransformerException: " + e, e);
+        } catch (SAXException e) {
+            throw new ProcessingException("SAXException while streaming DOM node to SAX: " + e, e);
+        }
+    }
+
+    /**
+     * Add string data
+     *
+     * @param contentHandler The SAX content handler
+     * @param data The string data
+     */
+    public static void data(ContentHandler contentHandler,
+                            String data)
+    throws SAXException {
+
+        contentHandler.characters(data.toCharArray(), 0, data.length());
+    }
+
+    /**
+     * Implementation of &lt;xsp:expr&gt; for <code>String</code> :
+     * outputs characters representing the value.
+     *
+     * @param contentHandler the SAX content handler
+     * @param text the value
+     */
+    public static void valueOf(ContentHandler contentHandler, String text)
+    throws SAXException {
+
+        if (text != null) {
+            data(contentHandler, text);
+        }
+    }
+
+    /**
+     * Implementation of &lt;xsp:expr&gt; for <code>XMLizable</code> :
+     * outputs the value by calling <code>v.toSax(contentHandler)</code>.
+     *
+     * @param contentHandler the SAX content handler
+     * @param v the XML fragment
+     */
+    public static void valueOf(ContentHandler contentHandler,
+                               org.apache.excalibur.xml.sax.XMLizable v)
+    throws SAXException {
+
+        if (v != null) {
+            v.toSAX(contentHandler);
+        }
+    }
+
+    /**
+     * Implementation of &lt;xsp:expr&gt; for <code>org.w3c.dom.Node</code> :
+     * converts the Node to a SAX event stream.
+     *
+     * @param contentHandler the SAX content handler
+     * @param v the value
+     */
+    public static void valueOf(ContentHandler contentHandler, Node v)
+    throws SAXException {
+
+        if (v != null) {
+            DOMStreamer streamer = new DOMStreamer(contentHandler);
+            if (contentHandler instanceof LexicalHandler) {
+                streamer.setLexicalHandler((LexicalHandler)contentHandler);
+            }
+            streamer.stream(v);
+        }
+    }
+
+    /**
+     * Implementation of &lt;xsp:expr&gt; for <code>java.util.Collection</code> :
+     * outputs the value by calling <code>xspExpr()</code> on each element of the
+     * collection.
+     *
+     * @param contentHandler the SAX content handler
+     * @param v the XML fragment
+     */
+    public static void valueOf(ContentHandler contentHandler,
+                               Collection v)
+    throws SAXException {
+
+        if (v != null) {
+            Iterator iterator = v.iterator();
+            while (iterator.hasNext()) {
+                valueOf(contentHandler, iterator.next());
+            }
+        }
+     }
+
+    /**
+     * Implementation of &lt;xsp:expr&gt; for <code>Object</code> depending on its class :
+     * <ul>
+     * <li>if it's an array, call <code>xspExpr()</code> on all its elements,</li>
+     * <li>if it's class has a specific <code>xspExpr()</code>implementation, use it,</li>
+     * <li>else, output it's string representation.</li>
+     * </ul>
+     *
+     * @param contentHandler the SAX content handler
+     * @param v the value
+     */
+    public static void valueOf(ContentHandler contentHandler, Object v)
+    throws SAXException {
+
+        if (v == null) {
+            return;
+        }
+
+        // Array: recurse over each element
+        if (v.getClass().isArray()) {
+            Object[] elements = (Object[]) v;
+
+            for (int i = 0; i < elements.length; i++) {
+                valueOf(contentHandler, elements[i]);
+            }
+            return;
+         }
+
+         // Check handled object types in case they were not typed in the XSP
+
+         // XMLizable
+         if (v instanceof org.apache.excalibur.xml.sax.XMLizable) {
+             valueOf(contentHandler, (org.apache.excalibur.xml.sax.XMLizable)v);
+             return;
+         }
+
+         // Node
+         if (v instanceof Node) {
+             valueOf(contentHandler, (Node)v);
+             return;
+         }
+
+         // Collection
+         if (v instanceof Collection) {
+             valueOf(contentHandler, (Collection)v);
+             return;
+         }
+
+         // Give up: hope it's a string or has a meaningful string representation
+         data(contentHandler, String.valueOf(v));
+    }
+
+    /**
+     * Create a start and endElement with a empty Namespace and without Attributes
+     *
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void createElement(ContentHandler contentHandler,
+                                     String localName)
+    throws SAXException {
+
+        startElement(contentHandler, localName);
+        endElement(contentHandler, localName);
+    }
+
+    /**
+     * Create a start and endElement with a empty Namespace and without Attributes
+     * The content of the Element is set to the stringValue parameter
+     *
+     * @param localName The local name (without prefix)
+     * @param stringValue The content of the Element
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void createElement(ContentHandler contentHandler,
+                                     String localName,
+                                     String stringValue)
+    throws SAXException {
+
+        startElement(contentHandler, localName);
+        data(contentHandler, stringValue);
+        endElement(contentHandler, localName);
+    }
+
+    /**
+     * Create a start and endElement with a empty Namespace
+     *
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void createElement(ContentHandler contentHandler,
+                                     String localName,
+                                     Attributes atts)
+    throws SAXException {
+
+        startElement(contentHandler, localName, atts);
+        endElement(contentHandler, localName);
+    }
+
+    /**
+     * Create a start and endElement with a empty Namespace
+     * The content of the Element is set to the stringValue parameter
+     *
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @param stringValue The content of the Element
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void createElement(ContentHandler contentHandler,
+                                     String localName,
+                                     Attributes atts,
+                                     String stringValue)
+    throws SAXException {
+
+        startElement(contentHandler, localName, atts);
+        data(contentHandler, stringValue);
+        endElement(contentHandler, localName);
+    }
+
+    /**
+     * Create a start and endElement without Attributes
+     *
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void createElementNS(ContentHandler contentHandler,
+                                       String namespaceURI,
+                                       String localName)
+    throws SAXException {
+
+        startElement(contentHandler, namespaceURI, localName);
+        endElement(contentHandler, namespaceURI, localName);
+    }
+
+    /**
+     * Create a start and endElement without Attributes
+     * The content of the Element is set to the stringValue parameter
+     *
+     * @param localName The local name (without prefix)
+     * @param stringValue The content of the Element
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void createElementNS(ContentHandler contentHandler,
+                                       String namespaceURI,
+                                       String localName,
+                                       String stringValue)
+    throws SAXException {
+
+        startElement(contentHandler, namespaceURI, localName);
+        data(contentHandler, stringValue);
+        endElement(contentHandler, namespaceURI, localName);
+    }
+
+    /**
+     * Create a start and endElement
+     *
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void createElementNS(ContentHandler contentHandler,
+                                       String namespaceURI,
+                                       String localName,
+                                       Attributes atts)
+    throws SAXException {
+
+        startElement(contentHandler, namespaceURI, localName, atts);
+        endElement(contentHandler, namespaceURI, localName);
+    }
+
+    /**
+     * Create a start and endElement with a empty Namespace
+     * The content of the Element is set to the stringValue parameter
+     *
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @param stringValue The content of the Element
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void createElementNS(ContentHandler contentHandler,
+                                       String namespaceURI,
+                                       String localName,
+                                       Attributes atts,
+                                       String stringValue)
+    throws SAXException {
+
+        startElement(contentHandler, namespaceURI, localName, atts);
+        data(contentHandler, stringValue);
+        endElement(contentHandler, namespaceURI, localName);
+    }
+
+
+    /**
+     * Create endElement with empty Namespace
+     *
+     * <p>For information on the names, see startElement.</p>
+     *
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public static void endElement(ContentHandler contentHandler,
+                                  String localName)
+    throws SAXException {
+
+        contentHandler.endElement("", localName, localName);
+    }
+
+    /**
+     * Create endElement
+     * Prefix must be mapped to empty String
+     *
+     * <p>For information on the names, see startElement.</p>
+     *
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     */
+    public static void endElement(ContentHandler contentHandler,
+                                  String namespaceURI,
+                                  String localName)
+    throws SAXException {
+
+        contentHandler.endElement(namespaceURI, localName, localName);
+    }
+
+    /**
+     * Create a startElement with a empty Namespace and without Attributes
+     *
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void startElement(ContentHandler contentHandler,
+                                    String localName)
+    throws SAXException {
+
+        contentHandler.startElement("", localName, localName, EMPTY_ATTRIBUTES);
+    }
+
+    /**
+     * Create a startElement without Attributes
+     * Prefix must be mapped to empty String
+     *
+     * @param namespaceURI The Namespace URI
+     * @param localName The local name (without prefix)
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     */
+    public static void startElement(ContentHandler contentHandler,
+                                    String namespaceURI,
+                                    String localName)
+    throws SAXException {
+
+        contentHandler.startElement(namespaceURI, localName, localName, EMPTY_ATTRIBUTES);
+    }
+
+    /**
+     * Create a startElement with a empty Namespace
+     *
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void startElement(ContentHandler contentHandler,
+                                    String localName,
+                                    Attributes atts)
+    throws SAXException {
+
+        contentHandler.startElement("", localName, localName, atts);
+    }
+
+    /**
+     * Create a startElement with a empty Namespace
+     * Prefix must be mapped to empty String
+     *
+     * @param namespaceURI The Namespace URI
+     * @param localName The local name (without prefix)
+     * @param atts The attributes attached to the element.  If
+     *        there are no attributes, it shall be an empty
+     *        Attributes object.
+     * @exception org.xml.sax.SAXException Any SAX exception, possibly
+     *            wrapping another exception.
+     * @see #endElement(ContentHandler, String)
+     * @see org.xml.sax.Attributes
+     */
+    public static void startElement(ContentHandler contentHandler,
+                                    String namespaceURI,
+                                    String localName,
+                                    Attributes atts)
+    throws SAXException {
+
+        contentHandler.startElement(namespaceURI, localName, localName, atts);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMBuilder.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMBuilder.java
new file mode 100644
index 0000000..98acfff
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMBuilder.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml.dom;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+
+import org.apache.cocoon.xml.AbstractXMLPipe;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+/**
+ * The <code>DOMBuilder</code> is a utility class that will generate a W3C
+ * DOM Document from SAX events.
+ *
+ * @version $Id$
+ */
+public class DOMBuilder extends AbstractXMLPipe {
+
+    /** The default transformer factory shared by all instances */
+    protected static final SAXTransformerFactory FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
+
+    /** The transformer factory */
+    protected SAXTransformerFactory factory;
+
+    /** The listener */
+    protected Listener listener;
+
+    /** The result */
+    protected DOMResult result;
+
+    /** The parentNode */
+    protected Node parentNode;
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     */
+    public DOMBuilder() {
+        this((Listener) null, (Node) null);
+    }
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     */
+    public DOMBuilder(SAXTransformerFactory factory) {
+        this(factory, null, null);
+    }
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     */
+    public DOMBuilder(Listener listener) {
+        this(listener, null);
+    }
+
+    /**
+     * Constructs a new instance that appends nodes to the given parent node.
+     * <br/>
+     * <strong>Note:</strong> You cannot use a <code>Listener<code> when appending to a
+     * <code>Node</code>, because the notification occurs at <code>endDocument()</code>
+     * which does not happen here.
+     */
+    public DOMBuilder(Node parentNode) {
+        this(null, parentNode);
+    }
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     */
+    public DOMBuilder(Listener listener, Node parentNode) {
+        this((SAXTransformerFactory) null, listener, parentNode);
+    }
+
+    /**
+     * Construct a new instance of this DOMBuilder.
+     */
+    public DOMBuilder(SAXTransformerFactory factory, Listener listener, Node parentNode) {
+        super();
+        this.factory = factory == null? FACTORY: factory;
+        this.listener = listener;
+        this.parentNode = parentNode;
+        setup();
+    }
+
+    /**
+     * Setup this instance transformer and result objects.
+     */
+    private void setup() {
+        try {
+            TransformerHandler handler = this.factory.newTransformerHandler();
+            setContentHandler(handler);
+            setLexicalHandler(handler);
+            if (this.parentNode != null) {
+                this.result = new DOMResult(this.parentNode);
+            } else {
+                this.result = new DOMResult();
+            }
+            handler.setResult(this.result);
+        } catch (javax.xml.transform.TransformerException local) {
+            throw new CascadingRuntimeException("Fatal-Error: Unable to get transformer handler", local);
+        }
+    }
+
+    /**
+     * Recycle this builder, prepare for re-use.
+     */
+    public void recycle() {
+        super.recycle();
+        setup();
+    }
+
+    /**
+     * Return the newly built Document.
+     */
+    public Document getDocument() {
+        if (this.result == null || this.result.getNode() == null) {
+            return null;
+        } else if (this.result.getNode().getNodeType() == Node.DOCUMENT_NODE) {
+            return (Document) this.result.getNode();
+        } else {
+            return this.result.getNode().getOwnerDocument();
+        }
+    }
+
+    /**
+     * Receive notification of the end of a document.
+     *
+     * @exception SAXException If this method was not called appropriately.
+     */
+    public void endDocument() throws SAXException {
+        super.endDocument();
+        // Notify the listener
+        notifyListener();
+    }
+
+    /**
+     * Receive notification of a successfully completed DOM tree generation.
+     */
+    protected void notifyListener() throws SAXException {
+        if (this.listener != null) {
+            this.listener.notify(getDocument());
+        }
+    }
+
+    /**
+     * The Listener interface must be implemented by those objects willing to
+     * be notified of a successful DOM tree generation.
+     */
+    public interface Listener {
+
+        /**
+         * Receive notification of a successfully completed DOM tree generation.
+         */
+        void notify(Document doc) throws SAXException;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMFactory.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMFactory.java
new file mode 100644
index 0000000..2f2258c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.dom;
+
+import org.w3c.dom.Document;
+
+/**
+ * This interface identifies classes producing instances of DOM
+ * <code>Document</code> objects.
+ *
+ * @version $Id$
+ */
+public interface DOMFactory {
+    /**
+     * Create a new Document object.
+     */
+    Document newDocument();
+
+    /**
+     * Create a new Document object with a specified DOCTYPE.
+     */
+    Document newDocument(String name);
+
+    /**
+     * Create a new Document object with a specified DOCTYPE, public ID and
+     * system ID.
+     */
+    Document newDocument(String name, String publicId, String systemId);
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMStreamer.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMStreamer.java
new file mode 100644
index 0000000..1a7ff71
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMStreamer.java
@@ -0,0 +1,716 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml.dom;
+
+import org.apache.avalon.excalibur.pool.Recyclable;
+
+import org.apache.cocoon.xml.AbstractXMLProducer;
+import org.apache.cocoon.xml.EmbeddedXMLPipe;
+import org.apache.cocoon.xml.XMLConsumer;
+import org.apache.cocoon.xml.XMLProducer;
+
+import org.apache.commons.lang.StringUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * The <code>DOMStreamer</code> is a utility class that will generate SAX
+ * events from a W3C DOM Document.
+ *
+ * <p>The DOMStreamer uses a different strategy based on the value of the
+ * normalizeNamespaces property:
+ * <ul>
+ * <li>if true (the default), the DOMStreamer will normalize namespace
+ * declarations (i.e. add missing xmlns attributes or correct them). See
+ * also {@link NamespaceNormalizingDOMStreamer}.
+ * <li>if false, the standard JAXP identity transformer is used.
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class DOMStreamer implements XMLProducer, Recyclable {
+
+    /** The transformer factory shared by all instances (only used by DefaultDOMStreamer) */
+    protected static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+
+    /** Default value for normalizeNamespaces. */
+    private static final boolean DEFAULT_NORMALIZE_NAMESPACES = true;
+
+    /** Indicates whether namespace normalization should happen. */
+    protected boolean normalizeNamespaces = DEFAULT_NORMALIZE_NAMESPACES;
+
+    /** DOMStreamer used in case of namespace normalization. */
+    protected NamespaceNormalizingDOMStreamer namespaceNormalizingDOMStreamer = new NamespaceNormalizingDOMStreamer();
+
+    /** DOMStreamer used when namespace normalization should not explicitely happen. */
+    protected DefaultDOMStreamer defaultDOMStreamer = new DefaultDOMStreamer();
+
+    /**
+     * Create a new <code>DOMStreamer</code> instance.
+     */
+    public DOMStreamer() {
+        super();
+    }
+
+    /**
+     * Create a new <code>DOMStreamer</code> instance.
+     */
+    public DOMStreamer(ContentHandler content, LexicalHandler lexical) {
+        this();
+        setContentHandler(content);
+        setLexicalHandler(lexical);
+    }
+
+    /**
+     * Create a new <code>DOMStreamer</code> instance.
+     */
+    public DOMStreamer(XMLConsumer consumer) {
+        this(consumer, consumer);
+    }
+
+    /**
+     * Create a new <code>DOMStreamer</code> instance.
+     */
+    public DOMStreamer(ContentHandler content) {
+        this(content, content instanceof LexicalHandler ? (LexicalHandler) content : null);
+    }
+
+    /**
+     * Set the <code>XMLConsumer</code> that will receive XML data.
+     */
+    public void setConsumer(XMLConsumer consumer) {
+        setContentHandler(consumer);
+        setLexicalHandler(consumer);
+    }
+
+    /**
+     * Set the <code>ContentHandler</code> that will receive XML data.
+     */
+    public void setContentHandler(ContentHandler handler) {
+        defaultDOMStreamer.setContentHandler(handler);
+        namespaceNormalizingDOMStreamer.setContentHandler(handler);
+    }
+
+    /**
+     * Set the <code>LexicalHandler</code> that will receive XML data.
+     */
+    public void setLexicalHandler(LexicalHandler handler) {
+        defaultDOMStreamer.setLexicalHandler(handler);
+        namespaceNormalizingDOMStreamer.setLexicalHandler(handler);
+    }
+
+    /**
+     * Start the production of SAX events.
+     */
+    public void stream(Node node) throws SAXException {
+        if (normalizeNamespaces) {
+            namespaceNormalizingDOMStreamer.stream(node);
+        } else {
+            defaultDOMStreamer.stream(node);
+        }
+    }
+
+    public boolean isNormalizeNamespaces() {
+        return normalizeNamespaces;
+    }
+
+    public void setNormalizeNamespaces(boolean normalizeNamespaces) {
+        this.normalizeNamespaces = normalizeNamespaces;
+    }
+
+    public void recycle() {
+        defaultDOMStreamer.recycle();
+        namespaceNormalizingDOMStreamer.recycle();
+        normalizeNamespaces = DEFAULT_NORMALIZE_NAMESPACES;
+    }
+
+    /**
+     * Streams a DOM tree to SAX events and normalizes namespace declarations on the way.
+     *
+     * <p>The code in this class is based on the org.apache.xml.utils.TreeWalker class from Xalan,
+     * though it differs in some important ways.
+     *
+     * <p>This class will automatically fix up ("normalize") namespace declarations
+     * while streaming to SAX. The original DOM-tree is not modified. The algorithm
+     * used is described in
+     * <a href="http://www.w3.org/TR/2002/WD-DOM-Level-3-Core-20021022/namespaces-algorithms.html#normalizeDocumentAlgo">an appendix of the DOM Level 3 spec</a>.
+     *
+     * <p>This class will NOT check the correctness of namespaces, e.g. it will not
+     * check that the "xml" prefix is not misused etc.
+     *
+     */
+    public static class NamespaceNormalizingDOMStreamer extends AbstractXMLProducer {
+        /**
+         * Information about the current element. Used to remember the localName, qName
+         * and namespaceURI for generating the endElement event, and holds the namespaces
+         * declared on the element. This extra class is needed because we don't want to
+         * modify the DOM-tree itself. The currentElementInfo has a pointer to its parent
+         * elementInfo.
+         */
+        protected NamespaceNormalizingDOMStreamer.ElementInfo currentElementInfo;
+
+        /** Counter used when generating new namespace prefixes. */
+        protected int newPrefixCounter;
+
+        public void recycle() {
+            super.recycle();
+            currentElementInfo = null;
+            newPrefixCounter = 0;
+        }
+
+        /**
+         * Start the production of SAX events.
+         *
+         * <p>Perform a pre-order traversal non-recursive style.
+         *
+         * <p>Note that TreeWalker assumes that the subtree is intended to represent
+         * a complete (though not necessarily well-formed) document and, during a
+         * traversal, startDocument and endDocument will always be issued to the
+         * SAX listener.
+         *
+         * @param pos Node in the tree where to start traversal
+         */
+        protected void stream(Node pos) throws SAXException {
+
+            // Start document only if we're streaming a document
+            boolean isDoc = (pos.getNodeType() == Node.DOCUMENT_NODE);
+            if (isDoc) {
+              contentHandler.startDocument();
+            }
+
+            Node top = pos;
+            while (null != pos) {
+                startNode(pos);
+
+                Node nextNode = pos.getFirstChild();
+                while (null == nextNode) {
+                    endNode(pos);
+
+                    if (top.equals(pos)) {
+                        break;
+                    }
+
+                    nextNode = pos.getNextSibling();
+                    if (null == nextNode) {
+                        pos = pos.getParentNode();
+
+                        if ((null == pos) || (top.equals(pos))) {
+                            if (null != pos) {
+                                endNode(pos);
+                            }
+                            nextNode = null;
+
+                            break;
+                        }
+                    }
+                }
+
+                pos = nextNode;
+            }
+
+            if (isDoc) {
+            	contentHandler.endDocument();
+            }
+        }
+
+        private final void dispatchChars(Node node) throws SAXException {
+            final String data = ((Text) node).getData();
+            if ( data != null ) {
+                contentHandler.characters(data.toCharArray(), 0, data.length());
+            }
+        }
+
+        /**
+         * Start processing given node
+         *
+         * @param node Node to process
+         */
+        protected void startNode(Node node) throws SAXException {
+
+            switch (node.getNodeType()) {
+                case Node.COMMENT_NODE:
+                    {
+                        if (lexicalHandler != null) {
+                            final String data = ((Comment) node).getData();
+                            if ( data != null ) {
+                                lexicalHandler.comment(data.toCharArray(), 0, data.length());
+                            }
+                        }
+                    }
+                    break;
+                case Node.DOCUMENT_FRAGMENT_NODE:
+
+                    // ??;
+                    break;
+                case Node.DOCUMENT_NODE:
+
+                    break;
+                case Node.ELEMENT_NODE:
+                    NamedNodeMap atts = node.getAttributes();
+                    int nAttrs = atts.getLength();
+
+                    // create a list of localy declared namespace prefixes
+                    currentElementInfo = new NamespaceNormalizingDOMStreamer.ElementInfo(currentElementInfo);
+                    for (int i = 0; i < nAttrs; i++) {
+                        Node attr = atts.item(i);
+                        String attrName = attr.getNodeName();
+
+                        if (attrName.equals("xmlns") || attrName.startsWith("xmlns:")) {
+                            int index;
+                            String prefix = (index = attrName.indexOf(":")) < 0
+                                    ? "" : attrName.substring(index + 1);
+
+                            currentElementInfo.put(prefix, attr.getNodeValue());
+                        }
+                    }
+
+                    String namespaceURI = node.getNamespaceURI();
+                    String prefix = node.getPrefix();
+                    String localName = node.getLocalName();
+
+                    if (localName == null) {
+                        // this is an element created with createElement instead of createElementNS
+                        String[] prefixAndLocalName = getPrefixAndLocalName(node.getNodeName());
+                        prefix = prefixAndLocalName[0];
+                        localName = prefixAndLocalName[1];
+                        // note: if prefix is null, there can still be a default namespace...
+                        namespaceURI = getNamespaceForPrefix(prefix, (Element)node);
+                    }
+
+                    if (namespaceURI != null) {
+                        // no prefix means: make this the default namespace
+                        if (prefix == null) {
+                            prefix = "";
+                        }
+                        // check that is declared
+                        String uri = currentElementInfo.findNamespaceURI(prefix);
+                        if (StringUtils.equals(uri, namespaceURI)) {
+                            // System.out.println("namespace is declared");
+                            // prefix is declared correctly, do nothing
+                        } else if (uri != null) {
+                            // System.out.println("prefix is declared with other namespace, overwriting it");
+                            // prefix exists but is bound to another namespace, overwrite it
+                            currentElementInfo.put(prefix, namespaceURI);
+                        } else {
+                            // System.out.println("prefix is not yet declared, declaring it now");
+                            currentElementInfo.put(prefix, namespaceURI);
+                        }
+                    } else {
+                        // element has no namespace
+                        // check if there is a default namespace, if so undeclare it
+                        String uri = currentElementInfo.findNamespaceURI("");
+                        if (StringUtils.isNotEmpty(uri)) {
+                            // System.out.println("undeclaring default namespace");
+                            currentElementInfo.put("", "");
+                        }
+                    }
+
+                    // SAX uses empty string to denote no namespace, while DOM uses null.
+                    if (namespaceURI == null)
+                        namespaceURI = "";
+
+                    String qName;
+                    if (StringUtils.isNotEmpty(prefix)) {
+                        qName = prefix + ":" + localName;
+                    } else {
+                        qName = localName;
+                    }
+
+                    // make the attributes
+                    AttributesImpl newAttrs = new AttributesImpl();
+                    for (int i = 0; i < nAttrs; i++) {
+                        Node attr = atts.item(i);
+                        String attrName = attr.getNodeName();
+                        String assignedAttrPrefix = null;
+
+                        // only do non-namespace attributes
+                        if (!(attrName.equals("xmlns") || attrName.startsWith("xmlns:"))) {
+                            String attrPrefix;
+                            String attrLocalName;
+                            String attrNsURI;
+
+                            if (attr.getLocalName() == null) {
+                                // this is an attribute created with setAttribute instead of setAttributeNS
+                                String[] prefixAndLocalName = getPrefixAndLocalName(attrName);
+                                attrPrefix = prefixAndLocalName[0];
+                                // the statement below causes the attribute to keep its prefix even if it is not
+                                // bound to a namespace (to support pre-namespace XML).
+                                assignedAttrPrefix = attrPrefix;
+                                attrLocalName = prefixAndLocalName[1];
+                                // note: if prefix is null, the attribute has no namespace (namespace defaulting
+                                // does not apply to attributes)
+                                if (attrPrefix != null)
+                                    attrNsURI = getNamespaceForPrefix(attrPrefix, (Element)node);
+                                else
+                                    attrNsURI = null;
+                            } else {
+                                attrLocalName = attr.getLocalName();
+                                attrPrefix = attr.getPrefix();
+                                attrNsURI = attr.getNamespaceURI();
+                            }
+
+                            if (attrNsURI != null) {
+                                String declaredUri = currentElementInfo.findNamespaceURI(attrPrefix);
+                                // if the prefix is null, or the prefix has not been declared, or conflicts with an in-scope binding
+                                if (declaredUri == null || !declaredUri.equals(attrNsURI)) {
+                                    String availablePrefix = currentElementInfo.findPrefix(attrNsURI);
+                                    if (availablePrefix != null && !availablePrefix.equals(""))
+                                        assignedAttrPrefix = availablePrefix;
+                                    else {
+                                        if (attrPrefix != null && declaredUri == null) {
+                                            // prefix is not null and is not yet declared: declare it
+                                            assignedAttrPrefix = attrPrefix;
+                                            currentElementInfo.put(assignedAttrPrefix, attrNsURI);
+                                        } else {
+                                            // attribute has no prefix (which is not allowed for namespaced attributes) or
+                                            // the prefix is already bound to something else: generate a new prefix
+                                            newPrefixCounter++;
+                                            assignedAttrPrefix = "NS" + newPrefixCounter;
+                                            currentElementInfo.put(assignedAttrPrefix, attrNsURI);
+                                        }
+                                    }
+                                } else {
+                                    assignedAttrPrefix = attrPrefix;
+                                }
+                            }
+
+                            String assignedAttrNsURI = attrNsURI != null ? attrNsURI : "";
+                            String attrQName;
+                            if (assignedAttrPrefix != null) {
+                                attrQName = assignedAttrPrefix + ":" + attrLocalName;
+                            } else {
+                                attrQName = attrLocalName;
+                            }
+                            newAttrs.addAttribute(assignedAttrNsURI, attrLocalName, attrQName, "CDATA", attr.getNodeValue());
+                        }
+                    }
+
+                    // add local namespace declaration and fire startPrefixMapping events
+                    if (currentElementInfo.namespaceDeclarations != null && currentElementInfo.namespaceDeclarations.size() > 0) {
+                        Iterator localNsDeclIt = currentElementInfo.namespaceDeclarations.entrySet().iterator();
+                        while (localNsDeclIt.hasNext()) {
+                            Map.Entry entry = (Map.Entry) localNsDeclIt.next();
+                            String pr = (String) entry.getKey();
+                            String ns = (String) entry.getValue();
+                            // the following lines enable the creation of explicit xmlns attributes
+                            //String pr1 = pr.equals("") ? "xmlns" : pr;
+                            //String qn = pr.equals("") ? "xmlns" : "xmlns:" + pr;
+                            //newAttrs.addAttribute("", pr1, qn, "CDATA", ns);
+                            // System.out.println("starting prefix mapping  for prefix " + pr + " for " + ns);
+                            contentHandler.startPrefixMapping(pr, ns);
+                        }
+                    }
+
+                    contentHandler.startElement(namespaceURI, localName, qName, newAttrs);
+
+                    currentElementInfo.localName = localName;
+                    currentElementInfo.namespaceURI = namespaceURI;
+                    currentElementInfo.qName = qName;
+                    break;
+                case Node.PROCESSING_INSTRUCTION_NODE:
+                    {
+                        ProcessingInstruction pi = (ProcessingInstruction) node;
+                        contentHandler.processingInstruction(pi.getNodeName(), pi.getData());
+                    }
+                    break;
+                case Node.CDATA_SECTION_NODE:
+                    {
+                        if (lexicalHandler != null)
+                            lexicalHandler.startCDATA();
+
+                        dispatchChars(node);
+
+                        if (lexicalHandler != null)
+                            lexicalHandler.endCDATA();
+                    }
+                    break;
+                case Node.TEXT_NODE:
+                    {
+                        dispatchChars(node);
+                    }
+                    break;
+                case Node.ENTITY_REFERENCE_NODE:
+                    {
+                        EntityReference eref = (EntityReference) node;
+
+                        if (lexicalHandler != null) {
+                            lexicalHandler.startEntity(eref.getNodeName());
+                        } else {
+                            // warning("Can not output entity to a pure SAX ContentHandler");
+                        }
+                    }
+                    break;
+                default :
+            }
+        }
+
+        /**
+         * Searches the namespace for a given namespace prefix starting from a
+         * given Element.
+         *
+         * <p>Note that this resolves the prefix in the orginal DOM-tree, not in
+         * the {@link ElementInfo} objects. This is used to resolve prefixes
+         * of elements or attributes created with createElement or setAttribute
+         * instead of createElementNS or setAttributeNS.
+         *
+         * <p>The code in this method is largely based on
+         * org.apache.xml.utils.DOMHelper.getNamespaceForPrefix() (from Xalan).
+         *
+         * @param prefix the prefix to look for, can be empty or null to find the
+         * default namespace
+         *
+         * @return the namespace, or null if not found.
+         */
+        public String getNamespaceForPrefix(String prefix, Element namespaceContext) {
+            int type;
+            Node parent = namespaceContext;
+            String namespace = null;
+
+            if (prefix == null)
+                prefix = "";
+
+            if (prefix.equals("xml")) {
+                namespace = "http://www.w3.org/XML/1998/namespace";
+            } else if(prefix.equals("xmlns")) {
+                namespace = "http://www.w3.org/2000/xmlns/";
+            } else {
+                // Attribute name for this prefix's declaration
+                String declname = (prefix.equals("")) ? "xmlns" : "xmlns:" + prefix;
+
+                // Scan until we run out of Elements or have resolved the namespace
+                while ((null != parent) && (null == namespace)
+                   && (((type = parent.getNodeType()) == Node.ELEMENT_NODE)
+                       || (type == Node.ENTITY_REFERENCE_NODE))) {
+                    if (type == Node.ELEMENT_NODE) {
+                        Attr attr=((Element)parent).getAttributeNode(declname);
+                        if (attr != null) {
+                            namespace = attr.getNodeValue();
+                            break;
+                        }
+                    }
+                    parent = parent.getParentNode();
+                }
+            }
+            return namespace;
+        }
+
+        /**
+         * Splits a nodeName into a prefix and a localName
+         *
+         * @return an array containing two elements, the first one is the prefix (can be null), the
+         * second one is the localName
+         */
+        private String[] getPrefixAndLocalName(String nodeName) {
+            String prefix, localName;
+            int colonPos = nodeName.indexOf(":");
+            if (colonPos != -1) {
+                prefix = nodeName.substring(0, colonPos);
+                localName = nodeName.substring(colonPos + 1, nodeName.length());
+            } else {
+                prefix = null;
+                localName = nodeName;
+            }
+            return new String[] {prefix, localName};
+        }
+
+
+        /**
+         * End processing of given node
+         *
+         * @param node Node we just finished processing
+         */
+        protected void endNode(Node node) throws org.xml.sax.SAXException {
+
+            switch (node.getNodeType()) {
+                case Node.DOCUMENT_NODE:
+                    break;
+
+                case Node.ELEMENT_NODE:
+                    contentHandler.endElement(currentElementInfo.namespaceURI,
+                            currentElementInfo.localName, currentElementInfo.qName);
+
+                    // generate endPrefixMapping events if needed
+                    if (currentElementInfo.namespaceDeclarations != null && currentElementInfo.namespaceDeclarations.size() > 0) {
+                        Iterator namespaceIt = currentElementInfo.namespaceDeclarations.entrySet().iterator();
+                        while (namespaceIt.hasNext()) {
+                            Map.Entry entry = (Map.Entry) namespaceIt.next();
+                            contentHandler.endPrefixMapping((String) entry.getKey());
+                            //System.out.println("ending prefix mapping " + (String) entry.getKey());
+                        }
+                    }
+
+                    currentElementInfo = currentElementInfo.parent;
+                    break;
+                case Node.CDATA_SECTION_NODE:
+                    break;
+                case Node.ENTITY_REFERENCE_NODE:
+                    {
+                        EntityReference eref = (EntityReference) node;
+
+                        if (lexicalHandler != null) {
+                            lexicalHandler.endEntity(eref.getNodeName());
+                        }
+                    }
+                    break;
+                default :
+            }
+        }
+
+        public static class ElementInfo {
+            public String localName;
+            public String namespaceURI;
+            public String qName;
+            public Map namespaceDeclarations = null;
+            public ElementInfo parent;
+
+            public ElementInfo(ElementInfo parent) {
+                this.parent = parent;
+            }
+
+            /**
+             * Declare a new namespace prefix on this element, possibly overriding
+             * an existing one.
+             */
+            public void put(String prefix, String namespaceURI) {
+                if (namespaceDeclarations == null)
+                    namespaceDeclarations = new HashMap();
+                namespaceDeclarations.put(prefix, namespaceURI);
+            }
+
+            /**
+             * Finds a prefix declared on this element.
+             */
+            public String getPrefix(String namespaceURI) {
+                if (namespaceDeclarations == null || namespaceDeclarations.size() == 0)
+                    return null;
+                // note: there could be more than one prefix for the same namespaceURI, but
+                // we return the first found one.
+                Iterator it = namespaceDeclarations.entrySet().iterator();
+                while (it.hasNext()) {
+                    Map.Entry entry = (Map.Entry) it.next();
+                    if (entry.getValue().equals(namespaceURI))
+                        return (String) entry.getKey();
+                }
+                return null;
+            }
+
+            /**
+             * Finds a namespace URI declared on this element.
+             */
+            public String getNamespaceURI(String prefix) {
+                if (namespaceDeclarations == null || namespaceDeclarations.size() == 0)
+                    return null;
+
+                return (String) namespaceDeclarations.get(prefix);
+            }
+
+            /**
+             * Finds a prefix declaration on this element or containing elements.
+             */
+            public String findPrefix(String namespaceURI) {
+                if (namespaceDeclarations != null && namespaceDeclarations.size() != 0) {
+                    String prefix = getPrefix(namespaceURI);
+                    if (prefix != null) {
+                        return prefix;
+                    }
+                }
+                if (parent != null) {
+                    return parent.findPrefix(namespaceURI);
+                }
+                return null;
+            }
+
+            /**
+             * Finds a namespace declaration on this element or containing elements.
+             */
+            public String findNamespaceURI(String prefix) {
+                if (namespaceDeclarations != null && namespaceDeclarations.size() != 0) {
+                    String uri = (String) namespaceDeclarations.get(prefix);
+                    if (uri != null) {
+                        return uri;
+                    }
+                }
+                if (parent != null) {
+                    return parent.findNamespaceURI(prefix);
+                }
+                return null;
+            }
+        }
+    }
+
+    /**
+     * The <code>DefaultDOMStreamer</code> is a utility class that will generate SAX
+     * events from a W3C DOM Document.
+     */
+    public static class DefaultDOMStreamer extends AbstractXMLProducer {
+
+        /** The private transformer for this instance */
+        protected Transformer transformer;
+
+        /**
+         * Start the production of SAX events.
+         */
+        public void stream(Node node)
+        throws SAXException {
+            if (this.transformer == null) {
+                try {
+                    this.transformer = FACTORY.newTransformer();
+                } catch (TransformerConfigurationException e) {
+                    throw new SAXException(e);
+                }
+            }
+            DOMSource source = new DOMSource(node);
+
+            ContentHandler handler;
+            if (node.getNodeType() == Node.DOCUMENT_NODE) {
+                // Pass all SAX events
+                handler = contentHandler;
+            } else {
+                // Strip start/endDocument
+                handler = new EmbeddedXMLPipe(contentHandler);
+            }
+
+            SAXResult result = new SAXResult(handler);
+            result.setLexicalHandler(lexicalHandler);
+
+            try {
+                transformer.transform(source, result);
+            } catch (TransformerException e) {
+                throw new SAXException(e);
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMUtil.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMUtil.java
new file mode 100644
index 0000000..69ca2ac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DOMUtil.java
@@ -0,0 +1,1138 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml.dom;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.excalibur.source.SourceParameters;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.excalibur.xml.xpath.NodeListImpl;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.apache.excalibur.xml.xpath.XPathUtil;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ *  This class is a utility class for miscellaneous DOM functions, like
+ *  getting and setting values of nodes.
+ *
+ * @version $Id$
+ */
+public final class DOMUtil {
+
+    /**
+     * Get the owner of the DOM document belonging to the node.
+     * This works even if the node is the document itself.
+     *
+     * @param node The node.
+     * @return     The corresponding document.
+     */
+    public static Document getOwnerDocument(Node node) {
+        if (node.getNodeType() == Node.DOCUMENT_NODE) {
+            return (Document) node;
+        } else {
+            return node.getOwnerDocument();
+        }
+    }
+
+    /**
+     * Get the value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node does not exist <CODE>null</CODE>
+     * is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @return     The value of the node or <CODE>null</CODE>
+     */
+    public static String getValueOfNode(XPathProcessor processor, Node root, String path)
+        throws ProcessingException {
+        if (path == null) {
+            throw new ProcessingException("Not a valid XPath: " + path);
+        }
+        if (root != null) {
+            path = StringUtils.strip(path, "/");
+            Node node = XPathUtil.searchSingleNode(processor, root, path);
+            if (node != null) {
+                return getValueOfNode(node);
+            }
+        }
+       return null;
+    }
+
+    /**
+     * Get the value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node is not found
+     * the <CODE>defaultValue</CODE> is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param defaultValue The default value if the node does not exist.
+     * @return     The value of the node or <CODE>defaultValue</CODE>
+     */
+    public static String getValueOfNode(
+        XPathProcessor processor,
+        Node root,
+        String path,
+        String defaultValue)
+        throws ProcessingException {
+        String value = getValueOfNode(processor, root, path);
+        if (value == null)
+            value = defaultValue;
+
+        return value;
+    }
+
+    /**
+     * Get the boolean value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node exists and has a value
+     * this value is converted to a boolean, e.g. "true" or "false" as value
+     * will result into the corresponding boolean values.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @return     The boolean value of the node.
+     * @throws ProcessingException If the node is not found.
+     */
+    public static boolean getValueOfNodeAsBoolean(XPathProcessor processor, Node root, String path)
+        throws ProcessingException {
+        String value = getValueOfNode(processor, root, path);
+        if (value == null) {
+            throw new ProcessingException("No such node: " + path);
+        }
+        return Boolean.valueOf(value).booleanValue();
+    }
+
+    /**
+     * Get the boolean value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node exists and has a value
+     * this value is converted to a boolean, e.g. "true" or "false" as value
+     * will result into the corresponding boolean values.
+     * If the node does not exist, the <CODE>defaultValue</CODE> is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param defaultValue Default boolean value.
+     * @return     The value of the node or <CODE>defaultValue</CODE>
+     */
+    public static boolean getValueOfNodeAsBoolean(XPathProcessor processor,
+                                                  Node root,
+                                                  String path,
+                                                  boolean defaultValue)
+    throws ProcessingException {
+        String value = getValueOfNode(processor, root, path);
+        if (value != null) {
+            return BooleanUtils.toBoolean(value);
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Get the value of the DOM node.
+     * The value of a node is the content of the first text node.
+     * If the node has no text nodes, <code>null</code> is returned.
+     */
+    public static String getValueOfNode(Node node) {
+        if (node != null) {
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                return node.getNodeValue();
+            } else {
+                node.normalize();
+                NodeList childs = node.getChildNodes();
+                int i = 0;
+                int length = childs.getLength();
+                while (i < length) {
+                    if (childs.item(i).getNodeType() == Node.TEXT_NODE) {
+                        return childs.item(i).getNodeValue().trim();
+                    } else {
+                        i++;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the node.
+     * The value of the node is the content of the first text node.
+     * If the node has no text nodes the <CODE>defaultValue</CODE> is
+     * returned.
+     */
+    public static String getValueOfNode(Node node, String defaultValue) {
+        return StringUtils.defaultString(getValueOfNode(node), defaultValue);
+    }
+
+    /**
+     * Set the value of the DOM node.
+     * All current children of the node are removed and a new text node
+     * with the value is appended.
+     */
+    public static void setValueOfNode(Node node, String value) {
+        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+            node.setNodeValue(value);
+        } else {
+            while (node.hasChildNodes() == true) {
+                node.removeChild(node.getFirstChild());
+            }
+            node.appendChild(node.getOwnerDocument().createTextNode(value));
+        }
+    }
+
+    /** XML definition for a document */
+    private static final String XML_DEFINITION = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
+    private static final String XML_ROOT_DEFINITION = XML_DEFINITION + "<root>";
+
+    /**
+     * Get a document fragment from a <code>Reader</code>.
+     * The reader must provide valid XML, but it is allowed that the XML
+     * has more than one root node. This xml is parsed by the
+     * specified parser instance and a DOM DocumentFragment is created.
+     */
+    public static DocumentFragment getDocumentFragment(SAXParser parser, Reader stream)
+        throws ProcessingException {
+        DocumentFragment frag = null;
+
+        Writer writer;
+        Reader reader;
+        boolean removeRoot = true;
+
+        try {
+            // create a writer,
+            // write the root element, then the input from the
+            // reader
+            writer = new StringWriter();
+
+            writer.write(XML_ROOT_DEFINITION);
+            char[] cbuf = new char[16384];
+            int len;
+            do {
+                len = stream.read(cbuf, 0, 16384);
+                if (len != -1) {
+                    writer.write(cbuf, 0, len);
+                }
+            } while (len != -1);
+            writer.write("</root>");
+
+            // now test if xml input start with <?xml
+            String xml = writer.toString();
+            String searchString = XML_ROOT_DEFINITION + "<?xml ";
+            if (xml.startsWith(searchString) == true) {
+                // now remove the surrounding root element
+                xml = xml.substring(XML_ROOT_DEFINITION.length(), xml.length() - 7);
+                removeRoot = false;
+            }
+
+            reader = new StringReader(xml);
+
+            InputSource input = new InputSource(reader);
+
+            DOMBuilder builder = new DOMBuilder();
+            builder.startDocument();
+            builder.startElement("", "root", "root", XMLUtils.EMPTY_ATTRIBUTES);
+
+            IncludeXMLConsumer filter = new IncludeXMLConsumer(builder, builder);
+            parser.parse(input, filter);
+
+            builder.endElement("", "root", "root");
+            builder.endDocument();
+
+            // Create Document Fragment, remove <root>
+            final Document doc = builder.getDocument();
+            frag = doc.createDocumentFragment();
+            final Node root = doc.getDocumentElement().getFirstChild();
+            root.normalize();
+            if (removeRoot == false) {
+                root.getParentNode().removeChild(root);
+                frag.appendChild(root);
+            } else {
+                Node child;
+                while (root.hasChildNodes() == true) {
+                    child = root.getFirstChild();
+                    root.removeChild(child);
+                    frag.appendChild(child);
+                }
+            }
+        } catch (SAXException sax) {
+            throw new ProcessingException("SAXException: " + sax, sax);
+        } catch (IOException ioe) {
+            throw new ProcessingException("IOException: " + ioe, ioe);
+        }
+        return frag;
+    }
+
+    /**
+     * Create a parameter object from xml.
+     * The xml is flat and consists of elements which all have exactly one text node:
+     * <parone>value_one<parone>
+     * <partwo>value_two<partwo>
+     * A parameter can occur more than once with different values.
+     * If <CODE>source</CODE> is not specified a new paramter object is created
+     * otherwise the parameters are added to source.
+     */
+    public static SourceParameters createParameters(Node fragment, SourceParameters source) {
+        SourceParameters par = (source == null ? new SourceParameters() : source);
+        if (fragment != null) {
+            NodeList childs = fragment.getChildNodes();
+            if (childs != null) {
+                Node current;
+                for (int i = 0; i < childs.getLength(); i++) {
+                    current = childs.item(i);
+
+                    // only element nodes
+                    if (current.getNodeType() == Node.ELEMENT_NODE) {
+                        current.normalize();
+                        NodeList valueChilds = current.getChildNodes();
+                        String key;
+                        StringBuffer valueBuffer;
+                        String value;
+
+                        key = current.getNodeName();
+                        valueBuffer = new StringBuffer();
+                        for (int m = 0; m < valueChilds.getLength(); m++) {
+                            current = valueChilds.item(m); // attention: current is reused here!
+                            if (current.getNodeType() == Node.TEXT_NODE) { // only text nodes
+                                if (valueBuffer.length() > 0)
+                                    valueBuffer.append(' ');
+                                valueBuffer.append(current.getNodeValue());
+                            }
+                        }
+                        value = valueBuffer.toString().trim();
+                        if (key != null && value != null && value.length() > 0) {
+                            par.setParameter(key, value);
+                        }
+                    }
+                }
+            }
+        }
+        return par;
+    }
+
+    /**
+     * Create a string from a DOM document fragment.
+     * Only the top level text nodes are chained together to build the text.
+     */
+    public static String createText(DocumentFragment fragment) {
+        StringBuffer value = new StringBuffer();
+        if (fragment != null) {
+            NodeList childs = fragment.getChildNodes();
+            if (childs != null) {
+                Node current;
+
+                for (int i = 0; i < childs.getLength(); i++) {
+                    current = childs.item(i);
+
+                    // only text nodes
+                    if (current.getNodeType() == Node.TEXT_NODE) {
+                        if (value.length() > 0)
+                            value.append(' ');
+                        value.append(current.getNodeValue());
+                    }
+                }
+            }
+        }
+        return value.toString().trim();
+    }
+
+    /**
+     * Compare all attributes of two elements.
+     * This method returns true only if both nodes have the same number of
+     * attributes and the same attributes with equal values.
+     * Namespace definition nodes are ignored
+     */
+    public static boolean compareAttributes(Element first, Element second) {
+        NamedNodeMap attr1 = first.getAttributes();
+        NamedNodeMap attr2 = second.getAttributes();
+        String value;
+
+        if (attr1 == null && attr2 == null)
+            return true;
+        int attr1Len = (attr1 == null ? 0 : attr1.getLength());
+        int attr2Len = (attr2 == null ? 0 : attr2.getLength());
+        if (attr1Len > 0) {
+            int l = attr1.getLength();
+            for (int i = 0; i < l; i++) {
+                if (attr1.item(i).getNodeName().startsWith("xmlns:") == true)
+                    attr1Len--;
+            }
+        }
+        if (attr2Len > 0) {
+            int l = attr2.getLength();
+            for (int i = 0; i < l; i++) {
+                if (attr2.item(i).getNodeName().startsWith("xmlns:") == true)
+                    attr2Len--;
+            }
+        }
+        if (attr1Len != attr2Len)
+            return false;
+        int i, l;
+        int m, l2;
+        i = 0;
+        l = attr1.getLength();
+        l2 = attr2.getLength();
+        boolean ok = true;
+        // each attribute of first must be in second with the same value
+        while (i < l && ok == true) {
+            value = attr1.item(i).getNodeName();
+            if (value.startsWith("xmlns:") == false) {
+                ok = false;
+                m = 0;
+                while (m < l2 && ok == false) {
+                    if (attr2.item(m).getNodeName().equals(value) == true) {
+                        // same name, same value?
+                        ok = attr1.item(i).getNodeValue().equals(attr2.item(m).getNodeValue());
+                    }
+                    m++;
+                }
+            }
+
+            i++;
+        }
+        return ok;
+    }
+
+    /**
+     * Implementation for <code>String</code> :
+     * outputs characters representing the value.
+     *
+     * @param parent The node getting the value
+     * @param text   the value
+     */
+    public static void valueOf(Node parent, String text) throws ProcessingException {
+        if (text != null) {
+            parent.appendChild(parent.getOwnerDocument().createTextNode(text));
+        }
+    }
+
+    /**
+     * Implementation for <code>XMLizable</code> :
+     * outputs the value by calling <code>v.toSax(contentHandler)</code>.
+     *
+     * @param parent The node getting the value
+     * @param v the XML fragment
+     */
+    public static void valueOf(Node parent, XMLizable v) throws ProcessingException {
+        if (v != null) {
+            DOMBuilder builder = new DOMBuilder(parent);
+            try {
+                v.toSAX(builder);
+            } catch (SAXException e) {
+                throw new ProcessingException(e);
+            }
+        }
+    }
+
+    /**
+     * Implementation for <code>org.w3c.dom.Node</code> :
+     * converts the Node to a SAX event stream.
+     *
+     * @param parent The node getting the value
+     * @param v the value
+     */
+    public static void valueOf(Node parent, Node v) throws ProcessingException {
+        if (v != null) {
+            parent.appendChild(parent.getOwnerDocument().importNode(v, true));
+        }
+    }
+
+    /**
+     * Implementation for <code>java.util.Collection</code> :
+     * outputs the value by calling {@link #valueOf(Node, Object)} on each element of the
+     * collection.
+     *
+     * @param parent The node getting the value
+     * @param v the XML fragment
+     */
+    public static void valueOf(Node parent, Collection v) throws ProcessingException {
+        if (v != null) {
+            Iterator iterator = v.iterator();
+            while (iterator.hasNext()) {
+                valueOf(parent, iterator.next());
+            }
+        }
+    }
+
+    /**
+     * Implementation for <code>java.util.Map</code> :
+     * For each entry an element is created with the childs key and value
+     * Outputs the value and the key by calling {@link #valueOf(Node, Object)}
+     * on each value and key of the Map.
+     *
+     * @param parent The node getting the value
+     * @param v      the Map
+     */
+    public static void valueOf(Node parent, Map v) throws ProcessingException {
+        if (v != null) {
+            Node mapNode = parent.getOwnerDocument().createElementNS(null, "java.util.map");
+            parent.appendChild(mapNode);
+            for (Iterator iter = v.entrySet().iterator(); iter.hasNext();) {
+                final Map.Entry me = (Map.Entry) iter.next();
+
+                Node entryNode = mapNode.getOwnerDocument().createElementNS(null, "entry");
+                mapNode.appendChild(entryNode);
+
+                Node keyNode = entryNode.getOwnerDocument().createElementNS(null, "key");
+                entryNode.appendChild(keyNode);
+                valueOf(keyNode, me.getKey());
+
+                Node valueNode = entryNode.getOwnerDocument().createElementNS(null, "value");
+                entryNode.appendChild(valueNode);
+                valueOf(valueNode, me.getValue());
+            }
+        }
+    }
+
+    /**
+     * Implementation for <code>Object</code> depending on its class :
+     * <ul>
+     * <li>if it's an array, call {@link #valueOf(Node, Object)} on all its elements,</li>
+     * <li>if it's class has a specific {@link #valueOf(Node, Object)} implementation, use it,</li>
+     * <li>else, output it's string representation.</li>
+     * </ul>
+     *
+     * @param parent The node getting the value
+     * @param v the value
+     */
+    public static void valueOf(Node parent, Object v) throws ProcessingException {
+        if (v == null) {
+            return;
+        }
+
+        // Array: recurse over each element
+        if (v.getClass().isArray()) {
+            Object[] elements = (Object[]) v;
+
+            for (int i = 0; i < elements.length; i++) {
+                valueOf(parent, elements[i]);
+            }
+            return;
+        }
+
+        // Check handled object types in case they were not typed in the XSP
+
+        // XMLizable
+        if (v instanceof XMLizable) {
+            valueOf(parent, (XMLizable) v);
+            return;
+        }
+
+        // Node
+        if (v instanceof Node) {
+            valueOf(parent, (Node) v);
+            return;
+        }
+
+        // Collection
+        if (v instanceof Collection) {
+            valueOf(parent, (Collection) v);
+            return;
+        }
+
+        // Map
+        if (v instanceof Map) {
+            valueOf(parent, (Map) v);
+            return;
+        }
+
+        // Give up: hope it's a string or has a meaningful string representation
+        valueOf(parent, String.valueOf(v));
+    }
+
+    /**
+     * Use an XPath string to select a single node. XPath namespace
+     * prefixes are resolved from the context node, which may not
+     * be what you want (see the next method).
+     *
+     * @param contextNode The node to start searching from.
+     * @param str A valid XPath string.
+     * @param processor The XPath processor to use
+     * @return The first node found that matches the XPath, or null.
+     *
+     * @throws TransformerException
+     */
+    public static Node getSingleNode(Node contextNode, String str,
+                                     XPathProcessor processor)
+    throws TransformerException {
+        String[] pathComponents = buildPathArray(str);
+        if (pathComponents == null) {
+            return processor.selectSingleNode(contextNode, str);
+        } else {
+            return getFirstNodeFromPath(contextNode, pathComponents, false);
+        }
+    }
+
+    /**
+     * Return the <CODE>Node</CODE> from the DOM Node <CODE>rootNode</CODE>
+     * using the XPath expression <CODE>path</CODE>.
+     * If the node does not exist, it is created and then returned.
+     * This is a very simple method for creating new nodes. If the
+     * XPath contains selectors ([,,,]) or "*" it is of course not
+     * possible to create the new node. So if you use such XPaths
+     * the node must exist beforehand.
+     * An simple exception is if the expression contains attribute
+     * test to values (e.g. [@id = 'du' and @number = 'you'],
+     * the attributes with the given values are added. The attributes
+     * must be separated with 'and'.
+     * Another problem are namespaces: XPath requires sometimes selectors for
+     * namespaces, e.g. : /*[namespace-uri()="uri" and local-name()="name"]
+     * Creating such a node with a namespace is not possible right now as we use
+     * a very simple XPath parser which is not able to parse all kinds of selectors
+     * correctly.
+     *
+     * @param rootNode  The node to start the search.
+     * @param path      XPath expression for searching the node.
+     * @param processor The XPath processor to use
+     * @return          The node specified by the path.
+     * @throws ProcessingException If no path is specified or the XPath engine fails.
+     */
+    public static Node selectSingleNode(Node rootNode, String path, XPathProcessor processor)
+    throws ProcessingException {
+        // Now we have to parse the string
+        // First test:  path? rootNode?
+        if (path == null) {
+            throw new ProcessingException("XPath is required.");
+        }
+        if (rootNode == null)
+            return rootNode;
+
+        if (path.length() == 0 || path.equals("/") == true)
+            return rootNode;
+
+        // now the first "quick" test is if the node exists using the
+        // full XPathAPI
+        try {
+            Node testNode = getSingleNode(rootNode, path, processor);
+            if (testNode != null)
+                return testNode;
+        } catch (javax.xml.transform.TransformerException local) {
+            throw new ProcessingException(
+                "Transforming exception during selectSingleNode with path: '"
+                    + path
+                    + "'. Exception: "
+                    + local,
+                local);
+        }
+
+        // remove leading "/" oon both ends
+        path = StringUtils.strip(path, "/");
+
+        // now step through the nodes!
+        Node parent = rootNode;
+        int pos;
+        int posSelector;
+        do {
+            pos = path.indexOf("/"); // get next separator
+            posSelector = path.indexOf("[");
+            if (posSelector != -1 && posSelector < pos) {
+                posSelector = path.indexOf("]");
+                pos = path.indexOf("/", posSelector);
+            }
+
+            String nodeName;
+            boolean isAttribute = false;
+            if (pos != -1) { // found separator
+                nodeName = path.substring(0, pos); // string until "/"
+                path = path.substring(pos + 1); // rest of string after "/"
+            } else {
+                nodeName = path;
+            }
+
+            // test for attribute spec
+            if (nodeName.startsWith("@") == true) {
+                isAttribute = true;
+            }
+
+            Node singleNode;
+            try {
+                singleNode = getSingleNode(parent, nodeName, processor);
+            } catch (javax.xml.transform.TransformerException localException) {
+                throw new ProcessingException(
+                    "XPathUtil.selectSingleNode: " + localException.getMessage(),
+                    localException);
+            }
+
+            // create node if necessary
+            if (singleNode == null) {
+                Node newNode;
+                // delete XPath selectors
+                int posSelect = nodeName.indexOf("[");
+                String XPathExp = null;
+                if (posSelect != -1) {
+                    XPathExp = nodeName.substring(posSelect + 1, nodeName.length() - 1);
+                    nodeName = nodeName.substring(0, posSelect);
+                }
+                if (isAttribute == true) {
+                    try {
+                        newNode =
+                            getOwnerDocument(rootNode).createAttributeNS(
+                                null,
+                                nodeName.substring(1));
+                        ((Element) parent).setAttributeNodeNS((org.w3c.dom.Attr) newNode);
+                        parent = newNode;
+                    } catch (DOMException local) {
+                        throw new ProcessingException(
+                            "Unable to create new DOM node: '" + nodeName + "'.",
+                            local);
+                    }
+                } else {
+                    try {
+                        newNode = getOwnerDocument(rootNode).createElementNS(null, nodeName);
+                    } catch (DOMException local) {
+                        throw new ProcessingException(
+                            "Unable to create new DOM node: '" + nodeName + "'.",
+                            local);
+                    }
+                    if (XPathExp != null) {
+                        java.util.List attrValuePairs = new java.util.ArrayList(4);
+                        boolean noError = true;
+
+                        String attr;
+                        String value;
+                        // scan for attributes
+                        java.util.StringTokenizer tokenizer =
+                            new java.util.StringTokenizer(XPathExp, "= ");
+                        while (tokenizer.hasMoreTokens() == true) {
+                            attr = tokenizer.nextToken();
+                            if (attr.startsWith("@") == true) {
+                                if (tokenizer.hasMoreTokens() == true) {
+                                    value = tokenizer.nextToken();
+                                    if (value.startsWith("'") && value.endsWith("'"))
+                                        value = value.substring(1, value.length() - 1);
+                                    if (value.startsWith("\"") && value.endsWith("\""))
+                                        value = value.substring(1, value.length() - 1);
+                                    attrValuePairs.add(attr.substring(1));
+                                    attrValuePairs.add(value);
+                                } else {
+                                    noError = false;
+                                }
+                            } else if (attr.trim().equals("and") == false) {
+                                noError = false;
+                            }
+                        }
+                        if (noError == true) {
+                            for (int l = 0; l < attrValuePairs.size(); l = l + 2) {
+                                ((Element) newNode).setAttributeNS(
+                                    null,
+                                    (String) attrValuePairs.get(l),
+                                    (String) attrValuePairs.get(l + 1));
+                            }
+                        }
+                    }
+                    parent.appendChild(newNode);
+                    parent = newNode;
+                }
+            } else {
+                parent = singleNode;
+            }
+        }
+        while (pos != -1);
+        return parent;
+    }
+
+    /**
+     * Get the value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node does not exist <CODE>null</CODE>
+     * is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param processor The XPath processor to use
+     * @return     The value of the node or <CODE>null</CODE>
+     */
+    public static String getValueOf(Node root, String path,
+                                    XPathProcessor processor) throws ProcessingException {
+        if (path == null) {
+            throw new ProcessingException("Not a valid XPath: " + path);
+        }
+        if (root == null)
+            return null;
+        path = StringUtils.strip(path, "/");
+
+        try {
+            Node node = getSingleNode(root, path, processor);
+            if (node != null) {
+                return getValueOfNode(node);
+            }
+        } catch (javax.xml.transform.TransformerException localException) {
+            throw new ProcessingException(
+                "XPathUtil.selectSingleNode: " + localException.getMessage(),
+                localException);
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node is not found
+     * the <CODE>defaultValue</CODE> is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param defaultValue The default value if the node does not exist.
+     * @param processor The XPath Processor
+     * @return     The value of the node or <CODE>defaultValue</CODE>
+     */
+    public static String getValueOf(Node root, String path, String defaultValue,
+                                    XPathProcessor processor)
+    throws ProcessingException {
+        String value = getValueOf(root, path, processor);
+        if (value == null) {
+            value = defaultValue;
+        }
+        return value;
+    }
+
+    /**
+     * Get the boolean value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node exists and has a value
+     * this value is converted to a boolean, e.g. "true" or "false" as value
+     * will result into the corresponding boolean values.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param processor The XPath Processor
+     * @return     The boolean value of the node.
+     * @throws ProcessingException If the node is not found.
+     */
+    public static boolean getValueAsBooleanOf(Node root, String path,
+                                              XPathProcessor processor)
+    throws ProcessingException {
+        String value = getValueOf(root, path, processor);
+        if (value == null) {
+            throw new ProcessingException("No such node: " + path);
+        }
+        return Boolean.valueOf(value).booleanValue();
+    }
+
+    /**
+     * Get the boolean value of the node specified by the XPath.
+     * This works similar to xsl:value-of. If the node exists and has a value
+     * this value is converted to a boolean, e.g. "true" or "false" as value
+     * will result into the corresponding boolean values.
+     * If the node does not exist, the <CODE>defaultValue</CODE> is returned.
+     *
+     * @param root The node to start the search.
+     * @param path XPath search expression.
+     * @param defaultValue Default boolean value.
+     * @param processor The XPath Processor
+     * @return     The value of the node or <CODE>defaultValue</CODE>
+     */
+    public static boolean getValueAsBooleanOf(Node root, String path, boolean defaultValue,
+                                              XPathProcessor processor)
+    throws ProcessingException {
+        String value = getValueOf(root, path, processor);
+        if (value != null) {
+            return Boolean.valueOf(value).booleanValue();
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Create a new empty DOM document.
+     */
+    public static Document createDocument() throws ProcessingException {
+        try {
+            DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
+            documentFactory.setNamespaceAware(true);
+            documentFactory.setValidating(false);
+            DocumentBuilder docBuilder = documentFactory.newDocumentBuilder();
+            return docBuilder.newDocument();
+        } catch (ParserConfigurationException pce) {
+            throw new ProcessingException("Creating document failed.", pce);
+        }
+    }
+
+    /**
+     *  Use an XPath string to select a nodelist.
+     *  XPath namespace prefixes are resolved from the contextNode.
+     *
+     *  @param contextNode The node to start searching from.
+     *  @param str A valid XPath string.
+     *  @param processor The XPath Processor
+     *  @return A NodeIterator, should never be null.
+     *
+     * @throws TransformerException
+     */
+    public static NodeList selectNodeList(Node contextNode, String str, XPathProcessor processor)
+    throws TransformerException {
+        String[] pathComponents = buildPathArray(str);
+        if (pathComponents != null) {
+            return getNodeListFromPath(contextNode, pathComponents);
+        }
+       return processor.selectNodeList(contextNode, str);
+    }
+
+    /**
+     * Build the input for the get...FromPath methods. If the XPath
+     * expression cannot be handled by the methods, <code>null</code>
+     * is returned.
+     */
+    public static String[] buildPathArray(String xpath) {
+        String[] result = null;
+        if (xpath != null && xpath.charAt(0) != '/') {
+            // test
+            int components = 1;
+            int i, l;
+            l = xpath.length();
+            boolean found = false;
+            i = 0;
+            while (i < l && found == false) {
+                switch (xpath.charAt(i)) {
+                    case '[' :
+                        found = true;
+                        break;
+                    case '(' :
+                        found = true;
+                        break;
+                    case '*' :
+                        found = true;
+                        break;
+                    case '@' :
+                        found = true;
+                        break;
+                    case ':' :
+                        found = true;
+                        break;
+                    case '/' :
+                        components++;
+                    default :
+                        i++;
+                }
+            }
+            if (found == false) {
+                result = new String[components];
+                if (components == 1) {
+                    result[components - 1] = xpath;
+                } else {
+                    i = 0;
+                    int start = 0;
+                    components = 0;
+                    while (i < l) {
+                        if (xpath.charAt(i) == '/') {
+                            result[components] = xpath.substring(start, i);
+                            start = i + 1;
+                            components++;
+                        }
+                        i++;
+                    }
+                    result[components] = xpath.substring(start);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Use a path to select the first occurence of a node. The namespace
+     * of a node is ignored!
+     * @param contextNode The node starting the search.
+     * @param path        The path to search the node. The
+     *                    contextNode is searched for a child named path[0],
+     *                    this node is searched for a child named path[1]...
+     * @param create      If a child with the corresponding name is not found
+     *                    and create is set, this node will be created.
+    */
+    public static Node getFirstNodeFromPath(
+        Node contextNode,
+        final String[] path,
+        final boolean create) {
+        if (contextNode == null || path == null || path.length == 0)
+            return contextNode;
+        // first test if the node exists
+        Node item = getFirstNodeFromPath(contextNode, path, 0);
+        if (item == null && create == true) {
+            int i = 0;
+            NodeList childs;
+            boolean found;
+            int m, l;
+            while (contextNode != null && i < path.length) {
+                childs = contextNode.getChildNodes();
+                found = false;
+                if (childs != null) {
+                    m = 0;
+                    l = childs.getLength();
+                    while (found == false && m < l) {
+                        item = childs.item(m);
+                        if (item.getNodeType() == Node.ELEMENT_NODE
+                            && item.getLocalName().equals(path[i]) == true) {
+                            found = true;
+                            contextNode = item;
+                        }
+                        m++;
+                    }
+                }
+                if (found == false) {
+                    Element e = contextNode.getOwnerDocument().createElementNS(null, path[i]);
+                    contextNode.appendChild(e);
+                    contextNode = e;
+                }
+                i++;
+            }
+            item = contextNode;
+        }
+        return item;
+    }
+
+    /**
+     * Private helper method for getFirstNodeFromPath()
+     */
+    private static Node getFirstNodeFromPath(
+        final Node contextNode,
+        final String[] path,
+        final int startIndex) {
+        int i = 0;
+        NodeList childs;
+        boolean found;
+        int l;
+        Node item = null;
+
+        childs = contextNode.getChildNodes();
+        found = false;
+        if (childs != null) {
+            i = 0;
+            l = childs.getLength();
+            while (found == false && i < l) {
+                item = childs.item(i);
+                if (item.getNodeType() == Node.ELEMENT_NODE
+                    && path[startIndex].equals(
+                        item.getLocalName() != null ? item.getLocalName() : item.getNodeName())
+                        == true) {
+                    if (startIndex == path.length - 1) {
+                        found = true;
+                    } else {
+                        item = getFirstNodeFromPath(item, path, startIndex + 1);
+                        if (item != null)
+                            found = true;
+                    }
+                }
+                if (found == false) {
+                    i++;
+                }
+            }
+            if (found == false) {
+                item = null;
+            }
+        }
+        return item;
+    }
+
+    /**
+     * Use a path to select all occurences of a node. The namespace
+     * of a node is ignored!
+     * @param contextNode The node starting the search.
+     * @param path        The path to search the node. The
+     *                    contextNode is searched for a child named path[0],
+     *                    this node is searched for a child named path[1]...
+     */
+    public static NodeList getNodeListFromPath(Node contextNode, String[] path) {
+        if (contextNode == null)
+            return new NodeListImpl();
+        if (path == null || path.length == 0) {
+            return new NodeListImpl(new Node[] { contextNode });
+        }
+        NodeListImpl result = new NodeListImpl();
+        try {
+            getNodesFromPath(result, contextNode, path, 0);
+        } catch (NullPointerException npe) {
+            // this NPE is thrown because the parser is not configured
+            // to use DOM Level 2
+            throw new NullPointerException(
+                "XMLUtil.getNodeListFromPath() did catch a NullPointerException."
+                    + "This might be due to a missconfigured XML parser which does not use DOM Level 2."
+                    + "Make sure that you use the XML parser shipped with Cocoon.");
+        }
+        return result;
+    }
+
+    /**
+     * Helper method for getNodeListFromPath()
+     */
+    private static void getNodesFromPath(
+        final NodeListImpl result,
+        final Node contextNode,
+        final String[] path,
+        final int startIndex) {
+        final NodeList childs = contextNode.getChildNodes();
+        int m, l;
+        Node item;
+        if (startIndex == (path.length - 1)) {
+            if (childs != null) {
+                m = 0;
+                l = childs.getLength();
+                while (m < l) {
+                    item = childs.item(m);
+                    if (item.getNodeType() == Node.ELEMENT_NODE) {
+                        // Work around: org.apache.xerces.dom.ElementImpl doesn't handle getLocalName() correct
+                        if (path[startIndex]
+                            .equals(
+                                item.getLocalName() != null
+                                    ? item.getLocalName()
+                                    : item.getNodeName())
+                            == true) {
+                            result.addNode(item);
+                        }
+                    }
+                    m++;
+                }
+            }
+        } else {
+            if (childs != null) {
+                m = 0;
+                l = childs.getLength();
+                while (m < l) {
+                    item = childs.item(m);
+                    if (item.getNodeType() == Node.ELEMENT_NODE) {
+                        // Work around: org.apache.xerces.dom.ElementImpl doesn't handle getLocalName() correct
+                        if (path[startIndex]
+                            .equals(
+                                item.getLocalName() != null
+                                    ? item.getLocalName()
+                                    : item.getNodeName())
+                            == true) {
+                            getNodesFromPath(result, item, path, startIndex + 1);
+                        }
+                    }
+                    m++;
+                }
+            }
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DocumentWrapper.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DocumentWrapper.java
new file mode 100644
index 0000000..2fe24ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/dom/DocumentWrapper.java
@@ -0,0 +1,1084 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml.dom;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.apache.excalibur.xml.sax.XMLizable;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.w3c.dom.UserDataHandler;
+import org.xml.sax.SAXException;
+
+
+/**
+ *  Wraps an org.w3c.dom.Document and offers additional interfaces
+ *  like XMLizable and a toString() method.
+ *
+ * @version $Id$
+ */
+public class DocumentWrapper implements org.w3c.dom.Document, XMLizable {
+
+    protected final static String DOMLEVEL3_ERR_MSG = 
+        "This method was just added for providing future compatibility to JDK 1.5's DOM level 3 Document interface.";
+
+    protected final Document document;
+    
+    /** Creates a new instance of DocmentWrapper */
+    public DocumentWrapper(Document doc) {
+        this.document = doc;
+    }
+
+
+    /**
+     * Generates SAX events representing the object's state.<br/>
+     * <b>NOTE</b> : if the implementation can produce lexical events,
+     * care should be taken that <code>handler</code> can actually be
+     * a {@link org.apache.cocoon.xml.XMLConsumer} that accepts such
+     * events.
+     */
+    public void toSAX(org.xml.sax.ContentHandler handler) throws SAXException {
+
+        DOMStreamer ds = new DOMStreamer(handler);
+        ds.stream(this.document.getDocumentElement());
+    }
+
+
+    public String toString() {
+        try {
+            return XMLUtils.serializeNode(this.document);
+        } catch (ProcessingException e) {
+        }
+        return "";
+    }
+
+
+    /** Adds the node <code>newChild</code> to the end of the list of children
+     * of this node. If the <code>newChild</code> is already in the tree, it
+     * is first removed.
+     * @param newChild The node to add.If it is a
+     *   <code>DocumentFragment</code> object, the entire contents of the
+     *   document fragment are moved into the child list of this node
+     * @return The node added.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+     *   allow children of the type of the <code>newChild</code> node, or if
+     *   the node to append is one of this node's ancestors or this node
+     *   itself.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or
+     *   if the previous parent of the node being inserted is readonly.
+     *
+     */
+    public Node appendChild(Node newChild) throws DOMException {
+        return this.document.appendChild(newChild);
+    }
+
+    /** Returns a duplicate of this node, i.e., serves as a generic copy
+     * constructor for nodes. The duplicate node has no parent; (
+     * <code>parentNode</code> is <code>null</code>.).
+     * <br>Cloning an <code>Element</code> copies all attributes and their
+     * values, including those generated by the XML processor to represent
+     * defaulted attributes, but this method does not copy any text it
+     * contains unless it is a deep clone, since the text is contained in a
+     * child <code>Text</code> node. Cloning an <code>Attribute</code>
+     * directly, as opposed to be cloned as part of an <code>Element</code>
+     * cloning operation, returns a specified attribute (
+     * <code>specified</code> is <code>true</code>). Cloning any other type
+     * of node simply returns a copy of this node.
+     * <br>Note that cloning an immutable subtree results in a mutable copy,
+     * but the children of an <code>EntityReference</code> clone are readonly
+     * . In addition, clones of unspecified <code>Attr</code> nodes are
+     * specified. And, cloning <code>Document</code>,
+     * <code>DocumentType</code>, <code>Entity</code>, and
+     * <code>Notation</code> nodes is implementation dependent.
+     * @param deep If <code>true</code>, recursively clone the subtree under
+     *   the specified node; if <code>false</code>, clone only the node
+     *   itself (and its attributes, if it is an <code>Element</code>).
+     * @return The duplicate node.
+     *
+     */
+    public Node cloneNode(boolean deep) {
+        return this.document.cloneNode(deep);
+    }
+
+    /** Creates an <code>Attr</code> of the given name. Note that the
+     * <code>Attr</code> instance can then be set on an <code>Element</code>
+     * using the <code>setAttributeNode</code> method.
+     * <br>To create an attribute with a qualified name and namespace URI, use
+     * the <code>createAttributeNS</code> method.
+     * @param name The name of the attribute.
+     * @return A new <code>Attr</code> object with the <code>nodeName</code>
+     *   attribute set to <code>name</code>, and <code>localName</code>,
+     *   <code>prefix</code>, and <code>namespaceURI</code> set to
+     *   <code>null</code>. The value of the attribute is the empty string.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an
+     *   illegal character.
+     *
+     */
+    public Attr createAttribute(String name) throws DOMException {
+        return this.document.createAttribute(name);
+    }
+
+    /** Creates an attribute of the given qualified name and namespace URI.
+     * @param namespaceURI The namespace URI of the attribute to create.
+     * @param qualifiedName The qualified name of the attribute to
+     *   instantiate.
+     * @return A new <code>Attr</code> object with the following attributes:
+     * <table border='1'>
+     * <tr>
+     * <th>
+     *   Attribute</th>
+     * <th>Value</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>qualifiedName</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>Node.namespaceURI</code></td>
+     * <td valign='top' rowspan='1' colspan='1'><code>namespaceURI</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>Node.prefix</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>prefix, extracted from
+     *   <code>qualifiedName</code>, or <code>null</code> if there is no
+     *   prefix</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>local name, extracted from
+     *   <code>qualifiedName</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Attr.name</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>qualifiedName</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeValue</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>the empty
+     *   string</td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name
+     *   contains an illegal character, per the XML 1.0 specification .
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+     *   malformed per the Namespaces in XML specification, if the
+     *   <code>qualifiedName</code> has a prefix and the
+     *   <code>namespaceURI</code> is <code>null</code>, if the
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace", or if the
+     *   <code>qualifiedName</code>, or its prefix, is "xmlns" and the
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/2000/xmlns/".
+     *   <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not
+     *   support the <code>"XML"</code> feature, since namespaces were
+     *   defined by XML.
+     * @since DOM Level 2
+     *
+     */
+    public Attr createAttributeNS(String namespaceURI, String qualifiedName) throws DOMException {
+        return this.document.createAttributeNS(namespaceURI, qualifiedName);
+    }
+
+    /** Creates a <code>CDATASection</code> node whose value is the specified
+     * string.
+     * @param data The data for the <code>CDATASection</code> contents.
+     * @return The new <code>CDATASection</code> object.
+     * @exception DOMException
+     *   NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     *
+     */
+    public CDATASection createCDATASection(String data) throws DOMException {
+        return this.document.createCDATASection(data);
+    }
+
+    /** Creates a <code>Comment</code> node given the specified string.
+     * @param data The data for the node.
+     * @return The new <code>Comment</code> object.
+     *
+     */
+    public Comment createComment(String data) {
+        return this.document.createComment(data);
+    }
+
+    /** Creates an empty <code>DocumentFragment</code> object.
+     * @return A new <code>DocumentFragment</code>.
+     *
+     */
+    public DocumentFragment createDocumentFragment() {
+        return this.document.createDocumentFragment();
+    }
+
+    /** Creates an element of the type specified. Note that the instance
+     * returned implements the <code>Element</code> interface, so attributes
+     * can be specified directly on the returned object.
+     * <br>In addition, if there are known attributes with default values,
+     * <code>Attr</code> nodes representing them are automatically created
+     * and attached to the element.
+     * <br>To create an element with a qualified name and namespace URI, use
+     * the <code>createElementNS</code> method.
+     * @param tagName The name of the element type to instantiate. For XML,
+     *   this is case-sensitive. For HTML, the <code>tagName</code>
+     *   parameter may be provided in any case, but it must be mapped to the
+     *   canonical uppercase form by the DOM implementation.
+     * @return A new <code>Element</code> object with the
+     *   <code>nodeName</code> attribute set to <code>tagName</code>, and
+     *   <code>localName</code>, <code>prefix</code>, and
+     *   <code>namespaceURI</code> set to <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an
+     *   illegal character.
+     *
+     */
+    public Element createElement(String tagName) throws DOMException {
+        return this.document.createElement(tagName);
+    }
+    
+    /** Creates an element of the given qualified name and namespace URI.
+     * @param namespaceURI The namespace URI of the element to create.
+     * @param qualifiedName The qualified name of the element type to
+     *   instantiate.
+     * @return A new <code>Element</code> object with the following
+     *   attributes:
+     * <table border='1'>
+     * <tr>
+     * <th>Attribute</th>
+     * <th>Value</th>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>qualifiedName</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.namespaceURI</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>namespaceURI</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.prefix</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>prefix, extracted
+     *   from <code>qualifiedName</code>, or <code>null</code> if there is
+     *   no prefix</td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>local name, extracted from
+     *   <code>qualifiedName</code></td>
+     * </tr>
+     * <tr>
+     * <td valign='top' rowspan='1' colspan='1'><code>Element.tagName</code></td>
+     * <td valign='top' rowspan='1' colspan='1'>
+     *   <code>qualifiedName</code></td>
+     * </tr>
+     * </table>
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified qualified name
+     *   contains an illegal character, per the XML 1.0 specification .
+     *   <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is
+     *   malformed per the Namespaces in XML specification, if the
+     *   <code>qualifiedName</code> has a prefix and the
+     *   <code>namespaceURI</code> is <code>null</code>, or if the
+     *   <code>qualifiedName</code> has a prefix that is "xml" and the
+     *   <code>namespaceURI</code> is different from "
+     *   http://www.w3.org/XML/1998/namespace" .
+     *   <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not
+     *   support the <code>"XML"</code> feature, since namespaces were
+     *   defined by XML.
+     * @since DOM Level 2
+     *
+     */
+    public Element createElementNS(String namespaceURI, String qualifiedName) throws DOMException {
+        return this.document.createElementNS(namespaceURI, qualifiedName);
+    }
+
+    /** Creates an <code>EntityReference</code> object. In addition, if the
+     * referenced entity is known, the child list of the
+     * <code>EntityReference</code> node is made the same as that of the
+     * corresponding <code>Entity</code> node.If any descendant of the
+     * <code>Entity</code> node has an unbound namespace prefix, the
+     * corresponding descendant of the created <code>EntityReference</code>
+     * node is also unbound; (its <code>namespaceURI</code> is
+     * <code>null</code>). The DOM Level 2 does not support any mechanism to
+     * resolve namespace prefixes.
+     * @param name The name of the entity to reference.
+     * @return The new <code>EntityReference</code> object.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified name contains an
+     *   illegal character.
+     *   <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     *
+     */
+    public EntityReference createEntityReference(String name) throws DOMException {
+        return this.document.createEntityReference(name);
+    }
+
+    /** Creates a <code>ProcessingInstruction</code> node given the specified
+     * name and data strings.
+     * @param target The target part of the processing instruction.
+     * @param data The data for the node.
+     * @return The new <code>ProcessingInstruction</code> object.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified target contains an
+     *   illegal character.
+     *   <br>NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
+     *
+     */
+    public ProcessingInstruction createProcessingInstruction(String target, String data) throws DOMException {
+        return this.document.createProcessingInstruction(target, data);
+    }
+
+    /** Creates a <code>Text</code> node given the specified string.
+     * @param data The data for the node.
+     * @return The new <code>Text</code> object.
+     *
+     */
+    public Text createTextNode(String data) {
+        return this.document.createTextNode(data);
+    }
+
+    /** A <code>NamedNodeMap</code> containing the attributes of this node (if
+     * it is an <code>Element</code>) or <code>null</code> otherwise.
+     *
+     */
+    public NamedNodeMap getAttributes() {
+        return this.document.getAttributes();
+    }
+
+    /** A <code>NodeList</code> that contains all children of this node. If
+     * there are no children, this is a <code>NodeList</code> containing no
+     * nodes.
+     *
+     */
+    public NodeList getChildNodes() {
+        return this.document.getChildNodes();
+    }
+
+    /** The Document Type Declaration (see <code>DocumentType</code>)
+     * associated with this document. For HTML documents as well as XML
+     * documents without a document type declaration this returns
+     * <code>null</code>. The DOM Level 2 does not support editing the
+     * Document Type Declaration. <code>docType</code> cannot be altered in
+     * any way, including through the use of methods inherited from the
+     * <code>Node</code> interface, such as <code>insertNode</code> or
+     * <code>removeNode</code>.
+     *
+     */
+    public DocumentType getDoctype() {
+        return this.document.getDoctype();
+    }
+
+    /** This is a convenience attribute that allows direct access to the child
+     * node that is the root element of the document. For HTML documents,
+     * this is the element with the tagName "HTML".
+     *
+     */
+    public Element getDocumentElement() {
+        return this.document.getDocumentElement();
+    }
+
+    /** Returns the <code>Element</code> whose <code>ID</code> is given by
+     * <code>elementId</code>. If no such element exists, returns
+     * <code>null</code>. Behavior is not defined if more than one element
+     * has this <code>ID</code>. The DOM implementation must have
+     * information that says which attributes are of type ID. Attributes
+     * with the name "ID" are not of type ID unless so defined.
+     * Implementations that do not know whether attributes are of type ID or
+     * not are expected to return <code>null</code>.
+     * @param elementId The unique <code>id</code> value for an element.
+     * @return The matching element.
+     * @since DOM Level 2
+     *
+     */
+    public Element getElementById(String elementId) {
+        return this.document.getElementById(elementId);
+    }
+
+    /** Returns a <code>NodeList</code> of all the <code>Elements</code> with a
+     * given tag name in the order in which they are encountered in a
+     * preorder traversal of the <code>Document</code> tree.
+     * @param tagname The name of the tag to match on. The special value "*"
+     *   matches all tags.
+     * @return A new <code>NodeList</code> object containing all the matched
+     *   <code>Elements</code>.
+     *
+     */
+    public NodeList getElementsByTagName(String tagname) {
+        return this.document.getElementsByTagName(tagname);
+    }
+
+    /** Returns a <code>NodeList</code> of all the <code>Elements</code> with a
+     * given local name and namespace URI in the order in which they are
+     * encountered in a preorder traversal of the <code>Document</code> tree.
+     * @param namespaceURI The namespace URI of the elements to match on. The
+     *   special value "*" matches all namespaces.
+     * @param localName The local name of the elements to match on. The
+     *   special value "*" matches all local names.
+     * @return A new <code>NodeList</code> object containing all the matched
+     *   <code>Elements</code>.
+     * @since DOM Level 2
+     *
+     */
+    public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
+        return this.document.getElementsByTagNameNS(namespaceURI, localName);
+    }
+
+    /** The first child of this node. If there is no such node, this returns
+     * <code>null</code>.
+     *
+     */
+    public Node getFirstChild() {
+        return this.document.getFirstChild();
+    }
+
+    /** The <code>DOMImplementation</code> object that handles this document. A
+     * DOM application may use objects from multiple implementations.
+     *
+     */
+    public DOMImplementation getImplementation() {
+        return this.document.getImplementation();
+    }
+
+    /** The last child of this node. If there is no such node, this returns
+     * <code>null</code>.
+     *
+     */
+    public Node getLastChild() {
+        return this.document.getLastChild();
+    }
+
+    /** Returns the local part of the qualified name of this node.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+     * method, such as <code>createElement</code> from the
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * @since DOM Level 2
+     *
+     */
+    public String getLocalName() {
+        return this.document.getLocalName();
+    }
+
+    /** The namespace URI of this node, or <code>null</code> if it is
+     * unspecified.
+     * <br>This is not a computed value that is the result of a namespace
+     * lookup based on an examination of the namespace declarations in
+     * scope. It is merely the namespace URI given at creation time.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+     * method, such as <code>createElement</code> from the
+     * <code>Document</code> interface, this is always <code>null</code>.Per
+     * the Namespaces in XML Specification  an attribute does not inherit
+     * its namespace from the element it is attached to. If an attribute is
+     * not explicitly given a namespace, it simply has no namespace.
+     * @since DOM Level 2
+     *
+     */
+    public String getNamespaceURI() {
+        return this.document.getNamespaceURI();
+    }
+
+    /** The node immediately following this node. If there is no such node,
+     * this returns <code>null</code>.
+     *
+     */
+    public Node getNextSibling() {
+        return this.document.getNextSibling();
+    }
+
+    /** The name of this node, depending on its type; see the table above.
+     *
+     */
+    public String getNodeName() {
+        return this.document.getNodeName();
+    }
+
+    /** A code representing the type of the underlying object, as defined above.
+     *
+     */
+    public short getNodeType() {
+        return this.document.getNodeType();
+    }
+
+    /** The value of this node, depending on its type; see the table above.
+     * When it is defined to be <code>null</code>, setting it has no effect.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     *
+     */
+    public String getNodeValue() throws DOMException {
+        return this.document.getNodeValue();
+    }
+
+    /** The <code>Document</code> object associated with this node. This is
+     * also the <code>Document</code> object used to create new nodes. When
+     * this node is a <code>Document</code> or a <code>DocumentType</code>
+     * which is not used with any <code>Document</code> yet, this is
+     * <code>null</code>.
+     * @since DOM Level 2
+     *
+     */
+    public Document getOwnerDocument() {
+        return this.document.getOwnerDocument();
+    }
+
+    /** The parent of this node. All nodes, except <code>Attr</code>,
+     * <code>Document</code>, <code>DocumentFragment</code>,
+     * <code>Entity</code>, and <code>Notation</code> may have a parent.
+     * However, if a node has just been created and not yet added to the
+     * tree, or if it has been removed from the tree, this is
+     * <code>null</code>.
+     *
+     */
+    public Node getParentNode() {
+        return this.document.getParentNode();
+    }
+
+    /** The namespace prefix of this node, or <code>null</code> if it is
+     * unspecified.
+     * <br>Note that setting this attribute, when permitted, changes the
+     * <code>nodeName</code> attribute, which holds the qualified name, as
+     * well as the <code>tagName</code> and <code>name</code> attributes of
+     * the <code>Element</code> and <code>Attr</code> interfaces, when
+     * applicable.
+     * <br>Note also that changing the prefix of an attribute that is known to
+     * have a default value, does not make a new attribute with the default
+     * value and the original prefix appear, since the
+     * <code>namespaceURI</code> and <code>localName</code> do not change.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+     * method, such as <code>createElement</code> from the
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
+     *   illegal character, per the XML 1.0 specification .
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is
+     *   malformed per the Namespaces in XML specification, if the
+     *   <code>namespaceURI</code> of this node is <code>null</code>, if the
+     *   specified prefix is "xml" and the <code>namespaceURI</code> of this
+     *   node is different from "http://www.w3.org/XML/1998/namespace", if
+     *   this node is an attribute and the specified prefix is "xmlns" and
+     *   the <code>namespaceURI</code> of this node is different from "
+     *   http://www.w3.org/2000/xmlns/", or if this node is an attribute and
+     *   the <code>qualifiedName</code> of this node is "xmlns" .
+     * @since DOM Level 2
+     *
+     */
+    public String getPrefix() {
+        return this.document.getPrefix();
+    }
+
+    /** The node immediately preceding this node. If there is no such node,
+     * this returns <code>null</code>.
+     *
+     */
+    public Node getPreviousSibling() {
+        return this.document.getPreviousSibling();
+    }
+
+    /** Returns whether this node (if it is an element) has any attributes.
+     * @return <code>true</code> if this node has any attributes,
+     *   <code>false</code> otherwise.
+     * @since DOM Level 2
+     *
+     */
+    public boolean hasAttributes() {
+        return this.document.hasAttributes();
+    }
+
+    /** Returns whether this node has any children.
+     * @return <code>true</code> if this node has any children,
+     *   <code>false</code> otherwise.
+     *
+     */
+    public boolean hasChildNodes() {
+        return this.document.hasChildNodes();
+    }
+
+    /** Imports a node from another document to this document. The returned
+     * node has no parent; (<code>parentNode</code> is <code>null</code>).
+     * The source node is not altered or removed from the original document;
+     * this method creates a new copy of the source node.
+     * <br>For all nodes, importing a node creates a node object owned by the
+     * importing document, with attribute values identical to the source
+     * node's <code>nodeName</code> and <code>nodeType</code>, plus the
+     * attributes related to namespaces (<code>prefix</code>,
+     * <code>localName</code>, and <code>namespaceURI</code>). As in the
+     * <code>cloneNode</code> operation on a <code>Node</code>, the source
+     * node is not altered.
+     * <br>Additional information is copied as appropriate to the
+     * <code>nodeType</code>, attempting to mirror the behavior expected if
+     * a fragment of XML or HTML source was copied from one document to
+     * another, recognizing that the two documents may have different DTDs
+     * in the XML case. The following list describes the specifics for each
+     * type of node.
+     * <dl>
+     * <dt>ATTRIBUTE_NODE</dt>
+     * <dd>The <code>ownerElement</code> attribute
+     * is set to <code>null</code> and the <code>specified</code> flag is
+     * set to <code>true</code> on the generated <code>Attr</code>. The
+     * descendants of the source <code>Attr</code> are recursively imported
+     * and the resulting nodes reassembled to form the corresponding subtree.
+     * Note that the <code>deep</code> parameter has no effect on
+     * <code>Attr</code> nodes; they always carry their children with them
+     * when imported.</dd>
+     * <dt>DOCUMENT_FRAGMENT_NODE</dt>
+     * <dd>If the <code>deep</code> option
+     * was set to <code>true</code>, the descendants of the source element
+     * are recursively imported and the resulting nodes reassembled to form
+     * the corresponding subtree. Otherwise, this simply generates an empty
+     * <code>DocumentFragment</code>.</dd>
+     * <dt>DOCUMENT_NODE</dt>
+     * <dd><code>Document</code>
+     * nodes cannot be imported.</dd>
+     * <dt>DOCUMENT_TYPE_NODE</dt>
+     * <dd><code>DocumentType</code>
+     * nodes cannot be imported.</dd>
+     * <dt>ELEMENT_NODE</dt>
+     * <dd>Specified attribute nodes of the
+     * source element are imported, and the generated <code>Attr</code>
+     * nodes are attached to the generated <code>Element</code>. Default
+     * attributes are not copied, though if the document being imported into
+     * defines default attributes for this element name, those are assigned.
+     * If the <code>importNode</code> <code>deep</code> parameter was set to
+     * <code>true</code>, the descendants of the source element are
+     * recursively imported and the resulting nodes reassembled to form the
+     * corresponding subtree.</dd>
+     * <dt>ENTITY_NODE</dt>
+     * <dd><code>Entity</code> nodes can be
+     * imported, however in the current release of the DOM the
+     * <code>DocumentType</code> is readonly. Ability to add these imported
+     * nodes to a <code>DocumentType</code> will be considered for addition
+     * to a future release of the DOM.On import, the <code>publicId</code>,
+     * <code>systemId</code>, and <code>notationName</code> attributes are
+     * copied. If a <code>deep</code> import is requested, the descendants
+     * of the the source <code>Entity</code> are recursively imported and
+     * the resulting nodes reassembled to form the corresponding subtree.</dd>
+     * <dt>
+     * ENTITY_REFERENCE_NODE</dt>
+     * <dd>Only the <code>EntityReference</code> itself is
+     * copied, even if a <code>deep</code> import is requested, since the
+     * source and destination documents might have defined the entity
+     * differently. If the document being imported into provides a
+     * definition for this entity name, its value is assigned.</dd>
+     * <dt>NOTATION_NODE</dt>
+     * <dd>
+     * <code>Notation</code> nodes can be imported, however in the current
+     * release of the DOM the <code>DocumentType</code> is readonly. Ability
+     * to add these imported nodes to a <code>DocumentType</code> will be
+     * considered for addition to a future release of the DOM.On import, the
+     * <code>publicId</code> and <code>systemId</code> attributes are copied.
+     * Note that the <code>deep</code> parameter has no effect on
+     * <code>Notation</code> nodes since they never have any children.</dd>
+     * <dt>
+     * PROCESSING_INSTRUCTION_NODE</dt>
+     * <dd>The imported node copies its
+     * <code>target</code> and <code>data</code> values from those of the
+     * source node.</dd>
+     * <dt>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE</dt>
+     * <dd>These three
+     * types of nodes inheriting from <code>CharacterData</code> copy their
+     * <code>data</code> and <code>length</code> attributes from those of
+     * the source node.</dd>
+     * </dl>
+     * @param importedNode The node to import.
+     * @param deep If <code>true</code>, recursively import the subtree under
+     *   the specified node; if <code>false</code>, import only the node
+     *   itself, as explained above. This has no effect on <code>Attr</code>
+     *   , <code>EntityReference</code>, and <code>Notation</code> nodes.
+     * @return The imported node that belongs to this <code>Document</code>.
+     * @exception DOMException
+     *   NOT_SUPPORTED_ERR: Raised if the type of node being imported is not
+     *   supported.
+     * @since DOM Level 2
+     *
+     */
+    public Node importNode(Node importedNode, boolean deep) throws DOMException {
+        return this.document.importNode(importedNode, deep);
+    }
+
+    /** Inserts the node <code>newChild</code> before the existing child node
+     * <code>refChild</code>. If <code>refChild</code> is <code>null</code>,
+     * insert <code>newChild</code> at the end of the list of children.
+     * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
+     * all of its children are inserted, in the same order, before
+     * <code>refChild</code>. If the <code>newChild</code> is already in the
+     * tree, it is first removed.
+     * @param newChild The node to insert.
+     * @param refChild The reference node, i.e., the node before which the
+     *   new node must be inserted.
+     * @return The node being inserted.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+     *   allow children of the type of the <code>newChild</code> node, or if
+     *   the node to insert is one of this node's ancestors or this node
+     *   itself.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or
+     *   if the parent of the node being inserted is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>refChild</code> is not a child of
+     *   this node.
+     *
+     */
+    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+        return this.document.insertBefore(newChild, refChild);
+    }
+
+    /** Tests whether the DOM implementation implements a specific feature and
+     * that feature is supported by this node.
+     * @param feature The name of the feature to test. This is the same name
+     *   which can be passed to the method <code>hasFeature</code> on
+     *   <code>DOMImplementation</code>.
+     * @param version This is the version number of the feature to test. In
+     *   Level 2, version 1, this is the string "2.0". If the version is not
+     *   specified, supporting any version of the feature will cause the
+     *   method to return <code>true</code>.
+     * @return Returns <code>true</code> if the specified feature is
+     *   supported on this node, <code>false</code> otherwise.
+     * @since DOM Level 2
+     *
+     */
+    public boolean isSupported(String feature, String version) {
+        return this.document.isSupported(feature, version);
+    }
+
+    /** Puts all <code>Text</code> nodes in the full depth of the sub-tree
+     * underneath this <code>Node</code>, including attribute nodes, into a
+     * "normal" form where only structure (e.g., elements, comments,
+     * processing instructions, CDATA sections, and entity references)
+     * separates <code>Text</code> nodes, i.e., there are neither adjacent
+     * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can
+     * be used to ensure that the DOM view of a document is the same as if
+     * it were saved and re-loaded, and is useful when operations (such as
+     * XPointer  lookups) that depend on a particular document tree
+     * structure are to be used.In cases where the document contains
+     * <code>CDATASections</code>, the normalize operation alone may not be
+     * sufficient, since XPointers do not differentiate between
+     * <code>Text</code> nodes and <code>CDATASection</code> nodes.
+     * @since DOM Level 2
+     *
+     */
+    public void normalize() {
+        this.document.normalize();
+    }
+
+    /** Removes the child node indicated by <code>oldChild</code> from the list
+     * of children, and returns it.
+     * @param oldChild The node being removed.
+     * @return The node removed.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
+     *   this node.
+     *
+     */
+    public Node removeChild(Node oldChild) throws DOMException {
+        return this.document.removeChild(oldChild);
+    }
+
+    /** Replaces the child node <code>oldChild</code> with <code>newChild</code>
+     *  in the list of children, and returns the <code>oldChild</code> node.
+     * <br>If <code>newChild</code> is a <code>DocumentFragment</code> object,
+     * <code>oldChild</code> is replaced by all of the
+     * <code>DocumentFragment</code> children, which are inserted in the
+     * same order. If the <code>newChild</code> is already in the tree, it
+     * is first removed.
+     * @param newChild The new node to put in the child list.
+     * @param oldChild The node being replaced in the list.
+     * @return The node replaced.
+     * @exception DOMException
+     *   HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
+     *   allow children of the type of the <code>newChild</code> node, or if
+     *   the node to put in is one of this node's ancestors or this node
+     *   itself.
+     *   <br>WRONG_DOCUMENT_ERR: Raised if <code>newChild</code> was created
+     *   from a different document than the one that created this node.
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of
+     *   the new node is readonly.
+     *   <br>NOT_FOUND_ERR: Raised if <code>oldChild</code> is not a child of
+     *   this node.
+     *
+     */
+    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+        return this.document.replaceChild(newChild, oldChild);
+    }
+
+    /** The value of this node, depending on its type; see the table above.
+     * When it is defined to be <code>null</code>, setting it has no effect.
+     * @exception DOMException
+     *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
+     *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
+     *   fit in a <code>DOMString</code> variable on the implementation
+     *   platform.
+     *
+     */
+    public void setNodeValue(String nodeValue) throws DOMException {
+        this.document.setNodeValue(nodeValue);
+    }
+
+    /** The namespace prefix of this node, or <code>null</code> if it is
+     * unspecified.
+     * <br>Note that setting this attribute, when permitted, changes the
+     * <code>nodeName</code> attribute, which holds the qualified name, as
+     * well as the <code>tagName</code> and <code>name</code> attributes of
+     * the <code>Element</code> and <code>Attr</code> interfaces, when
+     * applicable.
+     * <br>Note also that changing the prefix of an attribute that is known to
+     * have a default value, does not make a new attribute with the default
+     * value and the original prefix appear, since the
+     * <code>namespaceURI</code> and <code>localName</code> do not change.
+     * <br>For nodes of any type other than <code>ELEMENT_NODE</code> and
+     * <code>ATTRIBUTE_NODE</code> and nodes created with a DOM Level 1
+     * method, such as <code>createElement</code> from the
+     * <code>Document</code> interface, this is always <code>null</code>.
+     * @exception DOMException
+     *   INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
+     *   illegal character, per the XML 1.0 specification .
+     *   <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+     *   <br>NAMESPACE_ERR: Raised if the specified <code>prefix</code> is
+     *   malformed per the Namespaces in XML specification, if the
+     *   <code>namespaceURI</code> of this node is <code>null</code>, if the
+     *   specified prefix is "xml" and the <code>namespaceURI</code> of this
+     *   node is different from "http://www.w3.org/XML/1998/namespace", if
+     *   this node is an attribute and the specified prefix is "xmlns" and
+     *   the <code>namespaceURI</code> of this node is different from "
+     *   http://www.w3.org/2000/xmlns/", or if this node is an attribute and
+     *   the <code>qualifiedName</code> of this node is "xmlns" .
+     * @since DOM Level 2
+     *
+     */
+    public void setPrefix(String prefix) throws DOMException {
+        this.document.setPrefix(prefix);
+    }
+    
+    /**
+     * @since DOM Level 3
+     */
+    public Node renameNode(Node node, String namespaceURI, String qualifiedName) throws DOMException {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void normalizeDocument() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public DOMConfiguration getDomConfig() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public Node adoptNode(Node source) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void setDocumentURI(String uri) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getDocumentURI() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void setStrictErrorChecking(boolean value) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public boolean getStrictErrorChecking() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void setXmlVersion(String version) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getXmlVersion() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void setXmlStandalone(boolean value) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public boolean getXmlStandalone() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+    
+    /**
+     * @since DOM Level 3
+     */
+    public void setXmlEncoding(String version) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getXmlEncoding() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getInputEncoding() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public Object getUserData(String key) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public Object setUserData(String key, Object value, UserDataHandler handler) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+    
+    /**
+     * @since DOM Level 3
+     */
+    public Object getFeature(String feature, String version) { 
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public short compareDocumentPosition(Node other) throws DOMException {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getBaseURI() {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String getTextContent() throws DOMException {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public boolean isDefaultNamespace(String namespaceURI) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public boolean isEqualNode(Node arg) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public boolean isSameNode(Node other) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String lookupNamespaceURI(String prefix) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public String lookupPrefix(String namespaceURI) {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+
+    /**
+     * @since DOM Level 3
+     */
+    public void setTextContent(String textContent) throws DOMException {
+        throw new UnsupportedOperationException(DOMLEVEL3_ERR_MSG);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/ExtendedXLinkPipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/ExtendedXLinkPipe.java
new file mode 100644
index 0000000..83bbc5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/ExtendedXLinkPipe.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.xlink;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class extends the XLink semantic capabilities to understand those
+ * elements that are have default linking semantics associated.
+ *
+ * <p>This class reacts on 'href' and 'src' attributes and is able to understand
+ * the semantics of XHTML/WML/SMIL/SVG and all the rest of the languages that
+ * use either XLink of the above attributes.</p>
+ *
+ * <p>NOTE: this class is clearly a hack and is not future compatible, but
+ * since many XML formats to date are not compatible with the XLink semantics
+ * this is what we have to do to live in the bleeding edge. Once there will
+ * be a way to remove this, that will be a happy day for XML and for Cocoon too.</p>
+ *
+ * @version $Id$
+ */
+public abstract class ExtendedXLinkPipe extends XLinkPipe {
+
+    protected static Set arrayToSet(Object[] array) {
+        final Set set = new HashSet(array.length);
+
+        for (int i = 0; i < array.length; i++)
+            set.add(array[i]);
+        return set;
+    }
+    
+    private final Map MAP = new HashMap() {
+        {
+            put(
+                "",
+                arrayToSet(
+                    new String[] {
+                        "about",
+                        "action",
+                        "background",
+                        "data",
+                        "discuri",
+                        "href",
+                        "longdesc",
+                        "onenterforward",
+                        "onenterbackward",
+                        "ontimer",
+                        "onpick",
+                        "src" }));
+            put(
+                "http://www.w3.org/1999/xhtml",
+                arrayToSet(
+                    new String[] {
+                        "action",
+                        "background",
+                        "data",
+                        "href",
+                        "longdesc",
+                        "src" }));
+            put(
+                "http://www.w3.org/2001/XInclude",
+                arrayToSet(new String[] { "href" }));
+            put(
+                "http://www.wapforum.org/2001/wml",
+                arrayToSet(
+                    new String[] {
+                        "onenterforward",
+                        "onenterbackward",
+                        "ontimer",
+                        "href",
+                        "onpick",
+                        "src" }));
+            put(
+                "http://www.w3.org/2002/01/P3Pv1",
+                arrayToSet(
+                    new String[] { "about", "discuri", "src", "service" }));            
+        }
+    };
+
+    private int attrIndex = -1;
+
+    public void startElement(
+        String uri,
+        final String name,
+        final String raw,
+        final Attributes attr)
+        throws SAXException {
+        final Set attrList = (Set) MAP.get((uri == null) ? "" : uri);
+
+        if (attrList != null) {
+            for (int i = attrIndex + 1; i < attr.getLength(); i++)
+                if (attr.getURI(i).equals("")
+                    && attrList.contains(attr.getLocalName(i))) {
+
+                    final String att = attr.getValue(i);
+
+                    if (att != null) {
+                        final String str =
+                            ": URI="
+                                + uri
+                                + " NAME="
+                                + name
+                                + " RAW="
+                                + raw
+                                + " ATT="
+                                + attr.getLocalName(i)
+                                + " NS="
+                                + uri
+                                + " VALUE="
+                                + att;
+
+                        if (getLogger().isDebugEnabled())
+                           getLogger().debug("Transforming to XLink" + str);
+                           
+                        attrIndex = i;
+                        
+                        simpleLink(
+                            att,
+                            null,
+                            null,
+                            null,
+                            null,
+                            null,
+                            uri,
+                            name,
+                            raw,
+                            attr);
+                        
+                        return;
+                    }
+                }
+            attrIndex = -1;
+        }
+
+        super.startElement(uri, name, raw, attr);
+    }
+
+    public void simpleLink(
+        final String href,
+        final String role,
+        final String arcrole,
+        final String title,
+        final String show,
+        final String actuate,
+        final String uri,
+        final String name,
+        final String raw,
+        final Attributes attr)
+        throws SAXException {
+        if (attrIndex != -1) {
+            final AttributesImpl newattr = new AttributesImpl(attr);
+            newattr.setValue(attrIndex, href);
+            startElement(uri, name, raw, newattr);
+        } else {
+            super.simpleLink(
+                href,
+                role,
+                arcrole,
+                title,
+                show,
+                actuate,
+                uri,
+                name,
+                raw,
+                attr);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkHandler.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkHandler.java
new file mode 100644
index 0000000..e0dc62e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.xlink;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+/**
+ * This interface indicates an XLinkHandler that uses the same
+ * event driven design patterns that SAX enforces.
+ *
+ * @version $Id$
+ */
+public interface XLinkHandler  {
+
+    void simpleLink(String href, String role, String arcrole, String title, String show, String actuate, String uri, String name, String raw, Attributes attr) throws SAXException;
+
+    void startExtendedLink(String role, String title, String uri, String name, String raw, Attributes attr) throws SAXException;
+
+    void endExtendedLink(String uri, String name, String raw) throws SAXException;
+
+    void startLocator(String href, String role, String title, String label, String uri, String name, String raw, Attributes attr) throws SAXException;
+
+    void endLocator(String uri, String name, String raw) throws SAXException;
+
+    void startArc(String arcrole, String title, String show, String actuate, String from, String to, String uri, String name, String raw, Attributes attr) throws SAXException;
+
+    void endArc(String uri, String name, String raw) throws SAXException;
+
+    void linkResource(String role, String title, String label, String uri, String name, String raw, Attributes attr) throws SAXException;
+
+    void linkTitle(String uri, String name, String raw, Attributes attr) throws SAXException;
+
+}
+
diff --git a/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkPipe.java b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkPipe.java
new file mode 100644
index 0000000..0d5f8cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/java/org/apache/cocoon/xml/xlink/XLinkPipe.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.xlink;
+
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This class implements a SAX consumer wrapper that transforms the
+ * general SAX semantic into XLink semantics for easier consumption.
+ *
+ * Classes should extend this class and overwrite the abstract method
+ * to consume the XLink events that come in as SAX events.
+ *
+ * NOTE: this is based on XLink W3C Candidate Recommendation 3 July 2000
+ *
+ * @version $Id$
+ */
+public abstract class XLinkPipe extends AbstractXMLPipe implements XLinkHandler {
+
+    public static final String XLINK_NAMESPACE_URI = "http://www.w3.org/1999/xlink";
+    public static final String XLINK_TYPE = "type";
+    public static final String XLINK_HREF = "href";
+    public static final String XLINK_ROLE = "role";
+    public static final String XLINK_ARCROLE = "arcrole";
+    public static final String XLINK_TITLE = "title";
+    public static final String XLINK_SHOW = "show";
+    public static final String XLINK_ACTUATE = "actuate";
+    public static final String XLINK_LABEL = "label";
+    public static final String XLINK_FROM = "from";
+    public static final String XLINK_TO = "to";
+    public static final String XLINK_TYPE_SIMPLE = "simple";
+    public static final String XLINK_TYPE_EXTENDED = "extended";
+    public static final String XLINK_TYPE_LOCATOR = "locator";
+    public static final String XLINK_TYPE_ARC = "arc";
+    public static final String XLINK_TYPE_RESOURCE = "resource";
+    public static final String XLINK_TYPE_TITLE = "title";
+
+    private String extendedLinkElementName = null;
+    private String extendedLinkElementURI = null;
+    private String linkLocatorElementName = null;
+    private String linkLocatorElementURI = null;
+    private String linkArcElementName = null;
+    private String linkArcElementURI = null;
+
+    public void startElement( String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        String type = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TYPE );
+        if ( type != null )
+        {
+            if ( type.equals( XLINK_TYPE_SIMPLE ) )
+            {
+                if ( this.extendedLinkElementName != null )
+                {
+                    throw new SAXException( "An XLink simple link cannot be included into an 'extended' element" );
+                }
+                else if ( this.linkLocatorElementName != null )
+                {
+                    throw new SAXException( "An XLink simple link cannot be included into a 'locator' element" );
+                }
+                else if ( this.linkArcElementName != null )
+                {
+                    throw new SAXException( "An XLink simple link cannot be included into an 'arc' element" );
+                }
+                String href = attr.getValue( XLINK_NAMESPACE_URI, XLINK_HREF );
+                String role = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ROLE );
+                String arcrole = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ARCROLE );
+                String title = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TITLE );
+                String show = attr.getValue( XLINK_NAMESPACE_URI, XLINK_SHOW );
+                String actuate = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ACTUATE );
+                simpleLink( href, role, arcrole, title, show, actuate, uri, name, raw, attr );
+            }
+            else if ( type.equals( XLINK_TYPE_EXTENDED ) )
+            {
+                if ( this.extendedLinkElementName != null )
+                {
+                    throw new SAXException( "An XLink extended link cannot include another 'extended' element" );
+                }
+                else if ( this.linkLocatorElementName != null )
+                {
+                    throw new SAXException( "An XLink extended link cannot be included into a 'locator' element" );
+                }
+                else if ( this.linkArcElementName != null )
+                {
+                    throw new SAXException( "An XLink extended link cannot be included into an 'arc' element" );
+                }
+                String role = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ROLE );
+                String title = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TITLE );
+                this.extendedLinkElementName = name;
+                this.extendedLinkElementURI = uri;
+                startExtendedLink( role, title, uri, name, raw, attr );
+            }
+            else if ( type.equals( XLINK_TYPE_LOCATOR ) )
+            {
+                if ( this.extendedLinkElementName == null )
+                {
+                    throw new SAXException( "An XLink locator must be included into an 'extended' element" );
+                }
+                else if ( this.linkLocatorElementName != null )
+                {
+                    throw new SAXException( "An XLink locator  cannot be included into another 'locator' element" );
+                }
+                else if ( this.linkArcElementName != null )
+                {
+                    throw new SAXException( "An XLink locator cannot be included into an 'arc' element" );
+                }
+                String href = attr.getValue( XLINK_NAMESPACE_URI, XLINK_HREF );
+                String role = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ROLE );
+                String title = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TITLE );
+                String label = attr.getValue( XLINK_NAMESPACE_URI, XLINK_LABEL );
+                this.linkLocatorElementName = name;
+                this.linkLocatorElementURI = uri;
+                startLocator( href, role, title, label, uri, name, raw, attr );
+            }
+            else if ( type.equals( XLINK_TYPE_ARC ) )
+            {
+                if ( this.extendedLinkElementName == null )
+                {
+                    throw new SAXException( "An XLink arc must be included into an 'extended' element" );
+                }
+                else if ( this.linkLocatorElementName != null )
+                {
+                    throw new SAXException( "An XLink arc cannot be included into a 'locator' element" );
+                }
+                else if ( this.linkArcElementName != null )
+                {
+                    throw new SAXException( "An XLink arc cannot be included into another 'arc' element" );
+                }
+                String arcrole = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ARCROLE );
+                String title = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TITLE );
+                String show = attr.getValue( XLINK_NAMESPACE_URI, XLINK_SHOW );
+                String actuate = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ACTUATE );
+                String from = attr.getValue( XLINK_NAMESPACE_URI, XLINK_FROM );
+                String to = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TO );
+                this.linkArcElementName = name;
+                this.linkArcElementURI = uri;
+                startArc( arcrole, title, show, actuate, from, to, uri, name, raw, attr );
+            }
+            else if ( type.equals( XLINK_TYPE_RESOURCE ) )
+            {
+                if ( this.extendedLinkElementName == null )
+                {
+                    throw new SAXException( "An XLink resource must be included into an 'extended' element" );
+                }
+                String role = attr.getValue( XLINK_NAMESPACE_URI, XLINK_ROLE );
+                String title = attr.getValue( XLINK_NAMESPACE_URI, XLINK_TITLE );
+                String label = attr.getValue( XLINK_NAMESPACE_URI, XLINK_LABEL );
+                linkResource( role, title, label, uri, name, raw, attr );
+            }
+            else if ( type.equals( XLINK_TYPE_TITLE ) )
+            {
+                if ( ( this.extendedLinkElementName == null )
+                        && ( this.linkLocatorElementName == null )
+                        && ( this.linkArcElementName == null ) )
+                {
+                    throw new SAXException( "An XLink title must be included into an 'extended', 'locator' or 'arc' element" );
+                }
+                linkTitle( uri, name, raw, attr );
+            }
+            else
+            {
+                super.startElement( uri, name, raw, attr );
+            }
+        }
+        else
+        {
+            super.startElement( uri, name, raw, attr );
+        }
+    }
+
+    public void endElement( String uri, String name, String raw ) throws SAXException
+    {
+        if ( ( name.equals( this.extendedLinkElementName ) ) && ( uri.equals( this.extendedLinkElementURI ) ) )
+        {
+            this.extendedLinkElementName = null;
+            this.extendedLinkElementURI = null;
+            this.endExtendedLink( uri, name, raw );
+        }
+        else if ( ( name.equals( this.linkLocatorElementName ) ) && ( uri.equals( this.linkLocatorElementURI ) ) )
+        {
+            this.linkLocatorElementName = null;
+            this.linkLocatorElementURI = null;
+            this.endLocator( uri, name, raw );
+        }
+        else if ( ( name.equals( this.linkArcElementName ) ) && ( uri.equals( this.linkArcElementURI ) ) )
+        {
+            this.linkArcElementName = null;
+            this.linkArcElementURI = null;
+            this.endArc( uri, name, raw );
+        }
+        else
+        {
+            super.endElement( uri, name, raw );
+        }
+    }
+
+    // Default XLinkHandler implementation (defaults to copy over)
+
+    public void simpleLink( String href, String role, String arcrole, String title, String show, String actuate, String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        AttributesImpl newattr = new AttributesImpl( attr );
+        int hrefIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_HREF );
+        int roleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ROLE );
+        int arcroleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ARCROLE );
+        int titleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TITLE );
+        int showIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_SHOW );
+        int actuateIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ACTUATE );
+        if ( hrefIndex > -1 )
+            newattr.setValue( hrefIndex, href );
+        if ( roleIndex > -1 )
+            newattr.setValue( roleIndex, role );
+        if ( arcroleIndex > -1 )
+            newattr.setValue( arcroleIndex, arcrole );
+        if ( titleIndex > -1 )
+            newattr.setValue( titleIndex, title );
+        if ( showIndex > -1 )
+            newattr.setValue( showIndex, show );
+        if ( actuateIndex > -1 )
+            newattr.setValue( actuateIndex, actuate );
+        super.startElement( uri, name, raw, newattr );
+    }
+
+    public void startExtendedLink( String role, String title, String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        AttributesImpl newattr = new AttributesImpl( attr );
+        int roleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ROLE );
+        int titleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TITLE );
+        if ( roleIndex > -1 )
+            newattr.setValue( roleIndex, role );
+        if ( titleIndex > -1 )
+            newattr.setValue( titleIndex, title );
+        super.startElement( uri, name, raw, newattr );
+    }
+
+    public void startLocator( String href, String role, String title, String label, String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        AttributesImpl newattr = new AttributesImpl( attr );
+        int hrefIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_HREF );
+        int roleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ROLE );
+        int titleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TITLE );
+        int labelIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_LABEL );
+        if ( hrefIndex > -1 )
+            newattr.setValue( hrefIndex, href );
+        if ( roleIndex > -1 )
+            newattr.setValue( roleIndex, role );
+        if ( titleIndex > -1 )
+            newattr.setValue( titleIndex, title );
+        if ( labelIndex > -1 )
+            newattr.setValue( labelIndex, label );
+        super.startElement( uri, name, raw, newattr );
+    }
+
+    public void startArc( String arcrole, String title, String show, String actuate, String from, String to, String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        AttributesImpl newattr = new AttributesImpl( attr );
+        int arcroleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ARCROLE );
+        int titleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TITLE );
+        int showIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_SHOW );
+        int actuateIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ACTUATE );
+        int fromIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_FROM );
+        int toIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TO );
+        if ( arcroleIndex > -1 )
+            newattr.setValue( arcroleIndex, arcrole );
+        if ( titleIndex > -1 )
+            newattr.setValue( titleIndex, title );
+        if ( showIndex > -1 )
+            newattr.setValue( showIndex, show );
+        if ( actuateIndex > -1 )
+            newattr.setValue( actuateIndex, actuate );
+        if ( fromIndex > -1 )
+            newattr.setValue( actuateIndex, from );
+        if ( toIndex > -1 )
+            newattr.setValue( actuateIndex, to );
+        super.startElement( uri, name, raw, newattr );
+    }
+
+    public void linkResource( String role, String title, String label, String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        AttributesImpl newattr = new AttributesImpl( attr );
+        int roleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_ROLE );
+        int titleIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_TITLE );
+        int labelIndex = attr.getIndex( XLINK_NAMESPACE_URI, XLINK_LABEL );
+        if ( roleIndex > -1 )
+            newattr.setValue( roleIndex, role );
+        if ( titleIndex > -1 )
+            newattr.setValue( titleIndex, title );
+        if ( labelIndex > -1 )
+            newattr.setValue( labelIndex, label );
+        super.startElement( uri, name, raw, newattr );
+    }
+
+    public void linkTitle( String uri, String name, String raw, Attributes attr ) throws SAXException
+    {
+        super.startElement( uri, name, raw, attr );
+    }
+
+    public void endExtendedLink( String uri, String name, String raw ) throws SAXException
+    {
+        super.endElement( uri, name, raw );
+    }
+
+    public void endLocator( String uri, String name, String raw ) throws SAXException
+    {
+        super.endElement( uri, name, raw );
+    }
+
+    public void endArc( String uri, String name, String raw ) throws SAXException
+    {
+        super.endElement( uri, name, raw );
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/mocks/com/sun/tools/javac/Main.java b/non-releases/trunk_before_flattening/src/mocks/com/sun/tools/javac/Main.java
new file mode 100644
index 0000000..9e154ac
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/com/sun/tools/javac/Main.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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 com.sun.tools.javac;
+
+import java.io.PrintWriter;
+
+/**
+ * Mock class providing the declarations required to compile the Cocoon code when
+ * the actual library is not present.
+ * 
+ * @version $Id: Main.java 30932 2004-07-29 17:35:38Z vgritsenko $
+ */
+public class Main {
+
+	public Main() {
+       throw new UnsupportedOperationException("This is a mock object");
+	}
+
+	public static int compile(String[] strings, PrintWriter p) {
+	   throw new UnsupportedOperationException("This is a mock object");
+	}
+}
diff --git a/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/DOMConfiguration.java b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/DOMConfiguration.java
new file mode 100644
index 0000000..27d35f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/DOMConfiguration.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.w3c.dom;
+
+/**
+ * Mock class providing the declarations required to compile the Cocoon code when
+ * the actual library is not present. This class is required due to incompatible
+ * changes between JDK 1.4 and JDK 5.0 wrt the DOM interfaces (level 2 to level 3).
+ * 
+ * @version $Id$
+ */
+public interface DOMConfiguration {
+
+}
diff --git a/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/TypeInfo.java b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/TypeInfo.java
new file mode 100644
index 0000000..d6326a9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/TypeInfo.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.w3c.dom;
+
+/**
+ * Mock class providing the declarations required to compile the Cocoon code when
+ * the actual library is not present. This class is required due to incompatible
+ * changes between JDK 1.4 and JDK 5.0 wrt the DOM interfaces (level 2 to level 3).
+ * 
+ * @version $Id$
+ */
+public interface TypeInfo {
+
+}
diff --git a/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/UserDataHandler.java b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/UserDataHandler.java
new file mode 100644
index 0000000..72f1680
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/org/w3c/dom/UserDataHandler.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.w3c.dom;
+
+/**
+ * Mock class providing the declarations required to compile the Cocoon code when
+ * the actual library is not present. This class is required due to incompatible
+ * changes between JDK 1.4 and JDK 5.0 wrt the DOM interfaces (level 2 to level 3).
+ * 
+ * @version $Id$
+ */
+public interface UserDataHandler {
+
+}
diff --git a/non-releases/trunk_before_flattening/src/mocks/pom.xml b/non-releases/trunk_before_flattening/src/mocks/pom.xml
new file mode 100644
index 0000000..7989145
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | @version $Id:$
+    |
+    +-->
+<project>
+  <parent>
+    <groupId>apache-cocoon</groupId>
+    <artifactId>cocoon</artifactId>
+    <version>2.2-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>apache-cocoon</groupId>
+  <artifactId>cocoon-mocks</artifactId>
+  <version>2.2-SNAPSHOT</version>
+  <packaging>jar</packaging>
+  <name>Core Mocks</name>
+  <build>
+    <sourceDirectory>.</sourceDirectory>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/mocks/sun/tools/javac/Main.java b/non-releases/trunk_before_flattening/src/mocks/sun/tools/javac/Main.java
new file mode 100644
index 0000000..28152dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/mocks/sun/tools/javac/Main.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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 sun.tools.javac;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Mock class providing the declarations required to compile the Cocoon code when
+ * the actual library is not present.
+ * 
+ * @version $Id$
+ */
+public class Main {
+
+	public Main(OutputStream err, String string) {
+       throw new UnsupportedOperationException("This is a mock object");
+	}
+
+	public boolean compile(String[] strings) throws IOException {
+	   throw new UnsupportedOperationException("This is a mock object");
+	}
+}
diff --git a/non-releases/trunk_before_flattening/src/osgi-servlet/Manifest.mf b/non-releases/trunk_before_flattening/src/osgi-servlet/Manifest.mf
new file mode 100644
index 0000000..507c281
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/osgi-servlet/Manifest.mf
@@ -0,0 +1,34 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.5
+Created-By: 1.4.2_08-b03 (Sun Microsystems Inc.)
+Bundle-Name: cocoon_servlet
+Bundle-SymbolicName: org.apache.cocoon:cocoon_servlet:1.0.0
+Bundle-Version: 1.0.0
+Bundle-Description: Cocoon servlet bundle
+Bundle-Vendor: Apache
+Bundle-DocURL: http://cocoon.apache.org
+Bundle-ContactAddress: http://cocoon.apache.org
+Bundle-Activator: org.apache.cocoon.service.servlet.impl.Activator
+Bundle-Category: servlet
+Import-Package: 
+ javax.servlet,
+ javax.servlet.http,
+ org.apache.avalon.excalibur.logger,
+ org.apache.avalon.framework.logger,
+ org.apache.cocoon,
+ org.apache.cocoon.core,
+ org.apache.cocoon.core.osgi,
+ org.apache.cocoon.components.notification,
+ org.apache.cocoon.environment,
+ org.apache.cocoon.environment.http,
+ org.apache.cocoon.servlet.multipart,
+ org.apache.commons.lang.time,
+ org.osgi.framework,
+ org.osgi.service.http,
+ org.osgi.service.log
+DynamicImport-Package: org.apache.cocoon.*
+Bundle-UUID: org.apache.cocoon:cocoon_servlet:1.0.0:impl
+Built-From: C:\cygwin\usr\local\svn\cocoon\osgi\bundles\cocoon_servlet
+Build-Date: Fri July 15 2005, 22:46:00
+Bundle-SubversionURL: https://svn.apache.org/repos/asf/cocoon/trunk/src/osgi-servlet/
+
diff --git a/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/Activator.java b/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/Activator.java
new file mode 100644
index 0000000..0d56aa9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/Activator.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.service.servlet.impl;
+
+import java.util.HashSet;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.osgi.OSGiLoggerManager;
+import org.apache.cocoon.core.osgi.OSGiServiceManager;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.log.LogService;
+
+/**
+ * Activator which register a Cocoon servlet
+ * @version $Id$
+ */
+public class Activator implements BundleActivator {
+
+    static BundleContext bc;
+    static final String  SERVLET_ALIAS = "/";     // the http server root
+
+    private HashSet registrations = new HashSet();
+    private ClassLoader classLoader = getClass().getClassLoader();
+    private Logger logger;
+    private Core core;
+    private Processor processor;
+
+    public void start(BundleContext bc) throws Exception {
+
+        Activator.bc  = bc;
+
+        LoggerManager logManager = new OSGiLoggerManager(bc, LogService.LOG_DEBUG);
+        this.logger = logManager.getDefaultLogger();
+
+        OSGiServiceManager manager = new OSGiServiceManager(Activator.bc);
+        this.core = (Core)manager.lookup(Core.ROLE);
+        this.processor = (Processor)manager.lookup(Cocoon.class.getName());
+
+        ServiceListener listener = new ServiceListener() {
+                public void serviceChanged(ServiceEvent ev) {
+                    ServiceReference sr = ev.getServiceReference();
+
+                    switch(ev.getType()) {
+                    case ServiceEvent.REGISTERED:
+                        setRoot(sr);
+                        break;
+                    case ServiceEvent.UNREGISTERING:
+                        unsetRoot(sr);
+                        break;
+                    }
+                }
+            };
+
+        String filter = "(objectclass=" + HttpService.class.getName() + ")";
+
+        try {
+            bc.addServiceListener(listener, filter);
+
+            ServiceReference[] srl = bc.getServiceReferences(null, filter);
+            for(int i = 0; srl != null && i < srl.length; i++) {
+                listener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED,
+                                                         srl[i]));
+            }
+        } catch (Exception e) {
+            this.logger.info("Failed to set up listener for http service", e);
+        }
+    }
+
+    public void stop(BundleContext bc) throws Exception {
+    }
+
+    private void setRoot(ServiceReference sr) {
+
+        if(registrations.contains(sr)) {
+            return; // already done
+        }
+
+        this.logger.info("set root for " + sr);
+
+        HttpService http = (HttpService)bc.getService(sr);
+
+        try {
+            http.registerServlet(SERVLET_ALIAS,
+                                 new BlocksServlet(this.classLoader,
+                                                   this.logger,
+                                                   this.core,
+                                                   this.processor),
+                                 null,
+                                 null);
+
+            registrations.add(sr);
+        } catch (Exception e) {
+            this.logger.info("Failed to register resource", e);
+        }
+    }
+
+    private void unsetRoot(ServiceReference sr) {
+        if(!registrations.contains(sr)) {
+            return; // nothing to do
+        }
+
+        this.logger.info("unset root for " + sr);
+
+        HttpService http = (HttpService)bc.getService(sr);
+
+        if(http != null) {
+            http.unregister(SERVLET_ALIAS);
+            bc.ungetService(sr);
+        }
+        registrations.remove(sr);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/BlocksServlet.java b/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/BlocksServlet.java
new file mode 100644
index 0000000..28872d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/osgi-servlet/org/apache/cocoon/service/servlet/impl/BlocksServlet.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.service.servlet.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.SocketException;
+import java.util.HashMap;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.ConnectionResetException;
+import org.apache.cocoon.Constants;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.notification.DefaultNotifyingBuilder;
+import org.apache.cocoon.components.notification.Notifier;
+import org.apache.cocoon.components.notification.Notifying;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.http.HttpEnvironment;
+import org.apache.cocoon.servlet.multipart.MultipartHttpServletRequest;
+import org.apache.cocoon.servlet.multipart.RequestFactory;
+import org.apache.commons.lang.time.StopWatch;
+
+/**
+ * This is the entry point for Cocoon execution as an HTTP Servlet.
+ *
+ * @version $Id$
+ */
+public class BlocksServlet extends HttpServlet {
+
+    /**
+     * Application <code>Context</code> Key for the servlet configuration
+     * @since 2.1.3
+     */
+    public static final String CONTEXT_SERVLET_CONFIG = "servlet-config";
+
+    // Processing time message
+    protected static final String PROCESSED_BY = "Processed by "
+            + Constants.COMPLETE_NAME + " in ";
+
+    // Used by "show-time"
+    static final float SECOND = 1000;
+    static final float MINUTE = 60 * SECOND;
+    static final float HOUR   = 60 * MINUTE;
+
+    /**
+     * The <code>Processor</code> instance
+     */
+    protected Processor processor;
+
+    /**
+     * Holds exception happened during initialization (if any)
+     */
+    protected Exception exception;
+
+    private String containerEncoding;
+
+    /** The classloader that will be set as the context classloader if init-classloader is true */
+    protected ClassLoader classLoader;
+
+    /**
+     * The RequestFactory is responsible for wrapping multipart-encoded
+     * forms and for handing the file payload of incoming requests
+     */
+    protected RequestFactory requestFactory;
+
+    /** Core */
+    protected Core core;
+
+    /** The logger */
+    protected Logger log;
+
+    public BlocksServlet(ClassLoader classLoader,
+                         Logger logger,
+                         Core core,
+                         Processor processor) {
+        this.classLoader = classLoader;
+        this.log = logger;
+        this.core = core;
+        this.processor = processor;
+    }
+
+    /**
+     * Initialize this <code>BlocksServlet</code> instance.  You will
+     * notice that I have broken the init into sub methods to make it
+     * easier to maintain (BL).  The context is passed to a couple of
+     * the subroutines.  This is also because it is better to explicitly
+     * pass variables than implicitely.  It is both more maintainable,
+     * and more elegant.
+     *
+     * @param conf The ServletConfig object from the servlet engine.
+     *
+     * @throws ServletException
+     */
+    public void init(ServletConfig conf)
+    throws ServletException {
+        super.init(conf);
+
+        this.getLogger().info("Initializing Apache Cocoon " + Constants.VERSION);
+
+        this.containerEncoding = this.getInitParameter("container-encoding", "ISO-8859-1");
+        this.requestFactory = new RequestFactory(this.core.getSettings().isAutosaveUploads(),
+                                                 new File(this.core.getSettings().getUploadDirectory()),
+                                                 this.core.getSettings().isAllowOverwrite(),
+                                                 this.core.getSettings().isSilentlyRename(),
+                                                 this.core.getSettings().getMaxUploadSize(),
+                                                 this.containerEncoding);
+    }
+
+    /**
+     * Dispose Cocoon when servlet is destroyed
+     */
+    public void destroy() {
+        this.classLoader = null;
+        this.log = null;
+        this.core = null;
+        this.processor = null;
+        this.requestFactory = null;
+        super.destroy();
+    }
+
+    /**
+     * Process the specified <code>HttpServletRequest</code> producing output
+     * on the specified <code>HttpServletResponse</code>.
+     */
+    public void service(HttpServletRequest req, HttpServletResponse res)
+    throws ServletException, IOException {
+
+        /* Needed in OSGi environment */
+        try {
+            Thread.currentThread().setContextClassLoader(this.classLoader);
+        } catch (Exception e) {
+            // ignore
+        }
+
+        // used for timing the processing
+        StopWatch stopWatch = new StopWatch();
+        stopWatch.start();
+
+        // add the cocoon header timestamp
+        if (this.core.getSettings().isShowVersion()) {
+            res.addHeader("X-Cocoon-Version", Constants.VERSION);
+        }
+
+        // get the request (wrapped if contains multipart-form data)
+        HttpServletRequest request;
+        try{
+            if (this.core.getSettings().isEnableUploads()) {
+                request = requestFactory.getServletRequest(req);
+            } else {
+                request = req;
+            }
+        } catch (Exception e) {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error("Problem with Cocoon servlet", e);
+            }
+
+            manageException(req, res, null, null,
+                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                            "Problem in creating the Request", null, null, e);
+            return;
+        }
+
+        // We got it... Process the request
+        String uri = request.getServletPath();
+        if (uri == null) {
+            uri = "";
+        }
+        String pathInfo = request.getPathInfo();
+        if (pathInfo != null) {
+            // VG: WebLogic fix: Both uri and pathInfo starts with '/'
+            // This problem exists only in WL6.1sp2, not in WL6.0sp2 or WL7.0b.
+            if (uri.length() > 0 && uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            uri += pathInfo;
+        }
+
+        if (uri.length() == 0) {
+            /* empty relative URI
+                 -> HTTP-redirect from /cocoon to /cocoon/ to avoid
+                    StringIndexOutOfBoundsException when calling
+                    "".charAt(0)
+               else process URI normally
+            */
+            String prefix = request.getRequestURI();
+            if (prefix == null) {
+                prefix = "";
+            }
+
+            res.sendRedirect(res.encodeRedirectURL(prefix + "/"));
+            return;
+        }
+
+        String contentType = null;
+        Object handle = null;
+
+        Environment env;
+        try{
+            if (uri.charAt(0) == '/') {
+                uri = uri.substring(1);
+            }
+            // Pass uri into environment without URLDecoding, as it is already decoded.
+            env = getEnvironment(uri, request, res);
+        } catch (Exception e) {
+            if (getLogger().isErrorEnabled()) {
+                getLogger().error("Problem with Cocoon servlet", e);
+            }
+
+            manageException(request, res, null, uri,
+                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                            "Problem in creating the Environment", null, null, e);
+            return;
+        }
+
+        try {
+            try {
+                // FIXME: don't want the Servlet depend on coreUtil, find other way to initialized request
+                // handle = this.coreUtil.initializeRequest(env);
+
+                if (this.processor.process(env)) {
+                    contentType = env.getContentType();
+                } else {
+                    // We reach this when there is nothing in the processing change that matches
+                    // the request. For example, no matcher matches.
+                    getLogger().fatalError("The Cocoon engine failed to process the request.");
+                    manageException(request, res, env, uri,
+                                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                    "Request Processing Failed",
+                                    "Cocoon engine failed in process the request",
+                                    "The processing engine failed to process the request. This could be due to lack of matching or bugs in the pipeline engine.",
+                                    null);
+                    return;
+                }
+            } catch (ResourceNotFoundException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().warn(e.getMessage(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.getMessage());
+                }
+
+                manageException(request, res, env, uri,
+                                HttpServletResponse.SC_NOT_FOUND,
+                                "Resource Not Found",
+                                "Resource Not Found",
+                                "The requested resource \"" + request.getRequestURI() + "\" could not be found",
+                                e);
+                return;
+
+            } catch (ConnectionResetException e) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug(e.toString(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.toString());
+                }
+
+            } catch (IOException e) {
+                // Tomcat5 wraps SocketException into ClientAbortException which extends IOException.
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug(e.toString(), e);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn(e.toString());
+                }
+
+            } catch (Exception e) {
+                if (getLogger().isErrorEnabled()) {
+                    getLogger().error("Internal Cocoon Problem", e);
+                }
+
+                manageException(request, res, env, uri,
+                                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                "Internal Server Error", null, null, e);
+                return;
+            }
+
+            stopWatch.stop();
+            String timeString = null;
+            if (getLogger().isInfoEnabled()) {
+                timeString = processTime(stopWatch.getTime());
+                getLogger().info("'" + uri + "' " + timeString);
+            }
+
+            if (contentType != null && contentType.equals("text/html")) {
+                String showTime = request.getParameter(Constants.SHOWTIME_PARAM);
+                boolean show = this.core.getSettings().isShowTime();
+                if (showTime != null) {
+                    show = !showTime.equalsIgnoreCase("no");
+                }
+                if (show) {
+                    if ( timeString == null ) {
+                        timeString = processTime(stopWatch.getTime());
+                    }
+                    boolean hide = this.core.getSettings().isHideShowTime();
+                    if (showTime != null) {
+                        hide = showTime.equalsIgnoreCase("hide");
+                    }
+                    ServletOutputStream out = res.getOutputStream();
+                    out.print((hide) ? "<!-- " : "<p>");
+                    out.print(timeString);
+                    out.println((hide) ? " -->" : "</p>");
+                }
+            }
+        } finally {
+            // FIXME: don't want the Servlet depend on coreUtil, find other way to clean up request
+            // this.coreUtil.cleanUpRequest(handle);
+
+            try {
+                if (request instanceof MultipartHttpServletRequest) {
+                    if (getLogger().isDebugEnabled()) {
+                        getLogger().debug("Deleting uploaded file(s).");
+                    }
+                    ((MultipartHttpServletRequest) request).cleanup();
+                }
+            } catch (IOException e) {
+                getLogger().error("Cocoon got an Exception while trying to cleanup the uploaded files.", e);
+            }
+
+            try {
+                OutputStream out = res.getOutputStream();
+                out.flush();
+                out.close();
+            } catch (SocketException se) {
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("SocketException while trying to close stream.", se);
+                } else if (getLogger().isWarnEnabled()) {
+                    getLogger().warn("SocketException while trying to close stream.");
+                }
+            } catch (IOException e) {
+                // See: http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=107489037219505
+                if (getLogger().isDebugEnabled()) {
+                    getLogger().debug("IOException while trying to close stream.", e);
+                }
+            } catch (Exception e) {
+                getLogger().error("Exception while trying to close stream.", e);
+            }
+        }
+    }
+
+    protected void manageException(HttpServletRequest req, HttpServletResponse res, Environment env,
+                                   String uri, int errorStatus,
+                                   String title, String message, String description,
+                                   Exception e)
+    throws IOException {
+        if (this.core.getSettings().isManageExceptions()) {
+            if (env != null) {
+                env.tryResetResponse();
+            } else {
+                res.reset();
+            }
+
+            String type = Notifying.FATAL_NOTIFICATION;
+            HashMap extraDescriptions = null;
+
+            if (errorStatus == HttpServletResponse.SC_NOT_FOUND) {
+                type = "resource-not-found";
+                // Do not show the exception stacktrace for such common errors.
+                e = null;
+            } else {
+                extraDescriptions = new HashMap(2);
+                extraDescriptions.put(Notifying.EXTRA_REQUESTURI, req.getRequestURI());
+                if (uri != null) {
+                     extraDescriptions.put("Request URI", uri);
+                }
+
+                // Do not show exception stack trace when log level is WARN or above. Show only message.
+                if (!getLogger().isInfoEnabled()) {
+                    Throwable t = DefaultNotifyingBuilder.getRootCause(e);
+                    if (t != null) extraDescriptions.put(Notifying.EXTRA_CAUSE, t.getMessage());
+                    e = null;
+                }
+            }
+
+            Notifying n = new DefaultNotifyingBuilder().build(this,
+                                                              e,
+                                                              type,
+                                                              title,
+                                                              "Cocoon Servlet",
+                                                              message,
+                                                              description,
+                                                              extraDescriptions);
+
+            res.setContentType("text/html");
+            res.setStatus(errorStatus);
+            Notifier.notify(n, res.getOutputStream(), "text/html");
+        } else {
+            res.sendError(errorStatus, title);
+            res.flushBuffer();
+        }
+    }
+
+    /**
+     * Create the environment for the request
+     */
+    protected Environment getEnvironment(String uri,
+                                         HttpServletRequest req,
+                                         HttpServletResponse res)
+    throws Exception {
+        HttpEnvironment env;
+
+        String formEncoding = req.getParameter("cocoon-form-encoding");
+        if (formEncoding == null) {
+            formEncoding = this.core.getSettings().getFormEncoding();
+        }
+        env = new HttpEnvironment(uri,
+                                  null,
+                                  req,
+                                  res,
+                                  null,
+                                  this.core.getEnvironmentContext(),
+                                  this.containerEncoding,
+                                  formEncoding);
+        env.enableLogging(getLogger());
+        return env;
+    }
+
+    private String processTime(long time) {
+        StringBuffer out = new StringBuffer(PROCESSED_BY);
+        if (time <= SECOND) {
+            out.append(time);
+            out.append(" milliseconds.");
+        } else if (time <= MINUTE) {
+            out.append(time / SECOND);
+            out.append(" seconds.");
+        } else if (time <= HOUR) {
+            out.append(time / MINUTE);
+            out.append(" minutes.");
+        } else {
+            out.append(time / HOUR);
+            out.append(" hours.");
+        }
+        return out.toString();
+    }
+
+    /**
+     * Get an initialisation parameter. The value is trimmed, and null is returned if the trimmed value
+     * is empty.
+     */
+    public String getInitParameter(String name) {
+        String result = super.getInitParameter(name);
+        if (result != null) {
+            result = result.trim();
+            if (result.length() == 0) {
+                result = null;
+            }
+        }
+
+        return result;
+    }
+
+    /** Convenience method to access servlet parameters */
+    protected String getInitParameter(String name, String defaultValue) {
+        String result = getInitParameter(name);
+        if (result == null) {
+            if (getLogger() != null && getLogger().isDebugEnabled()) {
+                getLogger().debug(name + " was not set - defaulting to '" + defaultValue + "'");
+            }
+            return defaultValue;
+        }
+        return result;
+    }
+
+    protected Logger getLogger() {
+        return this.log;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/resources/dev/i18n/convert.xsl b/non-releases/trunk_before_flattening/src/resources/dev/i18n/convert.xsl
new file mode 100644
index 0000000..637734a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/dev/i18n/convert.xsl
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output indent="yes" method="xml"/>
+
+<!-- specify here the language of the catalogue you would like to create -->
+<xsl:param name="lang">hy</xsl:param>
+
+<xsl:template match="translations">
+	<catalogue xml:lang="{$lang}">
+		<xsl:apply-templates select="entry"/>
+	</catalogue>
+</xsl:template>
+
+<xsl:template match="entry">
+	<message key="{key}">
+		<xsl:value-of select="translation[@lang=$lang]"/>
+	</message>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/resources/dev/i18n/markup2messages.xsl b/non-releases/trunk_before_flattening/src/resources/dev/i18n/markup2messages.xsl
new file mode 100644
index 0000000..14873a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/dev/i18n/markup2messages.xsl
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
+exclude-result-prefixes="i18n">
+
+<xsl:output method="xml" indent="yes" />
+
+<xsl:param name="target-locale">en</xsl:param>
+
+<xsl:template match="/">
+    <catalogue>
+        <xsl:attribute name="xml:lang"><xsl:value-of select="$target-locale" /></xsl:attribute>
+        <xsl:apply-templates select="//i18n:text | //@i18n:attr"/>
+    </catalogue>
+</xsl:template>
+
+<!-- i18n:text element processing -->
+<xsl:template match="i18n:text">
+    <xsl:call-template name="create-entry">
+        <xsl:with-param name="key-value">
+            <xsl:choose>
+                <xsl:when test="@key"><xsl:value-of select="@key"/></xsl:when>
+                <xsl:otherwise><xsl:value-of select="text()" /></xsl:otherwise>
+            </xsl:choose>
+        </xsl:with-param>        
+    </xsl:call-template>
+</xsl:template>
+
+<!-- i18n:attr attribute processing -->
+<xsl:template match="@i18n:attr">
+    <xsl:call-template name="process-attributes">
+        <xsl:with-param name="attr-list" select="." />
+    </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="process-attributes">
+    <xsl:param name="attr-list" />
+    <xsl:variable name="attr-nlist" select="concat(normalize-space($attr-list), ' ')" />
+    <xsl:variable name="first" select="substring-before($attr-nlist, ' ')" />
+    <xsl:variable name="rest" select="substring-after($attr-nlist, ' ')" />        
+    <xsl:variable name="key-value" select="../@*[name()=$first][1]" />
+    <xsl:call-template name="create-entry">
+        <xsl:with-param name="key-value" select="$key-value" />
+    </xsl:call-template>
+    <xsl:if test="$rest">
+        <xsl:call-template name="process-attributes">
+            <xsl:with-param name="attr-list" select="$rest" />
+        </xsl:call-template>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template name="create-entry">
+    <xsl:param name="key-value" />
+    <message key="{$key-value}"><xsl:value-of select="$key-value" /></message>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/resources/dev/i18n/merge.xsl b/non-releases/trunk_before_flattening/src/resources/dev/i18n/merge.xsl
new file mode 100644
index 0000000..d8d20eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/dev/i18n/merge.xsl
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output indent="yes" method="xml" />
+<!--
+	Usage patterns.
+	******************
+	1. Key generation mode is used to generate a dictionary file 
+	from the existing containing only keys, empty translation nodes
+	with lang attribute equal to $new-lang and, optionaly, translation 
+	for another language - for convenience.
+	Example: $mode = keys, $new-lang=fr, $keep-lang=en
+	Result will be a dictionary template for French.
+	
+	2. Merging translations is useful when you need to add or update 
+	translations for a new or existing language. You have to create a 
+	translations file with new values and set $new-dict param.
+	
+	3. To add a new language you will need to generate a template with
+	keys, translate them, then merge with the existing dictionary.
+-->
+
+
+<!-- Modes: 
+		keys - generates a template with keys for the given language
+		merge - adds/updates translations from the given file
+-->
+<xsl:param name="mode">merge</xsl:param>
+<!-- The language to be added or used in keys mode -->
+<xsl:param name="new-lang">de</xsl:param>
+<!-- Translations for this language will be kept during key generation -->
+<xsl:param name="keep-lang"></xsl:param>
+<!-- New translations' file name - format is the same as for the dictionary -->
+<xsl:param name="new-dict">simple_dict_de.xml</xsl:param>
+
+<xsl:template match="translations">
+	<xsl:copy>
+		<xsl:choose>
+			<xsl:when test="$mode='keys'">
+				<xsl:apply-templates mode="keys" />
+			</xsl:when>
+			<xsl:otherwise>	
+				<xsl:apply-templates />
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="entry" mode="keys">
+	<xsl:copy>
+		<xsl:apply-templates select="key | translation[@lang=$keep-lang]" />
+		<translation lang="{$new-lang}">[translate]</translation>
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="entry" >
+	<xsl:copy>
+		<xsl:apply-templates />
+		<xsl:if test="not(translation[@lang=$new-lang])">	
+			<xsl:variable name="key" select="key/text()" />
+			<xsl:variable name="value" select="document($new-dict)/translations/entry[key=$key]/translation[@lang=$new-lang]" />
+			<translation lang="{$new-lang}"><xsl:value-of select="normalize-space($value)" /></translation>
+		</xsl:if>
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="translation[@lang=$new-lang]" >
+	<xsl:variable name="key" select="../key/text()" />
+	<xsl:variable name="value" select="document($new-dict)/translations/entry[key=$key]/translation[@lang=$new-lang]" />	
+	<xsl:copy>
+		<xsl:apply-templates select="@*"/>
+		<xsl:value-of select="normalize-space($value)" />
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="@* | * | text() | processing-instruction() | comment()" priority="-1" mode="keys">
+	<xsl:copy>
+     	<xsl:apply-templates select="@* | * | text() | processing-instruction() | comment()"/>
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="@* | * | text() | processing-instruction() | comment()" priority="-1">
+	<xsl:copy>
+     	<xsl:apply-templates select="@* | * | text() | processing-instruction() | comment()"/>
+	</xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/non-releases/trunk_before_flattening/src/resources/dev/i18n/simple_dict.xml b/non-releases/trunk_before_flattening/src/resources/dev/i18n/simple_dict.xml
new file mode 100644
index 0000000..0a1287d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/dev/i18n/simple_dict.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<translations>
+	<!-- 
+	Languages:
+		en - English
+		ru - Russian
+		de - German (thanks to Jörg Prante)
+		pl - Polish (thanks to Krzysztof Zieliński)
+		es - Spanish
+		hy - Armenian.
+-->
+	<!-- Language links -->
+	<entry>
+		<key>count_title</key>
+		<translation lang="en">This page was accessed {0} times. Last at: {1}.</translation>
+		<translation lang="ru">На эту страницу заходили {0} раз(а). В последний раз {1}.</translation>
+		<translation lang="de">Diese Seite wurde {0}mal aufgerufen. Letzter Aufruf: {1}.</translation>
+		<translation lang="pl">Ta strona była pobierana {0} razy. Ostatnio {1}</translation>
+		<translation lang="es">Esta página fue tenida acceso {0} veces. Pasado en: {1}.</translation>
+		<translation lang="hy">²Ûë ¿çÁ ³Ûó»É»É »Ý {0} ³Ý·³Ù. ì»ñçÇÝÁ {1}.</translation>
+	</entry>
+	<entry>
+		<key>a_key</key>
+		<translation lang="en">This is a key value.</translation>
+		<translation lang="ru">Это значение по ключу.</translation>
+		<translation lang="de">Dies ist der Wert eines Schlüssels.</translation>
+		<translation lang="pl">To jest klucz.</translation>
+		<translation lang="es">Esto es un valor clave.</translation>
+		<translation lang="hy">ê³ µ³Ý³ÉÇÇ ³éÅ»ùÝ ¿£</translation>
+	</entry>
+	<entry>
+		<key>lang_id1</key>
+		<translation lang="en">ru</translation>
+		<translation lang="ru">en</translation>
+		<translation lang="de">en</translation>
+		<translation lang="pl">en</translation>
+		<translation lang="es">en</translation>
+		<translation lang="hy">en</translation>
+	</entry>
+	<entry>
+		<key>lang_id2</key>
+		<translation lang="en">de</translation>
+		<translation lang="ru">de</translation>
+		<translation lang="de">ru</translation>
+		<translation lang="pl">ru</translation>
+		<translation lang="es">ru</translation>
+		<translation lang="hy">ru</translation>
+	</entry>
+	<entry>
+		<key>lang_id3</key>
+		<translation lang="en">pl</translation>
+		<translation lang="ru">pl</translation>
+		<translation lang="de">pl</translation>
+		<translation lang="pl">de</translation>
+		<translation lang="es">de</translation>
+		<translation lang="hy">de</translation>
+	</entry>
+	<entry>
+		<key>lang_id4</key>
+		<translation lang="en">es</translation>
+		<translation lang="ru">es</translation>
+		<translation lang="de">es</translation>
+		<translation lang="pl">es</translation>
+		<translation lang="es">pl</translation>
+		<translation lang="hy">pl</translation>
+	</entry>
+	<entry>
+		<key>lang_id5</key>
+		<translation lang="en">hy</translation>
+		<translation lang="ru">hy</translation>
+		<translation lang="de">hy</translation>
+		<translation lang="pl">hy</translation>
+		<translation lang="es">hy</translation>
+		<translation lang="hy">es</translation>
+	</entry>
+	<!-- current language -->
+	<entry>
+		<key>language</key>
+		<translation lang="en">English</translation>
+		<translation lang="ru">Русский</translation>
+		<translation lang="de">Deutsch</translation>
+		<translation lang="pl">Polski</translation>
+		<translation lang="es">Español</translation>
+		<translation lang="hy">гۻñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>language1</key>
+		<translation lang="en">Russian</translation>
+		<translation lang="ru">Английский</translation>
+		<translation lang="de">Englische</translation>
+		<translation lang="pl">Angielski</translation>
+		<translation lang="es">Inglés</translation>
+		<translation lang="hy">²Ý·É»ñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>language2</key>
+		<translation lang="en">German</translation>
+		<translation lang="ru">Немецкий</translation>
+		<translation lang="de">Russe</translation>
+		<translation lang="pl">Rosyjski</translation>
+		<translation lang="es">Ruso</translation>
+		<translation lang="hy">èáõë»ñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>language3</key>
+		<translation lang="en">Polish</translation>
+		<translation lang="ru">Польский</translation>
+		<translation lang="de">Polnisch</translation>
+		<translation lang="pl">Niemiecki</translation>
+		<translation lang="es">Alemán</translation>
+		<translation lang="hy">¶»ñٳݻñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>language4</key>
+		<translation lang="en">Spanish</translation>
+		<translation lang="ru">Испанский</translation>
+		<translation lang="de">Spanisch</translation>
+		<translation lang="pl">Hiszpañski</translation>
+		<translation lang="es">Polaco</translation>
+		<translation lang="hy">Ȼѻñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>language5</key>
+		<translation lang="en">Armenian</translation>
+		<translation lang="ru">Армянский</translation>
+		<translation lang="de">Armenier</translation>
+		<translation lang="pl">Armeñski</translation>
+		<translation lang="es">Armenio</translation>
+		<translation lang="hy">Æëå³Ý»ñ»Ý</translation>
+	</entry>
+	<entry>
+		<key>Hello, internationalization!</key>
+		<translation lang="en">Hello, internationalization!</translation>
+		<translation lang="ru">Привет, многоязычность!</translation>
+		<translation lang="de">Herzlich willkommen, Internationalisierung!</translation>
+		<translation lang="pl">Witam, oto przykład wielojęzycznej strony!</translation>
+		<translation lang="es">¡¡Hola!, internacionalización!</translation>
+		<translation lang="hy">´³ñ¢°, ÇÝï»ñݳóÛáݳÉáõÃÛáõÝ£</translation>
+	</entry>
+	<entry>
+		<key>Documentation link:</key>
+		<translation lang="en">See i18n documentation for details:</translation>
+		<translation lang="ru">Для дополнительной информации по i18n смотри:</translation>
+		<translation lang="de">Näheres unter der i18n Dokumentation:</translation>
+		<translation lang="pl">Widzą i18n dokumentacja dla szczegółów:</translation>
+		<translation lang="es">Visto la documentación i18n para detalles:</translation>
+		<translation lang="hy">سÝñ³Ù³ë µ³ó³ïñáõÃÛ³Ý Ñ³Ù³ñ ݳÇñª</translation>
+	</entry>
+	<entry>
+		<key>first</key>
+		<translation lang="en">First</translation>
+		<translation lang="ru">Первый</translation>
+		<translation lang="de">Erstens</translation>
+		<translation lang="pl">Pierwszy</translation>
+		<translation lang="es">Primero</translation>
+		<translation lang="hy">²é³çÇÝ</translation>
+	</entry>
+	<entry>
+		<key>second</key>
+		<translation lang="en">Second</translation>
+		<translation lang="ru">Второй</translation>
+		<translation lang="de">Zweitens</translation>
+		<translation lang="pl">Drugi</translation>
+		<translation lang="es">Segundo</translation>
+		<translation lang="hy">ºñÏñáñ¹</translation>
+	</entry>
+	<entry>
+		<key>third</key>
+		<translation lang="en">Third</translation>
+		<translation lang="ru">Третий</translation>
+		<translation lang="de">Drittens</translation>
+		<translation lang="pl">Trzeci</translation>
+		<translation lang="es">Tercio</translation>
+		<translation lang="hy">ºññáñ¹</translation>
+	</entry>
+	<entry>
+		<key>forth</key>
+		<translation lang="en">Forth</translation>
+		<translation lang="ru">Четвертый</translation>
+		<translation lang="de">Viertens</translation>
+		<translation lang="pl">Czwarty</translation>
+		<translation lang="es">En adelante</translation>
+		<translation lang="hy">¼áñáñ¹</translation>
+	</entry>
+	<entry>
+		<key>article</key>
+		<translation lang="en">Article</translation>
+		<translation lang="ru">Статья</translation>
+		<translation lang="de">Artikel</translation>
+		<translation lang="pl">Artykuł</translation>
+		<translation lang="es">Artículo</translation>
+		<translation lang="hy">Ðá¹í³Í</translation>
+	</entry>
+	<entry>
+		<key>article_text1</key>
+		<translation lang="en">This is a i18n paragraph.</translation>
+		<translation lang="ru">Это интернационализированный абзац.</translation>
+		<translation lang="de">Dies ist ein Absatz nach i18n.</translation>
+		<translation lang="pl">To jest paragraf w i18n.</translation>
+		<translation lang="es">Esto es un párrafo i18n.</translation>
+		<translation lang="hy">ê³ ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿£</translation>
+	</entry>
+	<entry>
+		<key>article_text2</key>
+		<translation lang="en">This is another i18n paragraph and is also a cool one.</translation>
+		<translation lang="ru">Это тоже интернационализированный абзац и такой же классный.</translation>
+		<translation lang="de">Dies ist ein weiterer Absatz nach i18n und auch noch ein ziemlich cooler dazu.</translation>
+		<translation lang="pl">To jest następny paragraf w i18n i jest takze fajny.</translation>
+		<translation lang="es">Esto es otro párrafo i18n y es también uno 'cool'.</translation>
+		<translation lang="hy">ê³ ÙÇ áõñÇß ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿, ¢ ÝáõÛÝ å»ë ó»Ýïñ£</translation>
+	</entry>
+	<entry>
+		<key>copyright</key>
+		<translation lang="en">Copyright © 2001 Konstantin Piroumian. No rights are reserved.</translation>
+		<translation lang="ru">Авторские права © 2001 Константин Пирумян. Ничто не защищено.</translation>
+		<translation lang="de">Copyright © 2001 Konstantin Piroumian. Deutsche Übersetzung von Jörg Prante.</translation>
+		<translation lang="pl">Copyright © 2001 Konstantin Piroumian i Krzysztof Zieliński. Żadne prawa nie są zastrzeżone:)</translation>
+		<translation lang="es">Copyright © 2001 Konstantin Piroumian. Ningunos derechos son reservados.</translation>
+		<translation lang="hy">Copyright © 2001 Konstantin Piroumian. àãÇÝã ãÇ å³Ñå³Ýí³Í£</translation>
+	</entry>
+	<entry>
+		<key>Hello, {0}! Glad to see you!</key>
+		<translation lang="en">Hello, {0}! Glad to see you!</translation>
+		<translation lang="ru">Привет, {0}! Рад тебя видеть!</translation>
+		<translation lang="de">Hallo {0}! Schön, dich zu sehen!</translation>
+		<translation lang="pl">Witam, {0}! Miło Cię widzieć!</translation>
+		<translation lang="es">¡¡Hola!, {0}! ¡Alegre de verle!</translation>
+		<translation lang="hy">´³ñ¢¯ {0}: àõñ³Ë »Ù ù»½ ï»ëݻɣ</translation>
+	</entry>
+	<entry>
+		<key>Kot</key>
+		<translation lang="en">Tomcat</translation>
+		<translation lang="ru">Кот</translation>
+		<translation lang="de">Tomcat</translation>
+		<translation lang="pl">Tomcat</translation>
+		<translation lang="es">Gato</translation>
+		<translation lang="hy">γïáõ</translation>
+	</entry>
+	<entry>
+		<key>none</key>
+		<translation lang="en">None</translation>
+		<translation lang="ru">Никто</translation>
+		<translation lang="de">nichts</translation>
+		<translation lang="pl">Nic</translation>
+		<translation lang="es">Ninguno</translation>
+		<translation lang="hy">àã áù</translation>
+	</entry>
+	<entry>
+		<key>one</key>
+		<translation lang="en">one</translation>
+		<translation lang="ru">раз</translation>
+		<translation lang="de">eins</translation>
+		<translation lang="pl">raz</translation>
+		<translation lang="es">un</translation>
+		<translation lang="hy">Ù»Ï</translation>
+	</entry>
+	<entry>
+		<key>two</key>
+		<translation lang="en">two</translation>
+		<translation lang="ru">два</translation>
+		<translation lang="de">zwei</translation>
+		<translation lang="pl">dwa</translation>
+		<translation lang="es">dos</translation>
+		<translation lang="hy">»ñÏáõë</translation>
+	</entry>
+</translations>
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-excalibur/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-excalibur/package-list
new file mode 100644
index 0000000..3540c9d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-excalibur/package-list
@@ -0,0 +1,68 @@
+org.apache.avalon.examples.jdbcdatasource
+org.apache.avalon.excalibur.component
+org.apache.avalon.excalibur.component.example_im
+org.apache.avalon.excalibur.component.servlet
+org.apache.avalon.excalibur.datasource
+org.apache.avalon.excalibur.datasource.cluster
+org.apache.avalon.excalibur.datasource.ids
+org.apache.avalon.excalibur.logger
+org.apache.avalon.excalibur.logger.decorator
+org.apache.avalon.excalibur.logger.factory
+org.apache.avalon.excalibur.logger.log4j
+org.apache.avalon.excalibur.logger.logkit
+org.apache.avalon.excalibur.logger.util
+org.apache.avalon.excalibur.monitor
+org.apache.avalon.excalibur.monitor.impl
+org.apache.avalon.excalibur.pool
+org.apache.avalon.excalibur.testcase
+org.apache.avalon.excalibur.thread.impl
+org.apache.avalon.fortress
+org.apache.avalon.fortress.examples.components
+org.apache.avalon.fortress.examples.extended
+org.apache.avalon.fortress.examples.extended.components
+org.apache.avalon.fortress.examples.extended.extensions
+org.apache.avalon.fortress.examples.servlet
+org.apache.avalon.fortress.examples.swing
+org.apache.avalon.fortress.examples.viewer
+org.apache.avalon.fortress.impl
+org.apache.avalon.fortress.impl.extensions
+org.apache.avalon.fortress.impl.factory
+org.apache.avalon.fortress.impl.handler
+org.apache.avalon.fortress.impl.lookup
+org.apache.avalon.fortress.impl.role
+org.apache.avalon.fortress.migration
+org.apache.avalon.fortress.testcase
+org.apache.avalon.fortress.tools
+org.apache.avalon.fortress.util
+org.apache.avalon.fortress.util.dag
+org.apache.avalon.lifecycle
+org.apache.excalibur.configuration
+org.apache.excalibur.configuration.merged
+org.apache.excalibur.configuration.validation
+org.apache.excalibur.event
+org.apache.excalibur.event.command
+org.apache.excalibur.event.impl
+org.apache.excalibur.instrument
+org.apache.excalibur.instrument.client
+org.apache.excalibur.instrument.manager
+org.apache.excalibur.instrument.manager.altrmi
+org.apache.excalibur.instrument.manager.http
+org.apache.excalibur.instrument.manager.http.server
+org.apache.excalibur.instrument.manager.interfaces
+org.apache.excalibur.mpool
+org.apache.excalibur.source
+org.apache.excalibur.source.impl
+org.apache.excalibur.source.impl.validity
+org.apache.excalibur.store
+org.apache.excalibur.store.impl
+org.apache.excalibur.thread
+org.apache.excalibur.thread.impl
+org.apache.excalibur.util
+org.apache.excalibur.util.system
+org.apache.excalibur.xml
+org.apache.excalibur.xml.dom
+org.apache.excalibur.xml.impl
+org.apache.excalibur.xml.sax
+org.apache.excalibur.xml.xpath
+org.apache.excalibur.xml.xslt
+org.apache.excalibur.xmlizer
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-framework/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-framework/package-list
new file mode 100644
index 0000000..689125b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-framework/package-list
@@ -0,0 +1,10 @@
+org.apache.avalon.framework
+org.apache.avalon.framework.activity
+org.apache.avalon.framework.component
+org.apache.avalon.framework.configuration
+org.apache.avalon.framework.container
+org.apache.avalon.framework.context
+org.apache.avalon.framework.logger
+org.apache.avalon.framework.parameters
+org.apache.avalon.framework.service
+org.apache.avalon.framework.thread
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-logkit/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-logkit/package-list
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/avalon-logkit/package-list
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/j2ee/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/j2ee/package-list
new file mode 100644
index 0000000..f03aab8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/j2ee/package-list
@@ -0,0 +1,32 @@
+javax.activation
+javax.ejb
+javax.ejb.spi
+javax.jms
+javax.mail
+javax.mail.event
+javax.mail.internet
+javax.mail.search
+javax.resource
+javax.resource.cci
+javax.resource.spi
+javax.resource.spi.security
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.login
+javax.security.auth.spi
+javax.servlet
+javax.servlet.http
+javax.servlet.jsp
+javax.servlet.jsp.tagext
+javax.sql
+javax.transaction
+javax.transaction.xa
+javax.xml.parsers
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stream
+org.w3c.dom
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/j2se/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/j2se/package-list
new file mode 100644
index 0000000..fecd4d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/j2se/package-list
@@ -0,0 +1,135 @@
+java.applet
+java.awt
+java.awt.color
+java.awt.datatransfer
+java.awt.dnd
+java.awt.event
+java.awt.font
+java.awt.geom
+java.awt.im
+java.awt.im.spi
+java.awt.image
+java.awt.image.renderable
+java.awt.print
+java.beans
+java.beans.beancontext
+java.io
+java.lang
+java.lang.ref
+java.lang.reflect
+java.math
+java.net
+java.nio
+java.nio.channels
+java.nio.channels.spi
+java.nio.charset
+java.nio.charset.spi
+java.rmi
+java.rmi.activation
+java.rmi.dgc
+java.rmi.registry
+java.rmi.server
+java.security
+java.security.acl
+java.security.cert
+java.security.interfaces
+java.security.spec
+java.sql
+java.text
+java.util
+java.util.jar
+java.util.logging
+java.util.prefs
+java.util.regex
+java.util.zip
+javax.accessibility
+javax.crypto
+javax.crypto.interfaces
+javax.crypto.spec
+javax.imageio
+javax.imageio.event
+javax.imageio.metadata
+javax.imageio.plugins.jpeg
+javax.imageio.spi
+javax.imageio.stream
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+javax.net
+javax.net.ssl
+javax.print
+javax.print.attribute
+javax.print.attribute.standard
+javax.print.event
+javax.rmi
+javax.rmi.CORBA
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.kerberos
+javax.security.auth.login
+javax.security.auth.spi
+javax.security.auth.x500
+javax.security.cert
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.sql
+javax.swing
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.metal
+javax.swing.plaf.multi
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.tree
+javax.swing.undo
+javax.transaction
+javax.transaction.xa
+javax.xml.parsers
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stream
+org.ietf.jgss
+org.omg.CORBA
+org.omg.CORBA.DynAnyPackage
+org.omg.CORBA.ORBPackage
+org.omg.CORBA.TypeCodePackage
+org.omg.CORBA.portable
+org.omg.CORBA_2_3
+org.omg.CORBA_2_3.portable
+org.omg.CosNaming
+org.omg.CosNaming.NamingContextExtPackage
+org.omg.CosNaming.NamingContextPackage
+org.omg.Dynamic
+org.omg.DynamicAny
+org.omg.DynamicAny.DynAnyFactoryPackage
+org.omg.DynamicAny.DynAnyPackage
+org.omg.IOP
+org.omg.IOP.CodecFactoryPackage
+org.omg.IOP.CodecPackage
+org.omg.Messaging
+org.omg.PortableInterceptor
+org.omg.PortableInterceptor.ORBInitInfoPackage
+org.omg.PortableServer
+org.omg.PortableServer.CurrentPackage
+org.omg.PortableServer.POAManagerPackage
+org.omg.PortableServer.POAPackage
+org.omg.PortableServer.ServantLocatorPackage
+org.omg.PortableServer.portable
+org.omg.SendingContext
+org.omg.stub.java.rmi
+org.w3c.dom
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.css b/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.css
new file mode 100644
index 0000000..f78f736
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.css
@@ -0,0 +1,52 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+/* Apache Javadoc style sheet */
+
+/* Page background color */
+body { background-color: #FFFFFF; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 12px }
+
+/* Links */
+a:link    { color: #0F3660 }
+a:visited { color: #008800 }
+a:active  { font-weight: bold }
+a:hover   { color: #880000; }
+
+/* Fix HTML markup */
+h2 { font-size: 20px }
+table { font-size: 12px }
+.NavBarCell1 font b { font-size: 12px }
+.NavBarCell2 font b { font-size: 10px }
+.NavBarCell3 font b { font-size: 12px }
+font b { font-size: 18px; }
+
+/* Table colors */
+.TableHeadingColor     { background: #E0E0E0; }
+.TableSubHeadingColor  { background: #F0F0F0; }
+.TableRowColor         { background: #F9F9F9; }
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color:#D0D0D0;}
+.NavBarCell1Rev { background-color:#A0A0A0;}
+.NavBarFont1    { font-size: 12px; }
+.NavBarFont1Rev { font-size: 12px; }
+.NavBarCell2    { background-color:#E0E0E0;}
+.NavBarCell3    { background-color:#F0F0F0;}
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: 10px; }
+.FrameHeadingFont { font-size: 16px; font-weight: bold; }
+.FrameItemFont    { font-size: 12px; }
+ 
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.xwelcome b/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.xwelcome
new file mode 100644
index 0000000..7ccde00
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/javadoc.xwelcome
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xwelcome xpath="/welcome" unless="message[@id='javadocs']">
+
+  <message id="javadocs">
+   Here you find the <link href="api/java/index.html">Java API documentation</link> of the Cocoon internals.
+  </message>
+  
+</xwelcome>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/jstl/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/jstl/package-list
new file mode 100644
index 0000000..0074b24
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/jstl/package-list
@@ -0,0 +1 @@
+javax.servlet.jsp.jstl.core
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/xalan/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/xalan/package-list
new file mode 100644
index 0000000..5e436af
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/xalan/package-list
@@ -0,0 +1,57 @@
+javax.xml.parsers
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stream
+org.apache.xalan
+org.apache.xalan.client
+org.apache.xalan.extensions
+org.apache.xalan.lib
+org.apache.xalan.lib.sql
+org.apache.xalan.processor
+org.apache.xalan.res
+org.apache.xalan.serialize
+org.apache.xalan.templates
+org.apache.xalan.trace
+org.apache.xalan.transformer
+org.apache.xalan.xslt
+org.apache.xalan.xsltc
+org.apache.xalan.xsltc.cmdline
+org.apache.xalan.xsltc.cmdline.getopt
+org.apache.xalan.xsltc.compiler
+org.apache.xalan.xsltc.compiler.util
+org.apache.xalan.xsltc.dom
+org.apache.xalan.xsltc.runtime
+org.apache.xalan.xsltc.runtime.output
+org.apache.xalan.xsltc.trax
+org.apache.xalan.xsltc.util
+org.apache.xml.dtm
+org.apache.xml.dtm.ref
+org.apache.xml.dtm.ref.dom2dtm
+org.apache.xml.dtm.ref.sax2dtm
+org.apache.xml.utils
+org.apache.xml.utils.res
+org.apache.xml.utils.synthetic
+org.apache.xml.utils.synthetic.reflection
+org.apache.xmlcommons
+org.apache.xpath
+org.apache.xpath.axes
+org.apache.xpath.compiler
+org.apache.xpath.domapi
+org.apache.xpath.functions
+org.apache.xpath.objects
+org.apache.xpath.operations
+org.apache.xpath.patterns
+org.apache.xpath.res
+org.w3c.dom
+org.w3c.dom.css
+org.w3c.dom.events
+org.w3c.dom.html
+org.w3c.dom.ranges
+org.w3c.dom.stylesheets
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.w3c.dom.xpath
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
diff --git a/non-releases/trunk_before_flattening/src/resources/javadoc/xerces/package-list b/non-releases/trunk_before_flattening/src/resources/javadoc/xerces/package-list
new file mode 100644
index 0000000..c58a63c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/resources/javadoc/xerces/package-list
@@ -0,0 +1,13 @@
+javax.xml.parsers
+org.w3c.dom
+org.w3c.dom.css
+org.w3c.dom.events
+org.w3c.dom.html
+org.w3c.dom.ls
+org.w3c.dom.ranges
+org.w3c.dom.stylesheets
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/SampleRequestListener.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/SampleRequestListener.java
new file mode 100644
index 0000000..697e57a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/SampleRequestListener.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+
+/**
+ * This is called from with {@link Cocoon#process(Environment)}, before any
+ * requests are passed onto the {@link Processor} and after the request has been
+ * processed. It allows all requests to be logged or monitored.
+ * NB Cocoon does not require an instance of this Component to function, but if
+ * there is one it will be used.
+ */
+public class SampleRequestListener extends AbstractLogEnabled implements RequestListener {
+
+    /** 
+     * <p>In this method you can call, for example:
+     * <code>Request req=ObjectModelHelper.getRequest(env.getObjectModel());</code>
+     * And then, you could use the following:
+     * <ul>
+     * <li>req.getRequestURI()</li>
+     * <li>req.getQueryString()</li>
+     * <li>req.getSession().getId()</li>
+     * <li>req.getLocale().getLanguage().toString()</li>
+     * </ul>
+     * <p>
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     */
+    public void onRequestStart(Environment environment){
+        Request req = ObjectModelHelper.getRequest(environment.getObjectModel());
+        getLogger().info(req.getRequestURI() + " started");
+    }
+
+    /** 
+     * <p>This method is called when a request has completed. This method is called before the
+     * response is committed.
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     */
+    public void onRequestEnd(Environment environment) {
+        Request req = ObjectModelHelper.getRequest(environment.getObjectModel());
+        getLogger().info(req.getRequestURI() + " ended");
+    }
+    /** 
+     * <p>This method is called when an exception has occurred processing the request.
+     * @param environment as supplied to {@link Processor#process(Environment)}
+     *                    from within {@link Cocoon#process(Environment)}.
+     * @param throwable the error that occurred processing the request.
+     */
+    public void onRequestException(Environment environment, Throwable throwable) {
+        Request req = ObjectModelHelper.getRequest(environment.getObjectModel());
+        getLogger().info(req.getRequestURI() + " failed with " + throwable.getMessage());
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/acting/modular/TestAction.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/acting/modular/TestAction.java
new file mode 100644
index 0000000..a2d8803
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/acting/modular/TestAction.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting.modular;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.acting.ServiceableAction;
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.components.modules.output.OutputModule;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/** Demo action that uses componentized input / output layer. In order
+ * to stop combinatorial explosion of actions, matchers, and selectors
+ * they should instead use components to access their inputs and
+ * outputs. Available components include request parameters,
+ * attributes, headers, and session attributes. Which component to use
+ * can be specified upon setup via "input-module" and
+ * "output-module" tags through the name attribute.
+ *
+ * This particular action copies all available parameters obtained
+ * from the input component to the output component or, if a specific
+ * parameter is specified through parameter-name, just one parameter.
+ *
+ * @version $Id$
+ */
+public class TestAction extends ServiceableAction 
+    implements Configurable, ThreadSafe {
+
+    String INPUT_MODULE_ROLE = InputModule.ROLE;
+    String OUTPUT_MODULE_ROLE = OutputModule.ROLE;
+    String INPUT_MODULE_SELECTOR = INPUT_MODULE_ROLE+"Selector";
+    String OUTPUT_MODULE_SELECTOR = OUTPUT_MODULE_ROLE+"Selector";
+
+    Configuration inputConf = null;
+    Configuration outputConf = null;
+    String inputName = null;
+    String outputName = null;
+    String defaultParameterName = null;
+    boolean useGetValues = false;
+
+    String inputHint = "request-param"; // default to request parameters
+    String outputHint = "request-attr"; // default to request attributes
+
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration config) throws ConfigurationException {
+
+        this.inputConf  = config.getChild("input-module");
+        this.inputName  = this.inputConf.getAttribute("name", this.inputHint);
+        this.outputConf = config.getChild("output-module");
+        this.outputName = this.outputConf.getAttribute("name", this.outputHint);
+        this.defaultParameterName = config.getChild("parameter-name").getValue(null);
+        this.useGetValues = config.getChild("use-getValues").getValueAsBoolean(this.useGetValues);
+    }
+
+
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.acting.Action#act(org.apache.cocoon.environment.Redirector, org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map act( Redirector redirector, SourceResolver resolver, Map objectModel, 
+                    String source, Parameters param ) throws Exception {
+
+        // general setup
+        String parameterName = param.getParameter("parameter-name",this.defaultParameterName);
+        boolean useGetValues = param.getParameterAsBoolean("use-getValues",this.useGetValues);
+        InputModule input = null;
+        OutputModule output = null;
+        ServiceSelector inputSelector = null;
+        ServiceSelector outputSelector = null;
+
+        try {
+            if (getLogger().isDebugEnabled()) getLogger().debug("start...");
+            // obtain input and output components
+            inputSelector=(ServiceSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); 
+            if (inputName != null && inputSelector != null && inputSelector.isSelectable(inputName)){
+                input = (InputModule) inputSelector.select(inputName);
+            }
+            outputSelector=(ServiceSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); 
+            if (outputName != null && outputSelector != null && outputSelector.isSelectable(outputName)){
+                output = (OutputModule) outputSelector.select(outputName);
+            }
+
+
+            if (input != null  && output != null) {
+                if (getLogger().isDebugEnabled()) getLogger().debug("got input and output modules");
+                // do something
+
+                if (parameterName == null) {
+                    if (getLogger().isDebugEnabled()) getLogger().debug("reading all parameter values");
+                    // for a test, read all parameters from input and write them to outout
+                    // get names first, then (one) value per name
+                    Iterator iter = input.getAttributeNames(this.inputConf,objectModel);
+                    while (iter.hasNext()) {
+                        parameterName = (String) iter.next();
+                        Object value = input.getAttribute(parameterName, this.inputConf, objectModel);
+                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
+                        
+                        if (getLogger().isDebugEnabled()) 
+                            getLogger().debug("["+parameterName+"] = ["+value+"]");
+                    }
+                        // ------------------------------------------------------------------------
+                } else {
+
+                    if (useGetValues) {
+                        // get all existing values
+                        Object[] value = input.getAttributeValues(parameterName, this.inputConf, objectModel);
+                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
+                        
+                        if (getLogger().isDebugEnabled()) 
+                            for (int i=0; i<value.length; i++)
+                                getLogger().debug("["+parameterName+"["+i+"]] = ["+value[i]+"]");
+                        // ------------------------------------------------------------------------
+
+                    } else {
+                        // get just one parameter value
+                        if (getLogger().isDebugEnabled()) 
+                            getLogger().debug("reading parameter values for "+parameterName);
+                        
+                        Object value = input.getAttribute(parameterName, this.inputConf, objectModel);
+                        output.setAttribute(this.outputConf, objectModel, parameterName, value);
+                        
+                        if (getLogger().isDebugEnabled()) getLogger().debug("["+parameterName+"] = ["+value+"]");
+                        // ------------------------------------------------------------------------
+                    }
+                }
+                output.commit(this.outputConf,objectModel);
+                if (getLogger().isDebugEnabled()) getLogger().debug("done commit");
+                // done
+            }
+
+
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            // release components
+            if (getLogger().isDebugEnabled()) getLogger().debug("releasing components");
+            if (outputSelector != null) {
+                if (output != null) 
+                    outputSelector.release(output);
+                this.manager.release(outputSelector);
+            }
+            if (inputSelector != null) {
+                if (input != null)
+                    inputSelector.release(input);
+                this.manager.release(inputSelector);
+            }
+            if (getLogger().isDebugEnabled()) getLogger().debug("... end");
+        }
+        return EMPTY_MAP;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ApplicationException.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ApplicationException.java
new file mode 100644
index 0000000..83a026d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ApplicationException.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.samples.errorhandling;
+
+/**
+ * @version $Id$
+ */
+public class ApplicationException extends Exception {
+    private int errorCode;
+
+    public ApplicationException(int errorCode, String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+
+    public ApplicationException(int errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public void setErrorCode(int errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public int getErrorCode() {
+        return this.errorCode;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionAction.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionAction.java
new file mode 100644
index 0000000..29a986d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionAction.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.samples.errorhandling;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.acting.AbstractAction;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.SourceResolver;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Exception action. Throws different kinds of exception depending on
+ * value of src attribute.
+ *
+ * @version $Id$
+ */
+public class ExceptionAction extends AbstractAction {
+
+    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters)
+    throws Exception {
+        String exception = parameters.getParameter("exception", source);
+        int code = parameters.getParameterAsInteger("code", 1);
+        exception(exception, code);
+        return null;
+    }
+
+    public static String exception(String exception, int code)
+    throws ProcessingException , SAXException, IOException {
+        if (exception == null) {
+            return "No exception occured.";
+        } else if (exception.equals("validation")) {
+            throw new ProcessingException(new ValidationException("Validation Exception Message"));
+        } else if (exception.equals("application")) {
+            throw new ProcessingException(new ApplicationException(code, "Application Exception " + code + " Message"));
+        } else if (exception.equals("processing")) {
+            throw new ProcessingException("Processing Exception Message");
+        } else if (exception.equals("notFound")) {
+            throw new ResourceNotFoundException("Resource Not Found Exception Message");
+        } else if (exception.equals("sax")) {
+            throw new SAXException("SAX Exception Message");
+        } else if (exception.equals("saxWrapped")) {
+            throw new SAXException(new ProcessingException("Processing Exception Wrapped In SAX Exception Message"));
+        } else if (exception.equals("nullPointer")) {
+            throw new NullPointerException("Null Pointer Exception Message");
+        } else if (exception.equals("io")) {
+            throw new IOException("IO Exception Message");
+        } else if (exception.equals("error")) {
+            throw new Error("Error Message");
+        } else {
+            return "Unknown exception requested.";
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionGenerator.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionGenerator.java
new file mode 100644
index 0000000..22da207
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ExceptionGenerator.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.samples.errorhandling;
+
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.generation.AbstractGenerator;
+import org.apache.cocoon.xml.XMLUtils;
+
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Exception generator. Throws different kinds of exception depending on
+ * value of src attribute.
+ *
+ * @version $Id$
+ */
+public class ExceptionGenerator extends AbstractGenerator {
+
+    private String exception;
+    private int code;
+
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters parameters)
+    throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, parameters);
+
+        this.exception = parameters.getParameter("exception", super.source);
+        this.code = Integer.parseInt(parameters.getParameter("code", "0"));
+
+        // Throw exception in the setup phase?
+        if (parameters.getParameterAsBoolean("setup", false)) {
+            ExceptionAction.exception(this.exception, this.code);
+        }
+    }
+
+    /**
+     * Overridden from superclass.
+     */
+    public void generate()
+    throws ProcessingException , SAXException, IOException {
+        this.contentHandler.startDocument();
+        this.contentHandler.startElement("", "html", "html", XMLUtils.EMPTY_ATTRIBUTES);
+        this.contentHandler.startElement("", "body", "body", XMLUtils.EMPTY_ATTRIBUTES);
+        this.contentHandler.startElement("", "p", "p", XMLUtils.EMPTY_ATTRIBUTES);
+
+        String text = ExceptionAction.exception(this.exception, this.code);
+        this.contentHandler.characters(text.toCharArray(), 0, text.length());
+
+        this.contentHandler.endElement("", "p", "p");
+        this.contentHandler.endElement("", "body", "body");
+        this.contentHandler.endElement("", "html", "html");
+        this.contentHandler.endDocument();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ValidationException.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ValidationException.java
new file mode 100644
index 0000000..700118d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/errorhandling/ValidationException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.samples.errorhandling;
+
+/**
+ * @since April 23, 2003
+ * @version $Id$
+ */
+public class ValidationException extends Exception {
+    public ValidationException() {
+        super();
+    }
+
+    public ValidationException(String message) {
+        super(message);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/User.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/User.java
new file mode 100644
index 0000000..e352fd4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/User.java
@@ -0,0 +1,150 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.samples.flow.prefs;
+
+/**
+ * Representation of a user.
+ *
+ * @version $Id$
+ */
+public class User
+{
+  String login;
+  String password;
+  String firstName;
+  String lastName;
+  String email;
+
+  public User(String login, String password,
+              String firstName, String lastName, String email)
+  {
+    this.login = login;
+    this.password = password;
+    this.firstName = firstName;
+    this.lastName = lastName;
+    this.email = email;
+  }
+
+  public int hashCode()
+  {
+    return login.hashCode();
+  }
+
+  public boolean equals(Object obj)
+  {
+    User anotherUser = (User)obj;
+    return anotherUser.login.equals(login);
+  }
+  
+  /**
+   * Sets the value of login
+   *
+   * @param argLogin Value to assign to this.login
+   */
+  public void setLogin(String argLogin)
+  {
+    this.login = argLogin;
+  }
+  /**
+   * Gets the value of login
+   *
+   * @return the value of login
+   */
+  public String getLogin() 
+  {
+    return this.login;
+  }
+
+  /**
+   * Gets the value of password
+   *
+   * @return the value of password
+   */
+  public String getPassword() 
+  {
+    return this.password;
+  }
+
+  /**
+   * Sets the value of password
+   *
+   * @param argPassword Value to assign to this.password
+   */
+  public void setPassword(String argPassword)
+  {
+    this.password = argPassword;
+  }
+
+  /**
+   * Gets the value of firstName
+   *
+   * @return the value of firstName
+   */
+  public String getFirstName() 
+  {
+    return this.firstName;
+  }
+
+  /**
+   * Sets the value of firstName
+   *
+   * @param argFirstName Value to assign to this.firstName
+   */
+  public void setFirstName(String argFirstName)
+  {
+    this.firstName = argFirstName;
+  }
+
+  /**
+   * Gets the value of lastName
+   *
+   * @return the value of lastName
+   */
+  public String getLastName() 
+  {
+    return this.lastName;
+  }
+
+  /**
+   * Sets the value of lastName
+   *
+   * @param argLastName Value to assign to this.lastName
+   */
+  public void setLastName(String argLastName)
+  {
+    this.lastName = argLastName;
+  }
+
+  /**
+   * Gets the value of email
+   *
+   * @return the value of email
+   */
+  public String getEmail() 
+  {
+    return this.email;
+  }
+
+  /**
+   * Sets the value of email
+   *
+   * @param argEmail Value to assign to this.email
+   */
+  public void setEmail(String argEmail)
+  {
+    this.email = argEmail;
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/UserRegistry.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/UserRegistry.java
new file mode 100644
index 0000000..4acc238
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/flow/prefs/UserRegistry.java
@@ -0,0 +1,87 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.samples.flow.prefs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Maintains a list of registered users. This is a very simple class,
+ * there is no persistence of the users, but such thing should be easy
+ * to add.
+ *
+ * @since August 28, 2002
+ * @version $Id$
+ */
+public class UserRegistry
+{
+  static UserRegistry userRegistry = new UserRegistry();
+
+  Map registeredUsers = new HashMap();
+
+  public static UserRegistry getUserRegistry()
+  {
+    return userRegistry;
+  }
+
+  protected UserRegistry()
+  {
+  }
+
+  public synchronized boolean addUser(User user)
+  {
+    if (registeredUsers.containsKey(user.getLogin()))
+      return false;
+
+    registeredUsers.put(user.getLogin(), user);
+    return true;
+  }
+
+  public boolean removeUser(User user)
+  {
+    return registeredUsers.remove(user) != null;
+  }
+
+  /**
+   * Checks is a particular login name is taken or not.
+   *
+   * @param loginName a <code>String</code> value
+   * @return true if <code>loginName</code> is taken, false otherwise
+   */
+  public boolean isLoginNameTaken(String loginName)
+  {
+    return registeredUsers.get(loginName) != null;
+  }
+
+  /**
+   * Returns the {@link User} object which represents an user. Note that
+   * we require a password to be present, to avoid presenting private
+   * information to anyone.
+   *
+   * @param loginName a <code>String</code> value
+   * @param password a <code>String</code> value
+   * @return an <code>User</code> value
+   */
+  public User getUserWithLogin(String loginName, String password)
+  {
+    User user = (User)registeredUsers.get(loginName);
+
+    if (user == null)
+      return null;
+
+    return password.equals(user.getPassword()) ? user : null;
+  }
+}
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java
new file mode 100644
index 0000000..f25661a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Configurator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.samples.parentcm;
+
+import org.apache.avalon.excalibur.naming.memory.MemoryInitialContextFactory;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.util.Hashtable;
+
+/**
+ * This class sets up the configuration used by the ParentServiceManager sample.
+ * The class also holds a reference to the initial context in which the configuration
+ * is available.
+ * <p>
+ * The configuration is bound to <code>org/apache/cocoon/samples/parentcm/ParentCMConfiguration</code>.
+ *
+ * @version $Id$
+ */
+public class Configurator  {
+
+    /**
+     * The Excalibur in-memory JNDI directory. Since the directory doesn't
+     * provide any persistence we must keep a reference to the initial context
+     * as a static member to avoid passing it around.
+     */
+    public static Context initialContext = null;
+
+    static {
+        try {
+            //
+            // Create a new role.
+            //
+            DefaultConfiguration config = new DefaultConfiguration("roles", "");
+            DefaultConfiguration timeComponent = new DefaultConfiguration("role", "roles");
+            timeComponent.setAttribute("name", Time.ROLE);
+            timeComponent.setAttribute("default-class", TimeComponent.class.getName());
+            timeComponent.setAttribute("shorthand", "samples-parentcm-time");
+            config.addChild(timeComponent);
+
+            //
+            // Bind it - get an initial context.
+            //
+            Hashtable environment = new Hashtable();
+            environment.put(Context.INITIAL_CONTEXT_FACTORY, MemoryInitialContextFactory.class.getName());
+            initialContext = new InitialContext(environment);
+
+            //
+            // Create subcontexts and bind the configuration.
+            //
+            Context ctx = initialContext.createSubcontext("org");
+            ctx = ctx.createSubcontext("apache");
+            ctx = ctx.createSubcontext("cocoon");
+            ctx = ctx.createSubcontext("samples");
+            ctx = ctx.createSubcontext("parentcm");
+            ctx.rebind("ParentCMConfiguration", config);
+        } catch (Exception e) {
+            e.printStackTrace(System.err);
+        }
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Generator.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Generator.java
new file mode 100644
index 0000000..ed45683
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Generator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.samples.parentcm;
+
+import org.apache.avalon.excalibur.pool.Poolable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.generation.ServiceableGenerator;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Generator for the parent component manager sample. The generator outputs
+ * a single tag <code>&lt;time&gt;<i>current time</i>&lt;/time&gt;</code>.
+ * Where <code><i>current time</i></code> is the current time as obtained from the
+ * <code>Time</code> component.
+ *
+ * @version $Id$
+ */
+public class Generator extends ServiceableGenerator implements Poolable {
+
+    /**
+     * Current time.
+     */
+    private Date time;
+
+    /**
+     * Looks up a <code>Time</code> component and obtains the current time.
+     */
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
+        throws ProcessingException, SAXException, IOException {
+
+        Time timeGiver = null;
+        try {
+            timeGiver = (Time) this.manager.lookup(Time.ROLE);
+            this.time = timeGiver.getTime ();
+        } catch (ServiceException ce) {
+            throw new ProcessingException ("Could not obtain current time.", ce);
+        } finally {
+            manager.release(timeGiver);
+        }
+    }
+
+    /**
+     * Generate XML data.
+     */
+    public void generate()
+    throws SAXException, ProcessingException {
+        contentHandler.startDocument();
+        contentHandler.startElement("", "time", "time", XMLUtils.EMPTY_ATTRIBUTES);
+
+        char[] text = this.time.toString().toCharArray();
+        contentHandler.characters(text, 0, text.length);
+
+        contentHandler.endElement("", "time", "time");
+        contentHandler.endDocument();
+    }
+
+    /**
+     * Prepare this object for another cycle.
+     */
+    public void recycle () {
+        this.time = null;
+    }
+}
+
+
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java
new file mode 100644
index 0000000..96f6af9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/ParentServiceManager.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.samples.parentcm;
+
+import org.apache.avalon.excalibur.naming.memory.MemoryInitialContextFactory;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.core.container.CoreServiceManager;
+
+import javax.naming.Context;
+import java.util.Hashtable;
+
+/**
+ * A sample parent component manager. This manager will lookup the configuration object
+ * given by the initialization parameter in JNDI, use it to configure an CocoonServiceManager
+ * and delegate any requests to it.
+ *
+ * @version $Id$
+ */
+public class ParentServiceManager implements ServiceManager, LogEnabled, Initializable {
+
+    /**
+     * Our logger.
+     */
+    private Logger logger;
+
+    /**
+     * The JNDI name where the component manager configuration can be found.
+     */
+    private final String jndiName;
+
+    /**
+     * The delegate that will be configured and provide the
+     * functionality for this component manager.
+     */
+    private final CoreServiceManager delegate;
+
+    public ParentServiceManager(final String jndiName) {
+        this.jndiName = jndiName;
+
+        // Initialize it here so we can let it be final.
+        this.delegate = new CoreServiceManager(null);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService(final String role) {
+        return delegate.hasService(role);
+    }
+
+    /**
+     * Initializes the CM by looking up the configuration object and using it to
+     * configure the delegate.
+     */
+    public void initialize() throws Exception {
+        this.logger.debug("Looking up component manager configuration at : " + this.jndiName);
+
+        Hashtable environment = new Hashtable();
+        environment.put(Context.INITIAL_CONTEXT_FACTORY, MemoryInitialContextFactory.class.getName());
+
+        //
+        // Yes, this is cheating, but the Excalibur in-memory naming provider
+        // is transient. That is, it doesn't store objects persistently and
+        // is more like a HashMap.
+        //
+        // Should be:
+        // Context initialContext = new InitialContext(environment);
+        //
+        Context initialContext = Configurator.initialContext;
+
+        Configuration config = (Configuration) initialContext.lookup(this.jndiName);
+
+        // We ignore the setRoleManager call, as CocoonServiceManager handles that
+        // in configure().
+        this.delegate.enableLogging(logger);
+        this.delegate.contextualize(new DefaultContext());
+        this.delegate.configure(config);
+        this.delegate.initialize();
+
+        this.logger.debug("Component manager successfully initialized.");
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup(final String role) throws ServiceException {
+        return this.delegate.lookup(role);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release(final Object component) {
+        this.delegate.release(component);
+    }
+
+    /**
+     * Provide component with a logger.
+     * 
+     * @param logger the logger
+     */
+    public void enableLogging(Logger logger) {
+        this.logger = logger;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Time.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Time.java
new file mode 100644
index 0000000..f29fe72
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/Time.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.samples.parentcm;
+
+import java.util.Date;
+
+/**
+ * Interface for a simple time-keeping component.
+ * @version $Id$
+ */
+public interface Time {
+
+    String ROLE = Time.class.getName();
+
+    /**
+     * Gets the current time.
+     */
+    Date getTime ();
+}
+
diff --git a/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/TimeComponent.java b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/TimeComponent.java
new file mode 100644
index 0000000..dd00158
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/samples/org/apache/cocoon/samples/parentcm/TimeComponent.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.samples.parentcm;
+
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+import java.util.Date;
+
+/**
+ * Implementing class for the parent component manager sample's
+ * <code>org.apache.cocoon.samples.parentcm.Time</code> component.
+ * @version $Id$
+ */
+public class TimeComponent implements Time, ThreadSafe {
+    
+    public Date getTime () {
+        return new Date();
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/schema/cob-schema-1.0.xsd b/non-releases/trunk_before_flattening/src/schema/cob-schema-1.0.xsd
new file mode 100644
index 0000000..744f4f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/cob-schema-1.0.xsd
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+<xs:schema targetNamespace="http://apache.org/cocoon/blocks/cob/1.0" 

+ xmlns="http://apache.org/cocoon/blocks/cob/1.0" 

+ xmlns:xs="http://www.w3.org/2001/XMLSchema" 

+ elementFormDefault="qualified">

+ 

+  <xs:element name="block">

+    <xs:complexType>

+      <xs:all>

+        <xs:element name="name" type="name"/>

+        <xs:element name="description" type="href"/>

+        <xs:element name="state" type="state"/>        

+        <xs:element name="license" type="href"/>

+        <xs:element name="author" type="href"/>

+        <xs:element name="sitemap" type="src" minOccurs="0"/>

+        <xs:element name="properties" type="properties" minOccurs="0"/>

+        <xs:element name="requirements" type="requirements" minOccurs="0"/>

+        <xs:element name="implements" type="implements" minOccurs="0"/>

+        <xs:element name="extends" type="extends" minOccurs="0"/>

+      </xs:all>

+      <xs:attribute name="id" type="xs:anyURI" use="required"/>

+    </xs:complexType>

+  </xs:element>

+    

+  <!-- general meta data -->

+  <xs:complexType name="name">

+    <xs:simpleContent>

+      <xs:extension base="xs:string"/>

+    </xs:simpleContent>

+  </xs:complexType> 

+

+  <xs:complexType name="state">
+  	<xs:attribute name="href" type="xs:anyURI" use="required"/>
+  	<xs:attribute name="community" type="community" use="required"/>
+  	<xs:attribute name="interfaces" type="stability" use="required"/>
+  	<xs:attribute name="implementation" type="stability" use="required"/>
+  </xs:complexType>

+  

+  <xs:simpleType name="community">

+	  <xs:restriction base="xs:string">

+	  	<xs:pattern value="committed|supported|deprecated|core"/>

+	  </xs:restriction>  	

+  </xs:simpleType>

+

+  <xs:simpleType name="stability">

+	  <xs:restriction base="xs:string">

+	  	<xs:pattern value="stable|unstable"/>

+	  </xs:restriction>  	

+  </xs:simpleType>

+  

+  <xs:complexType name="href">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="href" type="xs:anyURI"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType> 	

+  <xs:complexType name="src">

+    <xs:simpleContent>

+      <xs:extension base="xs:string">

+        <xs:attribute name="src" type="xs:string" use="required"/>

+      </xs:extension>

+    </xs:simpleContent>

+  </xs:complexType>  

+  

+  <!-- properties -->

+  <xs:complexType name="properties">
+		<xs:sequence>
+			<xs:element name="property" type="property" maxOccurs="unbounded"/>
+		</xs:sequence>
+  </xs:complexType>

+

+  <xs:complexType name="property">
+		<xs:all>
+			<xs:element name="default" minOccurs="0" maxOccurs="1" type="xs:string"/>
+			<xs:element name="description" minOccurs="1" maxOccurs="1" type="xs:string"/>
+		</xs:all>
+		<xs:attribute name="name" use="required"/>
+  </xs:complexType>  	

+

+  <!-- requirements -->

+  <xs:complexType name="requirements">
+		<xs:sequence>
+			<xs:element name="requires" type="requires" maxOccurs="unbounded"/>
+		</xs:sequence>
+  </xs:complexType>  

+

+  <xs:complexType name="requires">
+  	<xs:attribute name="interface" type="xs:anyURI" use="required"/>
+  	<xs:attribute name="default" type="xs:anyURI" use="optional"/>
+  	<xs:attribute name="name" type="xs:string" use="required"/>
+  </xs:complexType>  	

+

+  <!-- implements -->

+  <xs:complexType name="implements">
+		<xs:sequence>
+			<xs:element name="interface" type="interface" maxOccurs="unbounded"/>
+		</xs:sequence>
+  </xs:complexType>  	

+

+  <xs:complexType name="interface">
+  	<xs:attribute name="id" type="xs:anyURI" use="required"/>
+  </xs:complexType>  	  	

+

+  <!-- implements -->

+  <xs:complexType name="extends">
+  	<xs:attribute name="block" type="xs:anyURI" use="required"/>
+  </xs:complexType>  	  	

+

+</xs:schema>

diff --git a/non-releases/trunk_before_flattening/src/schema/deploy-schema-1.0.xsd b/non-releases/trunk_before_flattening/src/schema/deploy-schema-1.0.xsd
new file mode 100644
index 0000000..683e8f6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/deploy-schema-1.0.xsd
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+<xs:schema targetNamespace="http://cocoon.apache.org/cob-deployment/1.0" 

+ xmlns="http://cocoon.apache.org/cob-deployment/1.0" 

+ xmlns:xs="http://www.w3.org/2001/XMLSchema" 

+ elementFormDefault="qualified">

+ 

+  <xs:element name="deploy">

+    <xs:complexType>

+      <xs:all>

+        <xs:element ref="locators" minOccurs="1" maxOccurs="1"/>

+        <xs:element ref="install" minOccurs="1" maxOccurs="1"/>

+      </xs:all>

+    </xs:complexType>

+  </xs:element>

+

+  <!-- properties -->

+  <xs:element name="locators">

+  	<xs:complexType>

+			<xs:sequence>

+				<xs:element ref="locator" maxOccurs="unbounded"/>

+			</xs:sequence>

+  	</xs:complexType>

+  </xs:element>

+  <xs:element name="locator">

+  	<xs:complexType>

+			<xs:attribute name="uri" type="xs:anyURI" use="required"/>

+			<xs:attribute name="add-unavailable-blocks" use="optional" type="xs:boolean" default="false"/>

+  	</xs:complexType>  	

+  </xs:element>

+  

+  <!-- install (cocoon, blocks) -->

+  <xs:element name="install">

+  	<xs:complexType>

+			<xs:sequence>

+				<xs:element ref="cocoon" minOccurs="1" maxOccurs="1"/>

+				<xs:element ref="block" minOccurs="0" maxOccurs="unbounded"/>

+			</xs:sequence>

+  	</xs:complexType>  

+  </xs:element>

+  <xs:element name="cocoon">

+  	<xs:complexType>

+  		<xs:attribute name="target-uri" type="xs:anyURI" use="required"/>

+  		<xs:attribute name="version" use="required">

+  			<xs:simpleType>

+				  <xs:restriction base="xs:string">

+				   	<xs:pattern value="2.2"/>

+				  </xs:restriction>  			

+  			</xs:simpleType>

+  		</xs:attribute>

+  	</xs:complexType>  	

+  </xs:element>

+  <xs:element name="block">

+  	<xs:complexType>

+  		<xs:sequence>

+  			<xs:element ref="use" minOccurs="0" maxOccurs="unbounded"/>

+   			<xs:element ref="property" minOccurs="0" maxOccurs="unbounded"/> 			

+  		</xs:sequence>  		

+  		<xs:attribute name="id" type="xs:anyURI" use="required"/>

+  		<xs:attribute name="auto-resolve" type="xs:boolean" use="optional" default="false"/>

+  		<xs:attribute name="path" type="xs:anyURI" use="optional"/>

+  	</xs:complexType>  	

+  </xs:element>  

+  <xs:element name="use">

+  	<xs:complexType>

+  		<xs:attribute name="interface" type="xs:anyURI" use="required"/>

+  		<xs:attribute name="block" type="xs:anyURI" use="required"/>

+  	</xs:complexType>   	

+  </xs:element>

+  <xs:element name="property">

+  	<xs:complexType>

+  		<xs:attribute name="name" type="xs:string" use="required"/>

+  		<xs:attribute name="value" type="xs:string" use="required"/>

+  	</xs:complexType>   	

+  </xs:element>

+

+</xs:schema>

diff --git a/non-releases/trunk_before_flattening/src/schema/test-block.xml b/non-releases/trunk_before_flattening/src/schema/test-block.xml
new file mode 100644
index 0000000..01f8667
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/test-block.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"

+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

+	xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"

+	id="http://cocoon.apache.org/blocks/anyblock/1.0">

+	<name>anyblock</name>

+	<description href="http://cocoon.apache.org/blocks/anyblock/1.0">

+		A block based on the Apache Cocoon portal

+	</description>

+	<state 

+		href="http://cocoon.apache.org/blocks/anyblock/1.0/state.html" 

+		community="committed" 

+		interfaces="unstable" 

+		implementation="stable"/>

+	<license href="http://www.apache.org/licenses/">Apache License 2.0</license>

+	<author href="http://cocoon.apache.org">Apache Cocoon community</author>

+	<sitemap src="sitemap.xmap"/>

+	<properties>
+		<property name="mailserver">

+			<default>localhost</default>

+			<description>The IP adress or the DNS name of a server that can send mails.</description>

+		</property>

+		<property name="foo">

+			<description>bar</description>

+		</property>
+	</properties>

+	<requirements>
+		<requires 

+		  interface="http://cocoon.apache.org/interface/portal/1.0" 

+		  name="portal"

+		  default="http://cocoon.apache.org/blocks/portal/1.0.2"

+		  />
+	</requirements>

+	<extends block="http://cocoon.apache.org/blocks/another-block/1.0"/>

+	<implements>

+		<interface id="http://cocoon.apache.org/interface/bla/1.0"/>

+	</implements>

+</block>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/schema/test-deploy.xml b/non-releases/trunk_before_flattening/src/schema/test-deploy.xml
new file mode 100644
index 0000000..dd2f1ab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/test-deploy.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+<deploy xmlns="http://cocoon.apache.org/cob-deployment/1.0"

+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

+	xsi:schemaLocation="http://cocoon.apache.org/cob-deployment/1.0 deploy-schema-1.0.xsd">

+  <locators>

+    <locator uri="C:\myDirectory" add-unavailable-blocks="true"/>

+    <locator uri="F:\anotherDirectory"/>

+    <locator uri="http://cocoon.apache.org/block-repository/"/>

+  </locators>

+  <install>

+  	<!-- install Cocoon 2.2 at d:\ -->

+    <cocoon version="2.2" target-uri="d:\"/>

+    <!-- install this block and set the property xyz and define which

+         block implementations should be used for the defined requirements 

+         this overrides the default values set in block.xml -->

+    <block id="http://mycompany.com/webmail/1.3.43" auto-resolve="false">

+    	<use block="http://mycompany.com/myblock/1.3.43" interface="http://bla/1.0" />

+    	<use block="http://mycompany.com/myOtherBlock/1.3.43" interface="http://bar/1.0" />    	

+      <property name="mailserver" value="xyz"/>

+    </block>

+    <block id="http://mycompany.com/myblock/1.3.43" auto-resolve="false">

+      <property name="driver" value="myDriver.class"/>

+    </block>

+    <block id="http://mycompany.com/myOtherBlock/1.3.43" auto-resolve="false" path="E:\myBlockDevDir"/>

+  </install>

+</deploy>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/schema/test-wiring.xml b/non-releases/trunk_before_flattening/src/schema/test-wiring.xml
new file mode 100644
index 0000000..f1f5cca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/test-wiring.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+

+<wiring xmlns="http://apache.org/cocoon/blocks/wiring/1.0"

+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

+	xsi:schemaLocation="http://apache.org/cocoon/blocks/wiring/1.0 wiring-schema-1.0.xsd"

+>

+	<block id="http://mycompany.com/webmail/1.3.43" location="000001">

+		<mount path="/mail/"/>

+		<connections>

+			<connection name="external-skin" block="http://yetanothercompany.com/skins/fancy/1.2.2"/>

+			<connection name="internal-skin" block="http://mycompany.com/skins/corporate/34.3.345"/>

+			<connection name="repository" block="http://mycompany.com/repositories/email/exchange/3.2.1"/>

+		</connections>

+		<properties>

+			<property name="user" value="guest"/>

+			<property name="password" value="sj3u493"/>

+		</properties>

+	</block>

+	<block id="http://mycompany.com/repositories/email/exchange/3.2.1" location="000002">

+		<properties>

+			<property name="host" value="mail.blah.org"/>

+		</properties>

+	</block>

+	<block id="http://yetanothercompany.com/skins/fancy/1.2.2" location="000003"/>

+	<block id="http://mycompany.com/skins/corporate/34.3.345" location="000004"/>

+</wiring>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/schema/wiring-schema-1.0.xsd b/non-releases/trunk_before_flattening/src/schema/wiring-schema-1.0.xsd
new file mode 100644
index 0000000..13d757f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/schema/wiring-schema-1.0.xsd
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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. 

+-->

+<xs:schema targetNamespace="http://apache.org/cocoon/blocks/wiring/1.0" 

+ xmlns="http://apache.org/cocoon/blocks/wiring/1.0" 

+ xmlns:xs="http://www.w3.org/2001/XMLSchema" 

+ elementFormDefault="qualified">

+ 

+  <xs:element name="wiring">

+    <xs:complexType>

+      <xs:sequence minOccurs="0">

+      	<xs:element name="block" type="block" maxOccurs="unbounded"/>

+      </xs:sequence>

+    </xs:complexType>

+  </xs:element>

+  

+  <xs:complexType name="block">
+		<xs:all>
+			<xs:element name="mount" type="mount" minOccurs="0"/>
+			<xs:element name="connections" type="connections" minOccurs="0"/>
+			<xs:element name="properties" type="properties" minOccurs="0"/>
+		</xs:all>
+		<xs:attribute name="id" type="xs:anyURI" use="required"/>
+		<xs:attribute name="location" type="xs:anyURI" use="required"/>
+  </xs:complexType>  

+

+  <xs:complexType name="mount">
+  	<xs:attribute name="path" type="xs:string" use="required"/>
+  </xs:complexType>  	

+

+  <xs:complexType name="connections">
+  	<xs:sequence>
+  		<xs:element name="connection" type="connection" minOccurs="0" maxOccurs="unbounded"/>
+  	</xs:sequence>
+  </xs:complexType>  	

+

+  <xs:complexType name="connection">
+  	<xs:attribute name="name" type="xs:string" use="required"/>
+  	<xs:attribute name="block" type="xs:anyURI" use="required"/>
+  </xs:complexType>   	

+

+  <xs:complexType name="properties">
+  	<xs:sequence>
+  		<xs:element name="property" type="property" minOccurs="1" maxOccurs="unbounded"/>
+  	</xs:sequence>
+  </xs:complexType>  	

+

+  <xs:complexType name="property">
+  	<xs:attribute name="name" type="xs:string" use="required"/>
+  	<xs:attribute name="value" type="xs:string" use="required"/>
+  </xs:complexType>   	

+

+</xs:schema>

diff --git a/non-releases/trunk_before_flattening/src/test/anteater/bug26186InternalRequestMemoryLeak.xml b/non-releases/trunk_before_flattening/src/test/anteater/bug26186InternalRequestMemoryLeak.xml
new file mode 100644
index 0000000..42d82ec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/bug26186InternalRequestMemoryLeak.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<project name="Cocoon Stress Test" default="conditional">
+  <taskdef resource="META-INF/Anteater.tasks"/>
+  <typedef resource="META-INF/Anteater.types"/>
+  <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
+
+  <property name="url" value="${anteater.env.cocoon}/samples/xsp/java/resolver"/>
+
+  <target name="conditional" depends="main,disabled"/>
+  <target name="disabled" unless="anteater.test.bug26186InternalRequestMemoryLeak.enabled">
+    <echo>bug26186InternalRequestMemoryLeak disabled by configuration</echo>
+  </target>
+  <target name="main" if="anteater.test.bug26186InternalRequestMemoryLeak.enabled">
+    <echo>base=${anteater.target.base.path}</echo>
+    <echo>disabled? ${anteater.test.bug26186InternalRequestMemoryLeak.disabled}</echo>
+    <foreach list="0,1,2,3,4,5" target="multiplier1" param="m1"/>
+  </target>
+  <target name="multiplier1">
+    <foreach list="0,1,2,3,4,5,6,7,8,9" target="multiplier2" param="m2"/>
+  </target>
+  <target name="multiplier2">
+    <foreach list="0,1,2,3,4,5,6,7,8,9" target="multiplier3" param="m3"/>
+  </target>
+  <target name="multiplier3">
+    <foreach list="0,1,2,3,4,5,6,7,8,9" target="multiplier4" param="m4"/>
+  </target>
+  <target name="multiplier4">
+    <foreach list="0,1,2,3,4,5,6,7,8,9" target="content" param="m5"/>
+  </target>
+  <target name="content">
+    <echo>request no. ${m1}${m2}${m3}${m4}${m5}</echo>
+    <httpRequest href="${url}">
+      <match>
+        <responseCode value="200"/>
+        <regexp>An XSP Page using a source</regexp>
+      </match>
+    </httpRequest>
+  </target>
+</project>
+
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/bug26571SendPageRedirectTo.xml b/non-releases/trunk_before_flattening/src/test/anteater/bug26571SendPageRedirectTo.xml
new file mode 100644
index 0000000..3b4ea5b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/bug26571SendPageRedirectTo.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="sendpage-redirect-test" default="sendpage-redirect-test">
+
+  <group id="default">
+    <property name="usetidy" value="false"/>
+  </group>
+
+  <target name="sendpage-redirect-test">
+    <property name="sendpage-redirect-test" value="${anteater.env.cocoon}/samples/test/sendpage-redirect/test"/>
+
+    <httpRequest href="${sendpage-redirect-test}-good">
+      <match>
+        <responseCode value="302"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${sendpage-redirect-test}-bad">
+      <match>
+        <responseCode value="302"/>
+      </match>
+    </httpRequest>
+
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/calc.xml b/non-releases/trunk_before_flattening/src/test/anteater/calc.xml
new file mode 100644
index 0000000..5c25217
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/calc.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="calc-test" default="calc">
+
+  <group id="default">
+    <property name="usetidy" value="true"/>
+  </group>
+
+  <!-- Simulate the behavior of a user that opens a browser, starts
+  the calculator example, and goes back in the processing several
+  times. -->
+  <target name="calc">
+    <property name="calc" value="${anteater.env.cocoon}/samples/flow/jxcalc/"/>
+
+      <httpRequest href="${calc}/"
+		   description="Test the 'calc' JavaScript implementation">
+        <match>
+          <xpath select="html/body//form/@action" assign="cont1"/>
+        </match>
+      </httpRequest>
+      <httpRequest href="${calc}/${cont1}">
+        <parameter name="a" value="1"/>
+        <match>
+          <xpath select="html/body//form/@action" assign="cont2"/>
+        </match>
+      </httpRequest>
+      <httpRequest href="${calc}/${cont2}">
+        <parameter name="b" value="2"/>
+        <match>
+          <xpath select="html/body//form/@action" assign="cont3"/>
+        </match>
+      </httpRequest>
+      <httpRequest href="${calc}/${cont3}">
+        <parameter name="operator" value="plus"/>
+        <match>
+          <xpath select="html/body//form/p[contains(text(),'Result')]/strong"
+		 value="3.0"
+		 assign="result"/>
+        </match>
+      </httpRequest>
+      <echo>result = ${result}</echo>
+
+      <httpRequest href="${calc}/${cont2}"
+		   description="Simulate going back in the browser">
+        <parameter name="b" value="4"/>
+        <match>
+          <xpath select="html/body//form/@action" assign="cont4"/>
+        </match>
+      </httpRequest>
+      <httpRequest href="${calc}/${cont4}">
+        <parameter name="operator" value="minus"/>
+        <match>
+          <xpath select="html/body//form/p[contains(text(),'Result')]/strong"
+		 value="-3.0"
+		 assign="result"/>
+        </match>
+      </httpRequest>
+      <echo>result = ${result}</echo>
+
+      <httpRequest href="${calc}/${cont4}"
+		   description="Simulate going back again in the browser">
+        <parameter name="operator" value="divide"/>
+        <match>
+          <xpath select="html/body//form/p[contains(text(),'Result')]/strong"
+		 value="0.25"
+		 assign="result"/>
+        </match>
+      </httpRequest>
+      <echo>result = ${result}</echo>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/flowscript-dom-dump.xml b/non-releases/trunk_before_flattening/src/test/anteater/flowscript-dom-dump.xml
new file mode 100644
index 0000000..1e6d568
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/flowscript-dom-dump.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="flowscript-dom-dump" default="flowscript-dom-dump">
+
+    <!--
+      Check various ways of dumping DOM objects in Flowscript
+      (bugzilla 29381)
+    -->
+    <target name="flowscript-dom-dump">
+        <property name="baseUrl" value="${anteater.env.cocoon}/samples/test/flowscript-dom-dump"/>
+
+        <httpRequest href="${baseUrl}/dom-dump" description="Check dump without XSLT transform">
+            <match>
+                <header name="Content-type" value="text/xml"/>
+                <xpath select="//dump-without-star/root/child" pattern="childText"/>
+                <xpath select="//dump-with-star/root/child" pattern="childText"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/dom-dump-xslt" description="Check dump with XSLT transform">
+            <match>
+                <header name="Content-type" value="text/xml"/>
+                <xpath select="//dump-without-star/root/@test-transform" pattern="true"/>
+                <xpath select="//dump-without-star/root/child" pattern="childText"/>
+                <xpath select="//dump-with-star/root/@test-transform" pattern="true"/>
+                <xpath select="//dump-with-star/root/child" pattern="childText"/>
+            </match>
+        </httpRequest>
+
+    </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/flowscriptRecursive.xml b/non-releases/trunk_before_flattening/src/test/anteater/flowscriptRecursive.xml
new file mode 100644
index 0000000..d452205
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/flowscriptRecursive.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="flowscriptRecursive" default="flowscriptRecursive">
+
+  <group id="default">
+    <property name="usetidy" value="true"/>
+  </group>
+
+  <!-- Check the reloading of the sitemap -->
+  <target name="flowscriptRecursive">
+    <property name="test-dir" value="samples/flow/test"/>
+    <property name="url" value="${anteater.env.cocoon}/${test-dir}/factorial?n=5"/>
+
+    <httpRequest href="${url}" description="Send Request">
+      <match>
+        <xpath select="html/body/p[1]" pattern=" 5 "/>
+        <xpath select="html/body/p[2]" pattern="120\.0"/>
+      </match>
+    </httpRequest>
+
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/flowscriptReload.xml b/non-releases/trunk_before_flattening/src/test/anteater/flowscriptReload.xml
new file mode 100644
index 0000000..2267dc1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/flowscriptReload.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="flowscriptReload" default="flowscriptReload">
+
+  <group id="default">
+    <property name="usetidy" value="true"/>
+  </group>
+
+  <!-- Check the reloading of the sitemap -->
+  <target name="flowscriptReload">
+    <property name="test-dir" value="samples/flow/test"/>
+    <property name="url" value="${anteater.env.cocoon}/${test-dir}/showString"/>
+
+    <!--+
+        | Copy the flowscript from its source directory to the destination
+        | area, and replace the parameter value with 'abc' 
+        +-->
+
+    <copy file="${anteater.env.src-webapp-dir}/${test-dir}/sendpage.js"
+	  tofile="${anteater.env.deploy-dir}/${test-dir}/sendpage.js"
+	  overwrite="yes">
+      <filterset>
+        <filter token="REPLACEME" value="replaceme-abc"/>
+      </filterset>
+    </copy>
+
+    <!-- make sure change is detected -->
+    <sleep seconds="5"/>
+
+    <httpRequest href="${url}" description="Send original request">
+      <match>
+        <xpath select="html/body/p[1]" pattern=".*replaceme-abc.*"/>
+      </match>
+    </httpRequest>
+
+    <!--+ 
+        | Copy the flowscript from its source directory to the destination
+        | area, and replace the parameter value with '123' 
+        +-->
+
+    <copy file="${anteater.env.src-webapp-dir}/${test-dir}/sendpage.js"
+	  tofile="${anteater.env.deploy-dir}/${test-dir}/sendpage.js"
+	  overwrite="yes">
+      <filterset>
+	    <filter token="REPLACEME" value="replaceme-123"/>
+      </filterset>
+    </copy>
+
+    <!-- make sure change is detected -->
+    <sleep seconds="5"/>
+
+    <httpRequest href="${url}" description="Send next request after flowscript was modified">
+      <match>
+        <xpath select="html/body/p[1]" pattern=".*replaceme-123.*"/>
+      </match>
+    </httpRequest>
+
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/internalRequest.xml b/non-releases/trunk_before_flattening/src/test/anteater/internalRequest.xml
new file mode 100644
index 0000000..7149596
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/internalRequest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="internal-request-test" default="internal-request-test">
+
+  <group id="default">
+    <property name="usetidy" value="false"/>
+  </group>
+
+  <!-- test samples/test/simpletest -->
+  <target name="internal-request-test">
+    <property name="internal-request-test" value="${anteater.env.cocoon}/samples/test/internal-request/simpletest"/>
+
+      <httpRequest href="${internal-request-test}"
+		   description="Test the internal request handling">
+        <match>
+          <xpath select="test/test/@file" value="c"/>
+        </match>
+      </httpRequest>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/internalSendPage.xml b/non-releases/trunk_before_flattening/src/test/anteater/internalSendPage.xml
new file mode 100644
index 0000000..858aba2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/internalSendPage.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="internal-sendpage-test" default="internal-sendpage-test">
+
+  <group id="default">
+    <property name="usetidy" value="false"/>
+  </group>
+
+  <target name="internal-sendpage-test">
+    <property name="internal-sendpage-test" value="${anteater.env.cocoon}/samples/test/sendpage"/>
+    
+    <httpRequest href="${internal-sendpage-test}/testExternal">
+      <match>
+        <responseCode value="200"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${internal-sendpage-test}/testInternal">
+      <match>
+        <responseCode value="200"/>
+      </match>
+    </httpRequest>
+    
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/reader-mime-type.xml b/non-releases/trunk_before_flattening/src/test/anteater/reader-mime-type.xml
new file mode 100644
index 0000000..5c861f7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/reader-mime-type.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="reader-mime-type" default="reader-mime-type">
+
+    <group id="default">
+        <property name="usetidy" value="false"/>
+    </group>
+
+    <!-- Check mime-types (bugzilla 25212) -->
+    <target name="reader-mime-type">
+        <property name="baseUrl" value="${anteater.env.cocoon}/samples/test/reader-mime-type"/>
+
+        <httpRequest href="${baseUrl}/test10.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test10.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test20.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test20.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test30.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test30.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test40.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test40.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test50.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test50.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test60.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test60.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+        <httpRequest href="${baseUrl}/test70.html" description="Check content-type">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+        <httpRequest href="${baseUrl}/test70.html" description="Check content-type (cached)">
+            <match>
+                <header name="Content-type" value="text/html"/>
+            </match>
+        </httpRequest>
+
+    </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/redirect.xml b/non-releases/trunk_before_flattening/src/test/anteater/redirect.xml
new file mode 100644
index 0000000..ecad761
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/redirect.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="redirect-test" default="redirect-test">
+
+  <group id="default">
+    <property name="usetidy" value="false"/>
+  </group>
+
+  <target name="redirect-test">
+    <property name="redirect-test" value="${anteater.env.cocoon}/samples/test/redirect"/>
+    
+    <httpRequest href="${redirect-test}/redirect-to-from-sitemap">
+      <match>
+        <responseCode value="302"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/redirect-to-internal-from-sitemap">
+      <match>
+        <responseCode value="200"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/redirect-to-from-flow">
+      <match>
+        <responseCode value="302"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/send-status">
+      <match>
+        <responseCode value="204"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/send-page">
+      <match>
+        <responseCode value="200"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/donothing-from-sitemap">
+      <match>
+        <responseCode value="404"/>
+      </match>
+    </httpRequest>
+    
+    <httpRequest href="${redirect-test}/donothing-from-flow">
+      <match>
+        <responseCode value="500"/>
+      </match>
+    </httpRequest>
+    
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/run-tests.xml b/non-releases/trunk_before_flattening/src/test/anteater/run-tests.xml
new file mode 100644
index 0000000..15cc591
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/run-tests.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+
+  Automatically detects all the Anteater tests in the current
+  directory and runs them.
+
+  Date: April 4, 2002
+
+  Description:
+
+  To write a new Anteater test, just create a new Ant XML file with
+  a default target. Then go in the top level directory of Cocoon and
+  type:
+
+  ./build.sh anteater-tests
+  build anteater-tests
+
+  The newly added test file will be picked up and executed
+  auto-magically.
+
+  For block-specific tests, create anteater scripts in a subdirectory
+  called "test/anteater", for example src/blocks/batik/test/anteater
+  for the batik block.
+
+  -->
+
+<project name="anteater-tests" default="all">
+
+  <taskdef resource="META-INF/Anteater.tasks"/>
+  <typedef resource="META-INF/Anteater.types"/>
+  <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
+
+  <property name="cocoon.base.dir" value="../../../.."/>
+
+  <target name="init">
+    <!-- use build.properties as in the main build file, for example to selectively disable tests -->
+    <property file="${user.home}/cocoon.build.properties"/>
+    <property file="${cocoon.base.dir}/local.build.properties"/>
+    <property file="${cocoon.base.dir}/build.properties"/>
+
+    <property name="anteater.env.cocoon" value="http://${host}:${port}/${base}"/>
+    <property name="anteater.env.src-webapp-dir" value="../../../../src/webapp"/>
+    <property name="anteater.env.deploy-dir" value="../../../../build/webapp"/>
+  </target>
+
+  <target name="all" depends="init">
+    <foreach target="runtest" param="name">
+      <fileset dir=".">
+        <include name="*.xml"/>
+        <exclude name="run-tests.xml"/>
+      </fileset>
+    </foreach>
+  </target>
+
+  <target name="single" depends="init">
+    <foreach target="runtest" param="name">
+      <fileset dir=".">
+        <include name="${targetfile}.xml"/>
+      </fileset>
+    </foreach>
+  </target>  
+
+  <target name="runtest" depends="init">
+    <basename property="target" file="${name}" suffix=".xml"/>
+    <echo message="running test ${target} in dir ${basedir}"/>
+    <ant antfile="${target}.xml" dir="${basedir}" inheritAll="yes"/>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/sitemapAnnotationsFilter.xml b/non-releases/trunk_before_flattening/src/test/anteater/sitemapAnnotationsFilter.xml
new file mode 100644
index 0000000..8005fd5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/sitemapAnnotationsFilter.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="sitemapAnnotationsFilter" default="annotatedSitemapWorks">
+
+  <group id="default">
+    <property name="usetidy" value="false"/>
+  </group>
+
+  <target name="annotatedSitemapWorks">
+    <property name="url" value="${anteater.env.cocoon}samples/test/sitemap-annotations/annotations"/>
+
+    <!-- check that the "annotations" page contains annotations from the test sitemap -->
+    <httpRequest href="${url}" description="Test annotations extraction">
+      <match>
+        <xpath select="//info/author" value="The Cocoon team"/>
+      </match>
+    </httpRequest>
+
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/anteater/sitemapReload.xml b/non-releases/trunk_before_flattening/src/test/anteater/sitemapReload.xml
new file mode 100644
index 0000000..159712e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/anteater/sitemapReload.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<project name="sitemapReload" default="sitemapReload">
+
+  <group id="default">
+    <property name="usetidy" value="true"/>
+  </group>
+
+  <!-- Check the reloading of the sitemap -->
+  <target name="sitemapReload">
+    <property name="test-dir" value="samples/flow/test"/>
+    <property name="url" value="${anteater.env.cocoon}/${test-dir}/showString"/>
+
+    <!--+
+        | Copy the sitemap from its source directory to the destination
+        | area, and replace the parameter value with 'abc' 
+        +-->
+
+    <copy file="${anteater.env.src-webapp-dir}/${test-dir}/sitemap.xmap"
+	  tofile="${anteater.env.deploy-dir}/${test-dir}/sitemap.xmap"
+	  overwrite="yes">
+      <filterset>
+	    <filter token="PARAMETER" value="abc"/>
+      </filterset>
+    </copy>
+
+    <sleep seconds="1"/>
+
+    <httpRequest href="${url}" description="Send original request">
+      <match>
+        <xpath select="html/body//p[2]" pattern=".*abc.*"/>
+      </match>
+    </httpRequest>
+
+    <!--+ 
+        | Copy the sitemap from its source directory to the destination
+        | area, and replace the parameter value with '123' 
+        +-->
+
+    <copy file="${anteater.env.src-webapp-dir}/${test-dir}/sitemap.xmap"
+	  tofile="${anteater.env.deploy-dir}/${test-dir}/sitemap.xmap"
+	  overwrite="yes">
+      <filterset>
+	   <filter token="PARAMETER" value="123"/>
+      </filterset>
+    </copy>
+
+    <sleep seconds="1"/>
+
+    <httpRequest href="${url}"
+		 description="Send next request after sitemap was modified">
+      <match>
+        <xpath select="html/body//p[2]" pattern=".*123.*"/>
+      </match>
+    </httpRequest>
+
+  </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/CocoonTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/CocoonTestCase.java
new file mode 100644
index 0000000..f79ee7e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/CocoonTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.apache.cocoon.core.container.StandaloneServiceSelector;
+import org.apache.cocoon.core.container.ContainerTestCase;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.impl.ResourceSourceFactory;
+import org.apache.excalibur.source.impl.SourceResolverImpl;
+import org.apache.excalibur.source.impl.URLSourceFactory;
+
+/**
+ * Testcase for Cocoon. 
+ *
+ * @version $Id: SitemapComponentTestCase.java 55427 2004-10-24 11:38:37Z cziegeler $
+ */
+public abstract class CocoonTestCase extends ContainerTestCase {
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ContainerTestCase#addComponents(org.apache.cocoon.core.container.CocoonServiceManager)
+     */
+    protected void addComponents(CoreServiceManager manager) 
+    throws ServiceException, ConfigurationException {
+        super.addComponents(manager);
+        if ( this.addSourceFactories() ) {
+            // Create configuration for source-factories
+            final DefaultConfiguration df = new DefaultConfiguration("source-factories");
+            DefaultConfiguration factory = new DefaultConfiguration("component-instance");
+            factory.setAttribute("class", ResourceSourceFactory.class.getName());
+            factory.setAttribute("name", "resource");
+            df.addChild(factory);
+            factory = new DefaultConfiguration("component-instance");
+            factory.setAttribute("class", URLSourceFactory.class.getName());
+            factory.setAttribute("name", "*");
+            df.addChild(factory);
+            manager.addComponent("org.apache.excalibur.source.SourceFactorySelector", 
+                                 StandaloneServiceSelector.class.getName(), 
+                                 df,
+                                 null);
+        }
+        if ( this.addSourceResolver() ) {
+            manager.addComponent(SourceResolver.ROLE, 
+                    SourceResolverImpl.class.getName(), 
+                    new DefaultConfiguration("", "-"),
+                    null);
+        }
+    }
+    
+    /**
+     * This method should return true if the source factories should
+     * be added automatically. Can be overwritten by subclasses. The
+     * default is true.
+     */
+    protected boolean addSourceFactories() {
+        return true;
+    }
+    
+    /**
+     * This method should return true if the source resolver should
+     * be added automatically. Can be overwritten by subclasses. The
+     * default is true.
+     */
+    protected boolean addSourceResolver() {
+        return true;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockLogger.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockLogger.java
new file mode 100644
index 0000000..128347e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockLogger.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Mock logger for test cases. Delegates to a Commons Logging logger.
+ * 
+ * @version $Id$
+ */
+public class MockLogger implements Logger {
+    protected Log logger;
+    
+    /**
+     * Create a new logger for a given class.
+     * 
+     * @param clazz The class.
+     */
+    public MockLogger(Class clazz) {
+        this.logger = LogFactory.getLog(clazz);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#debug(java.lang.String)
+     */
+    public void debug(String msg) {
+        this.logger.debug(msg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#debug(java.lang.String, java.lang.Throwable)
+     */
+    public void debug(String msg, Throwable t) {
+        this.logger.debug(msg, t);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#isDebugEnabled()
+     */
+    public boolean isDebugEnabled() {
+        return this.logger.isDebugEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#info(java.lang.String)
+     */
+    public void info(String msg) {
+        this.logger.info(msg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#info(java.lang.String, java.lang.Throwable)
+     */
+    public void info(String msg, Throwable t) {
+        this.logger.info(msg, t);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#isInfoEnabled()
+     */
+    public boolean isInfoEnabled() {
+        return this.logger.isInfoEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#warn(java.lang.String)
+     */
+    public void warn(String msg) {
+        this.logger.warn(msg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#warn(java.lang.String, java.lang.Throwable)
+     */
+    public void warn(String msg, Throwable t) {
+        this.logger.warn(msg, t);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#isWarnEnabled()
+     */
+    public boolean isWarnEnabled() {
+        return this.logger.isWarnEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#error(java.lang.String)
+     */
+    public void error(String msg) {
+        this.logger.error(msg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#error(java.lang.String, java.lang.Throwable)
+     */
+    public void error(String msg, Throwable t) {
+        this.logger.error(msg, t);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#isErrorEnabled()
+     */
+    public boolean isErrorEnabled() {
+        return this.logger.isErrorEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#fatalError(java.lang.String)
+     */
+    public void fatalError(String msg) {
+        this.logger.fatal(msg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#fatalError(java.lang.String, java.lang.Throwable)
+     */
+    public void fatalError(String msg, Throwable t) {
+        this.logger.fatal(msg, t);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#isFatalErrorEnabled()
+     */
+    public boolean isFatalErrorEnabled() {
+        return this.logger.isFatalEnabled();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.logger.Logger#getChildLogger(java.lang.String)
+     */
+    public Logger getChildLogger(String arg0) {
+        return null;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockProcessor.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockProcessor.java
new file mode 100644
index 0000000..509dae6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/MockProcessor.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.SourceResolver;
+
+/**
+ * Mock processor
+ * 
+ * @version $Id$
+ */
+public class MockProcessor implements Processor {
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#buildPipeline(org.apache.cocoon.environment.Environment)
+     */
+    public InternalPipelineDescription buildPipeline(Environment environment)
+    throws Exception {
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getComponentConfigurations()
+     */
+    public Configuration[] getComponentConfigurations() {
+        return null;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getContext()
+     */
+    public String getContext() {
+        return null;
+    }
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getRootProcessor()
+     */
+    public Processor getRootProcessor() {
+        return this;
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#getSourceResolver()
+     */
+    public SourceResolver getSourceResolver() {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.Processor#process(org.apache.cocoon.environment.Environment)
+     */
+    public boolean process(Environment environment) throws Exception {
+        return false;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#removeAttribute(java.lang.String)
+     */
+    public Object removeAttribute(String name) {
+        return null;
+    }
+
+    /**
+     * @see org.apache.cocoon.Processor#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        // nothing to do
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/SitemapComponentTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/SitemapComponentTestCase.java
new file mode 100644
index 0000000..997442c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/SitemapComponentTestCase.java
@@ -0,0 +1,810 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.AbstractInterpreter;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.components.flow.Interpreter;
+import org.apache.cocoon.components.source.SourceResolverAdapter;
+import org.apache.cocoon.core.container.CoreServiceManager;
+import org.apache.cocoon.core.container.StandaloneServiceSelector;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.internal.EnvironmentHelper;
+import org.apache.cocoon.environment.mock.MockContext;
+import org.apache.cocoon.environment.mock.MockEnvironment;
+import org.apache.cocoon.environment.mock.MockRedirector;
+import org.apache.cocoon.environment.mock.MockRequest;
+import org.apache.cocoon.environment.mock.MockResponse;
+import org.apache.cocoon.generation.Generator;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.serialization.Serializer;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.transformation.Transformer;
+import org.apache.cocoon.xml.WhitespaceFilter;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.dom.DOMStreamer;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.custommonkey.xmlunit.Diff;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Testcase for actions, generators, transformers and serializer components. 
+ *
+ * @version $Id$
+ */
+public abstract class SitemapComponentTestCase extends CocoonTestCase {
+
+    public final static Parameters EMPTY_PARAMS = Parameters.EMPTY_PARAMETERS;
+
+    private MockRequest request = new MockRequest();
+    private MockResponse response = new MockResponse();
+    private MockContext context = new MockContext();
+    private MockRedirector redirector = new MockRedirector();
+    private Map objectmodel = new HashMap();
+
+    public final MockRequest getRequest() {
+        return request;
+    }
+
+    public final MockResponse getResponse() {
+        return response;
+    }
+
+    public final MockContext getContext() {
+        return context;
+    }
+
+    public final MockRedirector getRedirector() { 
+        return redirector;
+    }
+
+    public final Map getObjectModel() {
+        return objectmodel;
+    }
+    
+    protected void addContext(DefaultContext context) {
+        context.put(ContextHelper.CONTEXT_REQUEST_OBJECT, request);
+        context.put(ContextHelper.CONTEXT_RESPONSE_OBJECT, response);
+        context.put(ContextHelper.CONTEXT_OBJECT_MODEL, objectmodel);
+        context.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, getContext());
+    }
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    public void setUp() throws Exception {
+        super.setUp();
+        objectmodel.clear();
+
+        request.reset();
+        objectmodel.put(ObjectModelHelper.REQUEST_OBJECT, request);
+
+        response.reset();
+        objectmodel.put(ObjectModelHelper.RESPONSE_OBJECT, response);
+
+        context.reset();
+        objectmodel.put(ObjectModelHelper.CONTEXT_OBJECT, context);
+
+        redirector.reset();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.core.container.ContainerTestCase#addComponents(org.apache.cocoon.core.container.CocoonServiceManager)
+     */
+    protected void addComponents(CoreServiceManager manager) 
+    throws ServiceException, ConfigurationException {
+        super.addComponents(manager);
+        final String[] o = this.getSitemapComponentInfo();
+        if ( o != null ) {
+            final String typeClassName = o[0];
+            final String componentClassName = o[1];
+            final String key = o[2];
+            
+            // Create configuration for selector
+            final DefaultConfiguration df = new DefaultConfiguration("transformers");
+            final DefaultConfiguration factory = new DefaultConfiguration("component-instance");
+            factory.setAttribute("class", componentClassName);
+            factory.setAttribute("name", key);
+            df.addChild(factory);
+            manager.addComponent(typeClassName + "Selector", 
+                                 StandaloneServiceSelector.class.getName(), 
+                                 df,
+                                 null);
+        }
+    }
+
+    /**
+     * This triple can be used to add a sitemap component to the service manager
+     * @return A triple of strings: class name of the type, class name of the component, key
+     */
+    protected String[] getSitemapComponentInfo() {
+        return null;
+    }
+
+    /**
+     * Match with a pattern.
+     *
+     * @param type Hint of the matcher. 
+     * @param pattern Pattern for the matcher.
+     * @param parameters Matcher parameters.
+     */
+    public final Map match(String type, String pattern, Parameters parameters) throws PatternException {
+
+        ServiceSelector selector = null;
+        Matcher matcher = null;
+        SourceResolver resolver = null;
+
+        Map result = null;
+        try {
+            selector = (ServiceSelector) this.lookup(Matcher.ROLE +
+                "Selector");
+            assertNotNull("Test lookup of matcher selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if matcher name is not null", type);
+            matcher = (Matcher) selector.select(type);
+            assertNotNull("Test lookup of matcher", matcher);
+
+            result = matcher.match(pattern, objectmodel, parameters);
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve matcher", ce);
+            fail("Could not retrieve matcher: " + ce.toString());
+        } finally {
+            if (matcher != null) {
+                selector.release(matcher);
+            }
+            this.release(selector);
+            this.release(resolver);
+        }
+        return result;
+    }
+
+    /**
+     * Select with a pattern.
+     *
+     * @param type Hint of the matcher. 
+     * @param expression Expression for the selector.
+     * @param parameters Matcher parameters.
+     */
+    public final boolean select(String type, String expression, Parameters parameters) {
+
+        ServiceSelector selector = null;
+        org.apache.cocoon.selection.Selector sel = null;
+        SourceResolver resolver = null;
+
+        boolean result = false;
+        try {
+            selector = (ServiceSelector) this.lookup(org.apache.cocoon.selection.Selector.ROLE +
+                "Selector");
+            assertNotNull("Test lookup of selector selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if selector name is not null", type);
+            sel = (org.apache.cocoon.selection.Selector) selector.select(type);
+            assertNotNull("Test lookup of selector", sel);
+            
+
+            result = sel.select(expression, objectmodel, parameters);
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve selector", ce);
+            fail("Could not retrieve selector: " + ce.toString());
+        } finally {
+            if (sel != null) {
+                selector.release(sel);
+            }
+            this.release(selector);
+            this.release(resolver);
+        }
+        return result;
+    }
+
+    /**
+     * Perform the action component.
+     *
+     * @param type Hint of the action. 
+     * @param source Source for the action.
+     * @param parameters Action parameters.
+     */
+    public final Map act(String type, String source, Parameters parameters) throws Exception {
+        
+        redirector.reset();
+
+        ServiceSelector selector = null;
+        Action action = null;
+        SourceResolver resolver = null;
+
+        Map result = null;
+        try {
+            selector = (ServiceSelector) this.lookup(Action.ROLE +
+                "Selector");
+            assertNotNull("Test lookup of action selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if action name is not null", type);
+            action = (Action) selector.select(type);
+            assertNotNull("Test lookup of action", action);
+
+            result = action.act(redirector, new SourceResolverAdapter(resolver, this.getManager()),
+                                objectmodel, source, parameters);
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve action", ce);
+            fail("Could not retrieve action: " + ce.toString());
+        } finally {
+            if (action != null) {
+                selector.release(action);
+            }
+            this.release(selector);
+            this.release(resolver);
+        }
+        return result;
+    }
+
+    /**
+     * Generate the generator output.
+     *
+     * @param type Hint of the generator. 
+     * @param source Source for the generator.
+     * @param parameters Generator parameters.
+     */
+    public final Document generate(String type, String source, Parameters parameters) 
+        throws IOException, SAXException, ProcessingException {
+
+        ServiceSelector selector = null;
+        Generator generator = null;
+        SourceResolver resolver = null;
+        SAXParser parser = null;
+
+        Document document = null;
+        try {
+            selector = (ServiceSelector) this.lookup(Generator.ROLE +
+                "Selector");
+            assertNotNull("Test lookup of generator selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            parser = (SAXParser) this.lookup(SAXParser.ROLE);
+            assertNotNull("Test lookup of parser", parser);
+
+            assertNotNull("Test if generator name is not null", type);
+
+            generator = (Generator) selector.select(type);
+            assertNotNull("Test lookup of generator", generator);
+
+            generator.setup(new SourceResolverAdapter(resolver, getManager()),
+                            objectmodel, source, parameters);
+
+            DOMBuilder builder = new DOMBuilder();
+            generator.setConsumer(new WhitespaceFilter(builder));
+
+            generator.generate();
+
+            document = builder.getDocument();
+
+            assertNotNull("Test for generator document", document);
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve generator", ce);
+            fail("Could not retrieve generator: " + ce.toString());
+        } finally {
+            if (generator != null) {
+                selector.release(generator);
+            }
+            this.release(selector);
+            this.release(resolver);
+            this.release(parser);
+        }
+
+        return document;
+    }
+
+    /**     
+     * Trannsform a document by a transformer
+     *      
+     * @param type Hint of the transformer. 
+     * @param source Source for the transformer.
+     * @param parameters Generator parameters.
+     * @param input Input document.
+     */ 
+    public final Document transform(String type, String source, Parameters parameters, Document input) 
+    throws Exception {
+        // enter & leave environment, as a manager is looked up using
+        // the processing context stack
+        MockEnvironment env = new MockEnvironment();
+        Processor processor = new MockProcessor();
+        
+        EnvironmentHelper.enterProcessor(processor, this.getManager(), env);
+
+        try {
+            ServiceSelector selector = null;
+            Transformer transformer = null;
+            SourceResolver resolver = null;
+            SAXParser parser = null;
+            Source inputsource = null;
+    
+            assertNotNull("Test for component manager", this.getManager());
+    
+            Document document = null;
+            try {
+                selector = (ServiceSelector) this.lookup(Transformer.ROLE+
+                    "Selector");
+                assertNotNull("Test lookup of transformer selector", selector);
+    
+                resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+                assertNotNull("Test lookup of source resolver", resolver);
+    
+                parser = (SAXParser) this.lookup(SAXParser.ROLE);
+                assertNotNull("Test lookup of parser", parser);
+    
+    
+                assertNotNull("Test if transformer name is not null", type);
+                transformer = (Transformer) selector.select(type);
+                assertNotNull("Test lookup of transformer", transformer);
+    
+                transformer.setup(new SourceResolverAdapter(resolver, getManager()),
+                                      objectmodel, source, parameters);
+    
+                DOMBuilder builder = new DOMBuilder();
+                transformer.setConsumer(new WhitespaceFilter(builder));
+    
+                assertNotNull("Test if input document is not null", input);
+                DOMStreamer streamer = new DOMStreamer(transformer);
+                streamer.stream(input);
+    
+                document = builder.getDocument();
+                assertNotNull("Test for transformer document", document);
+    
+            } catch (ServiceException ce) {
+                getLogger().error("Could not retrieve transformer", ce);
+                ce.printStackTrace();
+                fail("Could not retrieve transformer:"+ce.toString());
+            } finally {
+                if (transformer!=null) {
+                    selector.release(transformer);
+                }
+    
+                if (selector!=null) {
+                    this.release(selector);
+                }
+    
+                if (inputsource!=null) {
+                    resolver.release(inputsource);
+                }
+    
+                if (resolver!=null) {
+                    this.release(resolver);
+                }
+    
+                if (parser!=null) {
+                    this.release(parser);
+                }
+            }
+    
+            return document;
+        } finally {
+            EnvironmentHelper.leaveProcessor();           
+        }
+    }
+
+    /**
+     * Serialize a document by a serializer
+     *
+     * @param type Hint of the serializer.
+     * @param parameters Serializer parameters.
+     * @param input Input document.
+     *
+     * @return Serialized data.
+     */
+    public final byte[] serialize(String type, Parameters parameters,
+                                  Document input) throws SAXException, IOException{
+
+        ServiceSelector selector = null;
+        Serializer serializer = null;
+        SourceResolver resolver = null;
+        Source inputsource = null;
+
+        assertNotNull("Test for component manager", this.getManager());
+
+        ByteArrayOutputStream document = null;
+
+        try {
+            selector = (ServiceSelector) this.lookup(Serializer.ROLE+
+                "Selector");
+            assertNotNull("Test lookup of serializer selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if serializer name is not null", type);
+            serializer = (Serializer) selector.select(type);
+            assertNotNull("Test lookup of serializer", serializer);
+
+            document = new ByteArrayOutputStream();
+            serializer.setOutputStream(document);
+
+            assertNotNull("Test if input document is not null", input);
+            DOMStreamer streamer = new DOMStreamer(serializer);
+
+            streamer.stream(input);
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve serializer", ce);
+            fail("Could not retrieve serializer:"+ce.toString());
+        } finally {
+            if (serializer!=null) {
+                selector.release(serializer);
+            }
+
+            if (selector!=null) {
+                this.release(selector);
+            }
+
+            if (inputsource!=null) {
+                resolver.release(inputsource);
+            }
+
+            if (resolver!=null) {
+                this.release(resolver);
+            }
+        }
+
+        return document.toByteArray();
+    }
+    
+    public String callFunction(String type, String source, String function, Map params) throws Exception {
+        
+        redirector.reset();
+        
+        ServiceSelector selector = null;
+        Interpreter interpreter = null;
+        SourceResolver resolver = null;
+
+        try {
+            selector = (ServiceSelector) this.lookup(Interpreter.ROLE + "Selector");
+            assertNotNull("Test lookup of interpreter selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if interpreter name is not null", type);
+            interpreter = (Interpreter) selector.select(type);
+            assertNotNull("Test lookup of interpreter", interpreter);
+            
+            ((AbstractInterpreter)interpreter).register(source);
+            
+            ArrayList parameters = new ArrayList();
+            for (Iterator i = params.keySet().iterator(); i.hasNext();) {
+                String name = (String)i.next();
+                String value = (String)params.get(name);
+                parameters.add(new Interpreter.Argument(name, value));
+            }
+            
+            interpreter.callFunction(function, parameters, getRedirector());
+            
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve interpeter", ce);
+            fail("Could not retrieve interpreter: " + ce.toString());
+        } finally {
+            if (interpreter != null) {
+                selector.release(interpreter);
+            }
+            this.release(selector);
+            this.release(resolver);
+        }
+        return FlowHelper.getWebContinuation(getObjectModel()).getId();
+    }
+    
+    public String callContinuation(String type, String source, String id, Map params) throws Exception {
+        
+        redirector.reset();
+        
+        ServiceSelector selector = null;
+        Interpreter interpreter = null;
+        SourceResolver resolver = null;
+
+        try {
+            selector = (ServiceSelector) this.lookup(Interpreter.ROLE + "Selector");
+            assertNotNull("Test lookup of interpreter selector", selector);
+
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            assertNotNull("Test if interpreter name is not null", type);
+            interpreter = (Interpreter) selector.select(type);
+            assertNotNull("Test lookup of interpreter", interpreter);
+
+            ((AbstractInterpreter)interpreter).register(source);
+            
+            ArrayList parameters = new ArrayList();
+            for (Iterator i = params.keySet().iterator(); i.hasNext();) {
+                String name = (String)i.next();
+                String value = (String)params.get(name);
+                parameters.add(new Interpreter.Argument(name, value));
+            }
+            
+            interpreter.handleContinuation(id, parameters, getRedirector());
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve interpreter", ce);
+            fail("Could not retrieve interpreter: " + ce.toString());
+        } finally {
+            if (interpreter != null) {
+                selector.release(interpreter);
+            }
+            this.release(selector);
+            this.release(resolver);
+        }
+        return FlowHelper.getWebContinuation(getObjectModel()).getId();
+    }
+    
+    public Object getFlowContextObject() {
+        return FlowHelper.getContextObject(getObjectModel());
+    }
+
+    public final void print(Document document) {
+        TransformerFactory factory = TransformerFactory.newInstance();
+        try
+        {
+          javax.xml.transform.Transformer serializer = factory.newTransformer();
+          serializer.transform(new DOMSource(document), new StreamResult(System.out));
+          System.out.println();
+        } 
+        catch (TransformerException te)
+        {
+          te.printStackTrace();
+        }
+    }
+
+    public final Document load(String source) {
+
+        SourceResolver resolver = null;
+        SAXParser parser = null;
+        Source assertionsource = null;
+
+        assertNotNull("Test for component manager", this.getManager());
+
+        Document assertiondocument = null;
+        try {
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            parser = (SAXParser) this.lookup(SAXParser.ROLE);
+            assertNotNull("Test lookup of parser", parser);
+
+            assertNotNull("Test if assertion document is not null",
+                          source);
+            assertionsource = resolver.resolveURI(source);
+            assertNotNull("Test lookup of assertion source",
+                          assertionsource);
+            assertTrue("Source '" + assertionsource.getURI() + "' must exist", assertionsource.exists());
+
+            DOMBuilder builder = new DOMBuilder();
+            assertNotNull("Test if inputstream of the assertion source is not null",
+                          assertionsource.getInputStream());
+
+            parser.parse(new InputSource(assertionsource.getInputStream()),
+                         new WhitespaceFilter(builder),
+                         builder);
+
+            assertiondocument = builder.getDocument();
+            assertNotNull("Test if assertion document exists", assertiondocument);
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve generator", ce);
+            fail("Could not retrieve generator: " + ce.toString());
+        } catch (Exception e) {
+            getLogger().error("Could not execute test", e);
+            fail("Could not execute test: " + e);
+        } finally {
+            if (resolver != null) {
+                resolver.release(assertionsource);
+            }
+            this.release(resolver);
+            this.release(parser);
+        }
+
+        return assertiondocument;
+    }
+
+    /**
+     * Load a binary document.
+     *
+     * @param source Source location.
+     *
+     * @return Binary data.
+     */
+    public final byte[] loadByteArray(String source) {
+
+        SourceResolver resolver = null;
+        SAXParser parser = null;
+        Source assertionsource = null;
+
+        assertNotNull("Test for component manager", this.getManager());
+
+        byte[] assertiondocument = null;
+
+        try {
+            resolver = (SourceResolver) this.lookup(SourceResolver.ROLE);
+            assertNotNull("Test lookup of source resolver", resolver);
+
+            parser = (SAXParser) this.lookup(SAXParser.ROLE);
+            assertNotNull("Test lookup of parser", parser);
+
+            assertNotNull("Test if assertion document is not null", source);
+            assertionsource = resolver.resolveURI(source);
+            assertNotNull("Test lookup of assertion source", assertionsource);
+            assertTrue("Test if source exist", assertionsource.exists());
+
+            assertNotNull("Test if inputstream of the assertion source is not null",
+                          assertionsource.getInputStream());
+
+            InputStream input = assertionsource.getInputStream();
+            long size = assertionsource.getContentLength();
+
+            assertiondocument = new byte[(int) size];
+            int i = 0;
+            int c;
+
+            while ((c = input.read())!=-1) {
+                assertiondocument[i] = (byte) c;
+                i++;
+            }
+
+        } catch (ServiceException ce) {
+            getLogger().error("Could not retrieve generator", ce);
+            fail("Could not retrieve generator: "+ce.toString());
+        } catch (Exception e) {
+            getLogger().error("Could not execute test", e);
+            fail("Could not execute test: "+e);
+        } finally {
+            if (resolver!=null) {
+                resolver.release(assertionsource);
+            }
+            this.release(resolver);
+            this.release(parser);
+        }
+
+        return assertiondocument;
+    }
+
+    /**
+     * Compare two XML documents provided as strings
+     * @param control Control document
+     * @param test Document to test
+     * @return Diff object describing differences in documents
+     */
+    public final Diff compareXML(Document control, Document test) {
+        return new Diff(control, test);
+    }
+
+    /**
+     * Assert that the result of an XML comparison is similar.
+     *
+     * @param msg The assertion message
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertEqual(String msg, Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals(msg + ", " + diff.toString(), true, diff.similar());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is similar.
+     *
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */  
+    public final void assertEqual(Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals("Test if the assertion document is equal, " + diff.toString(), true, diff.similar());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is identical.
+     *
+     * @param msg The assertion message
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertIdentical(String msg, Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals(msg + ", " + diff.toString(), true, diff.identical());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is identical.
+     *
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertIdentical(Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals("Test if the assertion document is equal, " + diff.toString(), true, diff.identical());
+    }
+
+    /**
+     * Assert that the result of a byte comparison is identical.
+     *
+     * @param expected The expected byte array
+     * @param actual The actual byte array
+     */
+    public final void assertIdentical(byte[] expected, byte[] actual) {
+        assertEquals("Byte arrays of differing sizes, ", expected.length,
+                     actual.length);
+
+        if (expected.length>0) {
+            for (int i = 0; i<expected.length; i++) {
+                assertEquals("Byte array differs at index "+i, expected[i],
+                             actual[i]);
+            }
+        }
+
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.java
new file mode 100644
index 0000000..938385b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.mock.MockRequest;
+
+/**
+ *
+ *
+ * @version $Id$
+ */
+public class RequestParamActionTestCase extends TestCase {
+    private Map objectModel = new HashMap();
+
+    public RequestParamActionTestCase(String name) {
+        super(name);
+    }
+
+    public void testRequestAction() throws Exception {
+
+        MockRequest request = new MockRequest();
+        request.setRequestURI("test.xml?abc=def&ghi=jkl");
+        request.setQueryString("abc=def&ghi=jkl");
+        request.setContextPath("servlet");
+        request.addParameter("abc", "def");
+        objectModel.put(ObjectModelHelper.REQUEST_OBJECT, request);
+
+        Parameters parameters = new Parameters();
+        parameters.setParameter("parameters", "true");
+
+        RequestParamAction action = new RequestParamAction();
+        Map result = action.act(null, null, objectModel, null, parameters); 
+
+        assertNotNull("Test if resource exists", result);
+        assertEquals("Test for parameter", "test.xml?abc=def&ghi=jkl", result.get("requestURI"));
+        assertEquals("Test for parameter", "?abc=def&ghi=jkl", result.get("requestQuery"));
+        assertEquals("Test for parameter", "servlet", result.get("context"));
+        assertEquals("Test for parameter", "def", result.get("abc"));
+        assertNull("Test for parameter", result.get("ghi"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.xtest
new file mode 100644
index 0000000..f631306
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/RequestParamActionTestCase.xtest
@@ -0,0 +1,46 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.excalibur.source.SourceFactorySelector"
+        shorthand="source-factories"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+
+  <role name="org.apache.excalibur.source.SourceResolver"
+        shorthand="source-resolver"
+        default-class="org.apache.excalibur.source.impl.SourceResolverImpl"/>
+
+  <role name="org.apache.cocoon.acting.ActionSelector"
+        shorthand="actions"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <source-factories>
+   <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+   <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <source-resolver class="org.apache.excalibur.source.impl.SourceResolverImpl"/>
+
+  <actions logger="test">
+   <component-instance class="org.apache.cocoon.acting.RequestParamAction" 
+                       name="request"/>
+  </actions>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/ResourceExistsActionTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/ResourceExistsActionTestCase.java
new file mode 100644
index 0000000..60e4092
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/acting/ResourceExistsActionTestCase.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.acting;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.MockLogger;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+/**
+ *
+ *
+ * @version $Id$
+ */
+public class ResourceExistsActionTestCase extends MockObjectTestCase {
+    private Map objectModel = new HashMap();
+
+    public ResourceExistsActionTestCase(String name) {
+        super(name);
+    }
+
+    public void testExists() throws Exception {
+        String src = "don't care";
+        Parameters parameters = new Parameters();
+        ResourceExistsAction action = new ResourceExistsAction();
+        action.enableLogging(new MockLogger(action.getClass()));
+        Mock resolver = new Mock(SourceResolver.class);
+        Mock source = new Mock(Source.class);
+        resolver.expects(once()).method("resolveURI").with(same(src)).
+                will(returnValue(source.proxy()));
+        resolver.expects(once()).method("release").with(same(source.proxy()));
+        source.expects(atLeastOnce()).method("exists").will(returnValue(true));
+        Map result = action.act(null, (SourceResolver) resolver.proxy(), 
+                objectModel, src, parameters);
+        assertSame("Test if resource exists", AbstractAction.EMPTY_MAP, result);
+        resolver.verify();
+        source.verify();
+    }
+
+    public void testNotExists() throws Exception {
+        String src = "don't care";
+        Parameters parameters = new Parameters();
+        ResourceExistsAction action = new ResourceExistsAction();
+        action.enableLogging(new MockLogger(action.getClass()));
+        Mock resolver = new Mock(SourceResolver.class);
+        resolver.expects(once()).method("resolveURI").with(same(src)).
+                will(this.throwException(new SourceNotFoundException("don't care")));
+        Map result = action.act(null, (SourceResolver) resolver.proxy(), 
+                objectModel, src, parameters);
+        assertNull("Test if resource not exists", result);
+        resolver.verify();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/bean/CocoonBeanTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/bean/CocoonBeanTestCase.java
new file mode 100644
index 0000000..99170ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/bean/CocoonBeanTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.bean;
+
+import java.io.ByteArrayOutputStream;
+
+import org.apache.cocoon.bean.helpers.OutputStreamListener;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>Test case for the CocoonBean.</p>
+ * 
+ * <p>To function correctly, this test case expects a built webapp at
+ *    <code>build/webapp/</code>, which includes the test-suite 
+ *    within it. Ensure this is included in build.properties by
+ *    commenting out <code>exclude.webapp.test-suite=true</code>.</p>
+ * 
+ * @version $Id$
+ */
+public class CocoonBeanTestCase extends TestCase {
+
+	/**
+	 * Constructor for CocoonBeanTest.
+	 * @param arg0
+	 */
+	public CocoonBeanTestCase(String arg0) {
+		super(arg0);
+        
+	}
+    
+    public void testProcessToStream() throws Exception {
+        CocoonBean cocoon = getCocoonBean();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        cocoon.processURI("test-suite/static-site/index.html", baos);
+        String result = baos.toString();
+        assertEquals(1603, result.length());
+        assertTrue(result.indexOf("Cocoon TestSuite")>-1);
+        assertTrue(result.indexOf("<h1>General information</h1>")>-1);
+        cocoon.dispose();
+    }
+    
+    private CocoonBean getCocoonBean() throws Exception {
+        CocoonBean cocoon = new CocoonBean();
+        cocoon.setContextDir("build/webapp");
+        cocoon.setConfigFile("WEB-INF/cocoon.xconf");
+        cocoon.setPrecompileOnly(false);
+        cocoon.setWorkDir("build/work");
+        cocoon.setLogKit("build/webapp/WEB-INF/logkit.xconf");
+        cocoon.setLogger("cli-test");
+        cocoon.setLogLevel("DEBUG");
+        //cocoon.setAgentOptions(*something*));
+        //cocoon.setAcceptOptions(*something*);
+        //cocoon.setDefaultFilename(*something*);
+        //listener.setReportFile(*something*);
+        cocoon.setFollowLinks(true);
+        cocoon.setConfirmExtensions(false);
+        //cocoon.addLoadedClasses(Arrays.asList(*something*));
+        //cocoon.addTargets(BeanConfigurator.processURIFile(*some file*), destDir);
+        cocoon.addListener(new OutputStreamListener(System.out));
+        cocoon.initialize();
+        return cocoon;        
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/sax/XMLByteStreamCompilerInterpreterTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/sax/XMLByteStreamCompilerInterpreterTestCase.java
new file mode 100644
index 0000000..278865a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/sax/XMLByteStreamCompilerInterpreterTestCase.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.sax;
+
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.ContentHandler;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.cocoon.xml.AbstractXMLTestCase;
+import org.apache.cocoon.xml.DefaultHandlerWrapper;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Testcase for XMLByteStreamCompiler and Interpreter
+ *
+ */
+public final class XMLByteStreamCompilerInterpreterTestCase extends AbstractXMLTestCase {
+    public XMLByteStreamCompilerInterpreterTestCase(String s) {
+        super(s);
+    }
+
+    public void testCompareDOM() throws Exception {
+        // reference
+        DOMBuilder in = new DOMBuilder();
+        generateLargeSAX(in);
+
+        // capture events
+        XMLByteStreamCompiler xmlc = new XMLByteStreamCompiler();
+        generateLargeSAX(xmlc);
+
+        // recall events and build a DOM from it
+        XMLByteStreamInterpreter xmli = new XMLByteStreamInterpreter();
+        DOMBuilder out = new DOMBuilder();
+        xmli.setConsumer(out);
+        xmli.deserialize(xmlc.getSAXFragment());
+
+        // compare DOMs
+        assertXMLEqual(in.getDocument(), out.getDocument());
+    }
+
+    public void testCompareByteArray() throws Exception {
+        // capture events
+        XMLByteStreamCompiler sa = new XMLByteStreamCompiler();
+        generateLargeSAX(sa);
+
+        // serialize events
+        byte[] aa = (byte[]) sa.getSAXFragment();
+
+        // deserialize and capture
+        XMLByteStreamCompiler sb = new XMLByteStreamCompiler();
+        XMLByteStreamInterpreter xmli = new XMLByteStreamInterpreter();
+        xmli.setConsumer(sb);
+        xmli.deserialize(aa);
+
+        // serialize again
+        byte[] ab = (byte[]) sb.getSAXFragment();
+
+        assertTrue(aa.length == ab.length);
+
+        for (int i=0;i<aa.length;i++) {
+            assertEquals(aa[i],ab[i]);
+        }
+    }
+
+    public void testStressLoop() throws Exception {
+        XMLByteStreamCompiler xmlc = new XMLByteStreamCompiler();
+
+        long loop = 10000;
+
+        // simply consume documents
+        long start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            generateSmallSAX(xmlc);
+            xmlc.recycle();
+        }
+        long stop = System.currentTimeMillis();
+
+        double r = 1000*loop/(stop-start);
+        System.out.println("consuming: "+ r + " documents per second");
+    }
+
+    public void testCompareToParsing() throws Exception {
+        DOMBuilder in = new DOMBuilder();
+        generateSmallSAX(in);
+
+        SAXParserFactory pfactory = SAXParserFactory.newInstance();
+        SAXParser p = pfactory.newSAXParser();
+
+        XMLByteStreamCompiler xmlc = new XMLByteStreamCompiler();
+        DefaultHandlerWrapper wrapper = new DefaultHandlerWrapper(xmlc);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(generateByteArray());
+
+        long loop = 10000;
+
+        // parse documents
+        long start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            xmlc.recycle();
+            bis.reset();
+            p.parse(bis,wrapper);
+        }
+        long stop = System.currentTimeMillis();
+
+        double r = 1000*loop/(stop-start);
+        System.out.println("parsed: " + r + " documents per second");
+
+
+        XMLByteStreamInterpreter xmli = new XMLByteStreamInterpreter();
+        ContentHandler ch = new DefaultHandler();
+
+        // recall documents
+        start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            xmli.setContentHandler(ch);
+            xmli.deserialize(xmlc.getSAXFragment());
+        }
+        stop = System.currentTimeMillis();
+
+        r = 1000*loop/(stop-start);
+        System.out.println("recalling: " + r + " documents per second");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/source/SourceResolverAdapter.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/source/SourceResolverAdapter.java
new file mode 100644
index 0000000..7d484ae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/source/SourceResolverAdapter.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.source;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+
+/**
+ * An adapter for the Excalibur SourceResolver.
+ *
+ * @version $Id$
+ */
+public class SourceResolverAdapter implements SourceResolver
+{
+    private org.apache.excalibur.source.SourceResolver resolver;
+
+    public SourceResolverAdapter(org.apache.excalibur.source.SourceResolver resolver, ServiceManager manager) {
+        this.resolver = resolver;
+    }
+
+    /**
+     * Get a <code>Source</code> object.
+     * This is a shortcut for <code>resolve(location, null, null)</code>
+     * @throws org.apache.excalibur.source.SourceException if the source cannot be resolved
+     */
+    public Source resolveURI( String location )
+        throws MalformedURLException, IOException, SourceException {
+  
+        return this.resolver.resolveURI(location);
+    }
+
+    /**
+     * Get a <code>Source</code> object.
+     * @param location - the URI to resolve. If this is relative it is either
+     *                   resolved relative to the base parameter (if not null)
+     *                   or relative to a base setting of the source resolver
+     *                   itself.
+     * @param base - a base URI for resolving relative locations. This
+     *               is optional and can be <code>null</code>.
+     * @param parameters - Additional parameters for the URI. The parameters
+     *                     are specific to the used protocol.
+     * @throws org.apache.excalibur.source.SourceException if the source cannot be resolved
+     */
+    public Source resolveURI( String location,
+                                                          String base,
+                                                          Map parameters )
+        throws MalformedURLException, IOException, SourceException {
+
+        return this.resolver.resolveURI(location, base, parameters);
+    }
+
+    /**
+     * Releases a resolved resource
+     */
+    public void release( Source source ) {
+        this.resolver.release(source);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/AbstractTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/AbstractTestCase.java
new file mode 100644
index 0000000..63ea1ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/AbstractTestCase.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.easymock.MockControl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+
+/**
+ * A {@link TestCase}with convenience methods to ease creation of Avalon mock
+ * classes.
+ *
+ * @version $Id$
+ */
+public class AbstractTestCase
+    extends TestCase
+{
+    //~ Instance fields --------------------------------------------------------
+
+    /**
+     * The {@link List}of {@link MockControl}s creted by the
+     * <code>create...Control</code> methods
+     */
+    private List m_controls;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Constructor
+     *
+     * @param name
+     */
+    public AbstractTestCase( String name )
+    {
+        super( name );
+    }
+
+    /**
+     * Constructor
+     */
+    public AbstractTestCase(  )
+    {
+        super(  );
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * Create an empty list for {@link MockControl}s created by
+     * <code>create...Control</code> methods
+     *
+     * @throws Exception
+     */
+    protected void setUp(  )
+        throws Exception
+    {
+        super.setUp(  );
+        m_controls = new ArrayList(  );
+    }
+
+    /**
+     * Create a mock {@link Configuration}instance that has a boolean value
+     *
+     * @param value The value to return
+     * @param defaultValue The value accepted as the default value
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createBooleanConfigMock( final boolean value,
+                                                     final boolean defaultValue )
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsBoolean( defaultValue );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a mock {@link Configuration}instance that has a boolean value
+     *
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     *
+     * @throws ConfigurationException
+     */
+    protected Configuration createBooleanConfigMock( final boolean value )
+        throws ConfigurationException
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsBoolean(  );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a child
+     *
+     * @param name The value accepted as the name for the child
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createChildConfigMock( final String name,
+                                                   final Configuration value )
+    {
+        final MockControl childConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration childConfig =
+            (Configuration)childConfigControl.getMock(  );
+        childConfig.getChild( name );
+        childConfigControl.setReturnValue( value );
+        childConfigControl.replay(  );
+
+        return childConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a boolean value
+     *
+     * @param name The value accepted as the name for the children
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createChildrenConfigMock( final String name,
+                                                      final Configuration [] value )
+    {
+        final MockControl childrenConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration childrenConfig =
+            (Configuration)childrenConfigControl.getMock(  );
+        childrenConfig.getChildren( name );
+        childrenConfigControl.setReturnValue( value );
+        childrenConfigControl.replay(  );
+
+        return childrenConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a int value
+     *
+     * @param value The value to return
+     * @param defaultValue The value accepted as the default value
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createIntegerConfigMock( final int value,
+                                                     final int defaultValue )
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsInteger( defaultValue );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a int value
+     *
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     *
+     * @throws ConfigurationException
+     */
+    protected Configuration createIntegerConfigMock( final int value )
+        throws ConfigurationException
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsInteger(  );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a long value
+     *
+     * @param value The value to return
+     * @param defaultValue The value accepted as the default value
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createLongConfigMock( final long value,
+                                                  final long defaultValue )
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsLong( defaultValue );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a long value
+     *
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     *
+     * @throws ConfigurationException
+     */
+    protected Configuration createLongConfigMock( final long value )
+        throws ConfigurationException
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValueAsLong(  );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a strict mock control
+     *
+     * @param clazz The interface class the mock object should represent
+     *
+     * @return The mock instance
+     */
+    protected MockControl createStrictControl( final Class clazz )
+    {
+        final MockControl control = MockControl.createStrictControl( clazz );
+        m_controls.add( control );
+
+        return control;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a string value
+     *
+     * @param value The value to return
+     * @param defaultValue The value accepted as the default value
+     *
+     * @return A mock <code>Configuration</code>
+     */
+    protected Configuration createValueConfigMock( final String value,
+                                                   final String defaultValue )
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValue( defaultValue );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * Create a {@link Configuration}instance that has a string value
+     *
+     * @param value The value to return
+     *
+     * @return A mock <code>Configuration</code>
+     *
+     * @throws ConfigurationException
+     */
+    protected Configuration createValueConfigMock( final String value )
+        throws ConfigurationException
+    {
+        final MockControl valueConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration valueConfig =
+            (Configuration)valueConfigControl.getMock(  );
+        valueConfig.getValue(  );
+        valueConfigControl.setReturnValue( value );
+        valueConfigControl.replay(  );
+
+        return valueConfig;
+    }
+
+    /**
+     * @see TestCase#tearDown()
+     */
+    protected void tearDown(  )
+        throws Exception
+    {
+        m_controls = null;
+    }
+
+    /**
+     * Verify all <code>MockCOntrol</code>s
+     */
+    protected void verify(  )
+    {
+        for( Iterator i = m_controls.iterator(  ); i.hasNext(  ); )
+        {
+            final MockControl control = (MockControl)i.next(  );
+            control.verify(  );
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultRunnableManagerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultRunnableManagerTestCase.java
new file mode 100644
index 0000000..0a60c13
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultRunnableManagerTestCase.java
@@ -0,0 +1,1110 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.easymock.MockControl;
+
+/**
+ * The $classType$ class ...
+ *
+ * @version $Id$
+ */
+public class DefaultRunnableManagerTestCase extends AbstractTestCase
+{
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Constructor for DefaultRunnableManagerTestCase.
+     *
+     * @param name
+     */
+    public DefaultRunnableManagerTestCase( String name )
+    {
+        super( name );
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    public final void testConfigureDaemonPool(  )
+    throws Exception
+    {
+        final MockControl threadPoolConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration threadPoolConfig =
+            (Configuration)threadPoolConfigControl.getMock(  );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "name" ),
+                                                 createValueConfigMock( "daemon" ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "queue-size" ),
+                                                 createIntegerConfigMock( 2 * DefaultRunnableManager.DEFAULT_QUEUE_SIZE,
+                                                                          DefaultRunnableManager.DEFAULT_QUEUE_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "max-pool-size" ),
+                                                 createIntegerConfigMock( 2 * DefaultRunnableManager.DEFAULT_MAX_POOL_SIZE,
+                                                                          DefaultRunnableManager.DEFAULT_MAX_POOL_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "min-pool-size" ),
+                                                 createIntegerConfigMock( DefaultRunnableManager.DEFAULT_MIN_POOL_SIZE / 3,
+                                                                          DefaultRunnableManager.DEFAULT_MIN_POOL_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "priority" ),
+                                                 createValueConfigMock( "LOW",
+                                                                        DefaultRunnableManager.DEFAULT_THREAD_PRIORITY ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "daemon" ),
+                                                 createBooleanConfigMock( false,
+                                                                          DefaultRunnableManager.DEFAULT_DAEMON_MODE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "keep-alive-time-ms" ),
+                                                 createLongConfigMock( DefaultRunnableManager.DEFAULT_KEEP_ALIVE_TIME / 2,
+                                                                       DefaultRunnableManager.DEFAULT_KEEP_ALIVE_TIME ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "block-policy" ),
+                                                 createValueConfigMock( "WAIT",
+                                                                        DefaultThreadPool.POLICY_DEFAULT ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "shutdown-graceful" ),
+                                                 createBooleanConfigMock( true,
+                                                                          DefaultRunnableManager.DEFAULT_SHUTDOWN_GRACEFUL ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "shutdown-wait-time-ms" ),
+                                                 createIntegerConfigMock( DefaultRunnableManager.DEFAULT_SHUTDOWN_WAIT_TIME / 2,
+                                                                          DefaultRunnableManager.DEFAULT_SHUTDOWN_WAIT_TIME ) );
+        threadPoolConfigControl.replay(  );
+
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration []
+                                                                     {
+                                                                         threadPoolConfig
+                                                                     } ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDaemonControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDaemon =
+            (Logger)childLoggerDaemonControl.getMock(  );
+        childLoggerDaemonControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        logger.warn( "Unknown thread priority \"LOW\". Set to \"NORM\"." );
+        loggerControl.expectAndReturn( logger.getChildLogger( "daemon" ),
+                                       childLoggerDaemon );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"daemon\" created with maximum queue-size=2147483647,max-pool-size=10,min-pool-size=1,priority=5,isDaemon=false,keep-alive-time-ms=30000,block-policy=\"WAIT\",shutdown-wait-time-ms=0" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool daemon" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool daemon disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        runnableManager.dispose(  );
+        verify(  );
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testConfigureMinimal(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        runnableManager.dispose(  );
+        verify(  );
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws Exception DOCUMENT ME!
+     */
+    public final void testConfigureMyPool(  )
+        throws Exception
+    {
+        final MockControl threadPoolConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration threadPoolConfig =
+            (Configuration)threadPoolConfigControl.getMock(  );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "name" ),
+                                                 createValueConfigMock( "mypool" ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "queue-size" ),
+                                                 createIntegerConfigMock( 2 * DefaultRunnableManager.DEFAULT_QUEUE_SIZE,
+                                                                          DefaultRunnableManager.DEFAULT_QUEUE_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "max-pool-size" ),
+                                                 createIntegerConfigMock( 2 * DefaultRunnableManager.DEFAULT_MAX_POOL_SIZE,
+                                                                          DefaultRunnableManager.DEFAULT_MAX_POOL_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "min-pool-size" ),
+                                                 createIntegerConfigMock( DefaultRunnableManager.DEFAULT_MIN_POOL_SIZE / 3,
+                                                                          DefaultRunnableManager.DEFAULT_MIN_POOL_SIZE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "priority" ),
+                                                 createValueConfigMock( "MIN",
+                                                                        DefaultRunnableManager.DEFAULT_THREAD_PRIORITY ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "daemon" ),
+                                                 createBooleanConfigMock( false,
+                                                                          DefaultRunnableManager.DEFAULT_DAEMON_MODE ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "keep-alive-time-ms" ),
+                                                 createLongConfigMock( DefaultRunnableManager.DEFAULT_KEEP_ALIVE_TIME / 2,
+                                                                       DefaultRunnableManager.DEFAULT_KEEP_ALIVE_TIME ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "block-policy" ),
+                                                 createValueConfigMock( "WAIT",
+                                                                        DefaultThreadPool.POLICY_DEFAULT ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "shutdown-graceful" ),
+                                                 createBooleanConfigMock( true,
+                                                                          DefaultRunnableManager.DEFAULT_SHUTDOWN_GRACEFUL ) );
+        threadPoolConfigControl.expectAndReturn( threadPoolConfig.getChild( "shutdown-wait-time-ms" ),
+                                                 createIntegerConfigMock( DefaultRunnableManager.DEFAULT_SHUTDOWN_WAIT_TIME / 2,
+                                                                          DefaultRunnableManager.DEFAULT_SHUTDOWN_WAIT_TIME ) );
+        threadPoolConfigControl.replay(  );
+
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration []
+                                                                     {
+                                                                         threadPoolConfig
+                                                                     } ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerMyPoolControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerMyPool =
+            (Logger)childLoggerMyPoolControl.getMock(  );
+        childLoggerMyPoolControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "mypool" ),
+                                       childLoggerMyPool );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"mypool\" created with maximum queue-size=2147483647,max-pool-size=10,min-pool-size=1,priority=1,isDaemon=false,keep-alive-time-ms=30000,block-policy=\"WAIT\",shutdown-wait-time-ms=0" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool mypool" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool mypool disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        runnableManager.dispose(  );
+        verify(  );
+    }
+
+    /**
+     * Class under test for void createPool(String, int, int, int, int,
+     * boolean, long, String, boolean, int)
+     */
+    public final void testCreatePoolStringintintintintbooleanlongStringbooleanint(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerMyPoolControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerMyPool =
+            (Logger)childLoggerMyPoolControl.getMock(  );
+        childLoggerMyPoolControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "mypool" ),
+                                       childLoggerMyPool );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"mypool\" created with maximum queue-size=230,max-pool-size=15,min-pool-size=12,priority=1,isDaemon=false,keep-alive-time-ms=15500,block-policy=\"DISCARD\",shutdown-wait-time-ms=22200" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool mypool" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool mypool disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        runnableManager.createPool( "mypool", 230, 15, 12, Thread.MIN_PRIORITY,
+                                    false, 15500, "DISCARD", false, 22200 );
+        runnableManager.dispose(  );
+        verify(  );
+    }
+
+    /**
+     * Class under test for ThreadPool createPool(int, int, int, int, boolean,
+     * long, String, boolean, int)
+     */
+    public final void testCreatePoolintintintintbooleanlongStringbooleanint(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerAnonControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerAnon =
+            (Logger)childLoggerAnonControl.getMock(  );
+        childLoggerAnonControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "anon-xxx" ),
+                                       childLoggerAnon );
+        loggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"anon-xxx\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=10,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool anon-xxx" );
+        loggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool anon-xxx disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final ThreadPool threadPool =
+            runnableManager.createPool( 200, 5, 2, Thread.MAX_PRIORITY, true,
+                                        15000, "ABORT", true, 22000 );
+        assertEquals( "queue-size", 200, threadPool.getMaximumQueueSize(  ) );
+        assertEquals( "max-pool-size", 5, threadPool.getMaximumPoolSize(  ) );
+        assertEquals( "min-pool-size", 2, threadPool.getMinimumPoolSize(  ) );
+        assertEquals( "priority", Thread.MAX_PRIORITY,
+                      threadPool.getPriority(  ) );
+        assertEquals( "keep-alive-time-ms", 15000,
+                      threadPool.getKeepAliveTime(  ) );
+        assertEquals( "block-policy", "ABORT", threadPool.getBlockPolicy(  ) );
+        runnableManager.dispose(  );
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(Runnable)
+     */
+    public final void testExecuteRunnable(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerControl =
+            createStrictControl( Logger.class );
+        final Logger childLogger = (Logger)childLoggerControl.getMock(  );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLogger );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=default, delay=0, interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"default\", schedule with interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.execute( runnable );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(Runnable, long)
+     */
+    public final void testExecuteRunnablelong(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerControl =
+            createStrictControl( Logger.class );
+        final Logger childLogger = (Logger)childLoggerControl.getMock(  );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLogger );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=default, delay=100, interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"default\", schedule with interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.execute( runnable, 100, 0 );
+            Thread.yield(  );
+            Thread.sleep( 200 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(Runnable, long, long)
+     */
+    public final void testExecuteRunnablelonglong(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerControl =
+            createStrictControl( Logger.class );
+        final Logger childLogger = (Logger)childLoggerControl.getMock(  );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerControl.expectAndReturn( childLogger.isDebugEnabled(  ), true );
+        childLogger.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLogger );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=default, delay=100, interval=100" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"default\", schedule with interval=100" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.setVoidCallable( MockControl.ONE_OR_MORE );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.execute( runnable, 100, 100 );
+            Thread.yield(  );
+            Thread.sleep( 200 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(String, Runnable)
+     */
+    public final void testExecuteStringRunnable(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.expectAndReturn( childLoggerDefault.isDebugEnabled(  ),
+                                                   true );
+        childLoggerDefault.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerDefaultControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerMyPoolControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerMyPool =
+            (Logger)childLoggerMyPoolControl.getMock(  );
+        childLoggerMyPoolControl.expectAndReturn( childLoggerMyPool.isDebugEnabled(  ),
+                                                  true );
+        childLoggerMyPool.debug( "Executing Command: EasyMock for interface java.lang.Runnable,pool=mypool" );
+        childLoggerMyPoolControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "mypool" ),
+                                       childLoggerMyPool );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"mypool\" created with maximum queue-size=230,max-pool-size=15,min-pool-size=12,priority=1,isDaemon=false,keep-alive-time-ms=15500,block-policy=\"DISCARD\",shutdown-wait-time-ms=22200" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=mypool, delay=0, interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"mypool\", schedule with interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool mypool" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool mypool disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.createPool( "mypool", 230, 15, 12,
+                                        Thread.MIN_PRIORITY, false, 15500,
+                                        "DISCARD", false, 22200 );
+            runnableManager.execute( "mypool", runnable );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(String, Runnable, long)
+     */
+    public final void testExecuteStringRunnablelong(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.expectAndReturn( childLoggerDefault.isDebugEnabled(  ),
+                                                   true );
+        childLoggerDefault.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerDefaultControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerMyPoolControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerMyPool =
+            (Logger)childLoggerMyPoolControl.getMock(  );
+        childLoggerMyPoolControl.expectAndReturn( childLoggerMyPool.isDebugEnabled(  ),
+                                                  true );
+        childLoggerMyPool.debug( "Executing Command: EasyMock for interface java.lang.Runnable,pool=mypool" );
+        childLoggerMyPoolControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "mypool" ),
+                                       childLoggerMyPool );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"mypool\" created with maximum queue-size=230,max-pool-size=15,min-pool-size=12,priority=1,isDaemon=false,keep-alive-time-ms=15500,block-policy=\"DISCARD\",shutdown-wait-time-ms=22200" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=mypool, delay=100, interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"mypool\", schedule with interval=0" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool mypool" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool mypool disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.createPool( "mypool", 230, 15, 12,
+                                        Thread.MIN_PRIORITY, false, 15500,
+                                        "DISCARD", false, 22200 );
+            runnableManager.execute( "mypool", runnable, 100, 0 );
+            Thread.yield(  );
+            Thread.sleep( 200 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+
+    /**
+     * Class under test for void execute(String, Runnable, long, long)
+     */
+    public final void testExecuteStringRunnablelonglong(  )
+    {
+        final MockControl mainConfigControl =
+            createStrictControl( Configuration.class );
+        final Configuration mainConfig =
+            (Configuration)mainConfigControl.getMock(  );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-factory" ),
+                                           createValueConfigMock( DefaultRunnableManager.DEFAULT_THREAD_FACTORY,
+                                                                  DefaultRunnableManager.DEFAULT_THREAD_FACTORY ) );
+        mainConfigControl.expectAndReturn( mainConfig.getChild( "thread-pools" ),
+                                           createChildrenConfigMock( "thread-pool",
+                                                                     new Configuration[ 0 ] ) );
+        mainConfigControl.replay(  );
+
+        final MockControl childLoggerDefaultControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerDefault =
+            (Logger)childLoggerDefaultControl.getMock(  );
+        childLoggerDefaultControl.expectAndReturn( childLoggerDefault.isDebugEnabled(  ),
+                                                   true );
+        childLoggerDefault.debug( "Executing Command: org.apache.cocoon.components.thread.DefaultRunnableManager" );
+        childLoggerDefaultControl.setMatcher( MockControl.ALWAYS_MATCHER );
+        childLoggerDefaultControl.replay(  );
+
+        final MockControl childLoggerMyPoolControl =
+            createStrictControl( Logger.class );
+        final Logger childLoggerMyPool =
+            (Logger)childLoggerMyPoolControl.getMock(  );
+        childLoggerMyPoolControl.expectAndReturn( childLoggerMyPool.isDebugEnabled(  ),
+                                                  true );
+        childLoggerMyPool.debug( "Executing Command: EasyMock for interface java.lang.Runnable,pool=mypool" );
+        childLoggerMyPoolControl.replay(  );
+
+        final MockControl loggerControl = createStrictControl( Logger.class );
+        final Logger logger = (Logger)loggerControl.getMock(  );
+        loggerControl.expectAndReturn( logger.getChildLogger( "default" ),
+                                       childLoggerDefault );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"default\" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy=\"RUN\",shutdown-wait-time-ms=-1" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Starting the heart" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Entering loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "No commands available. Will just wait for one" );
+        loggerControl.expectAndReturn( logger.getChildLogger( "mypool" ),
+                                       childLoggerMyPool );
+        loggerControl.expectAndReturn( logger.isInfoEnabled(  ), true );
+        logger.info( "ThreadPool named \"mypool\" created with maximum queue-size=230,max-pool-size=15,min-pool-size=12,priority=1,isDaemon=false,keep-alive-time-ms=15500,block-policy=\"DISCARD\",shutdown-wait-time-ms=22200" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Command entered: EasyMock for interface java.lang.Runnable, pool=mypool, delay=100, interval=100" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Executing command EasyMock for interface java.lang.Runnable in pool \"mypool\", schedule with interval=100" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Exiting loop" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing all thread pools" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool mypool" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool mypool disposed" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Disposing thread pool default" );
+        loggerControl.expectAndReturn( logger.isDebugEnabled(  ), true );
+        logger.debug( "Thread pool default disposed" );
+        loggerControl.replay(  );
+
+        final DefaultRunnableManager runnableManager =
+            new DefaultRunnableManager(  );
+        runnableManager.enableLogging( logger );
+
+        try
+        {
+            runnableManager.configure( mainConfig );
+        }
+        catch( final ConfigurationException ce )
+        {
+            assertTrue( "Throw unexpected ConfigurationException", false );
+        }
+
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        try
+        {
+            runnableManager.start(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.createPool( "mypool", 230, 15, 12,
+                                        Thread.MIN_PRIORITY, false, 15500,
+                                        "DISCARD", false, 22200 );
+            runnableManager.execute( "mypool", runnable, 100, 100 );
+            Thread.yield(  );
+            Thread.sleep( 200 );
+            runnableManager.stop(  );
+            Thread.yield(  );
+            Thread.sleep( 20 );
+            runnableManager.dispose(  );
+            Thread.sleep( 20 );
+        }
+        catch( final Throwable ex )
+        {
+            ex.printStackTrace(  );
+            assertTrue( "Unexpected Exception", false );
+        }
+
+        verify(  );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadFactoryTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadFactoryTestCase.java
new file mode 100644
index 0000000..91f53a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadFactoryTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import junit.framework.TestCase;
+
+
+/**
+ * The $classType$ class ...
+ *
+ * @version $Id$
+ */
+public class DefaultThreadFactoryTestCase extends TestCase
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testGetPriority(  )
+    {
+        final DefaultThreadFactory factory = new DefaultThreadFactory(  );
+        factory.setPriority( Thread.MAX_PRIORITY );
+        assertEquals( "priority", Thread.MAX_PRIORITY, factory.getPriority(  ) );
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testIsDaemon(  )
+    {
+        final DefaultThreadFactory factory = new DefaultThreadFactory(  );
+        factory.setDaemon( false );
+        assertEquals( "daemon mode", false, factory.isDaemon(  ) );
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testNewThread(  )
+    {
+        final DefaultThreadFactory factory = new DefaultThreadFactory(  );
+        factory.setDaemon( true );
+        factory.setPriority( Thread.MIN_PRIORITY );
+
+        final Thread thread = factory.newThread( new DummyRunnable(  ) );
+        assertEquals( "new thread daemon mode", true, thread.isDaemon(  ) );
+        assertEquals( "new thread priority", Thread.MIN_PRIORITY,
+                      thread.getPriority(  ) );
+        assertEquals( "factory daemon mode", factory.isDaemon(  ),
+                      thread.isDaemon(  ) );
+        assertEquals( "factory priority", factory.getPriority(  ),
+                      thread.getPriority(  ) );
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testSetDaemon(  )
+    {
+        final DefaultThreadFactory factory = new DefaultThreadFactory(  );
+        factory.setDaemon( false );
+
+        final Thread thread = factory.newThread( new DummyRunnable(  ) );
+        assertEquals( "daemon mode", false, thread.isDaemon(  ) );
+    }
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testSetPriority(  )
+    {
+        final DefaultThreadFactory factory = new DefaultThreadFactory(  );
+        factory.setPriority( Thread.MAX_PRIORITY );
+
+        final Thread thread = factory.newThread( new DummyRunnable(  ) );
+        assertEquals( "priority", Thread.MAX_PRIORITY, thread.getPriority(  ) );
+    }
+
+    //~ Inner Classes ----------------------------------------------------------
+
+    /**
+     * The $classType$ class ...
+     *
+     * @version $Id$
+     */
+    private static class DummyRunnable implements Runnable
+    {
+        //~ Methods ------------------------------------------------------------
+
+        /**
+         * DOCUMENT ME!
+         */
+        public void run(  )
+        {
+            // nothing
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java
new file mode 100644
index 0000000..ede6dee
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.components.thread;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.easymock.MockControl;
+
+/**
+ * The $classType$ class ...
+ *
+ * @version $Id$
+ */
+public class DefaultThreadPoolTestCase extends AbstractTestCase
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * DOCUMENT ME!
+     */
+    public final void testDefaultThreadPool(  )
+    {
+        final DefaultThreadPool pool = new DefaultThreadPool(  );
+        pool.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DEBUG ) );
+        pool.setName( "mypool" );
+
+        // We cannot mock the DefaultThreadFactory as the underlying
+        // PooledExecutor of the DefaultThreadPool will again wrapp it into a
+        // PooledExecutor.Worker instance that does some bookeeping.
+        // Using a easymocked DefaultThreadFactory will prevent the
+        // PooledExecutor from shutting down and thus hangs forever.
+        final ThreadFactory threadFactory = new DefaultThreadFactory();
+        threadFactory.setPriority( Thread.MAX_PRIORITY );
+        pool.setThreadFactory( threadFactory );
+        pool.setQueue( 230 );
+        pool.setMaximumPoolSize( 15 );
+        pool.setMinimumPoolSize( 9 );
+        pool.setKeepAliveTime( 11000 );
+        pool.setBlockPolicy( "ABORT" );
+        pool.setShutdownGraceful( false );
+        pool.setShutdownWaitTimeMs( 12345 );
+
+        assertEquals( "block-policy", "ABORT", pool.getBlockPolicy(  ) );
+        assertEquals( "keep-alive-time-ms", 11000L, pool.getKeepAliveTime(  ) );
+        assertEquals( "max-queueu-size", 230, pool.getMaximumQueueSize(  ) );
+        assertEquals( "max-pool-size", 15, pool.getMaximumPoolSize(  ) );
+        assertEquals( "min-pool-size", 9, pool.getMinimumPoolSize(  ) );
+        assertEquals( "name", "mypool", pool.getName(  ) );
+        assertEquals( "priority", Thread.MAX_PRIORITY, pool.getPriority(  ) );
+        assertEquals( "queue-size", 0, pool.getQueueSize(  ) );
+        assertEquals( "isQueued", true, pool.isQueued(  ) );
+        assertEquals( "isTerminatedAfterShutdown", false,
+                      pool.isTerminatedAfterShutdown(  ) );
+        verify(  );
+    }
+
+    /*
+     * Class under test for void execute(Runnable)
+     */
+    public final void testExecuteRunnable(  )
+        throws InterruptedException
+    {
+        final MockControl runnableControl =
+            createStrictControl( Runnable.class );
+        final Runnable runnable = (Runnable)runnableControl.getMock(  );
+        runnable.run(  );
+        runnableControl.replay(  );
+
+        final DefaultThreadPool pool = new DefaultThreadPool(  );
+        pool.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DEBUG ) );
+        pool.setName( "mypool" );
+        // We cannot mock the DefaultThreadFactory as the underlying
+        // PooledExecutor of the DefaultThreadPool will again wrapp it into a
+        // PooledExecutor.Worker instance that does some bookeeping.
+        // Using a easymocked DefaultThreadFactory will prevent the
+        // PooledExecutor from shutting down and thus hangs forever.
+        pool.setThreadFactory( new DefaultThreadFactory() );
+        pool.setQueue( 230 );
+        pool.setMaximumPoolSize( 15 );
+        pool.setMinimumPoolSize( 9 );
+        pool.setKeepAliveTime( 100 );
+        pool.setBlockPolicy( "ABORT" );
+        pool.setShutdownGraceful( false );
+        pool.setShutdownWaitTimeMs( 1234 );
+        pool.execute( runnable );
+        Thread.yield(  );
+        Thread.sleep( 100 );
+        pool.shutdown();
+        verify(  );
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @throws InterruptedException DOCUMENT ME!
+     */
+    public final void testShutdown(  )
+    throws InterruptedException
+    {
+        final Runnable runnable = new Runnable(){
+            public void run()
+            {
+                final ConsoleLogger logger = new ConsoleLogger( ConsoleLogger.LEVEL_DEBUG );
+                logger.info( "runnable runs" );
+                try
+                {
+                    Thread.sleep( 1000 );
+                }
+                catch( final InterruptedException ie )
+                {
+                    logger.info( "runnable has been interrupted ");
+                }
+                logger.info( "runnable terminated" );
+            }
+        };
+
+        final DefaultThreadPool pool = new DefaultThreadPool(  );
+        pool.enableLogging( new ConsoleLogger( ConsoleLogger.LEVEL_DEBUG ) );
+        pool.setName( "mypool" );
+        pool.setThreadFactory( new DefaultThreadFactory() );
+        pool.setQueue( 0 );
+        pool.setMaximumPoolSize( 15 );
+        pool.setMinimumPoolSize( 9 );
+        pool.setKeepAliveTime( 1000 );
+        pool.setBlockPolicy( "ABORT" );
+        pool.setShutdownGraceful( true );
+        pool.setShutdownWaitTimeMs( 100 );
+        pool.execute( runnable );
+        pool.execute( runnable );
+        Thread.yield();
+        Thread.sleep( 200 );
+        pool.shutdown(  );
+        Thread.sleep( 200 );
+        verify(  );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.java
new file mode 100644
index 0000000..cadcd75
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.components.treeprocessor.variables;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.components.treeprocessor.InvokeContext;
+import org.apache.cocoon.environment.mock.MockRequest;
+import org.apache.cocoon.sitemap.PatternException;
+
+/**
+ * Test case for the nested variant of the PreparedVariableResolver
+ *
+ * @version $Id$
+ */
+public class PreparedVariableResolverTestCase extends SitemapComponentTestCase {
+
+    public void testNestedExpressions() throws Exception {
+        String expr = "{request-param:{request-param:foo}}";
+        MockRequest request = getRequest();
+        request.reset();
+        request.addParameter("foo", "bar");
+        request.addParameter("bar", "123");
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+        
+        Map sitemapElements = new HashMap();
+        context.pushMap("sitemap", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testNestedModuleAndSitemapExpressions() throws Exception {
+        String expr = "{request-param:f{1}}";
+        MockRequest request = getRequest();
+        request.reset();
+        request.addParameter("foo", "123");
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+        
+        Map sitemapElements = new HashMap();
+        sitemapElements.put("1", "oo");
+        context.pushMap("sitemap", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123", resolver.resolve(context, getObjectModel()));
+    }
+    
+    public void testAnchors() throws PatternException {
+        String expr = "{#label:name}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+        
+        Map sitemapElements = new HashMap();
+        sitemapElements.put("name", "123");
+        context.pushMap("label", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123", resolver.resolve(context, getObjectModel()));        
+    }
+    
+    public void testSitemapVariables() throws PatternException {
+        String expr = "123{1}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements = new HashMap();
+        sitemapElements.put("1", "abc");
+        context.pushMap("label", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123abc", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testSitemapVariablesWithText() throws PatternException {
+        String expr = "123{1}/def";
+    
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements = new HashMap();
+        sitemapElements.put("1", "abc");
+        context.pushMap("label", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123abc/def", resolver.resolve(context, getObjectModel()));
+    }
+    
+    public void testPrefixedSitemapVariable() throws PatternException {
+        String expr = "123{sitemap:1}/def";
+    
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements = new HashMap();
+        sitemapElements.put("1", "abc");
+        context.pushMap("label", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("123abc/def", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testMultilevelSitemapVariables() throws PatternException {
+        String expr = "from {../1} to {1}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        sitemapElements.put("1", "juliet");
+        context.pushMap("label1", sitemapElements);
+        
+        sitemapElements = new HashMap();
+        sitemapElements.put("1", "oscar");
+        context.pushMap("label2", sitemapElements);
+
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("from juliet to oscar", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testRootSitemapVariables() throws PatternException {
+        String expr = "from {/1} to {1}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        sitemapElements.put("1", "juliet");
+        context.pushMap("label1", sitemapElements);
+        
+        sitemapElements = new HashMap();
+        sitemapElements.put("1", "oscar");
+        context.pushMap("label2", sitemapElements);
+
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("from juliet to oscar", resolver.resolve(context, getObjectModel()));
+    }
+    
+    public void testColonInTextContent() throws PatternException {
+        String expr = "http://cocoon.apache.org";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        context.pushMap("label", sitemapElements);
+        
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("http://cocoon.apache.org", resolver.resolve(context, getObjectModel()));
+    }
+    
+    public void testColonBeginningTextContent() throws PatternException {
+        String expr = ":colon-starts-this";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        context.pushMap("label", sitemapElements);
+        
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals(":colon-starts-this", resolver.resolve(context, getObjectModel()));
+    }
+    
+    public void testEmbeddedColon() throws PatternException {
+        String expr = "{1}:{1}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        sitemapElements.put("1", "abc");
+        context.pushMap("label", sitemapElements);
+        
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("abc:abc", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testEscapedBraces() throws PatternException {
+        String expr = "This is a \\{brace\\}";
+        
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+
+        Map sitemapElements;
+        sitemapElements = new HashMap();
+        context.pushMap("label", sitemapElements);
+
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("This is a {brace}", resolver.resolve(context, getObjectModel()));
+    }
+
+    public void testModuleWithoutOption() throws PatternException {
+        String expr = "{baselink:}";
+        InvokeContext context = new InvokeContext(true);
+        context.enableLogging(getLogger());
+        
+        Map sitemapElements = new HashMap();
+        context.pushMap("sitemap", sitemapElements);
+        PreparedVariableResolver resolver = new PreparedVariableResolver(expr, getManager());
+        assertEquals("", resolver.resolve(context, getObjectModel()));
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.CocoonTestCase#addSourceFactories()
+     */
+    protected boolean addSourceFactories() {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.CocoonTestCase#addSourceResolver()
+     */
+    protected boolean addSourceResolver() {
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.xtest
new file mode 100644
index 0000000..d2df07f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/components/treeprocessor/variables/PreparedVariableResolverTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.components.modules.input.InputModuleSelector"
+        shorthand="input-modules"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+   <input-modules>
+       <component-instance class="org.apache.cocoon.components.modules.input.RequestParameterModule" logger="core.modules.input" name="request-param"/>
+       <component-instance class="org.apache.cocoon.components.modules.input.BaseLinkModule" logger="core.modules.input" name="baselink"/>
+   </input-modules>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/ContainerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/ContainerTestCase.java
new file mode 100644
index 0000000..c4a4487
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/ContainerTestCase.java
@@ -0,0 +1,391 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.MutableSettings;
+
+/**
+ * JUnit TestCase for Cocoon Components.
+ * <p>
+ *   This class extends the JUnit TestCase class to setup an environment which
+ *   makes it possible to easily test Cocoon Components. The following methods
+ *   and instance variables are exposed for convenience testing:
+ * </p>
+ * <dl>
+ *   <dt>getManager()</dt>
+ *   <dd>
+ *     This instance variable contains an initialized service manager which
+ *     can be used to lookup components configured in the test configuration
+ *     file. (see below)
+ *   </dd>
+ *   <dt>getLogger()</dt>
+ *   <dd>
+ *     This method returns a logger for this test case. By default this
+ *     logger logs with log level DEBUG.
+ *   </dd>
+ * </dl>
+ * <p>
+ *   The following test case configuration can be used as a basis for new tests.
+ *   Detailed explanations of the configuration elements can be found after
+ *   the example. 
+ * </p>
+ * <pre>
+ *   &lt;testcase&gt;
+ *     &lt;context&gt;
+ *       &lt;entry name="foo" value="bar"/&gt;
+ *       &lt;entry name="baz" class="my.context.Class"/&gt;
+ *     &lt;/context&gt;
+ *
+ *     &lt;roles&gt;
+ *       &lt;role name="org.apache.avalon.excalibur.datasource.DataSourceComponentSelector"
+ *             shorthand="datasources"
+ *             default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"&gt;
+ *          &lt;hint shorthand="jdbc" class="org.apache.avalon.excalibur.datasource.JdbcDataSource"/&gt;
+ *       &lt;/role&gt;
+ *     &lt;/roles&gt;
+ *
+ *     &lt;components&gt;
+ *       &lt;datasources&gt;
+ *         &lt;jdbc name="personell"&gt;
+ *           &lt;pool-controller min="5" max="10"/&gt;
+ *           &lt;jdbc name="personnel"/&gt;
+ *           &lt;dburl&gt;jdbc:odbc:test&lt;/dburl&gt;
+ *           &lt;user&gt;test&lt;/user&gt;
+ *           &lt;password&gt;test&lt;/password&gt;
+ *           &lt;driver&gt;sun.jdbc.odbc.JdbcOdbcDriver&lt;/driver&gt;
+ *         &lt;/jdbc&gt;
+ *       &lt;/datasources&gt;
+ *     &lt;/components&gt;
+ *   &lt;/testcase&gt;
+ * </pre>
+ * <p>
+ * Element Explanation:
+ * <dl>
+ * <dt>testcase</dt>
+ * <dd>Defines a test case configuration.  Must contain one each of the
+ *  following elements: 
+ *  <code>context</code>, <code>roles</code>, and <code>components</code>
+ *  </dd>.
+ *
+ * <dt>context</dt>
+ * <dd>Allows context properties to be set in the context passed to any
+ *  Contextualizable components.</dd>
+ *
+ * <dt>roles</dt>
+ * <dd>Roles configuration for the components configured in the
+ *  <code>components</code> element.  
+ * </dd>
+ *
+ * <dt>components</dt>
+ * <dd>Used to configure any Components used by the test cases.  
+ * </dd>
+ *
+ * </dl>
+ *
+ * @version $Id$
+ */
+public class ContainerTestCase extends TestCase {
+    
+    /** The default logger */
+    private Logger logger;
+    
+    /** The service manager to use */
+    private ServiceManager manager;
+
+    /** The context */
+    private Context context;
+    
+    /** Return the logger */
+    protected Logger getLogger() {
+        return logger;
+    }
+
+    /** Return the service manager */
+    protected ServiceManager getManager() {
+        return this.manager;
+    }
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_WARN);
+        this.logger = new ConsoleLogger(Integer.parseInt(level));
+        this.prepare();
+    }
+    
+    /**
+     * Initializes the ComponentLocator
+     *
+     * The configuration file is determined by the class name plus .xtest appended,
+     * all '.' replaced by '/' and loaded as a resource via classpath
+     */
+    protected void prepare()
+    throws Exception {
+        final String resourceName = getClass().getName().replace( '.', '/' ) + ".xtest";
+        URL resource = getClass().getClassLoader().getResource( resourceName );
+
+        if( resource != null ) {
+            getLogger().debug( "Loading resource " + resourceName );
+            this.prepare( resource.openStream() );
+        } else {
+            getLogger().debug( "Resource not found " + resourceName );
+            this.prepare( null );
+        }
+    }
+
+    /**
+     * Initializes the ComponentLocator
+     *
+     * @param testconf The configuration file is passed as a <code>InputStream</code>
+     *
+     * A common way to supply a InputStream is to overwrite the initialize() method
+     * in the sub class, do there whatever is needed to get the right InputStream object
+     * supplying a conformant xtest configuartion and pass it to this initialize method.
+     * the mentioned initialize method is also the place to set a different logging priority
+     * to the member variable m_logPriority.
+     */
+    protected final void prepare( final InputStream testconf )
+    throws Exception {
+        if ( getLogger().isDebugEnabled() ) {
+            getLogger().debug( "Initializing " + this.getName() );
+        }
+
+        final DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+        final Configuration conf;
+        if ( testconf != null ) {
+            conf = builder.build( testconf );
+        } else {
+            conf = new DefaultConfiguration("", "-");
+        }
+
+        this.prepare( conf.getChild( "context" ),
+                      conf.getChild( "roles" ),
+                      conf.getChild( "components" ) );
+    }
+
+    /**
+     * Initializes the ComponentLocator
+     *
+     * @param context The configuration object for the context
+     * @param roles The configuration object for the roles
+     * @param components The configuration object for the components
+     *
+     * More detailed control over configuration can be achieved by
+     * overriding <code>prepare()</code>, construct the configuration
+     *  objects and call this method.
+     */
+    protected final void prepare( final Configuration context,
+                                  final Configuration roles,
+                                  final Configuration components )
+    throws Exception {
+        this.context = this.setupContext( context );
+
+        this.setupManagers( components, roles );
+    }
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        this.done();
+        super.tearDown();
+    }
+
+    /**
+     * Disposes the <code>ComponentLocator</code>
+     */
+    final private void done() {
+        if( manager != null ) {
+            ContainerUtil.dispose(manager);
+            manager = null;
+        }
+    }
+
+    /**
+     * set up a context according to the xtest configuration specifications context
+     * element.
+     *
+     * A method addContext(DefaultContext context) is called here to enable subclasses
+     * to put additional objects into the context programmatically.
+     */
+    final private Context setupContext( final Configuration conf )
+    throws Exception {
+        final DefaultContext context = new DefaultContext();
+        final Configuration[] confs = conf.getChildren( "entry" );
+        for( int i = 0; i < confs.length; i++ ) {
+            final String key = confs[ i ].getAttribute( "name" );
+            final String value = confs[ i ].getAttribute( "value", null );
+            if( value == null ) {
+                String clazz = confs[ i ].getAttribute( "class" );
+                Object obj = getClass().getClassLoader().loadClass( clazz ).newInstance();
+                context.put( key, obj );
+                if( getLogger().isInfoEnabled() ) {
+                    getLogger().info( "ContainerTestCase: added an instance of class " + clazz + " to context entry " + key );
+                }
+            } else {
+                context.put( key, value );
+                if( getLogger().isInfoEnabled() ) {
+                    getLogger().info( "ContainerTestCase: added value \"" + value + "\" to context entry " + key );
+                }
+            }
+        }
+        this.addContext( context );
+        return context ;
+    }
+
+    /**
+     * This method may be overwritten by subclasses to put additional objects
+     * into the context programmatically.
+     */
+    protected void addContext( DefaultContext context ) {
+        // nothing to add here
+    }
+
+    /**
+     * This method may be overwritten by subclasses to add aditional
+     * components.
+     */
+    protected void addComponents( CoreServiceManager manager) 
+    throws ServiceException, ConfigurationException {
+        // subclasses can add components here
+    }
+    
+    final private void setupManagers( final Configuration confCM,
+                                      final Configuration confRM)
+    throws Exception {
+        // Setup the RoleManager
+        RoleManager roleManager = new RoleManager();
+        roleManager.enableLogging( this.getLogger() );
+        roleManager.configure( confRM );
+
+        // Set up root manager for Core
+        Core core = new Core(new MutableSettings(), this.context);
+        ((DefaultContext)this.context).put(Core.ROLE, core);
+        SingleComponentServiceManager rsm = new SingleComponentServiceManager(null, core, Core.ROLE);
+ 
+        // Set up the ComponentLocator
+        CoreServiceManager ecManager = new CoreServiceManager(rsm);
+        ecManager.enableLogging( this.getLogger() );
+        ecManager.contextualize( this.context );
+        ecManager.setRoleManager( roleManager );
+        ecManager.setLoggerManager( new DefaultLoggerManager(this.logger));
+        ecManager.configure( confCM );
+        this.addComponents( ecManager );
+        ecManager.initialize();
+        this.manager = ecManager;
+    }
+
+    protected final Object lookup( final String key )
+    throws ServiceException {
+        return manager.lookup( key );
+    }
+
+    protected final void release( final Object object ) {
+        manager.release( object );
+    }
+    
+    private Object getComponent(String classname,
+                                Configuration conf,
+                                Parameters p) 
+    throws Exception {
+        final Object instance = Class.forName(classname).newInstance();
+        ContainerUtil.enableLogging(instance, getLogger());
+        ContainerUtil.contextualize(instance, this.context);
+        ContainerUtil.service(instance, getManager());
+        if ( instance instanceof Configurable ) {
+            // default configuration to invoke method!
+            if ( conf == null ) {
+                conf = new DefaultConfiguration("", "-");
+            }
+            ContainerUtil.configure(instance, conf);
+        }
+        if ( instance instanceof Parameterizable ) {
+            // default configuration to invoke method!
+            if ( p == null ) {
+                p = new Parameters();
+            }
+            ContainerUtil.parameterize(instance, p);                       
+        }
+        ContainerUtil.initialize(instance);
+        return instance;
+    }
+    
+    protected Object getComponent(String classname,
+                                  Configuration conf) 
+    throws Exception {
+        return this.getComponent(classname, conf, null);
+    }
+
+    protected Object getComponent(String classname,
+                                  Parameters p) 
+    throws Exception {
+        return this.getComponent(classname, null, p);
+    }
+    
+    protected Object getComponent(String classname) 
+    throws Exception {
+        return this.getComponent(classname, null, null);
+    }
+
+    /**
+     * We use this simple logger manager that sends all output to the console (logger)
+     */
+    protected static class DefaultLoggerManager implements LoggerManager {
+        
+        private Logger logger;
+        
+        public DefaultLoggerManager(Logger logger) {
+            this.logger = logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getDefaultLogger()
+         */
+        public Logger getDefaultLogger() {
+            return this.logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getLoggerForCategory(java.lang.String)
+         */
+        public Logger getLoggerForCategory(String arg0) {
+            return this.logger;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/CoreServiceManagerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/CoreServiceManagerTestCase.java
new file mode 100644
index 0000000..2e5ca8b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/CoreServiceManagerTestCase.java
@@ -0,0 +1,138 @@
+/* 
+ * Copyright 2005 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.excalibur.logger.ConsoleLoggerManager;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.NullLogger;
+import org.apache.cocoon.core.Core;
+import org.apache.cocoon.core.MutableSettings;
+
+/**
+ * Test cases for {@link CoreServiceManager}.
+ * 
+ * @version $Id$
+ */
+public class CoreServiceManagerTestCase extends TestCase {
+
+    protected CoreServiceManager parent;
+    protected CoreServiceManager child;
+
+    protected final static String PARENT_ROLE_CONFIG =
+        "<role-list cocoon-version = '2.2'>" +
+        "  <role name=\"list\" shorthand=\"config-list\"" +
+        "        default-class=\"java.util.ArrayList\"/>" +
+        "" + 
+        "  <role name=\"map\" shorthand=\"config-map\"" +
+        "        default-class=\"java.util.HashMap\"/>" +
+        "</role-list>";
+
+    protected final static String PARENT_CONFIG =
+        "<cocoon version=\"2.2\">" +
+        "  <config-map class=\"java.util.Hashtable\"/>" +
+        "</cocoon>";
+
+    protected final static String CHILD_ROLE_CONFIG =
+        "<role-list cocoon-version = '2.2'>" +
+        "  <role name=\"map\"" +
+        "        default-class=\"java.util.HashMap\"/>" +
+        "</role-list>";
+
+    protected final static String CHILD_CONFIG =
+        "<cocoon version=\"2.2\">" +
+        "</cocoon>";
+
+    protected Configuration getConfig(String configString)
+    throws Exception {
+        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
+        return builder.build(new ByteArrayInputStream(configString.getBytes("utf-8")));
+    }
+
+    /**
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+
+
+        // we setup a hierarchy of service managers
+        // let's start with a core component and settings
+        MutableSettings settings = new MutableSettings();
+        settings.setLazyMode(false);
+        settings.makeReadOnly();
+        Core core = new Core(settings, null);
+
+        // and now a context with the core
+        DefaultContext context = new DefaultContext();
+        context.put(Core.ROLE, core);
+
+        // a role manager for the parent
+        RoleManager parentRoleManager = new RoleManager(null);
+        parentRoleManager.enableLogging(new ConsoleLogger());
+        parentRoleManager.configure(this.getConfig(PARENT_ROLE_CONFIG));
+
+        // the parent service manager
+        this.parent = new CoreServiceManager(null);
+        this.parent.enableLogging(new ConsoleLogger());
+        this.parent.setLoggerManager(new ConsoleLoggerManager());
+        this.parent.setRoleManager(parentRoleManager);
+        this.parent.contextualize(context);
+        this.parent.configure(this.getConfig(PARENT_CONFIG));
+        this.parent.initialize();
+
+        // a role manager for the child
+        RoleManager childRoleManager = new RoleManager(parentRoleManager);
+        childRoleManager.enableLogging(new ConsoleLogger());
+        childRoleManager.configure(this.getConfig(CHILD_ROLE_CONFIG));
+
+        // the child service manager
+        this.child = new CoreServiceManager(this.parent);
+        this.child.enableLogging(new NullLogger());
+        this.child.setRoleManager(childRoleManager);
+        this.child.contextualize(context);
+        this.child.configure(this.getConfig(CHILD_CONFIG));
+        this.child.initialize();
+    }
+
+    public void testParentLookup()
+    throws Exception {
+        Object component = this.parent.lookup("list");
+        assertTrue(component instanceof ArrayList);
+
+        component = this.parent.lookup("map");
+        assertTrue(component instanceof Hashtable);
+    }
+
+    public void testChildLookup()
+    throws Exception {
+        Object component = this.child.lookup("list");
+        assertTrue(component instanceof ArrayList);
+
+        component = this.child.lookup("map");
+        assertTrue(component instanceof HashMap);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/RoleManagerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
new file mode 100644
index 0000000..7747dfc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/RoleManagerTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.core.container;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.components.ComponentInfo;
+import org.apache.cocoon.core.container.RoleManager;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+
+/**
+ * Test cases for {@link RoleManager}.
+ * 
+ * @version $Id$
+ */
+public class RoleManagerTestCase extends MockObjectTestCase {
+    
+    /**
+     * Constructor for RoleManagerTestCase.
+     * @param name The test name
+     */
+    public RoleManagerTestCase(String name) {
+        super(name);
+    }
+
+    public void testConfigureWithoutHints() throws ConfigurationException {
+        Mock conf = new Mock(Configuration.class);
+        Mock child0 = new Mock(Configuration.class);
+        Configuration roles[] = new Configuration[1];
+        roles[0] = (Configuration) child0.proxy();
+        Configuration hints[] = new Configuration[0];
+        conf.expects(once()).method("getName").will(returnValue("roles-list"));
+        conf.expects(once()).method("getChildren").will(returnValue(roles));
+        child0.expects(once()).method("getName").will(returnValue("role"));
+        child0.expects(once()).method("getAttribute").with(eq("name"))
+                .will(returnValue("testName"));
+        child0.expects(once()).method("getAttribute").with(eq("shorthand"), eq(null))
+                .will(returnValue("testShorthand"));
+        child0.expects(once()).method("getAttribute").with(eq("default-class"), eq(null))
+                .will(returnValue("testClass"));
+        child0.expects(once()).method("getAttribute").with(eq("model"), eq(null))
+                .will(returnValue(ComponentInfo.TYPE_SINGLETON));
+        child0.expects(once()).method("getAttribute").with(eq("init"), eq(null))
+                .will(returnValue(null));
+        child0.expects(once()).method("getAttribute").with(eq("destroy"), eq(null))
+        .will(returnValue(null));
+        child0.expects(once()).method("getAttribute").with(eq("logger"), eq(null))
+                .will(returnValue(null));
+        child0.expects(once()).method("getChildren").with(eq("hint"))
+                .will(returnValue(hints));
+        Mock logger = new Mock(Logger.class);
+        logger.expects(this.atLeastOnce()).method("isDebugEnabled").will(returnValue(false));
+        RoleManager rm = new RoleManager(null);
+        rm.enableLogging((Logger) logger.proxy());
+        rm.configure((Configuration) conf.proxy());
+        conf.verify();
+        child0.verify();
+        assertEquals("Role name for shorthand incorrect", "testName", rm.getRoleForName("testShorthand"));
+        assertEquals("Default service info for role incorrect", "testClass", rm.getDefaultServiceInfoForRole("testName").getServiceClassName());
+        assertNull("Default service info for key must be null", rm.getDefaultServiceInfoForKey("testName", "testShorthand"));
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/util/PropertyHelperTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/util/PropertyHelperTestCase.java
new file mode 100644
index 0000000..a358f65
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/core/container/util/PropertyHelperTestCase.java
@@ -0,0 +1,41 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation
+ * Licensed  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.cocoon.core.container.util;
+
+import junit.framework.TestCase;
+
+/**
+ * Test cases for the {@link PropertyHelper} class.
+ *
+ * @version $Id: AbstractComponentHandler.java 123887 2005-01-02 15:12:01Z sylvain $
+ */
+public class PropertyHelperTestCase extends TestCase {
+
+    public void testReplace() {
+        final String testA = "a simple string";
+        final String testB = "a simple string with a start token ${ somewhere";
+        final String testC = "and this is the } end token";
+        final String testD = "${this.does.not.exists}";
+        // some tests for not! replacing
+        assertEquals(PropertyHelper.replace(testA, null), testA);
+        assertEquals(PropertyHelper.replace(testB, null), testB);
+        assertEquals(PropertyHelper.replace(testC, null), testC);
+        assertEquals(PropertyHelper.replace(testD, null), testD);
+        // and finally we have something to replace
+        assertEquals(PropertyHelper.replace("${java.home}", null), System.getProperty("java.home"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/CommandLineContextTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/CommandLineContextTestCase.java
new file mode 100644
index 0000000..c08fdbb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/CommandLineContextTestCase.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.commandline.test;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+
+import org.apache.cocoon.environment.commandline.CommandLineContext;
+
+import junit.framework.TestCase;
+import junit.swingui.TestRunner;
+
+import java.io.File;
+import java.net.URL;
+
+/**
+ * A simple test case for CommandLineContext.
+ *
+ * @version $Id$
+ */
+public final class CommandLineContextTestCase extends TestCase {
+
+    private String commandLineContextDir;
+    private CommandLineContext commandLineContext;
+
+
+    /**
+     * Constructor for the CommandLineContextTestCase object
+     */
+    public CommandLineContextTestCase() {
+        this("CommandLineContextTestCase");
+    }
+
+    /**
+     * Constructor for the CommandLineContextTestCase object
+     */
+    public CommandLineContextTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * The main program for the CommandLineContextTestCase class
+     *
+     * @param  args           The command line arguments
+     */
+    public static void main(final String[] args) throws Exception {
+        final String[] testCaseName = {CommandLineContextTestCase.class.getName()};
+        TestRunner.main(testCaseName);
+    }
+
+
+    /**
+     * The JUnit setup method
+     */
+    public void setUp() throws Exception {
+        commandLineContextDir = System.getProperty("java.io.tmpdir", "/tmp");
+        new File(commandLineContextDir, "foo" + File.separator + "bar").mkdirs();
+
+        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_DEBUG);
+        Logger logger = new ConsoleLogger(Integer.parseInt(level));
+
+        commandLineContext = new CommandLineContext(commandLineContextDir);
+        commandLineContext.enableLogging(logger);
+    }
+
+    /**
+     * The teardown method for JUnit
+     */
+    public void tearDown() throws Exception {
+        new File(commandLineContextDir, "foo" + File.separator + "bar").delete();
+        new File(commandLineContextDir, "foo").delete();
+    }
+
+    /**
+     * A unit test for <code>getResource()</code>
+     */
+    public void testGetResource() throws Exception {
+        Object[] test_values = {
+                new String[]{"", commandLineContextDir},
+                new String[]{"/", commandLineContextDir},
+                new String[]{"foo", commandLineContextDir + File.separator + "foo"},
+                new String[]{"foo/bar", commandLineContextDir + File.separator + "foo/bar"},
+                new String[]{"foo/bar/nonexistent", null}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            URL result = commandLineContext.getResource(test);
+            URL expected = null;
+            if (result != null) {
+                expected = new File(tests[1]).toURL();
+            }
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+    /**
+     * A unit test for <code>getRealPath()</code>
+     */
+    public void testGetRealPath() throws Exception {
+        Object[] test_values = {
+                new String[]{"", ""},
+                new String[]{"/", "/"},
+                new String[]{"foo", "foo"},
+                new String[]{"foo/bar", "foo/bar"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            File expected_file = new File(commandLineContextDir, tests[1]);
+            String expected = expected_file.getAbsolutePath();
+
+            String result = commandLineContext.getRealPath(test);
+            String message = "Test " +
+                    "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+    /**
+     * A unit test for <code>getAttribute</code>,
+     * <code>setAttribute</code>, and <code>removeAttribute()</code>
+     */
+    public void testAttributes() throws Exception {
+        Object[] test_values = {
+                new String[]{"a", "b"},
+                new String[]{"foo", "foo"},
+                new String[]{"foo/bar", "foo/bar"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String name = tests[0];
+            String expected = tests[1];
+
+            commandLineContext.setAttribute(name, expected);
+
+            String result = (String) commandLineContext.getAttribute(name);
+            assertEquals("Test " + "'" + "n" + "'", expected, result);
+
+            commandLineContext.removeAttribute(name);
+            result = (String) commandLineContext.getAttribute(name);
+            assertEquals("Test " + "'" + "<null>" + "'", null, result);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/package.html b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/package.html
new file mode 100644
index 0000000..ebb8cde
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/commandline/test/package.html
@@ -0,0 +1,28 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+<head>
+  <title>Search</title>
+</head>
+<body>
+  <h1>Test Cases Environment Commandline</h1>
+  <p>
+    This package provides Cocoon environment commandline test cases.
+  </p>
+  <p>
+    For more information @see org.apache.cocoon.environment.commandline
+  </p>
+</body>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockContext.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockContext.java
new file mode 100644
index 0000000..9e47742
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockContext.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.io.InputStream;
+
+import org.apache.cocoon.environment.impl.AbstractContext;
+
+public class MockContext extends AbstractContext {
+
+    private Hashtable attributes = new Hashtable();
+    private Hashtable resources = new Hashtable();
+    private Hashtable mappings = new Hashtable();
+    private Hashtable initparameters = new Hashtable();
+
+    public Object getAttribute(String name) {
+        return attributes.get(name);
+    }
+
+    public void setAttribute(String name, Object value) {
+        attributes.put(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        attributes.remove(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        return attributes.keys();
+    }
+
+    public void setResource(String path, URL url) {
+        resources.put(path, url);
+    }
+
+    public URL getResource(String path) throws MalformedURLException {
+        return (URL)resources.get(path);
+    }
+
+    public String getRealPath(String path) {
+      return path;
+    }
+
+    public String getMimeType(String file) {
+        return (String)mappings.get(file.substring(file.lastIndexOf(".")+1)); 
+    }
+
+    public void setInitParameter(String name, String value) {
+        initparameters.put(name, value);
+    }
+
+    public String getInitParameter(String name) {
+        return (String)initparameters.get(name);
+    }
+
+    public InputStream getResourceAsStream(String path) {
+        return null;
+    }
+
+    public void reset() {
+        attributes.clear();
+        resources.clear();
+        mappings.clear();
+        initparameters.clear();
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockCookie.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockCookie.java
new file mode 100644
index 0000000..1a6fe5c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockCookie.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import org.apache.cocoon.environment.Cookie;
+
+public class MockCookie implements Cookie {
+
+    private String comment;
+    private String domain;
+    private int maxage;
+    private String path;
+    private boolean secure;
+    private String name;
+    private String value;
+    private int version; 
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setMaxAge(int maxage) {
+        this.maxage = maxage;
+    }
+
+    public int getMaxAge() {
+        return maxage;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setSecure(boolean secure) {
+        this.secure = secure;
+    }
+
+    public boolean getSecure() {
+        return secure;
+    }
+
+    public void setName(String name) {
+        this.name= name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockEnvironment.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockEnvironment.java
new file mode 100644
index 0000000..a66416f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockEnvironment.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import junit.framework.AssertionFailedError;
+import org.apache.cocoon.environment.Environment;
+
+public class MockEnvironment implements Environment {
+
+    private String uri;
+    private String uriprefix;
+    private String view;
+    private String action;
+    private String contenttype;
+    private int contentlength;
+    private int status;
+    private ByteArrayOutputStream outputstream;
+    private Map objectmodel;
+    private Hashtable attributes = new Hashtable();
+
+    public MockEnvironment() {
+        // empty constructor
+    }
+
+    public String getURI() {
+        return uri;
+    }
+
+    public String getURIPrefix() {
+        return uriprefix;
+    }
+
+    public String getView() {
+        return view;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public void setURI(String prefix, String uri) {
+        this.uriprefix = prefix;
+        this.uri = uri;
+    }
+
+    public void redirect(String url, boolean global, boolean permanent) throws IOException {
+        throw new AssertionFailedError("Use Redirector.redirect instead!");
+    }
+
+    public void setContentType(String contenttype) {
+        this.contenttype = contenttype;
+    }
+
+    public String getContentType() {
+        return contenttype;
+    }
+
+    public void setContentLength(int length) {
+        this.contentlength = length;
+    }
+
+    public int getContentLength() {
+        return contentlength;
+    }
+
+    public void setStatus(int statusCode) {
+        this.status = statusCode;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public OutputStream getOutputStream(int bufferSize) throws IOException {
+        outputstream = new ByteArrayOutputStream();
+        return outputstream;
+    }
+
+    public byte[] getOutput() {
+        return outputstream.toByteArray();
+    }
+
+    public Map getObjectModel() {
+        return objectmodel;
+    }
+
+    public void setObjectModel(Map objectmodel) {
+        this.objectmodel = objectmodel;
+    }
+
+    public boolean isResponseModified(long lastModified) {
+        return true;
+    }
+
+    public void setResponseIsNotModified() {
+        // nothing to do
+    }
+
+    public void setAttribute(String name, Object value) {
+        attributes.put(name, value);
+    }
+
+    public Object getAttribute(String name) {
+        return attributes.get(name);
+    }
+
+    public void removeAttribute(String name) {
+        attributes.remove(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        return attributes.keys();
+    }
+
+    public boolean tryResetResponse() throws IOException {
+        return false;
+    }
+
+    public void commitResponse() throws IOException {
+        // do nothing
+    }
+    
+    public void startingProcessing() {
+        // do nothing
+    }
+    
+    public void finishingProcessing() {
+        // do nothing
+    }
+
+    /**
+     * Always return <code>true</code>.
+     */
+    public boolean isExternal() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Environment#isInternalRedirect()
+     */
+    public boolean isInternalRedirect() {
+        return false;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRedirector.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRedirector.java
new file mode 100644
index 0000000..9bf1b28
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRedirector.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import org.apache.cocoon.ProcessingException;
+import java.io.IOException;
+
+import org.apache.cocoon.environment.Redirector;
+
+public class MockRedirector implements Redirector {
+
+    protected boolean hasRedirected = false;
+
+    private String redirect;
+
+    public void redirect(boolean sessionmode, String url) throws IOException, ProcessingException {
+        this.hasRedirected = true;
+
+        redirect = url;
+    }
+  
+    public void globalRedirect(boolean sessionmode, String url) throws IOException, ProcessingException {
+        redirect(sessionmode, url);
+    }
+
+    public String getRedirect() {
+        return redirect;
+    }
+    
+    public boolean hasRedirected() {
+        return this.hasRedirected;
+    }
+
+    public void reset() {
+        redirect = null;
+        hasRedirected = false;
+    }
+    
+    public void sendStatus(int sc) {
+        hasRedirected = true;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRequest.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRequest.java
new file mode 100644
index 0000000..1e40883
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockRequest.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.environment.mock;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Environment;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Session;
+import org.apache.cocoon.environment.impl.AbstractRequest;
+
+/**
+ * @version $Id$
+ */
+public class MockRequest extends AbstractRequest {
+    
+    private Hashtable attributes = new Hashtable();
+    private Hashtable globalAttributes = new Hashtable();
+    private String scheme;
+    private String protocol = "HTTP/1.1";
+    private String requestURI;
+    private String contextPath = "";
+    private String servletPath;
+    private String pathInfo;
+    private String queryString;
+    private String method = "GET";
+    private String contentType;
+    private Locale locale = Locale.US;
+    private Principal principal;
+    private String remoteAddr;
+    private String remoteHost;
+    private String remoteUser;
+    private String userRole;
+    private String reqSessionId;
+    private String authType;
+    private String charEncoding;
+    private String serverName;
+    private int port = 80;
+    private InputStream inputStream;
+    
+    private Hashtable parameters = new Hashtable();
+    private Hashtable headers = new Hashtable();
+    private Map cookies = new HashMap();
+    
+    private MockSession session;
+    private Environment environment = null;
+    
+    private boolean isRequestedSessionIdFromCookie = true;
+    private boolean isRequestedSessionIdFromURL = false;
+
+    // Needed to get getSitemapURI and getSitemapPath right
+    public void setEnvironment(Environment environment) {
+        this.environment = environment;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#get(java.lang.String)
+     */
+    public Object get(String name) { 
+        String[] values = this.getParameterValues(name);
+        if (values == null || values.length == 0) {
+            return null;
+        } else if (values.length == 1) {
+            return values[0];
+        } else {
+            Vector vect = new Vector(values.length);
+            for (int i = 0; i < values.length; i++) {
+                vect.add(values[i]);
+            }
+            return vect;
+        }
+    }
+    
+    public String getAuthType() {
+        return authType;
+    }
+    
+    public String getCharacterEncoding() {
+        return charEncoding;
+    }
+
+    public void setCharacterEncoding(String enc) throws java.io.UnsupportedEncodingException {
+        charEncoding = enc;
+    }
+
+    public int getContentLength() {
+        return -1;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    public String getParameter(String name) {
+        return (String)parameters.get(name);
+    }
+
+    public Enumeration getParameterNames() {
+        return parameters.keys();
+    }
+
+    public String[] getParameterValues(String name) {
+        Object param = parameters.get(name);
+        if ( null == param ) {
+            return null;
+        }
+        if (param.getClass().isArray()) {
+            return (String[]) param;
+        }
+        return new String[] {(String) param};
+    }
+
+    public void addParameter(String name, String value) {
+        parameters.put(name, value);
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public String getScheme() {
+        return scheme;
+    }
+
+    public String getServerName() {
+        return serverName;
+    }
+
+    public int getServerPort() {
+        return port;
+    }
+    
+    public String getRemoteAddr() {
+        return remoteAddr;
+    }
+    
+    public String getRemoteHost() {
+        return remoteHost;
+    }
+    
+    public Locale getLocale() {
+        return locale;
+    }
+    
+    public Enumeration getLocales() {
+        return Collections.enumeration(Collections.singleton(getLocale()));
+    }
+    
+    public boolean isSecure() {
+        if (scheme==null) {
+            return false;
+        }
+        return scheme.equalsIgnoreCase("HTTPS");
+    }
+    
+    public Cookie[] getCookies() {
+        if (cookies.isEmpty()) {
+            return null;
+        }
+        Cookie[] cookieArray = new Cookie[cookies.size()];
+        return (Cookie []) cookies.values().toArray(cookieArray);
+    }
+
+    public Map getCookieMap() {
+        return cookies;
+    }
+
+    public long getDateHeader(String name) {
+        String s1 = getHeader(name);
+        if (s1 == null) {
+            return -1L;
+        }
+        try {
+            DateFormat dateFormat = new SimpleDateFormat();
+            return dateFormat.parse(s1).getTime();
+        }
+        catch(ParseException exception) {
+            throw new IllegalArgumentException("Cannot parse date: " + s1);
+        }
+    }
+
+    public String getHeader(String name) {
+        return (String) headers.get(name);
+    }
+
+    public Enumeration getHeaders(String name) {
+        throw new AssertionFailedError("Not implemented");
+    }
+    
+    public Enumeration getHeaderNames() {
+        return headers.keys();
+    }
+    
+    public String getMethod() {
+        return method;
+    }
+    
+    public String getPathInfo() {
+        return pathInfo;
+    }
+    
+    public String getPathTranslated() {
+        throw new AssertionFailedError("Not implemented");
+    }
+    
+    public String getContextPath() {
+        return contextPath;
+    }
+    
+    public void setContextPath(String path) {
+        contextPath = path;
+    }
+    
+    public String getQueryString() {
+        return queryString;
+    }
+    
+    public void setQueryString(String string) {
+        queryString = string;
+    }
+    
+    public String getRemoteUser() {
+        return remoteUser;
+    }
+    
+    public Principal getUserPrincipal() {
+        return principal;
+    }
+    
+    public boolean isUserInRole(String role) {
+        return userRole.equals(role);
+    }
+    
+    public String getRequestedSessionId() {
+        return reqSessionId;
+    }
+    
+    public String getRequestURI() {
+        if (this.environment == null) {
+            return requestURI;
+        }
+        return this.environment.getURI();
+    }
+    
+    public void setRequestURI(String uri) {
+        requestURI = uri;
+    }
+    
+    public String getSitemapURI() {
+        if (this.environment == null) {
+            return requestURI;
+        }
+        return this.environment.getURI();
+    }
+    
+    public String getSitemapPath() {
+        if (this.environment == null) {
+            return "";
+        }
+        return this.environment.getURIPrefix();
+    }
+
+    public String getSitemapURIPrefix() {
+        return "";
+    }
+
+    public String getServletPath() {
+        return servletPath;
+    }
+
+    public Session getSession(boolean create) {
+        if ((session == null) && (create)) {
+            this.session = new MockSession();
+        } else if ((session != null) && (!(session).isValid()) && (create)) {
+            this.session = new MockSession();
+        }
+        if ((session != null) && ((session).isValid())) {
+            return this.session;
+        }
+        return null;
+    }
+
+    public Session getSession() {
+        return getSession(true);
+    }
+
+    public boolean isRequestedSessionIdValid() {
+        if (session != null) {
+            try {
+                session.getId();
+                return true;
+            } catch (IllegalStateException e) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromCookie() {
+        return isRequestedSessionIdFromCookie;
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+        return isRequestedSessionIdFromURL;
+    }
+
+    public void reset() {
+        attributes.clear();
+        globalAttributes.clear();
+        scheme = null;
+        protocol = "HTTP/1.1";
+        requestURI = null;
+        contextPath = null;
+        servletPath = null;
+        pathInfo = null;
+        queryString = null;
+        method = "GET";
+        contentType = null;
+        locale = Locale.US;
+        principal = null;
+        remoteAddr = null;
+        remoteHost = null;
+        remoteUser = null;
+        userRole = null;
+        reqSessionId = null;
+        authType = null;
+        charEncoding = null;
+        serverName = null;
+        port = 80;
+        
+        parameters.clear();
+        headers.clear();
+    }
+
+    public void setHeader( String key, String value ) {
+        this.headers.put(key, value );
+    }
+
+    public void setMethod( String method ) {
+        this.method = method;
+    }
+
+    public void clearSession() {
+        this.session = null;
+    }
+
+    public void setIsRequestedSessionIdFromURL( boolean isRequestedSessionIdFromURL ) {
+        this.isRequestedSessionIdFromURL = isRequestedSessionIdFromURL;
+    }
+    
+    public void setIsRequestedSessionIdFromCooki( boolean isRequestedSessionIdFromCookie ) {
+        this.isRequestedSessionIdFromCookie = isRequestedSessionIdFromCookie;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(String name) {
+        return this.getAttribute(name, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames()
+     */
+    public Enumeration getAttributeNames() {
+        return this.getAttributeNames(Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object)
+     */
+    public void setAttribute(String name, Object value) {
+        this.setAttribute(name, value, Request.GLOBAL_SCOPE);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String)
+     */
+    public void removeAttribute(String name) {
+        this.removeAttribute(name, Request.GLOBAL_SCOPE);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttribute(java.lang.String, int)
+     */
+    public Object getAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return this.attributes.get(name);
+        }
+        return this.globalAttributes.get(name);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getAttributeNames(int)
+     */
+    public Enumeration getAttributeNames(int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            return this.attributes.keys();
+        }
+        return this.globalAttributes.keys();
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#setAttribute(java.lang.String, java.lang.Object, int)
+     */
+    public void setAttribute(String name, Object value, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.put(name, value);
+        } else {
+            this.globalAttributes.put(name, value);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#removeAttribute(java.lang.String, int)
+     */
+    public void removeAttribute(String name, int scope) {
+        if ( scope == Request.REQUEST_SCOPE ) {
+            this.attributes.remove(name);
+        } else {
+            this.globalAttributes.remove(name);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.environment.Request#getInputStream()
+     */
+    public InputStream getInputStream() throws IOException, UnsupportedOperationException {
+        return this.inputStream;
+    }
+
+    public void setInputStream(InputStream is) {
+        this.inputStream = is;
+    }
+
+    /**
+     * @see org.apache.cocoon.environment.Request#searchAttribute(java.lang.String)
+     */
+    public Object searchAttribute(String name) {
+        Object result = this.getAttribute(name, REQUEST_SCOPE);
+        if ( result == null ) {
+            result = this.getAttribute(name, GLOBAL_SCOPE);
+        }
+        return result;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockResponse.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockResponse.java
new file mode 100644
index 0000000..22cee15
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockResponse.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import java.util.Locale;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.cocoon.environment.Cookie;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.Session;
+
+public class MockResponse implements Response {
+
+    private String encoding;
+    private Locale locale;
+    private Set cookies = new HashSet();
+    private Map header = new HashMap();
+
+    private Session session;
+    
+    public void setCharacterEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    public String getCharacterEncoding() {
+        return encoding;
+    }
+
+    public void setLocale(Locale locale) {
+        this.locale = locale;
+    }
+
+    public Locale getLocale() {
+        return locale;
+    }
+
+    public Cookie createCookie(String name, String value) {
+        MockCookie cookie = new MockCookie();
+        cookie.setName(name);
+        cookie.setValue(value);
+        return cookie;
+    }
+
+    public void addCookie(Cookie cookie) {
+        cookies.add(cookie);
+    }
+
+    public Set getCookies() {
+        return cookies;
+    }
+
+    public boolean containsHeader(String name) {
+        return header.containsKey(name);
+    }
+
+    public String encodeURL(String url) {
+        //throw new AssertionFailedError("Not implemented");
+        StringBuffer sb = new StringBuffer();
+            sb.append( url );
+        if (session != null) {
+            sb.append( "?JSESSIONID=");
+            sb.append( session.getId() );
+        }
+        return sb.toString();
+    }
+
+    public void setDateHeader(String name, long date) {
+        header.put(name, new Long(date));
+    }
+
+    public void addDateHeader(String name, long date) {
+        header.put(name, new Long(date));
+    }
+
+    public void setHeader(String name, String value) {
+        header.put(name, value);
+    }
+
+    public void addHeader(String name, String value) {
+        header.put(name, value);
+    }
+
+    public void setIntHeader(String name, int value) {
+        header.put(name, new Integer(value));
+    }
+
+    public void addIntHeader(String name, int value) {
+        header.put(name, new Integer(value));
+    }
+
+    public Map getHeader() {
+        return header;
+    }
+
+    public void reset() {
+        encoding = null;
+        locale = null;
+        cookies.clear();
+        header.clear();
+    }
+    
+    public void setSession( Session session ) {
+        this.session = session;
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockSession.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockSession.java
new file mode 100644
index 0000000..8b14635
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/environment/mock/MockSession.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.environment.mock;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.cocoon.environment.impl.AbstractSession;
+
+public class MockSession extends AbstractSession {
+
+    private long creationtime = System.currentTimeMillis();
+    private String id = "MockSession";
+    private long lastaccessedtime = System.currentTimeMillis();
+    private int maxinactiveinterval = -1;
+    private Hashtable attributes = new Hashtable();
+    private boolean valid = true;
+    private boolean isNew = false;
+
+    public long getCreationTime() {
+        checkValid();
+        return creationtime;
+    }
+  
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        checkValid();
+        return id;
+    }
+
+    public long getLastAccessedTime() {
+        checkValid();
+        return lastaccessedtime;
+    }
+
+    public void setMaxInactiveInterval(int interval) {
+        checkValid();
+        this.maxinactiveinterval = interval;
+    }
+
+    public int getMaxInactiveInterval() {
+        checkValid();
+        return maxinactiveinterval;
+    }
+
+    public Object getAttribute(String name) {
+        checkValid();
+        return attributes.get(name);
+    }
+
+    public Enumeration getAttributeNames() {
+        checkValid();
+        return attributes.keys();
+    }
+
+    public void setAttribute(String name, Object value) {
+        checkValid();
+        attributes.put(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        checkValid();
+        attributes.remove(name);
+    }
+
+    public void invalidate() {
+        checkValid();
+        this.valid = false;
+    }
+
+    public boolean isNew() {
+        checkValid();
+        return isNew;
+    }
+
+    private void checkValid() throws IllegalStateException {
+        if (!valid) {
+            throw new AssertionFailedError("session has been invalidated!");
+        }
+    }
+
+    public boolean isValid() {
+        return valid;
+    }
+    
+    public void setIsNew(boolean isNew ) {
+        this.isNew = isNew;
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.java
new file mode 100644
index 0000000..2fb0697
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.MockLogger;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.xml.WhitespaceFilter;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.impl.ResourceSource;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.custommonkey.xmlunit.Diff;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+import org.w3c.dom.Document;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ *
+ * @version $Id$
+ */
+public class FileGeneratorTestCase extends MockObjectTestCase {
+    private Map objectModel = new HashMap();
+    private SAXParser parser;
+    private Mock manager = new Mock(ServiceManager.class);
+    
+    public void setUp() throws SAXException {
+        final XMLReader xmlReader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+        parser = new SAXParser() {
+
+            public void parse(InputSource src, 
+                              ContentHandler contentHandler) throws SAXException, IOException {
+                xmlReader.setContentHandler(contentHandler);
+                xmlReader.parse(src);
+            }
+
+            public void parse(InputSource src, 
+                              ContentHandler contentHandler, 
+                              LexicalHandler lexicalHandler) throws SAXException, IOException {
+                parse(src, contentHandler);
+            }
+            
+        };
+    }
+    
+    public void testFileGenerator() throws Exception {
+        String src = "resource://org/apache/cocoon/generation/FileGeneratorTestCase.source.xml";
+        Parameters parameters = new Parameters();
+        String result = "resource://org/apache/cocoon/generation/FileGeneratorTestCase.source.xml";
+        FileGenerator generator = new FileGenerator();
+        generator.enableLogging(new MockLogger(generator.getClass()));
+        manager.expects(atLeastOnce()).method("lookup").with(same(SAXParser.ROLE)).
+                will(returnValue(parser));
+        manager.expects(once()).method("release").with(same(parser));
+        Mock resolver = new Mock(SourceResolver.class);
+        Source source = new ResourceSource(src);
+        resolver.expects(once()).method("resolveURI").with(same(src)).
+                will(returnValue(source));
+        resolver.expects(once()).method("release").with(same(source));
+        generator.service((ServiceManager) manager.proxy());
+        generator.setup((SourceResolver) resolver.proxy(), objectModel, src, parameters);
+        DOMBuilder builder = new DOMBuilder();
+        generator.setConsumer(new WhitespaceFilter(builder));
+        generator.generate();
+        assertEqual(load(result), builder.getDocument());
+    }
+
+    protected Document load(String src) throws ProcessingException, SAXException, IOException {
+        Source source = new ResourceSource(src);
+        manager.expects(atLeastOnce()).method("lookup").with(same(SAXParser.ROLE)).
+        will(returnValue(parser));
+        manager.expects(once()).method("release").with(same(parser));
+        DOMBuilder builder = new DOMBuilder();
+        SourceUtil.parse((ServiceManager) manager.proxy(), source, new WhitespaceFilter(builder));
+        return builder.getDocument();
+    }
+    
+    /**
+     * Compare two XML documents provided as strings
+     * @param control Control document
+     * @param test Document to test
+     * @return Diff object describing differences in documents
+     */
+    public final Diff compareXML(Document control, Document test) {
+        return new Diff(control, test);
+    }
+
+    /**
+     * Assert that the result of an XML comparison is similar.
+     *
+     * @param msg The assertion message
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertEqual(String msg, Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals(msg + ", " + diff.toString(), true, diff.similar());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is similar.
+     *
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */  
+    public final void assertEqual(Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals("Test if the assertion document is equal, " + diff.toString(), true, diff.similar());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is identical.
+     *
+     * @param msg The assertion message
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertIdentical(String msg, Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals(msg + ", " + diff.toString(), true, diff.identical());
+    }
+
+    /**
+     * Assert that the result of an XML comparison is identical.
+     *
+     * @param expected The expected XML document
+     * @param actual The actual XML Document
+     */
+    public final void assertIdentical(Document expected, Document actual) {
+
+        expected.getDocumentElement().normalize();
+        actual.getDocumentElement().normalize();
+
+        Diff diff = compareXML(expected, actual);
+
+        assertEquals("Test if the assertion document is equal, " + diff.toString(), true, diff.identical());
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.source.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.source.xml
new file mode 100644
index 0000000..33880dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.source.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<a>
+ <b>bla bla bla</b>
+ <c xmlns="http://xml.apache.org/cocoon/schema/bla/1.0">
+  <d>bla</d>
+ </c>
+</a>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/PauseGenerator.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/PauseGenerator.java
new file mode 100644
index 0000000..344d669
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/PauseGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import java.io.IOException;
+
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.generation.FileGenerator;
+import org.xml.sax.SAXException;
+
+/**
+ * This generator extends the usual FileGenerator with a pause parameter.
+ * During generation of the content, this generator pauses for the given
+ * amount of time.
+ * This is very usefull for caching tests.
+ * 
+ *  @version $Id$
+ *  @since   2.1
+ */
+public class PauseGenerator 
+    extends FileGenerator {
+
+
+    public void generate()
+    throws IOException, SAXException, ProcessingException {
+        long secs = this.parameters.getParameterAsLong("pause", 60);
+        this.getLogger().debug("Waiting for " + secs + " secs.");
+        try {
+            Thread.sleep(secs * 1000);
+        } catch (InterruptedException ie) {
+        }
+        this.getLogger().debug("Finished waiting.");
+        super.generate();
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.java
new file mode 100644
index 0000000..32307cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.generation;
+
+import org.apache.cocoon.test.SitemapTestCase;
+
+public class VirtualPipelineGeneratorTestCase extends SitemapTestCase {
+    public void testSimplePipe() throws Exception {
+        pipeTest("test", "vpc-test.xml");
+    }
+
+    public void testVirtualPipe() throws Exception {
+        pipeTest("v1", "vpc-test.xml");
+    }
+
+    public void testVirtualPipeParam() throws Exception {
+        pipeTest("v2", "vpc-param-expected.xml");
+    }
+
+    public void testVirtualPipeSourceParam() throws Exception {
+        pipeTest("v3", "vpc-source-param-expected.xml");
+    }
+
+    public void testVirtualSubPipeSourceParam() throws Exception {
+        pipeTest("sub/v3", "vpc-source-param-expected.xml");
+    }
+
+    public void testVirtualPipeSrc() throws Exception {
+        pipeTest("v4", "vpc-test.xml");
+    }
+
+    public void testVirtualSubPipeSrc() throws Exception {
+        pipeTest("sub/v4", "vpc-test.xml");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.xconf
new file mode 100644
index 0000000..194f5cf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/VirtualPipelineGeneratorTestCase.xconf
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<cocoon version="2.2">
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <input-modules>
+    <component-instance class="org.apache.cocoon.components.modules.input.EnvironmentAttributeModule" name="environment-attr"/>
+  </input-modules>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ModuleSourceFactory" name="module"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.XModuleSourceFactory" name="xmodule"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <!-- Relative sitemap path works during sitemap execution but
+       give exceptions during decommissioning -->
+  <sitemap file="resource://org/apache/cocoon/generation/vpc-sitemap.xmap"/>
+
+</cocoon>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-input1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-input1.xml
new file mode 100644
index 0000000..019b450
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-input1.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+Skin configuration file. This file contains details of your project, which will
+be used to configure the chosen Forrest skin.
+-->
+
+<!DOCTYPE skinconfig [
+
+  <!ENTITY % links.att 'name CDATA #REQUIRED'>
+  <!ENTITY % link.att 'name CDATA #REQUIRED href CDATA #REQUIRED'>
+  <!ELEMENT skinconfig (disable-search?, disable-compliance-links?, searchsite-domain?, searchsite-name?,
+  project-name, project-url, project-logo, group-name?, group-url?, group-logo?,
+  host-url?, host-logo?, year?, vendor?, trail?, credits?)*>
+  <!ELEMENT credits (credit*)>
+  <!ELEMENT credit (name, url, image?, width?, height?)>
+  <!-- id uniquely identifies the tool, and role indicates its function -->
+  <!ATTLIST credit id   CDATA #IMPLIED
+                   role CDATA #IMPLIED>
+  <!ELEMENT disable-search (#PCDATA)>
+  <!ELEMENT disable-compliance-links (#PCDATA)>
+  <!ELEMENT searchsite-domain (#PCDATA)>
+  <!ELEMENT searchsite-name (#PCDATA)>  
+  <!ELEMENT project-name (#PCDATA)>
+  <!ELEMENT project-url (#PCDATA)>
+  <!ELEMENT project-logo (#PCDATA)>
+  <!ELEMENT group-name (#PCDATA)>
+  <!ELEMENT group-url (#PCDATA)>
+  <!ELEMENT group-logo (#PCDATA)>
+  <!ELEMENT host-url (#PCDATA)>
+  <!ELEMENT host-logo (#PCDATA)>
+  <!ELEMENT year (#PCDATA)>
+  <!ELEMENT vendor (#PCDATA)>
+  <!ELEMENT trail (link1, link2, link3)>
+  <!ELEMENT link1 EMPTY>
+  <!-- Seems we can't use param entity refs until this is DTDified -->
+  <!ATTLIST link1 name CDATA #REQUIRED href CDATA #IMPLIED>
+  <!ELEMENT link2 EMPTY>
+  <!ATTLIST link2 name CDATA #REQUIRED href CDATA #IMPLIED>
+  <!ELEMENT link3 EMPTY>
+  <!ATTLIST link3 name CDATA #REQUIRED href CDATA #IMPLIED>
+  <!ELEMENT name (#PCDATA)>
+  <!ELEMENT url (#PCDATA)>
+  <!ELEMENT image (#PCDATA)>
+  <!ELEMENT width (#PCDATA)>
+  <!ELEMENT height (#PCDATA)>
+  ]>
+
+<skinconfig>
+  <!-- Do we want to disable the Google search box? -->
+  <disable-search>false</disable-search>
+  <disable-compliance-links>false</disable-compliance-links>
+
+  <searchsite-domain>xml.apache.org</searchsite-domain>
+  <searchsite-name>Apache XML</searchsite-name>  
+
+  <!-- mandatory project logo
+       skin: forrest-site renders it at the top -->
+  <project-name>Forrest</project-name>
+  <project-url>http://xml.apache.org/forrest/</project-url>
+  <project-logo>images/project-logo.gif</project-logo>
+
+  <!-- optional group logo
+       skin: forrest-site renders it at the top-left corner -->
+  <group-name>Apache XML</group-name>
+  <group-url>http://xml.apache.org/</group-url>
+  <group-logo>images/group-logo.gif</group-logo>
+
+  <!-- optional host logo (e.g. sourceforge logo)
+       skin: forrest-site renders it at the bottom-left corner -->
+  <host-url></host-url>
+  <host-logo></host-logo>
+
+  <!-- The following are used to construct a copyright statement -->
+  <year>2002</year>
+  <vendor>The Apache Software Foundation.</vendor>
+
+  <!-- Some skins use this to form a 'breadcrumb trail' of links. If you don't
+  want these, set the attributes to blank. The DTD purposefully requires them.
+  -->
+  <trail>
+    <link1 name="apache" href="http://www.apache.org/"/>
+    <link2 name="xml.apache" href="http://xml.apache.org/"/>
+    <link3 name="" href=""/>
+  </trail>
+
+  <!-- Credits are typically rendered as a set of small clickable images in the
+  page footer -->
+  <credits>
+    <credit>
+      <name>Built with Cocoon</name>
+      <url>http://xml.apache.org/cocoon/</url>
+      <image>images/built-with-cocoon.gif</image>
+      <width>88</width>
+      <height>31</height>
+    </credit>
+    <credit>
+      <name>Krysalis Centipede</name>
+      <url>http://www.krysalis.org/centipede/</url>
+      <image>images/centipede-logo-small.gif</image>
+      <width>138</width>
+      <height>31</height>
+    </credit>
+  </credits>
+</skinconfig>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-result1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-result1.xml
new file mode 100644
index 0000000..43ff380
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/filetest-result1.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<skinconfig>
+<!-- Do we want to disable the Google search box? -->
+  <disable-search>false</disable-search>
+  <disable-compliance-links>false</disable-compliance-links>
+  <searchsite-domain>xml.apache.org</searchsite-domain>
+  <searchsite-name>Apache XML</searchsite-name>
+<!-- mandatory project logo
+       skin: forrest-site renders it at the top -->
+  <project-name>Forrest</project-name>
+  <project-url>http://xml.apache.org/forrest/</project-url>
+  <project-logo>images/project-logo.gif</project-logo>
+<!-- optional group logo
+       skin: forrest-site renders it at the top-left corner -->
+  <group-name>Apache XML</group-name>
+  <group-url>http://xml.apache.org/</group-url>
+  <group-logo>images/group-logo.gif</group-logo>
+<!-- optional host logo (e.g. sourceforge logo)
+       skin: forrest-site renders it at the bottom-left corner -->
+  <host-url/>
+  <host-logo/>
+<!-- The following are used to construct a copyright statement -->
+  <year>2002</year>
+  <vendor>The Apache Software Foundation.</vendor>
+<!-- Some skins use this to form a 'breadcrumb trail' of links. If you don't
+  want these, set the attributes to blank. The DTD purposefully requires them.
+  -->
+  <trail>
+    <link1 name="apache" href="http://www.apache.org/"/>
+    <link2 name="xml.apache" href="http://xml.apache.org/"/>
+    <link3 name="" href=""/>
+  </trail>
+<!-- Credits are typically rendered as a set of small clickable images in the
+  page footer -->
+  <credits>
+    <credit>
+      <name>Built with Cocoon</name>
+      <url>http://xml.apache.org/cocoon/</url>
+      <image>images/built-with-cocoon.gif</image>
+      <width>88</width>
+      <height>31</height>
+    </credit>
+    <credit>
+      <name>Krysalis Centipede</name>
+      <url>http://www.krysalis.org/centipede/</url>
+      <image>images/centipede-logo-small.gif</image>
+      <width>138</width>
+      <height>31</height>
+    </credit>
+  </credits>
+</skinconfig>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/sitemap.xmap
new file mode 100644
index 0000000..0370afa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/sitemap.xmap
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="v3">
+        <map:generate type="virtual3">
+          <map:parameter name="source" value="test.xml"/>
+          <map:parameter name="foo" value="bar"/>
+        </map:generate>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="v4">
+        <map:generate type="virtual4" src="test.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/sub/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param-expected.xml
new file mode 100644
index 0000000..fc2f9ca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test foo2="bar"/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param.xml
new file mode 100644
index 0000000..3b616fb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-param.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test foo2="${cocoon.parameters.foo2}"/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-sitemap.xmap
new file mode 100644
index 0000000..2c9841c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-sitemap.xmap
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+      <map:generator name="jx" src="org.apache.cocoon.generation.JXTemplateGenerator"/>
+      <map:generator name="virtual1" src="org.apache.cocoon.generation.VirtualPipelineGenerator">
+        <map:generate type="file" src="vpc-test.xml"/>
+      </map:generator>
+      <map:generator name="virtual2" src="org.apache.cocoon.generation.VirtualPipelineGenerator">
+        <map:generate type="jx" src="vpc-param.xml">
+           <map:parameter name="foo2" value="{foo}"/>
+        </map:generate>
+      </map:generator>
+      <map:generator name="virtual3" src="org.apache.cocoon.generation.VirtualPipelineGenerator">
+        <map:source param="source"/>
+        <map:generate type="jx" src="vpc-source-param.xml">
+           <map:parameter name="source" value="{source}"/>
+           <map:parameter name="foo2" value="{foo}"/>
+        </map:generate>
+      </map:generator>
+      <map:generator name="virtual4" src="org.apache.cocoon.generation.VirtualPipelineGenerator">
+        <map:generate src="{src}"/>
+      </map:generator>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer">
+        <xslt-processor-role>xalan</xslt-processor-role>
+      </map:transformer>
+    </map:transformers>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="test">
+        <map:generate type="file" src="vpc-test.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="v1">
+        <map:generate type="virtual1"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="v2">
+        <map:generate type="virtual2">
+          <map:parameter name="foo" value="bar"/>
+        </map:generate>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="v3">
+        <map:generate type="virtual3">
+          <map:parameter name="source" value="vpc-test.xml"/>
+          <map:parameter name="foo" value="bar"/>
+        </map:generate>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="sub/**">
+        <map:mount uri-prefix="sub"
+                   src="resource://org/apache/cocoon/generation/sub/"/>
+      </map:match>
+
+      <map:match pattern="v4">
+        <map:generate type="virtual4" src="vpc-test.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param-expected.xml
new file mode 100644
index 0000000..72ec70b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test source="module:environment-attr:env-prefix-generator-source-map-virtual3#source" foo2="bar"/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param.xml
new file mode 100644
index 0000000..a0a1b2a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-source-param.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test source="${cocoon.parameters.source}" foo2="${cocoon.parameters.foo2}"/>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/generation/vpc-test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.java
new file mode 100644
index 0000000..1068787
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.mock.MockCookie;
+
+public class CookieMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(CookieMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple cookie matcher test
+     */
+    public void testCookieMatch() throws Exception {
+        // create a cookie
+        // setting name := cookieName, value := cookieValue
+        Map cookies = getRequest().getCookieMap();
+        MockCookie mockCookie = new MockCookie();
+        mockCookie.setName("cookieName");
+        mockCookie.setValue("cookieValue");
+        cookies.put( "cookieName", mockCookie );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("cookie", "cookieName", parameters);
+        System.out.println(result);
+        assertNotNull("Test if cookie exists", result);
+        assertEquals("Test for cookie cookieName having value cookieValue", "cookieValue", result.get("1"));
+    }
+    
+    /**
+     * A simple cookie matcher test
+     */
+    public void testCookieMatchFails() throws Exception {
+        // create a cookie
+        // setting name := cookieName, value := cookieValue
+        Map cookies = getRequest().getCookieMap();
+        MockCookie mockCookie = new MockCookie();
+        mockCookie.setName("cookieName");
+        mockCookie.setValue("cookieValue");
+        cookies.put( "cookieName", mockCookie );
+        
+        Parameters parameters = new Parameters();
+        
+        Map result = match( "cookie", "cookieNameDoesNotExists", parameters );
+        System.out.println(result);
+        assertNull( "Test if cookie does not exist", result );
+    }
+
+    protected boolean addSourceFactories() {
+        return true;
+    }
+    
+    protected boolean addSourceResolver() {
+        return true;
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.xtest
new file mode 100644
index 0000000..93a4344
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/CookieMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.CookieMatcher" 
+                       name="cookie"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.java
new file mode 100644
index 0000000..bf32313
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class HeaderMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(HeaderMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple header matcher test
+     */
+    public void testHeaderMatch() throws Exception {
+        // create a header attribute
+        final String headerName = "headerMatchTestCase";
+        final String headerValue = "headerMatchTestCaseValue";
+        getRequest().setHeader(headerName, headerValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("header", headerName, parameters);
+        System.out.println(result);
+        assertNotNull("Test if header entry exists", result);
+        assertEquals("Test for header " + headerName + " having value " + headerValue, headerValue, result.get("1"));
+    }
+    
+    /**
+     * A simple header matcher test
+     */
+    public void testHeaderMatchFails() throws Exception {
+        final String headerNameDoesNotExist = "headerNameDoesNotExist";
+        
+        final String headerName = "headerMatchTestCase";
+        final String headerValue = "headerMatchTestCaseValue";
+        getRequest().setHeader(headerName, headerValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("header", headerNameDoesNotExist, parameters);
+        assertNull( "Test if header entry " + headerNameDoesNotExist + " does not exist", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.xtest
new file mode 100644
index 0000000..23e28e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/HeaderMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.HeaderMatcher" 
+                       name="header"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.java
new file mode 100644
index 0000000..697fb84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class ParameterMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(ParameterMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple parameter matcher test
+     */
+    public void testParameterMatch() throws Exception {
+        // create a parameter attribute
+        
+        Parameters parameters = new Parameters();
+        final String parameterName = "paramterMatchTestCase";
+        final String parameterValue = "parameterMatchTestCaseValue";
+        parameters.setParameter( parameterName, parameterValue );
+
+        Map result = match("parameter", parameterName, parameters);
+        System.out.println(result);
+        assertNotNull("Test if parameter entry exists", result);
+        assertEquals("Test for parameter " + parameterName + " having value " + parameterValue, parameterValue, result.get("1"));
+    }
+    
+    /**
+     * A simple parameter matcher test
+     */
+    public void testParameterMatchFails() throws Exception {        
+        Parameters parameters = new Parameters();
+        
+        final String parameterNameDoesNotExist = "parameterNameDoesNotExist";
+        
+        // create a parameter attribute
+        final String parameterName = "paramterMatchTestCase";
+        final String parameterValue = "parameterMatchTestCaseValue";
+        parameters.setParameter( parameterName, parameterValue );
+
+        Map result = match("parameter", parameterNameDoesNotExist, parameters);
+        assertNull( "Test if parameter entry " + parameterNameDoesNotExist + " does not exist", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.xtest
new file mode 100644
index 0000000..5af761d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/ParameterMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.ParameterMatcher" 
+                       name="parameter"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.java
new file mode 100644
index 0000000..af665e3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.java
@@ -0,0 +1,65 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RegexpURIMatcherTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RegexpURIMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple regexp matcher test
+     */
+    public void testRegexpURIMatch() throws Exception {
+        getRequest().setRequestURI("/test/foo/bla/end");
+
+        Parameters parameters = new Parameters();
+
+        Map result = match("regexp-uri", "(.*)", parameters);
+        System.out.println(result);
+        assertNotNull("Test if resource exists", result);
+        assertEquals("Test for .*", "test/foo/bla/end", result.get("1"));
+        
+        result = match("regexp-uri", "(.*)/bla/(.*)", parameters);
+        System.out.println(result);
+        assertNotNull("Test if resource exists", result);
+        assertEquals("Test for (.*)/bla/(.*) {1}", "test/foo", result.get("1"));
+        assertEquals("Test for (.*)/bla/(.*) {2}", "end", result.get("2"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.xtest
new file mode 100644
index 0000000..b661f1e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RegexpURIMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.RegexpURIMatcher" 
+                       name="regexp-uri"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.java
new file mode 100644
index 0000000..565d90a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RequestAttributeMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RequestAttributeMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple request-attribute matcher test
+     */
+    public void testRequestAttributeMatch() throws Exception {
+        // create a request attribute
+        final String requestAttributeName = "requestAttributeMatchTestCase";
+        final String requestAttributeValue = "requestAttributeMatchTestCaseValue";
+        getRequest().setAttribute( requestAttributeName, requestAttributeValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("request-attribute", requestAttributeName, parameters);
+        System.out.println(result);
+        assertNotNull("Test if request-attribute entry exists", result);
+        assertEquals("Test for request-attribute " + requestAttributeName + " having value " + requestAttributeValue, requestAttributeValue, result.get("1"));
+    }
+    
+    /**
+     * A simple request-attribute matcher test
+     */
+    public void testHeaderMatchFails() throws Exception {
+        final String requestAttributeNameDoesNotExist = "requestAttributeDoesNotExist";
+        
+        // create a request attribute
+        final String requestAttributeName = "requestAttributeMatchTestCase";
+        final String requestAttributeValue = "requestAttributeMatchTestCaseValue";
+        getRequest().setAttribute( requestAttributeName, requestAttributeValue );
+        
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("request-attribute", requestAttributeNameDoesNotExist, parameters);
+        assertNull( "Test if request-attribute entry " + requestAttributeNameDoesNotExist + " does not exist", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.xtest
new file mode 100644
index 0000000..c2fa8dc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestAttributeMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.RequestAttributeMatcher" 
+                       name="request-attribute"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.java
new file mode 100644
index 0000000..2ee69eb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RequestParameterMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RequestParameterMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple request-parameter matcher test
+     */
+    public void testRequestParameterMatch() throws Exception {
+        // create a request parameter
+        final String requestParameterName = "requestParameterMatchTestCase";
+        final String requestParameterValue = "requestParameterMatchTestCaseValue";
+        getRequest().addParameter( requestParameterName, requestParameterValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("request-parameter", requestParameterName, parameters);
+        System.out.println(result);
+        assertNotNull("Test if request-parameter entry exists", result);
+        assertEquals("Test for request-parameter " + requestParameterName + " having value " + requestParameterValue, requestParameterValue, result.get("1"));
+    }
+    
+    /**
+     * A simple request-parameter matcher test
+     */
+    public void testParameterMatchFails() throws Exception {
+        final String requestParameterNameDoesNotExist = "requestParameterDoesNotExist";
+        
+        // create a request attribute
+        // create a request parameter
+        final String requestParameterName = "requestParameterMatchTestCase";
+        final String requestParameterValue = "requestParameterMatchTestCaseValue";
+        getRequest().addParameter( requestParameterName, requestParameterValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("request-parameter", requestParameterNameDoesNotExist, parameters);
+        assertNull( "Test if request-parameter entry " + requestParameterNameDoesNotExist + " does not exist", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.xtest
new file mode 100644
index 0000000..fbf1eef
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/RequestParameterMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.RequestParameterMatcher" 
+                       name="request-parameter"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.java
new file mode 100644
index 0000000..eed95a9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.Session;
+
+public class SessionAttributeMatcherTestCase extends SitemapComponentTestCase {
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(SessionAttributeMatcherTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple session-attribute matcher test
+     */
+    public void testSessionAttributeMatch() throws Exception {
+        // create a session attribute
+        final String sessionAttributeName = "sessionAttributeMatchTestCase";
+        final String sessionAttributeValue = "sessionAttributeMatchTestCaseValue";
+        Session session = getRequest().getSession(true);
+        session.setAttribute(sessionAttributeName, sessionAttributeValue );
+        
+        Parameters parameters = new Parameters();
+
+        Map result = match("session-attribute", sessionAttributeName, parameters);
+        System.out.println(result);
+        assertNotNull("Test if session-attribute entry exists", result);
+        assertEquals("Test for session-attribute " + sessionAttributeName + " having value " + sessionAttributeValue, sessionAttributeValue, result.get("1"));
+    }
+    
+    /**
+     * A simple request-attribute matcher test
+     */
+    public void testSessionMatchFails() throws Exception {
+        final String sessionAttributeNameDoesNotExist = "sessionAttributeDoesNotExist";
+        Parameters parameters = new Parameters();
+
+        // test w/o an existing session
+        getRequest().clearSession();
+
+        Map result;
+        result = match("session-attribute", sessionAttributeNameDoesNotExist, parameters);
+        assertNull( "Test if session-attribute entry " + sessionAttributeNameDoesNotExist + " does not exist", result );
+        
+        // create a session attribute
+        final String sessionAttributeName = "sessionAttributeMatchTestCase";
+        final String sessionAttributeValue = "sessionAttributeMatchTestCaseValue";
+        Session session = getRequest().getSession(true);
+        session.setAttribute(sessionAttributeName, sessionAttributeValue );        
+
+        // test w an existing session
+        result = match("session-attribute", sessionAttributeNameDoesNotExist, parameters);
+        assertNull( "Test if session-attribute entry " + sessionAttributeNameDoesNotExist + " does not exist", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.xtest
new file mode 100644
index 0000000..336958e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/SessionAttributeMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.SessionAttributeMatcher" 
+                       name="session-attribute"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.java
new file mode 100644
index 0000000..9cb06bd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.java
@@ -0,0 +1,62 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.matching;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class WildcardURIMatcherTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(WildcardURIMatcherTestCase.class);
+        return suite;
+    }
+    
+    public void testWildcardURIMatch() throws Exception {
+        getRequest().setRequestURI("/test/foo/bla/end");
+
+        Parameters parameters = new Parameters();
+
+        Map result = match("wildcard-uri", "**", parameters);
+        System.out.println(result);
+        assertNotNull("Test if resource exists", result);
+        assertEquals("Test for **", "test/foo/bla/end", result.get("1"));
+        
+        result = match("wildcard-uri", "**/bla/*", parameters);
+        System.out.println(result);
+        assertNotNull("Test if resource exists", result);
+        assertEquals("Test for **/bla/* {1}", "test/foo", result.get("1"));
+        assertEquals("Test for **/bla/* {2}", "end", result.get("2"));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.xtest
new file mode 100644
index 0000000..fb8fee9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/matching/WildcardURIMatcherTestCase.xtest
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.matching.MatcherSelector"
+        shorthand="matchers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <matchers logger="test">
+   <component-instance class="org.apache.cocoon.matching.WildcardURIMatcher" 
+                       name="wildcard-uri"/>
+  </matchers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.java
new file mode 100644
index 0000000..b51b3ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.reading;
+
+import org.apache.cocoon.test.SitemapTestCase;
+
+public class VirtualPipelineReaderTestCase extends SitemapTestCase {
+    public void testVirtualPipe() throws Exception {
+        pipeTest("v1", "vpc-test.xml");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.xconf
new file mode 100644
index 0000000..2ccce31
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/VirtualPipelineReaderTestCase.xconf
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<cocoon version="2.2">
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <input-modules>
+    <component-instance class="org.apache.cocoon.components.modules.input.EnvironmentAttributeModule" name="environment-attr"/>
+  </input-modules>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ModuleSourceFactory" name="module"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.XModuleSourceFactory" name="xmodule"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <!-- Relative sitemap path works during sitemap execution but
+       give exceptions during decommissioning -->
+  <sitemap file="resource://org/apache/cocoon/reading/vpc-sitemap.xmap"/>
+
+</cocoon>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-sitemap.xmap
new file mode 100644
index 0000000..a1bd182
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-sitemap.xmap
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer">
+        <xslt-processor-role>xalan</xslt-processor-role>
+      </map:transformer>
+    </map:transformers>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:readers>
+      <map:reader name="virtual1" src="org.apache.cocoon.reading.VirtualPipelineReader">
+        <map:generate type="file" src="vpc-test.xml"/>
+        <map:serialize type="xml"/>
+      </map:reader>
+    </map:readers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="v1">
+        <map:read type="virtual1"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/reading/vpc-test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.java
new file mode 100644
index 0000000..c4ce72a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.java
@@ -0,0 +1,81 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class BrowserSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(BrowserSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple non-configured browser name test
+     */
+    public void testBrowserSelectMisconfigured() throws Exception {
+        final String userAgent = "Mozilla";
+        
+        getRequest().setHeader("User-Agent", userAgent );
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        result = this.select( "browser", "non-configured-browser-name", parameters );
+        System.out.println( result );
+        assertTrue( "Test is browser is a non-configured-browser-name", !result );
+    }
+
+    /**
+     * A simple netscape browser test
+     */
+    public void testBrowserSelectNetscape() throws Exception {
+        final String userAgent = "Mozilla";
+        String expectedBrowserName;
+        
+        getRequest().setHeader("User-Agent", userAgent );
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        expectedBrowserName = "netscape";
+        result = this.select( "browser", expectedBrowserName, parameters );
+        System.out.println(result);
+        assertTrue( "Test if browser is " + expectedBrowserName, result );
+        
+        expectedBrowserName = "explorer";
+        result = this.select( "browser", expectedBrowserName, parameters );
+        System.out.println( result );
+        assertTrue( "Test if browser is NOT " + expectedBrowserName, !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.xtest
new file mode 100644
index 0000000..b43e8dd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/BrowserSelectorTestCase.xtest
@@ -0,0 +1,46 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.BrowserSelector" 
+                       name="browser">
+      <browser name="explorer" useragent="MSIE"/>
+      <browser name="pocketexplorer" useragent="MSPIE"/>
+      <browser name="handweb" useragent="HandHTTP"/>
+      <browser name="avantgo" useragent="AvantGo"/>
+      <browser name="imode" useragent="DoCoMo"/>
+      <browser name="opera" useragent="Opera"/>
+      <browser name="lynx" useragent="Lynx"/>
+      <browser name="java" useragent="Java"/>
+      <browser name="wap" useragent="Nokia"/>
+      <browser name="wap" useragent="UP"/>
+      <browser name="wap" useragent="Wapalizer"/>
+      <browser name="mozilla5" useragent="Mozilla/5"/>
+      <browser name="mozilla5" useragent="Netscape6/"/>
+      <browser name="netscape" useragent="Mozilla"/>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.java
new file mode 100644
index 0000000..6ca50f3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.java
@@ -0,0 +1,116 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.mock.MockCookie;
+
+public class CookieSelectorTestCase extends SitemapComponentTestCase {
+
+    private final String COOKIE_SELECTOR = "cookie";
+    
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(CookieSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple cookie select test
+     */
+    public void testCookieSelect() throws Exception {
+        final String cookieName = "cookieSelectorTestCase";
+        final String cookieValue = "cookieValue";
+        // create a cookie
+        // setting name := cookieName, value := cookieValue
+        Map cookies = getRequest().getCookieMap();
+        MockCookie mockCookie = new MockCookie();
+        mockCookie.setName( cookieName);
+        mockCookie.setValue( cookieValue );
+        cookies.put( cookieName, mockCookie );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( COOKIE_SELECTOR, cookieValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a cookie is selected", result );
+        
+        // test selection failure
+        result = this.select( COOKIE_SELECTOR, "unknownCookieValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a cookie is not selected", !result );
+    }
+
+    /**
+     * A simple cookie select test
+     */
+    public void testCookieSelectUsingParameters() throws Exception {
+        final String cookieName = "cookieSelectorTestCase1";
+        final String cookieValue = "cookieValue";
+        
+        // create a cookie
+        // setting name := cookieName, value := cookieValue
+        Map cookies = getRequest().getCookieMap();
+        MockCookie mockCookie = new MockCookie();
+        // this cookie shall get selected
+        mockCookie.setName( cookieName);
+        mockCookie.setValue( cookieValue );
+        cookies.put( cookieName, mockCookie );
+        
+        // this cookie shall be ignored, as its name differs
+        // from the parameterized cookie name
+        mockCookie = new MockCookie();
+        mockCookie.setName( "cookieSelectorTestCase" );
+        mockCookie.setValue( "unknownCookieValue" );
+        cookies.put( "cookieSelectorTestCase", mockCookie );
+
+        // check the cookie as defined by this parameter, not as
+        // defined in the component configuration
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "cookie-name", cookieName );
+        
+        boolean result;
+        
+        // test selection success
+        result = this.select( COOKIE_SELECTOR, cookieValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a cookie is selected", result );
+        
+        // test selection failure
+        result = this.select( COOKIE_SELECTOR, "unknownCookieValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a cookie is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.xtest
new file mode 100644
index 0000000..e6bdee6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/CookieSelectorTestCase.xtest
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.CookieSelector" 
+                       name="cookie">
+      <cookie-name>cookieSelectorTestCase</cookie-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.java
new file mode 100644
index 0000000..401e794
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.java
@@ -0,0 +1,148 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.ObjectModelHelper;
+
+public class ExceptionSelectorTestCase extends SitemapComponentTestCase {
+
+    private final String EXCEPTION_SELECTOR = "exception";    
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(ExceptionSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple exception select test
+     */
+    public void testExceptionSelect() throws Exception {
+        
+        // create an exception
+        final java.lang.NullPointerException npe = new java.lang.NullPointerException( "ExceptionSelectorTestCase");
+
+        // put the exception into the objectModel
+        Map objectModel = this.getObjectModel();
+        objectModel.put( ObjectModelHelper.THROWABLE_OBJECT, npe );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( EXCEPTION_SELECTOR, "npe", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a npe is selected", result );
+        
+        // test selection failure
+        result = this.select( EXCEPTION_SELECTOR, "non-specified-exception", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a non specified exception is not selected", !result );
+    }
+
+    /**
+     * A simple exception select test
+     */
+    public void testExceptionSelectUnknownException() throws Exception {
+        
+        // create an exception
+        final java.lang.IllegalArgumentException iae = new IllegalArgumentException( "ExceptionSelectorTestCase");
+
+        // put the exception into the objectModel
+        Map objectModel = this.getObjectModel();
+        objectModel.put( ObjectModelHelper.THROWABLE_OBJECT, iae );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection failure
+        result = this.select( EXCEPTION_SELECTOR, "npe", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a npe is not selected selected", !result );
+    }
+    
+    /**
+     * A simple exception select test
+     * The causing exception is listed, thus selecting the unrolling
+     * exception fails, selecting the causing exception succeeds.
+     */
+    public void testExceptionSelectProcessingException() throws Exception {
+        
+        // create an exception
+        final java.lang.NullPointerException npe = new NullPointerException( "NullPointerExceptionSelectorTestCase" );
+        final ProcessingException pe = new ProcessingException( "ProcessingExceptionSelectorTestCase", npe );
+        
+        // put the exception into the objectModel
+        Map objectModel = this.getObjectModel();
+        objectModel.put( ObjectModelHelper.THROWABLE_OBJECT, pe );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( EXCEPTION_SELECTOR, "npe", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a npe is selected", result );
+        
+        // test selection failure
+        result = this.select( EXCEPTION_SELECTOR, "pe", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a pe is not selected", !result );
+    }
+    
+    /**
+     * A simple exception select test.
+     * The causing exception is not listed, thus matching the unrolling
+     * exception succeeds
+     */
+    public void testExceptionSelectProcessingException2() throws Exception {
+        
+        // create an exception
+        final java.lang.IllegalArgumentException iae = new IllegalArgumentException( "ExceptionSelectorTestCase");
+        final ProcessingException pe = new ProcessingException( "ProcessingExceptionSelectorTestCase", iae );
+        
+        // put the exception into the objectModel
+        Map objectModel = this.getObjectModel();
+        objectModel.put( ObjectModelHelper.THROWABLE_OBJECT, pe );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( EXCEPTION_SELECTOR, "pe", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a pe is not selected", result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.xtest
new file mode 100644
index 0000000..e9f22d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ExceptionSelectorTestCase.xtest
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.ExceptionSelector" 
+                       name="exception">
+      <exception name="npe" class="java.lang.NullPointerException"/>
+      <exception name="not-found" class="org.apache.cocoon.ResourceNotFoundException"/>
+      <exception name="pe" class="org.apache.cocoon.ProcessingException" unroll="true"/>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.java
new file mode 100644
index 0000000..bccebf5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.java
@@ -0,0 +1,98 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class HeaderSelectorTestCase extends SitemapComponentTestCase {
+
+    private final String HEADER_SELECTOR = "header";
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(HeaderSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple header select test
+     */
+    public void testHeaderSelect() throws Exception {
+        final String headerName = "headerSelectorTestCase";
+        final String headerValue = "headerValue";
+        // create a header
+        // setting name := headerName, value := headerValue
+        getRequest().setHeader(headerName, headerValue);
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+
+        // test selection success
+        result = this.select( HEADER_SELECTOR, headerValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a header is selected", result );
+        
+        // test selection failure
+        result = this.select( HEADER_SELECTOR, "unknownHeaderValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a header is not selected", !result );
+    }
+
+    /**
+     * A simple header select test
+     */
+    public void testHeaderSelectUsingParameters() throws Exception {        
+        final String headerName = "headerSelectorTestCase1";
+        final String headerValue = "headerValue1";
+        // create a header
+        // setting name := headerName, value := headerValue
+        getRequest().setHeader(headerName, headerValue);
+
+        // check the header as defined by this parameter, not as
+        // defined in the component configuration
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "header-name", headerName );
+        
+        boolean result;
+        
+        // test selection success
+        result = this.select( HEADER_SELECTOR, headerValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a header is selected", result );
+        
+        // test selection failure
+        result = this.select( HEADER_SELECTOR, "unknownHeaderValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a header is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.xtest
new file mode 100644
index 0000000..66d1f35
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HeaderSelectorTestCase.xtest
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.HeaderSelector" 
+                       name="header">
+      <header-name>headerSelectorTestCase</header-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.java
new file mode 100644
index 0000000..62e9c77
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.java
@@ -0,0 +1,94 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class HostSelectorTestCase extends SitemapComponentTestCase {
+
+    private final String HOST_SELECTOR = "host";
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(HostSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple host selector test
+     */
+    public void testHostSelectEurope() throws Exception {
+        final String host = "myhost-dns-name-in-a-europe-country";
+        String expectedHostName;
+        
+        getRequest().setHeader("Host", host );
+        Parameters parameters = new Parameters();
+        boolean result;
+ 
+        // test selecting succeeds
+        expectedHostName = "myhost-eu";
+        result = this.select( HOST_SELECTOR, expectedHostName, parameters );
+        System.out.println(result);
+        assertTrue( "Test if host is " + expectedHostName, result );
+        
+        // test selecting fails
+        expectedHostName = "myhost-us";
+        result = this.select( HOST_SELECTOR, expectedHostName, parameters );
+        System.out.println(result);
+        assertTrue( "Test if host is not " + expectedHostName, !result );
+    }
+    
+    /**
+     * A simple host selector test
+     */
+    public void testHostSelectUnknownHost() throws Exception {
+        final String host = "myhost-dns-name-in-a-asia-country";
+        String expectedHostName;
+        
+        getRequest().setHeader("Host", host );
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selecting succeeds
+        expectedHostName = "myhost-eu";
+        result = this.select( HOST_SELECTOR, expectedHostName, parameters );
+        System.out.println(result);
+        assertTrue( "Test if host is not " + expectedHostName, !result );
+        
+        // test selecting fails
+        expectedHostName = "myhost-us";
+        result = this.select( HOST_SELECTOR, expectedHostName, parameters );
+        System.out.println(result);
+        assertTrue( "Test if host is not " + expectedHostName, !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.xtest
new file mode 100644
index 0000000..3d3ed88
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/HostSelectorTestCase.xtest
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.HostSelector" 
+                       name="host">
+      <host name="myhost-eu" value="myhost-dns-name-in-a-europe-country"/>
+      <host name="myhost-us" value="myhost-dns-name-in-a-us-state"/>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.java
new file mode 100644
index 0000000..16ae2d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.java
@@ -0,0 +1,85 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class ParameterSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(ParameterSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple parameter select test
+     */
+    public void testParameterSelect() throws Exception {
+        final String parameterName = "parameterSelectorTestCase";
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "parameter-selector-test", parameterName );
+        boolean result;
+        
+        // test selection success
+        result = this.select( "parameter", parameterName, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is selected", result );
+        
+        // test selection failure
+        result = this.select( "parameter", "unknownParameterName", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+    }
+
+    /**
+     * A simple parameter select test
+     */
+    public void testParameterSelectUndefined() throws Exception {
+        final String parameterName = "parameterSelectorTestCase";
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection fails
+        result = this.select( "parameter", parameterName, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+        
+        parameters.setParameter( "parameter-selector-test", "some-parameter-name" );
+        result = this.select( "parameter", parameterName, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.xtest
new file mode 100644
index 0000000..b6ef7fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ParameterSelectorTestCase.xtest
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.ParameterSelector" 
+                       name="parameter">
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.java
new file mode 100644
index 0000000..e892463
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.java
@@ -0,0 +1,113 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+/**
+ * Test case for RegexpHeaderSelector.
+ * 
+ * @version $Id$
+ */
+public class RegexpHeaderSelectorTestCase extends SitemapComponentTestCase {
+
+    private final String REGEXP_HEADER_SELECTOR = "regexp-header";
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RegexpHeaderSelectorTestCase.class);
+        return suite;
+    }
+    
+
+    /**
+     * A simple regexp-header selector test
+     */
+    public void testRegexpHeaderSelectEmpty() throws Exception {
+        // create a header
+        final String headerName = "headerSelectorTestCase";
+        getRequest().setHeader(headerName, "");
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        result = this.select( REGEXP_HEADER_SELECTOR, "empty", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " selects successfully", result );
+        
+        result = this.select( REGEXP_HEADER_SELECTOR, "number", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " does not select successfully", !result );
+        
+        result = this.select( REGEXP_HEADER_SELECTOR, "non-defined-name", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " does not select successfully", !result );
+    }
+
+    /**
+     * A simple regexp-header selector test
+     */
+    public void testRegexpHeaderSelectNumber() throws Exception {
+        // create a header
+        final String headerName = "headerSelectorTestCase";
+        final String headerName2 = "headerSelectorTestCase1";
+
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test w/o set request parameter
+        result = this.select( REGEXP_HEADER_SELECTOR, "empty", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " does not select successfully", !result );
+
+	// this time, set the header
+        getRequest().setHeader(headerName, "");
+
+	// create another header
+        getRequest().setHeader(headerName2, "123");
+
+        // override configured header name
+        parameters.setParameter( "header-name", headerName2 );
+        
+        result = this.select( REGEXP_HEADER_SELECTOR, "empty", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " does not select successfully", !result );
+
+        result = this.select( REGEXP_HEADER_SELECTOR, "number", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " selects successfully", result );
+
+        result = this.select( REGEXP_HEADER_SELECTOR, "non-defined-name", parameters );
+        System.out.println( result );
+        assertTrue( "Test is " + REGEXP_HEADER_SELECTOR + " does not select successfully", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.xtest
new file mode 100644
index 0000000..9135d34
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpHeaderSelectorTestCase.xtest
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.RegexpHeaderSelector" 
+                       name="regexp-header">
+     <pattern name="empty">^$</pattern>
+      <pattern name="number">^[0-9]+$</pattern>
+      <pattern name="string">^.+$</pattern>
+      <header-name>headerSelectorTestCase</header-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.java
new file mode 100644
index 0000000..1ef5f40
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.java
@@ -0,0 +1,94 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RegexpRequestParameterSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RegexpRequestParameterSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple regexp-request-parameter selector test
+     */
+    public void testRegexpRequestParameterSelectEmpty() throws Exception {
+        // create a request parameter
+        getRequest().addParameter( "parameterRegexpRequestParameterSelector", "" );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        result = this.select( "regexp-request-parameter", "empty", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter selects successfully", result );
+        
+        result = this.select( "regexp-request-parameter", "number", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter does not select successfully", !result );
+        
+        result = this.select( "regexp-request-parameter", "non-defined-name", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter does not select successfully", !result );
+    }
+
+    /**
+     * A simple regexp-request-parameter selector test
+     */
+    public void testRegexpRequestParameterSelectNumber() throws Exception {
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test w/o set request parameter
+        result = this.select( "regexp-request-parameter", "number", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter does not select successfully", !result );
+        
+        // create a request parameter
+        getRequest().addParameter( "parameterRegexpRequestParameterSelector1", "123" );
+
+        // override configured parameter name
+        parameters.setParameter( "parameter-name", "parameterRegexpRequestParameterSelector1" );
+        
+        result = this.select( "regexp-request-parameter", "number", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter does not selects successfully", result );
+
+        result = this.select( "regexp-request-parameter", "non-defined-name", parameters );
+        System.out.println( result );
+        assertTrue( "Test is regexp-request-parameter does not select successfully", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.xtest
new file mode 100644
index 0000000..7f2f178
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RegexpRequestParameterSelectorTestCase.xtest
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.RegexpRequestParameterSelector" 
+                       name="regexp-request-parameter">
+      <pattern name="empty">^$</pattern>
+      <pattern name="number">^[0-9]+$</pattern>
+      <pattern name="string">^.+$</pattern>
+      <parameter-name>parameterRegexpRequestParameterSelector</parameter-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.java
new file mode 100644
index 0000000..c1216c1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.java
@@ -0,0 +1,92 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RequestAttributeSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RequestAttributeSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A request-attribute parameter select test
+     */
+    public void testRequestAttributeSelect() throws Exception {
+        final String attributeName = "requestAttributeSelector";
+        final String attributeValue = "requestAttributeSelectorValue";
+        getRequest().setAttribute( attributeName, attributeValue );        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( "request-attribute", attributeValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a request attribtue is selected", result );
+        
+        // test selection failure
+        result = this.select( "request-attribute", "unknownValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a request attribute is not selected", !result );
+    }
+
+    /**
+     * A request-attribute parameter select test
+     */
+    public void testRequestAttributeSelectOverridden() throws Exception {
+        final String attributeName = "requestAttributeSelector1";
+        final String attributeValue = "requestAttributeSelectorValue1";
+        getRequest().setAttribute( attributeName, attributeValue );
+        
+        final String attributeNameOverridden = "requestAttributeSelector";
+        final String attributeValueOverridden = "requestAttributeSelectorValue";
+        getRequest().setAttribute( attributeNameOverridden, attributeValueOverridden );
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "attribute-name", attributeName );
+        boolean result;
+        
+        // test selection success
+        result = this.select( "request-attribute", attributeValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a requst attribtue is selected", result );
+        
+        // test selection failure
+        result = this.select( "request-attribute", attributeValueOverridden, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a request attribute is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.xtest
new file mode 100644
index 0000000..f5c5c69
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestAttributeSelectorTestCase.xtest
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.RequestAttributeSelector" 
+                       name="request-attribute">
+      <attribute-name>requestAttributeSelector</attribute-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.java
new file mode 100644
index 0000000..64d13de
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.java
@@ -0,0 +1,71 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RequestMethodSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RequestMethodSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A request-method select test
+     */
+    public void testRequestMethodSelect() throws Exception {
+        final String method = "POST";
+        getRequest().setMethod( "POST" );
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( "request-method", method, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a method is selected", result );
+        
+        // test selection failure
+        result = this.select( "request-method", "post", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a method is not selected", !result );
+        
+        // test selection failure
+        result = this.select( "request-method", "GET", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a method is not selected", !result );
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.xtest
new file mode 100644
index 0000000..217ed39
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestMethodSelectorTestCase.xtest
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.RequestMethodSelector" 
+                       name="request-method">
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.java
new file mode 100644
index 0000000..e4b5c57
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.java
@@ -0,0 +1,92 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class RequestParameterSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(RequestParameterSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A request-parameter parameter select test
+     */
+    public void testRequestParameterSelect() throws Exception {
+        final String parameterName = "requestParameterSelector";
+        final String parameterValue = "requestParameterSelectorValue";
+        getRequest().addParameter( parameterName, parameterValue );        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( "request-parameter", parameterValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a requst parameter is selected", result );
+        
+        // test selection failure
+        result = this.select( "request-parameter", "unknownValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a request parameter is not selected", !result );
+    }
+
+    /**
+     * A request-parameter parameter select test
+     */
+    public void testRequestParameterSelectOverridden() throws Exception {
+        final String parameterName = "requestParameterSelector1";
+        final String parameterValue = "requestParameterSelectorValue1";
+        getRequest().addParameter( parameterName, parameterValue );
+        
+        final String parameterNameOverridden = "requestParameterSelector";
+        final String parameterValueOverridden = "requestParameterSelectorValue";
+        getRequest().addParameter( parameterNameOverridden, parameterValueOverridden );
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "parameter-name", parameterName );
+        boolean result;
+        
+        // test selection success
+        result = this.select( "request-parameter", parameterValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a requst attribtue is selected", result );
+        
+        // test selection failure
+        result = this.select( "request-parameter", parameterValueOverridden, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a request parameter is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.xtest
new file mode 100644
index 0000000..709cdf3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/RequestParameterSelectorTestCase.xtest
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.RequestParameterSelector" 
+                       name="request-parameter">
+      <parameter-name>requestParameterSelector</parameter-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.java
new file mode 100644
index 0000000..e578dca
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.java
@@ -0,0 +1,92 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class ResourceExistsSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(ResourceExistsSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A resource-exists parameter select test
+     */
+    public void testResourceExistsSelect() throws Exception {
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        String expression = "";
+
+        // test selection success
+        expression = "resource://org/apache/cocoon/selection/ResourceExistsSelectorTestCase.class";
+        result = this.select( "resource-exists", expression, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a exisitng resource is selected", result );
+        
+        // test selection failure
+        expression = "resource://org/apache/cocoon/selection/NonExistingResource.class";
+        result = this.select( "resource-exists", expression, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a non exisitng resource is not selected", !result );
+        
+    }
+
+    /**
+     * A resource-exists parameter select test using the parameter prefix option
+     */
+    public void testResourceExistsSelectPrefix() throws Exception {
+        
+        Parameters parameters = new Parameters();
+        final String prefix = "resource://org/apache/cocoon/selection/";
+        parameters.setParameter( "prefix", prefix );
+        boolean result;
+        String expression = "";
+
+        // test selection success
+        expression = "ResourceExistsSelectorTestCase.class";
+        result = this.select( "resource-exists", expression, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a exisitng resource is selected", result );
+        
+        // test selection failure
+        expression = "NonExistingResource.class";
+        result = this.select( "resource-exists", expression, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a non exisitng resource is not selected", !result );
+        
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.xtest
new file mode 100644
index 0000000..3bf198c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/ResourceExistsSelectorTestCase.xtest
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.ResourceExistsSelector" 
+                       name="resource-exists">
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.java
new file mode 100644
index 0000000..71617bc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.java
@@ -0,0 +1,113 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.Session;
+
+public class SessionAttributeSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(SessionAttributeSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A session-attribute select test
+     */
+    public void testSessionAttributeSelect() throws Exception {
+        final String attributeName = "sessionAttributeSelector";
+        final String attributeValue = "sessionAttributeSelectorValue";
+        
+        Session session = getRequest().getSession(true);
+        session.setAttribute( attributeName, attributeValue );        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection success
+        result = this.select( "session-attribute", attributeValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a session attribtue is selected", result );
+        
+        // test selection failure
+        result = this.select( "session-attribute", "unknownValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a session attribute is not selected", !result );
+    }
+
+    /**
+     * A session-attribute select test
+     */
+    public void testSessionAttributeSelectOverridden() throws Exception {
+        final String attributeName = "sessionAttributeSelector1";
+        final String attributeValue = "sessionAttributeSelectorValue1";
+        Session session = getRequest().getSession(true);
+        session.setAttribute( attributeName, attributeValue );        
+        
+        final String attributeNameOverridden = "sessionAttributeSelector";
+        final String attributeValueOverridden = "sessionAttributeSelectorValue";
+        session.setAttribute( attributeNameOverridden, attributeValueOverridden );
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "attribute-name", attributeName );
+        boolean result;
+        
+        // test selection success
+        result = this.select( "session-attribute", attributeValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a requst attribtue is selected", result );
+        
+        // test selection failure
+        result = this.select( "session-attribute", attributeValueOverridden, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a session attribute is not selected", !result );
+    }
+    
+    /**
+     * A session-attribute select test
+     */
+    public void testSessionAttributeSelectMissingSession() throws Exception {
+        final String attributeValue = "sessionAttributeSelectorValue";
+
+        // test w/o session
+        getRequest().clearSession();
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection fails
+        result = this.select( "session-attribute", attributeValue, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a session attribtue is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.xtest
new file mode 100644
index 0000000..e300d37
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SessionAttributeSelectorTestCase.xtest
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.SessionAttributeSelector" 
+                       name="session-attribute">
+      <attribute-name>sessionAttributeSelector</attribute-name>
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.java
new file mode 100644
index 0000000..25100d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.java
@@ -0,0 +1,86 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.cocoon.selection;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+
+public class SimpleSelectorTestCase extends SitemapComponentTestCase {
+
+    /**
+     * Run this test suite from commandline
+     *
+     * @param args commandline arguments (ignored)
+     */
+    public static void main( String[] args ) {
+        TestRunner.run(suite());
+    }
+    
+    /** Create a test suite.
+     * This test suite contains all test cases of this class.
+     * @return the Test object containing all test cases.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite(SimpleSelectorTestCase.class);
+        return suite;
+    }
+    
+    /**
+     * A simple parameter select test
+     */
+    public void testSimpleSelect() throws Exception {
+        final String value = "simpleSelectorTestCase";
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "value", value );
+        boolean result;
+        
+        // test selection success
+        result = this.select( "simple", value, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is selected", result );
+        
+        // test selection failure
+        result = this.select( "simple", "unknownValue", parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+    }
+
+    /**
+     * A simple parameter select test
+     */
+    public void testParameterSelectUndefined() throws Exception {
+        final String value = "valueSelectorTestCase";
+        
+        Parameters parameters = new Parameters();
+        boolean result;
+        
+        // test selection fails
+        result = this.select( "simple", value, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+
+        parameters.setParameter( "value", "some-value" );
+        // test selection fails
+        result = this.select( "simple", value, parameters );
+        System.out.println( result );
+        assertTrue( "Test if a parameter is not selected", !result );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.xtest
new file mode 100644
index 0000000..17052cd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/selection/SimpleSelectorTestCase.xtest
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.cocoon.selection.SelectorSelector"
+        shorthand="selectors"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+ </roles>
+
+ <components>
+  <selectors logger="test">
+   <component-instance class="org.apache.cocoon.selection.SimpleSelector" 
+                       name="simple">
+    </component-instance>
+  </selectors>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.java
new file mode 100644
index 0000000..a5b4a34
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.serialization;
+
+import org.apache.cocoon.test.SitemapTestCase;
+
+public class VirtualPipelineSerializerTestCase extends SitemapTestCase {
+    public void testSerializer() throws Exception {
+        pipeTest("v1", "vpc-test.xml");
+    }
+
+    public void testInclude() throws Exception {
+        pipeTest("v2", "vpc-v2-expected.xml");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.xconf
new file mode 100644
index 0000000..8ff9f87
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/VirtualPipelineSerializerTestCase.xconf
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<cocoon version="2.2">
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <xslt-processor>
+     <parameter name="use-store" value="false"/>
+     <parameter name="incremental-processing" value="false"/>
+  </xslt-processor>
+
+  <component role="org.apache.excalibur.xml.xslt.XSLTProcessor/xalan"
+             class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl">
+     <parameter name="use-store" value="false"/>
+     <parameter name="incremental-processing" value="false"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.processor.TransformerFactoryImpl"/>
+  </component>
+
+  <input-modules>
+    <component-instance class="org.apache.cocoon.components.modules.input.EnvironmentAttributeModule" name="environment-attr"/>
+  </input-modules>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ModuleSourceFactory" name="module"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.XModuleSourceFactory" name="xmodule"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <!-- Relative sitemap path works during sitemap execution but
+       give exceptions during decommissioning -->
+  <sitemap file="resource://org/apache/cocoon/serialization/vpc-sitemap.xmap"/>
+
+</cocoon>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-include.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-include.xsl
new file mode 100644
index 0000000..a80ce3f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-include.xsl
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:param name="file"/>
+
+  <xsl:template match="/test">
+    <test-out file="{$file}">
+      <xsl:copy-of select="document($file)"/>
+    </test-out>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-sitemap.xmap
new file mode 100644
index 0000000..464ab88
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-sitemap.xmap
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer">
+        <xslt-processor-role>xalan</xslt-processor-role>
+      </map:transformer>
+    </map:transformers>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+      <map:serializer name="virtual1" src="org.apache.cocoon.serialization.VirtualPipelineSerializer">
+        <map:serialize type="xml"/>
+      </map:serializer>
+      <map:serializer name="virtual2" src="org.apache.cocoon.serialization.VirtualPipelineSerializer">
+        <map:transform src="vpc-include.xsl">
+           <map:parameter name="file" value="{src}"/>
+        </map:transform>
+        <map:serialize type="xml"/>
+      </map:serializer>
+    </map:serializers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="v1">
+        <map:generate src="vpc-test.xml"/>
+        <map:serialize type="virtual1"/>
+      </map:match>
+
+      <map:match pattern="v2">
+        <map:generate src="vpc-test.xml"/>
+        <map:serialize type="virtual2" src="vpc-test2.xml"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test2.xml
new file mode 100644
index 0000000..6b9d128
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-test2.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test2/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-v2-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-v2-expected.xml
new file mode 100644
index 0000000..ac14301
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/serialization/vpc-v2-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test-out file="module:environment-attr:env-prefix-serializer-source-map-virtual2#src"><test2/></test-out>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/ServletTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/ServletTestCase.java
new file mode 100644
index 0000000..6bd1a5a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/ServletTestCase.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Vector;
+
+
+import junit.framework.TestCase;
+
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.Cocoon;
+
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.WebRequest;
+import com.meterware.httpunit.WebResponse;
+import com.meterware.servletunit.ServletRunner;
+import com.meterware.servletunit.ServletUnitClient;
+
+public class ServletTestCase extends TestCase {
+
+	private ServletRunner servletRunner;
+    protected ServletUnitClient client;
+
+    private Logger logger;
+    private URL classDirURL;
+    
+    protected String processorClassName = Cocoon.class.getName();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_DEBUG);
+        this.logger = new ConsoleLogger(Integer.parseInt(level));
+
+        this.classDirURL = this.getClassDirURL();
+        URL webInf = new URL(classDirURL, "WEB-INF/web.xml");
+        File webInfFile = new File(webInf.getPath());
+        this.servletRunner = new ServletRunner(webInfFile, "");
+        this.client = this.servletRunner.newClient();
+    }
+
+    protected void tearDown() throws Exception {
+    	this.servletRunner.shutDown();
+        super.tearDown();
+    }
+
+    /** Return the logger */
+    protected Logger getLogger() {
+        return this.logger;
+    }
+    
+    /**
+     * Utility method for geting the URL to the directory that this class is in
+     */
+    protected URL getClassDirURL() throws RuntimeException {
+        String className = getClass().getName().replace( '.', '/' ) + ".class";
+        String classURL = null;
+        String classDir = null;
+        try {
+            classURL =
+                getClass().getClassLoader().getResource(className).toExternalForm();
+            getLogger().debug("classURL=" + classURL);
+            classDir = classURL.substring(0, classURL.lastIndexOf('/') + 1);
+            getLogger().debug("classDir=" + classDir);
+            return new URL(classDir);
+        } catch (SecurityException e) {
+            throw new RuntimeException("Not allowed to access classloader for " + className, e);
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Malformed URL for className=" + className +
+                                       " classURL=" + classURL + " classDir=" + classDir, e);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't create URL for " + className, e);
+        }
+    }
+
+    /**
+     * Load a binary document.
+     *
+     * @param input Stream containing the document.
+     *
+     * @return Binary data.
+     */
+    public final byte[] loadByteArray(InputStream input) {
+
+        byte[] assertiondocument = null;
+
+        try {
+            Vector document = new Vector();
+            int i = 0;
+            int c;
+
+            while ((c = input.read())!=-1) {
+                document.add(new Byte((byte) c)); 
+                i++;
+            }
+            assertiondocument = new byte[document.size()];
+            for (i = 0; i < document.size(); i++) {
+                assertiondocument[i] = ((Byte)document.get(i)).byteValue();
+            }
+
+        } catch (Exception e) {
+            getLogger().error("Could not execute test", e);
+            fail("Could not execute test: "+e);
+        }
+
+        return assertiondocument;
+    }
+
+    /**
+     * Assert that the result of a byte comparison is identical.
+     *
+     * @param expected The expected byte array
+     * @param actual The actual byte array
+     */
+    public final void assertIdentical(byte[] expected, byte[] actual) {
+        assertEquals("Byte arrays of differing sizes, ", expected.length,
+                     actual.length);
+
+        if (expected.length>0) {
+            for (int i = 0; i<expected.length; i++) {
+                assertEquals("Byte array differs at index "+i, expected[i],
+                             actual[i]);
+            }
+        }
+
+    }
+
+    protected InputStream process(String uri) throws Exception {
+    	String dummySite = "http://www.test.org";
+    	WebRequest request = new GetMethodWebRequest(dummySite + uri);
+    	/*
+    	InvocationContext ic = this.client.newInvocation(request);
+    	ic.getServlet();
+    	ic.service();
+    	WebResponse response = ic.getServletResponse();
+    	*/
+    	WebResponse response = this.client.getResponse(request);
+    	getLogger().info("Content type: " + response.getContentType());
+    	getLogger().info("Content length: " + response.getContentLength());
+    	getLogger().info("Output: " + response.getText());
+
+        return response.getInputStream();
+    }
+
+    protected void pipeTest(String uri, String expectedSource) throws Exception {
+        byte[] expected = loadByteArray((new URL(classDirURL, expectedSource)).openStream());
+        byte[] actual = loadByteArray(process(uri));
+        assertIdentical(expected, actual);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/SitemapTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/SitemapTestCase.java
new file mode 100644
index 0000000..aa9fdb0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/SitemapTestCase.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.Cocoon;
+import org.apache.cocoon.Processor;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreUtil;
+import org.apache.cocoon.test.core.TestBootstrapEnvironment;
+import org.apache.cocoon.test.core.TestCoreUtil;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.mock.MockContext;
+import org.apache.cocoon.environment.mock.MockEnvironment;
+import org.apache.cocoon.environment.mock.MockRequest;
+import org.apache.cocoon.environment.mock.MockResponse;
+
+public class SitemapTestCase extends TestCase {
+
+    private MockRequest request = new MockRequest();
+    private MockResponse response = new MockResponse();
+    private MockContext environmentContext = new MockContext();
+    private Map objectmodel = new HashMap();
+
+    private Logger logger;
+    private CoreUtil coreUtil;
+    private Processor processor;
+    private String classDir;
+    
+    protected String processorClassName = Cocoon.class.getName();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_DEBUG);
+        this.logger = new ConsoleLogger(Integer.parseInt(level));
+
+        objectmodel.clear();
+
+        request.reset();
+        objectmodel.put(ObjectModelHelper.REQUEST_OBJECT, request);
+
+        response.reset();
+        objectmodel.put(ObjectModelHelper.RESPONSE_OBJECT, response);
+
+        environmentContext.reset();
+        objectmodel.put(ObjectModelHelper.CONTEXT_OBJECT, environmentContext);
+
+        this.classDir = this.getClassDirURL().toExternalForm();
+        BootstrapEnvironment env = 
+            new TestBootstrapEnvironment(this.getConfiguration(),
+                                         this.classDir,
+                                         environmentContext,
+                                         this.logger,
+                                         this.processorClassName);
+
+        this.coreUtil = new TestCoreUtil(env);
+        this.processor = this.coreUtil.createProcessor();
+    }
+
+    protected void tearDown() throws Exception {
+        this.coreUtil.destroy();
+        super.tearDown();
+    }
+
+    /** Return the logger */
+    protected Logger getLogger() {
+        return this.logger;
+    }
+    
+    protected final Object lookup( final String key ) throws ServiceException {
+        if (this.processor instanceof Cocoon) {
+            return ((Cocoon)this.processor).getServiceManager().lookup( key );
+        } else {
+            throw new ServiceException(key, "The processor have no service manager");
+        }
+    }
+
+    protected final void release( final Object object ) {
+        if (this.processor instanceof Cocoon) {
+            ((Cocoon)this.processor).getServiceManager().release( object );
+        }
+    }
+    
+    protected String getConfiguration() {
+        String className = this.getClass().getName();
+        return className.substring(className.lastIndexOf('.') + 1) + ".xconf";
+    }
+    
+    /**
+     * Utility method for geting the URL to the directory that this class is in
+     */
+    protected URL getClassDirURL() throws RuntimeException {
+        String className = getClass().getName().replace( '.', '/' ) + ".class";
+        String classURL = null;
+        String classDir = null;
+        try {
+            classURL =
+                getClass().getClassLoader().getResource( className ).toExternalForm();
+            getLogger().debug("classURL=" + classURL);
+            classDir = classURL.substring(0, classURL.lastIndexOf('/') + 1);
+            getLogger().debug("classDir=" + classDir);
+            return new URL(classDir);
+        } catch (SecurityException e) {
+            throw new RuntimeException("Not allowed to access classloader for " + className, e);
+        } catch (MalformedURLException e) {
+            throw new RuntimeException("Malformed URL for className=" + className +
+                                       " classURL=" + classURL + " classDir=" + classDir, e);
+        } catch (Exception e) {
+            throw new RuntimeException("Couldn't create URL for " + className, e);
+        }
+    }
+
+    /**
+     * Load a binary document.
+     *
+     * @param source Source location.
+     *
+     * @return Binary data.
+     */
+    public final byte[] loadByteArray(String source) {
+
+        byte[] assertiondocument = null;
+
+        try {
+            URL url = new URL(source);
+            InputStream input = url.openStream();
+
+            Vector document = new Vector();
+            int i = 0;
+            int c;
+
+            while ((c = input.read())!=-1) {
+                document.add(new Byte((byte) c)); 
+                i++;
+            }
+            assertiondocument = new byte[document.size()];
+            for (i = 0; i < document.size(); i++) {
+                assertiondocument[i] = ((Byte)document.get(i)).byteValue();
+            }
+
+        } catch (Exception e) {
+            getLogger().error("Could not execute test", e);
+            fail("Could not execute test: "+e);
+        }
+
+        return assertiondocument;
+    }
+
+    /**
+     * Assert that the result of a byte comparison is identical.
+     *
+     * @param expected The expected byte array
+     * @param actual The actual byte array
+     */
+    public final void assertIdentical(byte[] expected, byte[] actual) {
+        assertEquals("Byte arrays of differing sizes, ", expected.length,
+                     actual.length);
+
+        if (expected.length>0) {
+            for (int i = 0; i<expected.length; i++) {
+                assertEquals("Byte array differs at index "+i, expected[i],
+                             actual[i]);
+            }
+        }
+
+    }
+
+    protected MockEnvironment getEnvironment(String uri) {
+        MockEnvironment env = new MockEnvironment();
+        env.setURI("", uri);
+        this.request.setEnvironment(env);
+        env.setObjectModel(this.objectmodel);
+
+        return env;
+    }
+
+    protected byte[] process(String uri) throws Exception {
+        MockEnvironment env = getEnvironment(uri);
+        this.processor.process(env);
+        getLogger().info("Output: " + new String(env.getOutput(), "UTF-8"));
+
+        return env.getOutput();
+    }
+
+    protected void pipeTest(String uri, String expectedSource) throws Exception {
+        byte[] expected = loadByteArray(this.classDir + expectedSource);
+        byte[] actual = process(uri);
+        assertIdentical(expected, actual);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.java
new file mode 100644
index 0000000..adc1d28
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test.blocks;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.test.SitemapTestCase;
+import org.apache.cocoon.blocks.BlockManager;
+import org.apache.cocoon.environment.mock.MockEnvironment;
+
+public class BlockManagerTestCase extends SitemapTestCase {
+    public void testCreate() throws ServiceException {
+        BlockManager block = (BlockManager)this.lookup(BlockManager.ROLE);
+        this.release(block);
+    }
+
+    public void testPipeline() throws Exception {
+        BlockManager block = (BlockManager)this.lookup(BlockManager.ROLE);
+        MockEnvironment env = getEnvironment("test");
+        block.process(env);
+        getLogger().info("Output: " + new String(env.getOutput(), "UTF-8"));
+        this.release(block);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.xconf
new file mode 100644
index 0000000..e810a8f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlockManagerTestCase.xconf
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<cocoon version="2.2">
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <source-resolver/>
+
+  <fam/>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <component role="org.apache.cocoon.blocks.BlockManager"
+             class="org.apache.cocoon.blocks.BlockManager"
+             id="test1id" location="test1/">
+    <mount path="/test1/"/>
+    <connections>
+      <connection name="test2" block="test2id"/>
+    </connections>
+    <properties>
+      <property name="foo" value="bar"/>
+    </properties>
+  </component>
+
+</cocoon>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java
new file mode 100644
index 0000000..593fc96
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/BlocksManagerTestCase.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test.blocks;
+
+import org.apache.cocoon.test.ServletTestCase;
+
+public class BlocksManagerTestCase extends ServletTestCase {
+    
+    public void testBlockSource1() throws Exception {
+        pipeTest("/test1/test", "test1/test.xml");
+    }
+
+    public void testBlockSource2() throws Exception {
+        pipeTest("/test1/test2", "test2/test.xml");
+    }
+
+    public void testBlockSource3() throws Exception {
+        pipeTest("/test1/test3", "test1/test.xml");
+    }
+    /*
+    public void testBlockSource4() throws Exception {
+        pipeTest("/test1/test4", "test1/COB-INF/classes/test.xml");
+    }
+    */
+    public void testBlockSourceSub1() throws Exception {
+        pipeTest("/test1/sub/test", "test1/sub/test.xml");
+    }
+
+    public void testBlockSourceSub2() throws Exception {
+        pipeTest("/test1/sub/test2", "test1/sub/test.xml");
+    }
+
+    public void testBlockSourceSub3() throws Exception {
+        pipeTest("/test1/sub/test3", "test1/test.xml");
+    }
+
+    public void testBlockExtend1() throws Exception {
+        pipeTest("/test3/test", "test3/test.xml");
+    }
+
+    public void testBlockExtend2() throws Exception {
+        pipeTest("/test3/test2", "test2/test.xml");
+    }
+
+    public void testBlockExtend3() throws Exception {
+        pipeTest("/test3/test3", "test3/test.xml");
+    }
+
+    public void testBlockExtend4() throws Exception {
+        pipeTest("/test3/test4", "test1/test.xml");
+    }
+
+    public void testBlockProperty() throws Exception {
+        pipeTest("/test3/prop", "test3/prop-expected.xml");
+    }
+
+    public void testAbsolutize() throws Exception {
+        pipeTest("/test1/sub/abs", "test1/sub/path-expected.xml");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml
new file mode 100644
index 0000000..6ab7b70
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/WEB-INF/web.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | This is the BlocksManagerTestCase web-app configurations file
+    +-->
+
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+  <!-- Servlet Configuration ========================================== -->
+
+  <servlet>
+    <servlet-name>BlocksManager</servlet-name>
+    <display-name>BlocksManager</display-name>
+    <description>BlocksManager</description>
+
+    <servlet-class>org.apache.cocoon.blocks.BlocksManager</servlet-class>
+
+    <init-param>
+      <param-name>work-directory</param-name>
+      <param-value>work</param-value>
+    </init-param>
+
+    <init-param>
+      <param-name>configurations</param-name>
+      <param-value>wiring.xml</param-value>
+    </init-param>
+
+    <!--
+      Set encoding used by the container. If not set the ISO-8859-1 encoding
+      will be assumed.
+      Since the servlet specification requires that the ISO-8859-1 encoding
+      is used (by default), you should never change this value unless
+      you have a buggy servlet container.
+    -->
+    <init-param>
+      <param-name>container-encoding</param-name>
+      <param-value>ISO-8859-1</param-value>
+    </init-param>
+
+  </servlet>
+
+  <!-- URL space mappings ============================================= -->
+
+  <servlet-mapping>
+    <servlet-name>BlocksManager</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+
+</web-app>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/core/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/core/COB-INF/block.xml
new file mode 100644
index 0000000..4896779
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/core/COB-INF/block.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/core/1.0">
+  <name>core</name>
+  <description href="http://cocoon.apache.org/blocks/core/1.0">
+    Cocoon core functionality
+  </description>
+  <state href="http://cocoon.apache.org/blocks/anyblock/1.0/state.html" 
+         community="committed" 
+         interfaces="unstable" 
+         implementation="stable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <components core="true">
+    <include src="resource://org/apache/cocoon/blocks/core-components.xconf"/>
+  </components>
+</block>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/block.xml
new file mode 100644
index 0000000..63217b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/block.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/anyblock/1.0">
+  <name>anyblock</name>
+  <description href="http://cocoon.apache.org/blocks/anyblock/1.0">
+    A test block
+  </description>
+  <state href="http://cocoon.apache.org/blocks/anyblock/1.0/state.html" 
+         community="committed" 
+         interfaces="unstable" 
+         implementation="stable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <components>
+    <include src="COB-INF/xconf/test1.xconf"/>
+  </components>
+  <sitemap src="block-sitemap.xmap"/>
+  <properties>
+    <property name="foo">
+      <default>baz</default>
+      <description>A test property</description>
+    </property>
+  </properties>
+  <requirements>
+    <requires interface="http://cocoon.apache.org/blocks/core/1.0"
+              name="core"
+              default="http://cocoon.apache.org/blocks/core/1.0"/>
+    <requires interface="http://cocoon.apache.org/blocks/another-interface/1.0"
+              name="test2"
+              default="http://cocoon.apache.org/blocks/another-block/1.0"/>
+  </requirements>
+</block>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/classes/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/classes/test.xml
new file mode 100644
index 0000000..8c7bfc3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/classes/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><local-classloader/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/xconf/test1.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/xconf/test1.xconf
new file mode 100644
index 0000000..476a246
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/COB-INF/xconf/test1.xconf
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id:test1.xconf 349759 2005-11-29 17:54:59 +0100 (Tue, 29 Nov 2005) danielf $ -->
+
+<map:components xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <source-factories>
+    <component-instance name="block" class="org.apache.cocoon.components.source.impl.BlockSourceFactory"/>
+  </source-factories>
+
+  <input-modules>
+    <component-instance name="block-path" class="org.apache.cocoon.components.modules.input.BlockPathModule" />
+  </input-modules>
+
+  <map:generators default="file">
+    <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+  </map:generators>
+
+  <map:transformers default="xslt">
+    <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"/>
+  </map:transformers>
+
+  <map:serializers default="xml">
+    <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer" />
+  </map:serializers>
+
+  <map:matchers default="wildcard">
+    <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+  </map:matchers>
+
+  <map:pipes default="noncaching">
+    <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline"/>
+  </map:pipes>
+</map:components>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/block-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/block-sitemap.xmap
new file mode 100644
index 0000000..0f6c703
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/block-sitemap.xmap
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id:$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <!--map:classpath>
+      <class-dir src="COB-INF/classes"/>
+    </map:classpath-->
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="test">
+        <map:generate src="test.xml"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="test2">
+        <map:generate src="block:test2:/test"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="test3">
+        <map:generate src="block:/test"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="test4">
+        <map:generate src="resource://test.xml"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="sub/**">
+        <map:mount uri-prefix="sub" src="sub/"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/block-paths.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/block-paths.xsl
new file mode 100644
index 0000000..3ee1783
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/block-paths.xsl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- $Id:$ -->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:param name="abs"/>
+  <xsl:param name="rel"/>
+  <xsl:param name="other"/>
+
+  <xsl:template match="/">
+    <properties abs="{$abs}" rel="{$rel}" other="{$other}"/>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/path-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/path-expected.xml
new file mode 100644
index 0000000..669bda4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/path-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><properties other="/test2/test" rel="/test1/sub/test" abs="/test1/test"/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/sitemap.xmap
new file mode 100644
index 0000000..92cb373
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/sitemap.xmap
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="test">
+        <map:generate src="test.xml"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="test2">
+        <map:generate src="block:./test"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="test3">
+        <map:generate src="block:/test"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="abs">
+        <map:generate src="test.xml"/>
+        <map:transform src="block-paths.xsl">
+          <map:parameter name="abs" value="{block-path:/test}"/>
+          <map:parameter name="rel" value="{block-path:./test}"/>
+          <map:parameter name="other" value="{block-path:test2:/test}"/>
+        </map:transform>
+        <map:serialize/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/test.xml
new file mode 100644
index 0000000..592f663
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/sub/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><sub/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test1/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/COB-INF/block.xml
new file mode 100644
index 0000000..355e1d7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/COB-INF/block.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/anyblock2/1.0">
+  <name>anyblock2</name>
+  <description href="http://cocoon.apache.org/blocks/anyblock2/1.0">
+    Another test block
+  </description>
+  <state href="http://cocoon.apache.org/blocks/anyblock/1.0/state.html" 
+         community="committed" 
+         interfaces="unstable" 
+         implementation="stable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <sitemap src="block-sitemap.xmap"/>
+  <requirements>
+    <requires interface="http://cocoon.apache.org/blocks/core/1.0"
+              name="core"
+              default="http://cocoon.apache.org/blocks/core/1.0"/>
+  </requirements>
+</block>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/block-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/block-sitemap.xmap
new file mode 100644
index 0000000..edfd980
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/block-sitemap.xmap
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id:$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"/>
+    </map:transformers>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="test">
+        <map:generate src="test.xml"/>
+        <map:serialize/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/test.xml
new file mode 100644
index 0000000..6b9d128
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test2/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test2/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/COB-INF/block.xml
new file mode 100644
index 0000000..24654c6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/COB-INF/block.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/extendedblock/1.0">
+  <name>extendedblock</name>
+  <description href="http://cocoon.apache.org/blocks/extendedblock/1.0">
+    An extended test block
+  </description>
+  <state href="http://cocoon.apache.org/blocks/extendedblock/1.0/state.html" 
+         community="committed" 
+         interfaces="unstable" 
+         implementation="stable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <sitemap src="block-sitemap.xmap"/>
+  <properties>
+    <property name="bar">
+      <default>gazonk</default>
+      <description>Another test property</description>
+    </property>
+    <property name="baz">
+      <description>Still another test property</description>
+    </property>
+  </properties>
+  <requirements>
+    <requires interface="http://cocoon.apache.org/blocks/core/1.0"
+              name="core"
+              default="http://cocoon.apache.org/blocks/core/1.0"/>
+  </requirements>
+  <extends block="http://cocoon.apache.org/blocks/anyblock/1.0"/>
+</block>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-properties.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-properties.xsl
new file mode 100644
index 0000000..bb19042
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-properties.xsl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- $Id:$ -->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:param name="foo"/>
+  <xsl:param name="bar"/>
+  <xsl:param name="baz"/>
+
+  <xsl:template match="/">
+    <properties foo="{$foo}" bar="{$bar}" baz="{$baz}"/>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-sitemap.xmap
new file mode 100644
index 0000000..235e00d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/block-sitemap.xmap
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id:$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <input-modules>
+      <component-instance name="block-property"  class="org.apache.cocoon.components.modules.input.BlockPropertyModule"/>
+    </input-modules>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:readers default="resource">
+      <map:reader name="resource" src="org.apache.cocoon.reading.ResourceReader"/>
+    </map:readers>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline type="noncaching">
+
+      <map:match type="wildcard" pattern="test">
+        <map:generate type="file" src="test.xml"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match type="wildcard" pattern="test4">
+        <map:generate type="file" src="block:super:/test"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match type="wildcard" pattern="prop">
+        <map:generate type="file" src="test.xml"/>
+        <map:transform type="xslt" src="block-properties.xsl">
+          <map:parameter name="foo" value="{block-property:foo}"/>
+          <map:parameter name="bar" value="{block-property:bar}"/>
+          <map:parameter name="baz" value="{block-property:baz}"/>
+        </map:transform>
+        <map:serialize/>
+      </map:match>
+
+      <map:match type="wildcard" pattern="**">
+        <map:read src="block:super:/{1}"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/prop-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/prop-expected.xml
new file mode 100644
index 0000000..7036c46
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/prop-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><properties baz="blah" bar="gazonk" foo="bar"/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/test.xml
new file mode 100644
index 0000000..f751223
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/test3/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test3/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/wiring.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/wiring.xml
new file mode 100644
index 0000000..bcf5891
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/blocks/wiring.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+
+<wiring xmlns="http://apache.org/cocoon/blocks/wiring/1.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+        xsi:schemaLocation="http://apache.org/cocoon/blocks/wiring/1.0 wiring-schema-1.0.xsd"
+>
+
+  <block id="core" location="core/"/>
+
+  <block id="test1id" location="test1/">
+    <mount path="/test1/"/>
+    <connections>
+      <connection name="core" block="core"/>
+      <connection name="test2" block="test2id"/>
+    </connections>
+    <properties>
+      <property name="foo" value="bar"/>
+    </properties>
+  </block>
+
+  <block id="test2id" location="test2/">
+    <mount path="/test2/"/>
+    <connections>
+      <connection name="core" block="core"/>
+    </connections>
+  </block>
+
+  <block id="test3id" location="test3/">
+    <mount path="/test3/"/>
+    <connections>
+      <connection name="core" block="core"/>
+      <connection name="super" block="test1id"/>
+    </connections>
+    <properties>
+      <property name="baz" value="blah"/>
+    </properties>
+  </block>
+
+</wiring>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestBootstrapEnvironment.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestBootstrapEnvironment.java
new file mode 100644
index 0000000..41d03fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestBootstrapEnvironment.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test.core;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.MutableSettings;
+import org.apache.cocoon.environment.Context;
+
+public class TestBootstrapEnvironment
+    implements BootstrapEnvironment {
+    
+    private final String configuration;
+    private final String contextPath;
+    public Logger logger;
+    private final Context environmentContext;
+    private String processorClassName;
+
+    public TestBootstrapEnvironment(String configuration,
+                                    String contextPath,
+                                    Context environmentContext,
+				                    Logger logger,
+                                    String processorClassName) {
+        this.configuration = configuration;
+        this.contextPath = contextPath;
+        this.environmentContext = environmentContext;
+        this.logger = logger;
+        this.processorClassName = processorClassName;
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BootstrapEnvironment#getBootstrapLogger(org.apache.cocoon.core.BootstrapEnvironment.LogLevel)
+     */
+    public Logger getBootstrapLogger(LogLevel logLevel) {
+        return this.logger;
+    }
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     */
+    public void log(String message) {
+        this.logger.info(message);
+    }
+
+    /** Log a message during bootstrapping. This is used to log
+     * information before the logging system is setup.
+     * @param message A message.
+     * @param error   An error.
+     */
+    public void log(String message, Throwable error) {
+        this.logger.info(message, error);
+    }
+
+    /**
+     * Pass the root logger back to the environment. As soon as the
+     * logging system is set up, this method is called.
+     * @param rootLogger The root logger.
+     */
+    public void setLogger(Logger rootLogger) {
+        this.logger = rootLogger;
+    }
+
+    /**
+     * @see org.apache.cocoon.core.BootstrapEnvironment#configure(org.apache.cocoon.core.MutableSettings)
+     */
+    public void configure(MutableSettings settings) {
+        settings.setConfiguration(this.configuration);
+        settings.setWorkDirectory("work");
+        settings.setProcessorClassName(this.processorClassName);
+    }
+
+    public void configureLoggingContext(DefaultContext context) {
+        // simply do nothing
+    }
+
+    public void configure(DefaultContext context) {
+    }
+
+    public Context getEnvironmentContext() {
+        return this.environmentContext;
+    }
+    
+    /**
+     * Returns the URL to the application context.
+     */
+    public String getContextURL() {
+        return this.contextPath;
+    }
+
+    /**
+     * Returns a file to the application context.
+     * @return A file pointing to the context or null if the context is not
+     *         writeable.
+     */
+    public File getContextForWriting() {
+        return null;
+    }
+
+    /**
+     * Set the ConfigFile for the Cocoon object.
+     *
+     * @param configFileName The file location for the cocoon.xconf
+     *
+     * @throws Exception
+     */
+    public URL getConfigFile(String configFileName) throws Exception {
+        return new URL(this.contextPath + configFileName);
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestCoreUtil.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestCoreUtil.java
new file mode 100644
index 0000000..0958010
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/test/core/TestCoreUtil.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.test.core;
+
+import org.apache.avalon.excalibur.logger.LoggerManager;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.cocoon.core.BootstrapEnvironment;
+import org.apache.cocoon.core.CoreUtil;
+
+public class TestCoreUtil extends CoreUtil {
+    public TestCoreUtil(BootstrapEnvironment env) throws Exception {
+        super(env);
+        this.classloader = TestCoreUtil.class.getClassLoader();
+    }
+
+    // Simplified logging
+    protected void initLogger() {
+        this.log = ((TestBootstrapEnvironment)this.env).logger;
+        this.loggerManager = new DefaultLoggerManager(this.log);
+    }
+
+    // Simplified classloader handling
+    protected void updateEnvironment() throws Exception {}
+
+    /**
+     * We use this simple logger manager that sends all output to the console (logger)
+     */
+    protected static class DefaultLoggerManager implements LoggerManager {
+        
+        private Logger logger;
+        
+        public DefaultLoggerManager(Logger logger) {
+            this.logger = logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getDefaultLogger()
+         */
+        public Logger getDefaultLogger() {
+            return this.logger;
+        }
+        /* (non-Javadoc)
+         * @see org.apache.avalon.excalibur.logger.LoggerManager#getLoggerForCategory(java.lang.String)
+         */
+        public Logger getLoggerForCategory(String arg0) {
+            return this.logger;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
new file mode 100644
index 0000000..40e7c99
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.w3c.dom.Document;
+
+
+/**
+ * A simple testcase for AugmentTransformer.
+ *
+ * @version $Id$
+ */
+public class AugmentTransformerTestCase extends SitemapComponentTestCase {
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.SitemapComponentTestCase#getSitemapComponentInfo()
+     */
+    protected String[] getSitemapComponentInfo() {
+        return new String[] {Transformer.class.getName(),
+                             AugmentTransformer.class.getName(),
+                             "augment"};
+    }
+
+    /** Testcase for augment transformation
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testAugment1() throws Exception {
+        getLogger().debug("testAugment1");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "mount", "portal1/sect1/" );
+        
+        String input = "resource://org/apache/cocoon/transformation/augment-input-1.xml";
+        String result = "resource://org/apache/cocoon/transformation/augment-result-1.xml";
+        String src =  null;
+        
+        Document resultDocument = load(result);
+        Document inputDocument = load(input);
+        Document transformDocument = transform("augment", src, parameters, inputDocument );
+        
+        printDocs( resultDocument, inputDocument, transformDocument );
+        
+        assertIdentical( resultDocument, transformDocument );
+    }
+    
+    /**
+     * print documents to System.out
+     *
+     * @param resultDocument the expected result document
+     * @param inputDocument the input document
+     * @param transformDocument  the transformed input document
+     */
+    protected void printDocs( Document resultDocument, Document inputDocument, Document transformDocument ) {
+        System.out.println( "resultDocument" );
+        this.print( resultDocument );
+        System.out.println( "inputDocument" );
+        this.print( inputDocument );
+        System.out.println( "transformDocument" );
+        this.print( transformDocument );
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.xtest
new file mode 100644
index 0000000..813de69
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/AugmentTransformerTestCase.xtest
@@ -0,0 +1,74 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <context>
+   <entry name="root-url" value="/"/>
+ </context>
+
+ <roles>
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+        
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
new file mode 100644
index 0000000..6e8b351
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+/**
+ * A simple testcase for FilterTransformer.
+ *
+ * @version $Id$
+ */
+public class CIncludeTransformerTestCase extends SitemapComponentTestCase {
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.SitemapComponentTestCase#getSitemapComponentInfo()
+     */
+    protected String[] getSitemapComponentInfo() {
+        return new String[] {Transformer.class.getName(),
+                             CIncludeTransformer.class.getName(),
+                             "cinclude"};
+    }
+
+    /** Testcase for cinclude simple include
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testCInclude1() throws Exception {
+        getLogger().debug("testCInclude1");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "support-caching", "false" );
+        
+        String input = "resource://org/apache/cocoon/transformation/cinclude-input-1.xml";
+        String result = "resource://org/apache/cocoon/transformation/cinclude-result-1.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("cinclude", src, parameters, load(input)));
+    }
+    
+    /**
+     * Testcase for cinclude specifying element for wrapping included content
+     *
+     * @throws Exception if  enterEnvironment fails
+     */
+    public void testCInclude2() throws Exception {
+        getLogger().debug("testCInclude2");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "support-caching", "false" );
+        
+        String input = "resource://org/apache/cocoon/transformation/cinclude-input-2.xml";
+        String result = "resource://org/apache/cocoon/transformation/cinclude-result-2.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("cinclude", src, parameters, load(input)));
+    }
+    
+    /**
+     * Testcase for cinclude specifying select attribute, selection elements from the included document
+     *
+     * @throws Exception if  enterEnvironment fails
+     */
+    public void testCInclude3() throws Exception {
+        getLogger().debug("testCInclude3");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "support-caching", "false" );
+        
+        String input = "resource://org/apache/cocoon/transformation/cinclude-input-3.xml";
+        String result = "resource://org/apache/cocoon/transformation/cinclude-result-3.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("cinclude", src, parameters, load(input)));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.xtest
new file mode 100644
index 0000000..2bae366
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/CIncludeTransformerTestCase.xtest
@@ -0,0 +1,72 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <context>
+   <entry name="root-url" value="/"/>
+ </context>
+
+ <roles>
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+        
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
new file mode 100644
index 0000000..df84fdd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+import org.apache.cocoon.environment.mock.MockRequest;
+import org.apache.cocoon.environment.mock.MockResponse;
+import org.apache.cocoon.environment.mock.MockSession;
+import org.w3c.dom.Document;
+
+
+/**
+ * A simple testcase for FilterTransformer.
+ *
+ * @version $Id$
+ */
+public class EncodeURLTransformerTestCase extends SitemapComponentTestCase {
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.SitemapComponentTestCase#getSitemapComponentInfo()
+     */
+    protected String[] getSitemapComponentInfo() {
+        return new String[] {Transformer.class.getName(),
+                             EncodeURLTransformer.class.getName(),
+                             "encodeurl"};
+    }
+    
+    /** Testcase for encode url transformation
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testEncodeURL1() throws Exception {
+        getLogger().debug("testEncodeURL1");
+        
+        Parameters parameters = new Parameters();
+        
+        String input = "resource://org/apache/cocoon/transformation/encodeurl-input-1.xml";
+        String result = "resource://org/apache/cocoon/transformation/encodeurl-result-1.xml";
+        String src =  null;
+        
+        Document inputDocument = load(input);
+        Document resultDocument = load(result);
+        Document transformDocument = transform("encodeurl", src, parameters, inputDocument);
+        
+        printDocs( resultDocument, inputDocument, transformDocument );
+        
+        assertIdentical( resultDocument, transformDocument );
+    }
+    
+    /** Testcase for encode url transformation
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testEncodeURL2() throws Exception {
+        getLogger().debug("testEncodeURL2");
+        
+        Parameters parameters = new Parameters();
+        
+        String input = "resource://org/apache/cocoon/transformation/encodeurl-input-2.xml";
+        String result = "resource://org/apache/cocoon/transformation/encodeurl-result-2.xml";
+        String src =  null;
+        
+        // force that sessionId is added to an URL
+        MockRequest request = getRequest();
+        MockSession session = (MockSession)request.getSession();
+        MockResponse response = getResponse();
+        
+        response.setSession(session);
+        getRequest().setIsRequestedSessionIdFromURL( true );
+
+        session.setIsNew(true);
+        
+        Document inputDocument = load(input);
+        Document resultDocument = load(result);
+        Document transformDocument = transform("encodeurl", src, parameters, inputDocument);
+        
+        printDocs( resultDocument, inputDocument, transformDocument );
+        assertIdentical( resultDocument, transformDocument );
+    }
+    
+    /**
+     * print documents to System.out
+     *
+     * @param resultDocument the expected result document
+     * @param inputDocument the input document
+     * @param transformDocument  the transformed input document
+     */
+    protected void printDocs( Document resultDocument, Document inputDocument, Document transformDocument ) {
+        System.out.println( "resultDocument" );
+        this.print( resultDocument );
+        System.out.println( "inputDocument" );
+        this.print( inputDocument );
+        System.out.println( "transformDocument" );
+        this.print( transformDocument );
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.xtest
new file mode 100644
index 0000000..5e84646
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/EncodeURLTransformerTestCase.xtest
@@ -0,0 +1,73 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <context>
+   <entry name="root-url" value="/"/>
+ </context>
+
+ <roles>
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+        
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.java
new file mode 100644
index 0000000..f563126
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+/**
+ * A simple testcase for FilterTransformer.
+ *
+ * @version $Id$
+ */
+public class FilterTransformerTestCase extends SitemapComponentTestCase {
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.SitemapComponentTestCase#getSitemapComponentInfo()
+     */
+    protected String[] getSitemapComponentInfo() {
+        return new String[] {Transformer.class.getName(),
+                             FilterTransformer.class.getName(),
+                             "filter"};
+    }
+
+    /**
+     * Testcase for count=1, blocknr=1
+     */
+    public void testFilter_1_1() throws Exception {
+        getLogger().debug("testFilter_1_1");
+
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "element-name", "leaf" );
+        parameters.setParameter( "count", "1" );
+        parameters.setParameter( "blocknr", "1" );
+
+        String input = "resource://org/apache/cocoon/transformation/filter-input.xml";
+        String result = "resource://org/apache/cocoon/transformation/filter-result-1-1.xml";
+        String src =  null;
+        
+        assertEqual(load(result), transform("filter", src, parameters, load(input)));
+    }
+    
+    /**
+     * Testcase for count=3, blocknr=1
+     */
+    public void testFilter_3_1() throws Exception {
+        getLogger().debug("testFilter_3_1");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "element-name", "leaf" );
+        parameters.setParameter( "count", "3" );
+        parameters.setParameter( "blocknr", "1" );
+        
+        String input = "resource://org/apache/cocoon/transformation/filter-input.xml";
+        String result = "resource://org/apache/cocoon/transformation/filter-result-3-1.xml";
+        String src =  null;
+        
+        assertEqual(load(result), transform("filter", src, parameters, load(input)));
+    }
+
+    /**
+     * Testcase for count=1, blocknr=3
+     */
+    public void testFilter_1_3() throws Exception {
+        getLogger().debug("testFilter_1_3");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "element-name", "leaf" );
+        parameters.setParameter( "count", "1" );
+        parameters.setParameter( "blocknr", "3" );
+        
+        String input = "resource://org/apache/cocoon/transformation/filter-input.xml";
+        String result = "resource://org/apache/cocoon/transformation/filter-result-1-3.xml";
+        String src =  null;
+        
+        assertEqual(load(result), transform("filter", src, parameters, load(input)));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.xtest
new file mode 100644
index 0000000..c735f66
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/FilterTransformerTestCase.xtest
@@ -0,0 +1,62 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
new file mode 100644
index 0000000..021a2c2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+/**
+ * A simple testcase for I18nTransformer.
+ *
+ * @version $Id$
+ */
+public class I18NTransformerTestCase extends SitemapComponentTestCase {
+    
+    /** Testcase for i18n
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testI18n1() throws Exception {
+        getLogger().debug("testI18n1");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "support-caching", "false" );
+        
+        String input = "resource://org/apache/cocoon/transformation/i18n-input-1.xml";
+        String result = "resource://org/apache/cocoon/transformation/i18n-result-1.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("i18n", src, parameters, load(input)));
+    }
+    
+    /** Testcase for i18n
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testI18n2() throws Exception {
+        getLogger().debug("testI18n2");
+        
+        Parameters parameters = new Parameters();
+        parameters.setParameter( "support-caching", "false" );
+        
+        String input = "resource://org/apache/cocoon/transformation/i18n-input-2.xml";
+        String result = "resource://org/apache/cocoon/transformation/i18n-result-2.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("i18n", src, parameters, load(input)));
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.xtest
new file mode 100644
index 0000000..542de6e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/I18NTransformerTestCase.xtest
@@ -0,0 +1,99 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <context>
+   <entry name="root-url" value="/"/>
+ </context>
+
+ <roles>
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+        
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <role name="org.apache.cocoon.transformation.TransformerSelector"
+        shorthand="transformers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <!-- i18n components for resource bundle handling -->
+  <role name="org.apache.cocoon.i18n.BundleFactory"
+        shorthand="i18n-bundles"
+        default-class="org.apache.cocoon.i18n.XMLResourceBundleFactory"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+  
+  <i18n-bundles logger="core.i18n-bundles">
+    <catalogue-name>messages</catalogue-name>
+    <catalogue-location>resource://org/apache/cocoon/transformation</catalogue-location>
+    <cache-at-startup>true</cache-at-startup>
+  </i18n-bundles>
+
+  <transformers logger="test">
+   <component-instance class="org.apache.cocoon.transformation.I18nTransformer" 
+                       name="i18n">
+    <catalogues default="messages">
+      <catalogue id="messages" name="i18n-messages" location="resource://org/apache/cocoon/transformation"/>
+      <catalogue id="menu" name="i18n-menu" location="resource://org/apache/cocoon/transformation"/>
+    </catalogues>
+    <cache-at-startup>true</cache-at-startup>
+   </component-instance>
+
+  </transformers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.java
new file mode 100644
index 0000000..b8a1d6f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+import org.w3c.dom.Document;
+
+/**
+ *
+ *
+ * @version $Id$
+ */
+public class TraxTransformerTestCase extends SitemapComponentTestCase {
+
+    public void testFunctionForXalan() throws Exception {
+
+        String src = "resource://org/apache/cocoon/transformation/traxtest-style.xsl";
+        Parameters parameters = new Parameters();
+        String input = "resource://org/apache/cocoon/transformation/traxtest-input.xml";
+        String result = "resource://org/apache/cocoon/transformation/traxtest-result.xml";
+
+        assertEqual(load(result), transform("xalan", src, parameters, load(input)));
+    }
+
+    public void testStressForXalan() throws Exception {
+
+        String src = "resource://org/apache/cocoon/transformation/traxtest-style.xsl";
+        Parameters parameters = new Parameters();
+        String input = "resource://org/apache/cocoon/transformation/traxtest-input.xml";
+        Document document = load(input);
+
+        for(int i=0; i<100; i++)
+          transform("xalan", src, parameters, document);
+    }
+
+    /*
+     FIXME: test doesn't run within a gump build, see
+            http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105082989401703&w=2
+
+    public void testFunctionForXSLTC() throws Exception {
+
+        String src = "resource://org/apache/cocoon/transformation/traxtest-style.xsl";
+        Parameters parameters = new Parameters();
+        String input = "resource://org/apache/cocoon/transformation/traxtest-input.xml";
+        String result = "resource://org/apache/cocoon/transformation/traxtest-result.xml";
+
+        assertEqual(load(result), transform("xsltc", src, parameters, load(input)));
+    }
+
+    public void testStressForXSLTC() throws Exception {
+
+        String src = "resource://org/apache/cocoon/transformation/traxtest-style.xsl";
+        Parameters parameters = new Parameters();
+        String input = "resource://org/apache/cocoon/transformation/traxtest-input.xml";
+        Document document = load(input);
+
+        for(int i=0; i<100; i++)
+          transform("xsltc", src, parameters, document);
+    }*/
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.xtest
new file mode 100644
index 0000000..bc8b72c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/TraxTransformerTestCase.xtest
@@ -0,0 +1,99 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <roles>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+
+  <role name="org.apache.cocoon.transformation.TransformerSelector"
+        shorthand="transformers"
+        default-class="org.apache.cocoon.core.container.StandaloneServiceSelector"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+
+  <component-instance logger="core.xslt-processor"
+                      role="org.apache.excalibur.xml.xslt.XSLTProcessor/xsltc"
+                      class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl">
+     <parameter name="use-store" value="true"/>
+     <parameter name="incremental-processing" value="true"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.xsltc.trax.TransformerFactoryImpl"/>
+  </component-instance>
+
+  <component-instance logger="core.xslt-processor"
+                      role="org.apache.excalibur.xml.xslt.XSLTProcessor/xalan"
+                      class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl">
+     <parameter name="use-store" value="true"/>
+     <parameter name="incremental-processing" value="true"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.processor.TransformerFactoryImpl"/>
+  </component-instance>
+
+  <transformers logger="test">
+   <component-instance class="org.apache.cocoon.transformation.TraxTransformer" 
+                       name="xalan">
+    <use-request-parameters>false</use-request-parameters>
+    <use-session-parameters>false</use-session-parameters>
+    <use-cookie-parameters>false</use-cookie-parameters>
+    <xslt-processor-role>xalan</xslt-processor-role>
+   </component-instance>
+
+   <component-instance name="xsltc" 
+                       class="org.apache.cocoon.transformation.TraxTransformer">
+    <use-request-parameters>false</use-request-parameters>
+    <use-session-parameters>false</use-session-parameters>
+    <use-cookie-parameters>false</use-cookie-parameters>
+    <xslt-processor-role>xsltc</xslt-processor-role>
+   </component-instance>
+  </transformers>
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.java
new file mode 100644
index 0000000..4f1b48c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.cocoon.test.SitemapTestCase;
+
+public class VirtualPipelineTransformerTestCase extends SitemapTestCase {
+    public void testTransformer() throws Exception {
+        pipeTest("v1", "vpc-test.xml");
+    }
+
+    public void testInclude() throws Exception {
+        pipeTest("v2", "vpc-v2-expected.xml");
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.xconf b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.xconf
new file mode 100644
index 0000000..0d74ca0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/VirtualPipelineTransformerTestCase.xconf
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<cocoon version="2.2">
+
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <xslt-processor>
+     <parameter name="use-store" value="false"/>
+     <parameter name="incremental-processing" value="false"/>
+  </xslt-processor>
+
+  <component role="org.apache.excalibur.xml.xslt.XSLTProcessor/xalan"
+             class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl">
+     <parameter name="use-store" value="false"/>
+     <parameter name="incremental-processing" value="false"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.processor.TransformerFactoryImpl"/>
+  </component>
+
+  <input-modules>
+    <component-instance class="org.apache.cocoon.components.modules.input.EnvironmentAttributeModule" name="environment-attr"/>
+  </input-modules>
+
+  <source-factories>
+    <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ContextSourceFactory" name="context"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.ModuleSourceFactory" name="module"/>
+    <component-instance class="org.apache.cocoon.components.source.impl.XModuleSourceFactory" name="xmodule"/>
+    <component-instance class="org.apache.excalibur.source.impl.FileSourceFactory" name="file"/>
+    <component-instance class="org.apache.excalibur.source.impl.URLSourceFactory" name="*"/>
+  </source-factories>
+
+  <!-- Relative sitemap path works during sitemap execution but
+       give exceptions during decommissioning -->
+  <sitemap file="resource://org/apache/cocoon/transformation/vpc-sitemap.xmap"/>
+
+</cocoon>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XAbstractDOMTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XAbstractDOMTransformerTestCase.java
new file mode 100644
index 0000000..86bb4e2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XAbstractDOMTransformerTestCase.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+
+/**
+ * A simple testcase for AbstractDOMTransformer.
+ *
+ * @version $Id$
+ */
+public class XAbstractDOMTransformerTestCase extends TestCase {
+
+    /**
+     * Test if sending two consecutive "characters" events to the transformer
+     * doesn't lose one of them (cfr. bug #26219).
+     */
+    public void testJoiningCharacters() throws Exception {
+        /*
+         * Simple transformer that produces a document with a root with a single
+         * text node whose value is given by the concatenation of the values
+         * of the children of the root element of the original document.
+         */
+        AbstractDOMTransformer adt = new AbstractDOMTransformer() {
+            protected Document transform(Document doc) {
+                try {
+                    Document newdoc = DocumentBuilderFactory
+                            .newInstance().newDocumentBuilder().newDocument();
+                    Element root = newdoc.createElement("out");
+                    newdoc.appendChild(root);
+                    NodeList children = doc.getDocumentElement().getChildNodes();
+                    StringBuffer value = new StringBuffer();
+                    for (int i = 0 ; i < children.getLength() ; ++i) {
+                        value.append(children.item(i).getNodeValue());
+                    }
+                    root.appendChild(newdoc.createTextNode(value.toString()));
+                    return newdoc;
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return null;
+                }
+            }
+        };
+        DOMBuilder builder = new DOMBuilder();
+        adt.setConsumer(builder);
+        Attributes attrs = new AttributesImpl();
+        char c1[] = "ABC".toCharArray();
+        char c2[] = "DEF".toCharArray();
+        adt.startDocument();
+        adt.startElement("", "in", "in", attrs);
+        adt.characters(c1, 0, 3);
+        adt.characters(c2, 0, 3);
+        adt.endElement("", "in", "in");
+        adt.endDocument();
+        assertEquals("Content of root element not what expected", "ABCDEF", 
+                builder.getDocument().getDocumentElement().getFirstChild().getNodeValue());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
new file mode 100644
index 0000000..7be4a24
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.transformation;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.SitemapComponentTestCase;
+
+/**
+ * A simple testcase for FilterTransformer.
+ *
+ * @version $Id$
+ */
+public class XIncludeTransformerTestCase extends SitemapComponentTestCase {
+    
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.SitemapComponentTestCase#getSitemapComponentInfo()
+     */
+    protected String[] getSitemapComponentInfo() {
+        return new String[] {Transformer.class.getName(),
+                             XIncludeTransformer.class.getName(),
+                             "xinclude"};
+    }
+    
+    /** Testcase for xinclude simple include
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testXInclude1() throws Exception {
+        getLogger().debug("testXInclude1");
+        
+        Parameters parameters = new Parameters();
+        
+        String input = "resource://org/apache/cocoon/transformation/xinclude-input-1.xml";
+        String result = "resource://org/apache/cocoon/transformation/xinclude-result-1.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("xinclude", src, parameters, load(input)));
+    }
+
+    /** Testcase for xinclude simple text include
+     *
+     * @throws Exception if ServiceManager enterEnvironment fails
+     */
+    public void testXInclude2() throws Exception {
+        getLogger().debug("testXInclude2");
+        
+        Parameters parameters = new Parameters();
+        
+        String input = "resource://org/apache/cocoon/transformation/xinclude-input-2.xml";
+        String result = "resource://org/apache/cocoon/transformation/xinclude-result-2.xml";
+        String src =  null;
+        
+        assertEqual( load(result),
+        transform("xinclude", src, parameters, load(input)));
+    }
+    
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.xtest b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.xtest
new file mode 100644
index 0000000..5e84646
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/XIncludeTransformerTestCase.xtest
@@ -0,0 +1,73 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<testcase>
+ <context>
+   <entry name="root-url" value="/"/>
+ </context>
+
+ <roles>
+  <role name="org.apache.excalibur.xml.dom.DOMParser"
+        shorthand="dom-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+  <role name="org.apache.excalibur.xml.sax.SAXParser"
+        shorthand="xml-parser"
+        default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
+
+  <role name="org.apache.excalibur.xmlizer.XMLizer"
+        shorthand="xmlizer"
+        default-class="org.apache.excalibur.xmlizer.DefaultXMLizer"/>
+
+  <role name="org.apache.excalibur.xml.xslt.XSLTProcessor"
+        shorthand="xslt-processor"
+        default-class="org.apache.excalibur.xml.xslt.XSLTProcessorImpl"/>
+        
+  <role name="org.apache.excalibur.xml.xpath.XPathProcessor"
+        shorthand="xpath-processor"
+        default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
+
+  <role name="org.apache.excalibur.store.Store/TransientStore"
+        shorthand="transient-store"
+        default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+
+  <role name="org.apache.excalibur.store.Store"
+       shorthand="persistent-store"
+       default-class="org.apache.excalibur.store.impl.MemoryStore"/>
+ </roles>
+
+ <components>
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser">
+   <parameter name="validate" value="false"/>
+   <parameter name="namespace-prefixes" value="false"/>
+   <parameter name="stop-on-warning" value="true"/>
+   <parameter name="stop-on-recoverable-error" value="true"/>
+   <parameter name="reuse-parsers" value="false"/>
+  </xml-parser>
+
+  <xmlizer/>
+
+  <transient-store/>
+
+  <persistent-store/>
+
+  <xslt-processor logger="core.xslt-processor">
+   <parameter name="use-store" value="true"/>
+   <parameter name="incremental-processing" value="true"/>
+  </xslt-processor>
+
+ </components>
+
+</testcase>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-input-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-input-1.xml
new file mode 100644
index 0000000..6ad07a6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-input-1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="x">x</a>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-result-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-result-1.xml
new file mode 100644
index 0000000..27f0bcb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/augment-result-1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="http://nullnull/portal1/sect1/x">x</a>
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-incl.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-incl.xml
new file mode 100644
index 0000000..b6bdcd0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-incl.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root-include>
+  <p>include 1</p>
+  <p>include 2</p>
+  <p>include 3</p>
+  <p>include 4</p>
+</root-include>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-1.xml
new file mode 100644
index 0000000..952fd39
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-1.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:ci="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<ci:include src="resource://org/apache/cocoon/transformation/cinclude-incl.xml"
+/>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-2.xml
new file mode 100644
index 0000000..7a985e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:ci="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<ci:include src="resource://org/apache/cocoon/transformation/cinclude-incl.xml"
+element="inc-root"
+/>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-3.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-3.xml
new file mode 100644
index 0000000..badcb55
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-input-3.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:ci="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<ci:include src="resource://org/apache/cocoon/transformation/cinclude-incl.xml"
+element="inc-root"
+select="root-include/p[3]"
+/>
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-1.xml
new file mode 100644
index 0000000..8d12863
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-1.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:ci="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<root-include>
+  <p>include 1</p>
+  <p>include 2</p>
+  <p>include 3</p>
+  <p>include 4</p>
+</root-include>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-2.xml
new file mode 100644
index 0000000..706198a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-2.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:inc="incl-ns"
+>
+  <p>P1</p>
+  <p>P2</p>
+
+<inc-root>
+<root-include>
+  <p>include 1</p>
+  <p>include 2</p>
+  <p>include 3</p>
+  <p>include 4</p>
+</root-include>
+</inc-root>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-3.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-3.xml
new file mode 100644
index 0000000..2f7c1e4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/cinclude-result-3.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:inc="incl-ns"
+>
+  <p>P1</p>
+  <p>P2</p>
+
+<inc-root>
+  <p>include 3</p>
+</inc-root>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-1.xml
new file mode 100644
index 0000000..6ad07a6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="x">x</a>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-2.xml
new file mode 100644
index 0000000..4f05798
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-input-2.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="x">x</a>
+  <img src="img/src must not be encoded"/>
+  <a href="href must be encoded"/>
+  <form action="action must be encoded"/>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-1.xml
new file mode 100644
index 0000000..2442123
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="x">x</a>
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-2.xml
new file mode 100644
index 0000000..40e7fbf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/encodeurl-result-2.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+
+<root>
+  <x>X</x>
+  <a>A</a>
+  <a b="c">d</a>
+  <a href="x?JSESSIONID=MockSession">x</a>
+  <img src="img/src must not be encoded"/>
+  <a href="href must be encoded?JSESSIONID=MockSession"/>
+  <form action="action must be encoded?JSESSIONID=MockSession"/>
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-input.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-input.xml
new file mode 100644
index 0000000..e66ffda
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-input.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<root>
+  <leaf>1 Hi</leaf>
+  <leaf>2 Hello</leaf>
+  <leaf>3 Goodbye</leaf>
+  <leaf>4 So long</leaf>
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-1.xml
new file mode 100644
index 0000000..44d7484
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-1.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<root>
+	<block id="1">
+     <leaf>1 Hi</leaf>
+   </block>
+   <block id="2"/>
+   <block id="3"/>
+   <block id="4"/>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-3.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-3.xml
new file mode 100644
index 0000000..00fa246
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-1-3.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<root>
+	<block id="1"/>
+   <block id="2"/>
+   <block id="3">
+     <leaf>3 Goodbye</leaf>
+   </block>
+   <block id="4"/>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-3-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-3-1.xml
new file mode 100644
index 0000000..fd393e6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/filter-result-3-1.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<root>
+	<block id="1">
+     <leaf>1 Hi</leaf>
+     <leaf>2 Hello</leaf>
+     <leaf>3 Goodbye</leaf>
+   </block>
+   <block id="2"/>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-1.xml
new file mode 100644
index 0000000..d82f1b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-1.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+    xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+>
+  <title><i18n:text>titletext</i18n:text></title>
+
+  <p>
+    <i18n:text key="a_key">article_text1</i18n:text>
+  </p>
+  <p>
+    <i18n:text key="a_key_which_does_not_exist">article_text2</i18n:text>
+  </p>
+
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-2.xml
new file mode 100644
index 0000000..952934f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-input-2.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+    xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+>
+  <title><i18n:text>titletext</i18n:text></title>
+
+  <p>
+    <i18n:text key="a_key">article_text1</i18n:text>
+  </p>
+  <p>
+    <i18n:text key="a_key_which_does_not_exist">article_text2</i18n:text>
+  </p>
+  <p>
+    <i18n:text i18n:catalogue="menu">Documentation</i18n:text>
+  </p>
+
+</root>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-menu.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-menu.xml
new file mode 100644
index 0000000..b6f9118
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-menu.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Default (English) message catalogue file for menu in Cocoon 2 i18n sample
+    |
+    | CVS $Id: i18n-menu.xml,v 1.2 2004/03/06 02:25:51 antonio Exp $
+    +-->
+
+<catalogue xml:lang="en">
+    <message key="Documentation">Documentation For I18NTransformerTestCase</message>
+</catalogue>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-messages.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-messages.xml
new file mode 100644
index 0000000..0229f32
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-messages.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Default (English) message catalogue file for Cocoon 2 i18n sample
+    |
+    | CVS $Id: i18n-messages.xml,v 1.2 2004/03/06 02:25:51 antonio Exp $
+    +-->
+
+<catalogue xml:lang="en">
+    <message key="a_key">This is a key value.</message>
+    <message key="language">English</message>
+    <message key="titletext">Hello, internationalization!</message>
+</catalogue>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-1.xml
new file mode 100644
index 0000000..9e89687
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-1.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+    xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+>
+  <title>Hello, internationalization!</title>
+
+  <p>
+    This is a key value.
+  </p>
+  <p>
+    article_text2
+  </p>
+
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-2.xml
new file mode 100644
index 0000000..5214647
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/i18n-result-2.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+    xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
+>
+  <title>Hello, internationalization!</title>
+
+  <p>
+    This is a key value.
+  </p>
+  <p>
+    article_text2
+  </p>
+  <p>
+    Documentation For I18NTransformerTestCase
+  </p>
+
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-input.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-input.xml
new file mode 100644
index 0000000..f0eb796
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-input.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<hello-world>
+ <title>Title of the example</title>
+ <some-text>This is a litte test file!</some-text>
+ <some-text>And will transformed into a HTML page.</some-text>
+</hello-world>
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-result.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-result.xml
new file mode 100644
index 0000000..02cc1ae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-result.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<page>
+ <tab title="Overview" href="welcome"/>
+ <row>
+  <column title="Title of the example">
+   <p>This is a litte test file!</p>
+   <p>And will transformed into a HTML page.</p>
+  </column>
+ </row>
+</page>
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-style.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-style.xsl
new file mode 100644
index 0000000..01e9919
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/traxtest-style.xsl
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:template match="hello-world">
+  <page>
+   <tab title="Overview" href="welcome"/>
+
+   <row>
+    <column title="{title}">
+     <xsl:apply-templates select="some-text"/>
+    </column>
+   </row>
+ 
+  </page>
+ </xsl:template>
+
+ <xsl:template match="some-text">
+  <p>
+   <xsl:apply-templates/>
+  </p>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-include.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-include.xsl
new file mode 100644
index 0000000..74e2ec5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-include.xsl
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:param name="file"/>
+
+  <xsl:template match="/test">
+    <test>
+      <xsl:copy-of select="*"/>
+      <xsl:copy-of select="document($file)"/>
+    </test>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-sitemap.xmap b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-sitemap.xmap
new file mode 100644
index 0000000..b341cf3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-sitemap.xmap
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer">
+        <xslt-processor-role>xalan</xslt-processor-role>
+      </map:transformer>
+      <map:transformer name="virtual1" src="org.apache.cocoon.transformation.VirtualPipelineTransformer">
+        <map:transform src="vpc-transform.xsl"/>
+      </map:transformer>
+      <map:transformer name="virtual2" src="org.apache.cocoon.transformation.VirtualPipelineTransformer">
+        <map:source param="src2"/>
+        <map:transform src="vpc-include.xsl">
+           <map:parameter name="file" value="{src}"/>
+        </map:transform>
+        <map:transform src="vpc-include.xsl">
+           <map:parameter name="file" value="{src2}"/>
+        </map:transform>
+      </map:transformer>
+    </map:transformers>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="v1">
+        <map:generate src="vpc-test.xml"/>
+        <map:transform type="virtual1"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="v2">
+        <map:generate src="vpc-test.xml"/>
+        <map:transform type="virtual2" src="vpc-test.xml">
+          <map:parameter name="src2" value="vpc-test2.xml"/>
+        </map:transform>
+        <map:serialize/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test2.xml
new file mode 100644
index 0000000..6b9d128
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-test2.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test2/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-transform.xsl b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-transform.xsl
new file mode 100644
index 0000000..35908d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-transform.xsl
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:template match="/test">
+    <test/>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-v2-expected.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-v2-expected.xml
new file mode 100644
index 0000000..5d9f536
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/vpc-v2-expected.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test><test/><test2/></test>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.txt b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.txt
new file mode 100644
index 0000000..80f7a6c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.txt
@@ -0,0 +1 @@
+Only some text getting included.
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.xml
new file mode 100644
index 0000000..b6bdcd0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-incl.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root-include>
+  <p>include 1</p>
+  <p>include 2</p>
+  <p>include 3</p>
+  <p>include 4</p>
+</root-include>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-1.xml
new file mode 100644
index 0000000..7289b11
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-1.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>P1</p>
+  <p>P2</p>
+
+<xi:include href="resource://org/apache/cocoon/transformation/xinclude-incl.xml"
+/>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-2.xml
new file mode 100644
index 0000000..cff41fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-input-2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:xi="http://www.w3.org/2001/XInclude">
+  <p>P1</p>
+  <p>P2</p>
+<p>
+<xi:include parse="text" href="resource://org/apache/cocoon/transformation/xinclude-incl.txt"
+/>
+</p>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-1.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-1.xml
new file mode 100644
index 0000000..f579d55
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-1.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:xi="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<root-include>
+  <p>include 1</p>
+  <p>include 2</p>
+  <p>include 3</p>
+  <p>include 4</p>
+</root-include>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-2.xml b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-2.xml
new file mode 100644
index 0000000..51fb4f6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/transformation/xinclude-result-2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<root
+  xmlns:xi="http://apache.org/cocoon/include/1.0">
+  <p>P1</p>
+  <p>P2</p>
+
+<p>
+Only some text getting included.
+</p>
+
+  <p>P3</p>
+  <p>P4</p>
+</root>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/location/LocationTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/location/LocationTestCase.java
new file mode 100644
index 0000000..8a3f461
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/location/LocationTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.location;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+public class LocationTestCase extends TestCase {
+    
+    public LocationTestCase(String name) {
+        super(name);
+    }
+    
+    static final String str = "path/to/file.xml:1:40";
+
+    public void testParse() throws Exception {
+        String str = "<map:generate> - path/to/file.xml:1:40";
+        Location loc = LocationUtils.getLocation(str);
+        
+        assertEquals("<map:generate>", loc.getDescription());
+        assertEquals("URI", "path/to/file.xml", loc.getURI());
+        assertEquals("line", 1, loc.getLineNumber());
+        assertEquals("column", 40, loc.getColumnNumber());
+        assertEquals("string representation", str, loc.toString());
+    }
+    
+    public void testEquals() throws Exception {
+        Location loc1 = LocationUtils.getLocation(str);
+        Location loc2 = new LocationImpl(null, "path/to/file.xml", 1, 40);
+        
+        assertEquals("locations", loc1, loc2);
+        assertEquals("hashcode", loc1.hashCode(), loc2.hashCode());
+        assertEquals("string representation", loc1.toString(), loc2.toString());
+    }
+    
+    /**
+     * Test that Location.UNKNOWN is kept identical on deserialization
+     */
+    public void testSerializeUnknown() throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        
+        oos.writeObject(Location.UNKNOWN);
+        oos.close();
+        bos.close();
+        
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bis);
+        
+        Object obj = ois.readObject();
+        
+        assertSame("unknown location", Location.UNKNOWN, obj);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/IOUtilsTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/IOUtilsTestCase.java
new file mode 100644
index 0000000..d8f9aa9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/IOUtilsTestCase.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.test;
+
+import java.io.File;
+import junit.framework.TestCase;
+import org.apache.cocoon.util.IOUtils;
+
+/**
+ * Test Cases for the IOUtils Class.
+ * @see org.apache.cocoon.util.IOUtils
+ *
+ * @version $Id$
+ */
+public class IOUtilsTestCase extends TestCase
+{
+
+    /**
+     *Constructor for the IOUtilsTestCase object
+     *
+     * @param  name  Description of Parameter
+     * @since
+     */
+    public IOUtilsTestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     *Description of the Method
+     *
+     * @param  args  Description of Parameter
+     * @since
+     */
+    public static void main(String args[]) {
+        junit.textui.TestRunner.run(IOUtilsTestCase.class);
+    }
+
+
+    /**
+     * A unit test for <code>normalizedFilename()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testNormalizedFilename() throws Exception {
+        Object[] test_values = {
+                new String[]{".", "__"},
+                new String[]{"", ""},
+                new String[]{"file://", "file_"},
+                // was new String[]{"file://", "file_" + File.separator + "_" + File.separator + "_"},
+                new String[]{"/a/b/c", "a" + File.separator + "b" + File.separator + "c"},
+                new String[]{"\\a\\b\\c", "a" + File.separator + "b" + File.separator + "c"},
+                new String[]{"a/b/c", "a" + File.separator + "b" + File.separator + "c"},
+                new String[]{"a\\b\\c", "a" + File.separator + "b" + File.separator + "c"},
+                
+                new String[]{"a/b/../c", "a" + File.separator + "c"},
+                new String[]{"public/final.xml", "public_" + File.separator + "final_xml"},
+                new String[]{"123", "_123"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            String expected = tests[1];
+
+            String result = IOUtils.normalizedFilename(test);
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>getContextFilePath()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testGetContextFilePath() throws Exception {
+        Object[] test_values = {
+                new String[]{"a", "a" + File.separator + "b", "b"},
+                new String[]{"a\\b", "a\\b" + File.separator + "c/d", "c" + File.separator + "d"},
+                new String[]{"a/b", "a/b" + File.separator + "c\\d", "c" + File.separator + "d"},
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test_directory_path = tests[0];
+            String test_file_path = tests[1];
+            String expected = tests[2];
+
+            String result = IOUtils.getContextFilePath(test_directory_path, test_file_path);
+            String message = "Test " + "'" + test_directory_path + "'" + ", " +
+                    "'" + test_file_path + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/MIMEUtilsTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/MIMEUtilsTestCase.java
new file mode 100644
index 0000000..3b06276
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/MIMEUtilsTestCase.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.io.StringReader;
+import junit.framework.TestCase;
+
+import org.apache.cocoon.util.MIMEUtils;
+import org.apache.commons.lang.SystemUtils;
+
+/**
+ * Test Cases for the MIMEUtils class.
+ * @see org.apache.cocoon.util.MIMEUtils
+ * Specifically, code for testing the parsing of mime.types files.
+ *
+ * @version $Id$
+ */
+public class MIMEUtilsTestCase extends TestCase
+{
+    final String NL = SystemUtils.LINE_SEPARATOR;
+    Map mimeMap;
+    Map extMap;
+    static final String M2E = "MIME to extension mappings";
+    static final String E2M = "Extension to MIME mappings";
+
+    public MIMEUtilsTestCase(String name) {
+        super(name);
+    }
+
+    public static void main(String args[]) {
+        junit.textui.TestRunner.run(MIMEUtilsTestCase.class);
+    }
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mimeMap = new HashMap();
+        extMap = new HashMap();
+    }
+
+    public void tearDown() throws Exception {
+        super.tearDown();
+        mimeMap = null;
+        extMap = null;
+    }
+
+    public void tstGetMimeType() {
+        assertEquals(E2M, "text/plain", MIMEUtils.getMIMEType(".txt"));
+        assertEquals(E2M, "image/jpeg", MIMEUtils.getMIMEType(".jpg"));
+        assertEquals(E2M, "video/mpeg", MIMEUtils.getMIMEType(".mpg"));
+        assertEquals(E2M, null, MIMEUtils.getMIMEType(".undefined"));
+        assertEquals(M2E, ".txt", MIMEUtils.getDefaultExtension("text/plain"));
+        assertEquals(M2E, ".jpeg", MIMEUtils.getDefaultExtension("image/jpeg"));
+        assertEquals(M2E, ".mpeg", MIMEUtils.getDefaultExtension("video/mpeg"));
+        assertEquals(M2E, null, MIMEUtils.getDefaultExtension("application/octet-stream"));
+
+    }
+
+    public void testTypicalUsage() throws Exception {
+        String mime_types="# MIME type mappings"+ NL +
+            "text/plain  txt text "+ NL +
+            "text/html   html htm"+ NL +
+            "   "+ NL +
+            "text/xml    xml"+ NL +
+            "text/css    css"+ NL +
+            "text/javascript		js "+ NL +
+            "application/x-javascript	js";
+
+        MIMEUtils.loadMimeTypes(new StringReader(mime_types), extMap, mimeMap);
+        assertEquals(".txt", extMap.get("text/plain"));
+        assertEquals(".html", extMap.get("text/html"));
+        assertEquals(".xml", extMap.get("text/xml"));
+        assertEquals(".css", extMap.get("text/css"));
+        assertEquals(".js", extMap.get("text/javascript"));
+        assertEquals(".js", extMap.get("application/x-javascript"));
+
+        assertEquals("text/plain", mimeMap.get(".text"));
+        assertEquals("text/plain", mimeMap.get(".txt"));
+        assertEquals("text/html", mimeMap.get(".html"));
+        assertEquals("text/html", mimeMap.get(".htm"));
+        assertEquals("text/xml", mimeMap.get(".xml"));
+        assertEquals("text/css", mimeMap.get(".css"));
+        assertEquals("text/javascript", mimeMap.get(".js"));
+
+        assertEquals(M2E, 6, extMap.size());
+        assertEquals(E2M, 7, mimeMap.size());
+    }
+
+    public void tstEmpty() throws Exception {
+        String mime_types="";
+        MIMEUtils.loadMimeTypes(new StringReader(mime_types), extMap, mimeMap);
+        assertEquals(M2E, 0, extMap.size());
+        assertEquals(E2M, 0, mimeMap.size());
+    }
+
+    public void tstCommentsAndWhitespace() throws Exception {
+        String mime_types="## A commented line"+NL+
+            "   "+ NL +
+            "# Another comment";
+        MIMEUtils.loadMimeTypes(new StringReader(mime_types), extMap, mimeMap);
+        assertEquals(M2E, 0, extMap.size());
+        assertEquals(E2M, 0, mimeMap.size());
+    }
+
+    public void tstMimeTypeWithoutExtension() throws Exception {
+        String mime_types=
+            "text/plain  txt text"+ NL +
+            "application/octet-stream"+ NL + NL;
+        MIMEUtils.loadMimeTypes(new StringReader(mime_types), extMap, mimeMap);
+        assertEquals(".txt", extMap.get("text/plain"));
+        assertEquals("text/plain", mimeMap.get(".txt"));
+        assertEquals("text/plain", mimeMap.get(".text"));
+        assertEquals(M2E, 1, extMap.size());
+        assertEquals(E2M, 2, mimeMap.size());
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/NetUtilsTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/NetUtilsTestCase.java
new file mode 100644
index 0000000..9917b52
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/util/test/NetUtilsTestCase.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.util.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.cocoon.util.NetUtils;
+
+/**
+ * Test Cases for the NetUtils class.
+ * @see org.apache.cocoon.util.NetUtils
+ *
+ * @version $Id$
+ */
+public class NetUtilsTestCase extends TestCase
+{
+
+    /**
+     *Constructor for the IOUtilsTestCase object
+     *
+     * @param  name  Description of Parameter
+     * @since
+     */
+    public NetUtilsTestCase(String name) {
+        super(name);
+    }
+
+
+    /**
+     *Description of the Method
+     *
+     * @param  args  Description of Parameter
+     * @since
+     */
+    public static void main(String args[]) {
+        junit.textui.TestRunner.run(NetUtilsTestCase.class);
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.getPath()</code>.
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testGetPath() throws Exception {
+        Object[] test_values = {
+                new String[]{"", ""},
+                new String[]{"/", ""},
+                new String[]{"/foo.bar", ""},
+                new String[]{"foo/bar", "foo"},
+                new String[]{"/foo/bar", "/foo"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            String expected = tests[1];
+
+            String result = NetUtils.getPath(test);
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.getExtension()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testGetExtension() throws Exception {
+        Object[] test_values = {
+                new String[]{"/foo.bar", ".bar"},
+                new String[]{"foo.bar#a", ".bar"},
+                new String[]{"foo.bar?b=c", ".bar"},
+                new String[]{"foo.bar#a?b=c", ".bar"},
+                new String[]{"foo.bar", ".bar"},
+                new String[]{"foo/bar", null},
+                new String[]{"/x.html", ".html"},
+                new String[]{"/foo.bar.org/x.y.z.html", ".html"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            String expected = tests[1];
+
+            String result = NetUtils.getExtension(test);
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.absolutize()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testAbsolutize() throws Exception {
+
+        Object[] test_values = {
+            new String[]{"/base/path",  "foo.bar",  "/base/path/foo.bar"},
+            new String[]{"/base/path/", "foo.bar",  "/base/path/foo.bar"},
+            new String[]{"/base/path",  "/foo.bar", "/foo.bar"},
+            
+            new String[]{"/base/path", "",   "/base/path"},
+            new String[]{"/base/path", null, "/base/path"},
+            
+            new String[]{"",   "foo.bar", "foo.bar"},
+            new String[]{null, "foo.bar", "foo.bar"},
+        };
+        
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test_path = tests[0];
+            String test_rel_resource = tests[1];
+            String expected = tests[2];
+
+            String result = NetUtils.absolutize(test_path, test_rel_resource);
+            String message = "Test " +
+                    " path " + "'" + test_path + "'" +
+                    " relativeResource " + "'" + test_rel_resource;
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.testEncodePath()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testEncodePath() throws Exception {
+
+        Object[] test_values = {
+                new String[]{"abc def", "abc%20def"},
+                new String[]{"foo/bar?n=v&N=V", "foo/bar%3Fn=v&N=V"}
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String original = tests[0];
+            String expected = tests[1];
+
+            String result = NetUtils.encodePath(original);
+            String message = "Test " +
+                    " original " + "'" + original + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.relativize()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testRelativize() throws Exception {
+
+        Object[] test_values = {
+                new String[]{"/xml.apache.org", "/xml.apache.org/foo.bar", "foo.bar"},
+                new String[]{"/xml.apache.org", "/xml.apache.org/foo.bar", "foo.bar"},
+                new String[]{"/xml.apache.org", "/xml.apache.org/foo.bar", "foo.bar"},
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test_path = tests[0];
+            String test_abs_resource = tests[1];
+            String expected = tests[2];
+
+            String result = NetUtils.relativize(test_path, test_abs_resource);
+            String message = "Test " +
+                    " path " + "'" + test_path + "'" +
+                    " absoluteResource " + "'" + test_abs_resource;
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for {@link NetUtils#normalize(String)}
+     */
+    public void testNormalize() throws Exception {
+        Object[] test_values = {
+                new String[]{"", ""},
+                new String[]{"/", "/"},
+                new String[]{"/../", "/../"},
+                new String[]{"/../../", "/../../"},
+                new String[]{"/../../foo", "/../../foo"},
+                new String[]{"/../../foo//./../bar", "/../../bar"},
+                new String[]{"//foo//bar", "//foo/bar"},
+                new String[]{"//foo//./bar", "//foo/bar"},
+                new String[]{"/foo/bar", "/foo/bar"},
+                new String[]{"/foo/bar/", "/foo/bar/"},
+                new String[]{"/foo/../bar", "/bar"},
+                new String[]{"/foo/../bar/", "/bar/"},
+                new String[]{"bar", "bar"},
+                new String[]{"foo/../bar", "bar"},
+                new String[]{"foo/./bar", "foo/bar"},
+                new String[]{"foo/bar1/bar2/bar3/../../..", "foo/"},
+                };
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            String expected = tests[1];
+            // alternative for JDK 1.4
+            //String expected = new java.net.URI(test).normalize().toString();
+
+            String result = NetUtils.normalize(test);
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.deparameterize()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testDeparameterize() throws Exception {
+        Map parameters = new HashMap();
+
+        Object[] test_values = {
+            new String[]{"/foo/bar", "/foo/bar"},
+            new String[]{"bar?a=b&c=d", "bar"},
+        };
+
+        for (int i = 0; i < test_values.length; i++) {
+            String tests[] = (String[]) test_values[i];
+            String test = tests[0];
+            String expected = tests[1];
+
+            parameters.clear();
+            String result = NetUtils.deparameterize(test, parameters);
+            if (test.indexOf('?') > -1) {
+                assertTrue(parameters.size() > 0);
+            }
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+    }
+
+
+    /**
+     * A unit test for <code>NetUtils.parameterize()</code>
+     *
+     * @exception  Exception  Description of Exception
+     * @since
+     */
+    public void testParameterize() throws Exception {
+        Map parameters1 = new HashMap();
+
+        Object[] test_values = {
+            new Object[]{"/foo/bar", parameters1, "/foo/bar"},
+        };
+
+        for (int i = 0; i < test_values.length; i++) {
+            Object tests[] = (Object[]) test_values[i];
+            String test = (String) tests[0];
+            Map parameters = (Map) tests[1];
+            String expected = (String) tests[2];
+
+            String result = NetUtils.parameterize(test, parameters);
+            String message = "Test " + "'" + test + "'";
+            assertEquals(message, expected, result);
+        }
+
+        Map parameters2 = new HashMap();
+        parameters2.put("a", "b");
+        parameters2.put("c", "d");
+        
+        String test = "bar";
+        String expected1 = "bar?a=b&c=d";
+        String expected2 = "bar?c=d&a=b";
+        
+        String message = "Test " + "'" + test + "'";
+                    
+        String result = NetUtils.parameterize(test, parameters2);        
+
+        if (expected1.equals(result)) {
+          assertEquals(message, expected1, result);  
+        } else {
+          assertEquals(message, expected2, result);  
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/AbstractXMLTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/AbstractXMLTestCase.java
new file mode 100644
index 0000000..9667f7f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/AbstractXMLTestCase.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.Source;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.dom.DOMSource;
+import java.io.ByteArrayOutputStream;
+
+
+/**
+ * general functions for XML related Testcases
+ *
+ */
+public abstract class AbstractXMLTestCase extends XMLTestCase {
+
+    public AbstractXMLTestCase(String s) {
+        super(s);
+    }
+
+    protected void generateLargeSAX( ContentHandler consumer ) throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+
+        final int size = 65000;
+        char[] large = new char[size];
+        for(int i=0;i<size;i++) {
+            large[i] = 'x';
+        }
+
+        consumer.startDocument();
+        consumer.startElement("", "root", "root", atts);
+        consumer.characters(large,0,size);
+        consumer.endElement("", "root", "root");
+        consumer.endDocument();
+    }
+
+    protected void generateSmallSAX( ContentHandler consumer ) throws SAXException {
+        AttributesImpl atts = new AttributesImpl();
+
+        consumer.startDocument();
+        consumer.startElement("", "root", "root", atts);
+        consumer.characters("test".toCharArray(),0,4);
+        consumer.endElement("", "root", "root");
+        consumer.endDocument();
+    }
+
+    protected byte[] generateByteArray() throws Exception {
+        DOMBuilder in = new DOMBuilder();
+        generateSmallSAX(in);
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        TransformerFactory tFactory = TransformerFactory.newInstance();
+        Transformer t = tFactory.newTransformer();
+        Source input = new DOMSource(in.getDocument());
+        Result output = new StreamResult(bos);
+        t.transform(input, output);
+        bos.close();
+
+        return bos.toByteArray();
+    }
+}
+
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/DefaultHandlerWrapper.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/DefaultHandlerWrapper.java
new file mode 100644
index 0000000..6efc364
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/DefaultHandlerWrapper.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Wrap a ContentHandler in a DefaultHandler
+ *
+ */
+public final class DefaultHandlerWrapper extends DefaultHandler {
+    private final ContentHandler handler;
+
+    public DefaultHandlerWrapper( ContentHandler handler ) {
+        this.handler = handler;
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        handler.setDocumentLocator(locator);
+    }
+
+    public void startDocument() throws SAXException {
+        handler.startDocument();
+    }
+
+    public void endDocument() throws SAXException {
+        handler.endDocument();
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+        handler.startPrefixMapping(prefix,uri);
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+        handler.endPrefixMapping(prefix);
+    }
+
+    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+        handler.startElement(namespaceURI,localName,qName,atts);
+    }
+
+    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+        handler.endElement(namespaceURI,localName,qName);
+    }
+
+    public void characters(char ch[], int start, int length) throws SAXException {
+        handler.characters(ch,start,length);
+    }
+
+    public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
+        handler.ignorableWhitespace(ch,start, length);
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+        handler.processingInstruction(target,data);
+    }
+
+    public void skippedEntity(String name) throws SAXException {
+        handler.skippedEntity(name);
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/NamespacesTableTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/NamespacesTableTestCase.java
new file mode 100644
index 0000000..01d823c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/NamespacesTableTestCase.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.xml;
+
+import junit.framework.TestCase;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Test case for NamespacesTable
+ * 
+ * @version $Id$
+ */
+public class NamespacesTableTestCase extends TestCase {
+    public NamespacesTableTestCase(String name) {
+        super(name);
+    }
+
+    public void testSimple() {
+        NamespacesTable ns = new NamespacesTable();
+        
+        ns.addDeclaration("ns1", "http://ns1");
+        ns.addDeclaration("ns2", "http://ns2");
+        
+        ns.enterScope();
+        
+          assertEquals("http://ns1", ns.getUri("ns1"));
+          assertEquals("ns1", ns.getPrefix("http://ns1"));
+        
+          assertEquals("http://ns2", ns.getUri("ns2"));
+          assertEquals("ns2", ns.getPrefix("http://ns2"));
+        
+          ns.enterScope();
+        
+            ns.addDeclaration("ns3", "http://ns3");
+            ns.enterScope();
+        
+              assertEquals("ns1", ns.getPrefix("http://ns1"));
+              assertEquals("ns3", ns.getPrefix("http://ns3"));
+              assertEquals(0, ns.getCurrentScopeDeclarations().length);
+            ns.leaveScope();
+            
+            // Declarations in this scope are no more visible...
+            assertNull(ns.getUri("ns3"));
+            // ... but still listed in the declared mappings
+            assertEquals(1, ns.getCurrentScopeDeclarations().length);
+            assertEquals("ns3", ns.getCurrentScopeDeclarations()[0].getPrefix());
+        
+          ns.leaveScope();
+        
+          assertNull(ns.getPrefix(ns.getPrefix("http://ns3")));
+          assertNull(ns.getUri("ns3"));
+        
+        ns.leaveScope();
+        // Declarations that occured before this scope are no more visible...
+        assertNull(ns.getUri("ns1"));
+        assertNull(ns.getPrefix("http://ns1"));
+        
+        assertNull(ns.getUri("ns2"));
+        assertNull(ns.getPrefix("http://ns2"));
+        
+        //... but are still available in getDeclaredPrefixes
+        NamespacesTable.Declaration[] prefixes = ns.getCurrentScopeDeclarations();
+        assertEquals(2, prefixes.length);
+
+        assertEquals("ns2", prefixes[0].getPrefix());
+        assertEquals("http://ns2", prefixes[0].getUri());
+        assertEquals("ns1", prefixes[1].getPrefix());
+        assertEquals("http://ns1", prefixes[1].getUri());
+        
+    }
+    
+    public void testOverride() {
+        NamespacesTable ns = new NamespacesTable();
+        
+        ns.addDeclaration("ns1", "http://ns1");
+        ns.enterScope();
+        ns.addDeclaration("ns1", "http://otherns1");
+        ns.enterScope();
+        ns.addDeclaration("ns1", "http://yetanotherns1");
+        ns.enterScope();
+        
+        assertEquals("http://yetanotherns1", ns.getUri("ns1"));
+        assertEquals(0, ns.getPrefixes("http://ns1").length);
+        
+        ns.leaveScope();
+        ns.leaveScope();
+        
+        assertEquals("http://ns1", ns.getUri("ns1"));
+        assertEquals(1, ns.getPrefixes("http://ns1").length);
+        
+        ns.leaveScope();
+        assertNull(ns.getUri("ns1"));
+    }
+    
+    public void testMultiDeclaration() {
+        NamespacesTable ns = new NamespacesTable();
+        ns.addDeclaration("ns1", "http://ns1");
+        ns.enterScope();
+        // two in the same scope
+        ns.addDeclaration("ns2", "http://ns1");
+        ns.addDeclaration("ns3", "http://ns1");
+        ns.enterScope();
+        
+        String[] prefixes = ns.getPrefixes("http://ns1");
+        assertEquals(3, prefixes.length);
+        assertEquals("ns3", prefixes[0]);
+        assertEquals("ns2", prefixes[1]);
+        assertEquals("ns1", prefixes[2]);
+    }
+    
+    public void testStreamDeclarations() throws Exception {
+        NamespacesTable ns = new NamespacesTable();
+        ns.addDeclaration("ns1", "http://ns1");
+        ns.enterScope();
+        ns.addDeclaration("ns2", "http://ns2");
+        ns.enterScope(new DefaultHandler() {
+            public void startPrefixMapping(String prefix, String uri) throws org.xml.sax.SAXException {
+                assertEquals("ns2", prefix);
+                assertEquals("http://ns2", uri);
+            }
+        });
+        
+        // Enter and leave a nested scope
+        ns.addDeclaration("ns3", "http://ns3");
+        ns.enterScope();
+        ns.leaveScope();
+        
+        ns.leaveScope(new DefaultHandler() {
+            public void endPrefixMapping(String prefix) throws org.xml.sax.SAXException {
+                assertEquals("ns2", prefix);
+            }
+        });
+    }
+    
+    /**
+     * A scenario that occurs in with jx:import where some prefixes are started but not used.
+     * @throws Exception
+     */
+    public void testJXImport() throws Exception {
+        NamespacesTable ns = new NamespacesTable();
+        ContentHandler handler = new DefaultHandler();
+        
+        ns.addDeclaration("ft", "http://apache.org/cocoon/forms/1.0#template");
+        ns.addDeclaration("fi", "http://apache.org/cocoon/forms/1.0#instance");
+        ns.addDeclaration("jx", "http://apache.org/cocoon/templates/jx/1.0");
+        ns.enterScope(handler);
+          assertEquals("ft", ns.getPrefix("http://apache.org/cocoon/forms/1.0#template"));
+          assertEquals("fi", ns.getPrefix("http://apache.org/cocoon/forms/1.0#instance"));
+          assertEquals("jx", ns.getPrefix("http://apache.org/cocoon/templates/jx/1.0"));
+          
+          // Add declarations that won't be used
+          ns.addDeclaration("jx", "http://apache.org/cocoon/templates/jx/1.0");
+          ns.addDeclaration("fi", "http://apache.org/cocoon/forms/1.0#instance");
+          ns.addDeclaration("bu", "http://apache.org/cocoon/browser-update/1.0");
+
+        ns.leaveScope(handler);
+        assertNull(ns.getPrefix("http://apache.org/cocoon/forms/1.0#template"));
+        assertNull(ns.getPrefix("http://apache.org/cocoon/forms/1.0#instance"));
+        assertNull(ns.getPrefix("http://apache.org/cocoon/templates/jx/1.0"));
+        assertEquals(3, ns.getCurrentScopeDeclarations().length);
+
+    }
+    
+    public void testDuplicate() throws Exception {
+        NamespacesTable ns = new NamespacesTable();
+        
+        ns.addDeclaration("ns1", "http://ns1");
+          ns.enterScope();
+            ns.addDeclaration("ns1", "http://ns1");
+              ns.enterScope();
+              ns.leaveScope();
+            ns.removeDeclaration("ns1");
+            assertEquals("http://ns1", ns.getUri("ns1"));
+          ns.leaveScope();
+        ns.removeDeclaration("ns1");
+        assertNull(ns.getUri("ns1"));
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/SaxBufferTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/SaxBufferTestCase.java
new file mode 100644
index 0000000..4b0c1d0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/SaxBufferTestCase.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Testcase for SaxBuffer
+ *
+ */
+public final class SaxBufferTestCase extends AbstractXMLTestCase {
+    public SaxBufferTestCase(String s) {
+        super(s);
+    }
+
+    public void testCompareDOM() throws Exception {
+        DOMBuilder in = new DOMBuilder();
+        generateLargeSAX(in);
+
+        SaxBuffer sb = new SaxBuffer();
+        generateLargeSAX(sb);
+
+        DOMBuilder out = new DOMBuilder();
+        sb.toSAX(out);
+
+        assertXMLEqual(in.getDocument(), out.getDocument());
+    }
+
+    public void testStressLoop() throws Exception {
+        SaxBuffer sb = new SaxBuffer();
+
+        long loop = 10000;
+
+        // simply consume documents
+        long start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            generateSmallSAX(sb);
+            sb.recycle();
+        }
+        long stop = System.currentTimeMillis() + 1;
+
+        double r = 1000*loop/(stop-start);
+        System.out.println("consuming: "+ r + " documents per second");
+    }
+
+    public void testCompareToParsing() throws Exception {
+        DOMBuilder in = new DOMBuilder();
+        generateSmallSAX(in);
+
+        SAXParserFactory pfactory = SAXParserFactory.newInstance();
+        SAXParser p = pfactory.newSAXParser();
+
+
+        SaxBuffer b = new SaxBuffer();
+        DefaultHandlerWrapper wrapper = new DefaultHandlerWrapper(b);
+        ByteArrayInputStream bis = new ByteArrayInputStream(generateByteArray());
+
+        long loop = 10000;
+
+        long start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            b.recycle();
+            bis.reset();
+            p.parse(bis,wrapper);
+        }
+        long stop = System.currentTimeMillis() + 1;
+
+        double r = 1000*loop/(stop-start);
+        System.out.println("parsed:" + r + " documents per second");
+
+
+        ContentHandler ch = new DefaultHandler();
+
+        start = System.currentTimeMillis();
+        for(int i=0;i<loop;i++) {
+            b.toSAX(ch);
+        }
+        stop = System.currentTimeMillis() + 1;
+
+        r = 1000*loop/(stop-start);
+        System.out.println("recalling: " + r + " documents per second");
+    }
+
+
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/WhitespaceFilter.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/WhitespaceFilter.java
new file mode 100644
index 0000000..7794d1f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/WhitespaceFilter.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml;
+
+import org.apache.cocoon.xml.AbstractXMLPipe;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A SAX filter to remove whitespace character, which disturb the
+ * XML matching process.
+ *
+ * @version $Id$
+ */
+public class WhitespaceFilter extends AbstractXMLPipe {
+    private StringBuffer buffer = null;
+
+    /**
+     * Create a new WhitespaceFilter.
+     *
+     * @param handler Content handler.
+     */
+    public WhitespaceFilter(ContentHandler handler) {
+        setContentHandler(handler);
+    }
+
+    /**
+     * Receive notification of character data.
+     */
+    public void characters(char c[], int start, int len) throws SAXException {
+        if (contentHandler==null) {
+            return;
+        }
+
+        if (buffer==null) {
+            buffer = new StringBuffer();
+        }
+
+        buffer.append(c, start, len);
+    }
+
+    /**
+     * Receive notification of ignorable whitespace in element content.
+     */
+    public void ignorableWhitespace(char c[], int start,
+                                    int len) throws SAXException {
+        // ignore
+    }
+
+    /**
+     * Receive notification of the beginning of an element.
+     */
+    public void startElement(String namespaceURI, String localName,
+                             String qName,
+                             Attributes atts) throws SAXException {
+
+        pushText();      
+        contentHandler.startElement(namespaceURI, localName, qName, atts);
+    }
+
+    /**
+     * Receive notification of the end of an element.
+     */
+    public void endElement(String uri, String loc, String raw)
+        throws SAXException {
+
+        pushText();
+        contentHandler.endElement(uri, loc, raw);        
+    }
+
+    /**
+     * Receive notification of a processing instruction.
+     */
+    public void processingInstruction(String target, String data)
+        throws SAXException {
+
+        pushText();
+        contentHandler.processingInstruction(target, data);
+    }
+
+    /**
+     * Report an XML comment anywhere in the document.
+     *
+     * @param ch An array holding the characters in the comment.
+     * @param start The starting position in the array.
+     * @param len The number of characters to use from the array.
+     */
+    public void comment(char ch[], int start, int len)
+        throws SAXException {
+  
+        pushText();
+        super.comment(ch, start, len);
+    }
+
+
+    public void pushText() throws SAXException {
+
+        if (buffer!=null) {
+            String text = buffer.toString();
+
+            StringBuffer normalized = new StringBuffer();
+
+            for(int i=0; i<text.length(); i++) {
+                if (Character.isWhitespace(text.charAt(i))) {
+                    normalized.append(' ');
+                    while (((i+1)<text.length()) && (Character.isWhitespace(text.charAt(i+1))))
+                        i++;
+                } else {
+                    normalized.append(text.charAt(i));
+                }
+            }
+
+            text = normalized.toString().trim();
+
+            if (text.length()>0) {
+                contentHandler.characters(text.toCharArray(), 0,
+                                          text.length());
+            }
+
+            buffer = null;
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderStreamerTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderStreamerTestCase.java
new file mode 100644
index 0000000..6d4422e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderStreamerTestCase.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.dom;
+
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.custommonkey.xmlunit.XMLUnit;
+
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Testcase for DOMStreamer and DOMBuilder.
+ *
+ * @version $Id$
+ */
+public class DOMBuilderStreamerTestCase extends XMLTestCase {
+
+    public DOMBuilderStreamerTestCase(String name) {
+        super(name);
+    }
+
+    public void testBuilderWithOneElement() throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startElement("", "root", "root", atts);
+        builder.endElement("", "root", "root");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<root/>");
+        assertXMLEqual(document, builder.getDocument());
+    }
+
+    public void testBuilderWithMoreElements() throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startElement("", "root", "root", atts);
+        builder.startElement("", "node", "node", atts);
+        builder.endElement("", "node", "node");
+        builder.startElement("", "node", "node", atts);
+        builder.endElement("", "node", "node");
+        builder.endElement("", "root", "root");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<root><node/><node/></root>");
+        assertXMLEqual(document, builder.getDocument());
+    }
+
+    public void testBuilderWithText() throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startElement("", "root", "root", atts);
+        builder.characters("abcd".toCharArray(), 0, 4);
+        builder.endElement("", "root", "node");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<root>abcd</root>");
+        assertXMLEqual(document, builder.getDocument());
+    }
+
+    /*public void testBuilderWithNS()  throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startPrefixMapping("", "http://xml.apache.org");
+        builder.startElement("", "root", "root", atts);
+        builder.endElement("", "node", "node");
+        builder.endPrefixMapping("");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<root xmlns=\"http://xml.apache.org\"/>");
+        assertXMLEqual(document, builder.getDocument());
+    }*/
+
+    /*public void testBuilderWithPrefix()  throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startPrefixMapping("bla", "http://xml.apache.org");
+        builder.startElement("http://xml.apache.org", "root", "bla:root", atts);
+        builder.endElement("http://xml.apache.org", "root", "bla:root");
+        builder.endPrefixMapping("bla");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<bla:root xmlns:bla=\"http://xml.apache.org\"/>");
+        assertXMLEqual(document, builder.getDocument());
+    }*/
+
+    /*public void testBuilderWithNSError()  throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+
+        try {
+            builder.startDocument();
+            builder.startPrefixMapping("bla", "http://xml.apache.org");
+            atts.addAttribute( "", "bla", "xmlns:bla", "CDATA", "http://xml.apache.org");
+            builder.startElement("http://xml.apache.org", "root", "bla:root", atts);
+            builder.endElement("http://xml.apache.org", "root", "bla:root");
+            builder.endPrefixMapping("bla");
+            builder.endDocument();
+
+            fail("DOMBuilder should throw exception because of permitted attribute");
+        } catch (Exception e) {
+            // nothing
+        }
+    }*/
+
+    public void testBuilderWithComments() throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startElement("", "root", "root", atts);
+        builder.comment("abcd".toCharArray(), 0, 4);
+        builder.endElement("", "root", "node");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<root><!--abcd--></root>");
+
+        assertXMLEqual(document, builder.getDocument());
+    }
+
+    public void testBuilderWithCommentWithinDocType() throws Exception {
+        AttributesImpl atts = new AttributesImpl();
+
+        DOMBuilder builder = new DOMBuilder();
+        builder.startDocument();
+        builder.startDTD("skinconfig", null, null);
+        builder.comment("abcd".toCharArray(), 0, 4);
+        builder.endDTD();
+        builder.startElement("", "root", "root", atts);
+        builder.endElement("", "root", "node");
+        builder.endDocument();
+
+        Document document = XMLUnit.buildControlDocument("<!DOCTYPE skinconfig [<!--abcd-->]><root></root>");
+
+        print(document);
+        print(builder.getDocument());
+
+        assertXMLEqual(document, builder.getDocument());
+    }
+
+    public final void print(Document document) {
+        TransformerFactory factory = TransformerFactory.newInstance();
+        try
+        {
+          javax.xml.transform.Transformer serializer = factory.newTransformer();
+          serializer.transform(new DOMSource(document), new StreamResult(System.out));
+          System.out.println();
+        }
+        catch (TransformerException te)
+        {
+          te.printStackTrace();
+        }
+    }
+
+
+    public void testTestFacility() throws Exception {
+        Document document = XMLUnit.getControlParser().newDocument();
+        Element elemA = document.createElement("root");
+        document.appendChild(elemA);
+
+        Document oneElementDocument = XMLUnit.buildControlDocument("<root/>");
+        assertXMLEqual(oneElementDocument, document);
+
+        document = XMLUnit.getControlParser().newDocument();
+        elemA = document.createElement("node");
+        document.appendChild(elemA);
+
+        oneElementDocument = XMLUnit.buildControlDocument("<root/>");
+        assertXMLNotEqual(oneElementDocument, document);
+    }
+
+    public void testStreamer() throws Exception {
+
+        Document document = XMLUnit.getControlParser().newDocument();
+        Element elemA = document.createElement("root");
+        document.appendChild(elemA);
+
+        Element elemB = document.createElement("node");
+        elemA.appendChild(elemB);
+        
+        elemB = document.createElement("node");
+        elemA.appendChild(elemB);
+
+        DOMBuilder builder = new DOMBuilder();
+        DOMStreamer streamer = new DOMStreamer(builder);
+
+        streamer.stream(document);
+
+        document = builder.getDocument();
+
+        Document moreElementDocument = XMLUnit.buildControlDocument("<root><node/><node/></root>");
+        assertXMLEqual(moreElementDocument, document);
+    }
+
+    /*public void testStreamerWithNS() throws Exception {
+
+        Document document = XMLUnit.getControlParser().newDocument();
+        Element elemA = document.createElementNS("http://xml.apache.org", "root");
+        document.appendChild(elemA);
+
+        Element elemB = document.createElementNS("http://xml.apache.org", "node");
+        elemA.appendChild(elemB);
+
+        elemB = document.createElementNS("http://xml.apache.org", "node");
+        elemA.appendChild(elemB);
+
+        DOMBuilder builder = new DOMBuilder();
+        DOMStreamer streamer = new DOMStreamer(builder);
+
+        streamer.stream(document);
+    
+        document = builder.getDocument();
+    
+        Document moreElementDocument = XMLUnit.buildControlDocument("<root xmlns=\"http://xml.apache.org\"><node/><node/></root>");
+        assertXMLEqual(moreElementDocument, document);
+    }*/
+}
diff --git a/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderTestCase.java b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderTestCase.java
new file mode 100644
index 0000000..41e1a2c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/test/org/apache/cocoon/xml/dom/DOMBuilderTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.cocoon.xml.dom;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+
+/**
+ * JUnit Testcase for {@link DOMBuilder}.
+ * 
+ * @version $Id$
+ */
+public class DOMBuilderTestCase extends TestCase {
+
+    /**
+     * Constructor.
+     * @param name
+     */
+    public DOMBuilderTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * Test if two consecutive "characters" events result in two text nodes
+     * whose concatenation is equal to the concatenation
+     * of the two strings (cfr. bug #26219).
+     * 
+     * @throws SAXException
+     */
+    public void testMultipleCharactersEvents() throws SAXException {
+        DOMBuilder builder = new DOMBuilder();
+        Attributes attrs = new AttributesImpl();
+        char c1[] = "ABC".toCharArray();
+        char c2[] = "DEF".toCharArray();
+        builder.startDocument();
+        builder.startElement("", "test", "test", attrs);
+        builder.characters(c1, 0, 3);
+        builder.characters(c2, 0, 3);
+        builder.endElement("", "test", "test");
+        builder.endDocument();
+        Document dom = builder.getDocument();
+        StringBuffer value = new StringBuffer();
+        for (int i = 0 ; i < dom.getDocumentElement().getChildNodes().getLength() ; ++i) {
+            value.append(dom.getDocumentElement().getChildNodes().item(i).getNodeValue());
+        }
+        assertEquals("Content of root element not what expected",
+                "ABCDEF", value.toString()); 
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/Manifest.mf b/non-releases/trunk_before_flattening/src/webapp/Manifest.mf
new file mode 100644
index 0000000..2af2270
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/Manifest.mf
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0

+Ant-Version: Apache Ant 1.6.5

+Created-By: 1.4.2_06-b03 (Sun Microsystems Inc.)

+Bundle-Name: cocoon_webapp

+Bundle-SymbolicName: org.apache.cocoon:cocoon_webapp:1.0.0

+Bundle-Version: 1.0.0

+Bundle-Description: Cocoon webapp

+Bundle-Vendor: Apache

+Bundle-DocURL: http://cocoon.apache.org

+Bundle-ContactAddress: http://cocoon.apache.org

+Bundle-Activator: org.apache.cocoon.core.osgi.CoreBlockActivator

+Bundle-Category: sitemap

+Import-Package: 

+ org.osgi.framework,

+ org.apache.cocoon,

+ org.apache.excalibur.source,

+ org.apache.excalibur.store,

+ org.apache.excalibur.xml,

+ org.apache.excalibur.xml.sax,

+ org.apache.excalibur.xml.xpath,

+ org.apache.excalibur.xml.xslt,

+ org.apache.excalibur.xmlizer

+DynamicImport-Package: org.apache.cocoon.*

+Bundle-UUID: org.apache.cocoon:cocoon_webapp:1.0.0:impl

diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/block.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/block.xml
new file mode 100644
index 0000000..619056f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/block.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/webapp/1.0">
+  <name>webapp</name>
+  <description href="http://cocoon.apache.org/blocks/webapp/1.0">
+    Cocoon core samples
+  </description>
+  <state href="http://cocoon.apache.org/blocks/wbapp/1.0/state.html" 
+         community="supported" 
+         interfaces="unstable" 
+         implementation="unstable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <components core="true">
+    <include src="context://WEB-INF/xconf/cocoon-core.xconf"/>
+    <include src="context://WEB-INF/xconf/cocoon-core-sitemap.xconf"/>
+    <include src="context://WEB-INF/sitemap-additions/cocoon-core-sitemap-additions.xconf"/>
+  </components>
+  <sitemap src="sitemap.xmap"/>
+</block>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/COB-INF/block.xml
new file mode 100644
index 0000000..2a923f1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/COB-INF/block.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/mysample/1.0">
+  <name>my sample</name>
+  <description href="http://cocoon.apache.org/blocks/mysample/1.0">
+    An example sample
+  </description>
+  <state href="http://cocoon.apache.org/blocks/mysample/1.0/state.html" 
+         community="contributed" 
+         interfaces="unstable" 
+         implementation="unstable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <sitemap src="sitemap.xmap"/>
+  <extends block="http://cocoon.apache.org/blocks/sample/1.0"/>
+</block>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/samples.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/samples.xml
new file mode 100644
index 0000000..6c28f2a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/samples.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | An example samples page
+    |
+    | $Id$
+    +-->
+
+<samples name="My Samples">
+
+  <group name="My Group of Samples">
+    <sample name="My sample" href="test1">
+      The complete separation between content and style
+      leads to a very powerful multi-channeling solution where you can
+      apply different stylesheets to the same content and generate different
+      flavors of it.
+    </sample>
+    <sample name="Another sample" href="test2">
+      A couple of existing web sites have been xml-ized to show you
+      how easier it is to handle pure-content markup.
+    </sample>   
+  </group>
+
+</samples>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/sitemap.xmap
new file mode 100644
index 0000000..97730ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/sitemap.xmap
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id:$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <source-factories>
+      <component-instance class="org.apache.cocoon.components.source.impl.BlockSourceFactory" name="block"/>
+    </source-factories>
+
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:serializers default="xml">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+    </map:serializers>
+
+    <map:readers default="resource">
+      <map:reader name="resource" src="org.apache.cocoon.reading.ResourceReader"/>
+    </map:readers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="samples.xml">
+        <map:generate src="samples.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="test*">
+        <map:generate src="test.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="**">
+        <map:read src="block:super:/{1}"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/test.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/test.xml
new file mode 100644
index 0000000..95a833c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/mysample/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><mytest/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/COB-INF/block.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/COB-INF/block.xml
new file mode 100644
index 0000000..f927595
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/COB-INF/block.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+<block xmlns="http://apache.org/cocoon/blocks/cob/1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+       xsi:schemaLocation="http://apache.org/cocoon/blocks/cob/1.0 cob-schema-1.0.xsd"
+       id="http://cocoon.apache.org/blocks/sample/1.0">
+  <name>sample</name>
+  <description href="http://cocoon.apache.org/blocks/sample/1.0">
+    Styling of Cocoon samples
+  </description>
+  <state href="http://cocoon.apache.org/blocks/mysample/1.0/state.html" 
+         community="contributed" 
+         interfaces="unstable" 
+         implementation="unstable"/>
+  <license href="http://www.apache.org/licenses/">Apache License 2.0</license>
+  <author href="http://cocoon.apache.org">Apache Cocoon community</author>
+  <sitemap src="sitemap.xmap"/>
+</block>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/images/cocoon.gif b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/images/cocoon.gif
new file mode 100644
index 0000000..8b6aed4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/images/cocoon.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/styles/main.css b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/styles/main.css
new file mode 100644
index 0000000..d732f5d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/resources/styles/main.css
@@ -0,0 +1,81 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+body { background-color: white; color: black; font-family: verdana, helvetica, arial, sans-serif; font-size: 80%; }
+
+h1 { color: #336699; text-align: center; font-size: 3em; padding-bottom: 10px; margin: 0px; }
+h2 { color: #336699; }
+h3 { color: #336699; }
+h4 { color: #336699; }
+
+a:link { color: #336699; }
+a:visited { color: #800080; }
+a:hover { color: #800080; background-color: #ffff80; }
+a:active { color: #006666; }
+
+img { border: 0; }
+.figure { text-align: center; }
+
+span.year { color: #336699; }
+
+p.copyright { text-align: center; padding-top: 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }
+p.author { color: #336699; padding-bottom: 10px; }
+p.block { text-align: center; }
+
+hr { height: 0px; color: #336699; }
+
+span.description { color: #336699; font-weight: bold; }
+span.switch { cursor: pointer; margin-left: 5px; text-decoration: underline; }
+
+/* Samples */
+
+.samplesGroup {
+    /* a tasteful shade of blue */
+    background-color: #BFCCDF;
+    color: black;
+    border-width: 0px 0px 2px 0px;
+    border-style: solid;
+    border-color: #336699;
+    font-size:120%;
+    padding-left: 0.2em;
+    padding-top: 0.2em;
+    padding-bottom: 0.2em;
+    margin-top: 1em;
+    margin-bottom: 0;
+ 
+    /* mozilla and some others support the fancy CSS3 borders */
+    -moz-border-radius-bottomleft: 1em;
+    border-radius-bottomleft: 1em;
+}
+
+.samplesNote {
+    color: #333333;
+    margin: 0.5em;
+    padding: 0.2em;
+    background-color: #ffffcc;
+    font-style: italic;
+}
+
+.samplesText {
+    margin-top: 0.2em;
+}
+
+div.resources {
+    text-align: right;
+}
+
+div.resources a {
+    margin: 5px;
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/samples.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/samples.xml
new file mode 100644
index 0000000..456884a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/samples.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | An example samples page
+    |
+    | $Id$
+    +-->
+
+<samples name="Example Samples">
+
+  <group name="A Group of Samples">
+    <sample name="A sample" href="test1">
+      The complete separation between content and style
+      leads to a very powerful multi-channeling solution where you can
+      apply different stylesheets to the same content and generate different
+      flavors of it.
+    </sample>
+    <sample name="Another sample" href="test2">
+      A couple of existing web sites have been xml-ized to show you
+      how easier it is to handle pure-content markup.
+    </sample>   
+  </group>
+
+  <group name="More Samples">
+    <sample name="Still another sample" href="test3">
+      This example shows the usage of Input Modules in sitemap attribute expressions.
+    </sample>
+  </group>
+
+</samples>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/simple-samples2html.xsl b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/simple-samples2html.xsl
new file mode 100644
index 0000000..c672f2c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/simple-samples2html.xsl
@@ -0,0 +1,188 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Covert samples file to the HTML page. Uses styles/main.css stylesheet.
+    |
+    | $Id$
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:template match="/">
+    <html>
+      <head>
+        <title>Apache Cocoon @version@</title>
+        <link rel="SHORTCUT ICON" href="favicon.ico"/>
+        <link href="block:/styles/main.css" type="text/css" rel="stylesheet"/>
+      </head>
+      <body>
+       <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+         <tr>
+           <td width="*">The Apache Software Foundation is proud to present...</td>
+           <td width="40%" align="center"><img border="0" src="block:/images/cocoon.gif"/></td>
+           <td width="30%" align="center">Version: <b>@version@</b></td>
+         </tr>
+       </table>
+
+       <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+         <tr>
+           <td width="75%">
+             <h2><xsl:value-of select="samples/@name"/></h2>
+           </td>
+           <td nowrap="nowrap" align="right">
+             Orthogonal views:
+             <a href="?cocoon-view=content">Content</a>
+             &#160;
+             <a href="?cocoon-view=pretty-content">Pretty content</a>
+             &#160;
+             <a href="?cocoon-view=links">Links</a>
+           </td>
+         </tr>
+       </table>
+
+       <xsl:apply-templates select="samples"/>
+
+       <p class="copyright">
+         Copyright &#169; @year@ <a href="http://www.apache.org/">The Apache Software Foundation</a>.
+         All rights reserved.
+       </p>
+      </body>
+    </html>
+  </xsl:template>
+
+
+  <xsl:template match="samples">
+    <xsl:variable name="gc" select="4"/><!-- group correction -->
+    <xsl:variable name="all-groups" select="$gc * count(group)"/>
+    <xsl:variable name="all-samples" select="count(group/sample)+count(group/note)+$all-groups"/>
+    <xsl:variable name="half-samples" select="round($all-samples div 2)"/>
+    <xsl:variable name="half-possibilities">
+      <xsl:choose>
+        <xsl:when test="count(group) = 1">1 </xsl:when><!-- single group sample.xml -->
+        <xsl:otherwise>
+          <xsl:for-each select="group">
+            <xsl:if test="position() &lt; last() and position() &gt;= 1">
+              <xsl:variable name="group-position" select="position()"/>
+              <xsl:variable name="prev-sample" select="count(../group[position() &lt;= $group-position - 1]/sample) + count(../group[position() &lt;= $group-position - 1]/note) + position() * $gc - $gc"/>
+              <xsl:variable name="curr-sample" select="count(../group[position() &lt;= $group-position]/sample) + count(../group[position() &lt;= $group-position]/note) + position() * $gc"/>
+              <xsl:variable name="next-sample" select="count(../group[position() &lt;= $group-position + 1]/sample) + count(../group[position() &lt;= $group-position + 1]/note) + position() * $gc + $gc"/>
+              <xsl:variable name="prev-deviation">
+                <xsl:choose>
+                  <xsl:when test="$prev-sample &gt; $half-samples">
+                    <xsl:value-of select="$prev-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $prev-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:variable name="curr-deviation">
+                <xsl:choose>
+                  <xsl:when test="$curr-sample &gt; $half-samples">
+                    <xsl:value-of select="$curr-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $curr-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:variable name="next-deviation">
+                <xsl:choose>
+                  <xsl:when test="$next-sample &gt; $half-samples">
+                    <xsl:value-of select="$next-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $next-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:if test="$prev-deviation &gt;= $curr-deviation and $curr-deviation &lt;= $next-deviation">
+                <xsl:value-of select="$group-position"/><xsl:text> </xsl:text>
+              </xsl:if>
+            </xsl:if>
+          </xsl:for-each>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="half">
+      <xsl:value-of select="substring-before($half-possibilities, ' ')"/>
+    </xsl:variable>
+
+    <table width="100%" cellspacing="5">
+      <tr>
+        <td width="50%" valign="top">
+          <xsl:for-each select="group">
+            <xsl:variable name="group-position" select="position()"/>
+            <xsl:choose>
+              <xsl:when test="$group-position &lt;= $half">
+                <h4 class="samplesGroup"><xsl:value-of select="@name"/></h4>
+                <p class="samplesText"><xsl:apply-templates/></p>
+              </xsl:when>
+              <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </td>
+        <td valign="top">
+          <xsl:for-each select="group">  <!-- [position()<=$half] -->
+            <xsl:variable name="group-position" select="position()"/>
+            <xsl:choose>
+              <xsl:when test="$group-position &gt; $half">
+                <h4 class="samplesGroup"><xsl:value-of select="@name"/></h4>
+                <p class="samplesText"><xsl:apply-templates/></p>
+              </xsl:when>
+              <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </td>
+      </tr>
+    </table>
+  </xsl:template>
+
+
+  <xsl:template match="sample">
+    <xsl:choose>
+      <xsl:when test="@href">
+        <a href="{@href}"><xsl:value-of select="@name"/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="@name"/>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text> - </xsl:text>
+    <xsl:copy-of select="*|text()"/>
+    <br/>
+  </xsl:template>
+
+
+  <xsl:template match="note">
+    <p class="samplesNote">
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+
+  <xsl:template match="@*|node()" priority="-2">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="text()" priority="-1">
+    <xsl:value-of select="."/>
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/sitemap.xmap
new file mode 100644
index 0000000..d41cfe8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/sitemap.xmap
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- SVN $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:components>
+    <source-factories>
+      <component-instance class="org.apache.cocoon.components.source.impl.BlockSourceFactory" name="block"/>
+    </source-factories>
+
+    <input-modules>
+      <component-instance name="block"  class="org.apache.cocoon.components.modules.input.BlockPathModule"/>
+      <component-instance logger="core.modules.input" name="request"          class="org.apache.cocoon.components.modules.input.RequestModule"/>
+    </input-modules>
+
+    <map:generators default="file">
+      <map:generator name="file" src="org.apache.cocoon.generation.FileGenerator"/>
+    </map:generators>
+
+    <map:transformers default="xslt">
+      <map:transformer name="xslt" src="org.apache.cocoon.transformation.TraxTransformer"/>
+      <map:transformer name="linkrewriter" src="org.apache.cocoon.transformation.LinkRewriterTransformer">
+	<link-attrs>href src</link-attrs>
+	<schemes>block</schemes>
+      </map:transformer>
+    </map:transformers>
+
+    <map:serializers default="html">
+      <map:serializer mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+      <map:serializer mime-type="text/html" name="html" src="org.apache.cocoon.serialization.HTMLSerializer">
+        <doctype-public>-//W3C//DTD HTML 4.01 Transitional//EN</doctype-public>
+        <doctype-system>http://www.w3.org/TR/html4/loose.dtd</doctype-system>
+      </map:serializer>
+
+    </map:serializers>
+
+    <map:readers default="resource">
+      <map:reader name="resource" src="org.apache.cocoon.reading.ResourceReader"/>
+    </map:readers>
+
+    <map:matchers default="wildcard">
+      <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+    </map:matchers>
+
+    <map:pipes default="noncaching">
+      <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      </map:pipe>
+    </map:pipes>
+  </map:components>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="">
+        <map:generate src="block:/samples.xml"/>
+        <map:transform src="simple-samples2html.xsl">
+          <map:parameter name="contextPath" value="{request:contextPath}"/>
+        </map:transform>
+        <map:transform type="linkrewriter"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="samples.xml">
+        <map:generate src="samples.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <map:match pattern="test*">
+        <map:generate src="test.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+
+      <!-- images -->
+      <map:match pattern="images/*.gif">
+	<map:read src="resources/images/{1}.gif" mime-type="image/gif"/>
+      </map:match>
+
+      <!-- CSS stylesheets -->
+      <map:match pattern="styles/*.css">
+	<map:read src="resources/styles/{1}.css" mime-type="text/css"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/test.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/test.xml
new file mode 100644
index 0000000..31c1bb8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/blocks/sample/test.xml
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><test/>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/classes/CatalogManager.properties b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/classes/CatalogManager.properties
new file mode 100644
index 0000000..05f99c7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/classes/CatalogManager.properties
@@ -0,0 +1,69 @@
+# CatalogManager.properties
+
+# Copyright 1999-2004 The Apache Software Foundation
+#
+# Licensed 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.
+
+#
+# This is the default properties file for Apache Cocoon. This facilitates local
+# configuration of application-specific catalogs. You can also use cocoon.xconf
+# to over-ride or supplement these settings.
+#
+# Note: The filesystem directory that contains this properties file must be
+# available on the Java classpath. The Cocoon build automatically does this.
+#
+# See the Apache Cocoon documentation
+# http://cocoon.apache.org/2.1/userdocs/concepts/catalog.html
+# and thence the Resolver API and accompanying documentation.
+
+# verbosity ... level of messages for status/debug (messages go to STDOUT)
+# The following messages are provided ...
+#  0 = none
+#  1 = ?
+#  2 = 1+, Loading catalog, Resolved public, Resolved system
+#  3 = 2+, Catalog does not exist, resolvePublic, resolveSystem
+#  10 = 3+, List all catalog entries when loading a catalog
+# (Cocoon also logs the "Resolved public" messages.) 
+# TODO: determine all messages at each level
+#
+verbosity=1
+
+# catalogs ... list of additional catalogs to load
+#  Note that Apache Cocoon will automatically load its own default catalog
+#  from WEB-INF/entities/catalog
+# use full pathnames
+# pathname separator is always semi-colon (;) regardless of operating system
+# directory separator is always slash (/) regardless of operating system
+#
+#catalogs=/path/to/local/catalog
+catalogs=
+
+# prefer ... we prefer to use Public Identifiers for entity resolution
+#
+prefer=public
+
+# static-catalog ... see the Sun doco
+#  TODO: ? what impact does this setting have for Apache Cocoon
+#
+static-catalog=yes
+
+# allow-oasis-xml-catalog-pi ... see the Sun doco
+#  TODO: ? what impact does this setting have for Apache Cocoon
+#
+allow-oasis-xml-catalog-pi=yes
+
+# catalog-class-name ... specify an alternate class name to use
+#  Apache Cocoon does not need this setting - we already have a named class
+#
+# catalog-class-name=com.sun.resolver.Resolver
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/cocoon.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/cocoon.xconf
new file mode 100644
index 0000000..32a0431
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/cocoon.xconf
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- CVS $Id$ -->
+<cocoon version="2.2">
+
+<!--+
+    | This is the main Apache Cocoon configuration file.
+    | It contains includes for the core components and for
+    | each of the blocks that are to be loaded.
+    |
+    | You can add your own components here or include some
+    | additional external files.
+    +-->
+
+  <include src="context://WEB-INF/xconf/cocoon-core.xconf"/>
+
+  <!--+
+      | Include all configuration files ending with ".xconf" 
+      | from the xconf directory.
+      +-->
+  <include dir="context://WEB-INF/xconf" pattern="*.xconf"/>
+
+  <!--+
+      | Include all configuration files ending with ".samplesxconf" 
+      | from the xconf directory.
+      +-->
+  <include dir="context://WEB-INF/xconf" pattern="*.samplesxconf"/>
+</cocoon>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOdia.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOdia.pen
new file mode 100644
index 0000000..df5c05d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOdia.pen
@@ -0,0 +1,34 @@
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOdia PUBLIC
+       "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML">
+     %ISOdia;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 10646 as its document character set. 
+     This includes XML documents and ISO HTML documents.
+     This entity set uses hexadecimal numeric character references. 
+          
+     Creator: Rick Jelliffe, Allette Systems
+     
+     Version: 1997-07-07
+-->
+
+<!ENTITY acute  "&#180;" ><!--=acute accent-->
+<!ENTITY breve  "&#x2D8;" ><!--=breve-->
+<!ENTITY caron  "&#x2C7;" ><!--=caron-->
+<!ENTITY cedil  "&#184;" ><!--=cedilla-->
+<!ENTITY circ   "^" ><!--=circumflex accent-->
+<!ENTITY dblac  "&#x2DD;" ><!--=double acute accent-->
+<!ENTITY die    "&#168;" ><!--=dieresis-->
+<!ENTITY dot    "&#x2D9;" ><!--=dot above-->
+<!ENTITY grave  "`" ><!--=grave accent-->
+<!ENTITY macr   "&#175;" ><!--=macron-->
+<!ENTITY ogon   "&#x2DB;" ><!--=ogonek-->
+<!ENTITY ring   "&#x2DA;" ><!--=ring-->
+<!ENTITY tilde  "&#x2DC;" ><!--=tilde-->
+<!ENTITY uml    "&#168;" ><!--=umlaut mark-->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOgrk1.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOgrk1.pen
new file mode 100644
index 0000000..cdab380
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOgrk1.pen
@@ -0,0 +1,74 @@
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+
+    Creator: version from ISO 8879:1986
+    
+    Version: 0.21 1992-12-04
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOGRK1 PUBLIC
+       "ISO 9573-15:1993//ENTITIES Greek Letters//EN//XML">
+     %ISOGRK1;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 10646 as its document character set. 
+     This includes XML documents and ISO HTML documents.
+     
+     Creator: Rick Jelliffe, from HTMLlat1
+     
+     Version: 1997-07-07
+-->
+
+<!ENTITY agr     "&#945;" ><!--small alpha, Greek, U03B1 -->
+<!ENTITY Agr     "&#913;" ><!--capital Alpha, Greek, U0391 -->
+<!ENTITY bgr     "&#946;" ><!--small beta, Greek, U03B2 -->
+<!ENTITY Bgr     "&#914;" ><!--capital Beta, Greek, U0392 -->
+<!ENTITY ggr     "&#947;" ><!--small gamma, Greek, U03B3 -->
+<!ENTITY Ggr     "&#915;" ><!--capital Gamma, Greek, U0393 -->
+<!ENTITY dgr     "&#948;" ><!--small delta, Greek, U03B4 -->
+<!ENTITY Dgr     "&#916;" ><!--capital Delta, Greek, U0394 -->
+<!ENTITY egr     "&#949;" ><!--small epsilon, Greek, U03B5 -->
+<!ENTITY Egr     "&#917;" ><!--capital Epsilon, Greek, U0395 -->
+<!ENTITY zgr     "&#950;" ><!--small zeta, Greek, U03B6 -->
+<!ENTITY Zgr     "&#918;" ><!--capital Zeta, Greek, U0396 -->
+<!ENTITY eegr    "&#951;" ><!--small eta, Greek, U03B7 -->
+<!ENTITY EEgr    "&#919;" ><!--capital Eta, Greek, U0397 -->
+<!ENTITY thgr    "&#952;" ><!--small theta, Greek, U03B8 -->
+<!ENTITY THgr    "&#920;" ><!--capital Theta, Greek, U0398 -->
+<!ENTITY igr     "&#953;" ><!--small iota, Greek, U03B9 -->
+<!ENTITY Igr     "&#921;" ><!--capital Iota, Greek, U0399 -->
+<!ENTITY kgr     "&#954;" ><!--small kappa, Greek, U03BA -->
+<!ENTITY Kgr     "&#922;" ><!--capital Kappa, Greek, U039A -->
+<!ENTITY lgr     "&#955;" ><!--small lambda, Greek, U03BB -->
+<!ENTITY Lgr     "&#923;" ><!--capital Lambda, Greek, U039B -->
+<!ENTITY mgr     "&#956;" ><!--small mu, Greek, U03BC -->
+<!ENTITY Mgr     "&#924;" ><!--capital Mu, Greek, U039C -->
+<!ENTITY ngr     "&#957;" ><!--small nu, Greek, U03BD -->
+<!ENTITY Ngr     "&#925;" ><!--capital Nu, Greek, U039D -->
+<!ENTITY xgr     "&#958;" ><!--small xi, Greek, U03BE -->
+<!ENTITY Xgr     "&#926;" ><!--capital Xi, Greek, U039E -->
+<!ENTITY ogr     "&#959;" ><!--small omicron, Greek, U03BF -->
+<!ENTITY Ogr     "&#927;" ><!--capital Omicron, Greek, U039F -->
+<!ENTITY pgr     "&#960;" ><!--small pi, Greek, U03C0 -->
+<!ENTITY Pgr     "&#928;" ><!--capital Pi, Greek, U03A0 -->
+<!ENTITY rgr     "&#961;" ><!--small rho, Greek, U03C1 -->
+<!ENTITY Rgr     "&#929;" ><!--capital Rho, Greek, U03A1 -->
+<!ENTITY sfgr    "&#962;" ><!--final small sigma, Greek, U03C2 --> 
+<!ENTITY sgr     "&#963;" ><!--small sigma, Greek, U03C3 -->
+<!ENTITY Sgr     "&#931;" ><!--capital Sigma, Greek, U03A3 -->
+<!ENTITY tgr     "&#964;" ><!--small tau, Greek, U03C4 -->
+<!ENTITY Tgr     "&#932;" ><!--capital Tau, Greek, U03A4 -->
+<!ENTITY ugr     "&#965;" ><!--small upsilon, Greek, U03C5 -->
+<!ENTITY Ugr     "&#933;" ><!--capital Upsilon, Greek, U03A5 -->
+<!ENTITY phgr    "&#966;" ><!--small phi, Greek, U03C6 -->
+<!ENTITY PHgr    "&#934;" ><!--capital Phi, Greek, U03A6 -->
+<!ENTITY khgr    "&#967;" ><!--small chi, Greek, U03C7 -->
+<!ENTITY KHgr    "&#935;" ><!--capital Chi, Greek, U03A7 -->
+<!ENTITY psgr    "&#968;" ><!--small psi, Greek, U03C8 -->
+<!ENTITY PSgr    "&#936;" ><!--capital Psi, Greek, U03A8 -->
+<!ENTITY ohgr    "&#969;" ><!--small omega, Greek, U03C9 -->
+<!ENTITY OHgr    "&#937;" ><!--capital Omega, Greek, U03A9 -->
+ 
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOlat1.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOlat1.pen
new file mode 100644
index 0000000..6222e2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOlat1.pen
@@ -0,0 +1,79 @@
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOlat1 PUBLIC
+       "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML">
+     %ISOlat1;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 8859-1 or ISO 10646 as its document character 
+     set. This includes XML documents and ISO HTML documents. 
+-->
+ 
+    <!ENTITY Agrave  "&#192;" ><!-- capital A, grave accent -->
+    <!ENTITY Aacute  "&#193;" ><!-- capital A, acute accent -->
+    <!ENTITY Acirc   "&#194;" ><!-- capital A, circumflex accent -->
+    <!ENTITY Atilde  "&#195;" ><!-- capital A, tilde -->
+    <!ENTITY Auml    "&#196;" ><!-- capital A, dieresis or umlaut mark -->
+    <!ENTITY Aring   "&#197;" ><!-- capital A, ring -->
+    <!ENTITY AElig   "&#198;" ><!-- capital AE diphthong (ligature) -->
+    <!ENTITY Ccedil  "&#199;" ><!-- capital C, cedilla -->
+    <!ENTITY Egrave  "&#200;" ><!-- capital E, grave accent -->
+    <!ENTITY Eacute  "&#201;" ><!-- capital E, acute accent -->
+    <!ENTITY Ecirc   "&#202;" ><!-- capital E, circumflex accent -->
+    <!ENTITY Euml    "&#203;" ><!-- capital E, dieresis or umlaut mark -->
+    <!ENTITY Igrave  "&#204;" ><!-- capital I, grave accent -->
+    <!ENTITY Iacute  "&#205;" ><!-- capital I, acute accent -->
+    <!ENTITY Icirc   "&#206;" ><!-- capital I, circumflex accent -->
+    <!ENTITY Iuml    "&#207;" ><!-- capital I, dieresis or umlaut mark -->
+    <!ENTITY ETH     "&#208;" ><!-- capital Eth, Icelandic -->
+    <!ENTITY Ntilde  "&#209;" ><!-- capital N, tilde -->
+    <!ENTITY Ograve  "&#210;" ><!-- capital O, grave accent -->
+    <!ENTITY Oacute  "&#211;" ><!-- capital O, acute accent -->
+    <!ENTITY Ocirc   "&#212;" ><!-- capital O, circumflex accent -->
+    <!ENTITY Otilde  "&#213;" ><!-- capital O, tilde -->
+    <!ENTITY Ouml    "&#214;" ><!-- capital O, dieresis or umlaut mark -->
+    <!ENTITY Oslash  "&#216;" ><!-- capital O, slash -->
+    <!ENTITY Ugrave  "&#217;" ><!-- capital U, grave accent -->
+    <!ENTITY Uacute  "&#218;" ><!-- capital U, acute accent -->
+    <!ENTITY Ucirc   "&#219;" ><!-- capital U, circumflex accent -->
+    <!ENTITY Uuml    "&#220;" ><!-- capital U, dieresis or umlaut mark -->
+    <!ENTITY Yacute  "&#221;" ><!-- capital Y, acute accent -->
+    <!ENTITY THORN   "&#222;" ><!-- capital THORN, Icelandic -->
+    <!ENTITY szlig   "&#223;" ><!-- small sharp s, German (sz ligature) -->
+    <!ENTITY agrave  "&#224;" ><!-- small a, grave accent -->   
+    <!ENTITY aacute  "&#225;" ><!-- small a, acute accent -->
+    <!ENTITY acirc   "&#226;" ><!-- small a, circumflex accent -->
+    <!ENTITY atilde  "&#227;" ><!-- small a, tilde -->
+    <!ENTITY auml    "&#228;" ><!-- small a, dieresis or umlaut mark -->
+    <!ENTITY aring   "&#229;" ><!-- small a, ring -->
+    <!ENTITY aelig   "&#230;" ><!-- small ae diphthong (ligature) -->
+    <!ENTITY ccedil  "&#231;" ><!-- small c, cedilla -->
+    <!ENTITY egrave  "&#232;" ><!-- small e, grave accent -->
+    <!ENTITY eacute  "&#233;" ><!-- small e, acute accent -->
+    <!ENTITY ecirc   "&#234;" ><!-- small e, circumflex accent -->
+    <!ENTITY euml    "&#235;" ><!-- small e, dieresis or umlaut mark -->
+    <!ENTITY igrave  "&#236;" ><!-- small i, grave accent -->
+    <!ENTITY iacute  "&#237;" ><!-- small i, acute accent -->
+    <!ENTITY icirc   "&#238;" ><!-- small i, circumflex accent -->
+    <!ENTITY iuml    "&#239;" ><!-- small i, dieresis or umlaut mark -->
+    <!ENTITY eth     "&#240;" ><!-- small eth, Icelandic -->
+    <!ENTITY ntilde  "&#241;" ><!-- small n, tilde -->
+    <!ENTITY ograve  "&#242;" ><!-- small o, grave accent -->
+    <!ENTITY oacute  "&#243;" ><!-- small o, acute accent -->
+    <!ENTITY ocirc   "&#244;" ><!-- small o, circumflex accent -->
+    <!ENTITY otilde  "&#245;" ><!-- small o, tilde -->
+    <!ENTITY ouml    "&#246;" ><!-- small o, dieresis or umlaut mark -->
+
+    <!ENTITY oslash  "&#248;" ><!-- small o, slash -->
+    <!ENTITY ugrave  "&#249;" ><!-- small u, grave accent -->
+    <!ENTITY uacute  "&#250;" ><!-- small u, acute accent -->
+    <!ENTITY ucirc   "&#251;" ><!-- small u, circumflex accent -->
+    <!ENTITY uuml    "&#252;" ><!-- small u, dieresis or umlaut mark -->
+    <!ENTITY yacute  "&#253;" ><!-- small y, acute accent -->
+    <!ENTITY thorn   "&#254;" ><!-- small thorn, Icelandic -->
+    <!ENTITY yuml    "&#255;" ><!-- small y, dieresis or umlaut mark -->
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOnum.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOnum.pen
new file mode 100644
index 0000000..02605bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOnum.pen
@@ -0,0 +1,109 @@
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOnum PUBLIC
+       "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML">
+     %ISOnum;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 10646 as its document character set. 
+     This includes XML documents and ISO HTML documents.
+     This entity set uses hexadecimal numeric character references. 
+          
+     Creator: Rick Jelliffe, Allette Systems
+     
+     Version: 1997-07-07
+-->
+
+<!ENTITY half   "&#189;" ><!--=fraction one-half-->
+<!ENTITY frac12 "&#189;" ><!--=fraction one-half-->
+<!ENTITY frac14 "&#188;" ><!--=fraction one-quarter-->
+<!ENTITY frac34 "&#190;" ><!--=fraction three-quarters-->
+<!ENTITY frac18 "&#x215B;" > 
+    <!-- or "&#xB1;&#x202;&#x2044;&#x2088;" --><!--=fraction one-eighth-->
+<!ENTITY frac38 "&#x215C;" >
+    <!-- or "&#xB3;&#x2044;&#x2088;" --><!--=fraction three-eighths-->
+<!ENTITY frac58 "&#x215D;" >
+    <!-- or "&#x2075;&#x2044;&#x2088;" --><!--=fraction five-eighths-->
+<!ENTITY frac78 "&#x215E;" >
+    <!-- or "&#x2077;&#x2044;&#x2088;" --><!--=fraction seven-eighths-->
+
+<!ENTITY sup1   "&#185;" ><!--=superscript one-->
+<!ENTITY sup2   "&#178;" ><!--=superscript two-->
+<!ENTITY sup3   "&#179;" ><!--=superscript three-->
+
+<!ENTITY plus   "+" ><!--=plus sign B:-->
+<!ENTITY plusmn "&#xB1;" ><!--/pm B: =plus-or-minus sign-->
+<!ENTITY lt     "&#38;#60;"      ><!--=less-than sign R:-->
+<!ENTITY equals "="      ><!--=equals sign R:-->
+<!ENTITY gt     ">"      ><!--=greater-than sign R:-->
+<!ENTITY divide "&#247;" ><!--/div B: =divide sign-->
+<!ENTITY times  "&#215;" ><!--/times B: =multiply sign-->
+
+<!ENTITY curren "&#164;" ><!--=general currency sign-->
+<!ENTITY pound  "&#163;" ><!--=pound sign-->
+<!ENTITY dollar "$"      ><!--=dollar sign-->
+<!ENTITY cent   "&#162;" ><!--=cent sign-->
+<!ENTITY yen    "&#165;" ><!--/yen =yen sign-->
+
+<!ENTITY num    "#" ><!--=number sign-->
+<!ENTITY percnt "&#37;" ><!--=percent sign-->
+<!ENTITY amp    "&#38;#38;" ><!--=ampersand-->
+<!ENTITY ast    "*" ><!--/ast B: =asterisk-->
+<!ENTITY commat "@" ><!--=commercial at-->
+<!ENTITY lsqb   "[" ><!--/lbrack O: =left square bracket-->
+<!ENTITY bsol   "\" ><!--/backslash =reverse solidus-->
+<!ENTITY rsqb   "]" ><!--/rbrack C: =right square bracket-->
+<!ENTITY lcub   "{" ><!--/lbrace O: =left curly bracket-->
+<!ENTITY horbar "&#x2015;" ><!--=horizontal bar-->
+<!ENTITY verbar "|" ><!--/vert =vertical bar-->
+<!ENTITY rcub   "}" ><!--/rbrace C: =right curly bracket-->
+<!ENTITY micro  "&#181;" ><!--=micro sign-->
+<!ENTITY ohm    "&#2126;" ><!--=ohm sign-->
+<!ENTITY deg    "&#176;" ><!--=degree sign-->
+<!ENTITY ordm   "&#186;" ><!--=ordinal indicator, masculine-->
+<!ENTITY ordf   "&#170;" ><!--=ordinal indicator, feminine-->
+<!ENTITY sect   "&#167;" ><!--=section sign-->
+<!ENTITY para   "&#182;" ><!--=pilcrow (paragraph sign)-->
+<!ENTITY middot "&#183;" ><!--/centerdot B: =middle dot-->
+<!ENTITY larr   "&#x2190;" ><!--/leftarrow /gets A: =leftward arrow-->
+<!ENTITY rarr   "&#x2192;" ><!--/rightarrow /to A: =rightward arrow-->
+<!ENTITY uarr   "&#x2191;" ><!--/uparrow A: =upward arrow-->
+<!ENTITY darr   "&#x2193;" ><!--/downarrow A: =downward arrow-->
+<!ENTITY copy   "&#169;" ><!--=copyright sign-->
+<!ENTITY reg    "&#174;" ><!--/circledR =registered sign-->
+<!ENTITY trade  "&#8482;" ><!--=trade mark sign-->
+<!ENTITY brvbar "&#xA6;" ><!--=bren (vertical) bar-->
+<!ENTITY not    "&#xAC;" ><!--/neg /lnot =not sign-->
+<!ENTITY sung   "&#x266A;" ><!--=music note (sung text sign)-->
+
+<!ENTITY excl   "!" ><!--=exclamation mark-->
+<!ENTITY iexcl  "&#xA1;" ><!--=inverted exclamation mark-->
+<!ENTITY quot   '"' ><!--=quotation mark-->
+<!ENTITY apos   "'" ><!--=apostrophe-->
+<!ENTITY lpar   "(" ><!--O: =left parenthesis-->
+<!ENTITY rpar   ")" ><!--C: =right parenthesis-->
+<!ENTITY comma  "," ><!--P: =comma-->
+<!ENTITY lowbar "_" ><!--=low line-->
+<!ENTITY hyphen "&#x2010;" ><!--=hyphen-->
+<!ENTITY period "." ><!--=full stop, period-->
+<!ENTITY sol    "/" ><!--=solidus-->
+<!ENTITY colon  ":" ><!--/colon P:-->
+<!ENTITY semi   ";" ><!--=semicolon P:-->
+<!ENTITY quest  "?" ><!--=question mark-->
+<!ENTITY iquest "&#xBF;" ><!--=inverted question mark-->
+<!ENTITY laquo  "&#x2039;" ><!--=angle quotation mark, left
+ But note that Unicode 1 & Maler & el Andaloussi give &#xAB; -->
+<!ENTITY raquo  "&#x203A;" ><!--=angle quotation mark, right
+ But note that Unicode 1 & Maler & el Andaloussi give &#xBB; -->
+<!ENTITY lsquo  "&#x2018;" ><!--=single quotation mark, left-->
+<!ENTITY rsquo  "&#x2019;" ><!--=single quotation mark, right-->
+<!ENTITY ldquo  "&#x201C;" ><!--=double quotation mark, left-->
+<!ENTITY rdquo  "&#x201D;" ><!--=double quotation mark, right-->
+<!ENTITY nbsp   "&#160;" ><!--=no break (required) space-->
+<!ENTITY shy    "&#173;" ><!--=soft hyphen-->
+
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOpub.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOpub.pen
new file mode 100644
index 0000000..04a5732
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOpub.pen
@@ -0,0 +1,110 @@
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOpub PUBLIC
+       "ISO 8879:1986//ENTITIES Publishing//EN//XML">
+     %ISOpub;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 10646 as its document character set. 
+     This includes XML documents and ISO HTML documents.
+     This entity set uses hexadecimal numeric character references. 
+          
+     Creator: Rick Jelliffe, Allette Systems
+     
+     Version: 1997-07-07
+-->
+<!ENTITY emsp   "&#x2003;" ><!--=em space-->
+<!ENTITY ensp   "&#x2002;" ><!--=en space (1/2-em)-->
+<!ENTITY emsp13 "&#x2004;" ><!--=1/3-em space-->
+<!ENTITY emsp14 "&#x2005;" ><!--=1/4-em space-->
+<!ENTITY numsp  "&#x2007;" ><!--=digit space (width of a number)-->
+<!ENTITY puncsp "&#x2008;" ><!--=punctuation space (width of comma)-->
+<!ENTITY thinsp "&#x2009;" ><!--=thin space (1/6-em)-->
+<!ENTITY hairsp "&#x200A;" ><!--=hair space-->
+<!ENTITY mdash  "&#x2014;" ><!--=em dash-->
+<!ENTITY ndash  "&#x2013;" ><!--=en dash-->
+<!ENTITY dash   "&#x2010;" ><!--=hyphen (true graphic)-->
+<!ENTITY blank  "&#x2423;" ><!--=significant blank symbol-->
+<!ENTITY hellip "&#x2026;" ><!--=ellipsis (horizontal)-->
+<!ENTITY nldr   "&#x2025;" ><!--=double baseline dot (en leader)-->
+<!ENTITY frac13 "&#x2153;" ><!--=fraction one-third-->
+<!ENTITY frac23 "&#x2154;" ><!--=fraction two-thirds-->
+<!ENTITY frac15 "&#x2155;" ><!--=fraction one-fifth-->
+<!ENTITY frac25 "&#x2156;" ><!--=fraction two-fifths-->
+<!ENTITY frac35 "&#x2157;" ><!--=fraction three-fifths-->
+<!ENTITY frac45 "&#x2158;" ><!--=fraction four-fifths-->
+<!ENTITY frac16 "&#x2159;" ><!--=fraction one-sixth-->
+<!ENTITY frac56 "&#x215a;" ><!--=fraction five-sixths-->
+<!ENTITY incare "&#x2105;" ><!--=in-care-of symbol-->
+<!ENTITY block  "&#x2588;" ><!--=full block-->
+<!ENTITY uhblk  "&#x2580;" ><!--=upper half block-->
+<!ENTITY lhblk  "&#x2584;" ><!--=lower half block-->
+<!ENTITY blk14  "&#x2591;" ><!--=25% shaded block-->
+<!ENTITY blk12  "&#x2592;" ><!--=50% shaded block-->
+<!ENTITY blk34  "&#x2593;" ><!--=75% shaded block-->
+<!ENTITY marker "&#x25AE;" ><!--=histogram marker-->
+<!ENTITY cir    "&#x25CB;" ><!--/circ B: =circle, open-->
+<!ENTITY squ    "&#x25A1;" ><!--=square, open-->
+<!ENTITY rect   "&#x25AD;" ><!--=rectangle, open-->
+<!ENTITY utri   "&#x25B5;" ><!--/triangle =up triangle, open-->
+<!ENTITY dtri   "&#x25BF;" ><!--/triangledown =down triangle, open-->
+<!ENTITY star   "&#x2606;" ><!--=star, open-->
+<!ENTITY bull   "&#x2022;" ><!--/bullet B: =round bullet, filled-->
+<!ENTITY squf   "&#x25AA;" ><!--/blacksquare =sq bullet, filled-->
+<!ENTITY utrif  "&#x25B4;" ><!--/blacktriangle =up tri, filled-->
+<!ENTITY dtrif  "&#x25BE;" ><!--/blacktriangledown =dn tri, filled-->
+<!ENTITY ltrif  "&#x25C2;" ><!--/blacktriangleleft R: =l tri, filled-->
+<!ENTITY rtrif  "&#x25B8;" ><!--/blacktriangleright R: =r tri, filled-->
+<!ENTITY clubs  "&#x2663;" ><!--/clubsuit =club suit symbol-->
+<!ENTITY diams  "&#x2662;" ><!--/diamondsuit =diamond suit symbol-->
+<!ENTITY hearts "&#x2661;" ><!--/heartsuit =heart suit symbol-->
+<!ENTITY spades "&#x2660;" ><!--/spadesuit =spades suit symbol-->
+<!ENTITY malt   "&#x2720;" ><!--/maltese =maltese cross-->
+<!ENTITY dagger "&#x2020;" ><!--/dagger B: =dagger-->
+<!ENTITY Dagger "&#x2021;" ><!--/ddagger B: =double dagger-->
+<!ENTITY check  "&#x2713;" ><!--/checkmark =tick, check mark-->
+<!ENTITY cross  "&#x2717;" ><!--=ballot cross-->
+<!ENTITY sharp  "&#x266F;" ><!--/sharp =musical sharp-->
+<!ENTITY flat   "&#x266D;" ><!--/flat =musical flat-->
+<!ENTITY male   "&#x2642;" ><!--=male symbol-->
+<!ENTITY female "&#x2640;" ><!--=female symbol-->
+<!ENTITY phone  "&#x26E0;" ><!--=telephone symbol-->
+<!ENTITY telrec "&#x2315;" ><!--=telephone recorder symbol-->
+<!ENTITY copysr "&#x2117;" ><!--=sound recording copyright sign-->
+<!ENTITY caret  "&#x2041;" ><!--=caret (insertion mark)-->
+<!ENTITY lsquor "&#x201A;" ><!--=rising single quote, left (low)-->
+<!ENTITY ldquor "&#x201E;" ><!--=rising dbl quote, left (low)-->
+
+<!ENTITY fflig  "&#xFB00;" ><!--small ff ligature-->
+<!ENTITY filig  "&#xFB01;" ><!--small fi ligature-->
+<!ENTITY fjlig  "fj" ><!--small fj ligature-->
+<!ENTITY ffilig "&#xFB03;" ><!--small ffi ligature-->
+<!ENTITY ffllig "&#xFB04;" ><!--small ffl ligature-->
+<!ENTITY fllig  "&#xFB02;" ><!--small fl ligature-->
+
+<!ENTITY mldr   "&#x2025;" ><!--em leader-->
+<!ENTITY rdquor "&#x201D;" ><!--rising dbl quote, right (high)-->
+<!ENTITY rsquor "&#x2019;" ><!--rising single quote, right (high)-->
+<!ENTITY vellip "&#x22EE;" ><!--vertical ellipsis-->
+
+<!ENTITY hybull "&#x2043;" ><!--rectangle, filled (hyphen bullet)-->
+<!ENTITY loz    "&#x2727;" ><!--/lozenge - lozenge or total mark-->
+<!ENTITY lozf   "&#x2726;" ><!--/blacklozenge - lozenge, filled-->
+<!ENTITY ltri   "&#x25C3;" ><!--/triangleleft B: l triangle, open-->
+<!ENTITY rtri   "&#x25B9;" ><!--/triangleright B: r triangle, open-->
+<!ENTITY starf  "&#x2605;" ><!--/bigstar - star, filled-->
+
+<!ENTITY natur  "&#x266E;" ><!--/natural - music natural-->
+<!ENTITY rx     "&#x211E;" ><!--pharmaceutical prescription (Rx)-->
+<!ENTITY sext   "&#x2736;" ><!--sextile (6-pointed star)-->
+
+<!ENTITY target "&#x2316;" ><!--register mark or target-->
+<!ENTITY dlcrop "&#x230D;" ><!--downward left crop mark -->
+<!ENTITY drcrop "&#x230C;" ><!--downward right crop mark -->
+<!ENTITY ulcrop "&#x230F;" ><!--upward left crop mark -->
+<!ENTITY urcrop "&#x230E;" ><!--upward right crop mark -->
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOtech.pen b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOtech.pen
new file mode 100644
index 0000000..b3b39f9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/ISOtech.pen
@@ -0,0 +1,85 @@
+
+<!-- (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % ISOtech PUBLIC
+       "ISO 8879:1986//ENTITIES General Technical//EN//XML" 
+       "ISOtech.pen">
+     %ISOtech;
+-->
+<!-- This version of the entity set can be used with any SGML document
+     which uses ISO 10646 as its document character set. 
+     This includes XML documents and ISO HTML documents.
+     This entity set uses hexadecimal numeric character references. 
+          
+     Creator: Rick Jelliffe, Allette Systems
+     
+     Version: 1997-07-07
+-->
+<!ENTITY aleph  "&#x2135;" ><!--/aleph =aleph, Hebrew-->
+<!ENTITY and    "&#x2227;" ><!--/wedge /land B: =logical and-->
+<!ENTITY ang90  "&#x221F;" ><!--=right (90 degree) angle-->
+<!ENTITY angsph "&#x2222;" ><!--/sphericalangle =angle-spherical-->
+<!ENTITY ap     "&#x2249;" ><!--/approx R: =approximate-->
+<!ENTITY becaus "&#x2235;" ><!--/because R: =because-->
+<!ENTITY bottom "&#x22A5;" ><!--/bot B: =perpendicular-->
+<!ENTITY cap    "&#x2229;" ><!--/cap B: =intersection-->
+<!ENTITY cong   "&#x2245;" ><!--/cong R: =congruent with-->
+<!ENTITY conint "&#x222E;" ><!--/oint L: =contour integral operator-->
+<!ENTITY cup    "&#x222A;" ><!--/cup B: =union or logical sum-->
+<!ENTITY equiv  "&#x2261;" ><!--/equiv R: =identical with-->
+<!ENTITY exist  "&#x2203;" ><!--/exists =at least one exists-->
+<!ENTITY forall "&#x2200;" ><!--/forall =for all-->
+<!ENTITY fnof   "&#x192;" ><!--=function of (italic small f)-->
+<!ENTITY ge     "&#x2265;" ><!--/geq /ge R: =greater-than-or-equal-->
+<!ENTITY iff    "&#x21D4;" ><!--/iff =if and only if-->
+<!ENTITY infin  "&#x221E;" ><!--/infty =infinity-->
+<!ENTITY int    "&#x222B;" ><!--/int L: =integral operator-->
+<!ENTITY isin   "&#x2208;" ><!--/in R: =set membership-->
+<!ENTITY lang   "&#x2329;" ><!--/langle O: =left angle bracket-->
+<!ENTITY lArr   "&#x21D0;" ><!--/Leftarrow A: =is implied by-->
+<!ENTITY le     "&#x2264;" ><!--/leq /le R: =less-than-or-equal-->
+<!ENTITY minus  "-" ><!--B: =minus sign-->
+<!ENTITY mnplus "&#x2213;" ><!--/mp B: =minus-or-plus sign-->
+<!ENTITY nabla  "&#x2207;" ><!--/nabla =del, Hamilton operator-->
+<!ENTITY ne     "&#x2260;" ><!--/ne /neq R: =not equal-->
+<!ENTITY ni     "&#x220B;" ><!--/ni /owns R: =contains-->
+<!ENTITY or     "&#x2228;" ><!--/vee /lor B: =logical or-->
+<!ENTITY par    "&#x2225;" ><!--/parallel R: =parallel-->
+<!ENTITY part   "&#x2202;" ><!--/partial =partial differential-->
+<!ENTITY permil "&#x2030;" ><!--=per thousand-->
+<!ENTITY perp   "&#x22A5;" ><!--/perp R: =perpendicular-->
+<!ENTITY prime  "&#x2032;" ><!--/prime =prime or minute-->
+<!ENTITY Prime  "&#x2033;" ><!--=double prime or second-->
+<!ENTITY prop   "&#x221D;" ><!--/propto R: =is proportional to-->
+<!ENTITY radic  "&#x221A;" ><!--/surd =radical-->
+<!ENTITY rang   "&#x232A;" ><!--/rangle C: =right angle bracket-->
+<!ENTITY rArr   "&#x21D2;" ><!--/Rightarrow A: =implies-->
+<!ENTITY sim    "&#x223C;" ><!--/sim R: =similar-->
+<!ENTITY sime   "&#x2243;" ><!--/simeq R: =similar, equals-->
+<!ENTITY square "&#x25A1;" ><!--/square B: =square-->
+<!ENTITY sub    "&#x2282;" ><!--/subset R: =subset or is implied by-->
+<!ENTITY sube   "&#x2286;" ><!--/subseteq R: =subset, equals-->
+<!ENTITY sup    "&#x2283;" ><!--/supset R: =superset or implies-->
+<!ENTITY supe   "&#x2287;" ><!--/supseteq R: =superset, equals-->
+<!ENTITY there4 "&#x2234;" ><!--/therefore R: =therefore-->
+<!ENTITY Verbar "&#x2016;" ><!--/Vert =dbl vertical bar-->
+
+<!ENTITY angst  "&#x212B;" ><!--Angstrom =capital A, ring-->
+<!ENTITY bernou "&#x212C;" ><!--Bernoulli function (script capital B)-->
+<!ENTITY compfn "&#x2218;" ><!--B: composite function (small circle)-->
+<!ENTITY Dot    "&#xA8;" ><!--=dieresis or umlaut mark-->
+<!ENTITY DotDot "&#x20DC;" ><!--four dots above-->
+<!ENTITY hamilt "&#x210B;" ><!--Hamiltonian (script capital H)-->
+<!ENTITY lagran "&#x2112;" ><!--Lagrangian (script capital L)-->
+<!ENTITY lowast "&#x2217;" ><!--low asterisk-->
+<!ENTITY notin  "&#x2209;" ><!--N: negated set membership-->
+<!ENTITY order  "&#x2134;" ><!--order of (script small o)-->
+<!ENTITY phmmat "&#x2133;" ><!--physics M-matrix (script capital M)-->
+<!ENTITY tdot   "&#x20DB;" ><!--three dots above-->
+<!ENTITY tprime "&#x2034;" ><!--triple prime-->
+<!ENTITY wedgeq "&#x2259;" ><!--R: corresponds to (wedge, equals)-->
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/README.txt b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/README.txt
new file mode 100644
index 0000000..975201b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/README.txt
@@ -0,0 +1,4 @@
+See Apache Cocoon documentation
+"Entity resolution with catalogs" (catalog.html)
+
+Please keep these resources in sync with the authoritative stuff at Forrest.
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/XMLSchema.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/XMLSchema.dtd
new file mode 100644
index 0000000..2b2d234
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/XMLSchema.dtd
@@ -0,0 +1,395 @@
+<!-- DTD for XML Schemas: Part 1: Structures
+     Public Identifier: "-//W3C//DTD XMLSCHEMA 200010//EN"
+     Official Location: http://www.w3.org/2000/10/XMLSchema.dtd -->
+<!-- $Id: XMLSchema.dtd,v 1.1 2003/03/09 00:10:44 pier Exp $ -->
+<!-- Note this DTD is NOT normative, or even definitive. -->           <!--d-->
+<!-- prose copy in the structures REC is the definitive version -->    <!--d-->
+<!-- (which shouldn't differ from this one except for this -->         <!--d-->
+<!-- comment and entity expansions, but just in case) -->              <!--d-->
+<!-- With the exception of cases with multiple namespace
+     prefixes for the XML Schema namespace, any XML document which is
+     not valid per this DTD given redefinitions in its internal subset of the
+     'p' and 's' parameter entities below appropriate to its namespace
+     declaration of the XML Schema namespace is almost certainly not
+     a valid schema. -->
+
+<!-- The simpleType element and its constituent parts
+     are defined in XML Schema: Part 2: Datatypes -->
+<!ENTITY % xs-datatypes PUBLIC 'datatypes' 'datatypes.dtd' >
+
+<!ENTITY % p ''> <!-- can be overriden in the internal subset of a
+                      schema document to establish a namespace prefix -->
+<!ENTITY % s ''> <!-- if %p is defined (e.g. as foo:) then you must
+                      also define %s as the suffix for the appropriate
+                      namespace declaration (e.g. :foo) -->
+<!ENTITY % nds 'xmlns%s;'>
+
+<!-- Define all the element names, with optional prefix -->
+<!ENTITY % schema "%p;schema">
+<!ENTITY % complexType "%p;complexType">
+<!ENTITY % complexContent "%p;complexContent">
+<!ENTITY % simpleContent "%p;simpleContent">
+<!ENTITY % extension "%p;extension">
+<!ENTITY % element "%p;element">
+<!ENTITY % unique "%p;unique">
+<!ENTITY % key "%p;key">
+<!ENTITY % keyref "%p;keyref">
+<!ENTITY % selector "%p;selector">
+<!ENTITY % field "%p;field">
+<!ENTITY % group "%p;group">
+<!ENTITY % all "%p;all">
+<!ENTITY % choice "%p;choice">
+<!ENTITY % sequence "%p;sequence">
+<!ENTITY % any "%p;any">
+<!ENTITY % anyAttribute "%p;anyAttribute">
+<!ENTITY % attribute "%p;attribute">
+<!ENTITY % attributeGroup "%p;attributeGroup">
+<!ENTITY % include "%p;include">
+<!ENTITY % import "%p;import">
+<!ENTITY % redefine "%p;redefine">
+<!ENTITY % notation "%p;notation">
+
+<!-- annotation elements -->
+<!ENTITY % annotation "%p;annotation">
+<!ENTITY % appinfo "%p;appinfo">
+<!ENTITY % documentation "%p;documentation">
+
+<!-- Customisation entities for the ATTLIST of each element type.
+     Define one of these if your schema takes advantage of the
+     anyAttribute='##other' in the schema for schemas -->
+
+<!ENTITY % schemaAttrs ''>
+<!ENTITY % complexTypeAttrs ''>
+<!ENTITY % complexContentAttrs ''>
+<!ENTITY % simpleContentAttrs ''>
+<!ENTITY % extensionAttrs ''>
+<!ENTITY % elementAttrs ''>
+<!ENTITY % groupAttrs ''>
+<!ENTITY % allAttrs ''>
+<!ENTITY % choiceAttrs ''>
+<!ENTITY % sequenceAttrs ''>
+<!ENTITY % anyAttrs ''>
+<!ENTITY % anyAttributeAttrs ''>
+<!ENTITY % attributeAttrs ''>
+<!ENTITY % attributeGroupAttrs ''>
+<!ENTITY % uniqueAttrs ''>
+<!ENTITY % keyAttrs ''>
+<!ENTITY % keyrefAttrs ''>
+<!ENTITY % selectorAttrs ''>
+<!ENTITY % fieldAttrs ''>
+<!ENTITY % includeAttrs ''>
+<!ENTITY % importAttrs ''>
+<!ENTITY % redefineAttrs ''>
+<!ENTITY % notationAttrs ''>
+
+<!ENTITY % complexDerivationChoice "(extension|restriction)">
+<!ENTITY % complexDerivationSet "CDATA">
+      <!-- #all or space-separated list drawn from derivationChoice -->
+<!ENTITY % blockSet "CDATA">
+      <!-- #all or space-separated list drawn from
+                      derivationChoice + 'substitution' -->
+
+<!ENTITY % mgs '%all; | %choice; | %sequence;'>
+<!ENTITY % cs '%choice; | %sequence;'>
+<!ENTITY % formValues '(qualified|unqualified)'>
+
+
+<!ENTITY % attrDecls    '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
+
+<!ENTITY % particleAndAttrs '((%mgs; | %group;)?, %attrDecls;)'>
+
+<!-- This is used in part2 -->
+<!ENTITY % restriction1 '((%mgs; | %group;)?)'>
+
+%xs-datatypes;
+
+<!-- the duplication below is to produce an unambiguous content model
+     which allows annotation everywhere -->
+<!ELEMENT %schema; ((%include; | %import; | %redefine; | %annotation;)*,
+                    ((%simpleType; | %complexType;
+                      | %element; | %attribute;
+                      | %attributeGroup; | %group;
+                      | %notation; ),
+                     (%annotation;)*)* )>
+<!ATTLIST %schema;
+   targetNamespace      %URIref;               #IMPLIED
+   version              CDATA                  #IMPLIED
+   %nds;                %URIref;               #FIXED 'http://www.w3.org/2000/10/XMLSchema'
+   finalDefault         %complexDerivationSet; ''
+   blockDefault         %blockSet;             ''
+   id                   ID                     #IMPLIED
+   elementFormDefault   %formValues;           'unqualified'
+   attributeFormDefault %formValues;           'unqualified'
+   %schemaAttrs;>
+<!-- Note the xmlns declaration is NOT in the Schema for Schemas,
+     because at the Infoset level where schemas operate,
+     xmlns(:prefix) is NOT an attribute! -->
+ 
+<!-- The id attribute here and below is for use in external references
+     from non-schemas using simple fragment identifiers.
+     It is NOT used for schema-to-schema reference, internal or
+     external. -->
+
+<!-- a type is a named content type specification which allows attribute
+     declarations-->
+<!-- -->
+
+<!ELEMENT %complexType; ((%annotation;)?,
+                         (%simpleContent;|%complexContent;|
+                          %particleAndAttrs;))>
+
+<!ATTLIST %complexType;
+          name      %NCName;                        #IMPLIED
+          id        ID                              #IMPLIED
+          abstract  %boolean;                       'false'
+          final     %complexDerivationSet;          #IMPLIED
+          block     %complexDerivationSet;          ''
+          mixed (true|false) 'false'
+          %complexTypeAttrs;>
+
+<!-- particleAndAttrs is shorthand for a root type -->
+<!-- mixed is disallowed if simpleContent, overriden if complexContent
+     has one too. -->
+
+<!-- If anyAttribute appears in one or more referenced attributeGroups
+     and/or explicitly, the intersection of the permissions is used -->
+
+<!ELEMENT %complexContent; (%restriction;|%extension;)>
+<!ATTLIST %complexContent;
+          mixed (true|false) #IMPLIED
+          id    ID           #IMPLIED
+          %complexContentAttrs;>
+
+<!-- restriction should use the branch defined above, not the simple
+     one from part2; extension should use the full model  -->
+
+<!ELEMENT %simpleContent; (%restriction;|%extension;)>
+<!ATTLIST %simpleContent;
+          id    ID           #IMPLIED
+          %simpleContentAttrs;>
+
+<!-- restriction should use the simple branch from part2, not the 
+     one defined above; extension should have no particle  -->
+
+<!ELEMENT %extension; (%particleAndAttrs;)>
+<!ATTLIST %extension;
+          base  %QName;      #REQUIRED
+          id    ID           #IMPLIED
+          %extensionAttrs;>
+
+<!-- an element is declared by either:
+ a name and a type (either nested or referenced via the type attribute)
+ or a ref to an existing element declaration -->
+
+<!ELEMENT %element; ((%annotation;)?, (%complexType;| %simpleType;)?,
+                     (%unique; | %key; | %keyref;)*)>
+<!-- simpleType or complexType only if no type|ref attribute -->
+<!-- ref not allowed at top level -->
+<!ATTLIST %element;
+            name               %NCName;               #IMPLIED
+            id                 ID                     #IMPLIED
+            ref                %QName;                #IMPLIED
+            type               %QName;                #IMPLIED
+            minOccurs          %nonNegativeInteger;   #IMPLIED
+            maxOccurs          CDATA                  #IMPLIED
+            nullable           %boolean;              #IMPLIED
+            substitutionGroup  %QName;                #IMPLIED
+            abstract           %boolean;              'false'
+            final              %complexDerivationSet; #IMPLIED
+            block              %blockSet;             #IMPLIED
+            default            CDATA                  #IMPLIED
+            fixed              CDATA                  #IMPLIED
+            form               %formValues;           #IMPLIED
+            %elementAttrs;>
+<!-- type and ref are mutually exclusive.
+     name and ref are mutually exclusive, one is required -->
+<!-- In the absence of type AND ref, type defaults to type of
+     substitutionGroup, if any, else the ur-type, i.e. unconstrained -->
+<!-- default and fixed are mutually exclusive -->
+
+<!ELEMENT %group; ((%annotation;)?,(%mgs;)?)>
+<!ATTLIST %group; 
+          name        %NCName;               #IMPLIED
+          ref         %QName;                #IMPLIED
+          minOccurs   %nonNegativeInteger;   #IMPLIED
+          maxOccurs   CDATA                  #IMPLIED
+          id          ID                     #IMPLIED
+          %groupAttrs;>
+
+<!ELEMENT %all; ((%annotation;)?, (%element;)*)>
+<!ATTLIST %all;
+          minOccurs   (1)                    #FIXED '1'
+          maxOccurs   (1)                    #FIXED '1'
+          id          ID                     #IMPLIED
+          %allAttrs;>
+
+<!ELEMENT %choice; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
+<!ATTLIST %choice;
+          minOccurs   %nonNegativeInteger;   '1'
+          maxOccurs   CDATA                  '1'
+          id          ID                     #IMPLIED
+          %choiceAttrs;>
+
+<!ELEMENT %sequence; ((%annotation;)?, (%element;| %group;| %cs; | %any;)*)>
+<!ATTLIST %sequence;
+          minOccurs   %nonNegativeInteger;   '1'
+          maxOccurs   CDATA                  '1'
+          id          ID                     #IMPLIED
+          %sequenceAttrs;>
+
+<!-- an anonymous grouping in a model, or
+     a top-level named group definition, or a reference to same -->
+
+<!-- Note that if order is 'all', group is not allowed inside.
+     If order is 'all' THIS group must be alone (or referenced alone) at
+     the top level of a content model -->
+<!-- If order is 'all', minOccurs==maxOccurs==1 on element/any inside -->
+<!-- Should allow minOccurs=0 inside order='all' . . . -->
+
+<!ELEMENT %any; (%annotation;)?>
+<!ATTLIST %any;
+            namespace       CDATA                  '##any'
+            processContents (skip|lax|strict)      'strict'
+            minOccurs       %nonNegativeInteger;   '1'
+            maxOccurs       CDATA                  '1'
+            id              ID                     #IMPLIED
+            %anyAttrs;>
+
+<!-- namespace is interpreted as follows:
+                  ##any      - - any non-conflicting WFXML at all
+
+                  ##other    - - any non-conflicting WFXML from namespace other
+                                  than targetNamespace
+
+                  ##local    - - any unqualified non-conflicting WFXML/attribute
+                  one or     - - any non-conflicting WFXML from
+                  more URI        the listed namespaces
+                  references
+
+                  ##targetNamespace ##local may appear in the above list,
+                    with the obvious meaning -->
+
+<!ELEMENT %anyAttribute; (%annotation;)?>
+<!ATTLIST %anyAttribute;
+            namespace       CDATA              '##any'
+            processContents (skip|lax|strict)  'strict'
+            id              ID                 #IMPLIED
+            %anyAttributeAttrs;>
+<!-- namespace is interpreted as for 'any' above -->
+
+<!-- simpleType only if no type|ref attribute -->
+<!-- ref not allowed at top level, name iff at top level -->
+<!ELEMENT %attribute; ((%annotation;)?, (%simpleType;)?)>
+<!ATTLIST %attribute;
+          name      %NCName;      #IMPLIED
+          id        ID            #IMPLIED
+          ref       %QName;       #IMPLIED
+          type      %QName;       #IMPLIED
+          use       (prohibited|optional|required|fixed|default) #IMPLIED
+          value     CDATA         #IMPLIED
+          form      %formValues;  #IMPLIED
+          %attributeAttrs;>
+<!-- type and ref are mutually exclusive.
+     name and ref are mutually exclusive, one is required -->
+<!-- value only if use is fixed, required or default, or name -->
+<!-- name and use are mutually exclusive -->
+<!-- default for use is optional when nested, none otherwise -->
+<!-- type attr and simpleType content are mutually exclusive -->
+
+<!-- an attributeGroup is a named collection of attribute decls, or a
+     reference thereto -->
+<!ELEMENT %attributeGroup; ((%annotation;)?,
+                       (%attribute; | %attributeGroup;)*,
+                       (%anyAttribute;)?) >
+<!ATTLIST %attributeGroup;
+                 name       %NCName;       #IMPLIED
+                 id         ID             #IMPLIED
+                 ref        %QName;        #IMPLIED
+                 %attributeGroupAttrs;>
+
+<!-- ref iff no content, no name.  ref iff not top level -->
+
+<!-- better reference mechanisms -->
+<!ELEMENT %unique; ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %unique;
+          name     %NCName;       #REQUIRED
+	  id       ID             #IMPLIED
+	  %uniqueAttrs;>
+
+<!ELEMENT %key;    ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %key;
+          name     %NCName;       #REQUIRED
+	  id       ID             #IMPLIED
+	  %keyAttrs;>
+
+<!ELEMENT %keyref; ((%annotation;)?, %selector;, (%field;)+)>
+<!ATTLIST %keyref;
+          name     %NCName;       #REQUIRED
+	  refer    %QName;        #REQUIRED
+	  id       ID             #IMPLIED
+	  %keyrefAttrs;>
+
+<!ELEMENT %selector; ((%annotation;)?)>
+<!ATTLIST %selector;
+          xpath %XPathExpr; #REQUIRED
+          id    ID          #IMPLIED
+          %selectorAttrs;>
+<!ELEMENT %field; ((%annotation;)?)>
+<!ATTLIST %field;
+          xpath %XPathExpr; #REQUIRED
+          id    ID          #IMPLIED
+          %fieldAttrs;>
+
+<!-- Schema combination mechanisms -->
+<!ELEMENT %include; (%annotation;)?>
+<!ATTLIST %include;
+          schemaLocation %URIref; #REQUIRED
+          id             ID       #IMPLIED
+          %includeAttrs;>
+
+<!ELEMENT %import; (%annotation;)?>
+<!ATTLIST %import;
+          namespace      %URIref; #IMPLIED
+          schemaLocation %URIref; #IMPLIED
+          id             ID       #IMPLIED
+          %importAttrs;>
+
+<!ELEMENT %redefine; (%annotation; | %simpleType; | %complexType; |
+                      %attributeGroup; | %group;)*>
+<!ATTLIST %redefine;
+          schemaLocation %URIref; #REQUIRED
+          id             ID       #IMPLIED
+          %redefineAttrs;>
+
+<!ELEMENT %notation; (%annotation;)?>
+<!ATTLIST %notation;
+	  name        %NCName;    #REQUIRED
+	  id          ID          #IMPLIED
+	  public      CDATA       #REQUIRED
+	  system      %URIref;    #IMPLIED
+	  %notationAttrs;>
+
+<!-- Annotation is either application information or documentation -->
+<!-- By having these here they are available for datatypes as well
+     as all the structures elements -->
+
+<!ELEMENT %annotation; (%appinfo; | %documentation;)*>
+
+<!-- User must define annotation elements in internal subset for this
+     to work -->
+<!ELEMENT %appinfo; ANY>   <!-- too restrictive -->
+<!ATTLIST %appinfo;
+          source     %URIref;      #IMPLIED
+          id         ID         #IMPLIED
+          %appinfoAttrs;>
+<!ELEMENT %documentation; ANY>   <!-- too restrictive -->
+<!ATTLIST %documentation;
+          source     %URIref;   #IMPLIED
+          id         ID         #IMPLIED
+          xml:lang   CDATA      #IMPLIED
+          %documentationAttrs;>
+
+<!NOTATION XMLSchemaStructures PUBLIC
+           'structures' 'http://www.w3.org/2000/10/XMLSchema.xsd' >
+<!NOTATION XML PUBLIC
+           'REC-xml-1998-0210' 'http://www.w3.org/TR/1998/REC-xml-19980210' >
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/any.rng b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/any.rng
new file mode 100644
index 0000000..bc5e4fd
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/any.rng
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+A RELAX NG schema that matches the (ANY) content type. Useful for prototyping,
+where you don't (yet) care what an element contains. Include it in another RNG
+schema with this line:
+
+<include href="any.rng"/>
+
+Taken from an email to XML-DEV by John Cowan, Subject "Re: [xml-dev] Quick
+RelaxNG question"
+
+$Revision: 1.1 $ $Date: 2003/03/09 00:10:45 $
+-->
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+  <start>
+    <element>
+      <anyName/>
+      <ref name="ANY"/>
+    </element>
+  </start>
+  <define name="ANY">
+    <interleave>
+      <zeroOrMore>
+        <attribute>
+          <anyName/>
+          <text/>
+        </attribute>
+      </zeroOrMore>
+      <zeroOrMore>
+        <element>
+          <anyName/>
+          <ref name="ANY"/>
+        </element>
+      </zeroOrMore>
+      <text/>
+    </interleave>
+  </define>
+</grammar>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-cocoon-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-cocoon-v10.dtd
new file mode 100644
index 0000000..08ee02e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-cocoon-v10.dtd
@@ -0,0 +1,74 @@
+<!--
+  Copyright 2001-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+     
+     Apache Cocoon Documentation Book DTD (Version 1.0)
+
+PURPOSE:
+This DTD defines the */book.xml documentation configuration files.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE book PUBLIC
+       "-//APACHE//DTD Cocoon Documentation Book Vx.yz//EN"
+       "book-cocoon-vxyz.dtd">
+
+  where 
+  
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+      
+NOTES:
+We need to replace this DTD with the proper one.
+We are only using this DTD to enable validation during "build docs"
+because every XML instance must declare its ruleset.
+
+This initial minimal DTD has been reverse-engineered from the structure
+of the current documents, e.g. 
+ documentation/xdocs/book.xml
+  
+FIXME:
+  - find the proper DTD for book.xml
+
+CHANGE HISTORY:
+  20011031 Initial version. (DC)
+    
+==================================================================== -->
+
+<!ELEMENT book (menu+)> 
+<!ELEMENT menu (menu-item|external)*>
+<!ELEMENT menu-item EMPTY>
+<!ELEMENT external EMPTY>
+<!ATTLIST book software CDATA #REQUIRED
+               title CDATA #REQUIRED
+               copyright CDATA #REQUIRED
+               xmlns:xlink CDATA #IMPLIED
+>
+<!ATTLIST menu label CDATA #REQUIRED
+>
+<!ATTLIST menu-item label CDATA #REQUIRED
+                    href CDATA #REQUIRED
+                    type (visible|hidden) "visible"
+>
+<!ATTLIST external  label CDATA #REQUIRED
+                    href CDATA #REQUIRED
+                    type (visible|hidden) "visible"
+>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-v01.rng b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-v01.rng
new file mode 100644
index 0000000..1e7dd77
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/book-v01.rng
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+         xmlns="http://relaxng.org/ns/structure/1.0"
+         xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0">
+<!-- ===================================================================
+
+     Apache Cocoon Book RELAX NG grammar (Version 0.1)
+
+PURPOSE:
+  DRAFT RELAX NG grammar for the Cocoon book.xml configuration files.
+
+NOTES:
+
+FIXME:
+- 
+
+CHANGE HISTORY:
+20021030 V0.1 Initial RELAX NG grammar generated from book-cocoon-v10.dtd
+              using DTDinst (DC)
+     
+==================================================================== -->
+  <define name="book">
+    <element name="book">
+      <ref name="attlist.book"/>
+      <oneOrMore>
+        <ref name="menu"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="menu">
+    <element name="menu">
+      <ref name="attlist.menu"/>
+      <zeroOrMore>
+        <choice>
+          <ref name="menu-item"/>
+          <ref name="external"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="menu-item">
+    <element name="menu-item">
+      <ref name="attlist.menu-item"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="external">
+    <element name="external">
+      <ref name="attlist.external"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="attlist.book" combine="interleave">
+    <attribute name="software"/>
+    <attribute name="title"/>
+    <attribute name="copyright"/>
+    <empty/>
+  </define>
+  <define name="attlist.menu" combine="interleave">
+    <attribute name="label"/>
+  </define>
+  <define name="attlist.menu-item" combine="interleave">
+    <attribute name="label"/>
+    <attribute name="href"/>
+    <optional>
+      <attribute name="type" a:defaultValue="visible">
+        <choice>
+          <value>visible</value>
+          <value>hidden</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
+  <define name="attlist.external" combine="interleave">
+    <attribute name="label"/>
+    <attribute name="href"/>
+    <optional>
+      <attribute name="type" a:defaultValue="visible">
+        <choice>
+          <value>visible</value>
+          <value>hidden</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
+  <start>
+    <choice>
+      <ref name="book"/>
+    </choice>
+  </start>
+</grammar>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog
new file mode 100644
index 0000000..a7a93ec
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog
@@ -0,0 +1,91 @@
+--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+--
+
+-- this is the default OASIS catalog for Apache Cocoon --
+
+OVERRIDE YES
+
+-- ISO public identifiers for sets of character entities --
+PUBLIC "ISO 8879-1986//ENTITIES Added Latin 1//EN//XML"
+       "ISOlat1.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+       "ISOlat1.pen"
+PUBLIC "ISO 9573-15:1993//ENTITIES Greek Letters//EN//XML"
+       "ISOgrk1.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Publishing//EN//XML"
+       "ISOpub.pen"
+PUBLIC "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+       "ISOtech.pen"
+PUBLIC "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+       "ISOnum.pen"
+
+-- W3C Document Type Definitions --
+CATALOG "w3c/catalog"
+
+-- Web Application Definitions --
+PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" 
+       "web-app_2_3.dtd" -- Note the deliberate avoidance of license issues --
+PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+       "web-app_2_3.dtd"
+
+-- Document Type Definitions --
+PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
+       "document-v10.dtd"
+PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
+       "document-v11.dtd"
+PUBLIC "-//APACHE//DTD Documentation V1.2//EN"
+       "document-v12.dtd"
+PUBLIC "-//APACHE//DTD Changes V1.0//EN"
+       "changes-v10.dtd"
+PUBLIC "-//APACHE//DTD FAQ V1.0//EN"
+       "faq-v10.dtd"
+PUBLIC "-//APACHE//DTD JavaDoc V1.0//EN"
+       "javadoc-v04draft.dtd"
+PUBLIC "-//APACHE//DTD Specification V1.0//EN"
+       "specification-v10.dtd"
+PUBLIC "-//APACHE//DTD Todo V1.0//EN"
+       "todo-v10.dtd"
+PUBLIC "-//APACHE//DTD Cocoon Sitemap V0.4//EN"
+       "sitemap-v04.dtd"
+
+-- enabling validation during Cocoon's own "build docs" --
+--   all *.xml require DTD for validation during "build docs" --
+PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN"
+       "book-cocoon-v10.dtd"
+
+-- other DTDs that are yet without a Public Identifier --
+-- XMLSchema.dtd .. what is its purpose ? --
+
+-- Character entity set that is referenced by some DTDs --
+-- characters.ent --
+-- ... has no public identifier --
+-- should be OK because it will be resolved relative to the DTD --
+-- ... perhaps the DTD should use the ISO*.pen sets instead? --
+
+-- these entries are used for the catalog-demo sample application --
+OVERRIDE NO
+PUBLIC "-//Arbortext//TEXT Test Override//EN"
+       "catalog-demo/override.txt"
+OVERRIDE YES
+PUBLIC "-//Arbortext//TEXT Test Public Identifier//EN"
+       "catalog-demo/testpub.txt"
+SYSTEM "urn:x-arbortext:test-system-identifier"
+       "catalog-demo/testsys.txt"
+PUBLIC "-//Indexgeo//DTD Catalog Demo v1.0//EN"
+       "catalog-demo/catalog-demo-v10.dtd"
+-- end of entries for the catalog-demo sample application --
+
+PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "open-office/dummy.dtd"
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/catalog-demo-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/catalog-demo-v10.dtd
new file mode 100644
index 0000000..11b7006
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/catalog-demo-v10.dtd
@@ -0,0 +1,27 @@
+<!--
+  Copyright 2001-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--
+This is the Document Type Definition for the Apache Cocoon sample
+demonstration "catalog-demo" which explains entity resolution
+using catalogs. See the Apache Cocoon documentation
+"Entity resolution with catalogs" (catalog.html).
+-->
+
+<!ELEMENT catalog-demo (section+)>
+<!ELEMENT link (#PCDATA)>
+<!ATTLIST link href CDATA #IMPLIED>
+<!ELEMENT para (#PCDATA | link)*>
+<!ELEMENT section (para+)>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/override.txt b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/override.txt
new file mode 100644
index 0000000..79a420f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/override.txt
@@ -0,0 +1,3 @@
+This is content from the override.txt external file.
+This content will not actually be included, because the catalog
+was set with OVERRIDE NO for this public identifier.
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testpub.txt b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testpub.txt
new file mode 100644
index 0000000..b476a1a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testpub.txt
@@ -0,0 +1,6 @@
+This paragraph is automatically included from the
+testpub.txt external file.
+The entity declaration deliberately used a non-existent file
+as the system identifier. The catalog then used the declared
+public identifer to resolve to a specific location on the local
+filesystem.
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testsys.txt b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testsys.txt
new file mode 100644
index 0000000..788fc42
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog-demo/testsys.txt
@@ -0,0 +1,4 @@
+This paragraph is automatically included from the
+testsys.txt external file.
+The declared SYSTEM identifier was resolved by the catalog to a
+specific location on the local filesystem.
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog.xcat b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog.xcat
new file mode 100644
index 0000000..48ac210
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/catalog.xcat
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--
+<!DOCTYPE catalog PUBLIC "-//OASIS//DTD XML Catalogs V1.0//EN"
+  "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+-->
+<!-- OASIS XML Catalog for Cocoon -->
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+
+<!-- FIXME: This xmlcatalog is still under development. See FIXME notes below.
+  The authoratitive catalog is the plain-text (TR 9401) version
+  at ./catalog
+-->
+
+<!-- FIXME: how to override
+OVERRIDE YES
+-->
+
+<!-- ISO public identifiers for sets of character entities -->
+<public publicId="ISO 8879-1986//ENTITIES Added Latin 1//EN//XML"
+        uri="ISOlat1.pen"/>
+<public publicId="ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+        uri="ISOlat1.pen"/>
+<public publicId="ISO 9573-15:1993//ENTITIES Greek Letters//EN//XML"
+        uri="ISOgrk1.pen"/>
+<public publicId="ISO 8879:1986//ENTITIES Publishing//EN//XML"
+        uri="ISOpub.pen"/>
+<public publicId="ISO 8879:1986//ENTITIES General Technical//EN//XML"
+        uri="ISOtech.pen"/>
+<public publicId="ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+        uri="ISOnum.pen"/>
+
+<!-- W3C Document Type Definitions -->
+<!-- FIXME: how to link to other catalogs
+CATALOG "w3c/catalog"
+-->
+
+<!-- Document Type Definitions -->
+<public publicId="-//APACHE//DTD Documentation V1.0//EN"
+        uri="document-v10.dtd"/>
+<public publicId="-//APACHE//DTD Documentation V1.1//EN"
+        uri="document-v11.dtd"/>
+<public publicId="-//APACHE//DTD Documentation V1.2//EN"
+        uri="document-v12.dtd"/>
+<public publicId="-//APACHE//DTD Changes V1.0//EN"
+        uri="changes-v10.dtd"/>
+<public publicId="-//APACHE//DTD FAQ V1.0//EN"
+        uri="faq-v10.dtd"/>
+<public publicId="-//APACHE//DTD JavaDoc V1.0//EN"
+        uri="javadoc-v04draft.dtd"/>
+<public publicId="-//APACHE//DTD Specification V1.0//EN"
+        uri="specification-v10.dtd"/>
+<public publicId="-//APACHE//DTD Todo V1.0//EN"
+        uri="todo-v10.dtd"/>
+<public publicId="-//APACHE//DTD Cocoon Documentation Book V1.0//EN"
+        uri="book-cocoon-v10.dtd"/>
+
+<!-- these entries are used for the catalog-demo sample application -->
+<!-- FIXME: how to override
+OVERRIDE NO
+-->
+<public publicId="-//Arbortext//TEXT Test Override//EN"
+        uri="catalog-demo/override.txt"/>
+<!-- FIXME: how to override
+OVERRIDE YES
+-->
+<public publicId="-//Arbortext//TEXT Test Public Identifier//EN"
+        uri="catalog-demo/testpub.txt"/>
+<system systemId="urn:x-arbortext:test-system-identifier"
+        uri="catalog-demo/testsys.txt"/>
+<public publicId="-//Indexgeo//DTD Catalog Demo v1.0//EN"
+        uri="catalog-demo/catalog-demo-v10.dtd"/>
+<!-- end of entries for the catalog-demo sample application -->
+</catalog>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/changes-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/changes-v10.dtd
new file mode 100644
index 0000000..eed1208
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/changes-v10.dtd
@@ -0,0 +1,95 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Changes DTD (Version 1.0)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software development changes for use with the Apache projects.
+  It is an XML-compliant DTD and it's maintained by the Apache XML
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Changes Vx.yz//EN"
+       "http://xml.apache.org/DTD/changes-vxyz.dtd">
+
+  where
+
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+
+NOTES:
+  It is important, expecially in open developped software projects, to keep
+  track of software changes both to give users indications of bugs that might
+  have been resolved, as well, and not less important, to provide credits
+  for the support given to the project. It is considered vital to provide
+  adequate payback using recognition and credits to let users and developers
+  feel part of the community, thus increasing development power.
+
+FIXME:
+
+CHANGE HISTORY:
+  19991129 Initial version. (SM)
+  20000316 Added bugfixing attribute. (SM)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Extend the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!-- FIXME (SM): this is hardcoding. Find a better way of doing this
+     possibly using public identifiers -->
+<!ENTITY % document-dtd SYSTEM "document-v10.dtd">
+%document-dtd;
+
+<!-- =============================================================== -->
+<!-- Common entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % types "add|remove|update|fix">
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT changes (devs, release*)>
+<!ATTLIST changes %common.att;
+                  %title.att;>
+
+    <!ELEMENT devs (person+)>
+    <!ATTLIST devs %common.att;>
+
+    <!ELEMENT release (action+)>
+    <!ATTLIST release %common.att;
+                      version  CDATA  #REQUIRED
+                      date     CDATA  #REQUIRED>
+
+        <!ELEMENT action (%content.mix;)*>
+        <!ATTLIST action %common.att;
+                         dev  IDREF  #REQUIRED
+                         type (%types;)  #IMPLIED
+                         due-to CDATA #IMPLIED
+                         due-to-email CDATA #IMPLIED
+                         fixes-bug CDATA #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/characters.ent b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/characters.ent
new file mode 100644
index 0000000..8ff5024
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/characters.ent
@@ -0,0 +1,290 @@
+<!-- 
+     Portions (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- 
+     Character entity set.
+-->
+
+<!-- Latin A -->
+<!ENTITY nbsp     "&#160;">  <!-- U+00A0 ISOnum    - no-break space = non-breaking space                                   -->
+<!ENTITY iexcl    "&#161;">  <!-- U+00A1 ISOnum    - inverted exclamation mark                                             -->
+<!ENTITY cent     "&#162;">  <!-- U+00A2 ISOnum    - cent sign                                                             -->
+<!ENTITY pound    "&#163;">  <!-- U+00A3 ISOnum    - pound sign                                                            -->
+<!ENTITY curren   "&#164;">  <!-- U+00A4 ISOnum    - currency sign                                                         -->
+<!ENTITY yen      "&#165;">  <!-- U+00A5 ISOnum    - yen sign = yuan sign                                                  -->
+<!ENTITY brvbar   "&#166;">  <!-- U+00A6 ISOnum    - broken bar = broken vertical bar                                      -->
+<!ENTITY sect     "&#167;">  <!-- U+00A7 ISOnum    - section sign                                                          -->
+<!ENTITY uml      "&#168;">  <!-- U+00A8 ISOdia    - diaeresis = spacing diaeresis                                         -->
+<!ENTITY copy     "&#169;">  <!-- U+00A9 ISOnum    - copyright sign                                                        -->
+<!ENTITY ordf     "&#170;">  <!-- U+00AA ISOnum    - feminine ordinal indicator                                            -->
+<!ENTITY laquo    "&#171;">  <!-- U+00AB ISOnum    - left-pointing double angle quotation mark = left pointing guillemet   -->
+<!ENTITY not      "&#172;">  <!-- U+00AC ISOnum    - not sign                                                              -->
+<!ENTITY shy      "&#173;">  <!-- U+00AD ISOnum    - soft hyphen = discretionary hyphen                                    -->
+<!ENTITY reg      "&#174;">  <!-- U+00AE ISOnum    - registered sign = registered trade mark sign                          -->
+<!ENTITY macr     "&#175;">  <!-- U+00AF ISOdia    - macron = spacing macron = overline = APL overbar                      -->
+<!ENTITY deg      "&#176;">  <!-- U+00B0 ISOnum    - degree sign                                                           -->
+<!ENTITY plusmn   "&#177;">  <!-- U+00B1 ISOnum    - plus-minus sign = plus-or-minus sign                                  -->
+<!ENTITY sup2     "&#178;">  <!-- U+00B2 ISOnum    - superscript two = superscript digit two = squared                     -->
+<!ENTITY sup3     "&#179;">  <!-- U+00B3 ISOnum    - superscript three = superscript digit three = cubed                   -->
+<!ENTITY acute    "&#180;">  <!-- U+00B4 ISOdia    - acute accent = spacing acute                                          -->
+<!ENTITY micro    "&#181;">  <!-- U+00B5 ISOnum    - micro sign                                                            -->
+<!ENTITY para     "&#182;">  <!-- U+00B6 ISOnum    - pilcrow sign = paragraph sign                                         -->
+<!ENTITY middot   "&#183;">  <!-- U+00B7 ISOnum    - middle dot = Georgian comma = Greek middle dot                        -->
+<!ENTITY cedil    "&#184;">  <!-- U+00B8 ISOdia    - cedilla = spacing cedilla                                             -->
+<!ENTITY sup1     "&#185;">  <!-- U+00B9 ISOnum    - superscript one = superscript digit one                               -->
+<!ENTITY ordm     "&#186;">  <!-- U+00BA ISOnum    - masculine ordinal indicator                                           -->
+<!ENTITY raquo    "&#187;">  <!-- U+00BB ISOnum    - right-pointing double angle quotation mark = right pointing guillemet -->
+<!ENTITY frac14   "&#188;">  <!-- U+00BC ISOnum    - vulgar fraction one quarter = fraction one quarter                    -->
+<!ENTITY frac12   "&#189;">  <!-- U+00BD ISOnum    - vulgar fraction one half = fraction one half                          -->
+<!ENTITY frac34   "&#190;">  <!-- U+00BE ISOnum    - vulgar fraction three quarters = fraction three quarters              -->
+<!ENTITY iquest   "&#191;">  <!-- U+00BF ISOnum    - inverted question mark = turned question mark                         -->
+<!ENTITY Agrave   "&#192;">  <!-- U+00C0 ISOlat1   - latin capital letter A with grave = latin capital letter A grave      -->
+<!ENTITY Aacute   "&#193;">  <!-- U+00C1 ISOlat1   - latin capital letter A with acute                                     -->
+<!ENTITY Acirc    "&#194;">  <!-- U+00C2 ISOlat1   - latin capital letter A with circumflex                                -->
+<!ENTITY Atilde   "&#195;">  <!-- U+00C3 ISOlat1   - latin capital letter A with tilde                                     -->
+<!ENTITY Auml     "&#196;">  <!-- U+00C4 ISOlat1   - latin capital letter A with diaeresis                                 -->
+<!ENTITY Aring    "&#197;">  <!-- U+00C5 ISOlat1   - latin capital letter A with ring above = latin capital letter A ring  -->
+<!ENTITY AElig    "&#198;">  <!-- U+00C6 ISOlat1   - latin capital letter AE = latin capital ligature AE                   -->
+<!ENTITY Ccedil   "&#199;">  <!-- U+00C7 ISOlat1   - latin capital letter C with cedilla                                   -->
+<!ENTITY Egrave   "&#200;">  <!-- U+00C8 ISOlat1   - latin capital letter E with grave                                     -->
+<!ENTITY Eacute   "&#201;">  <!-- U+00C9 ISOlat1   - latin capital letter E with acute                                     -->
+<!ENTITY Ecirc    "&#202;">  <!-- U+00CA ISOlat1   - latin capital letter E with circumflex                                -->
+<!ENTITY Euml     "&#203;">  <!-- U+00CB ISOlat1   - latin capital letter E with diaeresis                                 -->
+<!ENTITY Igrave   "&#204;">  <!-- U+00CC ISOlat1   - latin capital letter I with grave                                     -->
+<!ENTITY Iacute   "&#205;">  <!-- U+00CD ISOlat1   - latin capital letter I with acute                                     -->
+<!ENTITY Icirc    "&#206;">  <!-- U+00CE ISOlat1   - latin capital letter I with circumflex                                -->
+<!ENTITY Iuml     "&#207;">  <!-- U+00CF ISOlat1   - latin capital letter I with diaeresis                                 -->
+<!ENTITY ETH      "&#208;">  <!-- U+00D0 ISOlat1   - latin capital letter ETH                                              -->
+<!ENTITY Ntilde   "&#209;">  <!-- U+00D1 ISOlat1   - latin capital letter N with tilde                                     -->
+<!ENTITY Ograve   "&#210;">  <!-- U+00D2 ISOlat1   - latin capital letter O with grave                                     -->
+<!ENTITY Oacute   "&#211;">  <!-- U+00D3 ISOlat1   - latin capital letter O with acute                                     -->
+<!ENTITY Ocirc    "&#212;">  <!-- U+00D4 ISOlat1   - latin capital letter O with circumflex                                -->
+<!ENTITY Otilde   "&#213;">  <!-- U+00D5 ISOlat1   - latin capital letter O with tilde                                     -->
+<!ENTITY Ouml     "&#214;">  <!-- U+00D6 ISOlat1   - latin capital letter O with diaeresis                                 -->
+<!ENTITY times    "&#215;">  <!-- U+00D7 ISOnum    - multiplication sign                                                   -->
+<!ENTITY Oslash   "&#216;">  <!-- U+00D8 ISOlat1   - latin capital letter O with stroke = latin capital letter O slash     -->
+<!ENTITY Ugrave   "&#217;">  <!-- U+00D9 ISOlat1   - latin capital letter U with grave                                     -->
+<!ENTITY Uacute   "&#218;">  <!-- U+00DA ISOlat1   - latin capital letter U with acute                                     -->
+<!ENTITY Ucirc    "&#219;">  <!-- U+00DB ISOlat1   - latin capital letter U with circumflex                                -->
+<!ENTITY Uuml     "&#220;">  <!-- U+00DC ISOlat1   - latin capital letter U with diaeresis                                 -->
+<!ENTITY Yacute   "&#221;">  <!-- U+00DD ISOlat1   - latin capital letter Y with acute                                     -->
+<!ENTITY THORN    "&#222;">  <!-- U+00DE ISOlat1   - latin capital letter THORN                                            -->
+<!ENTITY szlig    "&#223;">  <!-- U+00DF ISOlat1   - latin small letter sharp s = ess-zed                                  -->
+<!ENTITY agrave   "&#224;">  <!-- U+00E0 ISOlat1   - latin small letter a with grave = latin small letter a grave          -->
+<!ENTITY aacute   "&#225;">  <!-- U+00E1 ISOlat1   - latin small letter a with acute                                       -->
+<!ENTITY acirc    "&#226;">  <!-- U+00E2 ISOlat1   - latin small letter a with circumflex                                  -->
+<!ENTITY atilde   "&#227;">  <!-- U+00E3 ISOlat1   - latin small letter a with tilde                                       -->
+<!ENTITY auml     "&#228;">  <!-- U+00E4 ISOlat1   - latin small letter a with diaeresis                                   -->
+<!ENTITY aring    "&#229;">  <!-- U+00E5 ISOlat1   - latin small letter a with ring above = latin small letter a ring      -->
+<!ENTITY aelig    "&#230;">  <!-- U+00E6 ISOlat1   - latin small letter ae = latin small ligature ae                       -->
+<!ENTITY ccedil   "&#231;">  <!-- U+00E7 ISOlat1   - latin small letter c with cedilla                                     -->
+<!ENTITY egrave   "&#232;">  <!-- U+00E8 ISOlat1   - latin small letter e with grave                                       -->
+<!ENTITY eacute   "&#233;">  <!-- U+00E9 ISOlat1   - latin small letter e with acute                                       -->
+<!ENTITY ecirc    "&#234;">  <!-- U+00EA ISOlat1   - latin small letter e with circumflex                                  -->
+<!ENTITY euml     "&#235;">  <!-- U+00EB ISOlat1   - latin small letter e with diaeresis                                   -->
+<!ENTITY igrave   "&#236;">  <!-- U+00EC ISOlat1   - latin small letter i with grave                                       -->
+<!ENTITY iacute   "&#237;">  <!-- U+00ED ISOlat1   - latin small letter i with acute                                       -->
+<!ENTITY icirc    "&#238;">  <!-- U+00EE ISOlat1   - latin small letter i with circumflex                                  -->
+<!ENTITY iuml     "&#239;">  <!-- U+00EF ISOlat1   - latin small letter i with diaeresis                                   -->
+<!ENTITY eth      "&#240;">  <!-- U+00F0 ISOlat1   - latin small letter eth                                                -->
+<!ENTITY ntilde   "&#241;">  <!-- U+00F1 ISOlat1   - latin small letter n with tilde                                       -->
+<!ENTITY ograve   "&#242;">  <!-- U+00F2 ISOlat1   - latin small letter o with grave                                       -->
+<!ENTITY oacute   "&#243;">  <!-- U+00F3 ISOlat1   - latin small letter o with acute                                       -->
+<!ENTITY ocirc    "&#244;">  <!-- U+00F4 ISOlat1   - latin small letter o with circumflex                                  -->
+<!ENTITY otilde   "&#245;">  <!-- U+00F5 ISOlat1   - latin small letter o with tilde                                       -->
+<!ENTITY ouml     "&#246;">  <!-- U+00F6 ISOlat1   - latin small letter o with diaeresis                                   -->
+<!ENTITY divide   "&#247;">  <!-- U+00F7 ISOnum    - division sign                                                         -->
+<!ENTITY oslash   "&#248;">  <!-- U+00F8 ISOlat1   - latin small letter o with stroke = latin small letter o slash         -->
+<!ENTITY ugrave   "&#249;">  <!-- U+00F9 ISOlat1   - latin small letter u with grave                                       -->
+<!ENTITY uacute   "&#250;">  <!-- U+00FA ISOlat1   - latin small letter u with acute                                       -->
+<!ENTITY ucirc    "&#251;">  <!-- U+00FB ISOlat1   - latin small letter u with circumflex                                  -->
+<!ENTITY uuml     "&#252;">  <!-- U+00FC ISOlat1   - latin small letter u with diaeresis                                   -->
+<!ENTITY yacute   "&#253;">  <!-- U+00FD ISOlat1   - latin small letter y with acute                                       -->
+<!ENTITY thorn    "&#254;">  <!-- U+00FE ISOlat1   - latin small letter thorn                                              -->
+<!ENTITY yuml     "&#255;">  <!-- U+00FF ISOlat1   - latin small letter y with diaeresis                                   -->
+
+<!-- Latin Extended-A -->
+<!ENTITY OElig    "&#338;">  <!-- U+0152 ISOlat2   - latin capital ligature OE                                             -->
+<!ENTITY oelig    "&#339;">  <!-- U+0153 ISOlat2   - latin small ligature oe                                               -->
+
+<!-- ligature is a misnomer, this is a separate character in some languages -->
+<!ENTITY Scaron   "&#352;">  <!-- U+0160 ISOlat2   - latin capital letter S with caron                                     -->
+<!ENTITY scaron   "&#353;">  <!-- U+0161 ISOlat2   - latin small letter s with caron                                       -->
+<!ENTITY Yuml     "&#376;">  <!-- U+0178 ISOlat2   - latin capital letter Y with diaeresis                                 -->
+
+<!-- Spacing Modifier Letters -->
+<!ENTITY circ     "&#710;">  <!-- U+02C6 ISOpub    - modifier letter circumflex accent                                     -->
+<!ENTITY tilde    "&#732;">  <!-- U+02DC ISOdia    - small tilde                                                           -->
+
+<!-- General Punctuation -->
+<!ENTITY ensp     "&#8194;"> <!-- U+2002 ISOpub    - en space                                                              -->
+<!ENTITY emsp     "&#8195;"> <!-- U+2003 ISOpub    - em space                                                              -->
+<!ENTITY thinsp   "&#8201;"> <!-- U+2009 ISOpub    - thin space                                                            -->
+<!ENTITY zwnj     "&#8204;"> <!-- U+200C RFC 2070  - zero width non-joiner                                                 -->
+<!ENTITY zwj      "&#8205;"> <!-- U+200D RFC 2070  - zero width joiner                                                     -->
+<!ENTITY lrm      "&#8206;"> <!-- U+200E RFC 2070  - left-to-right mark                                                    -->
+<!ENTITY rlm      "&#8207;"> <!-- U+200F RFC 2070  - right-to-left mark                                                    -->
+<!ENTITY ndash    "&#8211;"> <!-- U+2013 ISOpub    - en dash                                                               -->
+<!ENTITY mdash    "&#8212;"> <!-- U+2014 ISOpub    - em dash                                                               -->
+<!ENTITY lsquo    "&#8216;"> <!-- U+2018 ISOnum    - left single quotation mark                                            -->
+<!ENTITY rsquo    "&#8217;"> <!-- U+2019 ISOnum    - right single quotation mark                                           -->
+<!ENTITY sbquo    "&#8218;"> <!-- U+201A NEW       - single low-9 quotation mark                                           -->
+<!ENTITY ldquo    "&#8220;"> <!-- U+201C ISOnum    - left double quotation mark                                            -->
+<!ENTITY rdquo    "&#8221;"> <!-- U+201D ISOnum    - right double quotation mark,                                          -->
+<!ENTITY bdquo    "&#8222;"> <!-- U+201E NEW       - double low-9 quotation mark                                           -->
+<!ENTITY dagger   "&#8224;"> <!-- U+2020 ISOpub    - dagger                                                                -->
+<!ENTITY Dagger   "&#8225;"> <!-- U+2021 ISOpub    - double dagger                                                         -->
+<!ENTITY permil   "&#8240;"> <!-- U+2030 ISOtech   - per mille sign                                                        -->
+<!ENTITY lsaquo   "&#8249;"> <!-- U+2039 ISO prop. - single left-pointing angle quotation mark                             -->
+
+<!-- lsaquo is proposed but not yet ISO standardized -->
+<!ENTITY rsaquo   "&#8250;"> <!-- U+203A ISO prop. -   single right-pointing angle quotation mark                          -->
+
+<!-- rsaquo is proposed but not yet ISO standardized -->
+<!ENTITY euro     "&#8364;"> <!-- U+20AC NEW       -   euro sign                                                           -->
+
+<!-- Latin Extended-B -->
+<!ENTITY fnof     "&#402;">  <!-- U+0192 ISOtech   - latin small f with hook = function = florin                           -->
+
+<!-- Greek -->
+<!ENTITY Alpha    "&#913;">  <!-- U+0391           - greek capital letter alpha                                            -->
+<!ENTITY Beta     "&#914;">  <!-- U+0392           - greek capital letter beta                                             -->
+<!ENTITY Gamma    "&#915;">  <!-- U+0393 ISOgrk3   - greek capital letter gamma                                            -->
+<!ENTITY Delta    "&#916;">  <!-- U+0394 ISOgrk3   - greek capital letter delta                                            -->
+<!ENTITY Epsilon  "&#917;">  <!-- U+0395           - greek capital letter epsilon                                          -->
+<!ENTITY Zeta     "&#918;">  <!-- U+0396           - greek capital letter zeta                                             -->
+<!ENTITY Eta      "&#919;">  <!-- U+0397           - greek capital letter eta                                              -->
+<!ENTITY Theta    "&#920;">  <!-- U+0398 ISOgrk3   - greek capital letter theta                                            -->
+<!ENTITY Iota     "&#921;">  <!-- U+0399           - greek capital letter iota                                             -->
+<!ENTITY Kappa    "&#922;">  <!-- U+039A           - greek capital letter kappa                                            -->
+<!ENTITY Lambda   "&#923;">  <!-- U+039B ISOgrk3   - greek capital letter lambda                                           -->
+<!ENTITY Mu       "&#924;">  <!-- U+039C           - greek capital letter mu                                               -->
+<!ENTITY Nu       "&#925;">  <!-- U+039D           - greek capital letter nu                                               -->
+<!ENTITY Xi       "&#926;">  <!-- U+039E ISOgrk3   - greek capital letter xi                                               -->
+<!ENTITY Omicron  "&#927;">  <!-- U+039F           - greek capital letter omicron                                          -->
+<!ENTITY Pi       "&#928;">  <!-- U+03A0 ISOgrk3   - greek capital letter pi                                               -->
+<!ENTITY Rho      "&#929;">  <!-- U+03A1           - greek capital letter rho                                              -->
+<!ENTITY Sigma    "&#931;">  <!-- U+03A3 ISOgrk3   - greek capital letter sigma                                            -->
+<!ENTITY Tau      "&#932;">  <!-- U+03A4           - greek capital letter tau                                              -->
+<!ENTITY Upsilon  "&#933;">  <!-- U+03A5 ISOgrk3   - greek capital letter upsilon                                          -->
+<!ENTITY Phi      "&#934;">  <!-- U+03A6 ISOgrk3   - greek capital letter phi                                              -->
+<!ENTITY Chi      "&#935;">  <!-- U+03A7           - greek capital letter chi                                              -->
+<!ENTITY Psi      "&#936;">  <!-- U+03A8 ISOgrk3   - greek capital letter psi                                              -->
+<!ENTITY Omega    "&#937;">  <!-- U+03A9 ISOgrk3   - greek capital letter omega                                            -->
+<!ENTITY alpha    "&#945;">  <!-- U+03B1 ISOgrk3   - greek small letter alpha                                              -->
+<!ENTITY beta     "&#946;">  <!-- U+03B2 ISOgrk3   - greek small letter beta                                               -->
+<!ENTITY gamma    "&#947;">  <!-- U+03B3 ISOgrk3   - greek small letter gamma                                              -->
+<!ENTITY delta    "&#948;">  <!-- U+03B4 ISOgrk3   - greek small letter delta                                              -->
+<!ENTITY epsilon  "&#949;">  <!-- U+03B5 ISOgrk3   - greek small letter epsilon                                            -->
+<!ENTITY zeta     "&#950;">  <!-- U+03B6 ISOgrk3   - greek small letter zeta                                               -->
+<!ENTITY eta      "&#951;">  <!-- U+03B7 ISOgrk3   - greek small letter eta                                                -->
+<!ENTITY theta    "&#952;">  <!-- U+03B8 ISOgrk3   - greek small letter theta                                              -->
+<!ENTITY iota     "&#953;">  <!-- U+03B9 ISOgrk3   - greek small letter iota                                               -->
+<!ENTITY kappa    "&#954;">  <!-- U+03BA ISOgrk3   - greek small letter kappa                                              -->
+<!ENTITY lambda   "&#955;">  <!-- U+03BB ISOgrk3   - greek small letter lambda                                             -->
+<!ENTITY mu       "&#956;">  <!-- U+03BC ISOgrk3   - greek small letter mu                                                 -->
+<!ENTITY nu       "&#957;">  <!-- U+03BD ISOgrk3   - greek small letter nu                                                 -->
+<!ENTITY xi       "&#958;">  <!-- U+03BE ISOgrk3   - greek small letter xi                                                 -->
+<!ENTITY omicron  "&#959;">  <!-- U+03BF NEW       - greek small letter omicron                                            -->
+<!ENTITY pi       "&#960;">  <!-- U+03C0 ISOgrk3   - greek small letter pi                                                 -->
+<!ENTITY rho      "&#961;">  <!-- U+03C1 ISOgrk3   - greek small letter rho                                                -->
+<!ENTITY sigmaf   "&#962;">  <!-- U+03C2 ISOgrk3   - greek small letter final sigma                                        -->
+<!ENTITY sigma    "&#963;">  <!-- U+03C3 ISOgrk3   - greek small letter sigma                                              -->
+<!ENTITY tau      "&#964;">  <!-- U+03C4 ISOgrk3   - greek small letter tau                                                -->
+<!ENTITY upsilon  "&#965;">  <!-- U+03C5 ISOgrk3   - greek small letter upsilon                                            -->
+<!ENTITY phi      "&#966;">  <!-- U+03C6 ISOgrk3   - greek small letter phi                                                -->
+<!ENTITY chi      "&#967;">  <!-- U+03C7 ISOgrk3   - greek small letter chi                                                -->
+<!ENTITY psi      "&#968;">  <!-- U+03C8 ISOgrk3   - greek small letter psi                                                -->
+<!ENTITY omega    "&#969;">  <!-- U+03C9 ISOgrk3   - greek small letter omega                                              -->
+<!ENTITY thetasym "&#977;">  <!-- U+03D1 NEW       - greek small letter theta symbol                                       -->
+<!ENTITY upsih    "&#978;">  <!-- U+03D2 NEW       - greek upsilon with hook symbol                                        -->
+<!ENTITY piv      "&#982;">  <!-- U+03D6 ISOgrk3   - greek pi symbol                                                       -->
+
+<!-- General Punctuation -->
+<!ENTITY bull     "&#8226;"> <!-- U+2022 ISOpub    - bullet = black small circle                                           -->
+<!ENTITY hellip   "&#8230;"> <!-- U+2026 ISOpub    - horizontal ellipsis = three dot leader                                -->
+<!ENTITY prime    "&#8242;"> <!-- U+2032 ISOtech   - prime = minutes = feet                                                -->
+<!ENTITY Prime    "&#8243;"> <!-- U+2033 ISOtech   - double prime = seconds = inches                                       -->
+<!ENTITY oline    "&#8254;"> <!-- U+203E NEW       - overline = spacing overscore                                          -->
+<!ENTITY frasl    "&#8260;"> <!-- U+2044 NEW       - fraction slash                                                        -->
+
+<!-- Letterlike Symbols -->
+<!ENTITY weierp   "&#8472;"> <!-- U+2118 ISOamso   - script capital P = power set = Weierstrass p                          -->
+<!ENTITY image    "&#8465;"> <!-- U+2111 ISOamso   - blackletter capital I = imaginary part                                -->
+<!ENTITY real     "&#8476;"> <!-- U+211C ISOamso   - blackletter capital R = real part symbol                              -->
+<!ENTITY trade    "&#8482;"> <!-- U+2122 ISOnum    - trade mark sign                                                       -->
+<!ENTITY alefsym  "&#8501;"> <!-- U+2135 NEW       - alef symbol = first transfinite cardinal                              -->
+
+<!-- Arrows -->
+<!ENTITY larr     "&#8592;"> <!-- U+2190 ISOnum    - leftwards arrow                                                       -->
+<!ENTITY uarr     "&#8593;"> <!-- U+2191 ISOnum    - upwards arrow                                                         -->
+<!ENTITY rarr     "&#8594;"> <!-- U+2192 ISOnum    - rightwards arrow                                                      -->
+<!ENTITY darr     "&#8595;"> <!-- U+2193 ISOnum    - downwards arrow                                                       -->
+<!ENTITY harr     "&#8596;"> <!-- U+2194 ISOamsa   - left right arrow                                                      -->
+<!ENTITY crarr    "&#8629;"> <!-- U+21B5 NEW       - downwards arrow with corner leftwards = carriage return               -->
+<!ENTITY lArr     "&#8656;"> <!-- U+21D0 ISOtech   - leftwards double arrow                                                -->
+<!ENTITY uArr     "&#8657;"> <!-- U+21D1 ISOamsa   - upwards double arrow                                                  -->
+<!ENTITY rArr     "&#8658;"> <!-- U+21D2 ISOtech   - rightwards double arrow                                               -->
+<!ENTITY dArr     "&#8659;"> <!-- U+21D3 ISOamsa   - downwards double arrow                                                -->
+<!ENTITY hArr     "&#8660;"> <!-- U+21D4 ISOamsa   - left right double arrow                                               -->
+
+<!-- Mathematical Operators -->
+<!ENTITY forall   "&#8704;"> <!-- U+2200 ISOtech   - for all                                                               -->
+<!ENTITY part     "&#8706;"> <!-- U+2202 ISOtech   - partial differential                                                  -->
+<!ENTITY exist    "&#8707;"> <!-- U+2203 ISOtech   - there exists                                                          -->
+<!ENTITY empty    "&#8709;"> <!-- U+2205 ISOamso   - empty set = null set = diameter                                       -->
+<!ENTITY nabla    "&#8711;"> <!-- U+2207 ISOtech   - nabla = backward difference                                           -->
+<!ENTITY isin     "&#8712;"> <!-- U+2208 ISOtech   - element of                                                            -->
+<!ENTITY notin    "&#8713;"> <!-- U+2209 ISOtech   - not an element of                                                     -->
+<!ENTITY ni       "&#8715;"> <!-- U+220B ISOtech   - contains as member                                                    -->
+<!ENTITY prod     "&#8719;"> <!-- U+220F ISOamsb   - n-ary product = product sign                                          -->
+<!ENTITY sum      "&#8721;"> <!-- U+2211 ISOamsb   - n-ary sumation                                                        -->
+<!ENTITY minus    "&#8722;"> <!-- U+2212 ISOtech   - minus sign                                                            -->
+<!ENTITY lowast   "&#8727;"> <!-- U+2217 ISOtech   - asterisk operator                                                     -->
+<!ENTITY radic    "&#8730;"> <!-- U+221A ISOtech   - square root = radical sign                                            -->
+<!ENTITY prop     "&#8733;"> <!-- U+221D ISOtech   - proportional to                                                       -->
+<!ENTITY infin    "&#8734;"> <!-- U+221E ISOtech   - infinity                                                              -->
+<!ENTITY ang      "&#8736;"> <!-- U+2220 ISOamso   - angle                                                                 -->
+<!ENTITY and      "&#8743;"> <!-- U+2227 ISOtech   - logical and = wedge                                                   -->
+<!ENTITY or       "&#8744;"> <!-- U+2228 ISOtech   - logical or = vee                                                      -->
+<!ENTITY cap      "&#8745;"> <!-- U+2229 ISOtech   - intersection = cap                                                    -->
+<!ENTITY cup      "&#8746;"> <!-- U+222A ISOtech   - union = cup                                                           -->
+<!ENTITY int      "&#8747;"> <!-- U+222B ISOtech   - integral                                                              -->
+<!ENTITY there4   "&#8756;"> <!-- U+2234 ISOtech   - therefore                                                             -->
+<!ENTITY sim      "&#8764;"> <!-- U+223C ISOtech   - tilde operator = varies with = similar to                             -->
+<!ENTITY cong     "&#8773;"> <!-- U+2245 ISOtech   - approximately equal to                                                -->
+<!ENTITY asymp    "&#8776;"> <!-- U+2248 ISOamsr   - almost equal to = asymptotic to                                       -->
+<!ENTITY ne       "&#8800;"> <!-- U+2260 ISOtech   - not equal to                                                          -->
+<!ENTITY equiv    "&#8801;"> <!-- U+2261 ISOtech   - identical to                                                          -->
+<!ENTITY le       "&#8804;"> <!-- U+2264 ISOtech   - less-than or equal to                                                 -->
+<!ENTITY ge       "&#8805;"> <!-- U+2265 ISOtech   - greater-than or equal to                                              -->
+<!ENTITY sub      "&#8834;"> <!-- U+2282 ISOtech   - subset of                                                             -->
+<!ENTITY sup      "&#8835;"> <!-- U+2283 ISOtech   - superset of                                                           -->
+<!ENTITY nsub     "&#8836;"> <!-- U+2284 ISOamsn   - not a subset of                                                       -->
+<!ENTITY sube     "&#8838;"> <!-- U+2286 ISOtech   - subset of or equal to                                                 -->
+<!ENTITY supe     "&#8839;"> <!-- U+2287 ISOtech   - superset of or equal to                                               -->
+<!ENTITY oplus    "&#8853;"> <!-- U+2295 ISOamsb   - circled plus = direct sum                                             -->
+<!ENTITY otimes   "&#8855;"> <!-- U+2297 ISOamsb   - circled times = vector product                                        -->
+<!ENTITY perp     "&#8869;"> <!-- U+22A5 ISOtech   - up tack = orthogonal to = perpendicular                               -->
+<!ENTITY sdot     "&#8901;"> <!-- U+22C5 ISOamsb   - dot operator                                                          -->
+
+<!-- Miscellaneous Technical -->
+<!ENTITY lceil    "&#8968;"> <!-- U+2308 ISOamsc   - left ceiling = apl upstile                                            -->
+<!ENTITY rceil    "&#8969;"> <!-- U+2309 ISOamsc   - right ceiling                                                         -->
+<!ENTITY lfloor   "&#8970;"> <!-- U+230A ISOamsc   - left floor = apl downstile                                            -->
+<!ENTITY rfloor   "&#8971;"> <!-- U+230B ISOamsc   - right floor                                                           -->
+<!ENTITY lang     "&#9001;"> <!-- U+2329 ISOtech   - left-pointing angle bracket = bra                                     -->
+<!ENTITY rang     "&#9002;"> <!-- U+232A ISOtech   - right-pointing angle bracket = ket                                    -->
+
+<!-- Geometric Shapes -->
+<!ENTITY loz      "&#9674;"> <!-- U+25CA ISOpub    - lozenge                                                               -->
+
+<!-- Miscellaneous Symbols -->
+<!ENTITY spades   "&#9824;"> <!-- U+2660 ISOpub    - black spade suit                                                      -->
+<!ENTITY clubs    "&#9827;"> <!-- U+2663 ISOpub    - black club suit = shamrock                                            -->
+<!ENTITY hearts   "&#9829;"> <!-- U+2665 ISOpub    - black heart suit = valentine                                          -->
+<!ENTITY diams    "&#9830;"> <!-- U+2666 ISOpub    - black diamond suit                                                    -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/common-charents-v10.mod b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/common-charents-v10.mod
new file mode 100644
index 0000000..1f6ffcc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/common-charents-v10.mod
@@ -0,0 +1,74 @@
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Common Character Entity Sets (Version 1.0)
+
+PURPOSE:
+  Common elements across all DTDs.
+
+TYPICAL INVOCATION:
+
+  <!ENTITY % common-charents PUBLIC
+      "-//APACHE//ENTITIES Common Character Entity Sets Vx.y//EN"
+      "common-charents-vxy.mod">
+  %common-charents;
+
+  where
+
+    x := major version
+    y := minor version
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+  20020613 Initial version. (DC)
+
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Common ISO character entity sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % ISOlat1 PUBLIC
+    "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML"
+    "ISOlat1.pen">
+%ISOlat1;
+
+<!ENTITY % ISOpub PUBLIC
+    "ISO 8879:1986//ENTITIES Publishing//EN//XML"
+    "ISOpub.pen">
+%ISOpub;
+
+<!ENTITY % ISOtech PUBLIC
+    "ISO 8879:1986//ENTITIES General Technical//EN//XML"
+    "ISOtech.pen">
+%ISOtech;
+
+<!ENTITY % ISOnum PUBLIC
+    "ISO 8879:1986//ENTITIES Numeric and Special Graphic//EN//XML"
+    "ISOnum.pen">
+%ISOnum;
+
+<!ENTITY % ISOdia PUBLIC
+    "ISO 8879:1986//ENTITIES Diacritical Marks//EN//XML"
+    "ISOdia.pen">
+%ISOdia;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/datatypes.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/datatypes.dtd
new file mode 100644
index 0000000..5008e33
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/datatypes.dtd
@@ -0,0 +1,211 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- DTD for XML Schemas: Part 2: Datatypes -->
+<!-- Id: datatypes.dtd,v 1.14 2000/10/23 08:58:09 ht Exp  -->
+
+<!-- This DTD cannot be used on its own, it is intended only for incorporation
+     in XMLSchema.dtd, q.v. -->
+
+<!-- Define all the element names, with optional prefix -->
+<!ENTITY % simpleType "%p;simpleType">
+<!ENTITY % restriction "%p;restriction">
+<!ENTITY % list "%p;list">
+<!ENTITY % union "%p;union">
+<!ENTITY % maxExclusive "%p;maxExclusive">
+<!ENTITY % minExclusive "%p;minExclusive">
+<!ENTITY % maxInclusive "%p;maxInclusive">
+<!ENTITY % minInclusive "%p;minInclusive">
+<!ENTITY % precision "%p;precision">
+<!ENTITY % scale "%p;scale">
+<!ENTITY % length "%p;length">
+<!ENTITY % minLength "%p;minLength">
+<!ENTITY % maxLength "%p;maxLength">
+<!ENTITY % enumeration "%p;enumeration">
+<!ENTITY % whiteSpace "%p;whiteSpace">
+<!ENTITY % pattern "%p;pattern">
+<!ENTITY % encoding "%p;encoding">
+<!ENTITY % period "%p;period">
+<!ENTITY % duration "%p;duration">
+
+<!-- Customisation entities for the ATTLIST of each element type.
+     Define one of these if your schema takes advantage of the
+     anyAttribute='##other' in the schema for schemas -->
+
+<!ENTITY % simpleTypeAttrs "">
+<!ENTITY % restrictionAttrs "">
+<!ENTITY % listAttrs "">
+<!ENTITY % unionAttrs "">
+<!ENTITY % simpleTypeAttrs "">
+<!ENTITY % maxExclusiveAttrs "">
+<!ENTITY % minExclusiveAttrs "">
+<!ENTITY % maxInclusiveAttrs "">
+<!ENTITY % minInclusiveAttrs "">
+<!ENTITY % precisionAttrs "">
+<!ENTITY % scaleAttrs "">
+<!ENTITY % lengthAttrs "">
+<!ENTITY % minLengthAttrs "">
+<!ENTITY % maxLengthAttrs "">
+<!ENTITY % enumerationAttrs "">
+<!ENTITY % whiteSpaceAttrs "">
+<!ENTITY % patternAttrs "">
+<!ENTITY % encodingAttrs "">
+<!ENTITY % periodAttrs "">
+<!ENTITY % durationAttrs "">
+<!ENTITY % appinfoAttrs "">
+<!ENTITY % documentationAttrs "">
+
+<!-- Define some entities for informative use as attribute types -->
+<!ENTITY % URIref "CDATA">
+<!ENTITY % XPathExpr "CDATA">
+<!ENTITY % QName "NMTOKEN">
+<!ENTITY % QNames "NMTOKENS">
+<!ENTITY % NCName "NMTOKEN">
+<!ENTITY % nonNegativeInteger "NMTOKEN">
+<!ENTITY % boolean "(true|false)">
+
+<!-- Note that the use of 'facet' below is less restrictive than is
+     really intended:  There should in fact be no more than one of each of
+     minInclusive, minExclusive, maxInclusive, maxExclusive,
+     precision, scale,
+     length, maxLength, minLength, encoding, period within datatype,
+     and the min- and max- variants of Inclusive and Exclusive are
+     mutually exclusive.
+     On the other hand,  pattern and enumeration may repeat -->
+<!ENTITY % minBound "(%minInclusive; | %minExclusive;)">
+<!ENTITY % maxBound "(%maxInclusive; | %maxExclusive;)">
+<!ENTITY % bounds "%minBound; | %maxBound;">
+<!ENTITY % numeric "%precision; | %scale;">
+<!ENTITY % ordered "%bounds; | %numeric;">
+<!ENTITY % unordered
+   "%pattern; | %enumeration; | %whiteSpace; | %length; | %maxLength; | %minLength;
+    | %encoding; | %period; | %duration;">
+<!ENTITY % facet "%ordered; | %unordered;">
+<!ENTITY % facetAttr "value CDATA #REQUIRED">
+<!ENTITY % fixedAttr "fixed %boolean; #IMPLIED">
+<!ENTITY % facetModel "(%annotation;)?">
+<!ELEMENT %simpleType; ((%annotation;)?, (%restriction; | %list; | %union;))>
+<!ATTLIST %simpleType;
+    name      %NCName; #IMPLIED
+    id        ID       #IMPLIED
+    %simpleTypeAttrs;>
+<!-- name is required at top level -->
+<!ELEMENT %restriction; ((%annotation;)?,
+                         (%restriction1; |
+                          ((%simpleType;)?,(%facet;)*)),
+                         (%attrDecls;))>
+<!ATTLIST %restriction;
+    base      %QName;                  #IMPLIED
+    id        ID       #IMPLIED
+    %restrictionAttrs;>
+<!-- base and simpleType child are mutually exclusive, one is required -->
+<!-- restriction is shared between simpleType and simpleContent and -->
+<!-- complexContent (in XMLSchema.xsd). restriction1 is for the latter -->
+<!-- cases, when this is restricting a complex type, as is attrDecls -->
+<!ELEMENT %list; ((%annotation;)?,(%simpleType;)?)>
+<!ATTLIST %list;
+    itemType      %QName;             #IMPLIED
+    id        ID       #IMPLIED
+    %listAttrs;>
+<!-- itemType and simpleType child are mutually exclusive, one is required -->
+<!ELEMENT %union; ((%annotation;)?,(%simpleType;)*)>
+<!ATTLIST %union;
+    id            ID       #IMPLIED
+    memberTypes   %QNames;            #IMPLIED
+    %unionAttrs;>
+<!-- At least one item in memberTypes or one simpleType child is required -->
+
+<!ELEMENT %maxExclusive; %facetModel;>
+<!ATTLIST %maxExclusive;
+        %facetAttr;
+        %fixedAttr;
+    %maxExclusiveAttrs;>
+<!ELEMENT %minExclusive; %facetModel;>
+<!ATTLIST %minExclusive;
+        %facetAttr;
+        %fixedAttr;
+        %minExclusiveAttrs;>
+
+<!ELEMENT %maxInclusive; %facetModel;>
+<!ATTLIST %maxInclusive;
+        %facetAttr;
+        %fixedAttr;
+        %maxInclusiveAttrs;>
+<!ELEMENT %minInclusive; %facetModel;>
+<!ATTLIST %minInclusive;
+        %facetAttr;
+        %fixedAttr;
+        %minInclusiveAttrs;>
+
+<!ELEMENT %precision; %facetModel;>
+<!ATTLIST %precision;
+        %facetAttr;
+        %fixedAttr;
+        %precisionAttrs;>
+<!ELEMENT %scale; %facetModel;>
+<!ATTLIST %scale;
+        %facetAttr;
+        %fixedAttr;
+        %scaleAttrs;>
+
+<!ELEMENT %length; %facetModel;>
+<!ATTLIST %length;
+        %facetAttr;
+        %fixedAttr;
+        %lengthAttrs;>
+<!ELEMENT %minLength; %facetModel;>
+<!ATTLIST %minLength;
+        %facetAttr;
+        %fixedAttr;
+        %minLengthAttrs;>
+<!ELEMENT %maxLength; %facetModel;>
+<!ATTLIST %maxLength;
+        %facetAttr;
+        %fixedAttr;
+        %maxLengthAttrs;>
+
+<!-- This one can be repeated -->
+<!ELEMENT %enumeration; %facetModel;>
+<!ATTLIST %enumeration;
+        %facetAttr;
+        %enumerationAttrs;>
+
+<!ELEMENT %whiteSpace; %facetModel;>
+<!ATTLIST %whiteSpace;
+        %facetAttr;
+        %whiteSpaceAttrs;>
+
+<!-- This one can be repeated -->
+<!ELEMENT %pattern; %facetModel;>
+<!ATTLIST %pattern;
+        %facetAttr;
+        %patternAttrs;>
+
+<!ELEMENT %encoding; %facetModel;>
+<!ATTLIST %encoding;
+        %facetAttr;
+        %fixedAttr;
+        %encodingAttrs;>
+<!ELEMENT %period; %facetModel;>
+<!ATTLIST %period;
+        %facetAttr;
+        %fixedAttr;
+        %periodAttrs;>
+<!ELEMENT %duration; %facetModel;>
+<!ATTLIST %duration;
+        %facetAttr;
+        %fixedAttr;
+        %durationAttrs;>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v10.dtd
new file mode 100644
index 0000000..ed1b69b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v10.dtd
@@ -0,0 +1,499 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Documentation DTD (Version 1.0)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software documentation for use with the Apache projects.
+  It is an XML-compliant DTD and it's maintained by the Apache XML
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Documentation Vx.yz//EN"
+       "document-vxyz.dtd">
+
+  where
+
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+
+NOTES:
+  Many of the design patterns used in this DTD were take from the
+  W3C XML Specification DTD edited by Eve Maler <elm@arbortext.com>.
+
+  Where possible, great care has been used to reutilize HTML tag
+  names to reduce learning efforts and to allow HTML editors to be
+  used for complex authorings like tables and lists.
+
+FIXME:
+  - how can we include char entities without hardwiring them?
+  - should "form" tags be included?
+  - should all style-free HTML 4.0 markup tags be included?
+  - how do we handle the idea of "soft" xlinks?
+  - should we add "soft" links to images?
+
+CHANGE HISTORY:
+  19991121 Initial version. (SM)
+  19991123 Replaced "res" with more standard "strong" for emphasis. (SM)
+  19991124 Added "fork" element for window forking behavior. (SM)
+  19991124 Added "img-inline" element to separate from "img". (SM)
+  19991129 Removed "affiliation" from "author". (SM)
+  19991129 Made "author" empty and moved "name|email" as attributes. (SM)
+  19991215 Simplified table section. (SM)
+  19991215 Changed "img-block" in more friendly "figure". (SM)
+  20000125 Added the "icon" image. (SM)
+  20000126 Allowed "anchor" in all levels. (SM)
+  20000404 Removed the "role" attribute from common-xxx.att. (SM)
+  20000815 Allowed "code" inside "strong" and "em". (SM)
+  20020223 Allowed "figure" at section level (SM)
+
+==================================================================== -->
+<!-- =============================================================== -->
+<!-- Common character entities (included from external file) -->
+<!-- =============================================================== -->
+<!-- FIXME (SM): this is hardcoding. Find a better way of doing this
+     possibly using public identifiers of ISO latin char sets -->
+<!ENTITY % charEntity SYSTEM "characters.ent">
+%charEntity;
+<!-- =============================================================== -->
+<!-- Userful entitieis for increased DTD readability -->
+<!-- =============================================================== -->
+<!ENTITY % text "#PCDATA">
+<!-- =============================================================== -->
+<!-- Entities for general XML compliance -->
+<!-- =============================================================== -->
+<!-- Common attributes
+        Every element has an ID attribute (sometimes required,
+        but usually optional) for links. %common.att;
+        is for common attributes where the ID is optional, and
+        %common-idreq.att; is for common attributes where the
+        ID is required.
+-->
+<!ENTITY % common.att 'id                     ID              #IMPLIED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!ENTITY % common-idreq.att 'id                     ID              #REQUIRED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!-- xml:space attribute ===============================================
+        Indicates that the element contains white space
+        that the formatter or other application should retain,
+        as appropriate to its function.
+==================================================================== -->
+<!ENTITY % xmlspace.att 'xml:space (default|preserve) #FIXED "preserve"'>
+<!-- def attribute =====================================================
+        Points to the element where the relevant definition can be
+        found, using the IDREF mechanism.  %def.att; is for optional
+        def attributes, and %def-req.att; is for required def
+        attributes.
+==================================================================== -->
+<!ENTITY % def.att 'def                    IDREF           #IMPLIED'>
+<!ENTITY % def-req.att 'def                    IDREF           #REQUIRED'>
+<!-- ref attribute =====================================================
+        Points to the element where more information can be found,
+        using the IDREF mechanism.  %ref.att; is for optional
+        ref attributes, and %ref-req.att; is for required ref
+        attributes.
+================================================================== -->
+<!ENTITY % ref.att 'ref                    IDREF           #IMPLIED'>
+<!ENTITY % ref-req.att 'ref                    IDREF           #REQUIRED'>
+<!-- =============================================================== -->
+<!-- Entities for XLink compliance -->
+<!-- =============================================================== -->
+<!ENTITY % xlink-simple.att 'type      (simple|extended|locator|arc) #FIXED "simple"
+         href      CDATA                         #IMPLIED
+         role      CDATA                         #IMPLIED
+         title     CDATA                         #IMPLIED '>
+<!--    'xmlns     CDATA                         #FIXED "http://www.w3.org/XML/XLink/0.9" -->
+<!-- FIXME: brain-dead IE5 has broken support for
+     namespace validation and since I use it for editing
+     I remove this for now -->
+<!ENTITY % xlink-user-replace.att 'show      (new|parsed|replace)   #FIXED "replace"
+         actuate   (user|auto)            #FIXED "user" '>
+<!ENTITY % xlink-user-new.att 'show      (new|parsed|replace)   #FIXED "new"
+         actuate   (user|auto)            #FIXED "user" '>
+<!ENTITY % xlink-auto-parsed.att 'show      (new|parsed|replace)   #FIXED "parsed"
+         actuate   (user|auto)            #FIXED "auto" '>
+<!-- FIXME (SM): XLink doesn't yet cover the idea of soft links so
+     introducing it here using the same namespace is _somewhat_
+     illegal. Should we create it own namespace?
+-->
+<!ENTITY % xlink-soft.att 'mode      (hard|soft)            #FIXED "soft" '>
+<!-- =============================================================== -->
+<!-- Entities for general usage -->
+<!-- =============================================================== -->
+<!-- Key attribute =====================================================
+        Optionally provides a sorting or indexing key, for cases when
+        the element content is inappropriate for this purpose.
+==================================================================== -->
+<!ENTITY % key.att 'key                    CDATA           #IMPLIED'>
+<!-- Title attributes ==================================================
+        Indicates that the element requires to have a title.
+==================================================================== -->
+<!ENTITY % title.att 'title                  CDATA           #REQUIRED'>
+<!-- Name attributes ==================================================
+        Indicates that the element requires to have a name.
+==================================================================== -->
+<!ENTITY % name.att 'name                   CDATA           #REQUIRED'>
+<!-- Email attributes ==================================================
+        Indicates that the element requires to have an email.
+==================================================================== -->
+<!ENTITY % email.att 'email                  CDATA           #REQUIRED'>
+<!-- =============================================================== -->
+<!-- General definitions -->
+<!-- =============================================================== -->
+<!-- A person is a general human entity -->
+<!ELEMENT person EMPTY>
+<!ATTLIST person
+	%common.att; 
+	%name.att; 
+	%email.att; 
+>
+<!-- =============================================================== -->
+<!-- Content definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.content.mix "">
+<!ENTITY % markup "strong|em|code|sub|sup">
+<!ENTITY % links "link|connect|jump|fork|anchor">
+<!ENTITY % special "br|img|icon">
+<!ENTITY % link-content.mix "%text;|%markup;|%special;%local.content.mix;">
+<!ENTITY % content.mix "%link-content.mix;|%links;">
+<!-- ==================================================== -->
+<!-- Phrase Markup -->
+<!-- ==================================================== -->
+<!-- Code (typically monospaced) -->
+<!ELEMENT code (%text;)>
+<!ATTLIST code
+	%common.att; 
+>
+<!-- Strong (typically bold) -->
+<!ELEMENT strong (%text; | code)*>
+<!ATTLIST strong
+	%common.att; 
+>
+<!-- Emphasis (typically italic) -->
+<!ELEMENT em (%text; | code)*>
+<!ATTLIST em
+	%common.att; 
+>
+<!-- Superscript (typically smaller and higher) -->
+<!ELEMENT sup (%text;)>
+<!ATTLIST sup
+	%common.att; 
+>
+<!-- Subscript (typically smaller and lower) -->
+<!ELEMENT sub (%text;)>
+<!ATTLIST sub
+	%common.att; 
+>
+<!-- FIXME (SM): should we add these HTML 4.0 markups
+         which are style-free?
+
+          -dfn
+          -samp
+          -kbd
+          -var
+          -cite
+          -abbr
+          -acronym
+
+     -->
+<!-- ==================================================== -->
+<!-- Hypertextual Links -->
+<!-- ==================================================== -->
+<!-- hard replacing link (equivalent of <a ...>) -->
+<!ELEMENT link (%link-content.mix;)*>
+<!ATTLIST link
+	%common.att; 
+	%xlink-simple.att; 
+	%xlink-user-replace.att; 
+>
+<!-- Hard window replacing link (equivalent of <a ... target="_top">) -->
+<!ELEMENT jump (%link-content.mix;)*>
+<!ATTLIST jump
+	%common.att; 
+	%xlink-simple.att; 
+	%xlink-user-new.att; 
+>
+<!-- Hard window forking link (equivalent of <a ... target="_new">) -->
+<!ELEMENT fork (%link-content.mix;)*>
+<!ATTLIST fork
+	%common.att; 
+	%xlink-simple.att; 
+	%xlink-user-new.att; 
+>
+<!-- Anchor point (equivalent of <a name="...">) -->
+<!ELEMENT anchor EMPTY>
+<!ATTLIST anchor
+	%common-idreq.att; 
+>
+<!-- Soft link between processed pages (no equivalent in HTML) -->
+<!ELEMENT connect (%link-content.mix;)*>
+<!ATTLIST connect
+	%common.att; 
+	%xlink-simple.att; 
+	%xlink-user-replace.att; 
+	%xlink-soft.att; 
+>
+<!-- ==================================================== -->
+<!-- Specials -->
+<!-- ==================================================== -->
+<!-- Breakline Object (typically forces line break) -->
+<!ELEMENT br EMPTY>
+<!ATTLIST br
+	%common.att; 
+>
+<!-- Image Object (typically an inlined image) -->
+<!-- FIXME (SM): should we have the notion of soft links even here
+         for inlined objects? -->
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+	src CDATA #REQUIRED
+	alt CDATA #REQUIRED
+	height CDATA #IMPLIED
+	width CDATA #IMPLIED
+	usemap CDATA #IMPLIED
+	ismap (ismap) #IMPLIED
+	%common.att; 
+>
+<!-- Image Icon (typically an inlined image placed as graphical item) -->
+<!-- FIXME (SM): should we have the notion of soft links even here
+         for inlined objects? -->
+<!ELEMENT icon EMPTY>
+<!ATTLIST icon
+	src CDATA #REQUIRED
+	alt CDATA #REQUIRED
+	height CDATA #IMPLIED
+	width CDATA #IMPLIED
+	%common.att; 
+>
+<!-- =============================================================== -->
+<!-- Blocks definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.blocks "">
+<!ENTITY % local.lists "">
+<!ENTITY % paragraphs "p|source|note|fixme|figure">
+<!ENTITY % tables "table">
+<!ENTITY % lists "ol|ul|sl|dl %local.lists;">
+<!ENTITY % blocks "anchor|%paragraphs;|%tables;|%lists; %local.blocks;">
+<!-- ==================================================== -->
+<!-- Paragraphs -->
+<!-- ==================================================== -->
+<!-- Text Paragraph (normally vertically space delimited) -->
+<!ELEMENT p (%content.mix;)*>
+<!ATTLIST p
+	%common.att; 
+>
+<!-- Source Paragraph (normally space is preserved) -->
+<!ELEMENT source (%content.mix;)*>
+<!ATTLIST source
+	%common.att; 
+	%xmlspace.att; 
+>
+<!-- Note Paragraph (normally shown encapsulated) -->
+<!ELEMENT note (%content.mix;)*>
+<!ATTLIST note
+	%common.att; 
+>
+<!-- Fixme Paragraph (normally not shown) -->
+<!ELEMENT fixme (%content.mix;)*>
+<!-- the "author" attribute should match the "key" attribute of the
+         <author> element -->
+<!ATTLIST fixme
+	author CDATA #REQUIRED
+	%common.att; 
+>
+<!-- ==================================================== -->
+<!-- Tables -->
+<!-- ==================================================== -->
+<!-- Attributes that indicate the spanning of the table cell -->
+<!ENTITY % cell.span 'colspan CDATA "1"
+         rowspan CDATA "1"'>
+<!-- Table element -->
+<!ELEMENT table (caption?, tr+)>
+<!ATTLIST table
+	%common.att; 
+>
+<!-- The table title -->
+<!ELEMENT caption (%content.mix;)*>
+<!ATTLIST caption
+	%common.att; 
+>
+<!-- The table row element -->
+<!ELEMENT tr (th | td)+>
+<!ATTLIST tr
+	%common.att; 
+>
+<!-- The table row header element -->
+<!ELEMENT th (%content.mix;)*>
+<!ATTLIST th
+	%common.att; 
+	%cell.span; 
+>
+<!-- The table row description element -->
+<!ELEMENT td (%content.mix;)*>
+<!ATTLIST td
+	%common.att; 
+	%cell.span; 
+>
+<!-- ==================================================== -->
+<!-- Lists -->
+<!-- ==================================================== -->
+<!-- Unordered list (typically bulleted) -->
+<!ELEMENT ul (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ul
+	%common.att; 
+	spacing (normal | compact) #IMPLIED
+>
+<!-- Ordered list (typically numbered) -->
+<!ELEMENT ol (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ol
+	%common.att; 
+	spacing (normal | compact) #IMPLIED
+>
+<!-- Simple list (typically with no mark) -->
+<!ELEMENT sl (li | %lists;)+>
+<!ATTLIST sl
+	%common.att; 
+>
+<!-- List item -->
+<!ELEMENT li (%content.mix; | %lists;)*>
+<!ATTLIST li
+	%common.att; 
+>
+<!-- Definition list (typically two-column) -->
+<!ELEMENT dl (dt, dd)+>
+<!ATTLIST dl
+	%common.att; 
+>
+<!-- Definition term -->
+<!ELEMENT dt (%content.mix;)*>
+<!ATTLIST dt
+	%common.att; 
+>
+<!-- Definition description -->
+<!ELEMENT dd (%content.mix;)*>
+<!ATTLIST dd
+	%common.att; 
+>
+<!-- ==================================================== -->
+<!-- Special Blocks -->
+<!-- ==================================================== -->
+<!-- Image Block (typically a separated and centered image) -->
+<!-- FIXME (SM): should we have the notion of soft links even here
+         for inlined objects? -->
+<!ELEMENT figure EMPTY>
+<!ATTLIST figure
+	src CDATA #REQUIRED
+	alt CDATA #REQUIRED
+	height CDATA #IMPLIED
+	width CDATA #IMPLIED
+	usemap CDATA #IMPLIED
+	ismap (ismap) #IMPLIED
+	%common.att; 
+>
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+<!ELEMENT document (header?, body, footer?)>
+<!ATTLIST document
+	%common.att; 
+>
+<!-- ==================================================== -->
+<!-- Header -->
+<!-- ==================================================== -->
+<!ENTITY % local.headers "">
+<!ELEMENT header (title, subtitle?, version?, type?, authors,
+                      notice*, abstract? %local.headers;)>
+<!ATTLIST header
+	%common.att; 
+>
+<!ELEMENT title (%text;)>
+<!ATTLIST title
+	%common.att; 
+>
+<!ELEMENT subtitle (%text;)>
+<!ATTLIST subtitle
+	%common.att; 
+>
+<!ELEMENT version (%text;)>
+<!ATTLIST version
+	%common.att; 
+>
+<!ELEMENT type (%text;)>
+<!ATTLIST type
+	%common.att; 
+>
+<!ELEMENT authors (person+)>
+<!ATTLIST authors
+	%common.att; 
+>
+<!ELEMENT notice (%content.mix;)*>
+<!ATTLIST notice
+	%common.att; 
+>
+<!ELEMENT abstract (%content.mix;)*>
+<!ATTLIST abstract
+	%common.att; 
+>
+<!-- ==================================================== -->
+<!-- Body -->
+<!-- ==================================================== -->
+<!ENTITY % local.sections "">
+<!ENTITY % sections "s1|anchor|figure %local.sections;">
+<!ELEMENT body (%sections;)+>
+<!ATTLIST body
+	%common.att; 
+>
+<!ELEMENT s1 (s2 | %blocks;)*>
+<!ATTLIST s1
+	%title.att; %common.att;
+>
+<!ELEMENT s2 (s3 | %blocks;)*>
+<!ATTLIST s2
+	%title.att; %common.att;
+>
+<!ELEMENT s3 (s4 | %blocks;)*>
+<!ATTLIST s3
+	%title.att; %common.att;
+>
+<!ELEMENT s4 (%blocks;)*>
+<!ATTLIST s4
+	%title.att; %common.att;
+>
+<!-- ==================================================== -->
+<!-- Footer -->
+<!-- ==================================================== -->
+<!ENTITY % local.footers "">
+<!ELEMENT footer (legal %local.footers;)>
+<!ELEMENT legal (%content.mix;)*>
+<!ATTLIST legal
+	%common.att; 
+>
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.dtd
new file mode 100644
index 0000000..bb6df3c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.dtd
@@ -0,0 +1,137 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Documentation DTD (Version 1.1)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software documentation for use with the Apache projects.
+  It is an XML-compliant DTD and it's maintained by the Apache XML
+  project. It has now been superceded by v1.2.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Documentation V1.1//EN"
+       "document-v11.dtd">
+
+  where
+
+    x := major version
+    y := minor version
+
+NOTES:
+  Many of the design patterns used in this DTD were take from the
+  W3C XML Specification DTD edited by Eve Maler <elm@arbortext.com>.
+
+  Where possible, great care has been used to reuse HTML tag
+  names to reduce learning efforts and to allow HTML editors to be
+  used for complex authorings like tables and lists.
+
+EXTENSIBILITY:
+  This DTD includes several empty placeholders that can be used to
+  extend it. These placeholders are implemented with empty entities. Here
+  is the list of those empty entities and what they are used for:
+
+    - local.inline: this entity should contain extended definitions of
+                    elements that can be used 'inline', or directly inside
+                    the content. An example for this entity could be
+
+                        <!ENTITY % local.inline "|citation">
+
+    - local.blocks: this entity should contain extended definitions of
+                    elements that behave as 'blocks', thus can be visually
+                    rendered as areas on the canvas. An example for this
+                    entity could be:
+
+                        <!ENTITY % local.blocks "|poem">
+
+    - local.sections: this entity should contain extended definitions of
+                      elements that behave as 'sections', thus can be considered
+                      containers of block-level elements. An example for
+                      this entity could be:
+
+                        <!ENTITY % local.sections "|chapter">
+
+    - local.headers: this entity should contain extended definitions of
+                     elements that behave as parts of the document header.
+                     An example for this header could be:
+
+                        <!ENTITY % local.headers ", notes?">
+
+    - local.footers: this entity should contain extended definitions of
+                     elements that behave as parts of the document footer.
+                     An example for this header could be:
+
+                        <!ENTITY % local.footers ", annotations*">
+
+FIXME:
+  - should "form" tags be included?
+
+CHANGE HISTORY:
+[Version 1.0]
+  19991121 Initial version. (SM)
+  19991123 Replaced "res" with more standard "strong" for emphasis. (SM)
+  19991124 Added "fork" element for window forking behavior. (SM)
+  19991124 Added "img-inline" element to separate from "img". (SM)
+  19991129 Removed "affiliation" from "author". (SM)
+  19991129 Made "author" empty and moved "name|email" as attributes. (SM)
+  19991215 Simplified table section. (SM)
+  19991215 Changed "img-block" in more friendly "figure". (SM)
+  20000125 Added the "icon" image. (SM)
+  20000126 Allowed "anchor" in all levels. (SM)
+  20000404 Removed the "role" attribute from common-xxx.att. (SM)
+  20000815 Allowed "code" inside "strong" and "em". (SM)
+[Version 1.1]
+  20011212 Used public identifiers for external entities. (SM)
+  20011212 Removed xlink attributes since not used. (SM)
+  20011212 Removed "connect" since not required at this level. (SM)
+  20011218 Added "warning" as a block level object. (SM)
+  20011218 Removed explicitly numbered sections ("s1|s2|s3|s4"). (SM)
+  20011218 Added "section" element. (SM)
+  20011218 Allowed "body" to have blocks without a section. (SM)
+  20011218 Removed "sl" since not really different from "ul". (SM)
+  20020214 Moved empty placeholder entity declarations up front (SNS)
+  20020214 Corrected content model of content.mix parameter entity (SNS)
+  20020519 The DTDs are now modular so various parts can be re-used (SNS)
+  20020606 Made title into an child element of its parent instead of an attribute (SNS)
+  20020613 Move the declarations of ISO character entity sets to module (DC)
+
+==================================================================== -->
+
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+    "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+    "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+    "-//APACHE//ENTITIES Documentation V1.1//EN"
+    "document-v11.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.mod b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.mod
new file mode 100644
index 0000000..d84ef1d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v11.mod
@@ -0,0 +1,424 @@
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Common Documentation elements (Version 1.1)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software documentation for use with the Apache projects.
+  It has now been superceded by v1.2.
+
+TYPICAL INVOCATION:
+
+  <!ENTITY % document PUBLIC
+      "-//APACHE//ENTITIES Documentation V1.1//EN"
+      "document-v11.mod">
+  %document;
+
+  where
+
+    x := major version
+    y := minor version
+
+NOTES:
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+  20020608 Initial version. (SN)
+
+==================================================================== -->
+<!-- =============================================================== -->
+<!-- Useful entities for increased DTD readability -->
+<!-- =============================================================== -->
+<!ENTITY % text "#PCDATA">
+<!-- Entities referred to later on are defined up front -->
+<!ENTITY % markup "strong|em|code|sub|sup">
+<!ENTITY % special-inline "br|img|icon|acronym">
+<!ENTITY % links "link|jump|fork">
+<!ENTITY % paragraphs "p|source|note|warning|fixme">
+<!ENTITY % tables "table">
+<!ENTITY % lists "ol|ul|dl">
+<!ENTITY % special-blocks "figure|anchor">
+<!-- =============================================================== -->
+<!-- Entities for general XML compliance -->
+<!-- =============================================================== -->
+<!-- Common attributes
+        Every element has an ID attribute (sometimes required,
+        but usually optional) for links. %common.att;
+        is for common attributes where the ID is optional, and
+        %common-idreq.att; is for common attributes where the
+        ID is required.
+-->
+<!ENTITY % common.att 'id                     ID              #IMPLIED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!ENTITY % common-idreq.att 'id                     ID              #REQUIRED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!-- xml:space attribute ===============================================
+        Indicates that the element contains white space
+        that the formatter or other application should retain,
+        as appropriate to its function.
+==================================================================== -->
+<!ENTITY % xmlspace.att 'xml:space (default|preserve) #FIXED "preserve"'>
+<!-- def attribute =====================================================
+        Points to the element where the relevant definition can be
+        found, using the IDREF mechanism.  %def.att; is for optional
+        def attributes, and %def-req.att; is for required def
+        attributes.
+==================================================================== -->
+<!ENTITY % def.att 'def                    IDREF           #IMPLIED'>
+<!ENTITY % def-req.att 'def                    IDREF           #REQUIRED'>
+<!-- ref attribute =====================================================
+        Points to the element where more information can be found,
+        using the IDREF mechanism.  %ref.att; is for optional
+        ref attributes, and %ref-req.att; is for required ref
+        attributes.
+================================================================== -->
+<!ENTITY % ref.att 'ref                    IDREF           #IMPLIED'>
+<!ENTITY % ref-req.att 'ref                    IDREF           #REQUIRED'>
+<!-- =============================================================== -->
+<!-- Entities for general usage -->
+<!-- =============================================================== -->
+<!-- Key attribute =====================================================
+        Optionally provides a sorting or indexing key, for cases when
+        the element content is inappropriate for this purpose.
+==================================================================== -->
+<!ENTITY % key.att 'key                    CDATA           #IMPLIED'>
+<!-- Title attributes ==================================================
+        Indicates that the element requires to have a title attribute.
+==================================================================== -->
+<!ENTITY % title.att 'title                  CDATA           #REQUIRED'>
+<!-- Name attributes ==================================================
+        Indicates that the element requires to have a name attribute.
+==================================================================== -->
+<!ENTITY % name.att 'name                   CDATA           #REQUIRED'>
+<!-- Email attributes ==================================================
+        Indicates that the element requires to have an email attribute.
+==================================================================== -->
+<!ENTITY % email.att 'email                  CDATA           #REQUIRED'>
+<!-- Link attributes ===================================================
+        Indicates that the element requires to have hyperlink attributes.
+==================================================================== -->
+<!ENTITY % link.att 'href      CDATA                         #IMPLIED
+         role      CDATA                         #IMPLIED
+         title     CDATA                         #IMPLIED '>
+<!-- =============================================================== -->
+<!-- General definitions -->
+<!-- =============================================================== -->
+<!-- A person is a general unparsed human entity -->
+<!ELEMENT person EMPTY>
+<!ATTLIST person
+  %common.att; 
+  %name.att; 
+  %email.att; 
+>
+<!-- =============================================================== -->
+<!-- Content definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.inline "">
+<!ENTITY % link-content.mix "%text;|%markup;|%special-inline; %local.inline;">
+<!ENTITY % content.mix "%link-content.mix;|%links;">
+<!-- ==================================================== -->
+<!-- Phrase Markup -->
+<!-- ==================================================== -->
+<!-- Strong (typically bold) -->
+<!ELEMENT strong (%text; | code)*>
+<!ATTLIST strong
+  %common.att; 
+>
+<!-- Emphasis (typically italic) -->
+<!ELEMENT em (%text; | code)*>
+<!ATTLIST em
+  %common.att; 
+>
+<!-- Code (typically monospaced) -->
+<!ELEMENT code (%text;)>
+<!ATTLIST code
+  %common.att; 
+>
+<!-- Superscript (typically smaller and higher) -->
+<!ELEMENT sup (%text;)>
+<!ATTLIST sup
+  %common.att; 
+>
+<!-- Subscript (typically smaller and lower) -->
+<!ELEMENT sub (%text;)>
+<!ATTLIST sub
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Hypertextual Links -->
+<!-- ==================================================== -->
+<!-- hyperlink (equivalent of <a ...>) -->
+<!ELEMENT link (%link-content.mix;)*>
+<!ATTLIST link
+  %common.att; 
+  %link.att; 
+>
+<!-- windows-replacing link (equivalent of <a ... target="_top">) -->
+<!ELEMENT jump (%link-content.mix;)*>
+<!ATTLIST jump
+  %common.att; 
+  %link.att; 
+>
+<!-- window-forking link (equivalent of <a ... target="_blank">) -->
+<!ELEMENT fork (%link-content.mix;)*>
+<!ATTLIST fork
+  %common.att; 
+  %link.att; 
+>
+
+<!-- ==================================================== -->
+<!-- Specials -->
+<!-- ==================================================== -->
+<!-- Breakline Object (typically forces line break) -->
+<!ELEMENT br EMPTY>
+<!ATTLIST br
+  %common.att; 
+>
+<!-- Image Object (typically an inlined image) -->
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  usemap CDATA #IMPLIED
+  ismap (ismap) #IMPLIED
+  %common.att; 
+>
+<!-- Image Icon (typically an inlined image placed as graphical item) -->
+<!ELEMENT icon EMPTY>
+<!ATTLIST icon
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  %common.att; 
+>
+<!-- Acronym (in modern browsers, will have rollover text) -->
+<!ELEMENT acronym (%text;)*>
+<!ATTLIST acronym
+  title CDATA #REQUIRED
+  %common.att; 
+>
+
+<!-- =============================================================== -->
+<!-- Blocks definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.blocks "">
+<!ENTITY % blocks "%paragraphs;|%tables;|%lists;|%special-blocks; %local.blocks;">
+<!-- ==================================================== -->
+<!-- Paragraphs -->
+<!-- ==================================================== -->
+<!-- Text Paragraph (normally vertically space delimited. Space can be preserved.) -->
+<!ELEMENT p (%content.mix;)*>
+<!ATTLIST p
+  %common.att; 
+  xml:space (default|preserve) #IMPLIED
+>
+<!-- Source Paragraph (normally space is preserved) -->
+<!ELEMENT source (%content.mix;)*>
+<!ATTLIST source
+  %common.att; 
+  %xmlspace.att; 
+>
+<!-- Note Paragraph (normally shown encapsulated) -->
+<!ELEMENT note (%content.mix;)*>
+<!ATTLIST note
+  %common.att; 
+>
+<!-- Warning Paragraph (normally shown with eye-catching colors) -->
+<!ELEMENT warning (%content.mix;)*>
+<!ATTLIST warning
+  %common.att; 
+>
+<!-- Fixme Paragraph (normally not shown) -->
+<!ELEMENT fixme (%content.mix;)*>
+<!ATTLIST fixme
+  author CDATA #REQUIRED
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Tables -->
+<!-- ==================================================== -->
+<!-- Attributes that indicate the spanning of the table cell -->
+<!ENTITY % cell.span 'colspan CDATA "1"
+         rowspan CDATA "1"'>
+<!-- Table element -->
+<!ELEMENT table (caption?, tr+)>
+<!ATTLIST table
+  %common.att; 
+>
+<!-- The table title -->
+<!ELEMENT caption (%content.mix;)*>
+<!ATTLIST caption
+  %common.att; 
+>
+<!-- The table row element -->
+<!ELEMENT tr (th | td)+>
+<!ATTLIST tr
+  %common.att; 
+>
+<!-- The table row header element -->
+<!ELEMENT th (%content.mix;)*>
+<!ATTLIST th
+  %common.att; 
+  %cell.span; 
+>
+<!-- The table row description element -->
+<!ELEMENT td (%content.mix;)*>
+<!ATTLIST td
+  %common.att; 
+  %cell.span; 
+>
+<!-- ==================================================== -->
+<!-- Lists -->
+<!-- ==================================================== -->
+<!-- List item -->
+<!ELEMENT li (%content.mix; | %lists;)*>
+<!ATTLIST li
+  %common.att; 
+>
+<!-- Unordered list (typically bulleted) -->
+<!ELEMENT ul (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ul
+  %common.att; 
+  spacing (normal | compact) #IMPLIED
+>
+<!-- Ordered list (typically numbered) -->
+<!ELEMENT ol (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ol
+  %common.att; 
+  spacing (normal | compact) #IMPLIED
+>
+<!-- Definition list (typically two-column) -->
+<!ELEMENT dl (dt, dd)+>
+<!ATTLIST dl
+  %common.att; 
+>
+<!-- Definition term -->
+<!ELEMENT dt (%content.mix;)*>
+<!ATTLIST dt
+  %common.att; 
+>
+<!-- Definition description -->
+<!ELEMENT dd (%content.mix;)*>
+<!ATTLIST dd
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Special Blocks -->
+<!-- ==================================================== -->
+<!-- Image Block (typically a separated and centered image) -->
+<!ELEMENT figure EMPTY>
+<!ATTLIST figure
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  usemap CDATA #IMPLIED
+  ismap (ismap) #IMPLIED
+  %common.att; 
+>
+<!-- anchor point (equivalent of <a name="...">, typically not rendered) -->
+<!ELEMENT anchor EMPTY>
+<!ATTLIST anchor
+  %common-idreq.att; 
+>
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+<!ELEMENT document (header, body, footer?)>
+<!ATTLIST document
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Header -->
+<!-- ==================================================== -->
+<!ENTITY % local.headers "">
+<!ELEMENT header (title, subtitle?, version?, type?, authors?,
+                      notice*, abstract? %local.headers;)>
+<!ATTLIST header
+  %common.att; 
+>
+<!ELEMENT title (%text; | %markup;)*>
+<!ATTLIST title
+  %common.att; 
+>
+<!ELEMENT subtitle (%text; | %markup;)*>
+<!ATTLIST subtitle
+  %common.att; 
+>
+<!ELEMENT version (%text;)>
+<!ATTLIST version
+  %common.att;
+  major CDATA #IMPLIED
+  minor CDATA #IMPLIED
+  fix CDATA #IMPLIED
+  tag CDATA #IMPLIED
+>
+<!ELEMENT type (%text;)>
+<!ATTLIST type
+  %common.att; 
+>
+<!ELEMENT authors (person+)>
+<!ATTLIST authors
+  %common.att; 
+>
+<!ELEMENT notice (%content.mix;)*>
+<!ATTLIST notice
+  %common.att; 
+>
+<!ELEMENT abstract (%content.mix;)*>
+<!ATTLIST abstract
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Body -->
+<!-- ==================================================== -->
+<!ENTITY % local.sections "">
+<!ENTITY % sections "section %local.sections;">
+<!ELEMENT body (%sections; | %blocks;)+>
+<!ATTLIST body
+  %common.att; 
+>
+<!ELEMENT section (title, (%sections; | %blocks;)*)>
+<!ATTLIST section
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Footer -->
+<!-- ==================================================== -->
+<!ENTITY % local.footers "">
+<!ELEMENT footer (legal %local.footers;)>
+<!ELEMENT legal (%content.mix;)*>
+<!ATTLIST legal
+  %common.att; 
+>
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.dtd
new file mode 100644
index 0000000..050f9f4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.dtd
@@ -0,0 +1,144 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Documentation DTD (Version 1.2)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software documentation for use with the Apache projects.
+  It is an XML-compliant DTD and it's maintained by the Apache XML
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Documentation Vx.y//EN"
+       "document-vxy.dtd">
+
+  where
+
+    x := major version
+    y := minor version
+
+NOTES:
+  Many of the design patterns used in this DTD were take from the
+  W3C XML Specification DTD edited by Eve Maler <elm@arbortext.com>.
+
+  Where possible, great care has been used to reuse HTML tag
+  names to reduce learning efforts and to allow HTML editors to be
+  used for complex authorings like tables and lists.
+
+EXTENSIBILITY:
+  This DTD includes several empty placeholders that can be used to
+  extend it. These placeholders are implemented with empty entities. Here
+  is the list of those empty entities and what they are used for:
+
+    - local.inline: this entity should contain extended definitions of
+                    elements that can be used 'inline', or directly inside
+                    the content. An example for this entity could be
+
+                        <!ENTITY % local.inline "|citation">
+
+    - local.blocks: this entity should contain extended definitions of
+                    elements that behave as 'blocks', thus can be visually
+                    rendered as areas on the canvas. An example for this
+                    entity could be:
+
+                        <!ENTITY % local.blocks "|poem">
+
+    - local.sections: this entity should contain extended definitions of
+                      elements that behave as 'sections', thus can be considered
+                      containers of block-level elements. An example for
+                      this entity could be:
+
+                        <!ENTITY % local.sections "|chapter">
+
+    - local.headers: this entity should contain extended definitions of
+                     elements that behave as parts of the document header.
+                     An example for this header could be:
+
+                        <!ENTITY % local.headers ", notes?">
+
+    - local.footers: this entity should contain extended definitions of
+                     elements that behave as parts of the document footer.
+                     An example for this header could be:
+
+                        <!ENTITY % local.footers ", annotations*">
+
+FIXME:
+  - should "form" tags be included?
+
+CHANGE HISTORY:
+[Version 1.0]
+  19991121 Initial version. (SM)
+  19991123 Replaced "res" with more standard "strong" for emphasis. (SM)
+  19991124 Added "fork" element for window forking behavior. (SM)
+  19991124 Added "img-inline" element to separate from "img". (SM)
+  19991129 Removed "affiliation" from "author". (SM)
+  19991129 Made "author" empty and moved "name|email" as attributes. (SM)
+  19991215 Simplified table section. (SM)
+  19991215 Changed "img-block" in more friendly "figure". (SM)
+  20000125 Added the "icon" image. (SM)
+  20000126 Allowed "anchor" in all levels. (SM)
+  20000404 Removed the "role" attribute from common-xxx.att. (SM)
+  20000815 Allowed "code" inside "strong" and "em". (SM)
+[Version 1.1]
+  20011212 Used public identifiers for external entities. (SM)
+  20011212 Removed xlink attributes since not used. (SM)
+  20011212 Removed "connect" since not required at this level. (SM)
+  20011218 Added "warning" as a block level object. (SM)
+  20011218 Removed explicitly numbered sections ("s1|s2|s3|s4"). (SM)
+  20011218 Added "section" element. (SM)
+  20011218 Allowed "body" to have blocks without a section. (SM)
+  20011218 Removed "sl" since not really different from "ul". (SM)
+  20020214 Moved empty placeholder entity declarations up front (SNS)
+  20020214 Corrected content model of content.mix parameter entity (SNS)
+  20020519 The DTDs are now modular so various parts can be re-used (SNS)
+  20020606 Made title into an child element of its parent instead of an attribute (SNS)
+  20020613 Move the declarations of ISO character entity sets to module (DC)
+[Version 1.2]
+  20030320 Make @href required for link elements. (SNS)
+  20030320 Allow links (link|jump|fork) and inline elements (br|img|icon|acronym) inside title. (SNS)
+  20030419 Allow inline content (strong|em|code|sub|sup|br|img|icon|acronym|link|jump|fork) in strong and em. (JT)
+  20030419 Allow paragraphs (p|source|note|warning|fixme), table and figure|anchor inside li. (JT)
+  20030419 Allow paragraphs (p|source|note|warning|fixme), lists (ol|ul|dl), table, figure|anchor inside dd. (JT)
+  20030419 Allow paragraphs (p|source|note|warning|fixme), lists (ol|ul|dl), table, figure|anchor inside tables (td|dh). (JT)
+
+==================================================================== -->
+
+
+<!-- =============================================================== -->
+<!-- Include the Common ISO Character Entity Sets -->
+<!-- =============================================================== -->
+
+<!ENTITY % common-charents PUBLIC
+    "-//APACHE//ENTITIES Common Character Entity Sets V1.0//EN"
+    "common-charents-v10.mod">
+%common-charents;
+
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+
+<!ENTITY % document PUBLIC
+    "-//APACHE//ENTITIES Documentation V1.2//EN"
+    "document-v12.mod">
+%document;
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.mod b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.mod
new file mode 100644
index 0000000..1a386a0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/document-v12.mod
@@ -0,0 +1,430 @@
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+
+     Apache Common Documentation elements (Version 1.2)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document
+  type for software documentation for use with the Apache projects.
+
+TYPICAL INVOCATION:
+
+  <!ENTITY % document PUBLIC
+      "-//APACHE//ENTITIES Documentation Vxy//EN"
+      "document-vxy.mod">
+  %document;
+
+  where
+
+    x := major version
+    y := minor version
+
+NOTES:
+
+FIXME:
+
+CHANGE HISTORY:
+[Version 1.0]
+  20020608 Initial version. (SN)
+
+==================================================================== -->
+<!-- =============================================================== -->
+<!-- Useful entities for increased DTD readability -->
+<!-- =============================================================== -->
+<!ENTITY % text "#PCDATA">
+<!-- Entities referred to later on are defined up front -->
+<!ENTITY % markup "strong|em|code|sub|sup">
+<!ENTITY % special-inline "br|img|icon|acronym">
+<!ENTITY % links "link|jump|fork">
+<!ENTITY % paragraphs "p|source|note|warning|fixme">
+<!ENTITY % tables "table">
+<!ENTITY % lists "ol|ul|dl">
+<!ENTITY % special-blocks "figure|anchor">
+<!-- =============================================================== -->
+<!-- Entities for general XML compliance -->
+<!-- =============================================================== -->
+<!-- Common attributes
+        Every element has an ID attribute (sometimes required,
+        but usually optional) for links. %common.att;
+        is for common attributes where the ID is optional, and
+        %common-idreq.att; is for common attributes where the
+        ID is required.
+-->
+<!ENTITY % common.att 'id                     ID              #IMPLIED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!ENTITY % common-idreq.att 'id                     ID              #REQUIRED
+         xml:lang               NMTOKEN         #IMPLIED'>
+<!-- xml:space attribute ===============================================
+        Indicates that the element contains white space
+        that the formatter or other application should retain,
+        as appropriate to its function.
+==================================================================== -->
+<!ENTITY % xmlspace.att 'xml:space (default|preserve) #FIXED "preserve"'>
+<!-- def attribute =====================================================
+        Points to the element where the relevant definition can be
+        found, using the IDREF mechanism.  %def.att; is for optional
+        def attributes, and %def-req.att; is for required def
+        attributes.
+==================================================================== -->
+<!ENTITY % def.att 'def                    IDREF           #IMPLIED'>
+<!ENTITY % def-req.att 'def                    IDREF           #REQUIRED'>
+<!-- ref attribute =====================================================
+        Points to the element where more information can be found,
+        using the IDREF mechanism.  %ref.att; is for optional
+        ref attributes, and %ref-req.att; is for required ref
+        attributes.
+================================================================== -->
+<!ENTITY % ref.att 'ref                    IDREF           #IMPLIED'>
+<!ENTITY % ref-req.att 'ref                    IDREF           #REQUIRED'>
+<!-- =============================================================== -->
+<!-- Entities for general usage -->
+<!-- =============================================================== -->
+<!-- Key attribute =====================================================
+        Optionally provides a sorting or indexing key, for cases when
+        the element content is inappropriate for this purpose.
+==================================================================== -->
+<!ENTITY % key.att 'key                    CDATA           #IMPLIED'>
+<!-- Title attributes ==================================================
+        Indicates that the element requires to have a title attribute.
+==================================================================== -->
+<!ENTITY % title.att 'title                  CDATA           #REQUIRED'>
+<!-- Name attributes ==================================================
+        Indicates that the element requires to have a name attribute.
+==================================================================== -->
+<!ENTITY % name.att 'name                   CDATA           #REQUIRED'>
+<!-- Email attributes ==================================================
+        Indicates that the element requires to have an email attribute.
+==================================================================== -->
+<!ENTITY % email.att 'email                  CDATA           #REQUIRED'>
+<!-- Link attributes ===================================================
+        Indicates that the element requires to have hyperlink attributes.
+==================================================================== -->
+<!ENTITY % link.att 'href      CDATA             #REQUIRED
+         role      CDATA                         #IMPLIED
+         title     CDATA                         #IMPLIED '>
+<!-- =============================================================== -->
+<!-- General definitions -->
+<!-- =============================================================== -->
+<!-- A person is a general unparsed human entity -->
+<!ELEMENT person EMPTY>
+<!ATTLIST person
+  %common.att; 
+  %name.att; 
+  %email.att; 
+>
+<!-- =============================================================== -->
+<!-- Content definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.inline "">
+<!ENTITY % link-content.mix "%text;|%markup;|%special-inline; %local.inline;">
+<!ENTITY % content.mix "%link-content.mix;|%links;">
+<!-- ==================================================== -->
+<!-- Phrase Markup -->
+<!-- ==================================================== -->
+<!-- Strong (typically bold) -->
+<!ELEMENT strong (%content.mix;)*>
+<!ATTLIST strong
+  %common.att; 
+>
+<!-- Emphasis (typically italic) -->
+<!ELEMENT em (%content.mix;)*>
+<!ATTLIST em
+  %common.att; 
+>
+<!-- Code (typically monospaced) -->
+<!ELEMENT code (%text;)>
+<!ATTLIST code
+  %common.att; 
+>
+<!-- Superscript (typically smaller and higher) -->
+<!ELEMENT sup (%text;)>
+<!ATTLIST sup
+  %common.att; 
+>
+<!-- Subscript (typically smaller and lower) -->
+<!ELEMENT sub (%text;)>
+<!ATTLIST sub
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Hypertextual Links -->
+<!-- ==================================================== -->
+<!-- hyperlink (equivalent of <a ...>) -->
+<!ELEMENT link (%link-content.mix;)*>
+<!ATTLIST link
+  %common.att; 
+  %link.att; 
+>
+<!-- windows-replacing link (equivalent of <a ... target="_top">) -->
+<!ELEMENT jump (%link-content.mix;)*>
+<!ATTLIST jump
+  %common.att; 
+  %link.att; 
+>
+<!-- window-forking link (equivalent of <a ... target="_blank">) -->
+<!ELEMENT fork (%link-content.mix;)*>
+<!ATTLIST fork
+  %common.att; 
+  %link.att; 
+>
+
+<!-- ==================================================== -->
+<!-- Specials -->
+<!-- ==================================================== -->
+<!-- Breakline Object (typically forces line break) -->
+<!ELEMENT br EMPTY>
+<!ATTLIST br
+  %common.att; 
+>
+<!-- Image Object (typically an inlined image) -->
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  usemap CDATA #IMPLIED
+  ismap (ismap) #IMPLIED
+  %common.att; 
+>
+<!-- Image Icon (typically an inlined image placed as graphical item) -->
+<!ELEMENT icon EMPTY>
+<!ATTLIST icon
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  %common.att; 
+>
+<!-- Acronym (in modern browsers, will have rollover text) -->
+<!ELEMENT acronym (%text;)*>
+<!ATTLIST acronym
+  title CDATA #REQUIRED
+  %common.att; 
+>
+
+<!-- =============================================================== -->
+<!-- Blocks definitions -->
+<!-- =============================================================== -->
+<!ENTITY % local.blocks "">
+<!ENTITY % blocks "%paragraphs;|%tables;|%lists;|%special-blocks; %local.blocks;">
+
+<!-- Flow mixes block and inline -->
+<!ENTITY % flow "%content.mix;|%blocks;">
+
+<!-- ==================================================== -->
+<!-- Paragraphs -->
+<!-- ==================================================== -->
+<!-- Text Paragraph (normally vertically space delimited. Space can be preserved.) -->
+<!ELEMENT p (%content.mix;)*>
+<!ATTLIST p
+  %common.att; 
+  xml:space (default|preserve) #IMPLIED
+>
+<!-- Source Paragraph (normally space is preserved) -->
+<!ELEMENT source (%content.mix;)*>
+<!ATTLIST source
+  %common.att; 
+  %xmlspace.att; 
+>
+<!-- Note Paragraph (normally shown encapsulated) -->
+<!ELEMENT note (%content.mix;)*>
+<!ATTLIST note
+  label CDATA #IMPLIED
+  %common.att; 
+>
+<!-- Warning Paragraph (normally shown with eye-catching colors) -->
+<!ELEMENT warning (%content.mix;)*>
+<!ATTLIST warning
+  label CDATA #IMPLIED
+  %common.att; 
+>
+<!-- Fixme Paragraph (normally not shown) -->
+<!ELEMENT fixme (%content.mix;)*>
+<!ATTLIST fixme
+  author CDATA #REQUIRED
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Tables -->
+<!-- ==================================================== -->
+<!-- Attributes that indicate the spanning of the table cell -->
+<!ENTITY % cell.span 'colspan CDATA "1"
+         rowspan CDATA "1"'>
+<!-- Table element -->
+<!ELEMENT table (caption?, tr+)>
+<!ATTLIST table
+  %common.att; 
+>
+<!-- The table title -->
+<!ELEMENT caption (%content.mix;)*>
+<!ATTLIST caption
+  %common.att; 
+>
+<!-- The table row element -->
+<!ELEMENT tr (th | td)+>
+<!ATTLIST tr
+  %common.att; 
+>
+<!-- The table row header element -->
+<!ELEMENT th (%flow;)*>
+<!ATTLIST th
+  %common.att; 
+  %cell.span; 
+>
+<!-- The table row description element -->
+<!ELEMENT td (%flow;)*>
+<!ATTLIST td
+  %common.att; 
+  %cell.span; 
+>
+<!-- ==================================================== -->
+<!-- Lists -->
+<!-- ==================================================== -->
+<!-- List item -->
+<!ELEMENT li (%flow;)*>
+<!ATTLIST li
+  %common.att; 
+>
+<!-- Unordered list (typically bulleted) -->
+<!ELEMENT ul (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ul
+  %common.att; 
+  spacing (normal | compact) #IMPLIED
+>
+<!-- Ordered list (typically numbered) -->
+<!ELEMENT ol (li | %lists;)+>
+<!--    spacing attribute:
+            Use "normal" to get normal vertical spacing for items;
+            use "compact" to get less spacing.  The default is dependent
+            on the stylesheet. -->
+<!ATTLIST ol
+  %common.att; 
+  spacing (normal | compact) #IMPLIED
+>
+<!-- Definition list (typically two-column) -->
+<!ELEMENT dl (dt, dd)+>
+<!ATTLIST dl
+  %common.att; 
+>
+<!-- Definition term -->
+<!ELEMENT dt (%content.mix;)*>
+<!ATTLIST dt
+  %common.att; 
+>
+<!-- Definition description -->
+<!ELEMENT dd (%flow; )*>
+<!ATTLIST dd
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Special Blocks -->
+<!-- ==================================================== -->
+<!-- Image Block (typically a separated and centered image) -->
+<!ELEMENT figure EMPTY>
+<!ATTLIST figure
+  src CDATA #REQUIRED
+  alt CDATA #REQUIRED
+  height CDATA #IMPLIED
+  width CDATA #IMPLIED
+  usemap CDATA #IMPLIED
+  ismap (ismap) #IMPLIED
+  align CDATA #IMPLIED
+  %common.att; 
+>
+<!-- anchor point (equivalent of <a name="...">, typically not rendered) -->
+<!ELEMENT anchor EMPTY>
+<!ATTLIST anchor
+  %common-idreq.att; 
+>
+<!-- =============================================================== -->
+<!-- Document -->
+<!-- =============================================================== -->
+<!ELEMENT document (header, body, footer?)>
+<!ATTLIST document
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Header -->
+<!-- ==================================================== -->
+<!ENTITY % local.headers "">
+<!ELEMENT header (title, subtitle?, version?, type?, authors?,
+                      notice*, abstract? %local.headers;)>
+<!ATTLIST header
+  %common.att; 
+>
+<!ELEMENT title (%text; | %markup; | %links; | %special-inline;)*>
+<!ATTLIST title
+  %common.att; 
+>
+<!ELEMENT subtitle (%text; | %markup;)*>
+<!ATTLIST subtitle
+  %common.att; 
+>
+<!ELEMENT version (%text;)>
+<!ATTLIST version
+  %common.att;
+  major CDATA #IMPLIED
+  minor CDATA #IMPLIED
+  fix CDATA #IMPLIED
+  tag CDATA #IMPLIED
+>
+<!ELEMENT type (%text;)>
+<!ATTLIST type
+  %common.att; 
+>
+<!ELEMENT authors (person+)>
+<!ATTLIST authors
+  %common.att; 
+>
+<!ELEMENT notice (%content.mix;)*>
+<!ATTLIST notice
+  %common.att; 
+>
+<!ELEMENT abstract (%content.mix;)*>
+<!ATTLIST abstract
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Body -->
+<!-- ==================================================== -->
+<!ENTITY % local.sections "">
+<!ENTITY % sections "section %local.sections;">
+<!ELEMENT body (%sections; | %blocks;)+>
+<!ATTLIST body
+  %common.att; 
+>
+<!ELEMENT section (title, (%sections; | %blocks;)*)>
+<!ATTLIST section
+  %common.att; 
+>
+<!-- ==================================================== -->
+<!-- Footer -->
+<!-- ==================================================== -->
+<!ENTITY % local.footers "">
+<!ELEMENT footer (legal %local.footers;)>
+<!ELEMENT legal (%content.mix;)*>
+<!ATTLIST legal
+  %common.att; 
+>
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/faq-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/faq-v10.dtd
new file mode 100644
index 0000000..5289d0b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/faq-v10.dtd
@@ -0,0 +1,81 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+     
+     Apache FAQ DTD (Version 1.0)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document 
+  type for software FAQ's for use with the Apache projects.  
+  It is an XML-compliant DTD and it's maintained by the Apache XML 
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD FAQ Vx.yz//EN"
+       "http://xml.apache.org/DTD/faq-vxyz.dtd">
+
+  where 
+  
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+      
+NOTES:  
+  FAQs represent a powerful knowledge base and a very good way of solving
+  common user problems reducing messages on mail lists and reducing the effort
+  required for software installation and usage. Thid DTD want to be a common
+  format for FAQ interchange to allow FAQ-O-Matic-type workgroup services to 
+  be published in other formats as well as enhancing data interchange.
+  
+FIXME:
+
+CHANGE HISTORY:
+  19991129 Initial version. (SM)
+    
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Extend the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!-- FIXME (SM): this is hardcoding. Find a better way of doing this
+     possibly using public identifiers -->
+<!ENTITY % document-dtd SYSTEM "document-v10.dtd">
+%document-dtd;
+
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT faqs (authors?, faq)+>
+<!ATTLIST faqs %common.att; 
+               %title.att;>
+
+    <!ELEMENT faq (question, answer)>
+    <!ATTLIST faq %common.att;>
+    
+        <!ELEMENT question (%content.mix;)*>
+        <!ATTLIST question %common.att;>
+            
+        <!ELEMENT answer (%blocks;)*>
+        <!ATTLIST answer author IDREF #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/javadoc-v04draft.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/javadoc-v04draft.dtd
new file mode 100644
index 0000000..0aae013
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/javadoc-v04draft.dtd
@@ -0,0 +1,258 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+     
+     Apache JavaDoc DTD (version 0.4-draft)
+
+PURPOSE:
+  This DTD is designed to capture the output of JavaDoc as an XML document
+  through the use of the JavaDocXML Doclet. The hope is that by having the
+  JavaDoc documentation in an XML format, it will be easier for application
+  developers working with XML to treat their java source documentation in the
+  same way they treat any other XML document within their publication framework.
+  
+  This DTD should reflect the information contained within the RootDoc object 
+  passed to the JavaDocXML Doclet by JavaDoc. The RootDoc object and the rest 
+  of the javaDoc Doclet API is specified at
+  
+  http://java.sun.com/products/jdk/1.2/docs/tooldocs/javadoc/doclet/index.html
+  
+  The only information that appears to be difficult to derive from this DTD
+  that is easy to obtain from the RootDoc object is the information about 
+  serialization. However, this information should be derivable by manually 
+  looking for the correct serialization methods and other related structures.
+  
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD JavaDoc Vx.yz//EN"
+       "javadoc-vxyz.dtd">
+
+  where 
+  
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+      
+NOTES:  
+  The authors would like to thank the Cocoon's mail list subscribers for 
+  providing such great support and feedback for this DTD.
+  
+FIXME:
+
+CHANGE HISTORY:
+  199909?? Original idea of XML doclet. (KM)
+  199910?? Initial version of this DTD. (KM)
+  19991129 Cleaned up DTD. (SM)
+    
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Common Attribute Entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % name 'name CDATA #REQUIRED'>
+<!ENTITY % dimension 'dimension CDATA #REQUIRED'>
+
+<!ENTITY % abstract 'abstract (true | false) "false"'>
+<!ENTITY % anonymous 'anonymous (true | false) "false"'>
+<!ENTITY % synthetic 'synthetic (true | false) "false"'>
+<!ENTITY % static 'static (true | false) "false"'>
+<!ENTITY % final 'final (true | false) "false"'>
+<!ENTITY % transient 'transient (true | false) "false"'>
+<!ENTITY % volatile 'volatile (true | false) "false"'>
+<!ENTITY % native 'native (true | false) "false"'>
+<!ENTITY % synchronized 'synchronized (true | false) "false"'>
+
+<!ENTITY % access 'access (private | package | protected | public) "package"'>
+<!ENTITY % class.access 'access (package | public) "package"'>
+
+<!ENTITY % extensibility 'extensibility (abstract | final | default) "default"'>
+
+
+<!-- =============================================================== -->
+<!-- Javadoc -->
+<!-- =============================================================== -->
+
+<!ELEMENT javadoc (package*, class*, interface*)>
+
+<!-- =============================================================== -->
+<!-- Package -->
+<!-- =============================================================== -->
+
+<!ELEMENT package (doc?, package*, class*, interface*)>
+<!ATTLIST package %name;>
+
+<!-- =============================================================== -->
+<!-- Class -->
+<!-- =============================================================== -->
+
+<!ELEMENT class (doc?,
+                 extends_class?,
+                 implements?,
+                 field*, 
+                 constructor*, 
+                 method*,
+                 innerclass*)>
+<!ATTLIST class
+          %name;
+          %extensibility;
+          %class.access;>
+
+<!ELEMENT extends_class (classref+)>
+          
+<!ELEMENT innerclass (doc?,
+                      extends?,
+                      implements?,
+                      field*, 
+                      constructor*, 
+                      method*)>
+<!ATTLIST innerclass
+          %name;
+          %access;
+          %abstract;
+          %anonymous;
+          %final;
+          %static;>
+          
+<!-- =============================================================== -->
+<!-- Interface -->
+<!-- =============================================================== -->
+          
+<!ELEMENT interface (doc?,
+                     extends_interface?,
+                     field*,
+                     method*)>
+<!ATTLIST interface
+          %name;
+          %access;>
+          
+<!ELEMENT extends_interface (interfaceref+)>
+
+<!-- =============================================================== -->
+<!-- Elements -->
+<!-- =============================================================== -->
+
+<!ELEMENT implements (interfaceref+)>
+
+<!ELEMENT throws (classref)+>
+
+<!ELEMENT classref EMPTY>
+<!ATTLIST classref %name;>
+          
+<!ELEMENT interfaceref EMPTY>
+<!ATTLIST interfaceref %name;>
+          
+<!ELEMENT methodref EMPTY>
+<!ATTLIST methodref %name;>
+          
+<!ELEMENT packageref EMPTY>
+<!ATTLIST packageref %name;>
+          
+<!ELEMENT primitive EMPTY>
+<!ATTLIST primitive
+          type (void | boolean | int | long | byte | short | double | float | char) #REQUIRED>
+          
+<!ELEMENT field (doc?, (classref | interfaceref | primitive))>
+<!ATTLIST field
+          %name;
+          %access;
+          %dimension;
+          %synthetic;
+          %static;
+          %final;
+          %transient;
+          %volatile;>
+          
+<!ELEMENT constructor (doc?, parameter*, throws*)>
+<!ATTLIST constructor
+          %name;
+          %access;
+          %synthetic;>
+          
+<!ELEMENT method (doc?, returns, parameter*, throws*)>
+<!ATTLIST method
+          %name;
+          %access;
+          %extensibility;
+          %native;
+          %synthetic;
+          %static;
+          %synchronized;>
+          
+<!ELEMENT returns (classref | interfaceref | primitive)>
+<!ATTLIST returns %dimension;>
+          
+<!ELEMENT parameter (classref | interfaceref | primitive)>
+<!ATTLIST parameter
+          %name;
+          %final;
+          %dimension;>
+          
+<!ELEMENT dimension (#PCDATA)>
+
+<!ELEMENT doc (#PCDATA | 
+               linktag |
+               authortag |
+               versiontag |
+               paramtag |
+               returntag |
+               exceptiontag |
+               throwstag |
+               seetag |
+               sincetag |
+               deprecatedtag |
+               serialtag |
+               serialfieldtag |
+               serialdatatag)*>
+               
+<!ELEMENT linktag (#PCDATA)>
+<!ATTLIST linktag
+          src CDATA #REQUIRED>
+          
+<!ELEMENT authortag (#PCDATA | linktag)*>
+
+<!ELEMENT versiontag (#PCDATA | linktag)*>
+
+<!ELEMENT paramtag (#PCDATA | linktag)*>
+<!ATTLIST paramtag %name;>
+          
+<!ELEMENT returntag (#PCDATA | linktag)*>
+
+<!ELEMENT exceptiontag (#PCDATA | classref | linktag)*>
+
+<!ELEMENT throwstag (#PCDATA | classref | linktag)*>
+
+<!ELEMENT seetag (#PCDATA | linktag)*>
+<!ATTLIST seetag
+          src CDATA #REQUIRED>
+          
+<!ELEMENT sincetag (#PCDATA | linktag)*>
+
+<!ELEMENT deprecatedtag (#PCDATA | linktag)*>
+
+<!ELEMENT serialtag (#PCDATA | linktag)*>
+
+<!ELEMENT serialfieldtag (#PCDATA | linktag)*>
+<!ATTLIST serialfieldtag
+          fieldname CDATA #REQUIRED
+          fieldtype CDATA #REQUIRED>
+          
+<!ELEMENT serialdatatag (#PCDATA | linktag)*>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/open-office/dummy.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/open-office/dummy.dtd
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/open-office/dummy.dtd
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/roles-v01.rng b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/roles-v01.rng
new file mode 100644
index 0000000..924af60
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/roles-v01.rng
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+         xmlns="http://relaxng.org/ns/structure/1.0">
+
+<!-- ===================================================================
+
+     Apache Cocoon Roles RELAX NG grammar (Version 0.1)
+
+PURPOSE:
+  DRAFT RELAX NG grammar for the Cocoon cocoon.roles configuration files.
+
+NOTES:
+
+FIXME:
+- 
+
+CHANGE HISTORY:
+20021030 V0.1 Initial version. (DC)
+==================================================================== -->
+  <define name="role-list">
+    <element name="role-list">
+      <ref name="attlist.role-list"/>
+      <oneOrMore>
+        <ref name="role"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="attlist.role-list" combine="interleave">
+    <empty/>
+  </define>
+  <define name="role">
+    <element name="role">
+      <ref name="attlist.role"/>
+      <zeroOrMore>
+        <ref name="hint"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="hint">
+    <element name="hint">
+      <ref name="attlist.hint"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="attlist.role" combine="interleave">
+    <attribute name="name"/>
+    <attribute name="shorthand"/>
+    <optional>
+      <attribute name="default-class"/>
+    </optional>
+  </define>
+  <define name="attlist.hint" combine="interleave">
+    <attribute name="shorthand"/>
+    <attribute name="class"/>
+  </define>
+  <start>
+    <choice>
+      <ref name="role-list"/>
+    </choice>
+  </start>
+</grammar>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/sitemap-v06.rng b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/sitemap-v06.rng
new file mode 100644
index 0000000..82e489b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/sitemap-v06.rng
@@ -0,0 +1,2180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2002-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" 
+         xmlns:sch="http://www.ascc.net/xml/schematron"
+         xmlns="http://relaxng.org/ns/structure/1.0" 
+         xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" 
+         xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+ <sch:ns uri="http://apache.org/cocoon/sitemap/1.0" prefix="xmap"/>
+<!-- ===================================================================
+
+Apache Cocoon Sitemap RELAX NG grammar, with embedded Schematron rules
+Version 0.6
+
+PURPOSE:
+  DRAFT RELAX NG grammar for the Cocoon2 sitemap.xmap files.
+
+
+NOTES:
+* ATTENTION: The initial (v0.4) grammar was generated from sitemap-v04.dtd, 
+  which in turn was reverse-engineered by hand from the various
+  sitemap.xmap instances included in the current distribution. This is
+  just an attempt to document the existing rules for sitemap structure.
+  V0.5 has been enhanced to use stricter than were possible with the DTD.
+  A proper design process is still, still required.
+* Needed by XML editing tools for creation of reliable documents.
+* Can generate WXS from this grammar for the use of XML editors which
+  do not support RELAX NG.
+* The big questions (still) are: 
+  - What possibilities were missed because they were not included in the
+    default sitemaps?
+  - What in the default sitemap.xmap files is mandatory versus optional?
+  - What elements/attributes need their rules tightened?
+
+FIXME:
+- map:act is used in various contexts, so it has a loose definition
+- Completely rewrite this grammar looking from the application
+  point-of-view (do not rely on this temporary initial grammar)
+- align elements and attributes with sitemap*.xsl
+- review all xdocs/userdocs/generators/*.xml etc. and sync with this grammar
+- Add similar changes to those of 2002-11-29 for other component declarations
+  See Bruno email
+  http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=103847911212458
+
+====================================================================
+-->
+
+
+<!-- =============================================================== -->
+<!-- Common Attributes -->
+<!-- =============================================================== -->
+<!-- CPA: univeral attributes possessed by all elements -->
+<!-- CPA: id is for use by sitebuilder and others, but really it ought to be -->
+<!--      of type ID (I'm guessing) -->
+  <define name="universal.attr">
+    <optional>
+      <attribute name="id" >
+        <data type="string" />
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: the default attribute is common, and where it occurs is nearly always the same -->
+  <define name="default.attr">
+    <optional>
+      <attribute name="default">
+        <data type="string" /> 
+    	  <!-- CPA: in fact the default must always match the name attribute
+    	  of one of it's child elements. We will rely on a schematron schema to check
+    	  this (we cannot use ID/IDREF as there are multiple namespaces
+    	  e.g. map:generator uses a different namespace to
+    	  map:transformer) - NO - can't be done due to sitemap
+    	  inheritance -->
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: the name and src attributes are common, and where they occur
+          are always CDATA, but sometimes optional -->
+  <define name="src.attr">
+    <attribute name="src">
+      <data type="string"/>
+    </attribute>
+  </define>
+  <define name="optsrc.attr">
+    <optional>
+      <attribute name="src">
+      <data type="string"/>
+    </attribute>
+    </optional>
+  </define>
+
+  <define name="name.attr">
+    <attribute name="name">
+      <data type="string"/> <!-- CPA: see comment on default.attr -->
+    </attribute>
+  </define>
+  <define name="optname.attr">
+    <optional>
+    <attribute name="name">
+      <data type="string"/> <!-- CPA: see comment on default.attr -->
+    </attribute>
+    </optional>
+  </define>
+
+  <define name="uri.attr">
+    <attribute name="uri">
+      <data type="string"/>
+    </attribute>
+  </define>
+  <define name="opturi.attr">
+    <optional>
+      <attribute name="uri">
+      <data type="string"/>
+    </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: pool attributes from Excalibur's PoolableComponentHandler -->
+<!--      Defaults are set in cocoon.xconf -->
+  <define name="pool.attr">
+    <optional>
+      <attribute name="pool-max">
+        <data type="positiveInteger" />
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="pool-min">
+        <data type="nonNegativeInteger" />
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="pool-grow">
+        <data type="positiveInteger" />
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: logger attribute - default is set in cocoon.xconf -->
+  <define name="logger.attr">
+    <optional>
+      <attribute name="logger">
+        <data type="string" /> <!-- CPA: a Java class name -->
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: these three only occur together  -->
+<!-- they are used in AggregateNodeBuilder -->
+  <define name="aggregate.attr">
+    <optional>
+      <attribute name="element">
+        <data type="string" />
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="ns">
+        <data type="string" />
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="prefix">
+        <data type="string" />
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: attributes that occur more than once, and are always defined -->
+<!--      in the same way -->
+
+  <define name="value.attr">
+    <attribute name="value"/> 
+    <!-- CPA: I think we cannot restrict the datatype,
+              unless we do it on an element-by-element basis -->
+  </define>
+
+  <define name="mime.attr">
+    <optional>
+      <attribute name="mime-type"> 
+        <!-- restrict further in specific cases -->
+        <data type="string" /> <!-- CPA: tackle this in V0.6 -->
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="label.attr">
+    <optional>
+      <attribute name="label">
+        <data type="string"/> 
+<!-- DC: temporarily changed to "string" to avoid mass of validation errors
+        <data type="NMTOKEN"/> 
+-->
+        <!-- CPA: must match a component name , use schematron to enforce -->
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="type.attr">
+    <optional>
+      <attribute name="type">
+        <data type="string"/>
+      </attribute>
+    </optional>
+  </define>
+
+<!-- CPA: resource is used both in CallNodeBuilder and -->
+<!--      RedirectToNodeBuilder. It has no default -->
+  <define name="resource.attr">
+    <optional>
+      <attribute name="resource">
+        <data type="string" />
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="component.attr">
+    <ref name="label.attr"/>
+    <ref name="logger.attr"/>
+    <ref name="pool.attr"/>
+  </define>
+
+<!-- CPA: now for element contents -->
+
+  <define name="pipe.contents">
+    <zeroOrMore> <!-- CPA: look into this in V0.6 - I think, must use schematron -->
+      <choice>
+        <ref name="map.parameter"/>
+        <ref name="map.act"/>
+        <ref name="map.match"/>
+        <ref name="map.select"/>
+        <ref name="map.call"/>
+        <ref name="map.redirect-to"/>
+        <ref name="map.read"/>
+        <ref name="map.aggregate"/>
+        <ref name="map.generate"/>
+        <ref name="map.transform"/>
+        <ref name="map.serialize"/>
+        <ref name="map.mount"/>
+      </choice>
+    </zeroOrMore>
+  </define>
+
+<!-- CPA: contents confirmed by inspection of HtmlGenerator.java -->
+  <define name="htmlGenerator.contents">
+    <optional><ref name="jtidy-config"/></optional>
+  </define>
+
+<!-- CPA: contents confirmed by inspection of TraxTransformer.java -->
+  <define name="traxTransformer.contents">
+    <optional><ref name="use-request-parameters"/></optional>
+    <optional><ref name="use-cookies"/></optional>
+    <optional><ref name="use-browser-capabilities-db"/></optional>
+    <optional><ref name="use-session-info"/></optional>
+    <optional><ref name="use-deli"/></optional>
+    <optional><ref name="xslt-processor-role"/></optional>
+    <optional><ref name="transformer-factory"/></optional> 
+  </define>
+
+<!-- CPA: contents confirmed by inspection of I18nTransformer.java -->
+  <define name="i18nTransformer.contents">
+    <optional><ref name="catalogues"/></optional>
+    <optional><ref name="catalogue-name"/></optional>
+    <optional><ref name="catalogue-location"/></optional>
+    <optional><ref name="untranslated-text"/></optional>
+    <optional><ref name="cache-at-startup"/></optional>
+  </define>
+
+<!-- CPA: contents confirmed by inspection of XSLTProcessorImpl.java -->
+<!--      N.B. these appear in the source as if they were parameter -->
+<!--      tags, so I'm not sure if this is perfectly correct. -->
+  <define name="xsltTransformer.contents">
+    <optional><ref name="use-store"/></optional>
+    <optional><ref name="incremental-processing"/></optional>
+  </define>
+
+<!-- CPA: contents confirmed by inspection of EncodeURLTransformer.java -->
+  <define name="encodeURLTransformer.contents">
+    <optional><ref name="include-name"/></optional>
+    <optional><ref name="exclude-name"/></optional>
+  </define>
+
+  <define name="linkRewriterTransformer.contents">
+    <zeroOrMore>
+      <choice>
+        <element name="link-attrs"><text/></element>
+        <element name="schemes"><text/></element>
+        <element name="exclude-schemes"><text/></element>
+        <element name="bad-link-str"><text/></element>
+        <element name="input-module">
+          <ref name="anyAttribute"/>
+          <zeroOrMore>
+            <ref name="anyElement"/>
+          </zeroOrMore>
+        </element>
+      </choice>
+    </zeroOrMore>
+  </define>
+
+  <define name="IdGeneratorTransformer.contents">
+    <zeroOrMore>
+      <element name="element">
+        <text/>
+      </element>
+      <element name="id">
+        <text/>
+      </element>
+      <optional>
+        <element name="id-attr">
+          <text/>
+        </element>
+      </optional>
+    </zeroOrMore>
+  </define>
+
+<!-- CH: contents confirmed by inspection of Web3RfcTransformer.java -->
+  <define name="web3RfcTransformer.contents">
+    <optional><element name="system"><text/></element></optional>
+  </define>
+
+  <define name="simpleFormExtractTransformer.contents">
+    <optional>
+       <element name="output">
+          <ref name="name.attr"/>
+          <text/>
+       </element>
+    </optional>
+  </define>
+
+<!-- VG: contents of TagTransformer from the scratchpad -->
+  <define name="tagTransformer.contents">
+    <optional>
+       <element name="transformer-hint">
+          <text/>
+       </element>
+    </optional>
+  </define>
+
+<!-- CPA: contents confirmed by inspection of AbstractTextSerializer.java -->
+  <define name="textSerializer.contents">
+    <optional><ref name="cdata-section-elements"/></optional>
+    <optional><ref name="doctype-public"/></optional>
+    <optional><ref name="doctype-system"/></optional>
+    <optional><ref name="encoding"/></optional>
+    <optional><ref name="indent"/></optional>
+    <optional><ref name="media-type"/></optional>
+    <optional><ref name="method"/></optional>
+    <optional><ref name="omit-xml-declaration"/></optional>
+    <optional><ref name="standalone"/></optional>
+    <optional><ref name="version"/></optional>
+  </define>
+
+  <define name="svg2jpegSerializer.contents">
+    <optional>
+       <element name="parameter">
+          <attribute name="name"/>
+          <attribute name="type">
+            <value type="string">float</value>
+          </attribute>
+          <attribute name="value"/>
+       </element>
+    </optional>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Sitemap -->
+<!-- =============================================================== -->
+<!-- CPA: contents are all optional, as they can be inherited from the parent sitemap -->
+  <define name="map.sitemap">
+    <element name="map:sitemap" xmlns:map="http://apache.org/cocoon/sitemap/1.0" >
+      <ref name="map.sitemap.attlist"/>
+      <interleave>
+        <optional>
+          <ref name="map.components"/>
+        </optional>
+        <optional>
+          <ref name="map.views"/>
+        </optional>
+        <optional>
+          <ref name="map.resources"/>
+        </optional>
+        <optional>
+          <ref name="map.action-sets"/>
+        </optional>
+        <zeroOrMore>
+          <ref name="map.flow"/>
+        </zeroOrMore>
+        <ref name="map.pipelines"/>
+      </interleave>
+    </element>
+  </define>
+  <define name="map.sitemap.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <empty/>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Components -->
+<!-- =============================================================== -->
+<!-- CPA: map:components are optional, as they can be inherited from the parent sitemap -->
+<!-- CPA: Notes on ComponentSelector.java: Flow-Interpreters are not mentioned -->
+<!-- CPA: now 0 or 1 of each, in any order -->
+  <define name="map.components">
+    <element name="map:components">
+      <ref name="map.components.attlist"/>
+      <interleave>
+        <optional>
+          <ref name="map.generators"/>
+        </optional>
+        <optional>
+          <ref name="map.transformers"/>
+        </optional>
+        <optional>
+          <ref name="map.readers"/>
+        </optional>
+        <optional>
+          <ref name="map.serializers"/>
+        </optional>
+        <optional>
+          <ref name="map.matchers"/>
+        </optional>
+        <optional>
+          <ref name="map.selectors"/>
+        </optional>
+        <optional>
+          <ref name="map.actions"/>
+        </optional>
+        <optional>
+          <ref name="map.flow-interpreters"/>
+        </optional>
+        <optional>
+          <ref name="map.pipes"/>
+        </optional>
+      </interleave>
+    </element>
+  </define>
+  <define name="map.components.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+<!-- Generators ======================================== -->
+  <define name="map.generators">
+    <element name="map:generators">
+      <ref name="map.generators.attlist"/>
+      <zeroOrMore> 
+        <ref name="map.generator"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.generators.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.generator">
+    <element name="map:generator">
+      <ref name="map.generator.attlist"/>
+      <interleave>
+        <ref name="htmlGenerator.contents"/>
+      </interleave>
+      <zeroOrMore> 
+        <ref name="parameter"/>
+      </zeroOrMore>
+      <empty/>
+    </element>
+  </define>
+  <define name="map.generator.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="jtidy-config">
+    <element name="jtidy-config">
+      <text/>
+    </element>
+  </define>
+
+<!-- Transformers ====================================== -->
+  <define name="map.transformers">
+    <element name="map:transformers">
+      <ref name="map.transformers.attlist"/>
+      <zeroOrMore>
+        <ref name="map.transformer"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.transformers.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+<!-- CPA: Some transformers have children, others take parameter -->
+<!--      children on the map:transform element -->
+<!--      SourceWritingTransformer.java appears to look for a -->
+<!--      serializer child, but there are no examples so I have TODO (V0.6) -->
+<!--      omitted it for now. mapping comes from castor -->
+
+  <define name="map.transformer">
+    <element name="map:transformer">
+      <ref name="map.transformer.attlist"/>
+        <interleave>
+          <ref name="traxTransformer.contents"/>
+          <ref name="xsltTransformer.contents"/>
+          <ref name="i18nTransformer.contents"/>
+          <ref name="encodeURLTransformer.contents"/>
+          <ref name="linkRewriterTransformer.contents"/>
+          <ref name="web3RfcTransformer.contents"/>
+          <ref name="simpleFormExtractTransformer.contents"/>
+          <ref name="tagTransformer.contents"/>
+          <ref name="IdGeneratorTransformer.contents"/>
+          <optional><ref name="mapping"/></optional>
+          <zeroOrMore>
+           <ref name="parameter"/>
+          </zeroOrMore>
+        </interleave>
+    </element>
+  </define>
+  <define name="map.transformer.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="mime.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="use-store">
+  <!-- CPA: from  XSLTProcessorImpl.java -->  
+    <element name="use-store" a:defaultValue="true" >
+      <ref name="use-store.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="use-store.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="use-request-parameters">
+  <!-- CPA: from TraxTransformer.java -->
+    <element name="use-request-parameters" a:defaultValue="false">
+      <ref name="use-request-parameters.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>      
+    </element>
+  </define>
+  <define name="use-request-parameters.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="use-browser-capabilities-db">
+    <element name="use-browser-capabilities-db"  a:defaultValue="false">
+      <ref name="use-browser-capabilities-db.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="use-browser-capabilities-db.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="catalogues">
+    <element name="catalogues">
+      <ref name="catalogues.attlist"/>
+      <oneOrMore>
+        <ref name="catalogue"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="catalogues.attlist" combine="interleave">
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="catalogue">
+    <element name="catalogue">
+      <ref name="catalogue.attlist"/>
+    </element>
+  </define>
+  <define name="catalogue.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <attribute name="location"/>
+  </define>
+
+  <define name="catalogue-name">
+    <element name="catalogue-name">
+      <ref name="catalogue-name.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="catalogue-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="catalogue-location">
+    <element name="catalogue-location">
+      <ref name="catalogue-location.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="catalogue-location.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="use-deli">
+  <!-- CPA: this parameter has disappeared from the source TODO: clarify -->
+    <element name="use-deli">
+      <ref name="use-deli.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="use-deli.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="xslt-processor-role">
+    <element name="xslt-processor-role">
+      <ref name="xslt-processor-role.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="xslt-processor-role.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="cache-at-startup">
+  <!-- CPA: from XMLResourceBundleFactory and I18nTransformer -->
+    <element name="cache-at-startup" a:defaultValue="false">
+      <ref name="cache-at-startup.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="cache-at-startup.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="mapping">
+    <element name="mapping">
+      <ref name="mapping.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="mapping.attlist" combine="interleave">
+    <empty/>
+  </define>
+
+<!-- Readers =========================================== -->
+  <define name="map.readers">
+    <element name="map:readers">
+      <ref name="map.readers.attlist"/>
+      <zeroOrMore>
+        <ref name="map.reader"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.readers.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.reader">
+    <element name="map:reader">
+      <ref name="map.reader.attlist"/>
+      <optional><ref name="database.reader.content"/></optional>
+      <zeroOrMore>
+       <ref name="parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.reader.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="database.reader.content">
+     <!-- FIXME is this complete ? -->
+     <optional><element name="use-connection"><data type="string"/></element></optional>
+  </define>
+
+<!-- Serializers ======================================= -->
+  <define name="map.serializers">
+    <element name="map:serializers">
+      <ref name="map.serializers.attlist"/>
+      <zeroOrMore>
+        <ref name="map.serializer"/>
+      </zeroOrMore>
+    </element>
+    <sch:pattern name="Test constraints on map:serialize">
+      <sch:rule context="xmap:serialize">
+    	<sch:assert test="count(following-sibling::*[not(self::xmap:handle-errors)])=0">
+    	  map:serialize must be the last element in a pipeline (other than map:handle-errors).
+        </sch:assert>
+      </sch:rule>
+    </sch:pattern>
+  </define>
+  <define name="map.serializers.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+<!-- CPA: parameter is used by HSSFSerializer -->
+<!-- CPA: set-content-length is used by iTextSerializer -->
+  <define name="map.serializer">
+    <element name="map:serializer">
+      <ref name="map.serializer.attlist"/>
+      <optional><ref name="textSerializer.contents"/></optional>
+      <optional><ref name="svg2jpegSerializer.contents"/></optional>
+      <optional><ref name="set-content-length"/></optional>
+      <optional><ref name="buffer-size"/></optional> <!-- deprecated -->
+      <optional><ref name="user-config"/></optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="parameter"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+<!-- RNG: are these the only children of serializer? -->
+<!-- CPA: No. Added buffer-size for slide and others - don't know -->
+<!--      where it comes from in the source -->
+<!-- CPA: mime-type changed from #REQUIRED to #IMPLIED, because of LinkSerializer -->
+  <define name="map.serializer.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="mime.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="cdata-section-elements">
+    <element name="cdata-section-elements">
+      <ref name="cdata-section-elements.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="cdata-section-elements.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="doctype-public">
+    <element name="doctype-public">
+      <ref name="doctype-public.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="doctype-public.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="doctype-system">
+    <element name="doctype-system">
+      <ref name="doctype-system.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="doctype-system.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="encoding">
+    <element name="encoding">
+      <ref name="encoding.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="encoding.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="omit-xml-declaration">
+    <element name="omit-xml-declaration">
+      <ref name="omit-xml-declaration.attlist"/>
+      <choice>
+        <value>yes</value>
+        <value>no</value>
+      </choice>
+    </element>
+  </define>
+  <define name="omit-xml-declaration.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="parameter">
+    <element name="parameter">
+      <ref name="parameter.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="parameter.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="value.attr"/>
+    <ref name="type.attr"/>
+  </define>
+
+  <define name="map.parameter">
+    <element name="map:parameter">
+      <ref name="map.parameter.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="map.parameter.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="value.attr"/>
+  </define>
+
+  <define name="buffer-size">
+    <element name="buffer-size">
+      <ref name="buffer-size.attlist"/>
+      <data type="positiveInteger" />
+    </element>
+  </define>
+  <define name="buffer-size.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="user-config">
+    <element name="user-config">
+      <ref name="user-config.attlist"/>
+    </element>
+  </define>
+  <define name="user-config.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="src.attr"/>
+  </define>
+
+<!-- Selectors ========================================= -->
+  <define name="map.selectors">
+    <element name="map:selectors">
+      <ref name="map.selectors.attlist"/>
+      <zeroOrMore>
+        <ref name="map.selector"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.selectors.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.selector">
+    <element name="map:selector">
+      <ref name="map.selector.attlist"/>
+      <zeroOrMore>
+        <ref name="anyElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+
+  <define name="map.selector.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+<!-- CPA: elements currently used by map:selector s -->
+  <define name="browser">
+    <element name="browser">
+      <ref name="browser.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="browser.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <attribute name="useragent"/>
+  </define>
+
+  <define name="host">
+    <element name="host">
+      <ref name="host.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="host.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="value.attr"/>
+  </define>
+
+  <define name="cookie-name">
+    <element name="cookie-name">
+      <ref name="cookie-name.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="cookie-name.attlist" combine="interleave">
+    <empty/>
+  </define>
+
+<define name="anyElement">
+  <element>
+    <anyName/>
+    <zeroOrMore>
+      <choice>
+        <attribute>
+    	  <anyName/>
+    	</attribute>
+        <text/>
+        <ref name="anyElement"/>
+      </choice>
+    </zeroOrMore>
+  </element>
+</define>
+
+  <define name="anyAttribute">
+    <zeroOrMore>
+      <attribute>
+        <anyName/>
+      </attribute>
+    </zeroOrMore>
+  </define>
+
+<!-- Matchers ========================================== -->
+  <define name="map.matchers">
+    <element name="map:matchers">
+      <ref name="map.matchers.attlist"/>
+      <zeroOrMore>
+        <ref name="map.matcher"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.matchers.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.matcher">
+    <element name="map:matcher">
+      <ref name="map.matcher.attlist"/>
+      <zeroOrMore>
+        <choice>
+          <ref name="attribute-name"/>
+          <ref name="parameter-name"/>
+          <ref name="header-name"/>
+          <ref name="input-module"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.matcher.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="attribute-name">
+    <element name="attribute-name">
+      <ref name="attribute-name.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="attribute-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="parameter-name">
+    <element name="parameter-name">
+      <ref name="parameter-name.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="parameter-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="header-name">
+    <element name="header-name">
+      <ref name="header-name.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="header-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="input-module">
+    <element name="input-module">
+      <ref name="input-module.attlist"/>
+      <zeroOrMore><ref name="anyElement"/></zeroOrMore>
+    </element>
+  </define>
+  <define name="input-module.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+  </define>
+
+<!-- Actions =========================================== -->
+  <define name="map.actions">
+    <element name="map:actions">
+      <ref name="map.actions.attlist"/>
+      <zeroOrMore>
+        <ref name="map.action"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.actions.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.action">
+    <element name="map:action">
+      <ref name="map.action.attlist"/>
+      <zeroOrMore>
+        <ref name="anyElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.action.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+<!-- Pipes ======================================== -->
+  <define name="map.pipes">
+    <element name="map:pipes">
+      <ref name="map.pipes.attlist"/>
+      <zeroOrMore> 
+        <ref name="map.pipe"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.pipes.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.pipe">
+    <element name="map:pipe">
+      <ref name="map.pipe.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.pipe.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <ref name="src.attr"/>
+    <ref name="component.attr"/>
+    <optional>
+       <ref name="autoCachingPoint"/>
+     </optional>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Views -->
+<!-- =============================================================== -->
+  <define name="map.views">
+    <element name="map:views">
+      <ref name="map.views.attlist"/>
+      <zeroOrMore>
+        <ref name="map.view"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.views.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="map.view">
+    <element name="map:view">
+      <ref name="map.view.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+  <define name="map.view.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <optional>
+      <attribute name="from-label"/>
+    </optional>
+    <optional>
+      <attribute name="from-position" a:defaultValue="last">
+        <choice>
+          <value>first</value>
+          <value>last</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="map.serialize">
+    <element name="map:serialize">
+      <ref name="map.serialize.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+      <optional>
+        <ref name="encoding"/>
+      </optional>
+    </element>
+  </define>
+  <define name="map.serialize.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+    <ref name="mime.attr"/>
+    <ref name="label.attr"/>
+    <optional>
+      <attribute name="status-code"/>
+    </optional>
+    <ref name="optsrc.attr"/>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Resources -->
+<!-- =============================================================== -->
+  <define name="map.resources">
+    <element name="map:resources">
+      <ref name="map.resources.attlist"/>
+      <zeroOrMore>
+        <ref name="map.resource"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.resources.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="map.resource">
+    <element name="map:resource">
+      <ref name="map.resource.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+  <define name="map.resource.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Action Sets -->
+<!-- =============================================================== -->
+  <define name="map.action-sets">
+    <element name="map:action-sets">
+      <ref name="map.action-sets.attlist"/>
+      <zeroOrMore>
+        <ref name="map.action-set"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.action-sets.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="map.action-set">
+    <element name="map:action-set">
+      <ref name="map.action-set.attlist"/>
+      <oneOrMore>
+        <ref name="map.act"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="map.action-set.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+  </define>
+
+  <define name="map.act">
+    <element name="map:act">
+      <ref name="map.act.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+  <define name="map.act.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+    <optional>
+      <attribute name="action"/>
+    </optional>
+    <optional>
+      <attribute name="set"/>
+    </optional>
+    <ref name="optsrc.attr"/>
+    <ref name="optname.attr"/>
+  </define>
+
+<!-- =============================================================== -->
+<!-- Pipelines -->
+<!-- =============================================================== -->
+
+  <define name="map.pipelines">
+    <element name="map:pipelines">
+      <ref name="map.pipelines.attlist"/>
+      <optional>
+        <ref name="map.component-configurations"/>
+      </optional>
+      <zeroOrMore>
+        <ref name="map.pipeline"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.pipelines.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="default.attr"/>
+  </define>
+
+  <define name="map.pipeline">
+    <element name="map:pipeline">
+      <ref name="map.pipeline.attlist"/>
+      <optional>
+        <ref name="pipe.contents"/>
+        <zeroOrMore>
+          <ref name="map.handle-errors"/>
+        </zeroOrMore>
+      </optional>
+
+      <!-- Schematron rules for map:pipeline follow -->
+
+      <sch:pattern name="Test constraints on map:pipeline">
+    	 <sch:rule context="/xmap:sitemap/xmap:pipelines/xmap:pipeline">
+    	   <sch:assert test="(@src and @name) 
+    	                      or .//xmap:generate[not(ancestor::xmap:handle-errors)]
+    	                      or .//xmap:aggregate[not(ancestor::xmap:handle-errors)]
+    	                      or .//xmap:read[not(ancestor::xmap:handle-errors)]
+    	                      or .//xmap:mount[not(ancestor::xmap:handle-errors)]
+    	                      or .//xmap:redirect-to[not(ancestor::xmap:handle-errors)]
+    	                      or .//xmap:call[not(ancestor::xmap:handle-errors)]">
+    	     Pipeline with no map:generate|aggregate|act|mount|redirect-to|call, or src and name attributes, is illegal
+    	   </sch:assert>
+    	   <sch:assert test="not(.//*[namespace-uri()=namespace-uri(/xmap:sitemap)
+    	                        and (local-name()='generate' or local-name()='aggregate' or local-name()='transform')
+    	                        and not(ancestor::xmap:handle-errors)])
+    	                     or .//*[namespace-uri()=namespace-uri(/xmap:sitemap)
+    	                        and (local-name()='generate' or local-name()='aggregate' or local-name()='transform')
+    	                        and not(ancestor::xmap:handle-errors)]
+    	                                [following::*[namespace-uri()=namespace-uri(/xmap:sitemap)
+    	                                                    and (local-name()='serialize' or local-name()='call')
+    	                                                    and not(ancestor::xmap:handle-errors)
+    	                                             ]/ancestor::xmap:pipeline[. = current()]
+    	                                ]">
+    	     Pipeline with map:generate|aggregate|transform must have map:serialize or map:call
+    	   </sch:assert>
+    	 </sch:rule>
+
+    	 <sch:rule context="/xmap:sitemap/xmap:pipelines/xmap:pipeline//*[namespace-uri()=namespace-uri(/xmap:sitemap)
+    	                        and (local-name()='serialize' or local-name()='mount'  or local-name()='read'  
+    	                             or local-name()='redirect-to' or local-name()='call') ]">
+    	   <sch:assert test="count(following-sibling::*[namespace-uri()=namespace-uri(/xmap:sitemap) 
+    	            and local-name() != 'handle-errors'])=0">
+    	     Pipeline with component after map:serialize|read|mount|redirect-to|call is illegal 
+    	   </sch:assert>
+    	 </sch:rule>
+      </sch:pattern>
+    </element>
+  </define>
+  <define name="map.pipeline.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <optional>
+      <attribute name="internal-only"/>
+    </optional>
+    <ref name="optname.attr"/>
+    <ref name="optsrc.attr"/>
+    <ref name="type.attr"/>
+    <ref name="component.attr"/>
+  </define>
+
+  <define name="map.match">
+    <element name="map:match">
+      <ref name="map.match.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+<!-- RNG: It seemed from the example that match should be defined as
+  match (map:mount*|map:redirect-to*|(map:generate*,map:transform*,map:serialize*)*|map:read*|map:aggregate*)
+  but I have no way of knowing. -->
+<!-- DC: Now map:act complicates the content model even further -->
+  <define name="map.match.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+    <attribute name="pattern"/>
+    <ref name="optname.attr"/>
+  </define>
+
+  <define name="map.select">
+    <element name="map:select">
+      <ref name="map.select.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+      <zeroOrMore>
+        <ref name="map.when"/>
+      </zeroOrMore>
+      <optional>
+        <ref name="map.otherwise"/>
+      </optional>
+    </element>
+      <sch:pattern name="Test constraints on map:match and map:select">
+    	 <sch:rule context="xmap:match|xmap:when|xmap:otherwise[*]">
+    	   <sch:assert test="*[namespace-uri()=namespace-uri(/xmap:sitemap)
+    	                          and (local-name()='generate' or local-name()='transform'
+    	                            or local-name()='serialize' or local-name()='aggregate'
+    	                            or local-name()='read' or local-name()='redirect-to'
+    	                            or local-name()='act' or local-name()='match' or local-name()='select' 
+    	                            or local-name()='mount' or local-name()='call')
+    	              ]">
+    	     map:match|select without direct components, or map:mount|redirect-to|call|act|match|select is illegal
+    	   </sch:assert>
+    	 </sch:rule>
+      </sch:pattern>
+  </define>
+  <define name="map.select.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+  </define>
+
+  <define name="map.when">
+    <element name="map:when">
+      <ref name="map.when.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+  <define name="map.when.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <attribute name="test"/>
+  </define>
+
+  <define name="map.otherwise">
+    <element name="map:otherwise">
+      <ref name="map.otherwise.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+  </define>
+  <define name="map.otherwise.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="autoCachingPoint">
+    <element name="autoCachingPoint">
+      <ref name="autoCachingPoint.attlist"/>
+      <choice>
+        <value>on</value>
+        <value>On</value>
+        <value>off</value>
+        <value>Off</value>
+      </choice>
+    </element>
+  </define>
+  <define name="autoCachingPoint.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="map.mount">
+    <element name="map:mount">
+      <ref name="map.mount.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="map.mount.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <attribute name="uri-prefix"/>
+    <ref name="src.attr"/>
+    <optional>
+      <attribute name="reload-method" a:defaultValue="asynchron">
+        <choice>
+          <value>synchron</value>
+          <value>asynchron</value>
+        </choice>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="check-reload" a:defaultValue="no">
+        <choice>
+          <value>true</value>
+          <value>false</value>
+          <value>yes</value>
+          <value>no</value>
+        </choice>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="pass-through" a:defaultValue="false">
+        <choice>
+          <value>true</value>
+          <value>false</value>
+          <value>yes</value>
+          <value>no</value>
+        </choice>
+      </attribute>
+    </optional>    
+  </define>
+
+  <define name="map.redirect-to">
+    <element name="map:redirect-to">
+      <ref name="map.redirect-to.attlist"/>
+      <empty/>
+    </element>
+  </define>
+<!-- CH: redirects to resources are now deprecated -->
+<!-- CPA: attributes confirmed by inspection of RedirectToNodeBuilder -->
+  <define name="map.redirect-to.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="opturi.attr"/>
+    <ref name="resource.attr"/>
+    <optional>
+      <attribute name="target"/>
+    </optional>
+    <optional>
+      <attribute name="session" a:defaultValue="no">
+        <choice>
+          <value>true</value>
+          <value>false</value>
+          <value>yes</value>
+          <value>no</value>
+        </choice>
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="map.call">
+    <element name="map:call">
+      <ref name="map.call.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+
+  <define name="map.call.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+      <ref name="resource.attr"/>
+      <optional><attribute name="function"/></optional>
+      <optional><attribute name="continuation"/></optional>
+  </define>
+
+  <define name="map.generate">
+    <element name="map:generate">
+      <ref name="map.generate.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.generate.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+    <ref name="optsrc.attr"/>
+    <ref name="label.attr"/>
+  </define>
+
+  <define name="map.transform">
+    <element name="map:transform">
+      <ref name="map.transform.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.transform.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+    <ref name="optsrc.attr"/>
+    <ref name="label.attr"/>
+  </define>
+
+  <define name="map.read">
+    <element name="map:read">
+      <ref name="map.read.attlist"/>
+      <zeroOrMore>
+        <ref name="map.parameter"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.read.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="optsrc.attr"/>
+    <ref name="mime.attr"/>
+    <ref name="type.attr"/>
+  </define>
+
+  <define name="map.aggregate">
+    <element name="map:aggregate">
+      <ref name="map.aggregate.attlist"/>
+      <zeroOrMore>
+        <ref name="map.part"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="map.aggregate.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="aggregate.attr"/>
+    <ref name="label.attr"/>
+  </define>
+
+  <define name="map.part">
+    <element name="map:part">
+      <ref name="map.part.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="map.part.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="optsrc.attr"/>
+    <ref name="label.attr"/>
+    <ref name="aggregate.attr"/>
+    <optional>
+      <attribute name="strip-root"/>
+    </optional>
+  </define>
+
+  <define name="map.handle-errors">
+    <element name="map:handle-errors">
+      <ref name="map.handle-errors.attlist"/>
+      <ref name="pipe.contents"/>
+    </element>
+      <sch:pattern name="Test constraints on map:handle-errors">
+    	 <sch:rule context="xmap:handle-errors">
+    	   <sch:assert test="not(*[namespace-uri()=namespace-uri(/xmap:sitemap) 
+    	            and (local-name()='generate' or local-name()='mount')])">
+    	     Error handler can't have: map:generate or map:mount.
+    	   </sch:assert>
+    	   <sch:assert test="*[namespace-uri()=namespace-uri(/xmap:sitemap) 
+    	            and (local-name()='serialize' or local-name()='call')]">
+    	     Error handler must have map:serialize or map:call.
+    	   </sch:assert>
+    	 </sch:rule>
+    	 <sch:rule context="xmap:handle-errors//xmap:serialize">
+    	   <sch:assert test="not(following-sibling::*[namespace-uri()=namespace-uri(/xmap:sitemap)])">
+    	     Error handler can not have any components after map:serialize
+    	   </sch:assert>
+    	 </sch:rule>
+      </sch:pattern>
+  </define>
+
+  <define name="map.handle-errors.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="type.attr"/>
+  </define>
+
+  <define name="map.component-configurations">
+    <element name="map:component-configurations">
+      <ref name="map.component-configurations.attlist"/>
+      <optional>
+        <ref name="global-variables"/>
+      </optional>
+      <optional>
+        <ref name="authentication-manager"/>
+      </optional>
+    </element>
+  </define>
+  <define name="map.component-configurations.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="global-variables">
+    <element name="global-variables">
+      <ref name="global-variables.attlist"/>
+      <zeroOrMore>
+        <ref name="anyElement"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="global-variables.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="authentication-manager">
+    <element name="authentication-manager">
+      <ref name="authentication-manager.attlist"/>
+      <ref name="handlers"/>
+    </element>
+  </define>
+  <define name="authentication-manager.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="handlers">
+    <element name="handlers">
+      <ref name="handlers.attlist"/>
+      <oneOrMore>
+        <ref name="handler"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="handlers.attlist" combine="interleave">
+    <empty/>
+  </define>
+
+  <define name="handler">
+    <element name="handler">
+      <ref name="handler.attlist"/>
+      <ref name="redirect-to"/>
+      <ref name="authentication"/>
+      <optional>
+        <ref name="applications"/>
+      </optional>
+    </element>
+  </define>
+  <define name="handler.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+    <empty/>
+  </define>
+
+  <define name="redirect-to">
+    <element name="redirect-to">
+      <ref name="redirect-to.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="redirect-to.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="authentication">
+    <element name="authentication">
+      <ref name="authentication.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="authentication.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="applications">
+    <element name="applications">
+      <ref name="applications.attlist"/>
+      <oneOrMore>
+        <ref name="application"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="applications.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="application">
+    <element name="application">
+      <ref name="application.attlist"/>
+      <oneOrMore>
+        <ref name="configuration"/>
+      </oneOrMore>
+    </element>
+  </define>
+  <define name="application.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <attribute name="loadondemand"/>
+    <ref name="name.attr"/>
+  </define>
+
+  <define name="configuration">
+    <element name="configuration">
+      <ref name="configuration.attlist"/>
+      <zeroOrMore> <!-- CPA: not sure - maybe interleave optionals? TODO -->
+        <choice>
+          <ref name="auth-redirect"/>
+          <ref name="portal-uri"/>
+          <ref name="profile-cache"/>
+          <ref name="default-coplet-timeout"/>
+          <ref name="profile"/>
+          <ref name="load-users"/>
+          <ref name="load-roles"/>
+          <ref name="new-user"/>
+          <ref name="new-role"/>
+          <ref name="change-user"/>
+          <ref name="delete-role"/>
+          <ref name="delete-user"/>
+          <ref name="process-coplets-parallel"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="configuration.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="name.attr"/>
+  </define>
+
+  <define name="auth-redirect">
+    <element name="auth-redirect">
+      <ref name="auth-redirect.attlist"/>
+      <text/>
+    </element>
+  </define>
+  <define name="auth-redirect.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="portal-uri">
+    <element name="portal-uri">
+      <ref name="portal-uri.attlist"/>
+      <text/>
+    </element>
+  </define>
+  <define name="portal-uri.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="profile-cache">
+    <element name="profile-cache">
+      <ref name="profile-cache.attlist"/>
+      <text/>
+    </element>
+  </define>
+  <define name="profile-cache.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="default-coplet-timeout">
+    <element name="default-coplet-timeout">
+      <ref name="default-coplet-timeout.attlist"/>
+      <text/>
+    </element>
+  </define>
+  <define name="default-coplet-timeout.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="process-coplets-parallel">
+    <element name="process-coplets-parallel">
+      <ref name="process-coplets-parallel.attlist"/>
+      <text/>
+    </element>
+  </define>
+  <define name="process-coplets-parallel.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="profile">
+    <element name="profile">
+      <ref name="profile.attlist"/>
+      <ref name="layout-base"/>
+      <ref name="coplet-base"/>
+      <ref name="coplet-base-save"/>
+      <ref name="type-base"/>
+      <ref name="admin-type-base"/>
+      <ref name="global-delta-load"/>
+      <ref name="global-delta-save"/>
+      <ref name="role-delta-load"/>
+      <ref name="role-delta-save"/>
+      <ref name="user-delta-load"/>
+      <ref name="user-delta-save"/>
+      <ref name="user-status-load"/>
+      <ref name="user-status-save"/>
+    </element>
+  </define>
+  <define name="profile.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="layout-base">
+    <element name="layout-base">
+      <ref name="layout-base.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="layout-base.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="coplet-base">
+    <element name="coplet-base">
+      <ref name="coplet-base.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="coplet-base.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="coplet-base-save">
+    <element name="coplet-base-save">
+      <ref name="coplet-base-save.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="coplet-base-save.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="type-base">
+    <element name="type-base">
+      <ref name="type-base.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="type-base.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="admin-type-base">
+    <element name="admin-type-base">
+      <ref name="admin-type-base.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="admin-type-base.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="global-delta-load">
+    <element name="global-delta-load">
+      <ref name="global-delta-load.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="global-delta-load.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="global-delta-save">
+    <element name="global-delta-save">
+      <ref name="global-delta-save.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="global-delta-save.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="role-delta-load">
+    <element name="role-delta-load">
+      <ref name="role-delta-load.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="role-delta-load.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="role-delta-save">
+    <element name="role-delta-save">
+      <ref name="role-delta-save.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="role-delta-save.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="user-delta-load">
+    <element name="user-delta-load">
+      <ref name="user-delta-load.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="user-delta-load.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="user-delta-save">
+    <element name="user-delta-save">
+      <ref name="user-delta-save.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="user-delta-save.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="user-status-load">
+    <element name="user-status-load">
+      <ref name="user-status-load.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="user-status-load.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="user-status-save">
+    <element name="user-status-save">
+      <ref name="user-status-save.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="user-status-save.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="load-users">
+    <element name="load-users">
+      <ref name="load-users.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="load-users.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+  <define name="load-roles">
+    <element name="load-roles">
+      <ref name="load-roles.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="load-roles.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="new-user">
+    <element name="new-user">
+      <ref name="new-user.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="new-user.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="new-role">
+    <element name="new-role">
+      <ref name="new-role.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="new-role.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="change-user">
+    <element name="change-user">
+      <ref name="change-user.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="change-user.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="delete-user">
+    <element name="delete-user">
+      <ref name="delete-user.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="delete-user.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="delete-role">
+    <element name="delete-role">
+      <ref name="delete-role.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="delete-role.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="uri.attr"/>
+  </define>
+
+  <define name="map.flow-interpreters">
+    <element name="map:flow-interpreters">
+      <ref name="map.flow-interpreters.attlist"/>
+      <empty/>
+<!-- CPA: presumably it should NOT be empty for non-default usage, so this -->
+<!--      needs correcting, but I cannot find source code that clarifies -->
+    </element>
+  </define>
+  <define name="map.flow-interpreters.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <attribute name="default"/>
+  </define>
+
+  <define name="map.flow">
+    <element name="map:flow">
+      <ref name="map.flow.attlist"/>
+      <ref name="map.script"/>
+    </element>
+  </define>
+  <define name="map.flow.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <attribute name="language"/>
+  </define>
+
+  <define name="map.script">
+    <element name="map:script">
+      <ref name="map.script.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="map.script.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+    <ref name="src.attr"/>
+  </define>
+
+  <define name="include-name">
+    <element name="include-name">
+      <ref name="include-name.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="include-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="exclude-name">
+    <element name="exclude-name">
+      <ref name="exclude-name.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="exclude-name.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="method">
+    <element name="method">
+      <ref name="method.attlist"/>
+      <data type="string" /> 
+      <!-- CPA: should be xml, or html, or text or an expanded name -->
+    </element>
+  </define>
+  <define name="method.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="use-cookies">
+    <element name="use-cookies" a:defaultValue="false" >
+      <ref name="use-cookies.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="use-cookies.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="untranslated-text">
+    <element name="untranslated-text">
+      <ref name="untranslated-text.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="untranslated-text.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="media-type">
+    <element name="media-type">
+      <ref name="media-type.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="media-type.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="version">
+    <element name="version">
+      <ref name="version.attlist"/>
+      <data type="NMTOKEN" /> <!-- CPA: but actually a floating point version number -->
+    </element>
+  </define>
+  <define name="version.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="transformer-factory">
+    <element name="transformer-factory" a:defaultValue="default">
+      <ref name="transformer-factory.attlist"/>
+      <data type="string" />
+    </element>
+  </define>
+  <define name="transformer-factory.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="use-session-info">
+    <element name="use-session-info"  a:defaultValue="false" >
+      <ref name="use-session-info.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="use-session-info.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="incremental-processing">
+  <!-- CPA: from  XSLTProcessorImpl.java -->  
+    <element name="incremental-processing" a:defaultValue="false" >
+      <ref name="incremental-processing.attlist"/>
+      <choice>
+        <value>true</value>
+        <value>false</value>
+      </choice>
+    </element>
+  </define>
+  <define name="incremental-processing.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="indent">
+    <element name="indent">
+      <ref name="indent.attlist"/>
+      <choice>
+        <value>yes</value>
+        <value>no</value>
+      </choice>
+    </element>
+  </define>
+  <define name="indent.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="set-content-length">
+    <element name="set-content-length">
+      <ref name="set-content-length.attlist"/>
+      <empty/>
+    </element>
+  </define>
+  <define name="set-content-length.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+  <define name="standalone">
+    <element name="standalone">
+      <ref name="standalone.attlist"/>
+      <choice>
+        <value>yes</value>
+        <value>no</value>
+      </choice>
+    </element>
+  </define>
+  <define name="standalone.attlist" combine="interleave">
+    <ref name="universal.attr"/>
+  </define>
+
+
+  <start>
+    <ref name="map.sitemap"/>
+  </start>
+</grammar>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/specification-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/specification-v10.dtd
new file mode 100644
index 0000000..b42c73a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/specification-v10.dtd
@@ -0,0 +1,89 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+     
+     Apache Specification DTD (Version 1.0)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document 
+  type for software specifications for use with the Apache projects.  
+  It is an XML-compliant DTD and it's maintained by the Apache XML 
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Specification Vx.yz//EN"
+       "http://xml.apache.org/DTD/specification-vxyz.dtd">
+
+  where 
+  
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+      
+NOTES:  
+
+FIXME:
+
+CHANGE HISTORY:
+  19991129 Initial version. (SM)
+    
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Extend the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!-- extend the local.xxx entities -->
+<!ENTITY % local.lists "|bl">
+
+<!-- FIXME (SM): this is hardcoding. Find a better way of doing this
+     possibly using public identifiers -->
+<!ENTITY % document-dtd SYSTEM "document-v10.dtd">
+%document-dtd;
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT specification (header?, body, appendices?, footer?)>
+<!ATTLIST specification %common.att;>
+
+    <!ELEMENT appendices (%sections;)+>
+    <!ATTLIST appendices %common.att;>
+
+<!-- =============================================================== -->
+<!-- Bibliography List -->
+<!-- =============================================================== -->
+
+    <!-- Bibliography list -->
+    <!ELEMENT bl (bi)+>
+    <!ATTLIST bl %common.att;>
+
+        <!-- Book item -->
+        <!ELEMENT bi EMPTY>
+        <!ATTLIST bi %common.att;
+                     %name.att;
+                     %title.att;
+                     %xlink-simple.att;
+                     %xlink-user-new.att;
+                     authors CDATA #REQUIRED
+                     date    CDATA #IMPLIED>
+
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/todo-v10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/todo-v10.dtd
new file mode 100644
index 0000000..b6c1cc3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/todo-v10.dtd
@@ -0,0 +1,94 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- ===================================================================
+     
+     Apache Todos DTD (Version 1.0)
+
+PURPOSE:
+  This DTD was developed to create a simple yet powerful document 
+  type for software development todo lists for use with the Apache projects.  
+  It is an XML-compliant DTD and it's maintained by the Apache XML 
+  project.
+
+TYPICAL INVOCATION:
+
+  <!DOCTYPE document PUBLIC
+       "-//APACHE//DTD Todo Vx.yz//EN"
+       "todo-vxyz.dtd">
+
+  where 
+  
+    x := major version
+    y := minor version
+    z := status identifier (optional)
+      
+NOTES:  
+  It is important, expecially in open developped software projects, to keep
+  track of software changes that need to be done, planned features, development
+  assignment, etc. in order to allow better work parallelization and create
+  an entry point for people that want to help. This DTD wants to provide
+  a solid foundation to provide such information and to allow it to be
+  published as well as distributed in a common format.
+
+FIXME:
+  - do we need anymore working contexts? (SM)
+
+CHANGE HISTORY:
+  19991129 Initial version. (SM)
+  19991225 Added actions element for better structure (SM)
+    
+==================================================================== -->
+
+<!-- =============================================================== -->
+<!-- Extend the Documentation DTD -->
+<!-- =============================================================== -->
+
+<!-- FIXME (SM): this is hardcoding. Find a better way of doing this
+     possibly using public identifiers -->
+<!ENTITY % document-dtd SYSTEM "document-v10.dtd">
+%document-dtd;
+
+<!-- =============================================================== -->
+<!-- Common entities -->
+<!-- =============================================================== -->
+
+<!ENTITY % priorities "showstopper|high|medium|low|wish|dream">
+
+<!ENTITY % contexts "build|docs|code|admin|design">
+
+<!-- =============================================================== -->
+<!-- Document Type Definition -->
+<!-- =============================================================== -->
+
+<!ELEMENT todo (devs, actions*)>
+<!ATTLIST todo %common.att; 
+               %title.att;>
+
+    <!ELEMENT devs (person+)>
+    <!ATTLIST devs %common.att;>
+
+    <!ELEMENT actions (action+)>
+    <!ATTLIST actions %common.att;
+                     priority     (%priorities;)  #IMPLIED>
+
+        <!ELEMENT action (%content.mix;)*>
+        <!ATTLIST action %common.att;
+                         assigned-to  IDREF           #IMPLIED
+                         context      (%contexts;)    #REQUIRED>
+    
+<!-- =============================================================== -->
+<!-- End of DTD -->
+<!-- =============================================================== -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/catalog b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/catalog
new file mode 100644
index 0000000..6a12676
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/catalog
@@ -0,0 +1,30 @@
+OVERRIDE	YES
+
+
+        -- Oasis entity catalog for Extensible HTML 1.0 --
+
+PUBLIC  "-//W3C//DTD XHTML 1.0 Strict//EN"        "xhtml1-strict.dtd"
+PUBLIC  "-//W3C//DTD XHTML 1.0 Transitional//EN"  "xhtml1-transitional.dtd"
+PUBLIC  "-//W3C//DTD XHTML 1.0 Frameset//EN"      "xhtml1-frameset.dtd"
+
+        -- ISO latin 1 entity set for Extensible HTML (XML 1.0 format) --
+
+PUBLIC	"-//W3C//ENTITIES Latin 1 for XHTML//EN"  "xhtml-lat1.ent"
+PUBLIC	"-//W3C//ENTITIES Symbols for XHTML//EN"  "xhtml-symbol.ent"
+PUBLIC	"-//W3C//ENTITIES Special for XHTML//EN"  "xhtml-special.ent"
+
+SGMLDECL "xhtml1.dcl"
+
+
+        -- Oasis entity catalog for Extensible HTML 1.1 --
+
+PUBLIC "-//W3C//DTD XHTML 1.1//EN"                "xhtml11-flat.dtd"
+
+
+        -- Oasis entity catalog for Scalable Vector Graphics  --
+
+PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN" "svg-20000303-stylable.dtd"
+PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN"   "svg-20000303-shared.dtd"
+PUBLIC "-//W3C//DTD SVG 20000303 Exchange//EN" "svg-20000303-exchange.dtd"
+
+PUBLIC "-//W3C//DTD SVG 1.0//EN"               "svg10.dtd"
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-exchange.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-exchange.dtd
new file mode 100644
index 0000000..a4f7895
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-exchange.dtd
@@ -0,0 +1,59 @@
+<!--
+  This is the DTD for Exchange SVG. It adds various visual rendering attributes 
+  to the Shared DTD.
+
+  In most cases, authors should use the DTD for Stylable SVG.
+  The DTD for Exchange SVG is available for specific purposes
+  as described in the Exchange SVG chapter of the SVG specification.
+
+  The specification for SVG that corresponds to this DTD is available at:
+
+    http://www.w3.org/TR/2000/03/WD-SVG-20000303/
+
+  Copyright (c) 2000 W3C (MIT, INRIA, Keio), All Rights Reserved.
+
+  For this working draft:
+
+    Namespaces:
+      Stylable SVG:     http://www.w3.org/2000/svg-20000303-stylable
+      Exchange SVG:   http://www.w3.org/2000/svg-20000303-exchange  
+
+    Public identifiers:
+      PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Exchange//EN"
+
+    URIs for the DTDs:
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-shared.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-exchange.dtd
+
+  Typical usage in the case of stand-alone Exchange SVG documents:
+
+<?xml version="1.0" ... ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000303 Exchange//EN" 
+  "http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-exchange.dtd">
+<svg ...>
+ ...
+</svg>
+
+  Typical usage when Exchange SVG is embedded inline within a parent XML document:
+
+<?xml version="1.0" ... ?>
+<!DOCTYPE foo ... >
+<foo ...>
+ ...
+ <svg xmlns="http://www.w3.org/2000/svg-20000303-exchange" ... >
+    ...
+ </svg>
+ ...
+</foo>
+-->
+
+
+<!ENTITY % StylableSVG "IGNORE" >
+<!ENTITY % ExchangeSVG "INCLUDE" >
+<!ENTITY % SVGNamespace "http://www.w3.org/2000/svg-20000303-exchange" >
+<!ENTITY % Shared PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN" "svg-20000303-shared.dtd" >
+%Shared;
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-shared.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-shared.dtd
new file mode 100644
index 0000000..ce66dfb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-shared.dtd
@@ -0,0 +1,1600 @@
+<!--
+  This is the Shared DTD for SVG 1.0 (draft 20000303). It contains the
+  element, attribute and entities definitions which are common to the 
+  DTD for Stylable SVG and the DTD for Exchange SVG.
+
+  The only purpose of the Shared DTD is to serve as a single definition for
+  the definitions of elements, attributes and entities that are common to
+  the DTD for Stylable SVG and the DTD for Exchange SVG.
+  The Shared DTD should not be used directly; instead, use either the
+  DTD for Stylable SVG or the DTD for Exchange SVG.
+
+  The specification for SVG that corresponds to this DTD is available at:
+
+    http://www.w3.org/TR/2000/03/WD-SVG-20000303/
+
+  Copyright (c) 2000 W3C (MIT, INRIA, Keio), All Rights Reserved.
+
+  For this working draft:
+
+    Namespaces:
+      Stylable SVG:     http://www.w3.org/2000/svg-20000303-stylable
+      Exchange SVG:   http://www.w3.org/2000/svg-20000303-exchange  
+
+    Public identifiers:
+      PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Exchange//EN"
+
+    URIs for the DTDs:
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-shared.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-exchange.dtd
+-->
+
+
+<!--=================== Entity definitions ===================-->
+
+<!ENTITY % BaselineShiftValue "CDATA">
+    <!-- 'baseline-shift' property/attribute value (e.g., 'baseline', 'sub', etc.) -->
+
+<!ENTITY % Boolean "(false | true)">
+    <!-- feature specification -->
+
+<!ENTITY % ClassList "CDATA">
+    <!-- list of classes -->
+
+<!ENTITY % ClipValue "CDATA">
+    <!-- 'clip' property/attribute value (e.g., 'auto', rect(...)) -->
+
+<!ENTITY % ClipPathValue "CDATA">
+    <!-- 'clip-path' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % ClipFillRule "(evenodd | nonzero | inherit)">
+    <!-- 'clip-rule' or fill-rule property/attribute value -->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % Coordinate "CDATA">
+    <!-- a <coordinate> -->
+
+<!ENTITY % Coordinates "CDATA">
+    <!-- a list of <coordinate>s -->
+
+<!ENTITY % CSSColor "CDATA">
+    <!-- a <color> value, as per [CSS2-color] -->
+
+<!ENTITY % CursorValue "CDATA">
+    <!-- 'cursor' property/attribute value (e.g., 'crosshair', %URI;) -->
+
+<!ENTITY % EnableBackgroundValue "CDATA">
+    <!-- 'enable-background' property/attribute value (e.g., 'new', 'accumulate') -->
+
+<!ENTITY % Feature "CDATA">
+    <!-- feature specification -->
+
+<!ENTITY % FilterValue "CDATA">
+    <!-- 'filter' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % FontFamilyValue "CDATA">
+    <!-- 'font-family' property/attribute value (i.e., list of fonts) -->
+
+<!ENTITY % FontSizeValue "CDATA">
+    <!-- 'font-size' property/attribute value -->
+
+<!ENTITY % FontSizeAdjustValue "CDATA">
+    <!-- 'font-size-adjust' property/attribute value -->
+
+<!ENTITY % GlyphOrientationHorizontalValue "CDATA">
+    <!-- 'glyph-orientation-horizontal' property/attribute value (e.g., <angle>) -->
+
+<!ENTITY % GlyphOrientationVerticalValue "CDATA">
+    <!-- 'glyph-orientation-vertical' property/attribute value (e.g., 'auto', <angle>) -->
+
+<!ENTITY % Integer "CDATA">
+    <!-- a <integer> -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC1766] -->
+
+<!ENTITY % LanguageCodes "CDATA">
+    <!-- comma-separated list of language codes, as per [RFC1766] -->
+
+<!ENTITY % Length "CDATA">
+    <!-- a <length> -->
+
+<!ENTITY % Lengths "CDATA">
+    <!-- a list of <length>s -->
+
+<!ENTITY % LinkTarget "NMTOKEN">
+    <!-- link to this target -->
+
+<!ENTITY % MarkerValue "CDATA">
+    <!-- 'marker' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % MaskValue "CDATA">
+    <!-- 'mask' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % Number "CDATA">
+    <!-- a <number> -->
+
+<!ENTITY % OpacityValue "CDATA">
+    <!-- opacity value (e.g., <number>) -->
+
+<!ENTITY % Paint "CDATA">
+    <!-- a 'fill' or 'stroke' property/attribute value: <paint> -->
+
+<!ENTITY % PathData "CDATA">
+    <!-- a path data specification -->
+
+<!ENTITY % Points "CDATA">
+    <!-- a list of points -->
+
+<!ENTITY % PreserveAspectRatioSpec "CDATA">
+    <!-- 'preserveAspectRatio' attribute specification -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % SpacingValue "CDATA">
+    <!-- 'letter-spacing' or 'word-spacing' property/attribute value (e.g., normal | <length>) -->
+
+<!ENTITY % StopColorValue "CDATA">
+    <!-- 'stop-color' property/attribute value  -->
+
+<!ENTITY % StrokeDashArrayValue "CDATA">
+    <!-- 'stroke-dasharray' property/attribute value (e.g., 'none', list of <number>s) -->
+
+<!ENTITY % StrokeDashOffsetValue "CDATA">
+    <!-- 'stroke-dashoffset' property/attribute value (e.g., 'none', <legnth>) -->
+
+<!ENTITY % StrokeMiterLimitValue "CDATA">
+    <!-- 'stroke-miterlimit' property/attribute value (e.g., <number>) -->
+
+<!ENTITY % StrokeWidthValue "CDATA">
+    <!-- 'stroke-width' property/attribute value (e.g., <length>) -->
+
+<!ENTITY % StructuredText
+  "content CDATA #FIXED 'structured text'" >
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % SVGColor "CDATA">
+    <!-- An SVG color value (RGB plus optional ICC) -->
+
+<!ENTITY % TextDecorationValue "CDATA">
+    <!-- 'text-decoration' property/attribute value (e.g., 'none', 'underline') -->
+
+<!ENTITY % TransformList "CDATA">
+    <!-- list of transforms -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [URI] -->
+
+<!ENTITY % ViewBoxSpec "CDATA">
+    <!-- 'viewBox' attribute specification -->
+
+<!-- This entity allows for at most one of desc and title,
+     supplied in any order -->
+<!ENTITY % descTitle
+          "((desc,title?)|(title,desc?)?)" >
+
+<!-- This entity allows for at most one of desc, title and defs,
+     supplied in any order -->
+<!ENTITY % descTitleDefs
+          "(((desc,((title,defs?)|(defs,title?))?)|
+              (title,((desc,defs?)|(defs,desc?))?)|
+              (defs,((desc,title?)|(title,desc?))?))?)" >
+
+<!-- All elements have an ID. -->
+<!ENTITY % stdAttrs
+ "id ID #IMPLIED" >
+
+<!-- Common attributes for elements that might contain character data content. -->
+<!ENTITY % langSpaceAttrs
+ "xml:lang %LanguageCode; #IMPLIED
+  xml:space (default|preserve) #IMPLIED" >
+
+<!-- Common attributes to check for system capabilities. -->
+<!ENTITY % testAttrs
+ "system-required %Feature; #IMPLIED
+  system-language %LanguageCodes; #IMPLIED" >
+
+<!-- For most uses of URI referencing:
+        standard XLink attributes other than xlink:href. -->
+<!ENTITY % xlinkRefAttrs
+ "xmlns:xlink CDATA #FIXED 'http://www.w3.org/2000/xlink/namespace/'
+  xlink:type (simple|extended|locator|arc) 'simple' 
+  xlink:role CDATA #IMPLIED
+  xlink:title CDATA #IMPLIED
+  xlink:show (new|embed|replace) 'embed'
+  xlink:actuate (onRequest|onLoad) 'onLoad'" >
+
+<!ENTITY % graphicsElementEvents
+  "onfocusin %Script; #IMPLIED
+   onfocusout %Script; #IMPLIED
+   onactivate %Script; #IMPLIED
+   onmousedown %Script; #IMPLIED
+   onmouseup %Script; #IMPLIED
+   onclick %Script; #IMPLIED
+   ondblclick %Script; #IMPLIED
+   onmouseover %Script; #IMPLIED
+   onmousemove %Script; #IMPLIED
+   onmouseout %Script; #IMPLIED
+   onkeydown %Script; #IMPLIED
+   onkeypress %Script; #IMPLIED
+   onkeyup %Script; #IMPLIED
+   onload %Script; #IMPLIED
+   onselect %Script; #IMPLIED" >
+
+<!ENTITY % documentEvents
+  "onresize %Script; #IMPLIED
+   onscroll %Script; #IMPLIED
+   onunload %Script; #IMPLIED
+   onzoom %Script; #IMPLIED
+   onerror %Script; #IMPLIED
+   onabort %Script; #IMPLIED " >
+
+
+<!-- Definitions of elements and attributes that only apply to Stylable SVG -->
+
+<!-- Stylable SVG has a 'style' element and puts a 'style' attribute on most elements. -->
+<![%StylableSVG;[
+  <!ENTITY % StylableSVG-StyleElement 
+    "|style" >
+
+  <!ENTITY % StylableSVG-StyleAttribute 
+    "style %StyleSheet; #IMPLIED" >
+]]>
+
+<!-- These elements and attributes are not available for Exchange SVG. -->
+<![%ExchangeSVG;[
+  <!-- For Exchange SVG only, the 'style' attribute and 'style' element 
+       are removed from most elements. -->
+  <!ENTITY % StylableSVG-StyleAttribute "" >
+  <!ENTITY % StylableSVG-StyleElement "" >
+]]>
+
+
+<!-- Definitions of attribute collections that only apply to Exchange SVG -->
+
+<![%ExchangeSVG;[
+  <!-- For Exchange SVG only, all container elements have these attributes. -->
+  <!ENTITY % ExchangeSVG-ContainerAttrs
+    "enable-background %EnableBackgroundValue; #IMPLIED " >
+
+  <!-- For Exchange SVG only, attributes on elements that can be filled or stroked. -->
+  <!ENTITY % ExchangeSVG-FillStrokeAttrs
+    "fill %Paint; #IMPLIED
+     fill-opacity %OpacityValue; #IMPLIED
+     fill-rule %ClipFillRule; #IMPLIED
+     stroke %Paint; #IMPLIED
+     stroke-dasharray %StrokeDashArrayValue; #IMPLIED
+     stroke-dashoffset %StrokeDashOffsetValue; #IMPLIED
+     stroke-linecap (butt | round | square | inherit) #IMPLIED
+     stroke-linejoin (miter | round | bevel | inherit) #IMPLIED
+     stroke-miterlimit %StrokeMiterLimitValue; #IMPLIED
+     stroke-opacity %OpacityValue; #IMPLIED
+     stroke-width %StrokeWidthValue; #IMPLIED " >
+
+  <!-- For Exchange SVG only, all gradient elements have these attributes. -->
+  <!ENTITY % ExchangeSVG-GradientAttrs
+    "stop-color %StopColorValue; #IMPLIED
+     stop-opacity %OpacityValue; #IMPLIED " >
+
+  <!-- For Exchange SVG only, all graphics elements have these attributes. -->
+  <!ENTITY % ExchangeSVG-GraphicsAttrs
+    "clip-path %ClipPathValue; #IMPLIED
+     clip-rule %ClipFillRule; #IMPLIED
+     color %CSSColor; #IMPLIED
+     color-interpolation (auto | sRGB | linearRGB | inherit) #IMPLIED
+     color-rendering (auto | optimizeSpeed | optimizeQuality | inherit) #IMPLIED
+     cursor %CursorValue; #IMPLIED
+     display (inline | block | list-item | run-in | compact | marker |
+              table | inline-table | table-row-group | table-header-group |
+              table-footer-group | table-row | table-column-group | table-column |
+              table-cell | table-caption | none | inherit) #IMPLIED
+     filter %FilterValue; #IMPLIED
+     image-rendering (auto | optimizeSpeed | optimizeQuality | inherit) #IMPLIED
+     mask %MaskValue; #IMPLIED
+     opacity %OpacityValue; #IMPLIED
+     pointer-events (visiblePainted | visibleFill | visibleStroke | visibleFillStroke | visible |
+                     painted | fill | stroke | fillstroke | all | none | inherit) #IMPLIED
+     shape-rendering (auto | optimizeSpeed | crispEdges | geometricPrecision | inherit) #IMPLIED
+     text-rendering (auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit) #IMPLIED
+     visibility (visible | hidden | inherit) #IMPLIED " >
+
+  <!-- For Exchange SVG only, container elements and certain graphics elements have these attributes. -->
+  <!ENTITY % ExchangeSVG-MarkerAttrs
+    "marker-start %MarkerValue; #IMPLIED
+     marker-mid %MarkerValue; #IMPLIED
+     marker-end %MarkerValue; #IMPLIED " >
+
+  <!-- For Exchange SVG only, all text container elements have these attributes. -->
+  <!ENTITY % ExchangeSVG-TextContainerAttrs
+    "baseline-identifier (baseline | top | before-edge | text-top | text-before-edge |
+                          middle | bottom | after-edge | text-bottom | text-after-edge |
+                          ideographic | lower | hanging | mathematical | inherit) #IMPLIED
+     baseline-shift %BaselineShiftValue; #IMPLIED
+     direction (ltr | rtl | inherit) #IMPLIED
+     font-family %FontFamilyValue; #IMPLIED
+     font-size %FontSizeValue; #IMPLIED
+     font-size-adjust %FontSizeAdjustValue; #IMPLIED
+     font-stretch (normal | wider | narrower | ultra-condensed | extra-condensed |
+                   condensed | semi-condensed | semi-expanded | expanded |
+                   extra-expanded | ultra-expanded | inherit) #IMPLIED
+     font-style (normal | italic | oblique | inherit) #IMPLIED
+     font-variant (normal | small-caps | inherit) #IMPLIED
+     font-weight (normal | bold | bolder | lighter | 100 | 200 | 300 |
+                 400 | 500 | 600 | 700 | 800 | 900 | inherit) #IMPLIED
+     glyph-orientation-horizontal %GlyphOrientationHorizontalValue; #IMPLIED
+     glyph-orientation-vertical %GlyphOrientationVerticalValue; #IMPLIED
+     letter-spacing %SpacingValue; #IMPLIED
+     text-decoration %TextDecorationValue; #IMPLIED
+     unicode-bidi (normal | embed | bidi-override | inherit) #IMPLIED
+     word-spacing %SpacingValue; #IMPLIED " >
+
+  <!-- For Exchange SVG only, the 'text' element has these attributes. -->
+  <!ENTITY % ExchangeSVG-TextElementAttrs
+    "dominant-baseline (auto | autosense-script | no-change | reset|
+                        ideographic | lower | hanging | mathematical | inherit ) #IMPLIED
+     text-anchor (start | middle | end | inherit) #IMPLIED
+     writing-mode (lr-tb | rl-tb | tb-rl | lr | rl | tb | inherit) #IMPLIED " >
+
+  <!-- For Exchange SVG only, all elements that establish viewports have these attributes. -->
+  <!ENTITY % ExchangeSVG-ViewportAttrs
+    "clip %ClipValue; #IMPLIED
+     overflow (visible | hidden | scroll | auto | inherit) #IMPLIED " >
+
+  <!-- For Exchange SVG only, feFlood has these attributes. -->
+  <!ENTITY % ExchangeSVG-feFloodAttrs
+    "flood-color %SVGColor; #IMPLIED
+     flood-opacity %OpacityValue; #IMPLIED " >
+]]>
+
+<!-- These above Exchange SVG attribute collections 
+     are not available for Stylable SVG. -->
+<![%StylableSVG;[
+  <!ENTITY % ExchangeSVG-ContainerAttrs "" >
+  <!ENTITY % ExchangeSVG-FillStrokeAttrs "" >
+  <!ENTITY % ExchangeSVG-GradientAttrs "" >
+  <!ENTITY % ExchangeSVG-GraphicsAttrs "" >
+  <!ENTITY % ExchangeSVG-MarkerAttrs "" >
+  <!ENTITY % ExchangeSVG-TextContainerAttrs "" >
+  <!ENTITY % ExchangeSVG-TextElementAttrs "" >
+  <!ENTITY % ExchangeSVG-ViewportAttrs "" >
+  <!ENTITY % ExchangeSVG-feFloodAttrs "" >
+]]>
+
+
+<!-- Definitions of elements that only apply to Exchange SVG -->
+
+<!-- Exchange SVG has a corresponding XML version of the 
+     @font-face and @color-profile features available when SVG is styled with CSS. -->
+<![%ExchangeSVG;[
+  <!ENTITY % ExchangeSVG-ColorProfileElement 
+    "|color-profile" >
+
+  <!ENTITY % ExchangeSVG-FontFaceElement 
+    "|font-face" >
+]]>
+
+<!-- These elements are not available for Stylable SVG. -->
+<![%StylableSVG;[
+  <!ENTITY % ExchangeSVG-ColorProfileElement "" >
+  <!ENTITY % ExchangeSVG-FontFaceElement "" >
+]]>
+
+
+<!-- Allow for extending the DTD with internal subset for 
+     container and graphics elements -->
+<!ENTITY % ceExt "" >
+<!ENTITY % geExt "" >
+
+
+<!--========== Document Structure and Grouping ==========-->
+
+<!ENTITY % svgExt "" >
+<!ELEMENT svg (%descTitleDefs;,metadata?,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform
+                   %StylableSVG-StyleElement;
+                   %ExchangeSVG-ColorProfileElement;%ExchangeSVG-FontFaceElement;
+                   %ceExt;%svgExt;)*) >
+<!ATTLIST svg
+  xmlns CDATA #FIXED "%SVGNamespace;"
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  %graphicsElementEvents;
+  %documentEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED 
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  enableZoomAndPanControls %Boolean; "true"
+  contentScriptType %ContentType; "text/ecmascript"
+  contentStyleType %ContentType; "text/css"
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+<!ENTITY % gExt "" >
+<!ELEMENT g (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform
+                   %StylableSVG-StyleElement;
+                   %ExchangeSVG-ColorProfileElement;%ExchangeSVG-FontFaceElement;
+                   %ceExt;%gExt;)*) >
+<!ATTLIST g
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % defsExt "" >
+<!ELEMENT defs (
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform
+                   %StylableSVG-StyleElement;
+                   %ExchangeSVG-ColorProfileElement;%ExchangeSVG-FontFaceElement;
+                   %ceExt;%defsExt;)* >
+<!ATTLIST defs
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+
+<!--=================== Shapes ===================-->
+
+<!ENTITY % pathExt "" >
+<!ELEMENT path (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%pathExt;)*) >
+<!ATTLIST path
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  d %PathData; #REQUIRED
+  length %Number; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs; >
+
+<!ENTITY % rectExt "" >
+<!ELEMENT rect (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%rectExt;)*) >
+<!ATTLIST rect
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  rx %Length; #IMPLIED
+  ry %Length; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs; >
+
+<!ENTITY % circleExt "" >
+<!ELEMENT circle (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%circleExt;)*) >
+<!ATTLIST circle
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  cx %Coordinate; "0"
+  cy %Coordinate; "0"
+  r %Length; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs; >
+
+<!ENTITY % ellipseExt "" >
+<!ELEMENT ellipse (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%ellipseExt;)*) >
+<!ATTLIST ellipse
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  cx %Coordinate; "0"
+  cy %Coordinate; "0"
+  rx %Length; #REQUIRED
+  ry %Length; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs; >
+
+<!ENTITY % lineExt "" >
+<!ELEMENT line (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%lineExt;)*) >
+<!ATTLIST line
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x1 %Coordinate; "0"
+  y1 %Coordinate; "0"
+  x2 %Coordinate; "0"
+  y2 %Coordinate; "0"
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs; >
+
+<!ENTITY % polylineExt "" >
+<!ELEMENT polyline (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%polylineExt;)*) >
+<!ATTLIST polyline
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  points %Points; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs; >
+
+<!ENTITY % polygonExt "" >
+<!ELEMENT polygon (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%polygonExt;)*) >
+<!ATTLIST polygon
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  points %Points; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs; >
+
+
+<!--=================== Text ===================-->
+
+<!ENTITY % textExt "" >
+<!ELEMENT text (#PCDATA|desc|title|
+                tspan|tref|textPath|altGlyph|a|animate|set|
+                animateMotion|animateColor|animateTransform
+                %geExt;%textExt;)* >
+<!ATTLIST text
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % tspanExt "" >
+<!ELEMENT tspan (#PCDATA|tspan|tref|altGlyph|a|animate|set|animateColor
+                %tspanExt;)* >
+<!ATTLIST tspan
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate CDATA #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-TextContainerAttrs; >
+
+<!ENTITY % trefExt "" >
+<!ELEMENT tref (animate|set|animateColor
+                %trefExt;)* >
+<!ATTLIST tref
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate CDATA #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-TextContainerAttrs; >
+
+<!ENTITY % textPathExt "" >
+<!ELEMENT textPath (#PCDATA|tspan|tref|altGlyph|a|animate|set|animateColor
+                %textPathExt;)* >
+<!ATTLIST textPath
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  startOffset CDATA "0"
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-TextContainerAttrs; >
+
+<!ENTITY % altGlyphExt "" >
+<!ELEMENT altGlyph (#PCDATA %altGlyphExt;)* >
+<!ATTLIST altGlyph
+  %stdAttrs;
+  %langSpaceAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED >
+
+<!ENTITY % altGlyphDefExt "" >
+<!ELEMENT altGlyphDef (glyphSub %altGlyphDefExt;)* >
+<!ATTLIST altGlyphDef
+  %stdAttrs; >
+
+<!ELEMENT glyphSub EMPTY >
+<!ATTLIST glyphSub
+  %stdAttrs;
+  font CDATA #REQUIRED
+  glyphRef CDATA #REQUIRED
+  format CDATA #REQUIRED >
+
+<!--=================== SVG Fonts ===================-->
+
+<!ENTITY % fontExt "" >
+<!ELEMENT font (%descTitle;,missing-glyph,(glyph|hkern|vkern
+                   %fontExt;)*) >
+<!ATTLIST font
+  %stdAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  font-style CDATA #IMPLIED
+  font-variant CDATA #IMPLIED
+  font-weight CDATA #IMPLIED
+  font-stretch CDATA #IMPLIED
+  unicode-range CDATA #IMPLIED
+  units-per-em %Number; #REQUIRED
+  panose-1 CDATA #IMPLIED
+  slope %Number; #IMPLIED
+  cap-height %Number; #REQUIRED
+  x-height %Number; #REQUIRED
+  accent-height %Number; #IMPLIED
+  ascent %Number; #REQUIRED
+  descent %Number; #REQUIRED
+  horiz-origin-x %Number; #IMPLIED
+  horiz-origin-y %Number; #IMPLIED
+  horiz-adv-x %Number; #REQUIRED
+  vert-origin-x %Number; #IMPLIED
+  vert-origin-y %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED
+  text-bottom %Number; #REQUIRED
+  baseline %Number; #REQUIRED
+  centerline %Number; #REQUIRED
+  mathline %Number; #REQUIRED
+  ideographic %Number; #REQUIRED
+  hanging %Number; #REQUIRED
+  topline %Number; #REQUIRED
+  text-top %Number; #REQUIRED
+  font-face-name CDATA #IMPLIED
+  underline-position %Number; #IMPLIED
+  underline-thickness %Number; #IMPLIED
+  strikethrough-position %Number; #IMPLIED
+  strikethrough-thickness %Number; #IMPLIED
+  overline-position %Number; #IMPLIED
+  overline-thickness %Number; #IMPLIED >
+
+<!ENTITY % glyphExt "" >
+<!ELEMENT glyph (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|g|switch
+                   %glyphExt;)*) >
+<!ATTLIST glyph
+  %stdAttrs;
+  unicode CDATA #REQUIRED
+  glyph-name CDATA #IMPLIED
+  vert-text-orient CDATA #IMPLIED
+  arabic CDATA #IMPLIED
+  han CDATA #IMPLIED
+  horiz-adv-x %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED >
+
+<!ENTITY % missing-glyphExt "" >
+<!ELEMENT missing-glyph (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|g|switch
+                   %missing-glyphExt;)*) >
+<!ATTLIST missing-glyph
+  %stdAttrs;
+  horiz-adv-x %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED >
+
+<!ELEMENT hkern EMPTY >
+<!ATTLIST hkern
+  %stdAttrs;
+  u1 CDATA #IMPLIED
+  g1 CDATA #IMPLIED
+  u2 CDATA #IMPLIED
+  g2 CDATA #IMPLIED
+  k %Number; #REQUIRED >
+
+<!ELEMENT vkern EMPTY >
+<!ATTLIST vkern
+  %stdAttrs;
+  u1 CDATA #IMPLIED
+  g1 CDATA #IMPLIED
+  u2 CDATA #IMPLIED
+  g2 CDATA #IMPLIED
+  k %Number; #REQUIRED >
+
+
+<!--=================== Graphics Referencing Elements ===================-->
+
+<!ENTITY % useExt "" >
+<!ELEMENT use (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                   %geExt;%useExt;)*) >
+<!ATTLIST use
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+<!ENTITY % imageExt "" >
+<!ELEMENT image (%descTitle;,(animate|set|animateMotion|animateColor|animateTransform
+                   %geExt;%imageExt;)*) >
+<!ATTLIST image
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+
+<!--=================== Symbols and Markers ===================-->
+
+<!ENTITY % symbolExt "" >
+<!ELEMENT symbol (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|switch|a
+                   %ceExt;%symbolExt;)*) >
+<!ATTLIST symbol
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % markerExt "" >
+<!ELEMENT marker (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|switch|a
+                   %ceExt;%markerExt;)*) >
+<!ATTLIST marker
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  refX %Coordinate; #IMPLIED
+  refY %Coordinate; #IMPLIED
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  markerUnits (strokeWidth | userSpace | userSpaceOnUse) "strokeWidth"
+  markerWidth  %Length; "3"
+  markerHeight %Length; "3"
+  orient CDATA "0"
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+
+<!--========== Descriptions and Titles ==========-->
+
+<!ELEMENT desc (#PCDATA) >
+<!ATTLIST desc
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %StructuredText; >
+
+<!ELEMENT title (#PCDATA) >
+<!ATTLIST title
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %StructuredText; >
+
+
+<!--=================== Clipping and Masking ===================-->
+
+<!ENTITY % clipPathExt "" >
+<!ELEMENT clipPath (%descTitle;,
+                    (path|text|rect|circle|ellipse|line|polyline|polygon|
+                     use|animate|set|animateMotion|animateColor|animateTransform
+                     %ceExt;%clipPathExt;)*) >
+<!ATTLIST clipPath
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  clipPathUnits (userSpace | userSpaceOnUse | objectBoundingBox) "userSpace"
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % maskExt "" >
+<!ELEMENT mask (%descTitleDefs;,
+                    (path|text|rect|circle|ellipse|line|polyline|polygon|
+                     use|image|svg|g|switch|a|
+                     animate|set|animateMotion|animateColor|animateTransform
+                     %ceExt;%maskExt;)*) >
+<!ATTLIST mask
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  maskUnits (userSpace | userSpaceOnUse | objectBoundingBox) "userSpace"
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+
+<!--=================== Gradients and Patterns ===================-->
+
+<!ENTITY % linearGradientExt "" >
+<!ELEMENT linearGradient (stop|animate|set|animateTransform
+                   %linearGradientExt;)* >
+<!ATTLIST linearGradient
+  %stdAttrs;
+  gradientUnits (userSpace | userSpaceOnUse | objectBoundingBox) 'userSpace'
+  gradientTransform %TransformList; #IMPLIED
+  x1 %Coordinate; #IMPLIED
+  y1 %Coordinate; #IMPLIED
+  x2 %Coordinate; #IMPLIED
+  y2 %Coordinate; #IMPLIED
+  spreadMethod (pad | reflect | repeat) "pad"
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+
+<!ENTITY % radialGradientExt "" >
+<!ELEMENT radialGradient (stop|animate|set|animateTransform
+                   %radialGradientExt;)* >
+<!ATTLIST radialGradient
+  %stdAttrs;
+  gradientUnits (userSpace | userSpaceOnUse | objectBoundingBox) 'userSpace'
+  gradientTransform %TransformList; #IMPLIED
+  cx %Coordinate; #IMPLIED
+  cy %Coordinate; #IMPLIED
+  r %Length; #IMPLIED
+  fx %Coordinate; #IMPLIED
+  fy %Coordinate; #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+
+<!ENTITY % stopExt "" >
+<!ELEMENT stop (animate|set|animateColor
+                   %stopExt;)* >
+<!ATTLIST stop
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  offset %Length; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-GradientAttrs; >
+
+<!ENTITY % patternExt "" >
+<!ELEMENT pattern (%descTitleDefs;,
+                    (path|text|rect|circle|ellipse|line|polyline|polygon|
+                     use|image|svg|g|switch|a
+                     %ceExt;%patternExt;)*) >
+<!ATTLIST pattern
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  patternUnits (userSpace | userSpaceOnUse | objectBoundingBox) 'userSpace'
+  patternTransform %TransformList; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs; >
+
+
+
+<!--=================== Linking ===================-->
+
+<!ENTITY % aExt "" >
+<!ELEMENT a       (#PCDATA|desc|title|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|switch|a|
+                   tspan|tref|textPath|altGlyph
+                   %ceExt;%aExt;)* >
+<!ATTLIST a
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/2000/xlink/namespace/"
+  xlink:type (simple|extended|locator|arc) #FIXED "simple" 
+  xlink:role CDATA #IMPLIED
+  xlink:title CDATA #IMPLIED
+  xlink:show (new|embed|replace) 'replace'
+  xlink:actuate (onRequest|onLoad) #FIXED 'onRequest'
+  xlink:href %URI; #REQUIRED
+  target %LinkTarget; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % viewExt "" >
+<!ELEMENT view (%descTitle;%viewExt;) >
+<!ATTLIST view
+  %stdAttrs;
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  enableZoomAndPanControls (true | false) "true" 
+  viewTarget CDATA #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+
+<!--=================== Animation ===================-->
+
+<!ENTITY % animTargetAttrs
+ "%xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  attributeName  CDATA  #REQUIRED
+  attributeType  CDATA  #IMPLIED" >
+
+<!ENTITY % animTimingAttrs
+ "begin CDATA #IMPLIED 
+  dur CDATA #IMPLIED
+  restart (always | never | whenNotActive) 'always'
+  repeatCount CDATA #IMPLIED 
+  repeatDur CDATA #IMPLIED
+  end CDATA #IMPLIED
+  fill (remove | freeze) 'remove'" >
+
+<!ENTITY % animValueAttrs
+ "calcMode (discrete | linear | evenPace | spline) 'linear'
+  values CDATA #IMPLIED
+  from CDATA #IMPLIED
+  to CDATA #IMPLIED
+  by CDATA #IMPLIED
+  keyTimes CDATA #IMPLIED
+  keySplines CDATA #IMPLIED" >
+
+<!ENTITY % animAdditionAttrs
+ "additive       (replace | sum) 'replace'
+  accumulate     (none | sum) 'none'" >
+
+<!ENTITY % animateExt "" >
+<!ELEMENT animate (%descTitle;%animateExt;) >
+<!ATTLIST animate
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animTargetAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs; >
+
+<!ENTITY % setExt "" >
+<!ELEMENT set (%descTitle;%setExt;) >
+<!ATTLIST set
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animTargetAttrs;
+  %animTimingAttrs;
+  to CDATA #IMPLIED >
+
+<!ENTITY % animateMotionExt "" >
+<!ELEMENT animateMotion (%descTitle;%animateMotionExt;) >
+<!ATTLIST animateMotion
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs;
+  path CDATA #IMPLIED
+  rotate CDATA #IMPLIED
+  origin CDATA #IMPLIED >
+
+<!ENTITY % animateColorExt "" >
+<!ELEMENT animateColor (%descTitle;%animateColorExt;) >
+<!ATTLIST animateColor
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animTargetAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs; >
+
+<!ENTITY % animateTransformExt "" >
+<!ELEMENT animateTransform (%descTitle;%animateTransformExt;) >
+<!ATTLIST animateTransform
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animTargetAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs;
+  type (translate | scale | rotate | skewX | skewY) "translate" >
+
+
+<!--========== Defining Scripts and Declaring Styles ==========-->
+
+<!ELEMENT script (#PCDATA) >
+<!ATTLIST script
+  %stdAttrs;
+  type %ContentType; #REQUIRED
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+
+<!-- Define the 'style' element for Stylable SVG.
+     This element is not available for Exchange SVG. -->
+<![%StylableSVG;[
+  <!ELEMENT style (#PCDATA) >
+  <!ATTLIST style 
+    %stdAttrs;
+    type %ContentType; #REQUIRED >
+]]>
+
+
+<!--==== (Exchange SVG Only) Defining color profiles and font faces ====-->
+
+<![%ExchangeSVG;[
+  <!ELEMENT color-profile (%descTitle;,color-profile-src) >
+  <!ATTLIST color-profile 
+    %stdAttrs;
+    name CDATA #REQUIRED
+    rendering-intent CDATA #IMPLIED >
+
+  <!ELEMENT color-profile-src EMPTY >
+  <!ATTLIST color-profile-src 
+    %stdAttrs;
+    %xlinkRefAttrs;
+    xlink:href %URI; #REQUIRED >
+
+  <!ELEMENT font-face (%descTitle;,font-face-src,(definition-src)?) >
+  <!ATTLIST font-face 
+    %stdAttrs;
+    font-family CDATA #IMPLIED
+    font-style CDATA #IMPLIED
+    font-variant CDATA #IMPLIED
+    font-weight CDATA #IMPLIED
+    font-stretch CDATA #IMPLIED
+    font-size CDATA #IMPLIED
+    unicode-range CDATA #IMPLIED
+    units-per-em %Number; #IMPLIED
+    panose-1 CDATA #IMPLIED
+    stemv %Number; #IMPLIED
+    stemh %Number; #IMPLIED
+    slope %Number; #IMPLIED
+    cap-height %Number; #IMPLIED
+    x-height %Number; #IMPLIED
+    ascent %Number; #IMPLIED
+    descent %Number; #IMPLIED
+    widths CDATA #IMPLIED
+    bbox CDATA #IMPLIED
+    baseline %Number; #IMPLIED
+    centerline %Number; #IMPLIED
+    mathline %Number; #IMPLIED
+    topline %Number; #IMPLIED >
+
+  <!ELEMENT font-face-src (font-face-uri|font-face-name)+ >
+  <!ATTLIST font-face-src 
+    %stdAttrs; >
+
+  <!ELEMENT font-face-uri (font-face-format*) >
+  <!ATTLIST font-face-uri 
+    %stdAttrs;
+    %xlinkRefAttrs;
+    xlink:href %URI; #REQUIRED >
+
+  <!ELEMENT font-face-format EMPTY >
+  <!ATTLIST font-face-format 
+    %stdAttrs;
+    string CDATA #IMPLIED >
+
+  <!ELEMENT font-face-name EMPTY >
+  <!ATTLIST font-face-name 
+    %stdAttrs;
+    name CDATA #IMPLIED >
+
+  <!ELEMENT definition-src EMPTY >
+  <!ATTLIST definition-src 
+    %stdAttrs;
+    %xlinkRefAttrs;
+    xlink:href %URI; #REQUIRED >
+]]>
+
+
+<!--=================== Custom cursors ===================-->
+
+<!ELEMENT cursor (%descTitle;) >
+<!ATTLIST cursor
+  %stdAttrs;
+  %testAttrs;
+  x %Coordinate; "0"
+  y %Coordinate; "0"
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+
+<!--=================== Extensibility ===================-->
+
+<!ENTITY % switchExt "" >
+<!ELEMENT switch (%descTitleDefs;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|switch|a|foreignObject|
+                   animate|set|animateMotion|animateColor|animateTransform
+                   %ceExt;%switchExt;)*) >
+<!ATTLIST switch
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs; >
+
+<!ENTITY % foreignObjectExt "" >
+<!ELEMENT foreignObject (#PCDATA %ceExt;%foreignObjectExt;)* >
+<!ATTLIST foreignObject
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs;
+  %StructuredText; >
+
+
+
+<!--=================== Metadata ===================-->
+
+<!ENTITY % metadataExt "" >
+<!ELEMENT metadata (#PCDATA %metadataExt;)* >
+<!ATTLIST metadata
+  %stdAttrs; >
+
+
+<!--============== Filter Effects ==============-->
+
+<!ENTITY % filter_primitive_attributes
+  "x %Coordinate; #IMPLIED
+   y %Coordinate; #IMPLIED
+   width %Length; #IMPLIED
+   height %Length; #IMPLIED
+   result CDATA #IMPLIED" >
+
+<!ENTITY % filter_primitive_attributes_with_in
+  "%filter_primitive_attributes;
+   in CDATA #IMPLIED">
+
+<!ENTITY % component_transfer_function_attributes
+  "type (identity | table | linear | gamma) #REQUIRED
+   tableValues CDATA #IMPLIED
+   slope %Number; #IMPLIED
+   intercept %Number; #IMPLIED
+   amplitude %Number; #IMPLIED
+   exponent %Number; #IMPLIED
+   offset %Number; #IMPLIED" >
+
+<!ENTITY % filterExt "" >
+<!ELEMENT filter (feBlend|feFlood|
+  feColorMatrix|feComponentTransfer|
+  feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|
+  feGaussianBlur|feImage|feMerge|
+  feMorphology|feOffset|feSpecularLighting|
+  feTile|feTurbulence|
+  animate|set
+  %filterExt;)* >
+<!ATTLIST filter
+  %stdAttrs;
+  %langSpaceAttrs;
+  filterUnits (userSpace | userSpaceOnUse | objectBoundingBox) "userSpace"
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED
+  filterRes CDATA #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+<!ELEMENT feBlend (animate|set)* >
+<!ATTLIST feBlend
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  mode (normal | multiply | screen | darken | lighten) "normal"
+  in2 CDATA #REQUIRED >
+
+<!ELEMENT feColorMatrix (animate|set)* >
+<!ATTLIST feColorMatrix
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  type (matrix | saturate | hueRotate | luminanceToAlpha) "matrix"
+  values CDATA #IMPLIED >
+
+<!ELEMENT feComponentTransfer (feFuncR?,feFuncG?,feFuncB?,feFuncA?) >
+<!ATTLIST feComponentTransfer
+  %stdAttrs;
+  %filter_primitive_attributes_with_in; >
+
+<!ELEMENT feFuncR (animate|set)* >
+<!ATTLIST feFuncR
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncG (animate|set)* >
+<!ATTLIST feFuncG
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncB (animate|set)* >
+<!ATTLIST feFuncB
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncA (animate|set)* >
+<!ATTLIST feFuncA
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feComposite (animate|set)* >
+<!ATTLIST feComposite
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  operator (over | in | out | atop | xor | arithmetic) "over"
+  k1 %Integer; #IMPLIED
+  k2 %Integer; #IMPLIED
+  k3 %Integer; #IMPLIED
+  k4 %Integer; #IMPLIED
+  in2 CDATA #REQUIRED >
+
+<!ELEMENT feConvolveMatrix (animate|set)* >
+<!ATTLIST feConvolveMatrix
+  %filter_primitive_attributes_with_in;
+  order CDATA #REQUIRED
+  kernelMatrix CDATA #REQUIRED
+  divisor %Number; #IMPLIED
+  targetX %Integer; #IMPLIED
+  targetY %Integer; #IMPLIED
+  edgeMode (duplicate|wrap|none) "duplicate" 
+  kernelUnitLength CDATA #IMPLIED >
+
+<!ELEMENT feDiffuseLighting ((feDistantLight|fePointLight|feSpotLight),(animate|set|animateColor)*) >
+<!ATTLIST feDiffuseLighting
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  resultScale %Number; #IMPLIED
+  surfaceScale %Number; #IMPLIED
+  diffuseConstant %Number; #IMPLIED
+  lightColor %SVGColor; #IMPLIED >
+
+<!ELEMENT feDistantLight (animate|set)* >
+<!ATTLIST feDistantLight
+  %stdAttrs;
+  azimuth %Number; #IMPLIED
+  elevation %Number; #IMPLIED >
+
+<!ELEMENT fePointLight (animate|set)* >
+<!ATTLIST fePointLight
+  %stdAttrs;
+  x %Number; #IMPLIED
+  y %Number; #IMPLIED
+  z %Number; #IMPLIED >
+
+<!ELEMENT feSpotLight (animate|set)* >
+<!ATTLIST feSpotLight
+  %stdAttrs;
+  x %Number; #IMPLIED
+  y %Number; #IMPLIED
+  z %Number; #IMPLIED
+  pointsAtX %Number; #IMPLIED
+  pointsAtY %Number; #IMPLIED
+  pointsAtZ %Number; #IMPLIED
+  specularExponent %Number; #IMPLIED >
+
+<!ELEMENT feDisplacementMap (animate|set)* >
+<!ATTLIST feDisplacementMap
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  scale %Number; #IMPLIED
+  xChannelSelector (R | G | B | A) "A"
+  yChannelSelector (R | G | B | A) "A"
+  in2 CDATA #REQUIRED >
+
+<!ELEMENT feFlood (animate|set|animateColor)* >
+<!ATTLIST feFlood
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  style %StyleSheet; #IMPLIED
+  %ExchangeSVG-feFloodAttrs; >
+
+<!ELEMENT feGaussianBlur (animate|set)* >
+<!ATTLIST feGaussianBlur
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  stdDeviation CDATA #IMPLIED >
+
+<!ELEMENT feImage (animate|set|animateTransform)* >
+<!ATTLIST feImage
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  transform %TransformList; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %StylableSVG-StyleAttribute;
+  %ExchangeSVG-ContainerAttrs;
+  %ExchangeSVG-FillStrokeAttrs;
+  %ExchangeSVG-GradientAttrs;
+  %ExchangeSVG-GraphicsAttrs;
+  %ExchangeSVG-MarkerAttrs;
+  %ExchangeSVG-TextContainerAttrs;
+  %ExchangeSVG-TextElementAttrs;
+  %ExchangeSVG-ViewportAttrs;
+  %filter_primitive_attributes; >
+
+<!ELEMENT feMerge (feMergeNode)* >
+<!ATTLIST feMerge
+  %stdAttrs;
+  %filter_primitive_attributes; >
+
+<!ELEMENT feMergeNode (animate|set)* >
+<!ATTLIST feMergeNode
+  %stdAttrs;
+  in CDATA #IMPLIED >
+
+<!ELEMENT feMorphology (animate|set)* >
+<!ATTLIST feMorphology
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  operator (erode | dilate) "erode"
+  radius %Length; #IMPLIED >
+
+<!ELEMENT feOffset (animate|set)* >
+<!ATTLIST feOffset
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  dx %Length; #IMPLIED
+  dy %Length; #IMPLIED >
+
+<!ELEMENT feSpecularLighting ((feDistantLight|fePointLight|feSpotLight),(animate|set|animateColor)*) >
+<!ATTLIST feSpecularLighting
+  %stdAttrs;
+  %filter_primitive_attributes_with_in;
+  surfaceScale %Number; #IMPLIED
+  specularConstant %Number; #IMPLIED
+  specularExponent %Number; #IMPLIED
+  lightColor %SVGColor; #IMPLIED >
+
+<!ELEMENT feTile (animate|set)* >
+<!ATTLIST feTile
+  %stdAttrs;
+  %filter_primitive_attributes_with_in; >
+
+<!ELEMENT feTurbulence (animate|set)* >
+<!ATTLIST feTurbulence
+  %stdAttrs;
+  %filter_primitive_attributes;
+  baseFrequency CDATA #IMPLIED
+  numOctaves %Integer; #IMPLIED
+  seed %Number; #IMPLIED
+  stitchTiles (stitch | noStitch) "noStitch"
+  type (fractalNoise | turbulence) "turbulence" >
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-stylable.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-stylable.dtd
new file mode 100644
index 0000000..1b27982
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg-20000303-stylable.dtd
@@ -0,0 +1,59 @@
+<!--
+  This is the DTD for Stylable SVG. It adds a small number of 
+  elements and attributes to the Shared DTD for the purposes
+  of allowing SVG content to be styled.
+
+  In most cases, authors should use the DTD for Stylable SVG.
+  The DTD for Exchange SVG is available for specific purposes
+  as described in the Exchange SVG chapter of the SVG specification.
+
+  The specification for SVG that corresponds to this DTD is available at:
+
+    http://www.w3.org/TR/2000/03/WD-SVG-20000303/
+
+  Copyright (c) 2000 W3C (MIT, INRIA, Keio), All Rights Reserved.
+
+  For this working draft:
+
+    Namespaces:
+      Stylable SVG:     http://www.w3.org/2000/svg-20000303-stylable
+      Exchange SVG:   http://www.w3.org/2000/svg-20000303-exchange  
+
+    Public identifiers:
+      PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN"
+      PUBLIC "-//W3C//DTD SVG 20000303 Exchange//EN"
+
+    URIs for the DTDs:
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-shared.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd
+      http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-exchange.dtd
+
+  Typical usage in the case of stand-alone Stylable SVG documents:
+
+<?xml version="1.0" ... ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20000303 Stylable//EN" 
+  "http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd">
+<svg ...>
+ ...
+</svg>
+
+  Typical usage when Stylable SVG is embedded inline within a parent XML document:
+
+<?xml version="1.0" ... ?>
+<!DOCTYPE foo ... >
+<foo ...>
+ ...
+ <svg xmlns="http://www.w3.org/2000/svg-20000303-stylable" ... >
+    ...
+ </svg>
+ ...
+</foo>
+-->
+
+<!ENTITY % StylableSVG "INCLUDE" >
+<!ENTITY % ExchangeSVG "IGNORE" >
+<!ENTITY % SVGNamespace "http://www.w3.org/2000/svg-20000303-stylable" >
+<!ENTITY % Shared PUBLIC "-//W3C//DTD SVG 20000303 Shared//EN" "svg-20000303-shared.dtd" >
+%Shared;
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg10.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg10.dtd
new file mode 100644
index 0000000..110f5ce
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/svg10.dtd
@@ -0,0 +1,1704 @@
+<!-- =====================================================================
+  This is the DTD for SVG 1.0.
+
+  The specification for SVG that corresponds to this DTD is available at:
+
+    http://www.w3.org/TR/2001/REC-SVG-20010904/
+
+  Copyright (c) 2000 W3C (MIT, INRIA, Keio), All Rights Reserved.
+
+  For SVG 1.0:
+
+    Namespace:
+      http://www.w3.org/2000/svg  
+
+    Public identifier:
+      PUBLIC "-//W3C//DTD SVG 1.0//EN"
+
+    URI for the DTD:
+      http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd
+============================================================================= -->
+
+
+<!-- ==============================================================
+     ENTITY DECLARATIONS: Data types 
+     ============================================================== -->
+
+<!ENTITY % BaselineShiftValue "CDATA">
+    <!-- 'baseline-shift' property/attribute value (e.g., 'baseline', 'sub', etc.) -->
+
+<!ENTITY % Boolean "(false | true)">
+    <!-- feature specification -->
+
+<!ENTITY % ClassList "CDATA">
+    <!-- list of classes -->
+
+<!ENTITY % ClipValue "CDATA">
+    <!-- 'clip' property/attribute value (e.g., 'auto', rect(...)) -->
+
+<!ENTITY % ClipPathValue "CDATA">
+    <!-- 'clip-path' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % ClipFillRule "(nonzero | evenodd | inherit)">
+    <!-- 'clip-rule' or fill-rule property/attribute value -->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % Coordinate "CDATA">
+    <!-- a <coordinate> -->
+
+<!ENTITY % Coordinates "CDATA">
+    <!-- a list of <coordinate>s -->
+
+<!ENTITY % Color "CDATA">
+    <!-- a <color> value -->
+
+<!ENTITY % CursorValue "CDATA">
+    <!-- 'cursor' property/attribute value (e.g., 'crosshair', %URI;) -->
+
+<!ENTITY % EnableBackgroundValue "CDATA">
+    <!-- 'enable-background' property/attribute value (e.g., 'new', 'accumulate') -->
+
+<!ENTITY % ExtensionList "CDATA">
+    <!-- extension list specification -->
+
+<!ENTITY % FeatureList "CDATA">
+    <!-- feature list specification -->
+
+<!ENTITY % FilterValue "CDATA">
+    <!-- 'filter' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % FontFamilyValue "CDATA">
+    <!-- 'font-family' property/attribute value (i.e., list of fonts) -->
+
+<!ENTITY % FontSizeValue "CDATA">
+    <!-- 'font-size' property/attribute value -->
+
+<!ENTITY % FontSizeAdjustValue "CDATA">
+    <!-- 'font-size-adjust' property/attribute value -->
+
+<!ENTITY % GlyphOrientationHorizontalValue "CDATA">
+    <!-- 'glyph-orientation-horizontal' property/attribute value (e.g., <angle>) -->
+
+<!ENTITY % GlyphOrientationVerticalValue "CDATA">
+    <!-- 'glyph-orientation-vertical' property/attribute value (e.g., 'auto', <angle>) -->
+
+<!ENTITY % Integer "CDATA">
+    <!-- a <integer> -->
+
+<!ENTITY % KerningValue "CDATA">
+    <!-- 'kerning' property/attribute value (e.g., auto | <length>) -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % LanguageCodes "CDATA">
+    <!-- comma-separated list of language codes, as per [RFC3066] -->
+
+<!ENTITY % Length "CDATA">
+    <!-- a <length> -->
+
+<!ENTITY % Lengths "CDATA">
+    <!-- a list of <length>s -->
+
+<!ENTITY % LinkTarget "NMTOKEN">
+    <!-- link to this target -->
+
+<!ENTITY % MarkerValue "CDATA">
+    <!-- 'marker' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % MaskValue "CDATA">
+    <!-- 'mask' property/attribute value (e.g., 'none', %URI;) -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- comma-separated list of media descriptors. -->
+
+<!ENTITY % Number "CDATA">
+    <!-- a <number> -->
+
+<!ENTITY % NumberOptionalNumber "CDATA">
+    <!-- list of <number>s, but at least one and at most two -->
+
+<!ENTITY % NumberOrPercentage "CDATA">
+    <!-- a <number> or a  <percentage> -->
+
+<!ENTITY % Numbers "CDATA">
+    <!-- a list of <number>s -->
+
+<!ENTITY % OpacityValue "CDATA">
+    <!-- opacity value (e.g., <number>) -->
+
+<!ENTITY % Paint "CDATA">
+    <!-- a 'fill' or 'stroke' property/attribute value: <paint> -->
+
+<!ENTITY % PathData "CDATA">
+    <!-- a path data specification -->
+
+<!ENTITY % Points "CDATA">
+    <!-- a list of points -->
+
+<!ENTITY % PreserveAspectRatioSpec "CDATA">
+    <!-- 'preserveAspectRatio' attribute specification -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % SpacingValue "CDATA">
+    <!-- 'letter-spacing' or 'word-spacing' property/attribute value (e.g., normal | <length>) -->
+
+<!ENTITY % StrokeDashArrayValue "CDATA">
+    <!-- 'stroke-dasharray' property/attribute value (e.g., 'none', list of <number>s) -->
+
+<!ENTITY % StrokeDashOffsetValue "CDATA">
+    <!-- 'stroke-dashoffset' property/attribute value (e.g., 'none', <legnth>) -->
+
+<!ENTITY % StrokeMiterLimitValue "CDATA">
+    <!-- 'stroke-miterlimit' property/attribute value (e.g., <number>) -->
+
+<!ENTITY % StrokeWidthValue "CDATA">
+    <!-- 'stroke-width' property/attribute value (e.g., <length>) -->
+
+<!ENTITY % StructuredText
+  "content CDATA #FIXED 'structured text'" >
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % SVGColor "CDATA">
+    <!-- An SVG color value (RGB plus optional ICC) -->
+
+<!ENTITY % Text "CDATA">
+    <!-- arbitrary text string -->
+
+<!ENTITY % TextDecorationValue "CDATA">
+    <!-- 'text-decoration' property/attribute value (e.g., 'none', 'underline') -->
+
+<!ENTITY % TransformList "CDATA">
+    <!-- list of transforms -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [URI] -->
+
+<!ENTITY % ViewBoxSpec "CDATA">
+    <!-- 'viewBox' attribute specification -->
+
+
+<!-- ==============================================================
+     ENTITY DECLARATIONS: Collections of common attributes 
+     ============================================================== -->
+
+<!-- All elements have an ID. -->
+<!ENTITY % stdAttrs
+ "id ID #IMPLIED
+  xml:base %URI; #IMPLIED" >
+
+<!-- Common attributes for elements that might contain character data content. -->
+<!ENTITY % langSpaceAttrs
+ "xml:lang %LanguageCode; #IMPLIED
+  xml:space (default|preserve) #IMPLIED" >
+
+<!-- Common attributes to check for system capabilities. -->
+<!ENTITY % testAttrs
+ "requiredFeatures %FeatureList; #IMPLIED
+  requiredExtensions %ExtensionList; #IMPLIED
+  systemLanguage %LanguageCodes; #IMPLIED" >
+
+<!-- For most uses of URI referencing:
+        standard XLink attributes other than xlink:href. -->
+<!ENTITY % xlinkRefAttrs
+ "xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink'
+  xlink:type (simple) #FIXED 'simple' 
+  xlink:role %URI; #IMPLIED
+  xlink:arcrole %URI; #IMPLIED
+  xlink:title CDATA #IMPLIED
+  xlink:show (other) 'other'
+  xlink:actuate (onLoad) #FIXED 'onLoad'" >
+
+<!-- Standard XLink attributes for uses of URI referencing where xlink:show is 'embed' -->
+<!ENTITY % xlinkRefAttrsEmbed
+ "xmlns:xlink CDATA #FIXED 'http://www.w3.org/1999/xlink'
+  xlink:type (simple) #FIXED 'simple' 
+  xlink:role %URI; #IMPLIED
+  xlink:arcrole %URI; #IMPLIED
+  xlink:title CDATA #IMPLIED
+  xlink:show (embed) 'embed'
+  xlink:actuate (onLoad) #FIXED 'onLoad'" >
+
+<!ENTITY % graphicsElementEvents
+  "onfocusin %Script; #IMPLIED
+   onfocusout %Script; #IMPLIED
+   onactivate %Script; #IMPLIED
+   onclick %Script; #IMPLIED
+   onmousedown %Script; #IMPLIED
+   onmouseup %Script; #IMPLIED
+   onmouseover %Script; #IMPLIED
+   onmousemove %Script; #IMPLIED
+   onmouseout %Script; #IMPLIED
+   onload %Script; #IMPLIED" >
+
+<!ENTITY % documentEvents
+  "onunload %Script; #IMPLIED
+   onabort %Script; #IMPLIED
+   onerror %Script; #IMPLIED
+   onresize %Script; #IMPLIED
+   onscroll %Script; #IMPLIED
+   onzoom %Script; #IMPLIED" >
+
+<!ENTITY % animationEvents
+  "onbegin %Script; #IMPLIED
+   onend %Script; #IMPLIED
+   onrepeat %Script; #IMPLIED" >
+
+<!-- This entity allows for at most one of desc, title and metadata,
+     supplied in any order -->
+<!ENTITY % descTitleMetadata
+          "(((desc,((title,metadata?)|(metadata,title?))?)|
+          (title,((desc,metadata?)|(metadata,desc?))?)|
+          (metadata,((desc,title?)|(title,desc?))?))?)" >
+
+
+<!-- ==============================================================
+     ENTITY DECLARATIONS: Collections of presentation attributes 
+     ============================================================== -->
+
+<!-- The following presentation attributes have to do with specifying color. -->
+<!ENTITY % PresentationAttributes-Color
+  "color %Color; #IMPLIED
+   color-interpolation (auto | sRGB | linearRGB | inherit) #IMPLIED
+   color-rendering (auto | optimizeSpeed | optimizeQuality | inherit) #IMPLIED " >
+
+<!-- The following presentation attributes apply to container elements. -->
+<!ENTITY % PresentationAttributes-Containers
+  "enable-background %EnableBackgroundValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to 'feFlood' elements. -->
+<!ENTITY % PresentationAttributes-feFlood
+  "flood-color %SVGColor; #IMPLIED
+   flood-opacity %OpacityValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to filling and stroking operations. -->
+<!ENTITY % PresentationAttributes-FillStroke
+  "fill %Paint; #IMPLIED
+   fill-opacity %OpacityValue; #IMPLIED
+   fill-rule %ClipFillRule; #IMPLIED
+   stroke %Paint; #IMPLIED
+   stroke-dasharray %StrokeDashArrayValue; #IMPLIED
+   stroke-dashoffset %StrokeDashOffsetValue; #IMPLIED
+   stroke-linecap (butt | round | square | inherit) #IMPLIED
+   stroke-linejoin (miter | round | bevel | inherit) #IMPLIED
+   stroke-miterlimit %StrokeMiterLimitValue; #IMPLIED
+   stroke-opacity %OpacityValue; #IMPLIED
+   stroke-width %StrokeWidthValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to filter primitives. -->
+<!ENTITY % PresentationAttributes-FilterPrimitives
+  "color-interpolation-filters (auto | sRGB | linearRGB | inherit) #IMPLIED " >
+
+<!-- The following presentation attributes have to do with selecting a font to use. -->
+<!ENTITY % PresentationAttributes-FontSpecification
+  "font-family %FontFamilyValue; #IMPLIED
+   font-size %FontSizeValue; #IMPLIED
+   font-size-adjust %FontSizeAdjustValue; #IMPLIED
+   font-stretch (normal | wider | narrower | ultra-condensed | extra-condensed |
+                 condensed | semi-condensed | semi-expanded | expanded |
+                 extra-expanded | ultra-expanded | inherit) #IMPLIED
+   font-style (normal | italic | oblique | inherit) #IMPLIED
+   font-variant (normal | small-caps | inherit) #IMPLIED
+   font-weight (normal | bold | bolder | lighter | 100 | 200 | 300 |
+               400 | 500 | 600 | 700 | 800 | 900 | inherit) #IMPLIED " >
+
+<!-- The following presentation attributes apply to gradient 'stop' elements. -->
+<!ENTITY % PresentationAttributes-Gradients
+  "stop-color %SVGColor; #IMPLIED
+   stop-opacity %OpacityValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to graphics elements. -->
+<!ENTITY % PresentationAttributes-Graphics
+  "clip-path %ClipPathValue; #IMPLIED
+   clip-rule %ClipFillRule; #IMPLIED
+   cursor %CursorValue; #IMPLIED
+   display (inline | block | list-item | run-in | compact | marker |
+            table | inline-table | table-row-group | table-header-group |
+            table-footer-group | table-row | table-column-group | table-column |
+            table-cell | table-caption | none | inherit) #IMPLIED
+   filter %FilterValue; #IMPLIED
+   image-rendering (auto | optimizeSpeed | optimizeQuality | inherit) #IMPLIED
+   mask %MaskValue; #IMPLIED
+   opacity %OpacityValue; #IMPLIED
+   pointer-events (visiblePainted | visibleFill | visibleStroke | visible |
+                   painted | fill | stroke | all | none | inherit) #IMPLIED
+   shape-rendering (auto | optimizeSpeed | crispEdges | geometricPrecision | inherit) #IMPLIED
+   text-rendering (auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit) #IMPLIED
+   visibility (visible | hidden | inherit) #IMPLIED " >
+
+<!-- The following presentation attributes apply to 'image' elements. -->
+<!ENTITY % PresentationAttributes-Images
+  "color-profile CDATA #IMPLIED " >
+
+<!--The following presentation attributes apply to 'feDiffuseLighting' and 'feSpecularLighting' elements. -->
+<!ENTITY % PresentationAttributes-LightingEffects
+  "lighting-color %SVGColor; #IMPLIED " >
+
+<!-- The following presentation attributes apply to marker operations. -->
+<!ENTITY % PresentationAttributes-Markers
+  "marker-start %MarkerValue; #IMPLIED
+   marker-mid %MarkerValue; #IMPLIED
+   marker-end %MarkerValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to text content elements. -->
+<!ENTITY % PresentationAttributes-TextContentElements
+  "alignment-baseline (baseline | top | before-edge | text-top | text-before-edge |
+                        middle | bottom | after-edge | text-bottom | text-after-edge |
+                        ideographic | lower | hanging | mathematical | inherit) #IMPLIED
+   baseline-shift %BaselineShiftValue; #IMPLIED
+   direction (ltr | rtl | inherit) #IMPLIED
+   dominant-baseline (auto | autosense-script | no-change | reset|
+                      ideographic | lower | hanging | mathematical | inherit ) #IMPLIED
+   glyph-orientation-horizontal %GlyphOrientationHorizontalValue; #IMPLIED
+   glyph-orientation-vertical %GlyphOrientationVerticalValue; #IMPLIED
+   kerning %KerningValue; #IMPLIED
+   letter-spacing %SpacingValue; #IMPLIED
+   text-anchor (start | middle | end | inherit) #IMPLIED
+   text-decoration %TextDecorationValue; #IMPLIED
+   unicode-bidi (normal | embed | bidi-override | inherit) #IMPLIED
+   word-spacing %SpacingValue; #IMPLIED " >
+
+<!-- The following presentation attributes apply to 'text' elements. -->
+<!ENTITY % PresentationAttributes-TextElements
+  "writing-mode (lr-tb | rl-tb | tb-rl | lr | rl | tb | inherit) #IMPLIED " >
+
+<!-- The following presentation attributes apply to elements that establish viewports. -->
+<!ENTITY % PresentationAttributes-Viewports
+  "clip %ClipValue; #IMPLIED
+   overflow (visible | hidden | scroll | auto | inherit) #IMPLIED " >
+
+<!--The following represents the complete list of presentation attributes. -->
+<!ENTITY % PresentationAttributes-All
+  "%PresentationAttributes-Color;
+   %PresentationAttributes-Containers;
+   %PresentationAttributes-feFlood;
+   %PresentationAttributes-FillStroke;
+   %PresentationAttributes-FilterPrimitives;
+   %PresentationAttributes-FontSpecification;
+   %PresentationAttributes-Gradients;
+   %PresentationAttributes-Graphics;
+   %PresentationAttributes-Images;
+   %PresentationAttributes-LightingEffects;
+   %PresentationAttributes-Markers;
+   %PresentationAttributes-TextContentElements;
+   %PresentationAttributes-TextElements;
+   %PresentationAttributes-Viewports;" >
+
+
+
+<!-- ==============================================================
+     ENTITY DECLARATIONS: DTD extensions 
+     ============================================================== -->
+
+<!-- Allow for extending the DTD with internal subset for 
+     container and graphics elements -->
+<!ENTITY % ceExt "" >
+<!ENTITY % geExt "" >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Document Structure 
+     ============================================================== -->
+
+<!ENTITY % svgExt "" >
+<!ELEMENT svg (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%svgExt;)* >
+<!ATTLIST svg
+  xmlns CDATA #FIXED "http://www.w3.org/2000/svg"
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED 
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  zoomAndPan (disable | magnify) 'magnify'
+  %graphicsElementEvents;
+  %documentEvents;
+  version %Number; #FIXED "1.0"
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED
+  contentScriptType %ContentType; "text/ecmascript"
+  contentStyleType %ContentType; "text/css" >
+
+<!ENTITY % gExt "" >
+<!ELEMENT g (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%gExt;)* >
+<!ATTLIST g
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;  >
+
+<!ENTITY % defsExt "" >
+<!ELEMENT defs (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%defsExt;)* >
+<!ATTLIST defs
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;  >
+
+<!ENTITY % descExt "" >
+<!ELEMENT desc (#PCDATA %descExt;)* >
+<!ATTLIST desc
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %StructuredText; >
+
+<!ENTITY % titleExt "" >
+<!ELEMENT title (#PCDATA %titleExt;)* >
+<!ATTLIST title
+  %stdAttrs;
+  %langSpaceAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %StructuredText; >
+
+<!ENTITY % symbolExt "" >
+<!ELEMENT symbol (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%symbolExt;)* >
+<!ATTLIST symbol
+  %stdAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  %graphicsElementEvents; >
+
+<!ENTITY % useExt "" >
+<!ELEMENT use (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                   %geExt;%useExt;)*) >
+<!ATTLIST use
+  %stdAttrs;
+  %xlinkRefAttrsEmbed;
+  xlink:href %URI; #REQUIRED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED >
+
+<!ENTITY % imageExt "" >
+<!ELEMENT image (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                   %geExt;%imageExt;)*) >
+<!ATTLIST image
+  %stdAttrs;
+  %xlinkRefAttrsEmbed;
+  xlink:href %URI; #REQUIRED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-Images;
+  %PresentationAttributes-Viewports;
+  transform %TransformList; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  %graphicsElementEvents;
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED >
+
+<!ENTITY % switchExt "" >
+<!ELEMENT switch (%descTitleMetadata;,
+                  (path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|switch|a|foreignObject|
+                   animate|set|animateMotion|animateColor|animateTransform
+                   %ceExt;%switchExt;)*) >
+<!ATTLIST switch
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents; >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Styling 
+     ============================================================== -->
+
+<!ELEMENT style (#PCDATA) >
+<!ATTLIST style 
+  %stdAttrs;
+  xml:space (preserve) #FIXED "preserve"
+  type %ContentType; #REQUIRED
+  media %MediaDesc; #IMPLIED
+  title %Text; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Paths
+     ============================================================== -->
+
+<!ENTITY % pathExt "" >
+<!ELEMENT path (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%pathExt;)*) >
+<!ATTLIST path
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-Markers;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  d %PathData; #REQUIRED
+  pathLength %Number; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Basic Shapes
+     ============================================================== -->
+
+<!ENTITY % rectExt "" >
+<!ELEMENT rect (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%rectExt;)*) >
+<!ATTLIST rect
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  rx %Length; #IMPLIED
+  ry %Length; #IMPLIED >
+
+<!ENTITY % circleExt "" >
+<!ELEMENT circle (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%circleExt;)*) >
+<!ATTLIST circle
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  cx %Coordinate; #IMPLIED
+  cy %Coordinate; #IMPLIED
+  r %Length; #REQUIRED >
+
+<!ENTITY % ellipseExt "" >
+<!ELEMENT ellipse (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%ellipseExt;)*) >
+<!ATTLIST ellipse
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  cx %Coordinate; #IMPLIED
+  cy %Coordinate; #IMPLIED
+  rx %Length; #REQUIRED
+  ry %Length; #REQUIRED >
+
+<!ENTITY % lineExt "" >
+<!ELEMENT line (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%lineExt;)*) >
+<!ATTLIST line
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-Markers;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  x1 %Coordinate; #IMPLIED
+  y1 %Coordinate; #IMPLIED
+  x2 %Coordinate; #IMPLIED
+  y2 %Coordinate; #IMPLIED >
+
+<!ENTITY % polylineExt "" >
+<!ELEMENT polyline (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%polylineExt;)*) >
+<!ATTLIST polyline
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-Markers;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  points %Points; #REQUIRED >
+
+<!ENTITY % polygonExt "" >
+<!ELEMENT polygon (%descTitleMetadata;,(animate|set|animateMotion|animateColor|animateTransform
+                %geExt;%polygonExt;)*) >
+<!ATTLIST polygon
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-Markers;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  points %Points; #REQUIRED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Text
+     ============================================================== -->
+
+<!ENTITY % textExt "" >
+<!ELEMENT text (#PCDATA|desc|title|metadata|
+                tspan|tref|textPath|altGlyph|a|animate|set|
+                animateMotion|animateColor|animateTransform
+                %geExt;%textExt;)* >
+<!ATTLIST text
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %PresentationAttributes-TextElements;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate %Numbers; #IMPLIED
+  textLength %Length; #IMPLIED
+  lengthAdjust (spacing|spacingAndGlyphs) #IMPLIED >
+
+<!ENTITY % tspanExt "" >
+<!ELEMENT tspan (#PCDATA|desc|title|metadata|tspan|tref|altGlyph|a|animate|set|animateColor
+                %tspanExt;)* >
+<!ATTLIST tspan
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %graphicsElementEvents;
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate %Numbers; #IMPLIED
+  textLength %Length; #IMPLIED
+  lengthAdjust (spacing|spacingAndGlyphs) #IMPLIED >
+
+<!ENTITY % trefExt "" >
+<!ELEMENT tref (desc|title|metadata|animate|set|animateColor
+                %trefExt;)* >
+<!ATTLIST tref
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %graphicsElementEvents;
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate %Numbers; #IMPLIED
+  textLength %Length; #IMPLIED
+  lengthAdjust (spacing|spacingAndGlyphs) #IMPLIED >
+
+<!ENTITY % textPathExt "" >
+<!ELEMENT textPath (#PCDATA|desc|title|metadata|tspan|tref|altGlyph|a|animate|set|animateColor
+                %textPathExt;)* >
+<!ATTLIST textPath
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %langSpaceAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %graphicsElementEvents;
+  startOffset %Length; #IMPLIED
+  textLength %Length; #IMPLIED
+  lengthAdjust (spacing|spacingAndGlyphs) #IMPLIED
+  method (align|stretch) #IMPLIED
+  spacing (auto|exact) #IMPLIED >
+
+<!ENTITY % altGlyphExt "" >
+<!ELEMENT altGlyph (#PCDATA %altGlyphExt;)* >
+<!ATTLIST altGlyph
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED 
+  glyphRef CDATA #IMPLIED
+  format CDATA #IMPLIED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %graphicsElementEvents;
+  x %Coordinates; #IMPLIED
+  y %Coordinates; #IMPLIED
+  dx %Lengths; #IMPLIED
+  dy %Lengths; #IMPLIED
+  rotate %Numbers; #IMPLIED >
+
+<!ENTITY % altGlyphDefExt "" >
+<!ELEMENT altGlyphDef ((glyphRef+|altGlyphItem+) %altGlyphDefExt;) >
+<!ATTLIST altGlyphDef
+  %stdAttrs; >
+
+<!ENTITY % altGlyphItemExt "" >
+<!ELEMENT altGlyphItem (glyphRef+ %altGlyphItemExt;) >
+<!ATTLIST altGlyphItem
+  %stdAttrs; >
+
+<!ELEMENT glyphRef EMPTY >
+<!ATTLIST glyphRef
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-FontSpecification;
+  glyphRef CDATA #IMPLIED
+  format CDATA #IMPLIED
+  x %Number; #IMPLIED
+  y %Number; #IMPLIED
+  dx %Number; #IMPLIED
+  dy %Number; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Painting: Filling, Stroking and Marker Symbols 
+     ============================================================== -->
+
+<!ENTITY % markerExt "" >
+<!ELEMENT marker (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%markerExt;)* >
+<!ATTLIST marker
+  %stdAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  refX %Coordinate; #IMPLIED
+  refY %Coordinate; #IMPLIED
+  markerUnits (strokeWidth | userSpaceOnUse) #IMPLIED
+  markerWidth  %Length; #IMPLIED
+  markerHeight %Length; #IMPLIED
+  orient CDATA #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Color 
+     ============================================================== -->
+
+<!ELEMENT color-profile (%descTitleMetadata;) >
+<!ATTLIST color-profile 
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  local CDATA #IMPLIED  
+  name CDATA #REQUIRED
+  rendering-intent (auto | perceptual | relative-colorimetric | saturation | absolute-colorimetric) "auto" >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Gradients and Patterns 
+     ============================================================== -->
+
+<!ENTITY % linearGradientExt "" >
+<!ELEMENT linearGradient (%descTitleMetadata;,(stop|animate|set|animateTransform
+                   %linearGradientExt;)*) >
+<!ATTLIST linearGradient
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-Gradients;
+  gradientUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  gradientTransform %TransformList; #IMPLIED
+  x1 %Coordinate; #IMPLIED
+  y1 %Coordinate; #IMPLIED
+  x2 %Coordinate; #IMPLIED
+  y2 %Coordinate; #IMPLIED
+  spreadMethod (pad | reflect | repeat) #IMPLIED >
+
+
+<!ENTITY % radialGradientExt "" >
+<!ELEMENT radialGradient (%descTitleMetadata;,(stop|animate|set|animateTransform
+                   %radialGradientExt;)*) >
+<!ATTLIST radialGradient
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-Gradients;
+  gradientUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  gradientTransform %TransformList; #IMPLIED
+  cx %Coordinate; #IMPLIED
+  cy %Coordinate; #IMPLIED
+  r %Length; #IMPLIED
+  fx %Coordinate; #IMPLIED
+  fy %Coordinate; #IMPLIED
+  spreadMethod (pad | reflect | repeat) #IMPLIED >
+
+
+<!ENTITY % stopExt "" >
+<!ELEMENT stop (animate|set|animateColor
+                   %stopExt;)* >
+<!ATTLIST stop
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-Gradients;
+  offset %NumberOrPercentage; #REQUIRED >
+
+<!ENTITY % patternExt "" >
+<!ELEMENT pattern (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%patternExt;)* >
+<!ATTLIST pattern
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  patternUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  patternContentUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  patternTransform %TransformList; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Clipping, Masking and Compositing 
+     ============================================================== -->
+
+<!ENTITY % clipPathExt "" >
+<!ELEMENT clipPath (%descTitleMetadata;,
+                    (path|text|rect|circle|ellipse|line|polyline|polygon|
+                     use|animate|set|animateMotion|animateColor|animateTransform
+                     %ceExt;%clipPathExt;)*) >
+<!ATTLIST clipPath
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FillStroke;
+  %PresentationAttributes-FontSpecification;
+  %PresentationAttributes-Graphics;
+  %PresentationAttributes-TextContentElements;
+  %PresentationAttributes-TextElements;
+  transform %TransformList; #IMPLIED
+  clipPathUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED >
+
+<!ENTITY % maskExt "" >
+<!ELEMENT mask (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%maskExt;)*  >
+<!ATTLIST mask
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  maskUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  maskContentUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Filter Effects
+     ============================================================== -->
+
+<!ENTITY % filterExt "" >
+<!ELEMENT filter (%descTitleMetadata;,(feBlend|feFlood|
+  feColorMatrix|feComponentTransfer|
+  feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|
+  feGaussianBlur|feImage|feMerge|
+  feMorphology|feOffset|feSpecularLighting|
+  feTile|feTurbulence|
+  animate|set
+  %filterExt;)*) >
+<!ATTLIST filter
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  filterUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  primitiveUnits (userSpaceOnUse | objectBoundingBox) #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #IMPLIED
+  height %Length; #IMPLIED
+  filterRes %NumberOptionalNumber; #IMPLIED >
+
+<!ENTITY % filter_primitive_attributes
+  "x %Coordinate; #IMPLIED
+   y %Coordinate; #IMPLIED
+   width %Length; #IMPLIED
+   height %Length; #IMPLIED
+   result CDATA #IMPLIED" >
+
+<!ENTITY % filter_primitive_attributes_with_in
+  "%filter_primitive_attributes;
+   in CDATA #IMPLIED">
+
+<!ELEMENT feDistantLight (animate|set)* >
+<!ATTLIST feDistantLight
+  %stdAttrs;
+  azimuth %Number; #IMPLIED
+  elevation %Number; #IMPLIED >
+
+<!ELEMENT fePointLight (animate|set)* >
+<!ATTLIST fePointLight
+  %stdAttrs;
+  x %Number; #IMPLIED
+  y %Number; #IMPLIED
+  z %Number; #IMPLIED >
+
+<!ELEMENT feSpotLight (animate|set)* >
+<!ATTLIST feSpotLight
+  %stdAttrs;
+  x %Number; #IMPLIED
+  y %Number; #IMPLIED
+  z %Number; #IMPLIED
+  pointsAtX %Number; #IMPLIED
+  pointsAtY %Number; #IMPLIED
+  pointsAtZ %Number; #IMPLIED
+  specularExponent %Number; #IMPLIED
+  limitingConeAngle %Number; #IMPLIED >
+
+<!ELEMENT feBlend (animate|set)* >
+<!ATTLIST feBlend
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  in2 CDATA #REQUIRED
+  mode (normal | multiply | screen | darken | lighten) "normal" >
+
+<!ELEMENT feColorMatrix (animate|set)* >
+<!ATTLIST feColorMatrix
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  type (matrix | saturate | hueRotate | luminanceToAlpha) "matrix"
+  values CDATA #IMPLIED >
+
+<!ELEMENT feComponentTransfer (feFuncR?,feFuncG?,feFuncB?,feFuncA?) >
+<!ATTLIST feComponentTransfer
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in; >
+
+<!ENTITY % component_transfer_function_attributes
+  "type (identity | table | discrete | linear | gamma) #REQUIRED
+   tableValues CDATA #IMPLIED
+   slope %Number; #IMPLIED
+   intercept %Number; #IMPLIED
+   amplitude %Number; #IMPLIED
+   exponent %Number; #IMPLIED
+   offset %Number; #IMPLIED" >
+
+<!ELEMENT feFuncR (animate|set)* >
+<!ATTLIST feFuncR
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncG (animate|set)* >
+<!ATTLIST feFuncG
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncB (animate|set)* >
+<!ATTLIST feFuncB
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feFuncA (animate|set)* >
+<!ATTLIST feFuncA
+  %stdAttrs;
+  %component_transfer_function_attributes; >
+
+<!ELEMENT feComposite (animate|set)* >
+<!ATTLIST feComposite
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  in2 CDATA #REQUIRED
+  operator (over | in | out | atop | xor | arithmetic) "over"
+  k1 %Number; #IMPLIED
+  k2 %Number; #IMPLIED
+  k3 %Number; #IMPLIED
+  k4 %Number; #IMPLIED >
+
+<!ELEMENT feConvolveMatrix (animate|set)* >
+<!ATTLIST feConvolveMatrix
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  order %NumberOptionalNumber; #REQUIRED
+  kernelMatrix CDATA #REQUIRED
+  divisor %Number; #IMPLIED
+  bias %Number; #IMPLIED
+  targetX %Integer; #IMPLIED
+  targetY %Integer; #IMPLIED
+  edgeMode (duplicate|wrap|none) "duplicate" 
+  kernelUnitLength %NumberOptionalNumber; #IMPLIED 
+  preserveAlpha %Boolean; #IMPLIED >
+
+<!ELEMENT feDiffuseLighting ((feDistantLight|fePointLight|feSpotLight),(animate|set|animateColor)*) >
+<!ATTLIST feDiffuseLighting
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FilterPrimitives;
+  %PresentationAttributes-LightingEffects;
+  %filter_primitive_attributes_with_in;
+  surfaceScale %Number; #IMPLIED
+  diffuseConstant %Number; #IMPLIED 
+  kernelUnitLength %NumberOptionalNumber; #IMPLIED >
+
+<!ELEMENT feDisplacementMap (animate|set)* >
+<!ATTLIST feDisplacementMap
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  in2 CDATA #REQUIRED
+  scale %Number; #IMPLIED
+  xChannelSelector (R | G | B | A) "A"
+  yChannelSelector (R | G | B | A) "A" >
+
+<!ELEMENT feFlood (animate|set|animateColor)* >
+<!ATTLIST feFlood
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-feFlood;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in; >
+
+<!ELEMENT feGaussianBlur (animate|set)* >
+<!ATTLIST feGaussianBlur
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  stdDeviation %NumberOptionalNumber; #IMPLIED >
+
+<!ELEMENT feImage (animate|set|animateTransform)* >
+<!ATTLIST feImage
+  %stdAttrs;
+  %xlinkRefAttrsEmbed;
+  xlink:href %URI; #REQUIRED
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  %filter_primitive_attributes;
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet' >
+
+<!ELEMENT feMerge (feMergeNode)* >
+<!ATTLIST feMerge
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes; >
+
+<!ELEMENT feMergeNode (animate|set)* >
+<!ATTLIST feMergeNode
+  %stdAttrs;
+  in CDATA #IMPLIED >
+
+<!ELEMENT feMorphology (animate|set)* >
+<!ATTLIST feMorphology
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  operator (erode | dilate) "erode"
+  radius %NumberOptionalNumber; #IMPLIED >
+
+<!ELEMENT feOffset (animate|set)* >
+<!ATTLIST feOffset
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in;
+  dx %Number; #IMPLIED
+  dy %Number; #IMPLIED >
+
+<!ELEMENT feSpecularLighting ((feDistantLight|fePointLight|feSpotLight),(animate|set|animateColor)*) >
+<!ATTLIST feSpecularLighting
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-Color;
+  %PresentationAttributes-FilterPrimitives;
+  %PresentationAttributes-LightingEffects;
+  %filter_primitive_attributes_with_in;
+  surfaceScale %Number; #IMPLIED
+  specularConstant %Number; #IMPLIED
+  specularExponent %Number; #IMPLIED 
+  kernelUnitLength %NumberOptionalNumber; #IMPLIED >
+
+<!ELEMENT feTile (animate|set)* >
+<!ATTLIST feTile
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes_with_in; >
+
+<!ELEMENT feTurbulence (animate|set)* >
+<!ATTLIST feTurbulence
+  %stdAttrs;
+  %PresentationAttributes-FilterPrimitives;
+  %filter_primitive_attributes;
+  baseFrequency %NumberOptionalNumber; #IMPLIED
+  numOctaves %Integer; #IMPLIED
+  seed %Number; #IMPLIED
+  stitchTiles (stitch | noStitch) "noStitch"
+  type (fractalNoise | turbulence) "turbulence" >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Interactivity 
+     ============================================================== -->
+
+<!ELEMENT cursor (%descTitleMetadata;) >
+<!ATTLIST cursor
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Linking
+     ============================================================== -->
+
+<!ENTITY % aExt "" >
+<!ELEMENT a       (#PCDATA|desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %ceExt;%aExt;)* >
+<!ATTLIST a
+  %stdAttrs;
+  xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink"
+  xlink:type (simple) #FIXED "simple" 
+  xlink:role %URI; #IMPLIED
+  xlink:arcrole %URI; #IMPLIED
+  xlink:title CDATA #IMPLIED
+  xlink:show (new|replace) 'replace'
+  xlink:actuate (onRequest) #FIXED 'onRequest'
+  xlink:href %URI; #REQUIRED
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  target %LinkTarget; #IMPLIED >
+
+<!ENTITY % viewExt "" >
+<!ELEMENT view (%descTitleMetadata;%viewExt;) >
+<!ATTLIST view
+  %stdAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  viewBox %ViewBoxSpec; #IMPLIED
+  preserveAspectRatio %PreserveAspectRatioSpec; 'xMidYMid meet'
+  zoomAndPan (disable | magnify) 'magnify' 
+  viewTarget CDATA #IMPLIED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Scripting 
+     ============================================================== -->
+
+<!ELEMENT script (#PCDATA) >
+<!ATTLIST script
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED
+  externalResourcesRequired %Boolean; #IMPLIED
+  type %ContentType; #REQUIRED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Animation 
+     ============================================================== -->
+
+<!ENTITY % animElementAttrs
+ "%xlinkRefAttrs;
+  xlink:href %URI; #IMPLIED" >
+
+<!ENTITY % animAttributeAttrs
+ "attributeName  CDATA  #REQUIRED
+  attributeType  CDATA  #IMPLIED" >
+
+<!ENTITY % animTimingAttrs
+ "begin CDATA #IMPLIED 
+  dur CDATA #IMPLIED
+  end CDATA #IMPLIED
+  min CDATA #IMPLIED
+  max CDATA #IMPLIED
+  restart (always | never | whenNotActive) 'always'
+  repeatCount CDATA #IMPLIED 
+  repeatDur CDATA #IMPLIED
+  fill (remove | freeze) 'remove'" >
+
+<!ENTITY % animValueAttrs
+ "calcMode (discrete | linear | paced | spline) 'linear'
+  values CDATA #IMPLIED
+  keyTimes CDATA #IMPLIED
+  keySplines CDATA #IMPLIED
+  from CDATA #IMPLIED
+  to CDATA #IMPLIED
+  by CDATA #IMPLIED" >
+
+<!ENTITY % animAdditionAttrs
+ "additive       (replace | sum) 'replace'
+  accumulate     (none | sum) 'none'" >
+
+<!ENTITY % animateExt "" >
+<!ELEMENT animate (%descTitleMetadata;%animateExt;) >
+<!ATTLIST animate
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animationEvents;
+  %animElementAttrs;
+  %animAttributeAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs; >
+
+<!ENTITY % setExt "" >
+<!ELEMENT set (%descTitleMetadata;%setExt;) >
+<!ATTLIST set
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animationEvents;
+  %animElementAttrs;
+  %animAttributeAttrs;
+  %animTimingAttrs;
+  to CDATA #IMPLIED >
+
+<!ENTITY % animateMotionExt "" >
+<!ELEMENT animateMotion (%descTitleMetadata;,mpath? %animateMotionExt;) >
+<!ATTLIST animateMotion
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animationEvents;
+  %animElementAttrs;
+  %animTimingAttrs;
+  calcMode (discrete | linear | paced | spline) 'paced'
+  values CDATA #IMPLIED
+  keyTimes CDATA #IMPLIED
+  keySplines CDATA #IMPLIED
+  from CDATA #IMPLIED
+  to CDATA #IMPLIED
+  by CDATA #IMPLIED
+  %animAdditionAttrs;
+  path CDATA #IMPLIED
+  keyPoints CDATA #IMPLIED
+  rotate CDATA #IMPLIED
+  origin CDATA #IMPLIED >
+
+<!ENTITY % mpathExt "" >
+<!ELEMENT mpath (%descTitleMetadata;%mpathExt;) >
+<!ATTLIST mpath
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED
+  externalResourcesRequired %Boolean; #IMPLIED >
+
+<!ENTITY % animateColorExt "" >
+<!ELEMENT animateColor (%descTitleMetadata;%animateColorExt;) >
+<!ATTLIST animateColor
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animationEvents;
+  %animElementAttrs;
+  %animAttributeAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs; >
+
+<!ENTITY % animateTransformExt "" >
+<!ELEMENT animateTransform (%descTitleMetadata;%animateTransformExt;) >
+<!ATTLIST animateTransform
+  %stdAttrs;
+  %testAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  %animationEvents;
+  %animElementAttrs;
+  %animAttributeAttrs;
+  %animTimingAttrs;
+  %animValueAttrs;
+  %animAdditionAttrs;
+  type (translate | scale | rotate | skewX | skewY) "translate" >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Fonts 
+     ============================================================== -->
+
+<!ENTITY % fontExt "" >
+<!ELEMENT font (%descTitleMetadata;,font-face,
+                   missing-glyph,(glyph|hkern|vkern %fontExt;)*) >
+<!ATTLIST font
+  %stdAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  horiz-origin-x %Number; #IMPLIED
+  horiz-origin-y %Number; #IMPLIED
+  horiz-adv-x %Number; #REQUIRED
+  vert-origin-x %Number; #IMPLIED
+  vert-origin-y %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED >
+
+<!ENTITY % glyphExt "" >
+<!ELEMENT glyph (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %glyphExt;)* >
+<!ATTLIST glyph
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  unicode CDATA #IMPLIED
+  glyph-name CDATA #IMPLIED
+  d %PathData; #IMPLIED
+  orientation CDATA #IMPLIED
+  arabic-form CDATA #IMPLIED
+  lang %LanguageCodes; #IMPLIED
+  horiz-adv-x %Number; #IMPLIED
+  vert-origin-x %Number; #IMPLIED
+  vert-origin-y %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED >
+
+<!ENTITY % missing-glyphExt "" >
+<!ELEMENT missing-glyph (desc|title|metadata|defs|
+                   path|text|rect|circle|ellipse|line|polyline|polygon|
+                   use|image|svg|g|view|switch|a|altGlyphDef|
+                   script|style|symbol|marker|clipPath|mask|
+                   linearGradient|radialGradient|pattern|filter|cursor|font|
+                   animate|set|animateMotion|animateColor|animateTransform|
+                   color-profile|font-face
+                   %missing-glyphExt;)* >
+<!ATTLIST missing-glyph
+  %stdAttrs;
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  d %PathData; #IMPLIED
+  horiz-adv-x %Number; #IMPLIED
+  vert-origin-x %Number; #IMPLIED
+  vert-origin-y %Number; #IMPLIED
+  vert-adv-y %Number; #IMPLIED >
+
+<!ELEMENT hkern EMPTY >
+<!ATTLIST hkern
+  %stdAttrs;
+  u1 CDATA #IMPLIED
+  g1 CDATA #IMPLIED
+  u2 CDATA #IMPLIED
+  g2 CDATA #IMPLIED
+  k %Number; #REQUIRED >
+
+<!ELEMENT vkern EMPTY >
+<!ATTLIST vkern
+  %stdAttrs;
+  u1 CDATA #IMPLIED
+  g1 CDATA #IMPLIED
+  u2 CDATA #IMPLIED
+  g2 CDATA #IMPLIED
+  k %Number; #REQUIRED >
+
+<!ELEMENT font-face (%descTitleMetadata;,font-face-src?,definition-src?) >
+<!ATTLIST font-face 
+  %stdAttrs;
+  font-family CDATA #IMPLIED
+  font-style CDATA #IMPLIED
+  font-variant CDATA #IMPLIED
+  font-weight CDATA #IMPLIED
+  font-stretch CDATA #IMPLIED
+  font-size CDATA #IMPLIED
+  unicode-range CDATA #IMPLIED
+  units-per-em %Number; #IMPLIED
+  panose-1 CDATA #IMPLIED
+  stemv %Number; #IMPLIED
+  stemh %Number; #IMPLIED
+  slope %Number; #IMPLIED
+  cap-height %Number; #IMPLIED
+  x-height %Number; #IMPLIED
+  accent-height %Number; #IMPLIED
+  ascent %Number; #IMPLIED
+  descent %Number; #IMPLIED
+  widths CDATA #IMPLIED
+  bbox CDATA #IMPLIED
+  ideographic %Number; #IMPLIED
+  alphabetic %Number; #IMPLIED
+  mathematical %Number; #IMPLIED
+  hanging %Number; #IMPLIED
+  v-ideographic %Number; #IMPLIED
+  v-alphabetic %Number; #IMPLIED
+  v-mathematical %Number; #IMPLIED
+  v-hanging %Number; #IMPLIED
+  underline-position %Number; #IMPLIED
+  underline-thickness %Number; #IMPLIED
+  strikethrough-position %Number; #IMPLIED
+  strikethrough-thickness %Number; #IMPLIED
+  overline-position %Number; #IMPLIED
+  overline-thickness %Number; #IMPLIED >
+
+<!ELEMENT font-face-src (font-face-uri|font-face-name)+ >
+<!ATTLIST font-face-src 
+  %stdAttrs; >
+
+<!ELEMENT font-face-uri (font-face-format*) >
+<!ATTLIST font-face-uri 
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED >
+
+<!ELEMENT font-face-format EMPTY >
+<!ATTLIST font-face-format 
+  %stdAttrs;
+  string CDATA #IMPLIED >
+
+<!ELEMENT font-face-name EMPTY >
+<!ATTLIST font-face-name 
+  %stdAttrs;
+  name CDATA #IMPLIED >
+
+<!ELEMENT definition-src EMPTY >
+<!ATTLIST definition-src 
+  %stdAttrs;
+  %xlinkRefAttrs;
+  xlink:href %URI; #REQUIRED >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Metadata 
+     ============================================================== -->
+
+<!ENTITY % metadataExt "" >
+<!ELEMENT metadata (#PCDATA %metadataExt;)* >
+<!ATTLIST metadata
+  %stdAttrs; >
+
+
+<!-- ==============================================================
+     DECLARATIONS CORRESPONDING TO: Extensibility 
+     ============================================================== -->
+
+<!ENTITY % foreignObjectExt "" >
+<!ELEMENT foreignObject (#PCDATA %ceExt;%foreignObjectExt;)* >
+<!ATTLIST foreignObject
+  %stdAttrs;
+  %testAttrs;
+  %langSpaceAttrs;
+  externalResourcesRequired %Boolean; #IMPLIED
+  class %ClassList; #IMPLIED
+  style %StyleSheet; #IMPLIED
+  %PresentationAttributes-All;
+  transform %TransformList; #IMPLIED
+  %graphicsElementEvents;
+  x %Coordinate; #IMPLIED
+  y %Coordinate; #IMPLIED
+  width %Length; #REQUIRED
+  height %Length; #REQUIRED
+  %StructuredText; >
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-lat1.ent b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-lat1.ent
new file mode 100644
index 0000000..ffee223
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-lat1.ent
@@ -0,0 +1,196 @@
+<!-- Portions (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+    <!ENTITY % HTMLlat1 PUBLIC
+       "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
+    %HTMLlat1;
+-->
+
+<!ENTITY nbsp   "&#160;"> <!-- no-break space = non-breaking space,
+                                  U+00A0 ISOnum -->
+<!ENTITY iexcl  "&#161;"> <!-- inverted exclamation mark, U+00A1 ISOnum -->
+<!ENTITY cent   "&#162;"> <!-- cent sign, U+00A2 ISOnum -->
+<!ENTITY pound  "&#163;"> <!-- pound sign, U+00A3 ISOnum -->
+<!ENTITY curren "&#164;"> <!-- currency sign, U+00A4 ISOnum -->
+<!ENTITY yen    "&#165;"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->
+<!ENTITY brvbar "&#166;"> <!-- broken bar = broken vertical bar,
+                                  U+00A6 ISOnum -->
+<!ENTITY sect   "&#167;"> <!-- section sign, U+00A7 ISOnum -->
+<!ENTITY uml    "&#168;"> <!-- diaeresis = spacing diaeresis,
+                                  U+00A8 ISOdia -->
+<!ENTITY copy   "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
+<!ENTITY ordf   "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
+<!ENTITY laquo  "&#171;"> <!-- left-pointing double angle quotation mark
+                                  = left pointing guillemet, U+00AB ISOnum -->
+<!ENTITY not    "&#172;"> <!-- not sign = angled dash,
+                                  U+00AC ISOnum -->
+<!ENTITY shy    "&#173;"> <!-- soft hyphen = discretionary hyphen,
+                                  U+00AD ISOnum -->
+<!ENTITY reg    "&#174;"> <!-- registered sign = registered trade mark sign,
+                                  U+00AE ISOnum -->
+<!ENTITY macr   "&#175;"> <!-- macron = spacing macron = overline
+                                  = APL overbar, U+00AF ISOdia -->
+<!ENTITY deg    "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
+<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
+                                  U+00B1 ISOnum -->
+<!ENTITY sup2   "&#178;"> <!-- superscript two = superscript digit two
+                                  = squared, U+00B2 ISOnum -->
+<!ENTITY sup3   "&#179;"> <!-- superscript three = superscript digit three
+                                  = cubed, U+00B3 ISOnum -->
+<!ENTITY acute  "&#180;"> <!-- acute accent = spacing acute,
+                                  U+00B4 ISOdia -->
+<!ENTITY micro  "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
+<!ENTITY para   "&#182;"> <!-- pilcrow sign = paragraph sign,
+                                  U+00B6 ISOnum -->
+<!ENTITY middot "&#183;"> <!-- middle dot = Georgian comma
+                                  = Greek middle dot, U+00B7 ISOnum -->
+<!ENTITY cedil  "&#184;"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->
+<!ENTITY sup1   "&#185;"> <!-- superscript one = superscript digit one,
+                                  U+00B9 ISOnum -->
+<!ENTITY ordm   "&#186;"> <!-- masculine ordinal indicator,
+                                  U+00BA ISOnum -->
+<!ENTITY raquo  "&#187;"> <!-- right-pointing double angle quotation mark
+                                  = right pointing guillemet, U+00BB ISOnum -->
+<!ENTITY frac14 "&#188;"> <!-- vulgar fraction one quarter
+                                  = fraction one quarter, U+00BC ISOnum -->
+<!ENTITY frac12 "&#189;"> <!-- vulgar fraction one half
+                                  = fraction one half, U+00BD ISOnum -->
+<!ENTITY frac34 "&#190;"> <!-- vulgar fraction three quarters
+                                  = fraction three quarters, U+00BE ISOnum -->
+<!ENTITY iquest "&#191;"> <!-- inverted question mark
+                                  = turned question mark, U+00BF ISOnum -->
+<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
+                                  = latin capital letter A grave,
+                                  U+00C0 ISOlat1 -->
+<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
+                                  U+00C1 ISOlat1 -->
+<!ENTITY Acirc  "&#194;"> <!-- latin capital letter A with circumflex,
+                                  U+00C2 ISOlat1 -->
+<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
+                                  U+00C3 ISOlat1 -->
+<!ENTITY Auml   "&#196;"> <!-- latin capital letter A with diaeresis,
+                                  U+00C4 ISOlat1 -->
+<!ENTITY Aring  "&#197;"> <!-- latin capital letter A with ring above
+                                  = latin capital letter A ring,
+                                  U+00C5 ISOlat1 -->
+<!ENTITY AElig  "&#198;"> <!-- latin capital letter AE
+                                  = latin capital ligature AE,
+                                  U+00C6 ISOlat1 -->
+<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
+                                  U+00C7 ISOlat1 -->
+<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
+                                  U+00C8 ISOlat1 -->
+<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
+                                  U+00C9 ISOlat1 -->
+<!ENTITY Ecirc  "&#202;"> <!-- latin capital letter E with circumflex,
+                                  U+00CA ISOlat1 -->
+<!ENTITY Euml   "&#203;"> <!-- latin capital letter E with diaeresis,
+                                  U+00CB ISOlat1 -->
+<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
+                                  U+00CC ISOlat1 -->
+<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
+                                  U+00CD ISOlat1 -->
+<!ENTITY Icirc  "&#206;"> <!-- latin capital letter I with circumflex,
+                                  U+00CE ISOlat1 -->
+<!ENTITY Iuml   "&#207;"> <!-- latin capital letter I with diaeresis,
+                                  U+00CF ISOlat1 -->
+<!ENTITY ETH    "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
+<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
+                                  U+00D1 ISOlat1 -->
+<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
+                                  U+00D2 ISOlat1 -->
+<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
+                                  U+00D3 ISOlat1 -->
+<!ENTITY Ocirc  "&#212;"> <!-- latin capital letter O with circumflex,
+                                  U+00D4 ISOlat1 -->
+<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
+                                  U+00D5 ISOlat1 -->
+<!ENTITY Ouml   "&#214;"> <!-- latin capital letter O with diaeresis,
+                                  U+00D6 ISOlat1 -->
+<!ENTITY times  "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
+<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
+                                  = latin capital letter O slash,
+                                  U+00D8 ISOlat1 -->
+<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
+                                  U+00D9 ISOlat1 -->
+<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
+                                  U+00DA ISOlat1 -->
+<!ENTITY Ucirc  "&#219;"> <!-- latin capital letter U with circumflex,
+                                  U+00DB ISOlat1 -->
+<!ENTITY Uuml   "&#220;"> <!-- latin capital letter U with diaeresis,
+                                  U+00DC ISOlat1 -->
+<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
+                                  U+00DD ISOlat1 -->
+<!ENTITY THORN  "&#222;"> <!-- latin capital letter THORN,
+                                  U+00DE ISOlat1 -->
+<!ENTITY szlig  "&#223;"> <!-- latin small letter sharp s = ess-zed,
+                                  U+00DF ISOlat1 -->
+<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
+                                  = latin small letter a grave,
+                                  U+00E0 ISOlat1 -->
+<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
+                                  U+00E1 ISOlat1 -->
+<!ENTITY acirc  "&#226;"> <!-- latin small letter a with circumflex,
+                                  U+00E2 ISOlat1 -->
+<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
+                                  U+00E3 ISOlat1 -->
+<!ENTITY auml   "&#228;"> <!-- latin small letter a with diaeresis,
+                                  U+00E4 ISOlat1 -->
+<!ENTITY aring  "&#229;"> <!-- latin small letter a with ring above
+                                  = latin small letter a ring,
+                                  U+00E5 ISOlat1 -->
+<!ENTITY aelig  "&#230;"> <!-- latin small letter ae
+                                  = latin small ligature ae, U+00E6 ISOlat1 -->
+<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
+                                  U+00E7 ISOlat1 -->
+<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
+                                  U+00E8 ISOlat1 -->
+<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
+                                  U+00E9 ISOlat1 -->
+<!ENTITY ecirc  "&#234;"> <!-- latin small letter e with circumflex,
+                                  U+00EA ISOlat1 -->
+<!ENTITY euml   "&#235;"> <!-- latin small letter e with diaeresis,
+                                  U+00EB ISOlat1 -->
+<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
+                                  U+00EC ISOlat1 -->
+<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
+                                  U+00ED ISOlat1 -->
+<!ENTITY icirc  "&#238;"> <!-- latin small letter i with circumflex,
+                                  U+00EE ISOlat1 -->
+<!ENTITY iuml   "&#239;"> <!-- latin small letter i with diaeresis,
+                                  U+00EF ISOlat1 -->
+<!ENTITY eth    "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
+<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
+                                  U+00F1 ISOlat1 -->
+<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
+                                  U+00F2 ISOlat1 -->
+<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
+                                  U+00F3 ISOlat1 -->
+<!ENTITY ocirc  "&#244;"> <!-- latin small letter o with circumflex,
+                                  U+00F4 ISOlat1 -->
+<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
+                                  U+00F5 ISOlat1 -->
+<!ENTITY ouml   "&#246;"> <!-- latin small letter o with diaeresis,
+                                  U+00F6 ISOlat1 -->
+<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
+<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
+                                  = latin small letter o slash,
+                                  U+00F8 ISOlat1 -->
+<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
+                                  U+00F9 ISOlat1 -->
+<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
+                                  U+00FA ISOlat1 -->
+<!ENTITY ucirc  "&#251;"> <!-- latin small letter u with circumflex,
+                                  U+00FB ISOlat1 -->
+<!ENTITY uuml   "&#252;"> <!-- latin small letter u with diaeresis,
+                                  U+00FC ISOlat1 -->
+<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
+                                  U+00FD ISOlat1 -->
+<!ENTITY thorn  "&#254;"> <!-- latin small letter thorn,
+                                  U+00FE ISOlat1 -->
+<!ENTITY yuml   "&#255;"> <!-- latin small letter y with diaeresis,
+                                  U+00FF ISOlat1 -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-special.ent b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-special.ent
new file mode 100644
index 0000000..ca358b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-special.ent
@@ -0,0 +1,80 @@
+<!-- Special characters for XHTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLspecial PUBLIC
+        "-//W3C//ENTITIES Special for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
+     %HTMLspecial;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- C0 Controls and Basic Latin -->
+<!ENTITY quot    "&#34;"> <!--  quotation mark, U+0022 ISOnum -->
+<!ENTITY amp     "&#38;#38;"> <!--  ampersand, U+0026 ISOnum -->
+<!ENTITY lt      "&#38;#60;"> <!--  less-than sign, U+003C ISOnum -->
+<!ENTITY gt      "&#62;"> <!--  greater-than sign, U+003E ISOnum -->
+<!ENTITY apos	 "&#39;"> <!--  apostrophe = APL quote, U+0027 ISOnum -->
+
+<!-- Latin Extended-A -->
+<!ENTITY OElig   "&#338;"> <!--  latin capital ligature OE,
+                                    U+0152 ISOlat2 -->
+<!ENTITY oelig   "&#339;"> <!--  latin small ligature oe, U+0153 ISOlat2 -->
+<!-- ligature is a misnomer, this is a separate character in some languages -->
+<!ENTITY Scaron  "&#352;"> <!--  latin capital letter S with caron,
+                                    U+0160 ISOlat2 -->
+<!ENTITY scaron  "&#353;"> <!--  latin small letter s with caron,
+                                    U+0161 ISOlat2 -->
+<!ENTITY Yuml    "&#376;"> <!--  latin capital letter Y with diaeresis,
+                                    U+0178 ISOlat2 -->
+
+<!-- Spacing Modifier Letters -->
+<!ENTITY circ    "&#710;"> <!--  modifier letter circumflex accent,
+                                    U+02C6 ISOpub -->
+<!ENTITY tilde   "&#732;"> <!--  small tilde, U+02DC ISOdia -->
+
+<!-- General Punctuation -->
+<!ENTITY ensp    "&#8194;"> <!-- en space, U+2002 ISOpub -->
+<!ENTITY emsp    "&#8195;"> <!-- em space, U+2003 ISOpub -->
+<!ENTITY thinsp  "&#8201;"> <!-- thin space, U+2009 ISOpub -->
+<!ENTITY zwnj    "&#8204;"> <!-- zero width non-joiner,
+                                    U+200C NEW RFC 2070 -->
+<!ENTITY zwj     "&#8205;"> <!-- zero width joiner, U+200D NEW RFC 2070 -->
+<!ENTITY lrm     "&#8206;"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->
+<!ENTITY rlm     "&#8207;"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->
+<!ENTITY ndash   "&#8211;"> <!-- en dash, U+2013 ISOpub -->
+<!ENTITY mdash   "&#8212;"> <!-- em dash, U+2014 ISOpub -->
+<!ENTITY lsquo   "&#8216;"> <!-- left single quotation mark,
+                                    U+2018 ISOnum -->
+<!ENTITY rsquo   "&#8217;"> <!-- right single quotation mark,
+                                    U+2019 ISOnum -->
+<!ENTITY sbquo   "&#8218;"> <!-- single low-9 quotation mark, U+201A NEW -->
+<!ENTITY ldquo   "&#8220;"> <!-- left double quotation mark,
+                                    U+201C ISOnum -->
+<!ENTITY rdquo   "&#8221;"> <!-- right double quotation mark,
+                                    U+201D ISOnum -->
+<!ENTITY bdquo   "&#8222;"> <!-- double low-9 quotation mark, U+201E NEW -->
+<!ENTITY dagger  "&#8224;"> <!-- dagger, U+2020 ISOpub -->
+<!ENTITY Dagger  "&#8225;"> <!-- double dagger, U+2021 ISOpub -->
+<!ENTITY permil  "&#8240;"> <!-- per mille sign, U+2030 ISOtech -->
+<!ENTITY lsaquo  "&#8249;"> <!-- single left-pointing angle quotation mark,
+                                    U+2039 ISO proposed -->
+<!-- lsaquo is proposed but not yet ISO standardized -->
+<!ENTITY rsaquo  "&#8250;"> <!-- single right-pointing angle quotation mark,
+                                    U+203A ISO proposed -->
+<!-- rsaquo is proposed but not yet ISO standardized -->
+
+<!-- Currency Symbols -->
+<!ENTITY euro   "&#8364;"> <!--  euro sign, U+20AC NEW -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-symbol.ent b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-symbol.ent
new file mode 100644
index 0000000..63c2abf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml-symbol.ent
@@ -0,0 +1,237 @@
+<!-- Mathematical, Greek and Symbolic characters for XHTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLsymbol PUBLIC
+        "-//W3C//ENTITIES Symbols for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
+     %HTMLsymbol;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- Latin Extended-B -->
+<!ENTITY fnof     "&#402;"> <!-- latin small letter f with hook = function
+                                    = florin, U+0192 ISOtech -->
+
+<!-- Greek -->
+<!ENTITY Alpha    "&#913;"> <!-- greek capital letter alpha, U+0391 -->
+<!ENTITY Beta     "&#914;"> <!-- greek capital letter beta, U+0392 -->
+<!ENTITY Gamma    "&#915;"> <!-- greek capital letter gamma,
+                                    U+0393 ISOgrk3 -->
+<!ENTITY Delta    "&#916;"> <!-- greek capital letter delta,
+                                    U+0394 ISOgrk3 -->
+<!ENTITY Epsilon  "&#917;"> <!-- greek capital letter epsilon, U+0395 -->
+<!ENTITY Zeta     "&#918;"> <!-- greek capital letter zeta, U+0396 -->
+<!ENTITY Eta      "&#919;"> <!-- greek capital letter eta, U+0397 -->
+<!ENTITY Theta    "&#920;"> <!-- greek capital letter theta,
+                                    U+0398 ISOgrk3 -->
+<!ENTITY Iota     "&#921;"> <!-- greek capital letter iota, U+0399 -->
+<!ENTITY Kappa    "&#922;"> <!-- greek capital letter kappa, U+039A -->
+<!ENTITY Lambda   "&#923;"> <!-- greek capital letter lamda,
+                                    U+039B ISOgrk3 -->
+<!ENTITY Mu       "&#924;"> <!-- greek capital letter mu, U+039C -->
+<!ENTITY Nu       "&#925;"> <!-- greek capital letter nu, U+039D -->
+<!ENTITY Xi       "&#926;"> <!-- greek capital letter xi, U+039E ISOgrk3 -->
+<!ENTITY Omicron  "&#927;"> <!-- greek capital letter omicron, U+039F -->
+<!ENTITY Pi       "&#928;"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->
+<!ENTITY Rho      "&#929;"> <!-- greek capital letter rho, U+03A1 -->
+<!-- there is no Sigmaf, and no U+03A2 character either -->
+<!ENTITY Sigma    "&#931;"> <!-- greek capital letter sigma,
+                                    U+03A3 ISOgrk3 -->
+<!ENTITY Tau      "&#932;"> <!-- greek capital letter tau, U+03A4 -->
+<!ENTITY Upsilon  "&#933;"> <!-- greek capital letter upsilon,
+                                    U+03A5 ISOgrk3 -->
+<!ENTITY Phi      "&#934;"> <!-- greek capital letter phi,
+                                    U+03A6 ISOgrk3 -->
+<!ENTITY Chi      "&#935;"> <!-- greek capital letter chi, U+03A7 -->
+<!ENTITY Psi      "&#936;"> <!-- greek capital letter psi,
+                                    U+03A8 ISOgrk3 -->
+<!ENTITY Omega    "&#937;"> <!-- greek capital letter omega,
+                                    U+03A9 ISOgrk3 -->
+
+<!ENTITY alpha    "&#945;"> <!-- greek small letter alpha,
+                                    U+03B1 ISOgrk3 -->
+<!ENTITY beta     "&#946;"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->
+<!ENTITY gamma    "&#947;"> <!-- greek small letter gamma,
+                                    U+03B3 ISOgrk3 -->
+<!ENTITY delta    "&#948;"> <!-- greek small letter delta,
+                                    U+03B4 ISOgrk3 -->
+<!ENTITY epsilon  "&#949;"> <!-- greek small letter epsilon,
+                                    U+03B5 ISOgrk3 -->
+<!ENTITY zeta     "&#950;"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->
+<!ENTITY eta      "&#951;"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->
+<!ENTITY theta    "&#952;"> <!-- greek small letter theta,
+                                    U+03B8 ISOgrk3 -->
+<!ENTITY iota     "&#953;"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->
+<!ENTITY kappa    "&#954;"> <!-- greek small letter kappa,
+                                    U+03BA ISOgrk3 -->
+<!ENTITY lambda   "&#955;"> <!-- greek small letter lamda,
+                                    U+03BB ISOgrk3 -->
+<!ENTITY mu       "&#956;"> <!-- greek small letter mu, U+03BC ISOgrk3 -->
+<!ENTITY nu       "&#957;"> <!-- greek small letter nu, U+03BD ISOgrk3 -->
+<!ENTITY xi       "&#958;"> <!-- greek small letter xi, U+03BE ISOgrk3 -->
+<!ENTITY omicron  "&#959;"> <!-- greek small letter omicron, U+03BF NEW -->
+<!ENTITY pi       "&#960;"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->
+<!ENTITY rho      "&#961;"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->
+<!ENTITY sigmaf   "&#962;"> <!-- greek small letter final sigma,
+                                    U+03C2 ISOgrk3 -->
+<!ENTITY sigma    "&#963;"> <!-- greek small letter sigma,
+                                    U+03C3 ISOgrk3 -->
+<!ENTITY tau      "&#964;"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->
+<!ENTITY upsilon  "&#965;"> <!-- greek small letter upsilon,
+                                    U+03C5 ISOgrk3 -->
+<!ENTITY phi      "&#966;"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->
+<!ENTITY chi      "&#967;"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->
+<!ENTITY psi      "&#968;"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->
+<!ENTITY omega    "&#969;"> <!-- greek small letter omega,
+                                    U+03C9 ISOgrk3 -->
+<!ENTITY thetasym "&#977;"> <!-- greek theta symbol,
+                                    U+03D1 NEW -->
+<!ENTITY upsih    "&#978;"> <!-- greek upsilon with hook symbol,
+                                    U+03D2 NEW -->
+<!ENTITY piv      "&#982;"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->
+
+<!-- General Punctuation -->
+<!ENTITY bull     "&#8226;"> <!-- bullet = black small circle,
+                                     U+2022 ISOpub  -->
+<!-- bullet is NOT the same as bullet operator, U+2219 -->
+<!ENTITY hellip   "&#8230;"> <!-- horizontal ellipsis = three dot leader,
+                                     U+2026 ISOpub  -->
+<!ENTITY prime    "&#8242;"> <!-- prime = minutes = feet, U+2032 ISOtech -->
+<!ENTITY Prime    "&#8243;"> <!-- double prime = seconds = inches,
+                                     U+2033 ISOtech -->
+<!ENTITY oline    "&#8254;"> <!-- overline = spacing overscore,
+                                     U+203E NEW -->
+<!ENTITY frasl    "&#8260;"> <!-- fraction slash, U+2044 NEW -->
+
+<!-- Letterlike Symbols -->
+<!ENTITY weierp   "&#8472;"> <!-- script capital P = power set
+                                     = Weierstrass p, U+2118 ISOamso -->
+<!ENTITY image    "&#8465;"> <!-- black-letter capital I = imaginary part,
+                                     U+2111 ISOamso -->
+<!ENTITY real     "&#8476;"> <!-- black-letter capital R = real part symbol,
+                                     U+211C ISOamso -->
+<!ENTITY trade    "&#8482;"> <!-- trade mark sign, U+2122 ISOnum -->
+<!ENTITY alefsym  "&#8501;"> <!-- alef symbol = first transfinite cardinal,
+                                     U+2135 NEW -->
+<!-- alef symbol is NOT the same as hebrew letter alef,
+     U+05D0 although the same glyph could be used to depict both characters -->
+
+<!-- Arrows -->
+<!ENTITY larr     "&#8592;"> <!-- leftwards arrow, U+2190 ISOnum -->
+<!ENTITY uarr     "&#8593;"> <!-- upwards arrow, U+2191 ISOnum-->
+<!ENTITY rarr     "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
+<!ENTITY darr     "&#8595;"> <!-- downwards arrow, U+2193 ISOnum -->
+<!ENTITY harr     "&#8596;"> <!-- left right arrow, U+2194 ISOamsa -->
+<!ENTITY crarr    "&#8629;"> <!-- downwards arrow with corner leftwards
+                                     = carriage return, U+21B5 NEW -->
+<!ENTITY lArr     "&#8656;"> <!-- leftwards double arrow, U+21D0 ISOtech -->
+<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow
+    but also does not have any other character for that function. So lArr can
+    be used for 'is implied by' as ISOtech suggests -->
+<!ENTITY uArr     "&#8657;"> <!-- upwards double arrow, U+21D1 ISOamsa -->
+<!ENTITY rArr     "&#8658;"> <!-- rightwards double arrow,
+                                     U+21D2 ISOtech -->
+<!-- Unicode does not say this is the 'implies' character but does not have 
+     another character with this function so rArr can be used for 'implies'
+     as ISOtech suggests -->
+<!ENTITY dArr     "&#8659;"> <!-- downwards double arrow, U+21D3 ISOamsa -->
+<!ENTITY hArr     "&#8660;"> <!-- left right double arrow,
+                                     U+21D4 ISOamsa -->
+
+<!-- Mathematical Operators -->
+<!ENTITY forall   "&#8704;"> <!-- for all, U+2200 ISOtech -->
+<!ENTITY part     "&#8706;"> <!-- partial differential, U+2202 ISOtech  -->
+<!ENTITY exist    "&#8707;"> <!-- there exists, U+2203 ISOtech -->
+<!ENTITY empty    "&#8709;"> <!-- empty set = null set, U+2205 ISOamso -->
+<!ENTITY nabla    "&#8711;"> <!-- nabla = backward difference,
+                                     U+2207 ISOtech -->
+<!ENTITY isin     "&#8712;"> <!-- element of, U+2208 ISOtech -->
+<!ENTITY notin    "&#8713;"> <!-- not an element of, U+2209 ISOtech -->
+<!ENTITY ni       "&#8715;"> <!-- contains as member, U+220B ISOtech -->
+<!ENTITY prod     "&#8719;"> <!-- n-ary product = product sign,
+                                     U+220F ISOamsb -->
+<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
+     the same glyph might be used for both -->
+<!ENTITY sum      "&#8721;"> <!-- n-ary summation, U+2211 ISOamsb -->
+<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
+     though the same glyph might be used for both -->
+<!ENTITY minus    "&#8722;"> <!-- minus sign, U+2212 ISOtech -->
+<!ENTITY lowast   "&#8727;"> <!-- asterisk operator, U+2217 ISOtech -->
+<!ENTITY radic    "&#8730;"> <!-- square root = radical sign,
+                                     U+221A ISOtech -->
+<!ENTITY prop     "&#8733;"> <!-- proportional to, U+221D ISOtech -->
+<!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->
+<!ENTITY ang      "&#8736;"> <!-- angle, U+2220 ISOamso -->
+<!ENTITY and      "&#8743;"> <!-- logical and = wedge, U+2227 ISOtech -->
+<!ENTITY or       "&#8744;"> <!-- logical or = vee, U+2228 ISOtech -->
+<!ENTITY cap      "&#8745;"> <!-- intersection = cap, U+2229 ISOtech -->
+<!ENTITY cup      "&#8746;"> <!-- union = cup, U+222A ISOtech -->
+<!ENTITY int      "&#8747;"> <!-- integral, U+222B ISOtech -->
+<!ENTITY there4   "&#8756;"> <!-- therefore, U+2234 ISOtech -->
+<!ENTITY sim      "&#8764;"> <!-- tilde operator = varies with = similar to,
+                                     U+223C ISOtech -->
+<!-- tilde operator is NOT the same character as the tilde, U+007E,
+     although the same glyph might be used to represent both  -->
+<!ENTITY cong     "&#8773;"> <!-- approximately equal to, U+2245 ISOtech -->
+<!ENTITY asymp    "&#8776;"> <!-- almost equal to = asymptotic to,
+                                     U+2248 ISOamsr -->
+<!ENTITY ne       "&#8800;"> <!-- not equal to, U+2260 ISOtech -->
+<!ENTITY equiv    "&#8801;"> <!-- identical to, U+2261 ISOtech -->
+<!ENTITY le       "&#8804;"> <!-- less-than or equal to, U+2264 ISOtech -->
+<!ENTITY ge       "&#8805;"> <!-- greater-than or equal to,
+                                     U+2265 ISOtech -->
+<!ENTITY sub      "&#8834;"> <!-- subset of, U+2282 ISOtech -->
+<!ENTITY sup      "&#8835;"> <!-- superset of, U+2283 ISOtech -->
+<!ENTITY nsub     "&#8836;"> <!-- not a subset of, U+2284 ISOamsn -->
+<!ENTITY sube     "&#8838;"> <!-- subset of or equal to, U+2286 ISOtech -->
+<!ENTITY supe     "&#8839;"> <!-- superset of or equal to,
+                                     U+2287 ISOtech -->
+<!ENTITY oplus    "&#8853;"> <!-- circled plus = direct sum,
+                                     U+2295 ISOamsb -->
+<!ENTITY otimes   "&#8855;"> <!-- circled times = vector product,
+                                     U+2297 ISOamsb -->
+<!ENTITY perp     "&#8869;"> <!-- up tack = orthogonal to = perpendicular,
+                                     U+22A5 ISOtech -->
+<!ENTITY sdot     "&#8901;"> <!-- dot operator, U+22C5 ISOamsb -->
+<!-- dot operator is NOT the same character as U+00B7 middle dot -->
+
+<!-- Miscellaneous Technical -->
+<!ENTITY lceil    "&#8968;"> <!-- left ceiling = APL upstile,
+                                     U+2308 ISOamsc  -->
+<!ENTITY rceil    "&#8969;"> <!-- right ceiling, U+2309 ISOamsc  -->
+<!ENTITY lfloor   "&#8970;"> <!-- left floor = APL downstile,
+                                     U+230A ISOamsc  -->
+<!ENTITY rfloor   "&#8971;"> <!-- right floor, U+230B ISOamsc  -->
+<!ENTITY lang     "&#9001;"> <!-- left-pointing angle bracket = bra,
+                                     U+2329 ISOtech -->
+<!-- lang is NOT the same character as U+003C 'less than sign' 
+     or U+2039 'single left-pointing angle quotation mark' -->
+<!ENTITY rang     "&#9002;"> <!-- right-pointing angle bracket = ket,
+                                     U+232A ISOtech -->
+<!-- rang is NOT the same character as U+003E 'greater than sign' 
+     or U+203A 'single right-pointing angle quotation mark' -->
+
+<!-- Geometric Shapes -->
+<!ENTITY loz      "&#9674;"> <!-- lozenge, U+25CA ISOpub -->
+
+<!-- Miscellaneous Symbols -->
+<!ENTITY spades   "&#9824;"> <!-- black spade suit, U+2660 ISOpub -->
+<!-- black here seems to mean filled as opposed to hollow -->
+<!ENTITY clubs    "&#9827;"> <!-- black club suit = shamrock,
+                                     U+2663 ISOpub -->
+<!ENTITY hearts   "&#9829;"> <!-- black heart suit = valentine,
+                                     U+2665 ISOpub -->
+<!ENTITY diams    "&#9830;"> <!-- black diamond suit, U+2666 ISOpub -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-frameset.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-frameset.dtd
new file mode 100644
index 0000000..d31c3ea
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-frameset.dtd
@@ -0,0 +1,1235 @@
+<!--
+   Extensible HTML version 1.0 Frameset DTD
+
+   This is the same as HTML 4 Frameset except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
+
+   $Revision: 1.1 $
+   $Date: 2003/03/09 00:10:48 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % FrameTarget "NMTOKEN">
+    <!-- render in this frame -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % MultiLengths "CDATA">
+    <!-- comma-separated list of MultiLength -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!-- used for object, applet, img, input and iframe -->
+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">
+
+<!-- a color using sRGB: #RRGGBB as Hex values -->
+<!ENTITY % Color "CDATA">
+
+<!-- There are also 16 widely known color names with their sRGB values:
+
+    Black  = #000000    Green  = #008000
+    Silver = #C0C0C0    Lime   = #00FF00
+    Gray   = #808080    Olive  = #808000
+    White  = #FFFFFF    Yellow = #FFFF00
+    Maroon = #800000    Navy   = #000080
+    Red    = #FF0000    Blue   = #0000FF
+    Purple = #800080    Teal   = #008080
+    Fuchsia= #FF00FF    Aqua   = #00FFFF
+-->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!-- text alignment for p, div, h1-h6. The default is
+     align="left" for ltr headings, "right" for rtl -->
+
+<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.extra
+   "object | applet | img | map | iframe">
+	
+<!ENTITY % special.basic
+	"br | span | bdo">
+
+<!ENTITY % special
+   "%special.basic; | %special.extra;">
+
+<!ENTITY % fontstyle.extra "big | small | font | basefont">
+
+<!ENTITY % fontstyle.basic "tt | i | b | u
+                      | s | strike ">
+
+<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;">
+
+<!ENTITY % phrase.extra "sub | sup">
+<!ENTITY % phrase.basic "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym">
+
+<!ENTITY % phrase "%phrase.basic; | %phrase.extra;">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl | menu | dir">
+<!ENTITY % blocktext "pre | hr | blockquote | address | center">
+
+<!ENTITY % block
+    "p | %heading; | div | %lists; | %blocktext; | isindex | fieldset | table">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding img, object, applet, big, small,
+     sub, sup, font, or basefont -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; |
+	   %inline.forms; | %misc.inline;)*">
+
+
+<!-- form uses %Flow; excluding form -->
+
+<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form, form controls, iframe -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+      table | br | span | bdo | object | applet | img | map |
+      %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, frameset)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  id          ID             #IMPLIED
+  href        %URI;          #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  language    CDATA          #IMPLIED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Flow;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--======================= Frames =======================================-->
+
+<!-- only one noframes element permitted per document -->
+
+<!ELEMENT frameset (frameset|frame|noframes)*>
+<!ATTLIST frameset
+  %coreattrs;
+  rows        %MultiLengths; #IMPLIED
+  cols        %MultiLengths; #IMPLIED
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  >
+
+<!-- reserved frame names start with "_" otherwise starts with letter -->
+
+<!-- tiled window within frameset -->
+
+<!ELEMENT frame EMPTY>
+<!ATTLIST frame
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  noresize    (noresize)     #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  >
+
+<!-- inline subwindow -->
+
+<!ELEMENT iframe %Flow;>
+<!ATTLIST iframe
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  align       %ImgAlign;     #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!-- alternate content container for non frame-based rendering -->
+
+<!ELEMENT noframes (body)>
+<!ATTLIST noframes
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Flow;>
+<!ATTLIST body
+  %attrs;
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  background  %URI;          #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  text        %Color;        #IMPLIED
+  link        %Color;        #IMPLIED
+  vlink       %Color;        #IMPLIED
+  alink       %Color;        #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list bullet styles -->
+
+<!ENTITY % ULStyle "(disc|square|circle)">
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  type        %ULStyle;     #IMPLIED
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- Ordered list numbering style
+
+    1   arabic numbers      1, 2, 3, ...
+    a   lower alpha         a, b, c, ...
+    A   upper alpha         A, B, C, ...
+    i   lower roman         i, ii, iii, ...
+    I   upper roman         I, II, III, ...
+
+    The style is applied to the sequence number which by default
+    is reset to 1 for the first list item in an ordered list.
+-->
+<!ENTITY % OLStyle "CDATA">
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  type        %OLStyle;      #IMPLIED
+  compact     (compact)      #IMPLIED
+  start       %Number;       #IMPLIED
+  >
+
+<!-- single column list (DEPRECATED) --> 
+<!ELEMENT menu (li)+>
+<!ATTLIST menu
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- multiple column list (DEPRECATED) --> 
+<!ELEMENT dir (li)+>
+<!ATTLIST dir
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->
+<!ENTITY % LIStyle "CDATA">
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  type        %LIStyle;      #IMPLIED
+  value       %Number;       #IMPLIED
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  compact     (compact)      #IMPLIED
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  align       (left|center|right) #IMPLIED
+  noshade     (noshade)      #IMPLIED
+  size        %Pixels;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding 
+        "img|object|applet|big|small|sub|sup|font|basefont" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  width       %Number;      #IMPLIED
+  xml:space   (preserve)    #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Flow;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Text alignment ===================================-->
+
+<!-- center content -->
+<!ELEMENT center %Flow;>
+<!ATTLIST center
+  %attrs;
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  clear       (left|all|right|none) "none"
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!ELEMENT u %Inline;>   <!-- underline -->
+<!ATTLIST u %attrs;>
+
+<!ELEMENT s %Inline;>   <!-- strike-through -->
+<!ATTLIST s %attrs;>
+
+<!ELEMENT strike %Inline;>   <!-- strike-through -->
+<!ATTLIST strike %attrs;>
+
+<!ELEMENT basefont EMPTY>  <!-- base font size -->
+<!ATTLIST basefont
+  id          ID             #IMPLIED
+  size        CDATA          #REQUIRED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!ELEMENT font %Inline;> <!-- local change to font -->
+<!ATTLIST font
+  %coreattrs;
+  %i18n;
+  size        CDATA          #IMPLIED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form |%inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #REQUIRED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Java applet ==================================-->
+<!--
+  One of code or object attributes must be present.
+  Place param elements before other content.
+-->
+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST applet
+  %coreattrs;
+  codebase    %URI;          #IMPLIED
+  archive     CDATA          #IMPLIED
+  code        CDATA          #IMPLIED
+  object      CDATA          #IMPLIED
+  alt         %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  width       %Length;       #REQUIRED
+  height      %Length;       #REQUIRED
+  align       %ImgAlign;     #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  name        NMTOKEN        #IMPLIED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--================ Forms ===============================================-->
+
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  name        NMTOKEN        #IMPLIED
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ENTITY % LAlign "(top|bottom|left|right)">
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  align       %LAlign;       #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form, form controls, iframe
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!-- single-line text input control (DEPRECATED) -->
+<!ELEMENT isindex EMPTY>
+<!ATTLIST isindex
+  %coreattrs;
+  %i18n;
+  prompt      %Text;         #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal placement of table relative to document -->
+<!ENTITY % TAlign "(left|center|right)">
+
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=":"
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  align       %TAlign;       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!ENTITY % CAlign "(top|bottom|left|right)">
+
+<!ATTLIST caption
+  %attrs;
+  align       %CAlign;       #IMPLIED
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Pixels;       #IMPLIED
+  height      %Pixels;       #IMPLIED
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Pixels;       #IMPLIED
+  height      %Pixels;       #IMPLIED
+  >
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-strict.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-strict.dtd
new file mode 100644
index 0000000..2453965
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-strict.dtd
@@ -0,0 +1,978 @@
+<!--
+   Extensible HTML version 1.0 Strict DTD
+
+   This is the same as HTML 4 Strict except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+
+   $Revision: 1.1 $
+   $Date: 2003/03/09 00:10:48 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.pre
+   "br | span | bdo | map">
+
+
+<!ENTITY % special
+   "%special.pre; | object | img ">
+
+<!ENTITY % fontstyle "tt | i | b | big | small ">
+
+<!ENTITY % phrase "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym | sub | sup ">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl">
+<!ENTITY % blocktext "pre | hr | blockquote | address">
+
+<!ENTITY % block
+     "p | %heading; | div | %lists; | %blocktext; | fieldset | table">
+
+<!ENTITY % Block "(%block; | form | %misc;)*">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding big, small, sup or sup -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline;
+      | %inline.forms;)*">
+
+<!-- form uses %Block; excluding form -->
+
+<!ENTITY % form.content "(%block; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form and form controls -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+    table | %special; | %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, body)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  href        %URI;          #REQUIRED
+  id          ID             #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Block;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Block;>
+<!ATTLIST body
+  %attrs;
+  onload          %Script;   #IMPLIED
+  onunload        %Script;   #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+   %attrs;
+   >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+   %attrs;
+   >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+   %attrs;
+   >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+   %attrs;
+   >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+   %attrs;
+   >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+   %attrs;
+   >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  >
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  >
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address %Inline;>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding "img|object|big|small|sub|sup" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  xml:space (preserve) #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Block;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+   Note that in this DTD there is no name attribute. That
+   is only available in the transitional and frameset DTD.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  >
+
+<!--================ Forms ===============================================-->
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form and form controls
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=':'
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  >
+
+<!ATTLIST caption
+  %attrs;
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  >
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-transitional.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-transitional.dtd
new file mode 100644
index 0000000..cd77e15
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1-transitional.dtd
@@ -0,0 +1,1201 @@
+<!--
+   Extensible HTML version 1.0 Transitional DTD
+
+   This is the same as HTML 4 Transitional except for
+   changes due to the differences between XML and SGML.
+
+   Namespace = http://www.w3.org/1999/xhtml
+
+   For further information, see: http://www.w3.org/TR/xhtml1
+
+   Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio),
+   All Rights Reserved. 
+
+   This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+   SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
+
+   $Revision: 1.1 $
+   $Date: 2003/03/09 00:10:48 $
+
+-->
+
+<!--================ Character mnemonic entities =========================-->
+
+<!ENTITY % HTMLlat1 PUBLIC
+   "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+   "xhtml-lat1.ent">
+%HTMLlat1;
+
+<!ENTITY % HTMLsymbol PUBLIC
+   "-//W3C//ENTITIES Symbols for XHTML//EN"
+   "xhtml-symbol.ent">
+%HTMLsymbol;
+
+<!ENTITY % HTMLspecial PUBLIC
+   "-//W3C//ENTITIES Special for XHTML//EN"
+   "xhtml-special.ent">
+%HTMLspecial;
+
+<!--================== Imported Names ====================================-->
+
+<!ENTITY % ContentType "CDATA">
+    <!-- media type, as per [RFC2045] -->
+
+<!ENTITY % ContentTypes "CDATA">
+    <!-- comma-separated list of media types, as per [RFC2045] -->
+
+<!ENTITY % Charset "CDATA">
+    <!-- a character encoding, as per [RFC2045] -->
+
+<!ENTITY % Charsets "CDATA">
+    <!-- a space separated list of character encodings, as per [RFC2045] -->
+
+<!ENTITY % LanguageCode "NMTOKEN">
+    <!-- a language code, as per [RFC3066] -->
+
+<!ENTITY % Character "CDATA">
+    <!-- a single character, as per section 2.2 of [XML] -->
+
+<!ENTITY % Number "CDATA">
+    <!-- one or more digits -->
+
+<!ENTITY % LinkTypes "CDATA">
+    <!-- space-separated list of link types -->
+
+<!ENTITY % MediaDesc "CDATA">
+    <!-- single or comma-separated list of media descriptors -->
+
+<!ENTITY % URI "CDATA">
+    <!-- a Uniform Resource Identifier, see [RFC2396] -->
+
+<!ENTITY % UriList "CDATA">
+    <!-- a space separated list of Uniform Resource Identifiers -->
+
+<!ENTITY % Datetime "CDATA">
+    <!-- date and time information. ISO date format -->
+
+<!ENTITY % Script "CDATA">
+    <!-- script expression -->
+
+<!ENTITY % StyleSheet "CDATA">
+    <!-- style sheet data -->
+
+<!ENTITY % Text "CDATA">
+    <!-- used for titles etc. -->
+
+<!ENTITY % FrameTarget "NMTOKEN">
+    <!-- render in this frame -->
+
+<!ENTITY % Length "CDATA">
+    <!-- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % MultiLength "CDATA">
+    <!-- pixel, percentage, or relative -->
+
+<!ENTITY % Pixels "CDATA">
+    <!-- integer representing length in pixels -->
+
+<!-- these are used for image maps -->
+
+<!ENTITY % Shape "(rect|circle|poly|default)">
+
+<!ENTITY % Coords "CDATA">
+    <!-- comma separated list of lengths -->
+
+<!-- used for object, applet, img, input and iframe -->
+<!ENTITY % ImgAlign "(top|middle|bottom|left|right)">
+
+<!-- a color using sRGB: #RRGGBB as Hex values -->
+<!ENTITY % Color "CDATA">
+
+<!-- There are also 16 widely known color names with their sRGB values:
+
+    Black  = #000000    Green  = #008000
+    Silver = #C0C0C0    Lime   = #00FF00
+    Gray   = #808080    Olive  = #808000
+    White  = #FFFFFF    Yellow = #FFFF00
+    Maroon = #800000    Navy   = #000080
+    Red    = #FF0000    Blue   = #0000FF
+    Purple = #800080    Teal   = #008080
+    Fuchsia= #FF00FF    Aqua   = #00FFFF
+-->
+
+<!--=================== Generic Attributes ===============================-->
+
+<!-- core attributes common to most elements
+  id       document-wide unique id
+  class    space separated list of classes
+  style    associated style info
+  title    advisory title/amplification
+-->
+<!ENTITY % coreattrs
+ "id          ID             #IMPLIED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED"
+  >
+
+<!-- internationalization attributes
+  lang        language code (backwards compatible)
+  xml:lang    language code (as per XML 1.0 spec)
+  dir         direction for weak/neutral text
+-->
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #IMPLIED"
+  >
+
+<!-- attributes for common UI events
+  onclick     a pointer button was clicked
+  ondblclick  a pointer button was double clicked
+  onmousedown a pointer button was pressed down
+  onmouseup   a pointer button was released
+  onmousemove a pointer was moved onto the element
+  onmouseout  a pointer was moved away from the element
+  onkeypress  a key was pressed and released
+  onkeydown   a key was pressed down
+  onkeyup     a key was released
+-->
+<!ENTITY % events
+ "onclick     %Script;       #IMPLIED
+  ondblclick  %Script;       #IMPLIED
+  onmousedown %Script;       #IMPLIED
+  onmouseup   %Script;       #IMPLIED
+  onmouseover %Script;       #IMPLIED
+  onmousemove %Script;       #IMPLIED
+  onmouseout  %Script;       #IMPLIED
+  onkeypress  %Script;       #IMPLIED
+  onkeydown   %Script;       #IMPLIED
+  onkeyup     %Script;       #IMPLIED"
+  >
+
+<!-- attributes for elements that can get the focus
+  accesskey   accessibility key character
+  tabindex    position in tabbing order
+  onfocus     the element got the focus
+  onblur      the element lost the focus
+-->
+<!ENTITY % focus
+ "accesskey   %Character;    #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED"
+  >
+
+<!ENTITY % attrs "%coreattrs; %i18n; %events;">
+
+<!-- text alignment for p, div, h1-h6. The default is
+     align="left" for ltr headings, "right" for rtl -->
+
+<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED">
+
+<!--=================== Text Elements ====================================-->
+
+<!ENTITY % special.extra
+   "object | applet | img | map | iframe">
+	
+<!ENTITY % special.basic
+	"br | span | bdo">
+
+<!ENTITY % special
+   "%special.basic; | %special.extra;">
+
+<!ENTITY % fontstyle.extra "big | small | font | basefont">
+
+<!ENTITY % fontstyle.basic "tt | i | b | u
+                      | s | strike ">
+
+<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;">
+
+<!ENTITY % phrase.extra "sub | sup">
+<!ENTITY % phrase.basic "em | strong | dfn | code | q |
+                   samp | kbd | var | cite | abbr | acronym">
+
+<!ENTITY % phrase "%phrase.basic; | %phrase.extra;">
+
+<!ENTITY % inline.forms "input | select | textarea | label | button">
+
+<!-- these can occur at block or inline level -->
+<!ENTITY % misc.inline "ins | del | script">
+
+<!-- these can only occur at block level -->
+<!ENTITY % misc "noscript | %misc.inline;">
+
+<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
+
+<!-- %Inline; covers inline or "text-level" elements -->
+<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*">
+
+<!--================== Block level elements ==============================-->
+
+<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
+<!ENTITY % lists "ul | ol | dl | menu | dir">
+<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes">
+
+<!ENTITY % block
+    "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table">
+
+<!-- %Flow; mixes block and inline and is used for list items etc. -->
+<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
+
+<!--================== Content models for exclusions =====================-->
+
+<!-- a elements use %Inline; excluding a -->
+
+<!ENTITY % a.content
+   "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*">
+
+<!-- pre uses %Inline excluding img, object, applet, big, small,
+     font, or basefont -->
+
+<!ENTITY % pre.content
+   "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; |
+	   %inline.forms; | %misc.inline;)*">
+
+<!-- form uses %Flow; excluding form -->
+
+<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*">
+
+<!-- button uses %Flow; but excludes a, form, form controls, iframe -->
+
+<!ENTITY % button.content
+   "(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
+      table | br | span | bdo | object | applet | img | map |
+      %fontstyle; | %phrase; | %misc;)*">
+
+<!--================ Document Structure ==================================-->
+
+<!-- the namespace URI designates the document profile -->
+
+<!ELEMENT html (head, body)>
+<!ATTLIST html
+  %i18n;
+  id          ID             #IMPLIED
+  xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
+  >
+
+<!--================ Document Head =======================================-->
+
+<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*">
+
+<!-- content model is %head.misc; combined with a single
+     title and an optional base element in any order -->
+
+<!ELEMENT head (%head.misc;,
+     ((title, %head.misc;, (base, %head.misc;)?) |
+      (base, %head.misc;, (title, %head.misc;))))>
+
+<!ATTLIST head
+  %i18n;
+  id          ID             #IMPLIED
+  profile     %URI;          #IMPLIED
+  >
+
+<!-- The title element is not considered part of the flow of text.
+       It should be displayed, for example as the page header or
+       window title. Exactly one title is required per document.
+    -->
+<!ELEMENT title (#PCDATA)>
+<!ATTLIST title 
+  %i18n;
+  id          ID             #IMPLIED
+  >
+
+<!-- document base URI -->
+
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+  id          ID             #IMPLIED
+  href        %URI;          #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- generic metainformation -->
+<!ELEMENT meta EMPTY>
+<!ATTLIST meta
+  %i18n;
+  id          ID             #IMPLIED
+  http-equiv  CDATA          #IMPLIED
+  name        CDATA          #IMPLIED
+  content     CDATA          #REQUIRED
+  scheme      CDATA          #IMPLIED
+  >
+
+<!--
+  Relationship values can be used in principle:
+
+   a) for document specific toolbars/menus when used
+      with the link element in document head e.g.
+        start, contents, previous, next, index, end, help
+   b) to link to a separate style sheet (rel="stylesheet")
+   c) to make a link to a script (rel="script")
+   d) by stylesheets to control how collections of
+      html nodes are rendered into printed documents
+   e) to make a link to a printable version of this document
+      e.g. a PostScript or PDF version (rel="alternate" media="print")
+-->
+
+<!ELEMENT link EMPTY>
+<!ATTLIST link
+  %attrs;
+  charset     %Charset;      #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  type        %ContentType;  #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  media       %MediaDesc;    #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!-- style info, which may include CDATA sections -->
+<!ELEMENT style (#PCDATA)>
+<!ATTLIST style
+  %i18n;
+  id          ID             #IMPLIED
+  type        %ContentType;  #REQUIRED
+  media       %MediaDesc;    #IMPLIED
+  title       %Text;         #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- script statements, which may include CDATA sections -->
+<!ELEMENT script (#PCDATA)>
+<!ATTLIST script
+  id          ID             #IMPLIED
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #REQUIRED
+  language    CDATA          #IMPLIED
+  src         %URI;          #IMPLIED
+  defer       (defer)        #IMPLIED
+  xml:space   (preserve)     #FIXED 'preserve'
+  >
+
+<!-- alternate content container for non script-based rendering -->
+
+<!ELEMENT noscript %Flow;>
+<!ATTLIST noscript
+  %attrs;
+  >
+
+<!--======================= Frames =======================================-->
+
+<!-- inline subwindow -->
+
+<!ELEMENT iframe %Flow;>
+<!ATTLIST iframe
+  %coreattrs;
+  longdesc    %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  src         %URI;          #IMPLIED
+  frameborder (1|0)          "1"
+  marginwidth %Pixels;       #IMPLIED
+  marginheight %Pixels;      #IMPLIED
+  scrolling   (yes|no|auto)  "auto"
+  align       %ImgAlign;     #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!-- alternate content container for non frame-based rendering -->
+
+<!ELEMENT noframes %Flow;>
+<!ATTLIST noframes
+  %attrs;
+  >
+
+<!--=================== Document Body ====================================-->
+
+<!ELEMENT body %Flow;>
+<!ATTLIST body
+  %attrs;
+  onload      %Script;       #IMPLIED
+  onunload    %Script;       #IMPLIED
+  background  %URI;          #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  text        %Color;        #IMPLIED
+  link        %Color;        #IMPLIED
+  vlink       %Color;        #IMPLIED
+  alink       %Color;        #IMPLIED
+  >
+
+<!ELEMENT div %Flow;>  <!-- generic language/style container -->
+<!ATTLIST div
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Paragraphs =======================================-->
+
+<!ELEMENT p %Inline;>
+<!ATTLIST p
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Headings =========================================-->
+
+<!--
+  There are six levels of headings from h1 (the most important)
+  to h6 (the least important).
+-->
+
+<!ELEMENT h1  %Inline;>
+<!ATTLIST h1
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h2 %Inline;>
+<!ATTLIST h2
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h3 %Inline;>
+<!ATTLIST h3
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h4 %Inline;>
+<!ATTLIST h4
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h5 %Inline;>
+<!ATTLIST h5
+  %attrs;
+  %TextAlign;
+  >
+
+<!ELEMENT h6 %Inline;>
+<!ATTLIST h6
+  %attrs;
+  %TextAlign;
+  >
+
+<!--=================== Lists ============================================-->
+
+<!-- Unordered list bullet styles -->
+
+<!ENTITY % ULStyle "(disc|square|circle)">
+
+<!-- Unordered list -->
+
+<!ELEMENT ul (li)+>
+<!ATTLIST ul
+  %attrs;
+  type        %ULStyle;     #IMPLIED
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- Ordered list numbering style
+
+    1   arabic numbers      1, 2, 3, ...
+    a   lower alpha         a, b, c, ...
+    A   upper alpha         A, B, C, ...
+    i   lower roman         i, ii, iii, ...
+    I   upper roman         I, II, III, ...
+
+    The style is applied to the sequence number which by default
+    is reset to 1 for the first list item in an ordered list.
+-->
+<!ENTITY % OLStyle "CDATA">
+
+<!-- Ordered (numbered) list -->
+
+<!ELEMENT ol (li)+>
+<!ATTLIST ol
+  %attrs;
+  type        %OLStyle;      #IMPLIED
+  compact     (compact)      #IMPLIED
+  start       %Number;       #IMPLIED
+  >
+
+<!-- single column list (DEPRECATED) --> 
+<!ELEMENT menu (li)+>
+<!ATTLIST menu
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- multiple column list (DEPRECATED) --> 
+<!ELEMENT dir (li)+>
+<!ATTLIST dir
+  %attrs;
+  compact     (compact)     #IMPLIED
+  >
+
+<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" -->
+<!ENTITY % LIStyle "CDATA">
+
+<!-- list item -->
+
+<!ELEMENT li %Flow;>
+<!ATTLIST li
+  %attrs;
+  type        %LIStyle;      #IMPLIED
+  value       %Number;       #IMPLIED
+  >
+
+<!-- definition lists - dt for term, dd for its definition -->
+
+<!ELEMENT dl (dt|dd)+>
+<!ATTLIST dl
+  %attrs;
+  compact     (compact)      #IMPLIED
+  >
+
+<!ELEMENT dt %Inline;>
+<!ATTLIST dt
+  %attrs;
+  >
+
+<!ELEMENT dd %Flow;>
+<!ATTLIST dd
+  %attrs;
+  >
+
+<!--=================== Address ==========================================-->
+
+<!-- information on author -->
+
+<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*>
+<!ATTLIST address
+  %attrs;
+  >
+
+<!--=================== Horizontal Rule ==================================-->
+
+<!ELEMENT hr EMPTY>
+<!ATTLIST hr
+  %attrs;
+  align       (left|center|right) #IMPLIED
+  noshade     (noshade)      #IMPLIED
+  size        %Pixels;       #IMPLIED
+  width       %Length;       #IMPLIED
+  >
+
+<!--=================== Preformatted Text ================================-->
+
+<!-- content is %Inline; excluding 
+        "img|object|applet|big|small|sub|sup|font|basefont" -->
+
+<!ELEMENT pre %pre.content;>
+<!ATTLIST pre
+  %attrs;
+  width       %Number;      #IMPLIED
+  xml:space   (preserve)    #FIXED 'preserve'
+  >
+
+<!--=================== Block-like Quotes ================================-->
+
+<!ELEMENT blockquote %Flow;>
+<!ATTLIST blockquote
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!--=================== Text alignment ===================================-->
+
+<!-- center content -->
+<!ELEMENT center %Flow;>
+<!ATTLIST center
+  %attrs;
+  >
+
+<!--=================== Inserted/Deleted Text ============================-->
+
+<!--
+  ins/del are allowed in block and inline content, but its
+  inappropriate to include block content within an ins element
+  occurring in inline content.
+-->
+<!ELEMENT ins %Flow;>
+<!ATTLIST ins
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!ELEMENT del %Flow;>
+<!ATTLIST del
+  %attrs;
+  cite        %URI;          #IMPLIED
+  datetime    %Datetime;     #IMPLIED
+  >
+
+<!--================== The Anchor Element ================================-->
+
+<!-- content is %Inline; except that anchors shouldn't be nested -->
+
+<!ELEMENT a %a.content;>
+<!ATTLIST a
+  %attrs;
+  %focus;
+  charset     %Charset;      #IMPLIED
+  type        %ContentType;  #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  href        %URI;          #IMPLIED
+  hreflang    %LanguageCode; #IMPLIED
+  rel         %LinkTypes;    #IMPLIED
+  rev         %LinkTypes;    #IMPLIED
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--===================== Inline Elements ================================-->
+
+<!ELEMENT span %Inline;> <!-- generic language/style container -->
+<!ATTLIST span
+  %attrs;
+  >
+
+<!ELEMENT bdo %Inline;>  <!-- I18N BiDi over-ride -->
+<!ATTLIST bdo
+  %coreattrs;
+  %events;
+  lang        %LanguageCode; #IMPLIED
+  xml:lang    %LanguageCode; #IMPLIED
+  dir         (ltr|rtl)      #REQUIRED
+  >
+
+<!ELEMENT br EMPTY>   <!-- forced line break -->
+<!ATTLIST br
+  %coreattrs;
+  clear       (left|all|right|none) "none"
+  >
+
+<!ELEMENT em %Inline;>   <!-- emphasis -->
+<!ATTLIST em %attrs;>
+
+<!ELEMENT strong %Inline;>   <!-- strong emphasis -->
+<!ATTLIST strong %attrs;>
+
+<!ELEMENT dfn %Inline;>   <!-- definitional -->
+<!ATTLIST dfn %attrs;>
+
+<!ELEMENT code %Inline;>   <!-- program code -->
+<!ATTLIST code %attrs;>
+
+<!ELEMENT samp %Inline;>   <!-- sample -->
+<!ATTLIST samp %attrs;>
+
+<!ELEMENT kbd %Inline;>  <!-- something user would type -->
+<!ATTLIST kbd %attrs;>
+
+<!ELEMENT var %Inline;>   <!-- variable -->
+<!ATTLIST var %attrs;>
+
+<!ELEMENT cite %Inline;>   <!-- citation -->
+<!ATTLIST cite %attrs;>
+
+<!ELEMENT abbr %Inline;>   <!-- abbreviation -->
+<!ATTLIST abbr %attrs;>
+
+<!ELEMENT acronym %Inline;>   <!-- acronym -->
+<!ATTLIST acronym %attrs;>
+
+<!ELEMENT q %Inline;>   <!-- inlined quote -->
+<!ATTLIST q
+  %attrs;
+  cite        %URI;          #IMPLIED
+  >
+
+<!ELEMENT sub %Inline;> <!-- subscript -->
+<!ATTLIST sub %attrs;>
+
+<!ELEMENT sup %Inline;> <!-- superscript -->
+<!ATTLIST sup %attrs;>
+
+<!ELEMENT tt %Inline;>   <!-- fixed pitch font -->
+<!ATTLIST tt %attrs;>
+
+<!ELEMENT i %Inline;>   <!-- italic font -->
+<!ATTLIST i %attrs;>
+
+<!ELEMENT b %Inline;>   <!-- bold font -->
+<!ATTLIST b %attrs;>
+
+<!ELEMENT big %Inline;>   <!-- bigger font -->
+<!ATTLIST big %attrs;>
+
+<!ELEMENT small %Inline;>   <!-- smaller font -->
+<!ATTLIST small %attrs;>
+
+<!ELEMENT u %Inline;>   <!-- underline -->
+<!ATTLIST u %attrs;>
+
+<!ELEMENT s %Inline;>   <!-- strike-through -->
+<!ATTLIST s %attrs;>
+
+<!ELEMENT strike %Inline;>   <!-- strike-through -->
+<!ATTLIST strike %attrs;>
+
+<!ELEMENT basefont EMPTY>  <!-- base font size -->
+<!ATTLIST basefont
+  id          ID             #IMPLIED
+  size        CDATA          #REQUIRED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!ELEMENT font %Inline;> <!-- local change to font -->
+<!ATTLIST font
+  %coreattrs;
+  %i18n;
+  size        CDATA          #IMPLIED
+  color       %Color;        #IMPLIED
+  face        CDATA          #IMPLIED
+  >
+
+<!--==================== Object ======================================-->
+<!--
+  object is used to embed objects as part of HTML pages.
+  param elements should precede other content. Parameters
+  can also be expressed as attribute/value pairs on the
+  object element itself when brevity is desired.
+-->
+
+<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST object
+  %attrs;
+  declare     (declare)      #IMPLIED
+  classid     %URI;          #IMPLIED
+  codebase    %URI;          #IMPLIED
+  data        %URI;          #IMPLIED
+  type        %ContentType;  #IMPLIED
+  codetype    %ContentType;  #IMPLIED
+  archive     %UriList;      #IMPLIED
+  standby     %Text;         #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Pixels;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--
+  param is used to supply a named property value.
+  In XML it would seem natural to follow RDF and support an
+  abbreviated syntax where the param elements are replaced
+  by attribute value pairs on the object start tag.
+-->
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  id          ID             #IMPLIED
+  name        CDATA          #REQUIRED
+  value       CDATA          #IMPLIED
+  valuetype   (data|ref|object) "data"
+  type        %ContentType;  #IMPLIED
+  >
+
+<!--=================== Java applet ==================================-->
+<!--
+  One of code or object attributes must be present.
+  Place param elements before other content.
+-->
+<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*>
+<!ATTLIST applet
+  %coreattrs;
+  codebase    %URI;          #IMPLIED
+  archive     CDATA          #IMPLIED
+  code        CDATA          #IMPLIED
+  object      CDATA          #IMPLIED
+  alt         %Text;         #IMPLIED
+  name        NMTOKEN        #IMPLIED
+  width       %Length;       #REQUIRED
+  height      %Length;       #REQUIRED
+  align       %ImgAlign;     #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!--=================== Images ===========================================-->
+
+<!--
+   To avoid accessibility problems for people who aren't
+   able to see the image, you should provide a text
+   description using the alt and longdesc attributes.
+   In addition, avoid the use of server-side image maps.
+-->
+
+<!ELEMENT img EMPTY>
+<!ATTLIST img
+  %attrs;
+  src         %URI;          #REQUIRED
+  alt         %Text;         #REQUIRED
+  name        NMTOKEN        #IMPLIED
+  longdesc    %URI;          #IMPLIED
+  height      %Length;       #IMPLIED
+  width       %Length;       #IMPLIED
+  usemap      %URI;          #IMPLIED
+  ismap       (ismap)        #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  border      %Length;       #IMPLIED
+  hspace      %Pixels;       #IMPLIED
+  vspace      %Pixels;       #IMPLIED
+  >
+
+<!-- usemap points to a map element which may be in this document
+  or an external document, although the latter is not widely supported -->
+
+<!--================== Client-side image maps ============================-->
+
+<!-- These can be placed in the same document or grouped in a
+     separate document although this isn't yet widely supported -->
+
+<!ELEMENT map ((%block; | form | %misc;)+ | area+)>
+<!ATTLIST map
+  %i18n;
+  %events;
+  id          ID             #REQUIRED
+  class       CDATA          #IMPLIED
+  style       %StyleSheet;   #IMPLIED
+  title       %Text;         #IMPLIED
+  name        CDATA          #IMPLIED
+  >
+
+<!ELEMENT area EMPTY>
+<!ATTLIST area
+  %attrs;
+  %focus;
+  shape       %Shape;        "rect"
+  coords      %Coords;       #IMPLIED
+  href        %URI;          #IMPLIED
+  nohref      (nohref)       #IMPLIED
+  alt         %Text;         #REQUIRED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--================ Forms ===============================================-->
+
+<!ELEMENT form %form.content;>   <!-- forms shouldn't be nested -->
+
+<!ATTLIST form
+  %attrs;
+  action      %URI;          #REQUIRED
+  method      (get|post)     "get"
+  name        NMTOKEN        #IMPLIED
+  enctype     %ContentType;  "application/x-www-form-urlencoded"
+  onsubmit    %Script;       #IMPLIED
+  onreset     %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  accept-charset %Charsets;  #IMPLIED
+  target      %FrameTarget;  #IMPLIED
+  >
+
+<!--
+  Each label must not contain more than ONE field
+  Label elements shouldn't be nested.
+-->
+<!ELEMENT label %Inline;>
+<!ATTLIST label
+  %attrs;
+  for         IDREF          #IMPLIED
+  accesskey   %Character;    #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  >
+
+<!ENTITY % InputType
+  "(text | password | checkbox |
+    radio | submit | reset |
+    file | hidden | image | button)"
+   >
+
+<!-- the name attribute is required for all but submit & reset -->
+
+<!ELEMENT input EMPTY>     <!-- form control -->
+<!ATTLIST input
+  %attrs;
+  %focus;
+  type        %InputType;    "text"
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  checked     (checked)      #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  size        CDATA          #IMPLIED
+  maxlength   %Number;       #IMPLIED
+  src         %URI;          #IMPLIED
+  alt         CDATA          #IMPLIED
+  usemap      %URI;          #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  accept      %ContentTypes; #IMPLIED
+  align       %ImgAlign;     #IMPLIED
+  >
+
+<!ELEMENT select (optgroup|option)+>  <!-- option selector -->
+<!ATTLIST select
+  %attrs;
+  name        CDATA          #IMPLIED
+  size        %Number;       #IMPLIED
+  multiple    (multiple)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  tabindex    %Number;       #IMPLIED
+  onfocus     %Script;       #IMPLIED
+  onblur      %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!ELEMENT optgroup (option)+>   <!-- option group -->
+<!ATTLIST optgroup
+  %attrs;
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #REQUIRED
+  >
+
+<!ELEMENT option (#PCDATA)>     <!-- selectable choice -->
+<!ATTLIST option
+  %attrs;
+  selected    (selected)     #IMPLIED
+  disabled    (disabled)     #IMPLIED
+  label       %Text;         #IMPLIED
+  value       CDATA          #IMPLIED
+  >
+
+<!ELEMENT textarea (#PCDATA)>     <!-- multi-line text field -->
+<!ATTLIST textarea
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  rows        %Number;       #REQUIRED
+  cols        %Number;       #REQUIRED
+  disabled    (disabled)     #IMPLIED
+  readonly    (readonly)     #IMPLIED
+  onselect    %Script;       #IMPLIED
+  onchange    %Script;       #IMPLIED
+  >
+
+<!--
+  The fieldset element is used to group form fields.
+  Only one legend element should occur in the content
+  and if present should only be preceded by whitespace.
+-->
+<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*>
+<!ATTLIST fieldset
+  %attrs;
+  >
+
+<!ENTITY % LAlign "(top|bottom|left|right)">
+
+<!ELEMENT legend %Inline;>     <!-- fieldset label -->
+<!ATTLIST legend
+  %attrs;
+  accesskey   %Character;    #IMPLIED
+  align       %LAlign;       #IMPLIED
+  >
+
+<!--
+ Content is %Flow; excluding a, form, form controls, iframe
+--> 
+<!ELEMENT button %button.content;>  <!-- push button -->
+<!ATTLIST button
+  %attrs;
+  %focus;
+  name        CDATA          #IMPLIED
+  value       CDATA          #IMPLIED
+  type        (button|submit|reset) "submit"
+  disabled    (disabled)     #IMPLIED
+  >
+
+<!-- single-line text input control (DEPRECATED) -->
+<!ELEMENT isindex EMPTY>
+<!ATTLIST isindex
+  %coreattrs;
+  %i18n;
+  prompt      %Text;         #IMPLIED
+  >
+
+<!--======================= Tables =======================================-->
+
+<!-- Derived from IETF HTML table standard, see [RFC1942] -->
+
+<!--
+ The border attribute sets the thickness of the frame around the
+ table. The default units are screen pixels.
+
+ The frame attribute specifies which parts of the frame around
+ the table should be rendered. The values are not the same as
+ CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
+
+<!--
+ The rules attribute defines which rules to draw between cells:
+
+ If rules is absent then assume:
+     "none" if border is absent or border="0" otherwise "all"
+-->
+
+<!ENTITY % TRules "(none | groups | rows | cols | all)">
+  
+<!-- horizontal placement of table relative to document -->
+<!ENTITY % TAlign "(left|center|right)">
+
+<!-- horizontal alignment attributes for cell contents
+
+  char        alignment char, e.g. char=':'
+  charoff     offset for alignment char
+-->
+<!ENTITY % cellhalign
+  "align      (left|center|right|justify|char) #IMPLIED
+   char       %Character;    #IMPLIED
+   charoff    %Length;       #IMPLIED"
+  >
+
+<!-- vertical alignment attributes for cell contents -->
+<!ENTITY % cellvalign
+  "valign     (top|middle|bottom|baseline) #IMPLIED"
+  >
+
+<!ELEMENT table
+     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
+<!ELEMENT caption  %Inline;>
+<!ELEMENT thead    (tr)+>
+<!ELEMENT tfoot    (tr)+>
+<!ELEMENT tbody    (tr)+>
+<!ELEMENT colgroup (col)*>
+<!ELEMENT col      EMPTY>
+<!ELEMENT tr       (th|td)+>
+<!ELEMENT th       %Flow;>
+<!ELEMENT td       %Flow;>
+
+<!ATTLIST table
+  %attrs;
+  summary     %Text;         #IMPLIED
+  width       %Length;       #IMPLIED
+  border      %Pixels;       #IMPLIED
+  frame       %TFrame;       #IMPLIED
+  rules       %TRules;       #IMPLIED
+  cellspacing %Length;       #IMPLIED
+  cellpadding %Length;       #IMPLIED
+  align       %TAlign;       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!ENTITY % CAlign "(top|bottom|left|right)">
+
+<!ATTLIST caption
+  %attrs;
+  align       %CAlign;       #IMPLIED
+  >
+
+<!--
+colgroup groups a set of col elements. It allows you to group
+several semantically related columns together.
+-->
+<!ATTLIST colgroup
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+ col elements define the alignment properties for cells in
+ one or more columns.
+
+ The width attribute specifies the width of the columns, e.g.
+
+     width=64        width in screen pixels
+     width=0.5*      relative width of 0.5
+
+ The span attribute causes the attributes of one
+ col element to apply to more than one column.
+-->
+<!ATTLIST col
+  %attrs;
+  span        %Number;       "1"
+  width       %MultiLength;  #IMPLIED
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!--
+    Use thead to duplicate headers when breaking table
+    across page boundaries, or for static headers when
+    tbody sections are rendered in scrolling panel.
+
+    Use tfoot to duplicate footers when breaking table
+    across page boundaries, or for static footers when
+    tbody sections are rendered in scrolling panel.
+
+    Use multiple tbody sections when rules are needed
+    between groups of table rows.
+-->
+<!ATTLIST thead
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tfoot
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tbody
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  >
+
+<!ATTLIST tr
+  %attrs;
+  %cellhalign;
+  %cellvalign;
+  bgcolor     %Color;        #IMPLIED
+  >
+
+<!-- Scope is simpler than headers attribute for common tables -->
+<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
+
+<!-- th is for headers, td for data and for cells acting as both -->
+
+<!ATTLIST th
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Length;       #IMPLIED
+  height      %Length;       #IMPLIED
+  >
+
+<!ATTLIST td
+  %attrs;
+  abbr        %Text;         #IMPLIED
+  axis        CDATA          #IMPLIED
+  headers     IDREFS         #IMPLIED
+  scope       %Scope;        #IMPLIED
+  rowspan     %Number;       "1"
+  colspan     %Number;       "1"
+  %cellhalign;
+  %cellvalign;
+  nowrap      (nowrap)       #IMPLIED
+  bgcolor     %Color;        #IMPLIED
+  width       %Length;       #IMPLIED
+  height      %Length;       #IMPLIED
+  >
+
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1.dcl b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1.dcl
new file mode 100644
index 0000000..065ee84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml1.dcl
@@ -0,0 +1,192 @@
+<!SGML "ISO 8879:1986 (WWW)"
+
+     -- SGML Declaration for XML 1.0 --
+
+     -- from: 
+        Final text of revised Web SGML Adaptations Annex (TC2) to ISO 8879:1986
+        ISO/IEC JTC1/SC34 N0029: 1998-12-06
+        Annex L.2 (informative): SGML Declaration for XML
+
+        changes made to accommodate validation are noted with 'VALID:'
+     --
+
+     CHARSET
+         BASESET
+             "ISO Registration Number 177//CHARSET
+              ISO/IEC 10646-1:1993 UCS-4 with implementation
+              level 3//ESC 2/5 2/15 4/6"
+         DESCSET
+                 0        9  UNUSED
+                 9        2       9
+                11        2  UNUSED
+                13        1      13
+                14       18  UNUSED
+                32       95      32
+               127        1  UNUSED
+               128       32  UNUSED
+               160    55136     160
+             55296     2048  UNUSED  -- surrogates --
+             57344     8190   57344
+             65534        2  UNUSED  -- FFFE and FFFF --
+             65536  1048576   65536
+
+     CAPACITY NONE  -- Capacities are not restricted in XML --
+
+     SCOPE DOCUMENT
+
+     SYNTAX
+         SHUNCHAR NONE
+         BASESET "ISO Registration Number 177//CHARSET
+                  ISO/IEC 10646-1:1993 UCS-4 with implementation
+                  level 3//ESC 2/5 2/15 4/6"
+         DESCSET
+             0 1114112 0
+         FUNCTION
+             RE    13
+             RS    10
+             SPACE 32
+             TAB   SEPCHAR 9
+         NAMING
+             LCNMSTRT ""
+             UCNMSTRT ""
+             NAMESTRT
+                 58 95 192-214 216-246 248-305 308-318 321-328
+                 330-382 384-451 461-496 500-501 506-535 592-680
+                 699-705 902 904-906 908 910-929 931-974 976-982
+                 986 988 990 992 994-1011 1025-1036 1038-1103
+                 1105-1116 1118-1153 1168-1220 1223-1224
+                 1227-1228 1232-1259 1262-1269 1272-1273
+                 1329-1366 1369 1377-1414 1488-1514 1520-1522
+                 1569-1594 1601-1610 1649-1719 1722-1726
+                 1728-1742 1744-1747 1749 1765-1766 2309-2361
+                 2365 2392-2401 2437-2444 2447-2448 2451-2472
+                 2474-2480 2482 2486-2489 2524-2525 2527-2529
+                 2544-2545 2565-2570 2575-2576 2579-2600
+                 2602-2608 2610-2611 2613-2614 2616-2617
+                 2649-2652 2654 2674-2676 2693-2699 2701
+                 2703-2705 2707-2728 2730-2736 2738-2739
+                 2741-2745 2749 2784 2821-2828 2831-2832
+                 2835-2856 2858-2864 2866-2867 2870-2873 2877
+                 2908-2909 2911-2913 2949-2954 2958-2960
+                 2962-2965 2969-2970 2972 2974-2975 2979-2980
+                 2984-2986 2990-2997 2999-3001 3077-3084
+                 3086-3088 3090-3112 3114-3123 3125-3129
+                 3168-3169 3205-3212 3214-3216 3218-3240
+                 3242-3251 3253-3257 3294 3296-3297 3333-3340
+                 3342-3344 3346-3368 3370-3385 3424-3425
+                 3585-3630 3632 3634-3635 3648-3653 3713-3714
+                 3716 3719-3720 3722 3725 3732-3735 3737-3743
+                 3745-3747 3749 3751 3754-3755 3757-3758 3760
+                 3762-3763 3773 3776-3780 3904-3911 3913-3945
+                 4256-4293 4304-4342 4352 4354-4355 4357-4359
+                 4361 4363-4364 4366-4370 4412 4414 4416 4428
+                 4430 4432 4436-4437 4441 4447-4449 4451 4453
+                 4455 4457 4461-4462 4466-4467 4469 4510 4520
+                 4523 4526-4527 4535-4536 4538 4540-4546 4587
+                 4592 4601 7680-7835 7840-7929 7936-7957
+                 7960-7965 7968-8005 8008-8013 8016-8023 8025
+                 8027 8029 8031-8061 8064-8116 8118-8124 8126
+                 8130-8132 8134-8140 8144-8147 8150-8155
+                 8160-8172 8178-8180 8182-8188 8486 8490-8491
+                 8494 8576-8578 12295 12321-12329 12353-12436
+                 12449-12538 12549-12588 19968-40869 44032-55203
+
+             LCNMCHAR ""
+             UCNMCHAR ""
+             NAMECHAR
+                 45-46 183 720-721 768-837 864-865 903 1155-1158
+                 1425-1441 1443-1465 1467-1469 1471 1473-1474
+                 1476 1600 1611-1618 1632-1641 1648 1750-1764
+                 1767-1768 1770-1773 1776-1785 2305-2307 2364
+                 2366-2381 2385-2388 2402-2403 2406-2415
+                 2433-2435 2492 2494-2500 2503-2504 2507-2509
+                 2519 2530-2531 2534-2543 2562 2620 2622-2626
+                 2631-2632 2635-2637 2662-2673 2689-2691 2748
+                 2750-2757 2759-2761 2763-2765 2790-2799
+                 2817-2819 2876 2878-2883 2887-2888 2891-2893
+                 2902-2903 2918-2927 2946-2947 3006-3010
+                 3014-3016 3018-3021 3031 3047-3055 3073-3075
+                 3134-3140 3142-3144 3146-3149 3157-3158
+                 3174-3183 3202-3203 3262-3268 3270-3272
+                 3274-3277 3285-3286 3302-3311 3330-3331
+                 3390-3395 3398-3400 3402-3405 3415 3430-3439
+                 3633 3636-3642 3654-3662 3664-3673 3761
+                 3764-3769 3771-3772 3782 3784-3789 3792-3801
+                 3864-3865 3872-3881 3893 3895 3897 3902-3903
+                 3953-3972 3974-3979 3984-3989 3991 3993-4013
+                 4017-4023 4025 8400-8412 8417 12293 12330-12335
+                 12337-12341 12441-12442 12445-12446 12540-12542
+
+             NAMECASE
+                 GENERAL NO
+                 ENTITY  NO
+         DELIM
+             GENERAL  SGMLREF
+             HCRO     "&#38;#x"
+                      -- Ampersand followed by "#x" (without quotes) --
+             NESTC    "/"
+             NET      ">"
+             PIC      "?>"
+             SHORTREF NONE
+
+         NAMES
+             SGMLREF
+
+         QUANTITY
+             NONE -- Quantities are not restricted in XML --
+
+         ENTITIES
+             "amp"  38
+             "lt"   60
+             "gt"   62
+             "quot" 34
+             "apos" 39
+
+     FEATURES
+         MINIMIZE
+             DATATAG NO
+             OMITTAG NO
+             RANK    NO
+             SHORTTAG
+                 STARTTAG
+                     EMPTY    NO
+                     UNCLOSED NO
+                     NETENABL IMMEDNET
+                 ENDTAG
+                     EMPTY    NO
+                     UNCLOSED NO
+                 ATTRIB
+                     DEFAULT  YES
+                     OMITNAME NO
+                     VALUE    NO
+             EMPTYNRM  YES
+             IMPLYDEF
+                 ATTLIST  NO  -- VALID: was YES --
+                 DOCTYPE  NO
+                 ELEMENT  NO  -- VALID: was YES --
+                 ENTITY   NO
+                 NOTATION NO  -- VALID: was YES --
+         LINK
+             SIMPLE   NO
+             IMPLICIT NO
+             EXPLICIT NO
+         OTHER
+             CONCUR   NO
+             SUBDOC   NO
+             FORMAL   NO
+             URN      NO
+             KEEPRSRE YES
+             VALIDITY TYPE -- VALID: was NOASSERT --
+             ENTITIES
+                 REF      ANY
+                 INTEGRAL YES
+
+     APPINFO NONE
+
+     SEEALSO "ISO 8879//NOTATION Extensible Markup Language (XML) 1.0//EN"
+>
+<!-- Id: $Id: xhtml1.dcl,v 1.1 2003/03/09 00:10:48 pier Exp $ SMI
+     Revisions:
+#1999-04-09  changes for XML validation
+#2001-04-08  updated ISO registration number for UCS-4
+-->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml11-flat.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml11-flat.dtd
new file mode 100644
index 0000000..c7eb7e9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/w3c/xhtml11-flat.dtd
@@ -0,0 +1,4513 @@
+<!-- ....................................................................... -->
+<!-- XHTML 1.1 DTD  ........................................................ -->
+<!-- file: xhtml11.dtd
+-->
+
+<!-- XHTML 1.1 DTD
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+
+     The Extensible HyperText Markup Language (XHTML)
+     Copyright 1998-2000 World Wide Web Consortium
+        (Massachusetts Institute of Technology, Institut National de
+         Recherche en Informatique et en Automatique, Keio University).
+         All Rights Reserved.
+
+     Permission to use, copy, modify and distribute the XHTML DTD and its 
+     accompanying documentation for any purpose and without fee is hereby 
+     granted in perpetuity, provided that the above copyright notice and 
+     this paragraph appear in all copies.  The copyright holders make no 
+     representation about the suitability of the DTD for any purpose.
+
+     It is provided "as is" without expressed or implied warranty.
+
+        Author:     Murray M. Altheim <altheim@eng.sun.com>
+        Revision:   $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $
+
+-->
+<!-- This is the driver file for version 1.1 of the XHTML DTD.
+
+     Please use this formal public identifier to identify it:
+
+         "-//W3C//DTD XHTML 1.1//EN"
+-->
+<!ENTITY % XHTML.version  "-//W3C//DTD XHTML 1.1//EN" >
+
+<!-- Use this URI to identify the default namespace:
+
+         "http://www.w3.org/1999/xhtml"
+
+     See the Qualified Names module for information
+     on the use of namespace prefixes in the DTD.
+-->
+<!ENTITY % NS.prefixed "IGNORE" >
+<!ENTITY % XHTML.prefix "" >
+
+<!-- Reserved for use with the XLink namespace:
+-->
+<!ENTITY % XLINK.xmlns "" >
+<!ENTITY % XLINK.xmlns.attrib "" >
+
+<!-- For example, if you are using XHTML 1.1 directly, use the FPI
+     in the DOCTYPE declaration, with the xmlns attribute on the
+     document element to identify the default namespace:
+
+       <?xml version="1.0"?>
+       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
+       <html xmlns="http://www.w3.org/1999/xhtml"
+             xml:lang="en">
+       ...
+       </html>
+
+     Revisions:
+     (none)
+-->
+
+<!-- reserved for future use with document profiles -->
+<!ENTITY % XHTML.profile  "" >
+
+<!-- Bidirectional Text features
+     This feature-test entity is used to declare elements
+     and attributes used for bidirectional text support.
+-->
+<!ENTITY % XHTML.bidi  "INCLUDE" >
+
+<?doc type="doctype" role="title" { XHTML 1.1 } ?>
+
+<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
+
+<!-- Pre-Framework Redeclaration placeholder  .................... -->
+<!-- this serves as a location to insert markup declarations
+     into the DTD prior to the framework declarations.
+-->
+<!ENTITY % xhtml-prefw-redecl.module "IGNORE" >
+<![%xhtml-prefw-redecl.module;[
+%xhtml-prefw-redecl.mod;
+<!-- end of xhtml-prefw-redecl.module -->]]>
+
+<!ENTITY % xhtml-events.module "INCLUDE" >
+
+<!-- Inline Style Module  ........................................ -->
+<!ENTITY % xhtml-inlstyle.module "INCLUDE" >
+<![%xhtml-inlstyle.module;[
+<!ENTITY % xhtml-inlstyle.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Inline Style 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstyle-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Inline Style Module  ........................................... -->
+<!-- file: xhtml-inlstyle-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Inline Style 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstyle-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Inline Style
+
+     This module declares the 'style' attribute, used to support inline
+     style markup. This module must be instantiated prior to the XHTML
+     Common Attributes module in order to be included in %Core.attrib;.
+-->
+
+<!ENTITY % style.attrib
+     "style        CDATA                    #IMPLIED"
+>
+
+
+<!ENTITY % Core.extra.attrib
+     "%style.attrib;"
+>
+
+<!-- end of xhtml-inlstyle-1.mod -->
+]]>
+
+<!-- declare Document Model module instantiated in framework
+-->
+<!ENTITY % xhtml-model.mod
+     PUBLIC "-//W3C//ENTITIES XHTML 1.1 Document Model 1.0//EN"
+            "xhtml11-model-1.mod" >
+
+<!-- Modular Framework Module (required) ......................... -->
+<!ENTITY % xhtml-framework.module "INCLUDE" >
+<![%xhtml-framework.module;[
+<!ENTITY % xhtml-framework.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Modular Framework 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-framework-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Modular Framework Module  ...................................... -->
+<!-- file: xhtml-framework-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Modular Framework 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-framework-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Modular Framework
+
+     This required module instantiates the modules needed
+     to support the XHTML modularization model, including:
+
+        +  notations
+        +  datatypes
+        +  namespace-qualified names
+        +  common attributes
+        +  document model
+        +  character entities
+
+     The Intrinsic Events module is ignored by default but
+     occurs in this module because it must be instantiated
+     prior to Attributes but after Datatypes.
+-->
+
+<!ENTITY % xhtml-arch.module "IGNORE" >
+<![%xhtml-arch.module;[
+<!ENTITY % xhtml-arch.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Base Architecture 1.0//EN"
+            "xhtml-arch-1.mod" >
+%xhtml-arch.mod;]]>
+
+<!ENTITY % xhtml-notations.module "INCLUDE" >
+<![%xhtml-notations.module;[
+<!ENTITY % xhtml-notations.mod
+     PUBLIC "-//W3C//NOTATIONS XHTML Notations 1.0//EN"
+            "xhtml-notations-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Notations Module  .............................................. -->
+<!-- file: xhtml-notations-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//NOTATIONS XHTML Notations 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-notations-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Notations
+
+     defines the following notations, many of these imported from
+     other specifications and standards. When an existing FPI is
+     known, it is incorporated here.
+-->
+
+<!-- XML Notations ..................................... -->
+<!-- SGML and XML Notations ............................ -->
+
+<!-- W3C XML 1.0 Recommendation -->
+<!NOTATION w3c-xml
+     PUBLIC "ISO 8879//NOTATION Extensible Markup Language (XML) 1.0//EN" >
+
+<!-- XML 1.0 CDATA -->
+<!NOTATION cdata
+     PUBLIC "-//W3C//NOTATION XML 1.0: CDATA//EN" >
+
+<!-- SGML Formal Public Identifiers -->
+<!NOTATION fpi
+     PUBLIC "ISO 8879:1986//NOTATION Formal Public Identifier//EN" >
+
+<!-- XHTML Notations ................................... -->
+
+<!-- Length defined for cellpadding/cellspacing -->
+
+<!-- nn for pixels or nn% for percentage length -->
+<!NOTATION length
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Length//EN" >
+
+<!-- space-separated list of link types -->
+<!NOTATION linkTypes
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: LinkTypes//EN" >
+
+<!-- single or comma-separated list of media descriptors -->
+<!NOTATION mediaDesc
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: MediaDesc//EN" >
+
+<!-- pixel, percentage, or relative -->
+<!NOTATION multiLength
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: MultiLength//EN" >
+
+<!-- one or more digits (NUMBER) -->
+<!NOTATION number
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Number//EN" >
+
+<!-- integer representing length in pixels -->
+<!NOTATION pixels
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Pixels//EN" >
+
+<!-- script expression -->
+<!NOTATION script
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Script//EN" >
+
+<!-- textual content -->
+<!NOTATION text
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Text//EN" >
+
+<!-- Imported Notations ................................ -->
+
+<!-- a single character from [ISO10646] -->
+<!NOTATION character
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Character//EN" >
+
+<!-- a character encoding, as per [RFC2045] -->
+<!NOTATION charset
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Charset//EN" >
+
+<!-- a space separated list of character encodings, as per [RFC2045] -->
+<!NOTATION charsets
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Charsets//EN" >
+
+<!-- media type, as per [RFC2045] -->
+<!NOTATION contentType
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: ContentType//EN" >
+
+<!-- comma-separated list of media types, as per [RFC2045] -->
+<!NOTATION contentTypes
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: ContentTypes//EN" >
+
+<!-- date and time information. ISO date format -->
+<!NOTATION datetime
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: Datetime//EN" >
+
+<!-- a language code, as per [RFC3066] -->
+<!NOTATION languageCode
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: LanguageCode//EN" >
+
+<!-- a Uniform Resource Identifier, see [URI] -->
+<!NOTATION uri
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: URI//EN" >
+
+<!-- a space-separated list of Uniform Resource Identifiers, see [URI] -->
+<!NOTATION uris
+    PUBLIC "-//W3C//NOTATION XHTML Datatype: URIs//EN" >
+
+<!-- end of xhtml-notations-1.mod -->
+]]>
+
+<!ENTITY % xhtml-datatypes.module "INCLUDE" >
+<![%xhtml-datatypes.module;[
+<!ENTITY % xhtml-datatypes.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN"
+            "xhtml-datatypes-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Datatypes Module  .............................................. -->
+<!-- file: xhtml-datatypes-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-datatypes-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Datatypes
+
+     defines containers for the following datatypes, many of
+     these imported from other specifications and standards.
+-->
+
+<!-- Length defined for cellpadding/cellspacing -->
+
+<!-- nn for pixels or nn% for percentage length -->
+<!ENTITY % Length.datatype "CDATA" >
+
+<!-- space-separated list of link types -->
+<!ENTITY % LinkTypes.datatype "NMTOKENS" >
+
+<!-- single or comma-separated list of media descriptors -->
+<!ENTITY % MediaDesc.datatype "CDATA" >
+
+<!-- pixel, percentage, or relative -->
+<!ENTITY % MultiLength.datatype "CDATA" >
+
+<!-- one or more digits (NUMBER) -->
+<!ENTITY % Number.datatype "CDATA" >
+
+<!-- integer representing length in pixels -->
+<!ENTITY % Pixels.datatype "CDATA" >
+
+<!-- script expression -->
+<!ENTITY % Script.datatype "CDATA" >
+
+<!-- textual content -->
+<!ENTITY % Text.datatype "CDATA" >
+
+<!-- Imported Datatypes ................................ -->
+
+<!-- a single character from [ISO10646] -->
+<!ENTITY % Character.datatype "CDATA" >
+
+<!-- a character encoding, as per [RFC2045] -->
+<!ENTITY % Charset.datatype "CDATA" >
+
+<!-- a space separated list of character encodings, as per [RFC2045] -->
+<!ENTITY % Charsets.datatype "CDATA" >
+
+<!-- media type, as per [RFC2045] -->
+<!ENTITY % ContentType.datatype "CDATA" >
+
+<!-- comma-separated list of media types, as per [RFC2045] -->
+<!ENTITY % ContentTypes.datatype "CDATA" >
+
+<!-- date and time information. ISO date format -->
+<!ENTITY % Datetime.datatype "CDATA" >
+
+<!-- formal public identifier, as per [ISO8879] -->
+<!ENTITY % FPI.datatype "CDATA" >
+
+<!-- a language code, as per [RFC3066] -->
+<!ENTITY % LanguageCode.datatype "NMTOKEN" >
+
+<!-- a Uniform Resource Identifier, see [URI] -->
+<!ENTITY % URI.datatype "CDATA" >
+
+<!-- a space-separated list of Uniform Resource Identifiers, see [URI] -->
+<!ENTITY % URIs.datatype "CDATA" >
+
+<!-- end of xhtml-datatypes-1.mod -->
+]]>
+
+<!-- placeholder for XLink support module -->
+<!ENTITY % xhtml-xlink.mod "" >
+
+
+<!ENTITY % xhtml-qname.module "INCLUDE" >
+<![%xhtml-qname.module;[
+<!ENTITY % xhtml-qname.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Qualified Names 1.0//EN"
+            "xhtml-qname-1.mod" >
+<!-- ....................................................................... -->
+<!-- XHTML Qname Module  ................................................... -->
+<!-- file: xhtml-qname-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Qualified Names 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-qname-1.mod"
+
+     Revisions:
+#2000-10-22: added qname declarations for ruby elements
+     ....................................................................... -->
+
+<!-- XHTML Qname (Qualified Name) Module
+
+     This module is contained in two parts, labeled Section 'A' and 'B':
+
+       Section A declares parameter entities to support namespace-
+       qualified names, namespace declarations, and name prefixing
+       for XHTML and extensions.
+
+       Section B declares parameter entities used to provide
+       namespace-qualified names for all XHTML element types:
+
+         %applet.qname;   the xmlns-qualified name for <applet>
+         %base.qname;     the xmlns-qualified name for <base>
+         ...
+
+     XHTML extensions would create a module similar to this one.
+     Included in the XHTML distribution is a template module
+     ('template-qname-1.mod') suitable for this purpose.
+-->
+
+<!-- Section A: XHTML XML Namespace Framework :::::::::::::::::::: -->
+
+<!-- 1. Declare a %XHTML.prefixed; conditional section keyword, used
+        to activate namespace prefixing. The default value should
+        inherit '%NS.prefixed;' from the DTD driver, so that unless
+        overridden, the default behaviour follows the overall DTD
+        prefixing scheme.
+-->
+<!ENTITY % NS.prefixed "IGNORE" >
+<!ENTITY % XHTML.prefixed "%NS.prefixed;" >
+
+<!-- 2. Declare a parameter entity (eg., %XHTML.xmlns;) containing
+        the URI reference used to identify the XHTML namespace:
+-->
+<!ENTITY % XHTML.xmlns  "http://www.w3.org/1999/xhtml" >
+
+<!-- 3. Declare parameter entities (eg., %XHTML.prefix;) containing
+        the default namespace prefix string(s) to use when prefixing
+        is enabled. This may be overridden in the DTD driver or the
+        internal subset of an document instance. If no default prefix
+        is desired, this may be declared as an empty string.
+
+     NOTE: As specified in [XMLNAMES], the namespace prefix serves
+     as a proxy for the URI reference, and is not in itself significant.
+-->
+<!ENTITY % XHTML.prefix  "" >
+
+<!-- 4. Declare parameter entities (eg., %XHTML.pfx;) containing the
+        colonized prefix(es) (eg., '%XHTML.prefix;:') used when
+        prefixing is active, an empty string when it is not.
+-->
+<![%XHTML.prefixed;[
+<!ENTITY % XHTML.pfx  "%XHTML.prefix;:" >
+]]>
+<!ENTITY % XHTML.pfx  "" >
+
+<!-- declare qualified name extensions here ............ -->
+<!ENTITY % xhtml-qname-extra.mod "" >
+
+
+<!-- 5. The parameter entity %XHTML.xmlns.extra.attrib; may be
+        redeclared to contain any non-XHTML namespace declaration
+        attributes for namespaces embedded in XHTML. The default
+        is an empty string.  XLink should be included here if used
+        in the DTD.
+-->
+<!ENTITY % XHTML.xmlns.extra.attrib "" >
+
+<!-- The remainder of Section A is only followed in XHTML, not extensions. -->
+
+<!-- Declare a parameter entity %NS.decl.attrib; containing
+     all XML Namespace declarations used in the DTD, plus the
+     xmlns declaration for XHTML, its form dependent on whether
+     prefixing is active.
+-->
+<![%XHTML.prefixed;[
+<!ENTITY % NS.decl.attrib
+     "xmlns:%XHTML.prefix;  %URI.datatype;   #FIXED '%XHTML.xmlns;'
+      %XHTML.xmlns.extra.attrib;"
+>
+]]>
+<!ENTITY % NS.decl.attrib
+     "%XHTML.xmlns.extra.attrib;"
+>
+
+<!-- This is a placeholder for future XLink support.
+-->
+<!ENTITY % XLINK.xmlns.attrib "" >
+
+<!-- Declare a parameter entity %NS.decl.attrib; containing all
+     XML namespace declaration attributes used by XHTML, including
+     a default xmlns attribute when prefixing is inactive.
+-->
+<![%XHTML.prefixed;[
+<!ENTITY % XHTML.xmlns.attrib
+     "%NS.decl.attrib;
+      %XLINK.xmlns.attrib;"
+>
+]]>
+<!ENTITY % XHTML.xmlns.attrib
+     "xmlns        %URI.datatype;           #FIXED '%XHTML.xmlns;'
+      %XLINK.xmlns.attrib;"
+>
+
+<!-- placeholder for qualified name redeclarations -->
+<!ENTITY % xhtml-qname.redecl "" >
+
+
+<!-- Section B: XHTML Qualified Names ::::::::::::::::::::::::::::: -->
+
+<!-- 6. This section declares parameter entities used to provide
+        namespace-qualified names for all XHTML element types.
+-->
+
+<!-- module:  xhtml-applet-1.mod -->
+<!ENTITY % applet.qname  "%XHTML.pfx;applet" >
+
+<!-- module:  xhtml-base-1.mod -->
+<!ENTITY % base.qname    "%XHTML.pfx;base" >
+
+<!-- module:  xhtml-bdo-1.mod -->
+<!ENTITY % bdo.qname     "%XHTML.pfx;bdo" >
+
+<!-- module:  xhtml-blkphras-1.mod -->
+<!ENTITY % address.qname "%XHTML.pfx;address" >
+<!ENTITY % blockquote.qname  "%XHTML.pfx;blockquote" >
+<!ENTITY % pre.qname     "%XHTML.pfx;pre" >
+<!ENTITY % h1.qname      "%XHTML.pfx;h1" >
+<!ENTITY % h2.qname      "%XHTML.pfx;h2" >
+<!ENTITY % h3.qname      "%XHTML.pfx;h3" >
+<!ENTITY % h4.qname      "%XHTML.pfx;h4" >
+<!ENTITY % h5.qname      "%XHTML.pfx;h5" >
+<!ENTITY % h6.qname      "%XHTML.pfx;h6" >
+
+<!-- module:  xhtml-blkpres-1.mod -->
+<!ENTITY % hr.qname      "%XHTML.pfx;hr" >
+
+<!-- module:  xhtml-blkstruct-1.mod -->
+<!ENTITY % div.qname     "%XHTML.pfx;div" >
+<!ENTITY % p.qname       "%XHTML.pfx;p" >
+
+<!-- module:  xhtml-edit-1.mod -->
+<!ENTITY % ins.qname     "%XHTML.pfx;ins" >
+<!ENTITY % del.qname     "%XHTML.pfx;del" >
+
+<!-- module:  xhtml-form-1.mod -->
+<!ENTITY % form.qname    "%XHTML.pfx;form" >
+<!ENTITY % label.qname   "%XHTML.pfx;label" >
+<!ENTITY % input.qname   "%XHTML.pfx;input" >
+<!ENTITY % select.qname  "%XHTML.pfx;select" >
+<!ENTITY % optgroup.qname  "%XHTML.pfx;optgroup" >
+<!ENTITY % option.qname  "%XHTML.pfx;option" >
+<!ENTITY % textarea.qname  "%XHTML.pfx;textarea" >
+<!ENTITY % fieldset.qname  "%XHTML.pfx;fieldset" >
+<!ENTITY % legend.qname  "%XHTML.pfx;legend" >
+<!ENTITY % button.qname  "%XHTML.pfx;button" >
+
+<!-- module:  xhtml-hypertext-1.mod -->
+<!ENTITY % a.qname       "%XHTML.pfx;a" >
+
+<!-- module:  xhtml-image-1.mod -->
+<!ENTITY % img.qname     "%XHTML.pfx;img" >
+
+<!-- module:  xhtml-inlphras-1.mod -->
+<!ENTITY % abbr.qname    "%XHTML.pfx;abbr" >
+<!ENTITY % acronym.qname "%XHTML.pfx;acronym" >
+<!ENTITY % cite.qname    "%XHTML.pfx;cite" >
+<!ENTITY % code.qname    "%XHTML.pfx;code" >
+<!ENTITY % dfn.qname     "%XHTML.pfx;dfn" >
+<!ENTITY % em.qname      "%XHTML.pfx;em" >
+<!ENTITY % kbd.qname     "%XHTML.pfx;kbd" >
+<!ENTITY % q.qname       "%XHTML.pfx;q" >
+<!ENTITY % samp.qname    "%XHTML.pfx;samp" >
+<!ENTITY % strong.qname  "%XHTML.pfx;strong" >
+<!ENTITY % var.qname     "%XHTML.pfx;var" >
+
+<!-- module:  xhtml-inlpres-1.mod -->
+<!ENTITY % b.qname       "%XHTML.pfx;b" >
+<!ENTITY % big.qname     "%XHTML.pfx;big" >
+<!ENTITY % i.qname       "%XHTML.pfx;i" >
+<!ENTITY % small.qname   "%XHTML.pfx;small" >
+<!ENTITY % sub.qname     "%XHTML.pfx;sub" >
+<!ENTITY % sup.qname     "%XHTML.pfx;sup" >
+<!ENTITY % tt.qname      "%XHTML.pfx;tt" >
+
+<!-- module:  xhtml-inlstruct-1.mod -->
+<!ENTITY % br.qname      "%XHTML.pfx;br" >
+<!ENTITY % span.qname    "%XHTML.pfx;span" >
+
+<!-- module:  xhtml-ismap-1.mod (also csismap, ssismap) -->
+<!ENTITY % map.qname     "%XHTML.pfx;map" >
+<!ENTITY % area.qname    "%XHTML.pfx;area" >
+
+<!-- module:  xhtml-link-1.mod -->
+<!ENTITY % link.qname    "%XHTML.pfx;link" >
+
+<!-- module:  xhtml-list-1.mod -->
+<!ENTITY % dl.qname      "%XHTML.pfx;dl" >
+<!ENTITY % dt.qname      "%XHTML.pfx;dt" >
+<!ENTITY % dd.qname      "%XHTML.pfx;dd" >
+<!ENTITY % ol.qname      "%XHTML.pfx;ol" >
+<!ENTITY % ul.qname      "%XHTML.pfx;ul" >
+<!ENTITY % li.qname      "%XHTML.pfx;li" >
+
+<!-- module:  xhtml-meta-1.mod -->
+<!ENTITY % meta.qname    "%XHTML.pfx;meta" >
+
+<!-- module:  xhtml-param-1.mod -->
+<!ENTITY % param.qname   "%XHTML.pfx;param" >
+
+<!-- module:  xhtml-object-1.mod -->
+<!ENTITY % object.qname  "%XHTML.pfx;object" >
+
+<!-- module:  xhtml-script-1.mod -->
+<!ENTITY % script.qname  "%XHTML.pfx;script" >
+<!ENTITY % noscript.qname  "%XHTML.pfx;noscript" >
+
+<!-- module:  xhtml-struct-1.mod -->
+<!ENTITY % html.qname    "%XHTML.pfx;html" >
+<!ENTITY % head.qname    "%XHTML.pfx;head" >
+<!ENTITY % title.qname   "%XHTML.pfx;title" >
+<!ENTITY % body.qname    "%XHTML.pfx;body" >
+
+<!-- module:  xhtml-style-1.mod -->
+<!ENTITY % style.qname   "%XHTML.pfx;style" >
+
+<!-- module:  xhtml-table-1.mod -->
+<!ENTITY % table.qname   "%XHTML.pfx;table" >
+<!ENTITY % caption.qname "%XHTML.pfx;caption" >
+<!ENTITY % thead.qname   "%XHTML.pfx;thead" >
+<!ENTITY % tfoot.qname   "%XHTML.pfx;tfoot" >
+<!ENTITY % tbody.qname   "%XHTML.pfx;tbody" >
+<!ENTITY % colgroup.qname  "%XHTML.pfx;colgroup" >
+<!ENTITY % col.qname     "%XHTML.pfx;col" >
+<!ENTITY % tr.qname      "%XHTML.pfx;tr" >
+<!ENTITY % th.qname      "%XHTML.pfx;th" >
+<!ENTITY % td.qname      "%XHTML.pfx;td" >
+
+<!-- module:  xhtml-ruby-1.mod -->
+
+<!ENTITY % ruby.qname    "%XHTML.pfx;ruby" >
+<!ENTITY % rbc.qname     "%XHTML.pfx;rbc" >
+<!ENTITY % rtc.qname     "%XHTML.pfx;rtc" >
+<!ENTITY % rb.qname      "%XHTML.pfx;rb" >
+<!ENTITY % rt.qname      "%XHTML.pfx;rt" >
+<!ENTITY % rp.qname      "%XHTML.pfx;rp" >
+
+<!-- Provisional XHTML 2.0 Qualified Names  ...................... -->
+
+<!-- module:  xhtml-image-2.mod -->
+<!ENTITY % alt.qname     "%XHTML.pfx;alt" >
+
+<!-- end of xhtml-qname-1.mod -->
+]]>
+
+<!ENTITY % xhtml-events.module "IGNORE" >
+<![%xhtml-events.module;[
+<!ENTITY % xhtml-events.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Intrinsic Events 1.0//EN"
+            "xhtml-events-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Intrinsic Events Module  ....................................... -->
+<!-- file: xhtml-events-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Intrinsic Events 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-events-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Intrinsic Event Attributes
+
+     These are the event attributes defined in HTML 4.0,
+     Section 18.2.3 "Intrinsic Events". This module must be
+     instantiated prior to the Attributes Module but after
+     the Datatype Module in the Modular Framework module.
+
+    "Note: Authors of HTML documents are advised that changes
+     are likely to occur in the realm of intrinsic events
+     (e.g., how scripts are bound to events). Research in
+     this realm is carried on by members of the W3C Document
+     Object Model Working Group (see the W3C Web site at
+     http://www.w3.org/ for more information)."
+-->
+<!-- NOTE: Because the ATTLIST declarations in this module occur
+     before their respective ELEMENT declarations in other
+     modules, there may be a dependency on this module that
+     should be considered if any of the parameter entities used
+     for element type names (eg., %a.qname;) are redeclared.
+-->
+
+<!ENTITY % Events.attrib
+     "onclick      %Script.datatype;        #IMPLIED
+      ondblclick   %Script.datatype;        #IMPLIED
+      onmousedown  %Script.datatype;        #IMPLIED
+      onmouseup    %Script.datatype;        #IMPLIED
+      onmouseover  %Script.datatype;        #IMPLIED
+      onmousemove  %Script.datatype;        #IMPLIED
+      onmouseout   %Script.datatype;        #IMPLIED
+      onkeypress   %Script.datatype;        #IMPLIED
+      onkeydown    %Script.datatype;        #IMPLIED
+      onkeyup      %Script.datatype;        #IMPLIED"
+>
+
+<!-- additional attributes on anchor element
+-->
+<!ATTLIST %a.qname;
+     onfocus      %Script.datatype;         #IMPLIED
+     onblur       %Script.datatype;         #IMPLIED
+>
+
+<!-- additional attributes on form element
+-->
+<!ATTLIST %form.qname;
+      onsubmit     %Script.datatype;        #IMPLIED
+      onreset      %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on label element
+-->
+<!ATTLIST %label.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on input element
+-->
+<!ATTLIST %input.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+      onselect     %Script.datatype;        #IMPLIED
+      onchange     %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on select element
+-->
+<!ATTLIST %select.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+      onchange     %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on textarea element
+-->
+<!ATTLIST %textarea.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+      onselect     %Script.datatype;        #IMPLIED
+      onchange     %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on button element
+-->
+<!ATTLIST %button.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on body element
+-->
+<!ATTLIST %body.qname;
+      onload       %Script.datatype;        #IMPLIED
+      onunload     %Script.datatype;        #IMPLIED
+>
+
+<!-- additional attributes on area element
+-->
+<!ATTLIST %area.qname;
+      onfocus      %Script.datatype;        #IMPLIED
+      onblur       %Script.datatype;        #IMPLIED
+>
+
+<!-- end of xhtml-events-1.mod -->
+]]>
+
+<!ENTITY % xhtml-attribs.module "INCLUDE" >
+<![%xhtml-attribs.module;[
+<!ENTITY % xhtml-attribs.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Common Attributes 1.0//EN"
+            "xhtml-attribs-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Common Attributes Module  ...................................... -->
+<!-- file: xhtml-attribs-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Common Attributes 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-attribs-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Common Attributes
+
+     This module declares many of the common attributes for the XHTML DTD.
+     %NS.decl.attrib; is declared in the XHTML Qname module.
+-->
+
+<!ENTITY % id.attrib
+     "id           ID                       #IMPLIED"
+>
+
+<!ENTITY % class.attrib
+     "class        NMTOKENS                 #IMPLIED"
+>
+
+<!ENTITY % title.attrib
+     "title        %Text.datatype;          #IMPLIED"
+>
+
+<!ENTITY % Core.extra.attrib "" >
+
+<!ENTITY % Core.attrib
+     "%XHTML.xmlns.attrib;
+      %id.attrib;
+      %class.attrib;
+      %title.attrib;
+      %Core.extra.attrib;"
+>
+
+<!ENTITY % lang.attrib
+     "xml:lang     %LanguageCode.datatype;  #IMPLIED"
+>
+
+<![%XHTML.bidi;[
+<!ENTITY % dir.attrib
+     "dir          ( ltr | rtl )            #IMPLIED"
+>
+
+<!ENTITY % I18n.attrib
+     "%dir.attrib;
+      %lang.attrib;"
+>
+
+]]>
+<!ENTITY % I18n.attrib
+     "%lang.attrib;"
+>
+
+<!ENTITY % Common.extra.attrib "" >
+
+<!-- intrinsic event attributes declared previously
+-->
+<!ENTITY % Events.attrib "" >
+
+<!ENTITY % Common.attrib
+     "%Core.attrib;
+      %I18n.attrib;
+      %Events.attrib;
+      %Common.extra.attrib;"
+>
+
+<!-- end of xhtml-attribs-1.mod -->
+]]>
+
+<!-- placeholder for content model redeclarations -->
+<!ENTITY % xhtml-model.redecl "" >
+
+
+<!ENTITY % xhtml-model.module "INCLUDE" >
+<![%xhtml-model.module;[
+<!-- instantiate the Document Model module declared in the DTD driver
+-->
+<!-- ....................................................................... -->
+<!-- XHTML 1.1 Document Model Module  ...................................... -->
+<!-- file: xhtml11-model-1.mod
+
+     This is XHTML 1.1, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2000 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML 1.1 Document Model 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml11/DTD/xhtml11-model-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- XHTML 1.1 Document Model
+
+     This module describes the groupings of elements that make up
+     common content models for XHTML elements.
+
+     XHTML has three basic content models:
+
+         %Inline.mix;  character-level elements
+         %Block.mix;   block-like elements, eg., paragraphs and lists
+         %Flow.mix;    any block or inline elements
+
+     Any parameter entities declared in this module may be used
+     to create element content models, but the above three are
+     considered 'global' (insofar as that term applies here).
+
+     The reserved word '#PCDATA' (indicating a text string) is now
+     included explicitly with each element declaration that is
+     declared as mixed content, as XML requires that this token
+     occur first in a content model specification.
+-->
+<!-- Extending the Model
+
+     While in some cases this module may need to be rewritten to
+     accommodate changes to the document model, minor extensions
+     may be accomplished by redeclaring any of the three *.extra;
+     parameter entities to contain extension element types as follows:
+
+         %Misc.extra;    whose parent may be any block or
+                         inline element.
+
+         %Inline.extra;  whose parent may be any inline element.
+
+         %Block.extra;   whose parent may be any block element.
+
+     If used, these parameter entities must be an OR-separated
+     list beginning with an OR separator ("|"), eg., "| a | b | c"
+
+     All block and inline *.class parameter entities not part
+     of the *struct.class classes begin with "| " to allow for
+     exclusion from mixes.
+-->
+
+<!-- ..............  Optional Elements in head  .................. -->
+
+<!ENTITY % HeadOpts.mix
+     "( %script.qname; | %style.qname; | %meta.qname;
+      | %link.qname; | %object.qname; )*"
+>
+
+<!-- .................  Miscellaneous Elements  .................. -->
+
+<!-- ins and del are used to denote editing changes
+-->
+<!ENTITY % Edit.class "| %ins.qname; | %del.qname;" >
+
+<!-- script and noscript are used to contain scripts
+     and alternative content
+-->
+<!ENTITY % Script.class "| %script.qname; | %noscript.qname;" >
+
+<!ENTITY % Misc.extra "" >
+
+<!-- These elements are neither block nor inline, and can
+     essentially be used anywhere in the document body.
+-->
+<!ENTITY % Misc.class
+     "%Edit.class;
+      %Script.class;
+      %Misc.extra;"
+>
+
+<!-- ....................  Inline Elements  ...................... -->
+
+<!ENTITY % InlStruct.class "%br.qname; | %span.qname;" >
+
+<!ENTITY % InlPhras.class
+     "| %em.qname; | %strong.qname; | %dfn.qname; | %code.qname;
+      | %samp.qname; | %kbd.qname; | %var.qname; | %cite.qname;
+      | %abbr.qname; | %acronym.qname; | %q.qname;" >
+
+<!ENTITY % InlPres.class
+     "| %tt.qname; | %i.qname; | %b.qname; | %big.qname;
+      | %small.qname; | %sub.qname; | %sup.qname;" >
+
+<!ENTITY % I18n.class "| %bdo.qname;" >
+
+<!ENTITY % Anchor.class "| %a.qname;" >
+
+<!ENTITY % InlSpecial.class
+     "| %img.qname; | %map.qname;
+      | %object.qname;" >
+
+<!ENTITY % InlForm.class
+     "| %input.qname; | %select.qname; | %textarea.qname;
+      | %label.qname; | %button.qname;" >
+
+<!ENTITY % Inline.extra "" >
+
+<!ENTITY % Ruby.class "| %ruby.qname;" >
+
+<!-- %Inline.class; includes all inline elements,
+     used as a component in mixes
+-->
+<!ENTITY % Inline.class
+     "%InlStruct.class;
+      %InlPhras.class;
+      %InlPres.class;
+      %I18n.class;
+      %Anchor.class;
+      %InlSpecial.class;
+      %InlForm.class;
+      %Ruby.class;
+      %Inline.extra;"
+>
+
+<!-- %InlNoRuby.class; includes all inline elements
+     except ruby, used as a component in mixes
+-->
+<!ENTITY % InlNoRuby.class
+     "%InlStruct.class;
+      %InlPhras.class;
+      %InlPres.class;
+      %I18n.class;
+      %Anchor.class;
+      %InlSpecial.class;
+      %InlForm.class;
+      %Inline.extra;"
+>
+
+<!-- %NoRuby.content; includes all inlines except ruby
+-->
+<!ENTITY % NoRuby.content
+     "( #PCDATA
+      | %InlNoRuby.class;
+      %Misc.class; )*"
+>
+
+<!-- %InlNoAnchor.class; includes all non-anchor inlines,
+     used as a component in mixes
+-->
+<!ENTITY % InlNoAnchor.class
+     "%InlStruct.class;
+      %InlPhras.class;
+      %InlPres.class;
+      %I18n.class;
+      %InlSpecial.class;
+      %InlForm.class;
+      %Ruby.class;
+      %Inline.extra;"
+>
+
+<!-- %InlNoAnchor.mix; includes all non-anchor inlines
+-->
+<!ENTITY % InlNoAnchor.mix
+     "%InlNoAnchor.class;
+      %Misc.class;"
+>
+
+<!-- %Inline.mix; includes all inline elements, including %Misc.class;
+-->
+<!ENTITY % Inline.mix
+     "%Inline.class;
+      %Misc.class;"
+>
+
+<!-- .....................  Block Elements  ...................... -->
+
+<!-- In the HTML 4.0 DTD, heading and list elements were included
+     in the %block; parameter entity. The %Heading.class; and
+     %List.class; parameter entities must now be included explicitly
+     on element declarations where desired.
+-->
+
+<!ENTITY % Heading.class
+     "%h1.qname; | %h2.qname; | %h3.qname;
+      | %h4.qname; | %h5.qname; | %h6.qname;" >
+
+<!ENTITY % List.class "%ul.qname; | %ol.qname; | %dl.qname;" >
+
+<!ENTITY % Table.class "| %table.qname;" >
+
+<!ENTITY % Form.class  "| %form.qname;" >
+
+<!ENTITY % Fieldset.class  "| %fieldset.qname;" >
+
+<!ENTITY % BlkStruct.class "%p.qname; | %div.qname;" >
+
+<!ENTITY % BlkPhras.class
+     "| %pre.qname; | %blockquote.qname; | %address.qname;" >
+
+<!ENTITY % BlkPres.class "| %hr.qname;" >
+
+<!ENTITY % BlkSpecial.class
+     "%Table.class;
+      %Form.class;
+      %Fieldset.class;"
+>
+
+<!ENTITY % Block.extra "" >
+
+<!-- %Block.class; includes all block elements,
+     used as an component in mixes
+-->
+<!ENTITY % Block.class
+     "%BlkStruct.class;
+      %BlkPhras.class;
+      %BlkPres.class;
+      %BlkSpecial.class;
+      %Block.extra;"
+>
+
+<!-- %Block.mix; includes all block elements plus %Misc.class;
+-->
+<!ENTITY % Block.mix
+     "%Heading.class;
+      | %List.class;
+      | %Block.class;
+      %Misc.class;"
+>
+
+<!-- ................  All Content Elements  .................. -->
+
+<!-- %Flow.mix; includes all text content, block and inline
+-->
+<!ENTITY % Flow.mix
+     "%Heading.class;
+      | %List.class;
+      | %Block.class;
+      | %Inline.class;
+      %Misc.class;"
+>
+
+<!-- end of xhtml11-model-1.mod -->
+]]>
+
+<!ENTITY % xhtml-charent.module "INCLUDE" >
+<![%xhtml-charent.module;[
+<!ENTITY % xhtml-charent.mod
+     PUBLIC "-//W3C//ENTITIES XHTML Character Entities 1.0//EN"
+            "xhtml-charent-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Character Entities Module  ......................................... -->
+<!-- file: xhtml-charent-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ENTITIES XHTML Character Entities 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-charent-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Character Entities for XHTML
+
+     This module declares the set of character entities for XHTML,
+     including the Latin 1, Symbol and Special character collections.
+-->
+
+<!ENTITY % xhtml-lat1
+    PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+           "xhtml-lat1.ent" >
+<!-- Portions (C) International Organization for Standardization 1986
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+<!-- Character entity set. Typical invocation:
+    <!ENTITY % HTMLlat1 PUBLIC
+       "-//W3C//ENTITIES Latin 1 for XHTML//EN"
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
+    %HTMLlat1;
+-->
+
+<!ENTITY nbsp   "&#160;"> <!-- no-break space = non-breaking space,
+                                  U+00A0 ISOnum -->
+<!ENTITY iexcl  "&#161;"> <!-- inverted exclamation mark, U+00A1 ISOnum -->
+<!ENTITY cent   "&#162;"> <!-- cent sign, U+00A2 ISOnum -->
+<!ENTITY pound  "&#163;"> <!-- pound sign, U+00A3 ISOnum -->
+<!ENTITY curren "&#164;"> <!-- currency sign, U+00A4 ISOnum -->
+<!ENTITY yen    "&#165;"> <!-- yen sign = yuan sign, U+00A5 ISOnum -->
+<!ENTITY brvbar "&#166;"> <!-- broken bar = broken vertical bar,
+                                  U+00A6 ISOnum -->
+<!ENTITY sect   "&#167;"> <!-- section sign, U+00A7 ISOnum -->
+<!ENTITY uml    "&#168;"> <!-- diaeresis = spacing diaeresis,
+                                  U+00A8 ISOdia -->
+<!ENTITY copy   "&#169;"> <!-- copyright sign, U+00A9 ISOnum -->
+<!ENTITY ordf   "&#170;"> <!-- feminine ordinal indicator, U+00AA ISOnum -->
+<!ENTITY laquo  "&#171;"> <!-- left-pointing double angle quotation mark
+                                  = left pointing guillemet, U+00AB ISOnum -->
+<!ENTITY not    "&#172;"> <!-- not sign = discretionary hyphen,
+                                  U+00AC ISOnum -->
+<!ENTITY shy    "&#173;"> <!-- soft hyphen = discretionary hyphen,
+                                  U+00AD ISOnum -->
+<!ENTITY reg    "&#174;"> <!-- registered sign = registered trade mark sign,
+                                  U+00AE ISOnum -->
+<!ENTITY macr   "&#175;"> <!-- macron = spacing macron = overline
+                                  = APL overbar, U+00AF ISOdia -->
+<!ENTITY deg    "&#176;"> <!-- degree sign, U+00B0 ISOnum -->
+<!ENTITY plusmn "&#177;"> <!-- plus-minus sign = plus-or-minus sign,
+                                  U+00B1 ISOnum -->
+<!ENTITY sup2   "&#178;"> <!-- superscript two = superscript digit two
+                                  = squared, U+00B2 ISOnum -->
+<!ENTITY sup3   "&#179;"> <!-- superscript three = superscript digit three
+                                  = cubed, U+00B3 ISOnum -->
+<!ENTITY acute  "&#180;"> <!-- acute accent = spacing acute,
+                                  U+00B4 ISOdia -->
+<!ENTITY micro  "&#181;"> <!-- micro sign, U+00B5 ISOnum -->
+<!ENTITY para   "&#182;"> <!-- pilcrow sign = paragraph sign,
+                                  U+00B6 ISOnum -->
+<!ENTITY middot "&#183;"> <!-- middle dot = Georgian comma
+                                  = Greek middle dot, U+00B7 ISOnum -->
+<!ENTITY cedil  "&#184;"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia -->
+<!ENTITY sup1   "&#185;"> <!-- superscript one = superscript digit one,
+                                  U+00B9 ISOnum -->
+<!ENTITY ordm   "&#186;"> <!-- masculine ordinal indicator,
+                                  U+00BA ISOnum -->
+<!ENTITY raquo  "&#187;"> <!-- right-pointing double angle quotation mark
+                                  = right pointing guillemet, U+00BB ISOnum -->
+<!ENTITY frac14 "&#188;"> <!-- vulgar fraction one quarter
+                                  = fraction one quarter, U+00BC ISOnum -->
+<!ENTITY frac12 "&#189;"> <!-- vulgar fraction one half
+                                  = fraction one half, U+00BD ISOnum -->
+<!ENTITY frac34 "&#190;"> <!-- vulgar fraction three quarters
+                                  = fraction three quarters, U+00BE ISOnum -->
+<!ENTITY iquest "&#191;"> <!-- inverted question mark
+                                  = turned question mark, U+00BF ISOnum -->
+<!ENTITY Agrave "&#192;"> <!-- latin capital letter A with grave
+                                  = latin capital letter A grave,
+                                  U+00C0 ISOlat1 -->
+<!ENTITY Aacute "&#193;"> <!-- latin capital letter A with acute,
+                                  U+00C1 ISOlat1 -->
+<!ENTITY Acirc  "&#194;"> <!-- latin capital letter A with circumflex,
+                                  U+00C2 ISOlat1 -->
+<!ENTITY Atilde "&#195;"> <!-- latin capital letter A with tilde,
+                                  U+00C3 ISOlat1 -->
+<!ENTITY Auml   "&#196;"> <!-- latin capital letter A with diaeresis,
+                                  U+00C4 ISOlat1 -->
+<!ENTITY Aring  "&#197;"> <!-- latin capital letter A with ring above
+                                  = latin capital letter A ring,
+                                  U+00C5 ISOlat1 -->
+<!ENTITY AElig  "&#198;"> <!-- latin capital letter AE
+                                  = latin capital ligature AE,
+                                  U+00C6 ISOlat1 -->
+<!ENTITY Ccedil "&#199;"> <!-- latin capital letter C with cedilla,
+                                  U+00C7 ISOlat1 -->
+<!ENTITY Egrave "&#200;"> <!-- latin capital letter E with grave,
+                                  U+00C8 ISOlat1 -->
+<!ENTITY Eacute "&#201;"> <!-- latin capital letter E with acute,
+                                  U+00C9 ISOlat1 -->
+<!ENTITY Ecirc  "&#202;"> <!-- latin capital letter E with circumflex,
+                                  U+00CA ISOlat1 -->
+<!ENTITY Euml   "&#203;"> <!-- latin capital letter E with diaeresis,
+                                  U+00CB ISOlat1 -->
+<!ENTITY Igrave "&#204;"> <!-- latin capital letter I with grave,
+                                  U+00CC ISOlat1 -->
+<!ENTITY Iacute "&#205;"> <!-- latin capital letter I with acute,
+                                  U+00CD ISOlat1 -->
+<!ENTITY Icirc  "&#206;"> <!-- latin capital letter I with circumflex,
+                                  U+00CE ISOlat1 -->
+<!ENTITY Iuml   "&#207;"> <!-- latin capital letter I with diaeresis,
+                                  U+00CF ISOlat1 -->
+<!ENTITY ETH    "&#208;"> <!-- latin capital letter ETH, U+00D0 ISOlat1 -->
+<!ENTITY Ntilde "&#209;"> <!-- latin capital letter N with tilde,
+                                  U+00D1 ISOlat1 -->
+<!ENTITY Ograve "&#210;"> <!-- latin capital letter O with grave,
+                                  U+00D2 ISOlat1 -->
+<!ENTITY Oacute "&#211;"> <!-- latin capital letter O with acute,
+                                  U+00D3 ISOlat1 -->
+<!ENTITY Ocirc  "&#212;"> <!-- latin capital letter O with circumflex,
+                                  U+00D4 ISOlat1 -->
+<!ENTITY Otilde "&#213;"> <!-- latin capital letter O with tilde,
+                                  U+00D5 ISOlat1 -->
+<!ENTITY Ouml   "&#214;"> <!-- latin capital letter O with diaeresis,
+                                  U+00D6 ISOlat1 -->
+<!ENTITY times  "&#215;"> <!-- multiplication sign, U+00D7 ISOnum -->
+<!ENTITY Oslash "&#216;"> <!-- latin capital letter O with stroke
+                                  = latin capital letter O slash,
+                                  U+00D8 ISOlat1 -->
+<!ENTITY Ugrave "&#217;"> <!-- latin capital letter U with grave,
+                                  U+00D9 ISOlat1 -->
+<!ENTITY Uacute "&#218;"> <!-- latin capital letter U with acute,
+                                  U+00DA ISOlat1 -->
+<!ENTITY Ucirc  "&#219;"> <!-- latin capital letter U with circumflex,
+                                  U+00DB ISOlat1 -->
+<!ENTITY Uuml   "&#220;"> <!-- latin capital letter U with diaeresis,
+                                  U+00DC ISOlat1 -->
+<!ENTITY Yacute "&#221;"> <!-- latin capital letter Y with acute,
+                                  U+00DD ISOlat1 -->
+<!ENTITY THORN  "&#222;"> <!-- latin capital letter THORN,
+                                  U+00DE ISOlat1 -->
+<!ENTITY szlig  "&#223;"> <!-- latin small letter sharp s = ess-zed,
+                                  U+00DF ISOlat1 -->
+<!ENTITY agrave "&#224;"> <!-- latin small letter a with grave
+                                  = latin small letter a grave,
+                                  U+00E0 ISOlat1 -->
+<!ENTITY aacute "&#225;"> <!-- latin small letter a with acute,
+                                  U+00E1 ISOlat1 -->
+<!ENTITY acirc  "&#226;"> <!-- latin small letter a with circumflex,
+                                  U+00E2 ISOlat1 -->
+<!ENTITY atilde "&#227;"> <!-- latin small letter a with tilde,
+                                  U+00E3 ISOlat1 -->
+<!ENTITY auml   "&#228;"> <!-- latin small letter a with diaeresis,
+                                  U+00E4 ISOlat1 -->
+<!ENTITY aring  "&#229;"> <!-- latin small letter a with ring above
+                                  = latin small letter a ring,
+                                  U+00E5 ISOlat1 -->
+<!ENTITY aelig  "&#230;"> <!-- latin small letter ae
+                                  = latin small ligature ae, U+00E6 ISOlat1 -->
+<!ENTITY ccedil "&#231;"> <!-- latin small letter c with cedilla,
+                                  U+00E7 ISOlat1 -->
+<!ENTITY egrave "&#232;"> <!-- latin small letter e with grave,
+                                  U+00E8 ISOlat1 -->
+<!ENTITY eacute "&#233;"> <!-- latin small letter e with acute,
+                                  U+00E9 ISOlat1 -->
+<!ENTITY ecirc  "&#234;"> <!-- latin small letter e with circumflex,
+                                  U+00EA ISOlat1 -->
+<!ENTITY euml   "&#235;"> <!-- latin small letter e with diaeresis,
+                                  U+00EB ISOlat1 -->
+<!ENTITY igrave "&#236;"> <!-- latin small letter i with grave,
+                                  U+00EC ISOlat1 -->
+<!ENTITY iacute "&#237;"> <!-- latin small letter i with acute,
+                                  U+00ED ISOlat1 -->
+<!ENTITY icirc  "&#238;"> <!-- latin small letter i with circumflex,
+                                  U+00EE ISOlat1 -->
+<!ENTITY iuml   "&#239;"> <!-- latin small letter i with diaeresis,
+                                  U+00EF ISOlat1 -->
+<!ENTITY eth    "&#240;"> <!-- latin small letter eth, U+00F0 ISOlat1 -->
+<!ENTITY ntilde "&#241;"> <!-- latin small letter n with tilde,
+                                  U+00F1 ISOlat1 -->
+<!ENTITY ograve "&#242;"> <!-- latin small letter o with grave,
+                                  U+00F2 ISOlat1 -->
+<!ENTITY oacute "&#243;"> <!-- latin small letter o with acute,
+                                  U+00F3 ISOlat1 -->
+<!ENTITY ocirc  "&#244;"> <!-- latin small letter o with circumflex,
+                                  U+00F4 ISOlat1 -->
+<!ENTITY otilde "&#245;"> <!-- latin small letter o with tilde,
+                                  U+00F5 ISOlat1 -->
+<!ENTITY ouml   "&#246;"> <!-- latin small letter o with diaeresis,
+                                  U+00F6 ISOlat1 -->
+<!ENTITY divide "&#247;"> <!-- division sign, U+00F7 ISOnum -->
+<!ENTITY oslash "&#248;"> <!-- latin small letter o with stroke,
+                                  = latin small letter o slash,
+                                  U+00F8 ISOlat1 -->
+<!ENTITY ugrave "&#249;"> <!-- latin small letter u with grave,
+                                  U+00F9 ISOlat1 -->
+<!ENTITY uacute "&#250;"> <!-- latin small letter u with acute,
+                                  U+00FA ISOlat1 -->
+<!ENTITY ucirc  "&#251;"> <!-- latin small letter u with circumflex,
+                                  U+00FB ISOlat1 -->
+<!ENTITY uuml   "&#252;"> <!-- latin small letter u with diaeresis,
+                                  U+00FC ISOlat1 -->
+<!ENTITY yacute "&#253;"> <!-- latin small letter y with acute,
+                                  U+00FD ISOlat1 -->
+<!ENTITY thorn  "&#254;"> <!-- latin small letter thorn with,
+                                  U+00FE ISOlat1 -->
+<!ENTITY yuml   "&#255;"> <!-- latin small letter y with diaeresis,
+                                  U+00FF ISOlat1 -->
+
+
+<!ENTITY % xhtml-symbol
+    PUBLIC "-//W3C//ENTITIES Symbols for XHTML//EN"
+           "xhtml-symbol.ent" >
+<!-- Mathematical, Greek and Symbolic characters for HTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLsymbol PUBLIC
+        "-//W3C//ENTITIES Symbols for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent">
+     %HTMLsymbol;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- Latin Extended-B -->
+<!ENTITY fnof     "&#402;"> <!-- latin small f with hook = function
+                                    = florin, U+0192 ISOtech -->
+
+<!-- Greek -->
+<!ENTITY Alpha    "&#913;"> <!-- greek capital letter alpha, U+0391 -->
+<!ENTITY Beta     "&#914;"> <!-- greek capital letter beta, U+0392 -->
+<!ENTITY Gamma    "&#915;"> <!-- greek capital letter gamma,
+                                    U+0393 ISOgrk3 -->
+<!ENTITY Delta    "&#916;"> <!-- greek capital letter delta,
+                                    U+0394 ISOgrk3 -->
+<!ENTITY Epsilon  "&#917;"> <!-- greek capital letter epsilon, U+0395 -->
+<!ENTITY Zeta     "&#918;"> <!-- greek capital letter zeta, U+0396 -->
+<!ENTITY Eta      "&#919;"> <!-- greek capital letter eta, U+0397 -->
+<!ENTITY Theta    "&#920;"> <!-- greek capital letter theta,
+                                    U+0398 ISOgrk3 -->
+<!ENTITY Iota     "&#921;"> <!-- greek capital letter iota, U+0399 -->
+<!ENTITY Kappa    "&#922;"> <!-- greek capital letter kappa, U+039A -->
+<!ENTITY Lambda   "&#923;"> <!-- greek capital letter lambda,
+                                    U+039B ISOgrk3 -->
+<!ENTITY Mu       "&#924;"> <!-- greek capital letter mu, U+039C -->
+<!ENTITY Nu       "&#925;"> <!-- greek capital letter nu, U+039D -->
+<!ENTITY Xi       "&#926;"> <!-- greek capital letter xi, U+039E ISOgrk3 -->
+<!ENTITY Omicron  "&#927;"> <!-- greek capital letter omicron, U+039F -->
+<!ENTITY Pi       "&#928;"> <!-- greek capital letter pi, U+03A0 ISOgrk3 -->
+<!ENTITY Rho      "&#929;"> <!-- greek capital letter rho, U+03A1 -->
+<!-- there is no Sigmaf, and no U+03A2 character either -->
+<!ENTITY Sigma    "&#931;"> <!-- greek capital letter sigma,
+                                    U+03A3 ISOgrk3 -->
+<!ENTITY Tau      "&#932;"> <!-- greek capital letter tau, U+03A4 -->
+<!ENTITY Upsilon  "&#933;"> <!-- greek capital letter upsilon,
+                                    U+03A5 ISOgrk3 -->
+<!ENTITY Phi      "&#934;"> <!-- greek capital letter phi,
+                                    U+03A6 ISOgrk3 -->
+<!ENTITY Chi      "&#935;"> <!-- greek capital letter chi, U+03A7 -->
+<!ENTITY Psi      "&#936;"> <!-- greek capital letter psi,
+                                    U+03A8 ISOgrk3 -->
+<!ENTITY Omega    "&#937;"> <!-- greek capital letter omega,
+                                    U+03A9 ISOgrk3 -->
+
+<!ENTITY alpha    "&#945;"> <!-- greek small letter alpha,
+                                    U+03B1 ISOgrk3 -->
+<!ENTITY beta     "&#946;"> <!-- greek small letter beta, U+03B2 ISOgrk3 -->
+<!ENTITY gamma    "&#947;"> <!-- greek small letter gamma,
+                                    U+03B3 ISOgrk3 -->
+<!ENTITY delta    "&#948;"> <!-- greek small letter delta,
+                                    U+03B4 ISOgrk3 -->
+<!ENTITY epsilon  "&#949;"> <!-- greek small letter epsilon,
+                                    U+03B5 ISOgrk3 -->
+<!ENTITY zeta     "&#950;"> <!-- greek small letter zeta, U+03B6 ISOgrk3 -->
+<!ENTITY eta      "&#951;"> <!-- greek small letter eta, U+03B7 ISOgrk3 -->
+<!ENTITY theta    "&#952;"> <!-- greek small letter theta,
+                                    U+03B8 ISOgrk3 -->
+<!ENTITY iota     "&#953;"> <!-- greek small letter iota, U+03B9 ISOgrk3 -->
+<!ENTITY kappa    "&#954;"> <!-- greek small letter kappa,
+                                    U+03BA ISOgrk3 -->
+<!ENTITY lambda   "&#955;"> <!-- greek small letter lambda,
+                                    U+03BB ISOgrk3 -->
+<!ENTITY mu       "&#956;"> <!-- greek small letter mu, U+03BC ISOgrk3 -->
+<!ENTITY nu       "&#957;"> <!-- greek small letter nu, U+03BD ISOgrk3 -->
+<!ENTITY xi       "&#958;"> <!-- greek small letter xi, U+03BE ISOgrk3 -->
+<!ENTITY omicron  "&#959;"> <!-- greek small letter omicron, U+03BF NEW -->
+<!ENTITY pi       "&#960;"> <!-- greek small letter pi, U+03C0 ISOgrk3 -->
+<!ENTITY rho      "&#961;"> <!-- greek small letter rho, U+03C1 ISOgrk3 -->
+<!ENTITY sigmaf   "&#962;"> <!-- greek small letter final sigma,
+                                    U+03C2 ISOgrk3 -->
+<!ENTITY sigma    "&#963;"> <!-- greek small letter sigma,
+                                    U+03C3 ISOgrk3 -->
+<!ENTITY tau      "&#964;"> <!-- greek small letter tau, U+03C4 ISOgrk3 -->
+<!ENTITY upsilon  "&#965;"> <!-- greek small letter upsilon,
+                                    U+03C5 ISOgrk3 -->
+<!ENTITY phi      "&#966;"> <!-- greek small letter phi, U+03C6 ISOgrk3 -->
+<!ENTITY chi      "&#967;"> <!-- greek small letter chi, U+03C7 ISOgrk3 -->
+<!ENTITY psi      "&#968;"> <!-- greek small letter psi, U+03C8 ISOgrk3 -->
+<!ENTITY omega    "&#969;"> <!-- greek small letter omega,
+                                    U+03C9 ISOgrk3 -->
+<!ENTITY thetasym "&#977;"> <!-- greek small letter theta symbol,
+                                    U+03D1 NEW -->
+<!ENTITY upsih    "&#978;"> <!-- greek upsilon with hook symbol,
+                                    U+03D2 NEW -->
+<!ENTITY piv      "&#982;"> <!-- greek pi symbol, U+03D6 ISOgrk3 -->
+
+<!-- General Punctuation -->
+<!ENTITY bull     "&#8226;"> <!-- bullet = black small circle,
+                                     U+2022 ISOpub  -->
+<!-- bullet is NOT the same as bullet operator, U+2219 -->
+<!ENTITY hellip   "&#8230;"> <!-- horizontal ellipsis = three dot leader,
+                                     U+2026 ISOpub  -->
+<!ENTITY prime    "&#8242;"> <!-- prime = minutes = feet, U+2032 ISOtech -->
+<!ENTITY Prime    "&#8243;"> <!-- double prime = seconds = inches,
+                                     U+2033 ISOtech -->
+<!ENTITY oline    "&#8254;"> <!-- overline = spacing overscore,
+                                     U+203E NEW -->
+<!ENTITY frasl    "&#8260;"> <!-- fraction slash, U+2044 NEW -->
+
+<!-- Letterlike Symbols -->
+<!ENTITY weierp   "&#8472;"> <!-- script capital P = power set
+                                     = Weierstrass p, U+2118 ISOamso -->
+<!ENTITY image    "&#8465;"> <!-- blackletter capital I = imaginary part,
+                                     U+2111 ISOamso -->
+<!ENTITY real     "&#8476;"> <!-- blackletter capital R = real part symbol,
+                                     U+211C ISOamso -->
+<!ENTITY trade    "&#8482;"> <!-- trade mark sign, U+2122 ISOnum -->
+<!ENTITY alefsym  "&#8501;"> <!-- alef symbol = first transfinite cardinal,
+                                     U+2135 NEW -->
+<!-- alef symbol is NOT the same as hebrew letter alef,
+     U+05D0 although the same glyph could be used to depict both characters -->
+
+<!-- Arrows -->
+<!ENTITY larr     "&#8592;"> <!-- leftwards arrow, U+2190 ISOnum -->
+<!ENTITY uarr     "&#8593;"> <!-- upwards arrow, U+2191 ISOnum-->
+<!ENTITY rarr     "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
+<!ENTITY darr     "&#8595;"> <!-- downwards arrow, U+2193 ISOnum -->
+<!ENTITY harr     "&#8596;"> <!-- left right arrow, U+2194 ISOamsa -->
+<!ENTITY crarr    "&#8629;"> <!-- downwards arrow with corner leftwards
+                                     = carriage return, U+21B5 NEW -->
+<!ENTITY lArr     "&#8656;"> <!-- leftwards double arrow, U+21D0 ISOtech -->
+<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow
+    but also does not have any other character for that function. So ? lArr can
+    be used for 'is implied by' as ISOtech suggests -->
+<!ENTITY uArr     "&#8657;"> <!-- upwards double arrow, U+21D1 ISOamsa -->
+<!ENTITY rArr     "&#8658;"> <!-- rightwards double arrow,
+                                     U+21D2 ISOtech -->
+<!-- Unicode does not say this is the 'implies' character but does not have 
+     another character with this function so ?
+     rArr can be used for 'implies' as ISOtech suggests -->
+<!ENTITY dArr     "&#8659;"> <!-- downwards double arrow, U+21D3 ISOamsa -->
+<!ENTITY hArr     "&#8660;"> <!-- left right double arrow,
+                                     U+21D4 ISOamsa -->
+
+<!-- Mathematical Operators -->
+<!ENTITY forall   "&#8704;"> <!-- for all, U+2200 ISOtech -->
+<!ENTITY part     "&#8706;"> <!-- partial differential, U+2202 ISOtech  -->
+<!ENTITY exist    "&#8707;"> <!-- there exists, U+2203 ISOtech -->
+<!ENTITY empty    "&#8709;"> <!-- empty set = null set = diameter,
+                                     U+2205 ISOamso -->
+<!ENTITY nabla    "&#8711;"> <!-- nabla = backward difference,
+                                     U+2207 ISOtech -->
+<!ENTITY isin     "&#8712;"> <!-- element of, U+2208 ISOtech -->
+<!ENTITY notin    "&#8713;"> <!-- not an element of, U+2209 ISOtech -->
+<!ENTITY ni       "&#8715;"> <!-- contains as member, U+220B ISOtech -->
+<!-- should there be a more memorable name than 'ni'? -->
+<!ENTITY prod     "&#8719;"> <!-- n-ary product = product sign,
+                                     U+220F ISOamsb -->
+<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though
+     the same glyph might be used for both -->
+<!ENTITY sum      "&#8721;"> <!-- n-ary sumation, U+2211 ISOamsb -->
+<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma'
+     though the same glyph might be used for both -->
+<!ENTITY minus    "&#8722;"> <!-- minus sign, U+2212 ISOtech -->
+<!ENTITY lowast   "&#8727;"> <!-- asterisk operator, U+2217 ISOtech -->
+<!ENTITY radic    "&#8730;"> <!-- square root = radical sign,
+                                     U+221A ISOtech -->
+<!ENTITY prop     "&#8733;"> <!-- proportional to, U+221D ISOtech -->
+<!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->
+<!ENTITY ang      "&#8736;"> <!-- angle, U+2220 ISOamso -->
+<!ENTITY and      "&#8743;"> <!-- logical and = wedge, U+2227 ISOtech -->
+<!ENTITY or       "&#8744;"> <!-- logical or = vee, U+2228 ISOtech -->
+<!ENTITY cap      "&#8745;"> <!-- intersection = cap, U+2229 ISOtech -->
+<!ENTITY cup      "&#8746;"> <!-- union = cup, U+222A ISOtech -->
+<!ENTITY int      "&#8747;"> <!-- integral, U+222B ISOtech -->
+<!ENTITY there4   "&#8756;"> <!-- therefore, U+2234 ISOtech -->
+<!ENTITY sim      "&#8764;"> <!-- tilde operator = varies with = similar to,
+                                     U+223C ISOtech -->
+<!-- tilde operator is NOT the same character as the tilde, U+007E,
+     although the same glyph might be used to represent both  -->
+<!ENTITY cong     "&#8773;"> <!-- approximately equal to, U+2245 ISOtech -->
+<!ENTITY asymp    "&#8776;"> <!-- almost equal to = asymptotic to,
+                                     U+2248 ISOamsr -->
+<!ENTITY ne       "&#8800;"> <!-- not equal to, U+2260 ISOtech -->
+<!ENTITY equiv    "&#8801;"> <!-- identical to, U+2261 ISOtech -->
+<!ENTITY le       "&#8804;"> <!-- less-than or equal to, U+2264 ISOtech -->
+<!ENTITY ge       "&#8805;"> <!-- greater-than or equal to,
+                                     U+2265 ISOtech -->
+<!ENTITY sub      "&#8834;"> <!-- subset of, U+2282 ISOtech -->
+<!ENTITY sup      "&#8835;"> <!-- superset of, U+2283 ISOtech -->
+<!-- note that nsup, 'not a superset of, U+2283' is not covered by the Symbol 
+     font encoding and is not included. Should it be, for symmetry?
+     It is in ISOamsn  --> 
+<!ENTITY nsub     "&#8836;"> <!-- not a subset of, U+2284 ISOamsn -->
+<!ENTITY sube     "&#8838;"> <!-- subset of or equal to, U+2286 ISOtech -->
+<!ENTITY supe     "&#8839;"> <!-- superset of or equal to,
+                                     U+2287 ISOtech -->
+<!ENTITY oplus    "&#8853;"> <!-- circled plus = direct sum,
+                                     U+2295 ISOamsb -->
+<!ENTITY otimes   "&#8855;"> <!-- circled times = vector product,
+                                     U+2297 ISOamsb -->
+<!ENTITY perp     "&#8869;"> <!-- up tack = orthogonal to = perpendicular,
+                                     U+22A5 ISOtech -->
+<!ENTITY sdot     "&#8901;"> <!-- dot operator, U+22C5 ISOamsb -->
+<!-- dot operator is NOT the same character as U+00B7 middle dot -->
+
+<!-- Miscellaneous Technical -->
+<!ENTITY lceil    "&#8968;"> <!-- left ceiling = apl upstile,
+                                     U+2308 ISOamsc  -->
+<!ENTITY rceil    "&#8969;"> <!-- right ceiling, U+2309 ISOamsc  -->
+<!ENTITY lfloor   "&#8970;"> <!-- left floor = apl downstile,
+                                     U+230A ISOamsc  -->
+<!ENTITY rfloor   "&#8971;"> <!-- right floor, U+230B ISOamsc  -->
+<!ENTITY lang     "&#9001;"> <!-- left-pointing angle bracket = bra,
+                                     U+2329 ISOtech -->
+<!-- lang is NOT the same character as U+003C 'less than' 
+     or U+2039 'single left-pointing angle quotation mark' -->
+<!ENTITY rang     "&#9002;"> <!-- right-pointing angle bracket = ket,
+                                     U+232A ISOtech -->
+<!-- rang is NOT the same character as U+003E 'greater than' 
+     or U+203A 'single right-pointing angle quotation mark' -->
+
+<!-- Geometric Shapes -->
+<!ENTITY loz      "&#9674;"> <!-- lozenge, U+25CA ISOpub -->
+
+<!-- Miscellaneous Symbols -->
+<!ENTITY spades   "&#9824;"> <!-- black spade suit, U+2660 ISOpub -->
+<!-- black here seems to mean filled as opposed to hollow -->
+<!ENTITY clubs    "&#9827;"> <!-- black club suit = shamrock,
+                                     U+2663 ISOpub -->
+<!ENTITY hearts   "&#9829;"> <!-- black heart suit = valentine,
+                                     U+2665 ISOpub -->
+<!ENTITY diams    "&#9830;"> <!-- black diamond suit, U+2666 ISOpub -->
+
+
+<!ENTITY % xhtml-special
+    PUBLIC "-//W3C//ENTITIES Special for XHTML//EN"
+           "xhtml-special.ent" >
+<!-- Special characters for HTML -->
+
+<!-- Character entity set. Typical invocation:
+     <!ENTITY % HTMLspecial PUBLIC
+        "-//W3C//ENTITIES Special for XHTML//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent">
+     %HTMLspecial;
+-->
+
+<!-- Portions (C) International Organization for Standardization 1986:
+     Permission to copy in any form is granted for use with
+     conforming SGML systems and applications as defined in
+     ISO 8879, provided this notice is included in all copies.
+-->
+
+<!-- Relevant ISO entity set is given unless names are newly introduced.
+     New names (i.e., not in ISO 8879 list) do not clash with any
+     existing ISO 8879 entity names. ISO 10646 character numbers
+     are given for each character, in hex. values are decimal
+     conversions of the ISO 10646 values and refer to the document
+     character set. Names are Unicode names. 
+-->
+
+<!-- C0 Controls and Basic Latin -->
+<!ENTITY quot    "&#34;"> <!--  quotation mark = APL quote,
+                                    U+0022 ISOnum -->
+<!ENTITY amp     "&#38;#38;"> <!--  ampersand, U+0026 ISOnum -->
+<!ENTITY lt      "&#38;#60;"> <!--  less-than sign, U+003C ISOnum -->
+<!ENTITY gt      "&#62;"> <!--  greater-than sign, U+003E ISOnum -->
+<!ENTITY apos	 "&#39;"> <!--  apostrophe mark, U+0027 ISOnum -->
+
+<!-- Latin Extended-A -->
+<!ENTITY OElig   "&#338;"> <!--  latin capital ligature OE,
+                                    U+0152 ISOlat2 -->
+<!ENTITY oelig   "&#339;"> <!--  latin small ligature oe, U+0153 ISOlat2 -->
+<!-- ligature is a misnomer, this is a separate character in some languages -->
+<!ENTITY Scaron  "&#352;"> <!--  latin capital letter S with caron,
+                                    U+0160 ISOlat2 -->
+<!ENTITY scaron  "&#353;"> <!--  latin small letter s with caron,
+                                    U+0161 ISOlat2 -->
+<!ENTITY Yuml    "&#376;"> <!--  latin capital letter Y with diaeresis,
+                                    U+0178 ISOlat2 -->
+
+<!-- Spacing Modifier Letters -->
+<!ENTITY circ    "&#710;"> <!--  modifier letter circumflex accent,
+                                    U+02C6 ISOpub -->
+<!ENTITY tilde   "&#732;"> <!--  small tilde, U+02DC ISOdia -->
+
+<!-- General Punctuation -->
+<!ENTITY ensp    "&#8194;"> <!-- en space, U+2002 ISOpub -->
+<!ENTITY emsp    "&#8195;"> <!-- em space, U+2003 ISOpub -->
+<!ENTITY thinsp  "&#8201;"> <!-- thin space, U+2009 ISOpub -->
+<!ENTITY zwnj    "&#8204;"> <!-- zero width non-joiner,
+                                    U+200C NEW RFC 2070 -->
+<!ENTITY zwj     "&#8205;"> <!-- zero width joiner, U+200D NEW RFC 2070 -->
+<!ENTITY lrm     "&#8206;"> <!-- left-to-right mark, U+200E NEW RFC 2070 -->
+<!ENTITY rlm     "&#8207;"> <!-- right-to-left mark, U+200F NEW RFC 2070 -->
+<!ENTITY ndash   "&#8211;"> <!-- en dash, U+2013 ISOpub -->
+<!ENTITY mdash   "&#8212;"> <!-- em dash, U+2014 ISOpub -->
+<!ENTITY lsquo   "&#8216;"> <!-- left single quotation mark,
+                                    U+2018 ISOnum -->
+<!ENTITY rsquo   "&#8217;"> <!-- right single quotation mark,
+                                    U+2019 ISOnum -->
+<!ENTITY sbquo   "&#8218;"> <!-- single low-9 quotation mark, U+201A NEW -->
+<!ENTITY ldquo   "&#8220;"> <!-- left double quotation mark,
+                                    U+201C ISOnum -->
+<!ENTITY rdquo   "&#8221;"> <!-- right double quotation mark,
+                                    U+201D ISOnum -->
+<!ENTITY bdquo   "&#8222;"> <!-- double low-9 quotation mark, U+201E NEW -->
+<!ENTITY dagger  "&#8224;"> <!-- dagger, U+2020 ISOpub -->
+<!ENTITY Dagger  "&#8225;"> <!-- double dagger, U+2021 ISOpub -->
+<!ENTITY permil  "&#8240;"> <!-- per mille sign, U+2030 ISOtech -->
+<!ENTITY lsaquo  "&#8249;"> <!-- single left-pointing angle quotation mark,
+                                    U+2039 ISO proposed -->
+<!-- lsaquo is proposed but not yet ISO standardized -->
+<!ENTITY rsaquo  "&#8250;"> <!-- single right-pointing angle quotation mark,
+                                    U+203A ISO proposed -->
+<!-- rsaquo is proposed but not yet ISO standardized -->
+<!ENTITY euro   "&#8364;"> <!--  euro sign, U+20AC NEW -->
+
+
+<!-- end of xhtml-charent-1.mod -->
+]]>
+
+<!-- end of xhtml-framework-1.mod -->
+]]>
+
+<!-- Post-Framework Redeclaration placeholder  ................... -->
+<!-- this serves as a location to insert markup declarations
+     into the DTD following the framework declarations.
+-->
+<!ENTITY % xhtml-postfw-redecl.module "IGNORE" >
+<![%xhtml-postfw-redecl.module;[
+%xhtml-postfw-redecl.mod;
+<!-- end of xhtml-postfw-redecl.module -->]]>
+
+<!-- Text Module (Required)  ..................................... -->
+<!ENTITY % xhtml-text.module "INCLUDE" >
+<![%xhtml-text.module;[
+<!ENTITY % xhtml-text.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Text 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Text Module  ................................................... -->
+<!-- file: xhtml-text-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Text 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Textual Content
+
+     The Text module includes declarations for all core
+     text container elements and their attributes.
+-->
+
+<!ENTITY % xhtml-inlstruct.module "INCLUDE" >
+<![%xhtml-inlstruct.module;[
+<!ENTITY % xhtml-inlstruct.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Inline Structural 1.0//EN"
+            "xhtml-inlstruct-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Inline Structural Module  ...................................... -->
+<!-- file: xhtml-inlstruct-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Inline Structural 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstruct-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Inline Structural
+
+        br, span
+
+     This module declares the elements and their attributes
+     used to support inline-level structural markup.
+-->
+
+<!-- br: forced line break ............................. -->
+
+<!ENTITY % br.element  "INCLUDE" >
+<![%br.element;[
+
+<!ENTITY % br.content  "EMPTY" >
+<!ENTITY % br.qname  "br" >
+<!ELEMENT %br.qname;  %br.content; >
+
+<!-- end of br.element -->]]>
+
+<!ENTITY % br.attlist  "INCLUDE" >
+<![%br.attlist;[
+<!ATTLIST %br.qname;
+      %Core.attrib;
+>
+<!-- end of br.attlist -->]]>
+
+<!-- span: generic inline container .................... -->
+
+<!ENTITY % span.element  "INCLUDE" >
+<![%span.element;[
+<!ENTITY % span.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % span.qname  "span" >
+<!ELEMENT %span.qname;  %span.content; >
+<!-- end of span.element -->]]>
+
+<!ENTITY % span.attlist  "INCLUDE" >
+<![%span.attlist;[
+<!ATTLIST %span.qname;
+      %Common.attrib;
+>
+<!-- end of span.attlist -->]]>
+
+<!-- end of xhtml-inlstruct-1.mod -->
+]]>
+
+<!ENTITY % xhtml-inlphras.module "INCLUDE" >
+<![%xhtml-inlphras.module;[
+<!ENTITY % xhtml-inlphras.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Inline Phrasal 1.0//EN"
+            "xhtml-inlphras-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Inline Phrasal Module  ......................................... -->
+<!-- file: xhtml-inlphras-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Inline Phrasal 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlphras-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Inline Phrasal
+
+        abbr, acronym, cite, code, dfn, em, kbd, q, samp, strong, var
+
+     This module declares the elements and their attributes used to
+     support inline-level phrasal markup.
+-->
+
+<!ENTITY % abbr.element  "INCLUDE" >
+<![%abbr.element;[
+<!ENTITY % abbr.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % abbr.qname  "abbr" >
+<!ELEMENT %abbr.qname;  %abbr.content; >
+<!-- end of abbr.element -->]]>
+
+<!ENTITY % abbr.attlist  "INCLUDE" >
+<![%abbr.attlist;[
+<!ATTLIST %abbr.qname;
+      %Common.attrib;
+>
+<!-- end of abbr.attlist -->]]>
+
+<!ENTITY % acronym.element  "INCLUDE" >
+<![%acronym.element;[
+<!ENTITY % acronym.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % acronym.qname  "acronym" >
+<!ELEMENT %acronym.qname;  %acronym.content; >
+<!-- end of acronym.element -->]]>
+
+<!ENTITY % acronym.attlist  "INCLUDE" >
+<![%acronym.attlist;[
+<!ATTLIST %acronym.qname;
+      %Common.attrib;
+>
+<!-- end of acronym.attlist -->]]>
+
+<!ENTITY % cite.element  "INCLUDE" >
+<![%cite.element;[
+<!ENTITY % cite.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % cite.qname  "cite" >
+<!ELEMENT %cite.qname;  %cite.content; >
+<!-- end of cite.element -->]]>
+
+<!ENTITY % cite.attlist  "INCLUDE" >
+<![%cite.attlist;[
+<!ATTLIST %cite.qname;
+      %Common.attrib;
+>
+<!-- end of cite.attlist -->]]>
+
+<!ENTITY % code.element  "INCLUDE" >
+<![%code.element;[
+<!ENTITY % code.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % code.qname  "code" >
+<!ELEMENT %code.qname;  %code.content; >
+<!-- end of code.element -->]]>
+
+<!ENTITY % code.attlist  "INCLUDE" >
+<![%code.attlist;[
+<!ATTLIST %code.qname;
+      %Common.attrib;
+>
+<!-- end of code.attlist -->]]>
+
+<!ENTITY % dfn.element  "INCLUDE" >
+<![%dfn.element;[
+<!ENTITY % dfn.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % dfn.qname  "dfn" >
+<!ELEMENT %dfn.qname;  %dfn.content; >
+<!-- end of dfn.element -->]]>
+
+<!ENTITY % dfn.attlist  "INCLUDE" >
+<![%dfn.attlist;[
+<!ATTLIST %dfn.qname;
+      %Common.attrib;
+>
+<!-- end of dfn.attlist -->]]>
+
+<!ENTITY % em.element  "INCLUDE" >
+<![%em.element;[
+<!ENTITY % em.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % em.qname  "em" >
+<!ELEMENT %em.qname;  %em.content; >
+<!-- end of em.element -->]]>
+
+<!ENTITY % em.attlist  "INCLUDE" >
+<![%em.attlist;[
+<!ATTLIST %em.qname;
+      %Common.attrib;
+>
+<!-- end of em.attlist -->]]>
+
+<!ENTITY % kbd.element  "INCLUDE" >
+<![%kbd.element;[
+<!ENTITY % kbd.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % kbd.qname  "kbd" >
+<!ELEMENT %kbd.qname;  %kbd.content; >
+<!-- end of kbd.element -->]]>
+
+<!ENTITY % kbd.attlist  "INCLUDE" >
+<![%kbd.attlist;[
+<!ATTLIST %kbd.qname;
+      %Common.attrib;
+>
+<!-- end of kbd.attlist -->]]>
+
+<!ENTITY % q.element  "INCLUDE" >
+<![%q.element;[
+<!ENTITY % q.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % q.qname  "q" >
+<!ELEMENT %q.qname;  %q.content; >
+<!-- end of q.element -->]]>
+
+<!ENTITY % q.attlist  "INCLUDE" >
+<![%q.attlist;[
+<!ATTLIST %q.qname;
+      %Common.attrib;
+      cite         %URI.datatype;           #IMPLIED
+>
+<!-- end of q.attlist -->]]>
+
+<!ENTITY % samp.element  "INCLUDE" >
+<![%samp.element;[
+<!ENTITY % samp.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % samp.qname  "samp" >
+<!ELEMENT %samp.qname;  %samp.content; >
+<!-- end of samp.element -->]]>
+
+<!ENTITY % samp.attlist  "INCLUDE" >
+<![%samp.attlist;[
+<!ATTLIST %samp.qname;
+      %Common.attrib;
+>
+<!-- end of samp.attlist -->]]>
+
+<!ENTITY % strong.element  "INCLUDE" >
+<![%strong.element;[
+<!ENTITY % strong.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % strong.qname  "strong" >
+<!ELEMENT %strong.qname;  %strong.content; >
+<!-- end of strong.element -->]]>
+
+<!ENTITY % strong.attlist  "INCLUDE" >
+<![%strong.attlist;[
+<!ATTLIST %strong.qname;
+      %Common.attrib;
+>
+<!-- end of strong.attlist -->]]>
+
+<!ENTITY % var.element  "INCLUDE" >
+<![%var.element;[
+<!ENTITY % var.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % var.qname  "var" >
+<!ELEMENT %var.qname;  %var.content; >
+<!-- end of var.element -->]]>
+
+<!ENTITY % var.attlist  "INCLUDE" >
+<![%var.attlist;[
+<!ATTLIST %var.qname;
+      %Common.attrib;
+>
+<!-- end of var.attlist -->]]>
+
+<!-- end of xhtml-inlphras-1.mod -->
+]]>
+
+<!ENTITY % xhtml-blkstruct.module "INCLUDE" >
+<![%xhtml-blkstruct.module;[
+<!ENTITY % xhtml-blkstruct.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Block Structural 1.0//EN"
+            "xhtml-blkstruct-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Block Structural Module  ....................................... -->
+<!-- file: xhtml-blkstruct-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Block Structural 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-blkstruct-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Block Structural
+
+        div, p
+
+     This module declares the elements and their attributes used to
+     support block-level structural markup.
+-->
+
+<!ENTITY % div.element  "INCLUDE" >
+<![%div.element;[
+<!ENTITY % div.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ENTITY % div.qname  "div" >
+<!ELEMENT %div.qname;  %div.content; >
+<!-- end of div.element -->]]>
+
+<!ENTITY % div.attlist  "INCLUDE" >
+<![%div.attlist;[
+<!ATTLIST %div.qname;
+      %Common.attrib;
+>
+<!-- end of div.attlist -->]]>
+
+<!ENTITY % p.element  "INCLUDE" >
+<![%p.element;[
+<!ENTITY % p.content
+     "( #PCDATA | %Inline.mix; )*" >
+<!ENTITY % p.qname  "p" >
+<!ELEMENT %p.qname;  %p.content; >
+<!-- end of p.element -->]]>
+
+<!ENTITY % p.attlist  "INCLUDE" >
+<![%p.attlist;[
+<!ATTLIST %p.qname;
+      %Common.attrib;
+>
+<!-- end of p.attlist -->]]>
+
+<!-- end of xhtml-blkstruct-1.mod -->
+]]>
+
+<!ENTITY % xhtml-blkphras.module "INCLUDE" >
+<![%xhtml-blkphras.module;[
+<!ENTITY % xhtml-blkphras.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Block Phrasal 1.0//EN"
+            "xhtml-blkphras-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Block Phrasal Module  .......................................... -->
+<!-- file: xhtml-blkphras-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Block Phrasal 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-blkphras-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Block Phrasal
+
+        address, blockquote, pre, h1, h2, h3, h4, h5, h6
+
+     This module declares the elements and their attributes used to
+     support block-level phrasal markup.
+-->
+
+<!ENTITY % address.element  "INCLUDE" >
+<![%address.element;[
+<!ENTITY % address.content
+     "( #PCDATA | %Inline.mix; )*" >
+<!ENTITY % address.qname  "address" >
+<!ELEMENT %address.qname;  %address.content; >
+<!-- end of address.element -->]]>
+
+<!ENTITY % address.attlist  "INCLUDE" >
+<![%address.attlist;[
+<!ATTLIST %address.qname;
+      %Common.attrib;
+>
+<!-- end of address.attlist -->]]>
+
+<!ENTITY % blockquote.element  "INCLUDE" >
+<![%blockquote.element;[
+<!ENTITY % blockquote.content
+     "( %Block.mix; )+"
+>
+<!ENTITY % blockquote.qname  "blockquote" >
+<!ELEMENT %blockquote.qname;  %blockquote.content; >
+<!-- end of blockquote.element -->]]>
+
+<!ENTITY % blockquote.attlist  "INCLUDE" >
+<![%blockquote.attlist;[
+<!ATTLIST %blockquote.qname;
+      %Common.attrib;
+      cite         %URI.datatype;           #IMPLIED
+>
+<!-- end of blockquote.attlist -->]]>
+
+<!ENTITY % pre.element  "INCLUDE" >
+<![%pre.element;[
+<!ENTITY % pre.content
+     "( #PCDATA
+      | %InlStruct.class;
+      %InlPhras.class;
+      | %tt.qname; | %i.qname; | %b.qname;
+      %I18n.class;
+      %Anchor.class;
+      | %script.qname; | %map.qname;
+      %Inline.extra; )*"
+>
+<!ENTITY % pre.qname  "pre" >
+<!ELEMENT %pre.qname;  %pre.content; >
+<!-- end of pre.element -->]]>
+
+<!ENTITY % pre.attlist  "INCLUDE" >
+<![%pre.attlist;[
+<!ATTLIST %pre.qname;
+      %Common.attrib;
+      xml:space    ( preserve )             #FIXED 'preserve'
+>
+<!-- end of pre.attlist -->]]>
+
+<!-- ...................  Heading Elements  ................... -->
+
+<!ENTITY % Heading.content  "( #PCDATA | %Inline.mix; )*" >
+
+<!ENTITY % h1.element  "INCLUDE" >
+<![%h1.element;[
+<!ENTITY % h1.qname  "h1" >
+<!ELEMENT %h1.qname;  %Heading.content; >
+<!-- end of h1.element -->]]>
+
+<!ENTITY % h1.attlist  "INCLUDE" >
+<![%h1.attlist;[
+<!ATTLIST %h1.qname;
+      %Common.attrib;
+>
+<!-- end of h1.attlist -->]]>
+
+<!ENTITY % h2.element  "INCLUDE" >
+<![%h2.element;[
+<!ENTITY % h2.qname  "h2" >
+<!ELEMENT %h2.qname;  %Heading.content; >
+<!-- end of h2.element -->]]>
+
+<!ENTITY % h2.attlist  "INCLUDE" >
+<![%h2.attlist;[
+<!ATTLIST %h2.qname;
+      %Common.attrib;
+>
+<!-- end of h2.attlist -->]]>
+
+<!ENTITY % h3.element  "INCLUDE" >
+<![%h3.element;[
+<!ENTITY % h3.qname  "h3" >
+<!ELEMENT %h3.qname;  %Heading.content; >
+<!-- end of h3.element -->]]>
+
+<!ENTITY % h3.attlist  "INCLUDE" >
+<![%h3.attlist;[
+<!ATTLIST %h3.qname;
+      %Common.attrib;
+>
+<!-- end of h3.attlist -->]]>
+
+<!ENTITY % h4.element  "INCLUDE" >
+<![%h4.element;[
+<!ENTITY % h4.qname  "h4" >
+<!ELEMENT %h4.qname;  %Heading.content; >
+<!-- end of h4.element -->]]>
+
+<!ENTITY % h4.attlist  "INCLUDE" >
+<![%h4.attlist;[
+<!ATTLIST %h4.qname;
+      %Common.attrib;
+>
+<!-- end of h4.attlist -->]]>
+
+<!ENTITY % h5.element  "INCLUDE" >
+<![%h5.element;[
+<!ENTITY % h5.qname  "h5" >
+<!ELEMENT %h5.qname;  %Heading.content; >
+<!-- end of h5.element -->]]>
+
+<!ENTITY % h5.attlist  "INCLUDE" >
+<![%h5.attlist;[
+<!ATTLIST %h5.qname;
+      %Common.attrib;
+>
+<!-- end of h5.attlist -->]]>
+
+<!ENTITY % h6.element  "INCLUDE" >
+<![%h6.element;[
+<!ENTITY % h6.qname  "h6" >
+<!ELEMENT %h6.qname;  %Heading.content; >
+<!-- end of h6.element -->]]>
+
+<!ENTITY % h6.attlist  "INCLUDE" >
+<![%h6.attlist;[
+<!ATTLIST %h6.qname;
+      %Common.attrib;
+>
+<!-- end of h6.attlist -->]]>
+
+<!-- end of xhtml-blkphras-1.mod -->
+]]>
+
+<!-- end of xhtml-text-1.mod -->
+]]>
+
+<!-- Hypertext Module (required) ................................. -->
+<!ENTITY % xhtml-hypertext.module "INCLUDE" >
+<![%xhtml-hypertext.module;[
+<!ENTITY % xhtml-hypertext.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Hypertext 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Hypertext Module  .............................................. -->
+<!-- file: xhtml-hypertext-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Hypertext 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Hypertext
+
+        a
+
+     This module declares the anchor ('a') element type, which
+     defines the source of a hypertext link. The destination
+     (or link 'target') is identified via its 'id' attribute
+     rather than the 'name' attribute as was used in HTML.
+-->
+
+<!-- ............  Anchor Element  ............ -->
+
+<!ENTITY % a.element  "INCLUDE" >
+<![%a.element;[
+<!ENTITY % a.content
+     "( #PCDATA | %InlNoAnchor.mix; )*"
+>
+<!ENTITY % a.qname  "a" >
+<!ELEMENT %a.qname;  %a.content; >
+<!-- end of a.element -->]]>
+
+<!ENTITY % a.attlist  "INCLUDE" >
+<![%a.attlist;[
+<!ATTLIST %a.qname;
+      %Common.attrib;
+      href         %URI.datatype;           #IMPLIED
+      charset      %Charset.datatype;       #IMPLIED
+      type         %ContentType.datatype;   #IMPLIED
+      hreflang     %LanguageCode.datatype;  #IMPLIED
+      rel          %LinkTypes.datatype;     #IMPLIED
+      rev          %LinkTypes.datatype;     #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+>
+<!-- end of a.attlist -->]]>
+
+<!-- end of xhtml-hypertext-1.mod -->
+]]>
+
+<!-- Lists Module (required)  .................................... -->
+<!ENTITY % xhtml-list.module "INCLUDE" >
+<![%xhtml-list.module;[
+<!ENTITY % xhtml-list.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Lists 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Lists Module  .................................................. -->
+<!-- file: xhtml-list-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Lists 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Lists
+
+        dl, dt, dd, ol, ul, li
+
+     This module declares the list-oriented element types
+     and their attributes.
+-->
+
+<!ENTITY % dl.qname  "dl" >
+<!ENTITY % dt.qname  "dt" >
+<!ENTITY % dd.qname  "dd" >
+<!ENTITY % ol.qname  "ol" >
+<!ENTITY % ul.qname  "ul" >
+<!ENTITY % li.qname  "li" >
+
+<!-- dl: Definition List ............................... -->
+
+<!ENTITY % dl.element  "INCLUDE" >
+<![%dl.element;[
+<!ENTITY % dl.content  "( %dt.qname; | %dd.qname; )+" >
+<!ELEMENT %dl.qname;  %dl.content; >
+<!-- end of dl.element -->]]>
+
+<!ENTITY % dl.attlist  "INCLUDE" >
+<![%dl.attlist;[
+<!ATTLIST %dl.qname;
+      %Common.attrib;
+>
+<!-- end of dl.attlist -->]]>
+
+<!-- dt: Definition Term ............................... -->
+
+<!ENTITY % dt.element  "INCLUDE" >
+<![%dt.element;[
+<!ENTITY % dt.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ELEMENT %dt.qname;  %dt.content; >
+<!-- end of dt.element -->]]>
+
+<!ENTITY % dt.attlist  "INCLUDE" >
+<![%dt.attlist;[
+<!ATTLIST %dt.qname;
+      %Common.attrib;
+>
+<!-- end of dt.attlist -->]]>
+
+<!-- dd: Definition Description ........................ -->
+
+<!ENTITY % dd.element  "INCLUDE" >
+<![%dd.element;[
+<!ENTITY % dd.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ELEMENT %dd.qname;  %dd.content; >
+<!-- end of dd.element -->]]>
+
+<!ENTITY % dd.attlist  "INCLUDE" >
+<![%dd.attlist;[
+<!ATTLIST %dd.qname;
+      %Common.attrib;
+>
+<!-- end of dd.attlist -->]]>
+
+<!-- ol: Ordered List (numbered styles) ................ -->
+
+<!ENTITY % ol.element  "INCLUDE" >
+<![%ol.element;[
+<!ENTITY % ol.content  "( %li.qname; )+" >
+<!ELEMENT %ol.qname;  %ol.content; >
+<!-- end of ol.element -->]]>
+
+<!ENTITY % ol.attlist  "INCLUDE" >
+<![%ol.attlist;[
+<!ATTLIST %ol.qname;
+      %Common.attrib;
+>
+<!-- end of ol.attlist -->]]>
+
+<!-- ul: Unordered List (bullet styles) ................ -->
+
+<!ENTITY % ul.element  "INCLUDE" >
+<![%ul.element;[
+<!ENTITY % ul.content  "( %li.qname; )+" >
+<!ELEMENT %ul.qname;  %ul.content; >
+<!-- end of ul.element -->]]>
+
+<!ENTITY % ul.attlist  "INCLUDE" >
+<![%ul.attlist;[
+<!ATTLIST %ul.qname;
+      %Common.attrib;
+>
+<!-- end of ul.attlist -->]]>
+
+<!-- li: List Item ..................................... -->
+
+<!ENTITY % li.element  "INCLUDE" >
+<![%li.element;[
+<!ENTITY % li.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ELEMENT %li.qname;  %li.content; >
+<!-- end of li.element -->]]>
+
+<!ENTITY % li.attlist  "INCLUDE" >
+<![%li.attlist;[
+<!ATTLIST %li.qname;
+      %Common.attrib;
+>
+<!-- end of li.attlist -->]]>
+
+<!-- end of xhtml-list-1.mod -->
+]]>
+
+<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
+
+<!-- Edit Module  ................................................ -->
+<!ENTITY % xhtml-edit.module "INCLUDE" >
+<![%xhtml-edit.module;[
+<!ENTITY % xhtml-edit.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Editing Elements 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-edit-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Editing Elements Module  ....................................... -->
+<!-- file: xhtml-edit-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Editing Markup 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-edit-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Editing Elements
+
+        ins, del
+
+     This module declares element types and attributes used to indicate
+     inserted and deleted content while editing a document.
+-->
+
+<!-- ins: Inserted Text  ............................... -->
+
+<!ENTITY % ins.element  "INCLUDE" >
+<![%ins.element;[
+<!ENTITY % ins.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ENTITY % ins.qname  "ins" >
+<!ELEMENT %ins.qname;  %ins.content; >
+<!-- end of ins.element -->]]>
+
+<!ENTITY % ins.attlist  "INCLUDE" >
+<![%ins.attlist;[
+<!ATTLIST %ins.qname;
+      %Common.attrib;
+      cite         %URI.datatype;           #IMPLIED
+      datetime     %Datetime.datatype;      #IMPLIED
+>
+<!-- end of ins.attlist -->]]>
+
+<!-- del: Deleted Text  ................................ -->
+
+<!ENTITY % del.element  "INCLUDE" >
+<![%del.element;[
+<!ENTITY % del.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ENTITY % del.qname  "del" >
+<!ELEMENT %del.qname;  %del.content; >
+<!-- end of del.element -->]]>
+
+<!ENTITY % del.attlist  "INCLUDE" >
+<![%del.attlist;[
+<!ATTLIST %del.qname;
+      %Common.attrib;
+      cite         %URI.datatype;           #IMPLIED
+      datetime     %Datetime.datatype;      #IMPLIED
+>
+<!-- end of del.attlist -->]]>
+
+<!-- end of xhtml-edit-1.mod -->
+]]>
+
+<!-- BIDI Override Module  ....................................... -->
+<!ENTITY % xhtml-bdo.module "%XHTML.bidi;" >
+<![%xhtml-bdo.module;[
+<!ENTITY % xhtml-bdo.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML BIDI Override Element 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-bdo-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML BDO Element Module ............................................. -->
+<!-- file: xhtml-bdo-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML BDO Element 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-bdo-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Bidirectional Override (bdo) Element
+
+     This modules declares the element 'bdo', used to override the
+     Unicode bidirectional algorithm for selected fragments of text.
+
+     DEPENDENCIES:
+     Relies on the conditional section keyword %XHTML.bidi; declared
+     as "INCLUDE". Bidirectional text support includes both the bdo
+     element and the 'dir' attribute.
+-->
+
+<!ENTITY % bdo.element  "INCLUDE" >
+<![%bdo.element;[
+<!ENTITY % bdo.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % bdo.qname  "bdo" >
+<!ELEMENT %bdo.qname;  %bdo.content; >
+<!-- end of bdo.element -->]]>
+
+<!ENTITY % bdo.attlist  "INCLUDE" >
+<![%bdo.attlist;[
+<!ATTLIST %bdo.qname;
+      %Core.attrib;
+      xml:lang     %LanguageCode.datatype;  #IMPLIED
+      dir          ( ltr | rtl )            #REQUIRED
+>
+]]>
+
+<!-- end of xhtml-bdo-1.mod -->
+]]>
+
+<!-- Ruby Module  ................................................ -->
+<!ENTITY % Ruby.common.attlists "INCLUDE" >
+<!ENTITY % Ruby.common.attrib "%Common.attrib;" >
+<!ENTITY % xhtml-ruby.module "INCLUDE" >
+<![%xhtml-ruby.module;[
+<!ENTITY % xhtml-ruby.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN"
+            "http://www.w3.org/TR/ruby/xhtml-ruby-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Ruby Module .................................................... -->
+<!-- file: xhtml-ruby-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1999-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $
+
+     This module is based on the W3C Ruby Annotation Specification:
+
+        http://www.w3.org/TR/ruby
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/ruby/xhtml-ruby-1.mod"
+
+     ...................................................................... -->
+
+<!-- Ruby Elements
+
+        ruby, rbc, rtc, rb, rt, rp
+
+     This module declares the elements and their attributes used to
+     support ruby annotation markup.
+-->
+
+<!-- declare qualified element type names:
+-->
+<!ENTITY % ruby.qname  "ruby" >
+<!ENTITY % rbc.qname  "rbc" >
+<!ENTITY % rtc.qname  "rtc" >
+<!ENTITY % rb.qname  "rb" >
+<!ENTITY % rt.qname  "rt" >
+<!ENTITY % rp.qname  "rp" >
+
+<!-- rp fallback is included by default.
+-->
+<!ENTITY % Ruby.fallback "INCLUDE" >
+<!ENTITY % Ruby.fallback.mandatory "IGNORE" >
+
+<!-- Complex ruby is included by default; it may be 
+     overridden by other modules to ignore it.
+-->
+<!ENTITY % Ruby.complex "INCLUDE" >
+
+<!-- Fragments for the content model of the ruby element -->
+<![%Ruby.fallback;[
+<![%Ruby.fallback.mandatory;[
+<!ENTITY % Ruby.content.simple 
+     "( %rb.qname;, %rp.qname;, %rt.qname;, %rp.qname; )"
+>
+]]>
+<!ENTITY % Ruby.content.simple 
+     "( %rb.qname;, ( %rt.qname; | ( %rp.qname;, %rt.qname;, %rp.qname; ) ) )"
+>
+]]>
+<!ENTITY % Ruby.content.simple "( %rb.qname;, %rt.qname; )" >
+
+<![%Ruby.complex;[
+<!ENTITY % Ruby.content.complex 
+     "| ( %rbc.qname;, %rtc.qname;, %rtc.qname;? )"
+>
+]]>
+<!ENTITY % Ruby.content.complex "" >
+
+<!-- Content models of the rb and the rt elements are intended to
+     allow other inline-level elements of its parent markup language,
+     but it should not include ruby descendent elements. The following
+     parameter entity %NoRuby.content; can be used to redefine
+     those content models with minimum effort.  It's defined as
+     '( #PCDATA )' by default.
+-->
+<!ENTITY % NoRuby.content "( #PCDATA )" >
+
+<!-- one or more digits (NUMBER) -->
+<!ENTITY % Number.datatype "CDATA" >
+
+<!-- ruby element ...................................... -->
+
+<!ENTITY % ruby.element  "INCLUDE" >
+<![%ruby.element;[
+<!ENTITY % ruby.content
+     "( %Ruby.content.simple; %Ruby.content.complex; )"
+>
+<!ELEMENT %ruby.qname;  %ruby.content; >
+<!-- end of ruby.element -->]]>
+
+<![%Ruby.complex;[
+<!-- rbc (ruby base component) element ................. -->
+
+<!ENTITY % rbc.element  "INCLUDE" >
+<![%rbc.element;[
+<!ENTITY % rbc.content
+     "(%rb.qname;)+"
+>
+<!ELEMENT %rbc.qname;  %rbc.content; >
+<!-- end of rbc.element -->]]>
+
+<!-- rtc (ruby text component) element ................. -->
+
+<!ENTITY % rtc.element  "INCLUDE" >
+<![%rtc.element;[
+<!ENTITY % rtc.content
+     "(%rt.qname;)+"
+>
+<!ELEMENT %rtc.qname;  %rtc.content; >
+<!-- end of rtc.element -->]]>
+]]>
+
+<!-- rb (ruby base) element ............................ -->
+
+<!ENTITY % rb.element  "INCLUDE" >
+<![%rb.element;[
+<!-- %rb.content; uses %NoRuby.content; as its content model,
+     which is '( #PCDATA )' by default. It may be overridden
+     by other modules to allow other inline-level elements
+     of its parent markup language, but it should not include
+     ruby descendent elements.
+-->
+<!ENTITY % rb.content "%NoRuby.content;" >
+<!ELEMENT %rb.qname;  %rb.content; >
+<!-- end of rb.element -->]]>
+
+<!-- rt (ruby text) element ............................ -->
+
+<!ENTITY % rt.element  "INCLUDE" >
+<![%rt.element;[
+<!-- %rt.content; uses %NoRuby.content; as its content model,
+     which is '( #PCDATA )' by default. It may be overridden
+     by other modules to allow other inline-level elements
+     of its parent markup language, but it should not include
+     ruby descendent elements.
+-->
+<!ENTITY % rt.content "%NoRuby.content;" >
+
+<!ELEMENT %rt.qname;  %rt.content; >
+<!-- end of rt.element -->]]>
+
+<!-- rbspan attribute is used for complex ruby only ...... -->
+<![%Ruby.complex;[
+<!ENTITY % rt.attlist  "INCLUDE" >
+<![%rt.attlist;[
+<!ATTLIST %rt.qname;
+      rbspan         %Number.datatype;      "1"
+>
+<!-- end of rt.attlist -->]]>
+]]>
+
+<!-- rp (ruby parenthesis) element ..................... -->
+
+<![%Ruby.fallback;[
+<!ENTITY % rp.element  "INCLUDE" >
+<![%rp.element;[
+<!ENTITY % rp.content
+     "( #PCDATA )"
+>
+<!ELEMENT %rp.qname;  %rp.content; >
+<!-- end of rp.element -->]]>
+]]>
+
+<!-- Ruby Common Attributes
+
+     The following optional ATTLIST declarations provide an easy way
+     to define common attributes for ruby elements.  These declarations
+     are ignored by default.
+
+     Ruby elements are intended to have common attributes of its
+     parent markup language.  For example, if a markup language defines
+     common attributes as a parameter entity %attrs;, you may add
+     those attributes by just declaring the following parameter entities
+
+         <!ENTITY % Ruby.common.attlists  "INCLUDE" >
+         <!ENTITY % Ruby.common.attrib  "%attrs;" >
+
+     before including the Ruby module.
+-->
+
+<!ENTITY % Ruby.common.attlists  "IGNORE" >
+<![%Ruby.common.attlists;[
+<!ENTITY % Ruby.common.attrib  "" >
+
+<!-- common attributes for ruby ........................ -->
+
+<!ENTITY % Ruby.common.attlist  "INCLUDE" >
+<![%Ruby.common.attlist;[
+<!ATTLIST %ruby.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Ruby.common.attlist -->]]>
+
+<![%Ruby.complex;[
+<!-- common attributes for rbc ......................... -->
+
+<!ENTITY % Rbc.common.attlist  "INCLUDE" >
+<![%Rbc.common.attlist;[
+<!ATTLIST %rbc.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Rbc.common.attlist -->]]>
+
+<!-- common attributes for rtc ......................... -->
+
+<!ENTITY % Rtc.common.attlist  "INCLUDE" >
+<![%Rtc.common.attlist;[
+<!ATTLIST %rtc.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Rtc.common.attlist -->]]>
+]]>
+
+<!-- common attributes for rb .......................... -->
+
+<!ENTITY % Rb.common.attlist  "INCLUDE" >
+<![%Rb.common.attlist;[
+<!ATTLIST %rb.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Rb.common.attlist -->]]>
+
+<!-- common attributes for rt .......................... -->
+
+<!ENTITY % Rt.common.attlist  "INCLUDE" >
+<![%Rt.common.attlist;[
+<!ATTLIST %rt.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Rt.common.attlist -->]]>
+
+<![%Ruby.fallback;[
+<!-- common attributes for rp .......................... -->
+
+<!ENTITY % Rp.common.attlist  "INCLUDE" >
+<![%Rp.common.attlist;[
+<!ATTLIST %rp.qname;
+      %Ruby.common.attrib;
+>
+<!-- end of Rp.common.attlist -->]]>
+]]>
+]]>
+
+<!-- end of xhtml-ruby-1.mod -->
+]]>
+
+<!-- Presentation Module  ........................................ -->
+<!ENTITY % xhtml-pres.module "INCLUDE" >
+<![%xhtml-pres.module;[
+<!ENTITY % xhtml-pres.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Presentation 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-pres-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Presentation Module ............................................ -->
+<!-- file: xhtml-pres-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Presentation 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-pres-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Presentational Elements
+
+     This module defines elements and their attributes for
+     simple presentation-related markup.
+-->
+
+<!ENTITY % xhtml-inlpres.module "INCLUDE" >
+<![%xhtml-inlpres.module;[
+<!ENTITY % xhtml-inlpres.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Inline Presentation 1.0//EN"
+            "xhtml-inlpres-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Inline Presentation Module  .................................... -->
+<!-- file: xhtml-inlpres-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Inline Presentation 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlpres-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Inline Presentational Elements
+
+        b, big, i, small, sub, sup, tt
+
+     This module declares the elements and their attributes used to
+     support inline-level presentational markup.
+-->
+
+<!ENTITY % b.element  "INCLUDE" >
+<![%b.element;[
+<!ENTITY % b.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % b.qname  "b" >
+<!ELEMENT %b.qname;  %b.content; >
+<!-- end of b.element -->]]>
+
+<!ENTITY % b.attlist  "INCLUDE" >
+<![%b.attlist;[
+<!ATTLIST %b.qname;
+      %Common.attrib;
+>
+<!-- end of b.attlist -->]]>
+
+<!ENTITY % big.element  "INCLUDE" >
+<![%big.element;[
+<!ENTITY % big.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % big.qname  "big" >
+<!ELEMENT %big.qname;  %big.content; >
+<!-- end of big.element -->]]>
+
+<!ENTITY % big.attlist  "INCLUDE" >
+<![%big.attlist;[
+<!ATTLIST %big.qname;
+      %Common.attrib;
+>
+<!-- end of big.attlist -->]]>
+
+<!ENTITY % i.element  "INCLUDE" >
+<![%i.element;[
+<!ENTITY % i.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % i.qname  "i" >
+<!ELEMENT %i.qname;  %i.content; >
+<!-- end of i.element -->]]>
+
+<!ENTITY % i.attlist  "INCLUDE" >
+<![%i.attlist;[
+<!ATTLIST %i.qname;
+      %Common.attrib;
+>
+<!-- end of i.attlist -->]]>
+
+<!ENTITY % small.element  "INCLUDE" >
+<![%small.element;[
+<!ENTITY % small.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % small.qname  "small" >
+<!ELEMENT %small.qname;  %small.content; >
+<!-- end of small.element -->]]>
+
+<!ENTITY % small.attlist  "INCLUDE" >
+<![%small.attlist;[
+<!ATTLIST %small.qname;
+      %Common.attrib;
+>
+<!-- end of small.attlist -->]]>
+
+<!ENTITY % sub.element  "INCLUDE" >
+<![%sub.element;[
+<!ENTITY % sub.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % sub.qname  "sub" >
+<!ELEMENT %sub.qname;  %sub.content; >
+<!-- end of sub.element -->]]>
+
+<!ENTITY % sub.attlist  "INCLUDE" >
+<![%sub.attlist;[
+<!ATTLIST %sub.qname;
+      %Common.attrib;
+>
+<!-- end of sub.attlist -->]]>
+
+<!ENTITY % sup.element  "INCLUDE" >
+<![%sup.element;[
+<!ENTITY % sup.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % sup.qname  "sup" >
+<!ELEMENT %sup.qname;  %sup.content; >
+<!-- end of sup.element -->]]>
+
+<!ENTITY % sup.attlist  "INCLUDE" >
+<![%sup.attlist;[
+<!ATTLIST %sup.qname;
+      %Common.attrib;
+>
+<!-- end of sup.attlist -->]]>
+
+<!ENTITY % tt.element  "INCLUDE" >
+<![%tt.element;[
+<!ENTITY % tt.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ENTITY % tt.qname  "tt" >
+<!ELEMENT %tt.qname;  %tt.content; >
+<!-- end of tt.element -->]]>
+
+<!ENTITY % tt.attlist  "INCLUDE" >
+<![%tt.attlist;[
+<!ATTLIST %tt.qname;
+      %Common.attrib;
+>
+<!-- end of tt.attlist -->]]>
+
+<!-- end of xhtml-inlpres-1.mod -->
+]]>
+
+<!ENTITY % xhtml-blkpres.module "INCLUDE" >
+<![%xhtml-blkpres.module;[
+<!ENTITY % xhtml-blkpres.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Block Presentation 1.0//EN"
+            "xhtml-blkpres-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Block Presentation Module  ..................................... -->
+<!-- file: xhtml-blkpres-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Block Presentation 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-blkpres-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Block Presentational Elements
+
+        hr
+
+     This module declares the elements and their attributes used to
+     support block-level presentational markup.
+-->
+
+<!ENTITY % hr.element  "INCLUDE" >
+<![%hr.element;[
+<!ENTITY % hr.content  "EMPTY" >
+<!ENTITY % hr.qname  "hr" >
+<!ELEMENT %hr.qname;  %hr.content; >
+<!-- end of hr.element -->]]>
+
+<!ENTITY % hr.attlist  "INCLUDE" >
+<![%hr.attlist;[
+<!ATTLIST %hr.qname;
+      %Common.attrib;
+>
+<!-- end of hr.attlist -->]]>
+
+<!-- end of xhtml-blkpres-1.mod -->
+]]>
+
+<!-- end of xhtml-pres-1.mod -->
+]]>
+
+<!-- Link Element Module  ........................................ -->
+<!ENTITY % xhtml-link.module "INCLUDE" >
+<![%xhtml-link.module;[
+<!ENTITY % xhtml-link.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Link Element 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-link-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Link Element Module  ........................................... -->
+<!-- file: xhtml-link-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Link Element 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-link-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Link element
+
+        link
+
+     This module declares the link element type and its attributes,
+     which could (in principle) be used to define document-level links
+     to external resources such as:
+
+     a) for document specific toolbars/menus, e.g. start, contents,
+        previous, next, index, end, help
+     b) to link to a separate style sheet (rel="stylesheet")
+     c) to make a link to a script (rel="script")
+     d) by stylesheets to control how collections of html nodes are
+        rendered into printed documents
+     e) to make a link to a printable version of this document
+        e.g. a postscript or pdf version (rel="alternate" media="print")
+-->
+
+<!-- link: Media-Independent Link ...................... -->
+
+<!ENTITY % link.element  "INCLUDE" >
+<![%link.element;[
+<!ENTITY % link.content  "EMPTY" >
+<!ENTITY % link.qname  "link" >
+<!ELEMENT %link.qname;  %link.content; >
+<!-- end of link.element -->]]>
+
+<!ENTITY % link.attlist  "INCLUDE" >
+<![%link.attlist;[
+<!ATTLIST %link.qname;
+      %Common.attrib;
+      charset      %Charset.datatype;       #IMPLIED
+      href         %URI.datatype;           #IMPLIED
+      hreflang     %LanguageCode.datatype;  #IMPLIED
+      type         %ContentType.datatype;   #IMPLIED
+      rel          %LinkTypes.datatype;     #IMPLIED
+      rev          %LinkTypes.datatype;     #IMPLIED
+      media        %MediaDesc.datatype;     #IMPLIED
+>
+<!-- end of link.attlist -->]]>
+
+<!-- end of xhtml-link-1.mod -->
+]]>
+
+<!-- Document Metainformation Module  ............................ -->
+<!ENTITY % xhtml-meta.module "INCLUDE" >
+<![%xhtml-meta.module;[
+<!ENTITY % xhtml-meta.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Metainformation 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-meta-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Document Metainformation Module  ............................... -->
+<!-- file: xhtml-meta-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Metainformation 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-meta-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Meta Information
+
+        meta
+
+     This module declares the meta element type and its attributes,
+     used to provide declarative document metainformation.
+-->
+
+<!-- meta: Generic Metainformation ..................... -->
+
+<!ENTITY % meta.element  "INCLUDE" >
+<![%meta.element;[
+<!ENTITY % meta.content  "EMPTY" >
+<!ENTITY % meta.qname  "meta" >
+<!ELEMENT %meta.qname;  %meta.content; >
+<!-- end of meta.element -->]]>
+
+<!ENTITY % meta.attlist  "INCLUDE" >
+<![%meta.attlist;[
+<!ATTLIST %meta.qname;
+      %XHTML.xmlns.attrib;
+      %I18n.attrib;
+      http-equiv   NMTOKEN                  #IMPLIED
+      name         NMTOKEN                  #IMPLIED
+      content      CDATA                    #REQUIRED
+      scheme       CDATA                    #IMPLIED
+>
+<!-- end of meta.attlist -->]]>
+
+<!-- end of xhtml-meta-1.mod -->
+]]>
+
+<!-- Base Element Module  ........................................ -->
+<!ENTITY % xhtml-base.module "INCLUDE" >
+<![%xhtml-base.module;[
+<!ENTITY % xhtml-base.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Base Element 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-base-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Base Element Module  ........................................... -->
+<!-- file: xhtml-base-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Base Element 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-base-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Base element
+
+        base
+
+     This module declares the base element type and its attributes,
+     used to define a base URI against which relative URIs in the
+     document will be resolved.
+
+     Note that this module also redeclares the content model for
+     the head element to include the base element.
+-->
+
+<!-- base: Document Base URI ........................... -->
+
+<!ENTITY % base.element  "INCLUDE" >
+<![%base.element;[
+<!ENTITY % base.content  "EMPTY" >
+<!ENTITY % base.qname  "base" >
+<!ELEMENT %base.qname;  %base.content; >
+<!-- end of base.element -->]]>
+
+<!ENTITY % base.attlist  "INCLUDE" >
+<![%base.attlist;[
+<!ATTLIST %base.qname;
+      %XHTML.xmlns.attrib;
+      href         %URI.datatype;           #REQUIRED
+>
+<!-- end of base.attlist -->]]>
+
+<!ENTITY % head.content
+    "( %HeadOpts.mix;,
+     ( ( %title.qname;, %HeadOpts.mix;, ( %base.qname;, %HeadOpts.mix; )? )
+     | ( %base.qname;, %HeadOpts.mix;, ( %title.qname;, %HeadOpts.mix; ))))"
+>
+
+<!-- end of xhtml-base-1.mod -->
+]]>
+
+<!-- Scripting Module  ........................................... -->
+<!ENTITY % xhtml-script.module "INCLUDE" >
+<![%xhtml-script.module;[
+<!ENTITY % xhtml-script.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Scripting 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-script-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Document Scripting Module  ..................................... -->
+<!-- file: xhtml-script-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Scripting 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-script-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Scripting
+
+        script, noscript
+
+     This module declares element types and attributes used to provide
+     support for executable scripts as well as an alternate content
+     container where scripts are not supported.
+-->
+
+<!-- script: Scripting Statement ....................... -->
+
+<!ENTITY % script.element  "INCLUDE" >
+<![%script.element;[
+<!ENTITY % script.content  "( #PCDATA )" >
+<!ENTITY % script.qname  "script" >
+<!ELEMENT %script.qname;  %script.content; >
+<!-- end of script.element -->]]>
+
+<!ENTITY % script.attlist  "INCLUDE" >
+<![%script.attlist;[
+<!ATTLIST %script.qname;
+      %XHTML.xmlns.attrib;
+      charset      %Charset.datatype;       #IMPLIED
+      type         %ContentType.datatype;   #REQUIRED
+      src          %URI.datatype;           #IMPLIED
+      defer        ( defer )                #IMPLIED
+      xml:space    ( preserve )             #FIXED 'preserve'
+>
+<!-- end of script.attlist -->]]>
+
+<!-- noscript: No-Script Alternate Content ............. -->
+
+<!ENTITY % noscript.element  "INCLUDE" >
+<![%noscript.element;[
+<!ENTITY % noscript.content
+     "( %Block.mix; )+"
+>
+<!ENTITY % noscript.qname  "noscript" >
+<!ELEMENT %noscript.qname;  %noscript.content; >
+<!-- end of noscript.element -->]]>
+
+<!ENTITY % noscript.attlist  "INCLUDE" >
+<![%noscript.attlist;[
+<!ATTLIST %noscript.qname;
+      %Common.attrib;
+>
+<!-- end of noscript.attlist -->]]>
+
+<!-- end of xhtml-script-1.mod -->
+]]>
+
+<!-- Style Sheets Module  ......................................... -->
+<!ENTITY % xhtml-style.module "INCLUDE" >
+<![%xhtml-style.module;[
+<!ENTITY % xhtml-style.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Style Sheets 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-style-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Document Style Sheet Module  .................................... -->
+<!-- file: xhtml-style-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//DTD XHTML Style Sheets 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-style-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Style Sheets
+
+        style
+
+     This module declares the style element type and its attributes,
+     used to embed stylesheet information in the document head element.
+-->
+
+<!-- style: Style Sheet Information ..................... -->
+
+<!ENTITY % style.element  "INCLUDE" >
+<![%style.element;[
+<!ENTITY % style.content  "( #PCDATA )" >
+<!ENTITY % style.qname  "style" >
+<!ELEMENT %style.qname;  %style.content; >
+<!-- end of style.element -->]]>
+
+<!ENTITY % style.attlist  "INCLUDE" >
+<![%style.attlist;[
+<!ATTLIST %style.qname;
+      %XHTML.xmlns.attrib;
+      %title.attrib;
+      %I18n.attrib;
+      type         %ContentType.datatype;   #REQUIRED
+      media        %MediaDesc.datatype;     #IMPLIED
+      xml:space    ( preserve )             #FIXED 'preserve'
+>
+<!-- end of style.attlist -->]]>
+
+<!-- end of xhtml-style-1.mod -->
+]]>
+
+<!-- Image Module  ............................................... -->
+<!ENTITY % xhtml-image.module "INCLUDE" >
+<![%xhtml-image.module;[
+<!ENTITY % xhtml-image.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-image-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Images Module  ................................................. -->
+<!-- file: xhtml-image-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Rovision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-image-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Images
+
+        img
+
+     This module provides markup to support basic image embedding.
+-->
+
+<!-- To avoid problems with text-only UAs as well as to make
+     image content understandable and navigable to users of
+     non-visual UAs, you need to provide a description with
+     the 'alt' attribute, and avoid server-side image maps.
+-->
+
+<!ENTITY % img.element  "INCLUDE" >
+<![%img.element;[
+<!ENTITY % img.content  "EMPTY" >
+<!ENTITY % img.qname  "img" >
+<!ELEMENT %img.qname;  %img.content; >
+<!-- end of img.element -->]]>
+
+<!ENTITY % img.attlist  "INCLUDE" >
+<![%img.attlist;[
+<!ATTLIST %img.qname;
+      %Common.attrib;
+      src          %URI.datatype;           #REQUIRED
+      alt          %Text.datatype;          #REQUIRED
+      longdesc     %URI.datatype;           #IMPLIED
+      height       %Length.datatype;        #IMPLIED
+      width        %Length.datatype;        #IMPLIED
+>
+<!-- end of img.attlist -->]]>
+
+<!-- end of xhtml-image-1.mod -->
+]]>
+
+<!-- Client-side Image Map Module  ............................... -->
+<!ENTITY % xhtml-csismap.module "INCLUDE" >
+<![%xhtml-csismap.module;[
+<!ENTITY % xhtml-csismap.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Client-side Image Maps 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-csismap-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Client-side Image Map Module  .................................. -->
+<!-- file: xhtml-csismap-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Client-side Image Maps 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-csismap-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Client-side Image Maps
+
+        area, map
+
+     This module declares elements and attributes to support client-side
+     image maps. This requires that the Image Module (or a module
+     declaring the img element type) be included in the DTD.
+
+     These can be placed in the same document or grouped in a
+     separate document, although the latter isn't widely supported
+-->
+
+<!ENTITY % area.element  "INCLUDE" >
+<![%area.element;[
+<!ENTITY % area.content  "EMPTY" >
+<!ENTITY % area.qname  "area" >
+<!ELEMENT %area.qname;  %area.content; >
+<!-- end of area.element -->]]>
+
+<!ENTITY % Shape.datatype "( rect | circle | poly | default )">
+<!ENTITY % Coords.datatype "CDATA" >
+
+<!ENTITY % area.attlist  "INCLUDE" >
+<![%area.attlist;[
+<!ATTLIST %area.qname;
+      %Common.attrib;
+      href         %URI.datatype;           #IMPLIED
+      shape        %Shape.datatype;         'rect'
+      coords       %Coords.datatype;        #IMPLIED
+      nohref       ( nohref )               #IMPLIED
+      alt          %Text.datatype;          #REQUIRED
+      tabindex     %Number.datatype;        #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+>
+<!-- end of area.attlist -->]]>
+
+<!-- modify anchor attribute definition list
+     to allow for client-side image maps
+-->
+<!ATTLIST %a.qname;
+      shape        %Shape.datatype;         'rect'
+      coords       %Coords.datatype;        #IMPLIED
+>
+
+<!-- modify img attribute definition list
+     to allow for client-side image maps
+-->
+<!ATTLIST %img.qname;
+      usemap       IDREF                    #IMPLIED
+>
+
+<!-- modify form input attribute definition list
+     to allow for client-side image maps
+-->
+<!ATTLIST %input.qname;
+      usemap       IDREF                    #IMPLIED
+>
+
+<!-- modify object attribute definition list
+     to allow for client-side image maps
+-->
+<!ATTLIST %object.qname;
+      usemap       IDREF                    #IMPLIED
+>
+
+<!-- 'usemap' points to the 'id' attribute of a <map> element,
+     which must be in the same document; support for external
+     document maps was not widely supported in HTML and is
+     eliminated in XHTML.
+
+     It is considered an error for the element pointed to by
+     a usemap IDREF to occur in anything but a <map> element.
+-->
+
+<!ENTITY % map.element  "INCLUDE" >
+<![%map.element;[
+<!ENTITY % map.content
+     "(( %Block.mix; ) | %area.qname; )+"
+>
+<!ENTITY % map.qname  "map" >
+<!ELEMENT %map.qname;  %map.content; >
+<!-- end of map.element -->]]>
+
+<!ENTITY % map.attlist  "INCLUDE" >
+<![%map.attlist;[
+<!ATTLIST %map.qname;
+      %XHTML.xmlns.attrib;
+      id           ID                       #REQUIRED
+      %class.attrib;
+      %title.attrib;
+      %Core.extra.attrib;
+      %I18n.attrib;
+      %Events.attrib;
+>
+<!-- end of map.attlist -->]]>
+
+<!-- end of xhtml-csismap-1.mod -->
+]]>
+
+<!-- Server-side Image Map Module  ............................... -->
+<!ENTITY % xhtml-ssismap.module "INCLUDE" >
+<![%xhtml-ssismap.module;[
+<!ENTITY % xhtml-ssismap.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Server-side Image Maps 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-ssismap-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Server-side Image Map Module  .................................. -->
+<!-- file: xhtml-ssismap-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Server-side Image Maps 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-ssismap-1.mod"
+
+     Revisions:
+#2000-10-22: added declaration for 'ismap' on <input>
+     ....................................................................... -->
+
+<!-- Server-side Image Maps
+
+     This adds the 'ismap' attribute to the img and input elements
+     to support server-side processing of a user selection.
+-->
+
+<!ATTLIST %img.qname;
+      ismap        ( ismap )                #IMPLIED
+>
+
+<!ATTLIST %input.qname;
+      ismap        ( ismap )                #IMPLIED
+>
+
+<!-- end of xhtml-ssismap-1.mod -->
+]]>
+
+<!-- Param Element Module  ....................................... -->
+<!ENTITY % xhtml-param.module "INCLUDE" >
+<![%xhtml-param.module;[
+<!ENTITY % xhtml-param.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Param Element 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-param-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Param Element Module  ..................................... -->
+<!-- file: xhtml-param-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Param Element 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-param-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Parameters for Java Applets and Embedded Objects
+
+        param
+
+     This module provides declarations for the param element,
+     used to provide named property values for the applet
+     and object elements.
+-->
+
+<!-- param: Named Property Value ....................... -->
+
+<!ENTITY % param.element  "INCLUDE" >
+<![%param.element;[
+<!ENTITY % param.content  "EMPTY" >
+<!ENTITY % param.qname  "param" >
+<!ELEMENT %param.qname;  %param.content; >
+<!-- end of param.element -->]]>
+
+<!ENTITY % param.attlist  "INCLUDE" >
+<![%param.attlist;[
+<!ATTLIST %param.qname;
+      %XHTML.xmlns.attrib;
+      %id.attrib;
+      name         CDATA                    #REQUIRED
+      value        CDATA                    #IMPLIED
+      valuetype    ( data | ref | object )  'data'
+      type         %ContentType.datatype;   #IMPLIED
+>
+<!-- end of param.attlist -->]]>
+
+<!-- end of xhtml-param-1.mod -->
+]]>
+
+<!-- Embedded Object Module  ..................................... -->
+<!ENTITY % xhtml-object.module "INCLUDE" >
+<![%xhtml-object.module;[
+<!ENTITY % xhtml-object.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Embedded Object 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-object-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Embedded Object Module  ........................................ -->
+<!-- file: xhtml-object-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Embedded Object 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-object-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Embedded Objects
+
+        object
+
+     This module declares the object element type and its attributes, used
+     to embed external objects as part of XHTML pages. In the document,
+     place param elements prior to other content within the object element.
+
+     Note that use of this module requires instantiation of the Param
+     Element Module.
+-->
+
+<!-- object: Generic Embedded Object ................... -->
+
+<!ENTITY % object.element  "INCLUDE" >
+<![%object.element;[
+<!ENTITY % object.content
+     "( #PCDATA | %Flow.mix; | %param.qname; )*"
+>
+<!ENTITY % object.qname  "object" >
+<!ELEMENT %object.qname;  %object.content; >
+<!-- end of object.element -->]]>
+
+<!ENTITY % object.attlist  "INCLUDE" >
+<![%object.attlist;[
+<!ATTLIST %object.qname;
+      %Common.attrib;
+      declare      ( declare )              #IMPLIED
+      classid      %URI.datatype;           #IMPLIED
+      codebase     %URI.datatype;           #IMPLIED
+      data         %URI.datatype;           #IMPLIED
+      type         %ContentType.datatype;   #IMPLIED
+      codetype     %ContentType.datatype;   #IMPLIED
+      archive      %URIs.datatype;          #IMPLIED
+      standby      %Text.datatype;          #IMPLIED
+      height       %Length.datatype;        #IMPLIED
+      width        %Length.datatype;        #IMPLIED
+      name         CDATA                    #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+>
+<!-- end of object.attlist -->]]>
+
+<!-- end of xhtml-object-1.mod -->
+]]>
+
+<!-- Tables Module ............................................... -->
+<!ENTITY % xhtml-table.module "INCLUDE" >
+<![%xhtml-table.module;[
+<!ENTITY % xhtml-table.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Tables 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-table-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Table Module  .................................................. -->
+<!-- file: xhtml-table-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Tables 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-table-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Tables
+
+        table, caption, thead, tfoot, tbody, colgroup, col, tr, th, td
+
+     This module declares element types and attributes used to provide
+     table markup similar to HTML 4.0, including features that enable
+     better accessibility for non-visual user agents.
+-->
+
+<!-- declare qualified element type names:
+-->
+<!ENTITY % table.qname  "table" >
+<!ENTITY % caption.qname  "caption" >
+<!ENTITY % thead.qname  "thead" >
+<!ENTITY % tfoot.qname  "tfoot" >
+<!ENTITY % tbody.qname  "tbody" >
+<!ENTITY % colgroup.qname  "colgroup" >
+<!ENTITY % col.qname  "col" >
+<!ENTITY % tr.qname  "tr" >
+<!ENTITY % th.qname  "th" >
+<!ENTITY % td.qname  "td" >
+
+<!-- The frame attribute specifies which parts of the frame around
+     the table should be rendered. The values are not the same as
+     CALS to avoid a name clash with the valign attribute.
+-->
+<!ENTITY % frame.attrib
+     "frame        ( void
+                   | above
+                   | below
+                   | hsides
+                   | lhs
+                   | rhs
+                   | vsides
+                   | box
+                   | border )               #IMPLIED"
+>
+
+<!-- The rules attribute defines which rules to draw between cells:
+
+     If rules is absent then assume:
+
+       "none" if border is absent or border="0" otherwise "all"
+-->
+<!ENTITY % rules.attrib
+     "rules        ( none
+                   | groups
+                   | rows
+                   | cols
+                   | all )                  #IMPLIED"
+>
+
+<!-- horizontal alignment attributes for cell contents
+-->
+<!ENTITY % CellHAlign.attrib
+     "align        ( left
+                   | center
+                   | right
+                   | justify
+                   | char )                 #IMPLIED
+      char         %Character.datatype;     #IMPLIED
+      charoff      %Length.datatype;        #IMPLIED"
+>
+
+<!-- vertical alignment attribute for cell contents
+-->
+<!ENTITY % CellVAlign.attrib
+     "valign       ( top
+                   | middle
+                   | bottom
+                   | baseline )             #IMPLIED"
+>
+
+<!-- scope is simpler than axes attribute for common tables
+-->
+<!ENTITY % scope.attrib
+     "scope        ( row
+                   | col
+                   | rowgroup
+                   | colgroup )             #IMPLIED"
+>
+
+<!-- table: Table Element .............................. -->
+
+<!ENTITY % table.element  "INCLUDE" >
+<![%table.element;[
+<!ENTITY % table.content
+     "( %caption.qname;?, ( %col.qname;* | %colgroup.qname;* ),
+      (( %thead.qname;?, %tfoot.qname;?, %tbody.qname;+ ) | ( %tr.qname;+ )))"
+>
+<!ELEMENT %table.qname;  %table.content; >
+<!-- end of table.element -->]]>
+
+<!ENTITY % table.attlist  "INCLUDE" >
+<![%table.attlist;[
+<!ATTLIST %table.qname;
+      %Common.attrib;
+      summary      %Text.datatype;          #IMPLIED
+      width        %Length.datatype;        #IMPLIED
+      border       %Pixels.datatype;        #IMPLIED
+      %frame.attrib;
+      %rules.attrib;
+      cellspacing  %Length.datatype;        #IMPLIED
+      cellpadding  %Length.datatype;        #IMPLIED
+>
+<!-- end of table.attlist -->]]>
+
+<!-- caption: Table Caption ............................ -->
+
+<!ENTITY % caption.element  "INCLUDE" >
+<![%caption.element;[
+<!ENTITY % caption.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ELEMENT %caption.qname;  %caption.content; >
+<!-- end of caption.element -->]]>
+
+<!ENTITY % caption.attlist  "INCLUDE" >
+<![%caption.attlist;[
+<!ATTLIST %caption.qname;
+      %Common.attrib;
+>
+<!-- end of caption.attlist -->]]>
+
+<!-- thead: Table Header ............................... -->
+
+<!-- Use thead to duplicate headers when breaking table
+     across page boundaries, or for static headers when
+     tbody sections are rendered in scrolling panel.
+-->
+
+<!ENTITY % thead.element  "INCLUDE" >
+<![%thead.element;[
+<!ENTITY % thead.content  "( %tr.qname; )+" >
+<!ELEMENT %thead.qname;  %thead.content; >
+<!-- end of thead.element -->]]>
+
+<!ENTITY % thead.attlist  "INCLUDE" >
+<![%thead.attlist;[
+<!ATTLIST %thead.qname;
+      %Common.attrib;
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of thead.attlist -->]]>
+
+<!-- tfoot: Table Footer ............................... -->
+
+<!-- Use tfoot to duplicate footers when breaking table
+     across page boundaries, or for static footers when
+     tbody sections are rendered in scrolling panel.
+-->
+
+<!ENTITY % tfoot.element  "INCLUDE" >
+<![%tfoot.element;[
+<!ENTITY % tfoot.content  "( %tr.qname; )+" >
+<!ELEMENT %tfoot.qname;  %tfoot.content; >
+<!-- end of tfoot.element -->]]>
+
+<!ENTITY % tfoot.attlist  "INCLUDE" >
+<![%tfoot.attlist;[
+<!ATTLIST %tfoot.qname;
+      %Common.attrib;
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of tfoot.attlist -->]]>
+
+<!-- tbody: Table Body ................................. -->
+
+<!-- Use multiple tbody sections when rules are needed
+     between groups of table rows.
+-->
+
+<!ENTITY % tbody.element  "INCLUDE" >
+<![%tbody.element;[
+<!ENTITY % tbody.content  "( %tr.qname; )+" >
+<!ELEMENT %tbody.qname;  %tbody.content; >
+<!-- end of tbody.element -->]]>
+
+<!ENTITY % tbody.attlist  "INCLUDE" >
+<![%tbody.attlist;[
+<!ATTLIST %tbody.qname;
+      %Common.attrib;
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of tbody.attlist -->]]>
+
+<!-- colgroup: Table Column Group ...................... -->
+
+<!-- colgroup groups a set of col elements. It allows you
+     to group several semantically-related columns together.
+-->
+
+<!ENTITY % colgroup.element  "INCLUDE" >
+<![%colgroup.element;[
+<!ENTITY % colgroup.content  "( %col.qname; )*" >
+<!ELEMENT %colgroup.qname;  %colgroup.content; >
+<!-- end of colgroup.element -->]]>
+
+<!ENTITY % colgroup.attlist  "INCLUDE" >
+<![%colgroup.attlist;[
+<!ATTLIST %colgroup.qname;
+      %Common.attrib;
+      span         %Number.datatype;        '1'
+      width        %MultiLength.datatype;   #IMPLIED
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of colgroup.attlist -->]]>
+
+<!-- col: Table Column ................................. -->
+
+<!-- col elements define the alignment properties for
+     cells in one or more columns.
+
+     The width attribute specifies the width of the
+     columns, e.g.
+
+       width="64"        width in screen pixels
+       width="0.5*"      relative width of 0.5
+
+     The span attribute causes the attributes of one
+     col element to apply to more than one column.
+-->
+
+<!ENTITY % col.element  "INCLUDE" >
+<![%col.element;[
+<!ENTITY % col.content  "EMPTY" >
+<!ELEMENT %col.qname;  %col.content; >
+<!-- end of col.element -->]]>
+
+<!ENTITY % col.attlist  "INCLUDE" >
+<![%col.attlist;[
+<!ATTLIST %col.qname;
+      %Common.attrib;
+      span         %Number.datatype;        '1'
+      width        %MultiLength.datatype;   #IMPLIED
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of col.attlist -->]]>
+
+<!-- tr: Table Row ..................................... -->
+
+<!ENTITY % tr.element  "INCLUDE" >
+<![%tr.element;[
+<!ENTITY % tr.content  "( %th.qname; | %td.qname; )+" >
+<!ELEMENT %tr.qname;  %tr.content; >
+<!-- end of tr.element -->]]>
+
+<!ENTITY % tr.attlist  "INCLUDE" >
+<![%tr.attlist;[
+<!ATTLIST %tr.qname;
+      %Common.attrib;
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of tr.attlist -->]]>
+
+<!-- th: Table Header Cell ............................. -->
+
+<!-- th is for header cells, td for data,
+     but for cells acting as both use td
+-->
+
+<!ENTITY % th.element  "INCLUDE" >
+<![%th.element;[
+<!ENTITY % th.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ELEMENT %th.qname;  %th.content; >
+<!-- end of th.element -->]]>
+
+<!ENTITY % th.attlist  "INCLUDE" >
+<![%th.attlist;[
+<!ATTLIST %th.qname;
+      %Common.attrib;
+      abbr         %Text.datatype;          #IMPLIED
+      axis         CDATA                    #IMPLIED
+      headers      IDREFS                   #IMPLIED
+      %scope.attrib;
+      rowspan      %Number.datatype;        '1'
+      colspan      %Number.datatype;        '1'
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of th.attlist -->]]>
+
+<!-- td: Table Data Cell ............................... -->
+
+<!ENTITY % td.element  "INCLUDE" >
+<![%td.element;[
+<!ENTITY % td.content
+     "( #PCDATA | %Flow.mix; )*"
+>
+<!ELEMENT %td.qname;  %td.content; >
+<!-- end of td.element -->]]>
+
+<!ENTITY % td.attlist  "INCLUDE" >
+<![%td.attlist;[
+<!ATTLIST %td.qname;
+      %Common.attrib;
+      abbr         %Text.datatype;          #IMPLIED
+      axis         CDATA                    #IMPLIED
+      headers      IDREFS                   #IMPLIED
+      %scope.attrib;
+      rowspan      %Number.datatype;        '1'
+      colspan      %Number.datatype;        '1'
+      %CellHAlign.attrib;
+      %CellVAlign.attrib;
+>
+<!-- end of td.attlist -->]]>
+
+<!-- end of xhtml-table-1.mod -->
+]]>
+
+<!-- Forms Module  ............................................... -->
+<!ENTITY % xhtml-form.module "INCLUDE" >
+<![%xhtml-form.module;[
+<!ENTITY % xhtml-form.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Forms 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-form-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Forms Module  .................................................. -->
+<!-- file: xhtml-form-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Forms 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-form-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Forms
+
+        form, label, input, select, optgroup, option,
+        textarea, fieldset, legend, button
+
+     This module declares markup to provide support for online
+     forms, based on the features found in HTML 4.0 forms.
+-->
+
+<!-- declare qualified element type names:
+-->
+<!ENTITY % form.qname  "form" >
+<!ENTITY % label.qname  "label" >
+<!ENTITY % input.qname  "input" >
+<!ENTITY % select.qname  "select" >
+<!ENTITY % optgroup.qname  "optgroup" >
+<!ENTITY % option.qname  "option" >
+<!ENTITY % textarea.qname  "textarea" >
+<!ENTITY % fieldset.qname  "fieldset" >
+<!ENTITY % legend.qname  "legend" >
+<!ENTITY % button.qname  "button" >
+
+<!-- %BlkNoForm.mix; includes all non-form block elements,
+     plus %Misc.class;
+-->
+<!ENTITY % BlkNoForm.mix
+     "%Heading.class;
+      | %List.class;
+      | %BlkStruct.class;
+      %BlkPhras.class;
+      %BlkPres.class;
+      %Table.class;
+      %Block.extra;
+      %Misc.class;"
+>
+
+<!-- form: Form Element ................................ -->
+
+<!ENTITY % form.element  "INCLUDE" >
+<![%form.element;[
+<!ENTITY % form.content
+     "( %BlkNoForm.mix;
+      | %fieldset.qname; )+"
+>
+<!ELEMENT %form.qname;  %form.content; >
+<!-- end of form.element -->]]>
+
+<!ENTITY % form.attlist  "INCLUDE" >
+<![%form.attlist;[
+<!ATTLIST %form.qname;
+      %Common.attrib;
+      action       %URI.datatype;           #REQUIRED
+      method       ( get | post )           'get'
+      enctype      %ContentType.datatype;   'application/x-www-form-urlencoded'
+      accept-charset %Charsets.datatype;    #IMPLIED
+      accept       %ContentTypes.datatype;  #IMPLIED
+>
+<!-- end of form.attlist -->]]>
+
+<!-- label: Form Field Label Text ...................... -->
+
+<!-- Each label must not contain more than ONE field
+-->
+
+<!ENTITY % label.element  "INCLUDE" >
+<![%label.element;[
+<!ENTITY % label.content
+     "( #PCDATA
+      | %input.qname; | %select.qname; | %textarea.qname; | %button.qname;
+      | %InlStruct.class;
+      %InlPhras.class;
+      %I18n.class;
+      %InlPres.class;
+      %Anchor.class;
+      %InlSpecial.class;
+      %Inline.extra;
+      %Misc.class; )*"
+>
+<!ELEMENT %label.qname;  %label.content; >
+<!-- end of label.element -->]]>
+
+<!ENTITY % label.attlist  "INCLUDE" >
+<![%label.attlist;[
+<!ATTLIST %label.qname;
+      %Common.attrib;
+      for          IDREF                    #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+>
+<!-- end of label.attlist -->]]>
+
+<!-- input: Form Control ............................... -->
+
+<!ENTITY % input.element  "INCLUDE" >
+<![%input.element;[
+<!ENTITY % input.content  "EMPTY" >
+<!ELEMENT %input.qname;  %input.content; >
+<!-- end of input.element -->]]>
+
+<!ENTITY % input.attlist  "INCLUDE" >
+<![%input.attlist;[
+<!ENTITY % InputType.class
+     "( text | password | checkbox | radio | submit
+      | reset | file | hidden | image | button )"
+>
+<!-- attribute 'name' required for all but submit & reset
+-->
+<!ATTLIST %input.qname;
+      %Common.attrib;
+      type         %InputType.class;        'text'
+      name         CDATA                    #IMPLIED
+      value        CDATA                    #IMPLIED
+      checked      ( checked )              #IMPLIED
+      disabled     ( disabled )             #IMPLIED
+      readonly     ( readonly )             #IMPLIED
+      size         %Number.datatype;        #IMPLIED
+      maxlength    %Number.datatype;        #IMPLIED
+      src          %URI.datatype;           #IMPLIED
+      alt          %Text.datatype;          #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+      accept       %ContentTypes.datatype;  #IMPLIED
+>
+<!-- end of input.attlist -->]]>
+
+<!-- select: Option Selector ........................... -->
+
+<!ENTITY % select.element  "INCLUDE" >
+<![%select.element;[
+<!ENTITY % select.content
+     "( %optgroup.qname; | %option.qname; )+"
+>
+<!ELEMENT %select.qname;  %select.content; >
+<!-- end of select.element -->]]>
+
+<!ENTITY % select.attlist  "INCLUDE" >
+<![%select.attlist;[
+<!ATTLIST %select.qname;
+      %Common.attrib;
+      name         CDATA                    #IMPLIED
+      size         %Number.datatype;        #IMPLIED
+      multiple     ( multiple )             #IMPLIED
+      disabled     ( disabled )             #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+>
+<!-- end of select.attlist -->]]>
+
+<!-- optgroup: Option Group ............................ -->
+
+<!ENTITY % optgroup.element  "INCLUDE" >
+<![%optgroup.element;[
+<!ENTITY % optgroup.content  "( %option.qname; )+" >
+<!ELEMENT %optgroup.qname;  %optgroup.content; >
+<!-- end of optgroup.element -->]]>
+
+<!ENTITY % optgroup.attlist  "INCLUDE" >
+<![%optgroup.attlist;[
+<!ATTLIST %optgroup.qname;
+      %Common.attrib;
+      disabled     ( disabled )             #IMPLIED
+      label        %Text.datatype;          #REQUIRED
+>
+<!-- end of optgroup.attlist -->]]>
+
+<!-- option: Selectable Choice ......................... -->
+
+<!ENTITY % option.element  "INCLUDE" >
+<![%option.element;[
+<!ENTITY % option.content  "( #PCDATA )" >
+<!ELEMENT %option.qname;  %option.content; >
+<!-- end of option.element -->]]>
+
+<!ENTITY % option.attlist  "INCLUDE" >
+<![%option.attlist;[
+<!ATTLIST %option.qname;
+      %Common.attrib;
+      selected     ( selected )             #IMPLIED
+      disabled     ( disabled )             #IMPLIED
+      label        %Text.datatype;          #IMPLIED
+      value        CDATA                    #IMPLIED
+>
+<!-- end of option.attlist -->]]>
+
+<!-- textarea: Multi-Line Text Field ................... -->
+
+<!ENTITY % textarea.element  "INCLUDE" >
+<![%textarea.element;[
+<!ENTITY % textarea.content  "( #PCDATA )" >
+<!ELEMENT %textarea.qname;  %textarea.content; >
+<!-- end of textarea.element -->]]>
+
+<!ENTITY % textarea.attlist  "INCLUDE" >
+<![%textarea.attlist;[
+<!ATTLIST %textarea.qname;
+      %Common.attrib;
+      name         CDATA                    #IMPLIED
+      rows         %Number.datatype;        #REQUIRED
+      cols         %Number.datatype;        #REQUIRED
+      disabled     ( disabled )             #IMPLIED
+      readonly     ( readonly )             #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+>
+<!-- end of textarea.attlist -->]]>
+
+<!-- fieldset: Form Control Group ...................... -->
+
+<!-- #PCDATA is to solve the mixed content problem,
+     per specification only whitespace is allowed
+-->
+
+<!ENTITY % fieldset.element  "INCLUDE" >
+<![%fieldset.element;[
+<!ENTITY % fieldset.content
+     "( #PCDATA | %legend.qname; | %Flow.mix; )*"
+>
+<!ELEMENT %fieldset.qname;  %fieldset.content; >
+<!-- end of fieldset.element -->]]>
+
+<!ENTITY % fieldset.attlist  "INCLUDE" >
+<![%fieldset.attlist;[
+<!ATTLIST %fieldset.qname;
+      %Common.attrib;
+>
+<!-- end of fieldset.attlist -->]]>
+
+<!-- legend: Fieldset Legend ........................... -->
+
+<!ENTITY % legend.element  "INCLUDE" >
+<![%legend.element;[
+<!ENTITY % legend.content
+     "( #PCDATA | %Inline.mix; )*"
+>
+<!ELEMENT %legend.qname;  %legend.content; >
+<!-- end of legend.element -->]]>
+
+<!ENTITY % legend.attlist  "INCLUDE" >
+<![%legend.attlist;[
+<!ATTLIST %legend.qname;
+      %Common.attrib;
+      accesskey    %Character.datatype;     #IMPLIED
+>
+<!-- end of legend.attlist -->]]>
+
+<!-- button: Push Button ............................... -->
+
+<!ENTITY % button.element  "INCLUDE" >
+<![%button.element;[
+<!ENTITY % button.content
+     "( #PCDATA
+      | %BlkNoForm.mix;
+      | %InlStruct.class;
+      %InlPhras.class;
+      %InlPres.class;
+      %I18n.class;
+      %InlSpecial.class;
+      %Inline.extra; )*"
+>
+<!ELEMENT %button.qname;  %button.content; >
+<!-- end of button.element -->]]>
+
+<!ENTITY % button.attlist  "INCLUDE" >
+<![%button.attlist;[
+<!ATTLIST %button.qname;
+      %Common.attrib;
+      name         CDATA                    #IMPLIED
+      value        CDATA                    #IMPLIED
+      type         ( button | submit | reset ) 'submit'
+      disabled     ( disabled )             #IMPLIED
+      tabindex     %Number.datatype;        #IMPLIED
+      accesskey    %Character.datatype;     #IMPLIED
+>
+<!-- end of button.attlist -->]]>
+
+<!-- end of xhtml-form-1.mod -->
+]]>
+
+<!-- Legacy Markup ............................................... -->
+<!ENTITY % xhtml-legacy.module "IGNORE" >
+<![%xhtml-legacy.module;[
+<!ENTITY % xhtml-legacy.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Legacy Markup 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-legacy-1.mod" >
+%xhtml-legacy.mod;]]>
+
+<!-- Document Structure Module (required)  ....................... -->
+<!ENTITY % xhtml-struct.module "INCLUDE" >
+<![%xhtml-struct.module;[
+<!ENTITY % xhtml-struct.mod
+     PUBLIC "-//W3C//ELEMENTS XHTML Document Structure 1.0//EN"
+            "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-struct-1.mod" >
+<!-- ...................................................................... -->
+<!-- XHTML Structure Module  .............................................. -->
+<!-- file: xhtml-struct-1.mod
+
+     This is XHTML, a reformulation of HTML as a modular XML application.
+     Copyright 1998-2001 W3C (MIT, INRIA, Keio), All Rights Reserved.
+     Revision: $Id: xhtml11-flat.dtd,v 1.1 2003/05/15 14:02:27 vgritsenko Exp $ SMI
+
+     This DTD module is identified by the PUBLIC and SYSTEM identifiers:
+
+       PUBLIC "-//W3C//ELEMENTS XHTML Document Structure 1.0//EN"
+       SYSTEM "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-struct-1.mod"
+
+     Revisions:
+     (none)
+     ....................................................................... -->
+
+<!-- Document Structure
+
+        title, head, body, html
+
+     The Structure Module defines the major structural elements and
+     their attributes.
+
+     Note that the content model of the head element type is redeclared
+     when the Base Module is included in the DTD.
+
+     The parameter entity containing the XML namespace URI value used
+     for XHTML is '%XHTML.xmlns;', defined in the Qualified Names module.
+-->
+
+<!-- title: Document Title ............................. -->
+
+<!-- The title element is not considered part of the flow of text.
+     It should be displayed, for example as the page header or
+     window title. Exactly one title is required per document.
+-->
+
+<!ENTITY % title.element  "INCLUDE" >
+<![%title.element;[
+<!ENTITY % title.content  "( #PCDATA )" >
+<!ENTITY % title.qname  "title" >
+<!ELEMENT %title.qname;  %title.content; >
+<!-- end of title.element -->]]>
+
+<!ENTITY % title.attlist  "INCLUDE" >
+<![%title.attlist;[
+<!ATTLIST %title.qname;
+      %XHTML.xmlns.attrib;
+      %I18n.attrib;
+>
+<!-- end of title.attlist -->]]>
+
+<!-- head: Document Head ............................... -->
+
+<!ENTITY % head.element  "INCLUDE" >
+<![%head.element;[
+<!ENTITY % head.content
+    "( %HeadOpts.mix;, %title.qname;, %HeadOpts.mix; )"
+>
+<!ENTITY % head.qname  "head" >
+<!ELEMENT %head.qname;  %head.content; >
+<!-- end of head.element -->]]>
+
+<!ENTITY % head.attlist  "INCLUDE" >
+<![%head.attlist;[
+<!-- reserved for future use with document profiles
+-->
+<!ENTITY % profile.attrib
+     "profile      %URI.datatype;           '%XHTML.profile;'"
+>
+
+<!ATTLIST %head.qname;
+      %XHTML.xmlns.attrib;
+      %I18n.attrib;
+      %profile.attrib;
+>
+<!-- end of head.attlist -->]]>
+
+<!-- body: Document Body ............................... -->
+
+<!ENTITY % body.element  "INCLUDE" >
+<![%body.element;[
+<!ENTITY % body.content
+     "( %Block.mix; )+"
+>
+<!ENTITY % body.qname  "body" >
+<!ELEMENT %body.qname;  %body.content; >
+<!-- end of body.element -->]]>
+
+<!ENTITY % body.attlist  "INCLUDE" >
+<![%body.attlist;[
+<!ATTLIST %body.qname;
+      %Common.attrib;
+>
+<!-- end of body.attlist -->]]>
+
+<!-- html: XHTML Document Element ...................... -->
+
+<!ENTITY % html.element  "INCLUDE" >
+<![%html.element;[
+<!ENTITY % html.content  "( %head.qname;, %body.qname; )" >
+<!ENTITY % html.qname  "html" >
+<!ELEMENT %html.qname;  %html.content; >
+<!-- end of html.element -->]]>
+
+<!ENTITY % html.attlist  "INCLUDE" >
+<![%html.attlist;[
+<!-- version attribute value defined in driver
+-->
+<!ENTITY % XHTML.version.attrib
+     "version      %FPI.datatype;           #FIXED '%XHTML.version;'"
+>
+
+<!-- see the Qualified Names module for information
+     on how to extend XHTML using XML namespaces
+-->
+<!ATTLIST %html.qname;
+      %XHTML.xmlns.attrib;
+      %XHTML.version.attrib;
+      %I18n.attrib;
+>
+<!-- end of html.attlist -->]]>
+
+<!-- end of xhtml-struct-1.mod -->
+]]>
+
+<!-- end of XHTML 1.1 DTD  ................................................. -->
+<!-- ....................................................................... -->
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/web-app_2_3.dtd b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/web-app_2_3.dtd
new file mode 100644
index 0000000..5e3ab01
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/web-app_2_3.dtd
@@ -0,0 +1,1063 @@
+<!--
+Copyright (c) 2000 Sun Microsystems, Inc.,
+901 San Antonio Road,
+Palo Alto, California 94303, U.S.A.
+All rights reserved.
+
+Sun Microsystems, Inc. has intellectual property rights relating to
+technology embodied in the product that is described in this document.
+In particular, and without limitation, these intellectual property
+rights may include one or more of the U.S. patents listed at
+http://www.sun.com/patents and one or more additional patents or
+pending patent applications in the U.S. and in other countries.
+
+This document and the product to which it pertains are distributed
+under licenses restricting their use, copying, distribution, and
+decompilation.  This document may be reproduced and distributed but may
+not be changed without prior written authorization of Sun and its
+licensors, if any.
+
+Third-party software, including font technology, is copyrighted and
+licensed from Sun suppliers.
+
+Sun,  Sun Microsystems,  the Sun logo,  Java,  JavaServer Pages,  Java
+Naming and Directory Interface,  JDBC,  JDK,  JavaMail and  and
+Enterprise JavaBeans are trademarks or registered trademarks of Sun
+Microsystems, Inc. in the U.S. and other countries.
+
+Federal Acquisitions: Commercial Software - Government Users Subject to
+Standard License Terms and Conditions.
+
+DOCUMENTATION IS PROVIDED "AS IS" AND ALL EXPRESS OR IMPLIED
+CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED
+WARRANTY OF MERCHANTABILITY, FITNESS FOR FOR A PARTICULAR PURPOSE OR
+NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
+DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.
+
+
+_________________________________________________________________________
+
+Copyright (c) 2000 Sun Microsystems, Inc.,
+901 San Antonio Road,
+Palo Alto, California 94303, E'tats-Unis.
+Tous droits re'serve's.
+
+Sun Microsystems, Inc. a les droits de proprie'te' intellectuels
+relatants a` la technologie incorpore'e dans le produit qui est de'crit
+dans ce document. En particulier, et sans la limitation, ces droits de
+proprie'te' intellectuels peuvent inclure un ou plus des brevets
+ame'ricains e'nume're's a` http://www.sun.com/patents et un ou les
+brevets plus supple'mentaires ou les applications de brevet en attente
+dans les E'tats-Unis et dans les autres pays.
+
+Ce produit ou document est prote'ge' par un copyright et distribue'
+avec des licences qui en restreignent l'utilisation, la copie, la
+distribution, et la de'compilation.  Ce documention associe n peut
+e^tre reproduite et distribuer, par quelque moyen que ce soit, sans
+l'autorisation pre'alable et e'crite de Sun et de ses bailleurs de
+licence, le cas e'che'ant.
+
+Le logiciel de'tenu par des tiers, et qui comprend la technologie
+relative aux polices de caracte`res, est prote'ge' par un copyright et
+licencie' par des fournisseurs de Sun.
+
+Sun,  Sun Microsystems,  le logo Sun,  Java,  JavaServer Pages,  Java
+Naming and Directory Interface,  JDBC,  JDK,  JavaMail et  and
+Enterprise JavaBeans sont des marques de fabrique ou des marques
+de'pose'es de Sun Microsystems, Inc. aux E'tats-Unis et dans d'autres
+pays.
+
+LA DOCUMENTATION EST FOURNIE "EN L'E'TAT" ET TOUTES AUTRES CONDITIONS,
+DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT FORMELLEMENT
+EXCLUES, DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE, Y COMPRIS
+NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE MARCHANDE, A
+L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE DE
+CONTREFAC,ON.
+-->
+
+<!--
+This is the XML DTD for the Servlet 2.3 deployment descriptor.
+All Servlet 2.3 deployment descriptors must include a DOCTYPE
+of the following form:
+
+  <!DOCTYPE web-app PUBLIC
+	"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+	"http://java.sun.com/dtd/web-app_2_3.dtd">
+
+-->
+
+<!--
+The following conventions apply to all J2EE deployment descriptor
+elements unless indicated otherwise.
+
+- In elements that contain PCDATA, leading and trailing whitespace
+  in the data may be ignored.
+
+- In elements whose value is an "enumerated type", the value is
+  case sensitive.
+
+- In elements that specify a pathname to a file within the same
+  JAR file, relative filenames (i.e., those not starting with "/")
+  are considered relative to the root of the JAR file's namespace.
+  Absolute filenames (i.e., those starting with "/") also specify
+  names in the root of the JAR file's namespace.  In general, relative
+  names are preferred.  The exception is .war files where absolute
+  names are preferred for consistency with the servlet API.
+-->
+
+
+<!--
+The web-app element is the root of the deployment descriptor for
+a web application.
+-->
+<!ELEMENT web-app (icon?, display-name?, description?, distributable?,
+context-param*, filter*, filter-mapping*, listener*, servlet*,
+servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,
+error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,
+login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>
+
+<!--
+The auth-constraint element indicates the user roles that should
+be permitted access to this resource collection. The role-name
+used here must either correspond to the role-name of one of the
+security-role elements defined for this web application, or be
+the specially reserved role-name "*" that is a compact syntax for
+indicating all roles in the web application. If both "*" and
+rolenames appear, the container interprets this as all roles.
+If no roles are defined, no user is allowed access to the portion of
+the web application described by the containing security-constraint.
+The container matches role names case sensitively when determining
+access.
+
+
+Used in: security-constraint
+-->
+<!ELEMENT auth-constraint (description?, role-name*)>
+
+<!--
+The auth-method element is used to configure the authentication
+mechanism for the web application. As a prerequisite to gaining access to any web resources which are protected by an authorization
+constraint, a user must have authenticated using the configured
+mechanism. Legal values for this element are "BASIC", "DIGEST",
+"FORM", or "CLIENT-CERT".
+
+Used in: login-config
+-->
+<!ELEMENT auth-method (#PCDATA)>
+
+<!--
+The context-param element contains the declaration of a web
+application's servlet context initialization parameters.
+
+Used in: web-app
+-->
+<!ELEMENT context-param (param-name, param-value, description?)>
+
+<!--
+The description element is used to provide text describing the parent
+element.  The description element should include any information that
+the web application war file producer wants to provide to the consumer of
+the web application war file (i.e., to the Deployer). Typically, the tools
+used by the web application war file consumer will display the description
+when processing the parent element that contains the description.
+
+Used in: auth-constraint, context-param, ejb-local-ref, ejb-ref,
+env-entry, filter, init-param, resource-env-ref, resource-ref, run-as,
+security-role, security-role-ref, servlet, user-data-constraint,
+web-app, web-resource-collection
+-->
+<!ELEMENT description (#PCDATA)>
+
+<!--
+The display-name element contains a short name that is intended to be
+displayed by tools.  The display name need not be unique.
+
+Used in: filter, security-constraint, servlet, web-app
+
+Example:
+
+<display-name>Employee Self Service</display-name>
+-->
+<!ELEMENT display-name (#PCDATA)>
+
+<!--
+The distributable element, by its presence in a web application
+deployment descriptor, indicates that this web application is
+programmed appropriately to be deployed into a distributed servlet
+container
+
+Used in: web-app
+-->
+<!ELEMENT distributable EMPTY>
+
+<!--
+The ejb-link element is used in the ejb-ref or ejb-local-ref
+elements to specify that an EJB reference is linked to an
+enterprise bean.
+
+The name in the ejb-link element is composed of a
+path name specifying the ejb-jar containing the referenced enterprise
+bean with the ejb-name of the target bean appended and separated from
+the path name by "#".  The path name is relative to the war file
+containing the web application that is referencing the enterprise bean.
+This allows multiple enterprise beans with the same ejb-name to be
+uniquely identified.
+
+Used in: ejb-local-ref, ejb-ref
+
+Examples:
+
+	<ejb-link>EmployeeRecord</ejb-link>
+
+	<ejb-link>../products/product.jar#ProductEJB</ejb-link>
+
+-->
+<!ELEMENT ejb-link (#PCDATA)>
+
+<!--
+The ejb-local-ref element is used for the declaration of a reference to
+an enterprise bean's local home. The declaration consists of:
+
+	- an optional description
+	- the EJB reference name used in the code of the web application
+	  that's referencing the enterprise bean
+	- the expected type of the referenced enterprise bean
+	- the expected local home and local interfaces of the referenced
+	  enterprise bean
+	- optional ejb-link information, used to specify the referenced
+	  enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-local-ref (description?, ejb-ref-name, ejb-ref-type,
+		local-home, local, ejb-link?)>
+
+<!--
+The ejb-ref element is used for the declaration of a reference to
+an enterprise bean's home. The declaration consists of:
+
+	- an optional description
+	- the EJB reference name used in the code of
+	  the web application that's referencing the enterprise bean
+	- the expected type of the referenced enterprise bean
+	- the expected home and remote interfaces of the referenced
+	  enterprise bean
+	- optional ejb-link information, used to specify the referenced
+	  enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-ref (description?, ejb-ref-name, ejb-ref-type,
+		home, remote, ejb-link?)>
+
+<!--
+The ejb-ref-name element contains the name of an EJB reference. The
+EJB reference is an entry in the web application's environment and is
+relative to the java:comp/env context.  The name must be unique
+within the web application.
+
+It is recommended that name is prefixed with "ejb/".
+
+Used in: ejb-local-ref, ejb-ref
+
+Example:
+
+<ejb-ref-name>ejb/Payroll</ejb-ref-name>
+-->
+<!ELEMENT ejb-ref-name (#PCDATA)>
+
+<!--
+The ejb-ref-type element contains the expected type of the
+referenced enterprise bean.
+
+The ejb-ref-type element must be one of the following:
+
+	<ejb-ref-type>Entity</ejb-ref-type>
+	<ejb-ref-type>Session</ejb-ref-type>
+
+Used in: ejb-local-ref, ejb-ref
+-->
+<!ELEMENT ejb-ref-type (#PCDATA)>
+
+<!--
+The env-entry element contains the declaration of a web application's
+environment entry. The declaration consists of an optional
+description, the name of the environment entry, and an optional
+value.  If a value is not specified, one must be supplied
+during deployment.
+-->
+<!ELEMENT env-entry (description?, env-entry-name, env-entry-value?,
+env-entry-type)>
+
+<!--
+The env-entry-name element contains the name of a web applications's
+environment entry.  The name is a JNDI name relative to the
+java:comp/env context.  The name must be unique within a web application.
+
+Example:
+
+<env-entry-name>minAmount</env-entry-name>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-name (#PCDATA)>
+
+<!--
+The env-entry-type element contains the fully-qualified Java type of
+the environment entry value that is expected by the web application's
+code.
+
+The following are the legal values of env-entry-type:
+
+	java.lang.Boolean
+	java.lang.Byte
+	java.lang.Character
+	java.lang.String
+	java.lang.Short
+	java.lang.Integer
+	java.lang.Long
+	java.lang.Float
+	java.lang.Double
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-type (#PCDATA)>
+
+<!--
+The env-entry-value element contains the value of a web application's
+environment entry. The value must be a String that is valid for the
+constructor of the specified type that takes a single String
+parameter, or for java.lang.Character, a single character.
+
+Example:
+
+<env-entry-value>100.00</env-entry-value>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-value (#PCDATA)>
+
+<!--
+The error-code contains an HTTP error code, ex: 404
+
+Used in: error-page
+-->
+<!ELEMENT error-code (#PCDATA)>
+
+<!--
+The error-page element contains a mapping between an error code
+or exception type to the path of a resource in the web application
+
+Used in: web-app
+-->
+<!ELEMENT error-page ((error-code | exception-type), location)>
+
+<!--
+The exception type contains a fully qualified class name of a
+Java exception type.
+
+Used in: error-page
+-->
+<!ELEMENT exception-type (#PCDATA)>
+
+<!--
+The extension element contains a string describing an
+extension. example: "txt"
+
+Used in: mime-mapping
+-->
+<!ELEMENT extension (#PCDATA)>
+
+<!--
+Declares a filter in the web application. The filter is mapped to
+either a servlet or a URL pattern in the filter-mapping element, using
+the filter-name value to reference. Filters can access the
+initialization parameters declared in the deployment descriptor at
+runtime via the FilterConfig interface.
+
+Used in: web-app
+-->
+<!ELEMENT filter (icon?, filter-name, display-name?, description?,
+filter-class, init-param*)>
+
+<!--
+The fully qualified classname of the filter.
+
+Used in: filter
+-->
+<!ELEMENT filter-class (#PCDATA)>
+
+<!--
+Declaration of the filter mappings in this web application. The
+container uses the filter-mapping declarations to decide which filters
+to apply to a request, and in what order. The container matches the
+request URI to a Servlet in the normal way. To determine which filters
+to apply it matches filter-mapping declarations either on servlet-name,
+or on url-pattern for each filter-mapping element, depending on which
+style is used. The order in which filters are invoked is the order in
+which filter-mapping declarations that match a request URI for a
+servlet appear in the list of filter-mapping elements.The filter-name
+value must be the value of the <filter-name> sub-elements of one of the
+<filter> declarations in the deployment descriptor.
+
+Used in: web-app
+-->
+<!ELEMENT filter-mapping (filter-name, (url-pattern | servlet-name))>
+
+<!--
+The logical name of the filter. This name is used to map the filter.
+Each filter name is unique within the web application.
+
+Used in: filter, filter-mapping
+-->
+<!ELEMENT filter-name (#PCDATA)>
+
+<!--
+The form-error-page element defines the location in the web app
+where the error page that is displayed when login is not successful
+can be found. The path begins with a leading / and is interpreted
+relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-error-page (#PCDATA)>
+
+<!--
+The form-login-config element specifies the login and error pages
+that should be used in form based login. If form based authentication
+is not used, these elements are ignored.
+
+Used in: login-config
+-->
+<!ELEMENT form-login-config (form-login-page, form-error-page)>
+
+<!--
+The form-login-page element defines the location in the web app
+where the page that can be used for login can be found. The path
+begins with a leading / and is interpreted relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-login-page (#PCDATA)>
+
+<!--
+The home element contains the fully-qualified name of the enterprise
+bean's home interface.
+
+Used in: ejb-ref
+
+Example:
+
+<home>com.aardvark.payroll.PayrollHome</home>
+-->
+<!ELEMENT home (#PCDATA)>
+
+<!--
+The http-method contains an HTTP method (GET | POST |...).
+
+Used in: web-resource-collection
+-->
+<!ELEMENT http-method (#PCDATA)>
+
+<!--
+The icon element contains small-icon and large-icon elements that
+specify the file names for small and a large GIF or JPEG icon images
+used to represent the parent element in a GUI tool.
+
+Used in: filter, servlet, web-app
+-->
+<!ELEMENT icon (small-icon?, large-icon?)>
+
+<!--
+The init-param element contains a name/value pair as an
+initialization param of the servlet
+
+Used in: filter, servlet
+-->
+<!ELEMENT init-param (param-name, param-value, description?)>
+
+<!--
+The jsp-file element contains the full path to a JSP file within
+the web application beginning with a `/'.
+
+Used in: servlet
+-->
+<!ELEMENT jsp-file (#PCDATA)>
+
+<!--
+The large-icon element contains the name of a file
+containing a large (32 x 32) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<large-icon>employee-service-icon32x32.jpg</large-icon>
+-->
+<!ELEMENT large-icon (#PCDATA)>
+
+<!--
+The listener element indicates the deployment properties for a web
+application listener bean.
+
+Used in: web-app
+-->
+<!ELEMENT listener (listener-class)>
+
+<!--
+The listener-class element declares a class in the application must be
+registered as a web application listener bean. The value is the fully qualified classname of the listener class.
+
+
+Used in: listener
+-->
+<!ELEMENT listener-class (#PCDATA)>
+
+<!--
+The load-on-startup element indicates that this servlet should be
+loaded (instantiated and have its init() called) on the startup
+of the web application. The optional contents of
+these element must be an integer indicating the order in which
+the servlet should be loaded. If the value is a negative integer,
+or the element is not present, the container is free to load the
+servlet whenever it chooses. If the value is a positive integer
+or 0, the container must load and initialize the servlet as the
+application is deployed. The container must guarantee that
+servlets marked with lower integers are loaded before servlets
+marked with higher integers. The container may choose the order
+of loading of servlets with the same load-on-start-up value.
+
+Used in: servlet
+-->
+<!ELEMENT load-on-startup (#PCDATA)>
+
+<!--
+
+The local element contains the fully-qualified name of the
+enterprise bean's local interface.
+
+Used in: ejb-local-ref
+
+-->
+<!ELEMENT local (#PCDATA)>
+
+<!--
+
+The local-home element contains the fully-qualified name of the
+enterprise bean's local home interface.
+
+Used in: ejb-local-ref
+-->
+<!ELEMENT local-home (#PCDATA)>
+
+<!--
+The location element contains the location of the resource in the web
+application relative to the root of the web application. The value of
+the location must have a leading `/'.
+
+Used in: error-page
+-->
+<!ELEMENT location (#PCDATA)>
+
+<!--
+The login-config element is used to configure the authentication
+method that should be used, the realm name that should be used for
+this application, and the attributes that are needed by the form login
+mechanism.
+
+Used in: web-app
+-->
+<!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>
+
+<!--
+The mime-mapping element defines a mapping between an extension
+and a mime type.
+
+Used in: web-app
+-->
+<!ELEMENT mime-mapping (extension, mime-type)>
+
+<!--
+The mime-type element contains a defined mime type. example:
+"text/plain"
+
+Used in: mime-mapping
+-->
+<!ELEMENT mime-type (#PCDATA)>
+
+<!--
+The param-name element contains the name of a parameter. Each parameter
+name must be unique in the web application.
+
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-name (#PCDATA)>
+
+<!--
+The param-value element contains the value of a parameter.
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-value (#PCDATA)>
+
+<!--
+The realm name element specifies the realm name to use in HTTP
+Basic authorization.
+
+Used in: login-config
+-->
+<!ELEMENT realm-name (#PCDATA)>
+
+<!--
+The remote element contains the fully-qualified name of the enterprise
+bean's remote interface.
+
+Used in: ejb-ref
+
+Example:
+
+<remote>com.wombat.empl.EmployeeService</remote>
+-->
+<!ELEMENT remote (#PCDATA)>
+
+<!--
+The res-auth element specifies whether the web application code signs
+on programmatically to the resource manager, or whether the Container
+will sign on to the resource manager on behalf of the web application. In the
+latter case, the Container uses information that is supplied by the
+Deployer.
+
+The value of this element must be one of the two following:
+
+	<res-auth>Application</res-auth>
+	<res-auth>Container</res-auth>
+
+Used in: resource-ref
+-->
+<!ELEMENT res-auth (#PCDATA)>
+
+<!--
+The res-ref-name element specifies the name of a resource manager
+connection factory reference.  The name is a JNDI name relative to the
+java:comp/env context.  The name must be unique within a web application.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-ref-name (#PCDATA)>
+
+<!--
+The res-sharing-scope element specifies whether connections obtained
+through the given resource manager connection factory reference can be
+shared. The value of this element, if specified, must be one of the
+two following:
+
+	<res-sharing-scope>Shareable</res-sharing-scope>
+	<res-sharing-scope>Unshareable</res-sharing-scope>
+
+The default value is Shareable.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-sharing-scope (#PCDATA)>
+
+<!--
+The res-type element specifies the type of the data source. The type
+is specified by the fully qualified Java language class or interface
+expected to be implemented by the data source.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-type (#PCDATA)>
+
+<!--
+The resource-env-ref element contains a declaration of a web application's
+reference to an administered object associated with a resource
+in the web application's environment.  It consists of an optional
+description, the resource environment reference name, and an
+indication of the resource environment reference type expected by
+the web application code.
+
+Used in: web-app
+
+Example:
+
+<resource-env-ref>
+    <resource-env-ref-name>jms/StockQueue</resource-env-ref-name>
+    <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
+</resource-env-ref>
+-->
+<!ELEMENT resource-env-ref (description?, resource-env-ref-name,
+		resource-env-ref-type)>
+
+<!--
+The resource-env-ref-name element specifies the name of a resource
+environment reference; its value is the environment entry name used in
+the web application code.  The name is a JNDI name relative to the
+java:comp/env context and must be unique within a web application.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-name (#PCDATA)>
+
+<!--
+The resource-env-ref-type element specifies the type of a resource
+environment reference.  It is the fully qualified name of a Java
+language class or interface.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-type (#PCDATA)>
+
+<!--
+The resource-ref element contains a declaration of a web application's
+reference to an external resource. It consists of an optional
+description, the resource manager connection factory reference name,
+the indication of the resource manager connection factory type
+expected by the web application code, the type of authentication
+(Application or Container), and an optional specification of the
+shareability of connections obtained from the resource (Shareable or
+Unshareable).
+
+Used in: web-app
+
+Example:
+
+    <resource-ref>
+	<res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
+	<res-type>javax.sql.DataSource</res-type>
+	<res-auth>Container</res-auth>
+	<res-sharing-scope>Shareable</res-sharing-scope>
+    </resource-ref>
+-->
+<!ELEMENT resource-ref (description?, res-ref-name, res-type, res-auth,
+		res-sharing-scope?)>
+
+<!--
+The role-link element is a reference to a defined security role. The
+role-link element must contain the name of one of the security roles
+defined in the security-role elements.
+
+Used in: security-role-ref
+-->
+<!ELEMENT role-link (#PCDATA)>
+
+<!--
+The role-name element contains the name of a security role.
+
+The name must conform to the lexical rules for an NMTOKEN.
+
+Used in: auth-constraint, run-as, security-role, security-role-ref
+-->
+<!ELEMENT role-name (#PCDATA)>
+
+<!--
+The run-as element specifies the run-as identity to be used for the
+execution of the web application. It contains an optional description, and
+the name of a security role.
+
+Used in: servlet
+-->
+<!ELEMENT run-as (description?, role-name)>
+
+<!--
+The security-constraint element is used to associate security
+constraints with one or more web resource collections
+
+Used in: web-app
+-->
+<!ELEMENT security-constraint (display-name?, web-resource-collection+,
+auth-constraint?, user-data-constraint?)>
+
+<!--
+The security-role element contains the definition of a security
+role. The definition consists of an optional description of the
+security role, and the security role name.
+
+Used in: web-app
+
+Example:
+
+    <security-role>
+	<description>
+	    This role includes all employees who are authorized
+	    to access the employee service application.
+	</description>
+	<role-name>employee</role-name>
+    </security-role>
+-->
+<!ELEMENT security-role (description?, role-name)>
+
+<!--
+The security-role-ref element contains the declaration of a security
+role reference in the web application's code. The declaration consists
+of an optional description, the security role name used in the code,
+and an optional link to a security role. If the security role is not
+specified, the Deployer must choose an appropriate security role.
+
+The value of the role-name element must be the String used as the
+parameter to the EJBContext.isCallerInRole(String roleName) method
+or the HttpServletRequest.isUserInRole(String role) method.
+
+Used in: servlet
+
+-->
+<!ELEMENT security-role-ref (description?, role-name, role-link?)>
+
+<!--
+The servlet element contains the declarative data of a
+servlet. If a jsp-file is specified and the load-on-startup element is
+present, then the JSP should be precompiled and loaded.
+
+Used in: web-app
+-->
+<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,
+(servlet-class|jsp-file), init-param*, load-on-startup?, run-as?, security-role-ref*)>
+
+<!--
+The servlet-class element contains the fully qualified class name
+of the servlet.
+
+Used in: servlet
+-->
+<!ELEMENT servlet-class (#PCDATA)>
+
+<!--
+The servlet-mapping element defines a mapping between a servlet
+and a url pattern
+
+Used in: web-app
+-->
+<!ELEMENT servlet-mapping (servlet-name, url-pattern)>
+
+<!--
+The servlet-name element contains the canonical name of the
+servlet. Each servlet name is unique within the web application.
+
+Used in: filter-mapping, servlet, servlet-mapping
+-->
+<!ELEMENT servlet-name (#PCDATA)>
+
+<!--
+The session-config element defines the session parameters for
+this web application.
+
+Used in: web-app
+-->
+<!ELEMENT session-config (session-timeout?)>
+
+<!--
+The session-timeout element defines the default session timeout
+interval for all sessions created in this web application. The
+specified timeout must be expressed in a whole number of minutes.
+If the timeout is 0 or less, the container ensures the default
+behaviour of sessions is never to time out.
+
+Used in: session-config
+-->
+<!ELEMENT session-timeout (#PCDATA)>
+
+<!--
+The small-icon element contains the name of a file
+containing a small (16 x 16) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<small-icon>employee-service-icon16x16.jpg</small-icon>
+-->
+<!ELEMENT small-icon (#PCDATA)>
+
+<!--
+The taglib element is used to describe a JSP tag library.
+
+Used in: web-app
+-->
+<!ELEMENT taglib (taglib-uri, taglib-location)>
+
+<!--
+the taglib-location element contains the location (as a resource
+relative to the root of the web application) where to find the Tag
+Libary Description file for the tag library.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-location (#PCDATA)>
+
+<!--
+The taglib-uri element describes a URI, relative to the location
+of the web.xml document, identifying a Tag Library used in the Web
+Application.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-uri (#PCDATA)>
+
+<!--
+The transport-guarantee element specifies that the communication
+between client and server should be NONE, INTEGRAL, or
+CONFIDENTIAL. NONE means that the application does not require any
+transport guarantees. A value of INTEGRAL means that the application
+requires that the data sent between the client and server be sent in
+such a way that it can't be changed in transit. CONFIDENTIAL means
+that the application requires that the data be transmitted in a
+fashion that prevents other entities from observing the contents of
+the transmission. In most cases, the presence of the INTEGRAL or
+CONFIDENTIAL flag will indicate that the use of SSL is required.
+
+Used in: user-data-constraint
+-->
+<!ELEMENT transport-guarantee (#PCDATA)>
+
+<!--
+The url-pattern element contains the url pattern of the mapping. Must
+follow the rules specified in Section 11.2 of the Servlet API
+Specification.
+
+Used in: filter-mapping, servlet-mapping, web-resource-collection
+-->
+<!ELEMENT url-pattern (#PCDATA)>
+
+<!--
+The user-data-constraint element is used to indicate how data
+communicated between the client and container should be protected.
+
+Used in: security-constraint
+-->
+<!ELEMENT user-data-constraint (description?, transport-guarantee)>
+
+<!--
+The web-resource-collection element is used to identify a subset
+of the resources and HTTP methods on those resources within a web
+application to which a security constraint applies. If no HTTP methods
+are specified, then the security constraint applies to all HTTP
+methods.
+
+Used in: security-constraint
+-->
+<!ELEMENT web-resource-collection (web-resource-name, description?,
+url-pattern*, http-method*)>
+
+<!--
+The web-resource-name contains the name of this web resource
+collection.
+
+Used in: web-resource-collection
+-->
+<!ELEMENT web-resource-name (#PCDATA)>
+
+<!--
+The welcome-file element contains file name to use as a default
+welcome file, such as index.html
+
+Used in: welcome-file-list
+-->
+<!ELEMENT welcome-file (#PCDATA)>
+
+<!--
+The welcome-file-list contains an ordered list of welcome files
+elements.
+
+Used in: web-app
+-->
+<!ELEMENT welcome-file-list (welcome-file+)>
+
+<!--
+The ID mechanism is to allow tools that produce additional deployment
+information (i.e., information beyond the standard deployment
+descriptor information) to store the non-standard information in a
+separate file, and easily refer from these tool-specific files to the
+information in the standard deployment descriptor.
+
+Tools are not allowed to add the non-standard information into the
+standard deployment descriptor.
+-->
+
+<!ATTLIST auth-constraint id ID #IMPLIED>
+<!ATTLIST auth-method id ID #IMPLIED>
+<!ATTLIST context-param id ID #IMPLIED>
+<!ATTLIST description id ID #IMPLIED>
+<!ATTLIST display-name id ID #IMPLIED>
+<!ATTLIST distributable id ID #IMPLIED>
+<!ATTLIST ejb-link id ID #IMPLIED>
+<!ATTLIST ejb-local-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref-name id ID #IMPLIED>
+<!ATTLIST ejb-ref-type id ID #IMPLIED>
+<!ATTLIST env-entry id ID #IMPLIED>
+<!ATTLIST env-entry-name id ID #IMPLIED>
+<!ATTLIST env-entry-type id ID #IMPLIED>
+<!ATTLIST env-entry-value id ID #IMPLIED>
+<!ATTLIST error-code id ID #IMPLIED>
+<!ATTLIST error-page id ID #IMPLIED>
+<!ATTLIST exception-type id ID #IMPLIED>
+<!ATTLIST extension id ID #IMPLIED>
+<!ATTLIST filter id ID #IMPLIED>
+<!ATTLIST filter-class id ID #IMPLIED>
+<!ATTLIST filter-mapping id ID #IMPLIED>
+<!ATTLIST filter-name id ID #IMPLIED>
+<!ATTLIST form-error-page id ID #IMPLIED>
+<!ATTLIST form-login-config id ID #IMPLIED>
+<!ATTLIST form-login-page id ID #IMPLIED>
+<!ATTLIST home id ID #IMPLIED>
+<!ATTLIST http-method id ID #IMPLIED>
+<!ATTLIST icon id ID #IMPLIED>
+<!ATTLIST init-param id ID #IMPLIED>
+<!ATTLIST jsp-file id ID #IMPLIED>
+<!ATTLIST large-icon id ID #IMPLIED>
+<!ATTLIST listener id ID #IMPLIED>
+<!ATTLIST listener-class id ID #IMPLIED>
+<!ATTLIST load-on-startup id ID #IMPLIED>
+<!ATTLIST local id ID #IMPLIED>
+<!ATTLIST local-home id ID #IMPLIED>
+<!ATTLIST location id ID #IMPLIED>
+<!ATTLIST login-config id ID #IMPLIED>
+<!ATTLIST mime-mapping id ID #IMPLIED>
+<!ATTLIST mime-type id ID #IMPLIED>
+<!ATTLIST param-name id ID #IMPLIED>
+<!ATTLIST param-value id ID #IMPLIED>
+<!ATTLIST realm-name id ID #IMPLIED>
+<!ATTLIST remote id ID #IMPLIED>
+<!ATTLIST res-auth id ID #IMPLIED>
+<!ATTLIST res-ref-name id ID #IMPLIED>
+<!ATTLIST res-sharing-scope id ID #IMPLIED>
+<!ATTLIST res-type id ID #IMPLIED>
+<!ATTLIST resource-env-ref id ID #IMPLIED>
+<!ATTLIST resource-env-ref-name id ID #IMPLIED>
+<!ATTLIST resource-env-ref-type id ID #IMPLIED>
+<!ATTLIST resource-ref id ID #IMPLIED>
+<!ATTLIST role-link id ID #IMPLIED>
+<!ATTLIST role-name id ID #IMPLIED>
+<!ATTLIST run-as id ID #IMPLIED>
+<!ATTLIST security-constraint id ID #IMPLIED>
+<!ATTLIST security-role id ID #IMPLIED>
+<!ATTLIST security-role-ref id ID #IMPLIED>
+<!ATTLIST servlet id ID #IMPLIED>
+<!ATTLIST servlet-class id ID #IMPLIED>
+<!ATTLIST servlet-mapping id ID #IMPLIED>
+<!ATTLIST servlet-name id ID #IMPLIED>
+<!ATTLIST session-config id ID #IMPLIED>
+<!ATTLIST session-timeout id ID #IMPLIED>
+<!ATTLIST small-icon id ID #IMPLIED>
+<!ATTLIST taglib id ID #IMPLIED>
+<!ATTLIST taglib-location id ID #IMPLIED>
+<!ATTLIST taglib-uri id ID #IMPLIED>
+<!ATTLIST transport-guarantee id ID #IMPLIED>
+<!ATTLIST url-pattern id ID #IMPLIED>
+<!ATTLIST user-data-constraint id ID #IMPLIED>
+<!ATTLIST web-app id ID #IMPLIED>
+<!ATTLIST web-resource-collection id ID #IMPLIED>
+<!ATTLIST web-resource-name id ID #IMPLIED>
+<!ATTLIST welcome-file id ID #IMPLIED>
+<!ATTLIST welcome-file-list id ID #IMPLIED>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/xslt-20020523.rng b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/xslt-20020523.rng
new file mode 100644
index 0000000..a23200e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/entities/xslt-20020523.rng
@@ -0,0 +1,897 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Id: xslt.rng,v 1.9 2002/05/23 09:39:03 jjc Exp $ -->
+<!-- http://www.thaiopensource.com/relaxng/xslt.rng -->
+<!-- This was mostly generated from the syntax summary in the XSLT
+     Recommendation (using XSLT of course). -->
+<!-- Issues: this validates extension elements as literal result
+     elements, which is overly restrictive. -->
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+         ns="http://www.w3.org/1999/XSL/Transform"
+         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+   <start>
+      <choice>
+         <ref name="stylesheet.element"/>
+         <ref name="transform.element"/>
+         <ref name="literal-result-element-as-stylesheet"/>
+      </choice>
+   </start>
+   <define name="version">
+      <value>1.0</value>
+   </define>
+   <define name="top-level-elements.model">
+      <zeroOrMore>
+         <choice>
+            <ref name="top-level-element.category"/>
+            <ref name="top-level-extension"/>
+         </choice>
+      </zeroOrMore>
+   </define>
+   <define name="top-level-extension">
+      <element>
+         <anyName>
+            <except>
+               <nsName/>
+               <nsName ns=""/>
+            </except>
+         </anyName>
+         <grammar>
+            <start>
+              <ref name="any"/>
+            </start>
+            <define name="any">
+	       <zeroOrMore>
+		  <choice>
+		     <attribute>
+			<anyName/>
+		     </attribute>
+		     <text/>
+		     <element>
+			<anyName/>
+			<ref name="any"/>
+		     </element>
+		  </choice>
+	       </zeroOrMore>
+            </define>
+         </grammar>
+      </element>
+   </define>
+   <define name="template.model">
+      <zeroOrMore>
+         <choice>
+            <ref name="instruction.category"/>
+            <ref name="literal-result-element"/>
+            <text/>
+         </choice>
+      </zeroOrMore>
+   </define>
+   <define name="literal-result-element-as-stylesheet">
+      <element>
+         <anyName>
+            <except>
+               <nsName/>
+            </except>
+         </anyName>
+         <attribute>
+            <name>version</name>
+            <ref name="version"/>
+         </attribute>
+         <ref name="literal-result-element-no-version.atts"/>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="literal-result-element">
+      <element>
+         <anyName>
+            <except>
+               <nsName/>
+            </except>
+         </anyName>
+         <ref name="literal-result-element.atts"/>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="literal-result-element.atts">
+      <ref name="literal-result-element-no-version.atts"/>
+      <optional>
+	 <attribute>
+	    <name>version</name>
+	    <ref name="version"/>
+	 </attribute>
+      </optional>
+   </define>
+   <define name="literal-result-element-no-version.atts">
+      <zeroOrMore>
+         <choice>
+            <attribute>
+	       <anyName>
+		  <except>
+		     <nsName/>
+		  </except>
+	       </anyName>
+               <ref name="avt.datatype"/>
+            </attribute>
+            <attribute>
+               <name>extension-element-prefixes</name>
+               <ref name="prefixes.datatype"/>
+	    </attribute>
+            <attribute>
+               <name>exclude-result-prefixes</name>
+               <ref name="prefixes.datatype"/>
+	    </attribute>
+            <attribute>
+               <name>use-attribute-sets</name>
+               <ref name="qnames.datatype"/>
+            </attribute>
+         </choice>
+      </zeroOrMore>
+   </define>
+   <define name="top-level-element.category">
+      <choice>
+         <ref name="include.element"/>
+         <ref name="strip-space.element"/>
+         <ref name="preserve-space.element"/>
+         <ref name="template.element"/>
+         <ref name="namespace-alias.element"/>
+         <ref name="attribute-set.element"/>
+         <ref name="variable.element"/>
+         <ref name="param.element"/>
+         <ref name="key.element"/>
+         <ref name="decimal-format.element"/>
+         <ref name="output.element"/>
+      </choice>
+   </define>
+   <define name="instruction.category">
+      <choice>
+         <ref name="apply-templates.element"/>
+         <ref name="apply-imports.element"/>
+         <ref name="call-template.element"/>
+         <ref name="element.element"/>
+         <ref name="attribute.element"/>
+         <ref name="text.element"/>
+         <ref name="processing-instruction.element"/>
+         <ref name="comment.element"/>
+         <ref name="copy.element"/>
+         <ref name="value-of.element"/>
+         <ref name="number.element"/>
+         <ref name="for-each.element"/>
+         <ref name="if.element"/>
+         <ref name="choose.element"/>
+         <ref name="variable.element"/>
+         <ref name="copy-of.element"/>
+         <ref name="message.element"/>
+         <ref name="fallback.element"/>
+      </choice>
+   </define>
+   <define name="extension.atts">
+      <zeroOrMore>
+         <attribute>
+            <anyName>
+               <except>
+                  <nsName/>
+                  <nsName ns=""/>
+               </except>
+            </anyName>
+         </attribute>
+      </zeroOrMore>
+   </define>
+   <define name="stylesheet.element">
+      <element name="stylesheet">
+         <ref name="stylesheet.model"/>
+      </element>
+   </define>
+   <define name="transform.element">
+      <element name="transform">
+         <ref name="stylesheet.model"/>
+      </element>
+   </define>
+   <define name="stylesheet.model">
+      <ref name="extension.atts"/>
+      <optional>
+	 <attribute name="id">
+	    <data type="NCName"/>
+	 </attribute>
+      </optional>
+      <optional>
+	 <attribute name="extension-element-prefixes">
+            <ref name="prefixes.datatype"/>
+	 </attribute>
+      </optional>
+      <optional>
+	 <attribute name="exclude-result-prefixes">
+            <ref name="prefixes.datatype"/>
+	 </attribute>
+      </optional>
+      <attribute name="version">
+	 <ref name="version"/>
+      </attribute>
+      <group>
+	 <zeroOrMore>
+	    <ref name="import.element"/>
+	 </zeroOrMore>
+	 <ref name="top-level-elements.model"/>
+      </group>
+   </define>
+   <define name="include.element">
+      <element name="include">
+         <ref name="extension.atts"/>
+         <attribute name="href">
+            <data type="anyURI"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="import.element">
+      <element name="import">
+         <ref name="extension.atts"/>
+         <attribute name="href">
+            <data type="anyURI"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="strip-space.element">
+      <element name="strip-space">
+         <ref name="extension.atts"/>
+         <attribute name="elements">
+            <ref name="wildcards.datatype"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="preserve-space.element">
+      <element name="preserve-space">
+         <ref name="extension.atts"/>
+         <attribute name="elements">
+            <ref name="wildcards.datatype"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="template.element">
+      <element name="template">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="match">
+               <ref name="pattern.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="name">
+               <ref name="qname.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="priority">
+               <ref name="number.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="mode">
+               <ref name="qname.datatype"/>
+            </attribute>
+         </optional>
+         <group>
+            <zeroOrMore>
+               <ref name="param.element"/>
+            </zeroOrMore>
+            <ref name="template.model"/>
+         </group>
+      </element>
+   </define>
+   <define name="apply-templates.element">
+      <element name="apply-templates">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="select">
+               <ref name="expression.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="mode">
+               <ref name="qname.datatype"/>
+            </attribute>
+         </optional>
+         <zeroOrMore>
+            <choice>
+               <ref name="sort.element"/>
+               <ref name="with-param.element"/>
+            </choice>
+         </zeroOrMore>
+      </element>
+   </define>
+   <define name="apply-imports.element">
+      <element name="apply-imports">
+         <ref name="extension.atts"/>
+      </element>
+   </define>
+   <define name="call-template.element">
+      <element name="call-template">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <zeroOrMore>
+            <ref name="with-param.element"/>
+         </zeroOrMore>
+      </element>
+   </define>
+   <define name="namespace-alias.element">
+      <element name="namespace-alias">
+         <ref name="extension.atts"/>
+         <attribute name="stylesheet-prefix">
+            <ref name="prefix.datatype"/>
+         </attribute>
+         <attribute name="result-prefix">
+            <ref name="prefix.datatype"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="element.element">
+      <element name="element">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <choice>
+               <ref name="qname.datatype"/>
+               <ref name="expr-avt.datatype"/>
+            </choice>
+         </attribute>
+         <optional>
+            <attribute name="namespace">
+               <choice>
+                  <data type="anyURI"/>
+                  <ref name="brace-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="use-attribute-sets">
+               <ref name="qnames.datatype"/>
+            </attribute>
+         </optional>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="attribute.element">
+      <element name="attribute">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <choice>
+               <ref name="qname.datatype"/>
+               <ref name="expr-avt.datatype"/>
+            </choice>
+         </attribute>
+         <optional>
+            <attribute name="namespace">
+               <choice>
+                  <data type="anyURI"/>
+                  <ref name="brace-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="attribute-set.element">
+      <element name="attribute-set">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <optional>
+            <attribute name="use-attribute-sets">
+               <ref name="qnames.datatype"/>
+            </attribute>
+         </optional>
+         <zeroOrMore>
+            <ref name="attribute.element"/>
+         </zeroOrMore>
+      </element>
+   </define>
+   <define name="text.element">
+      <element name="text">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="disable-output-escaping">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+         <text/>
+      </element>
+   </define>
+   <define name="processing-instruction.element">
+      <element name="processing-instruction">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <choice>
+               <data type="NCName"/>
+               <ref name="expr-avt.datatype"/>
+            </choice>
+         </attribute>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="comment.element">
+      <element name="comment">
+         <ref name="extension.atts"/>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="copy.element">
+      <element name="copy">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="use-attribute-sets">
+               <ref name="qnames.datatype"/>
+            </attribute>
+         </optional>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="value-of.element">
+      <element name="value-of">
+         <ref name="extension.atts"/>
+         <attribute name="select">
+            <ref name="expression.datatype"/>
+         </attribute>
+         <optional>
+            <attribute name="disable-output-escaping">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+      </element>
+   </define>
+   <define name="number.element">
+      <element name="number">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="level">
+               <choice>
+                  <value type="string">single</value>
+                  <value type="string">multiple</value>
+                  <value type="string">any</value>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="count">
+               <ref name="pattern.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="from">
+               <ref name="pattern.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="value">
+               <ref name="expression.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="format">
+               <ref name="avt.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="lang">
+               <choice>
+                  <data type="NMTOKEN"/>
+                  <ref name="expr-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="letter-value">
+	       <choice>
+		  <value type="string">alphabetic</value>
+		  <value type="string">traditional</value>
+		  <ref name="expr-avt.datatype"/>
+	       </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="grouping-separator">
+               <choice>
+                  <ref name="char.datatype"/>
+                  <ref name="expr-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="grouping-size">
+               <choice>
+                  <ref name="number.datatype"/>
+                  <ref name="expr-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+      </element>
+   </define>
+   <define name="for-each.element">
+      <element name="for-each">
+         <ref name="extension.atts"/>
+         <attribute name="select">
+            <ref name="expression.datatype"/>
+         </attribute>
+         <group>
+            <zeroOrMore>
+               <ref name="sort.element"/>
+            </zeroOrMore>
+            <ref name="template.model"/>
+         </group>
+      </element>
+   </define>
+   <define name="if.element">
+      <element name="if">
+         <ref name="extension.atts"/>
+         <attribute name="test">
+            <ref name="expression.datatype"/>
+         </attribute>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="choose.element">
+      <element name="choose">
+         <ref name="extension.atts"/>
+         <group>
+            <oneOrMore>
+               <ref name="when.element"/>
+            </oneOrMore>
+            <optional>
+               <ref name="otherwise.element"/>
+            </optional>
+         </group>
+      </element>
+   </define>
+   <define name="when.element">
+      <element name="when">
+         <ref name="extension.atts"/>
+         <attribute name="test">
+            <ref name="expression.datatype"/>
+         </attribute>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="otherwise.element">
+      <element name="otherwise">
+         <ref name="extension.atts"/>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="sort.element">
+      <element name="sort">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="select">
+               <ref name="expression.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="lang">
+               <choice>
+                  <data type="NMTOKEN"/>
+                  <ref name="expr-avt.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="data-type">
+	       <choice>
+		  <value type="string">text</value>
+		  <value type="string">number</value>
+		  <ref name="qname-but-not-ncname.datatype"/>
+		  <ref name="expr-avt.datatype"/>
+	       </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="order">
+	       <choice>
+		  <value type="string">ascending</value>
+		  <value type="string">descending</value>
+		  <ref name="expr-avt.datatype"/>
+	       </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="case-order">
+	       <choice>
+		  <value type="string">upper-first</value>
+		  <value type="string">lower-first</value>
+		  <ref name="expr-avt.datatype"/>
+	       </choice>
+            </attribute>
+         </optional>
+      </element>
+   </define>
+   <define name="variable.element">
+      <element name="variable">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <choice>
+            <attribute name="select">
+               <ref name="expression.datatype"/>
+            </attribute>
+            <ref name="template.model"/>
+         </choice>
+      </element>
+   </define>
+   <define name="param.element">
+      <element name="param">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <choice>
+            <attribute name="select">
+               <ref name="expression.datatype"/>
+            </attribute>
+            <ref name="template.model"/>
+         </choice>
+      </element>
+   </define>
+   <define name="copy-of.element">
+      <element name="copy-of">
+         <ref name="extension.atts"/>
+         <attribute name="select">
+            <ref name="expression.datatype"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="with-param.element">
+      <element name="with-param">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <choice>
+            <attribute name="select">
+               <ref name="expression.datatype"/>
+            </attribute>
+            <ref name="template.model"/>
+         </choice>
+      </element>
+   </define>
+   <define name="key.element">
+      <element name="key">
+         <ref name="extension.atts"/>
+         <attribute name="name">
+            <ref name="qname.datatype"/>
+         </attribute>
+         <attribute name="match">
+            <ref name="pattern.datatype"/>
+         </attribute>
+         <attribute name="use">
+            <ref name="expression.datatype"/>
+         </attribute>
+      </element>
+   </define>
+   <define name="decimal-format.element">
+      <element name="decimal-format">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="name">
+               <ref name="qname.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="decimal-separator">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="grouping-separator">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="infinity">
+               <text/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="minus-sign">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="NaN">
+               <text/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="percent">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="per-mille">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="zero-digit">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="digit">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="pattern-separator">
+               <ref name="char.datatype"/>
+            </attribute>
+         </optional>
+      </element>
+   </define>
+   <define name="message.element">
+      <element name="message">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="terminate">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="fallback.element">
+      <element name="fallback">
+         <ref name="extension.atts"/>
+         <ref name="template.model"/>
+      </element>
+   </define>
+   <define name="output.element">
+      <element name="output">
+         <ref name="extension.atts"/>
+         <optional>
+            <attribute name="method">
+               <choice>
+                  <value type="string">xml</value>
+                  <value type="string">html</value>
+                  <value type="string">text</value>
+                  <ref name="qname-but-not-ncname.datatype"/>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="version">
+               <data type="NMTOKEN"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="encoding">
+               <text/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="omit-xml-declaration">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="standalone">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="doctype-public">
+               <text/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="doctype-system">
+               <text/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="cdata-section-elements">
+               <ref name="qnames.datatype"/>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="indent">
+               <choice>
+                  <value type="string">yes</value>
+                  <value type="string">no</value>
+               </choice>
+            </attribute>
+         </optional>
+         <optional>
+            <attribute name="media-type">
+               <text/>
+            </attribute>
+         </optional>
+      </element>
+   </define>
+   <define name="prefixes.datatype">
+      <list>
+         <zeroOrMore>
+            <choice>
+               <data type="NCName"/>
+               <value>#default</value>
+            </choice>
+         </zeroOrMore>
+      </list>
+   </define>
+   <define name="prefix.datatype">
+      <choice>
+	 <data type="NCName"/>
+	 <value>#default</value>
+      </choice>
+   </define>
+   <define name="wildcards.datatype">
+      <list>
+         <zeroOrMore>
+	    <choice>
+	       <data type="QName"/>
+	       <data type="token">
+		  <param name="pattern">\*|\i\c*:\*</param>
+	       </data>
+	    </choice>
+         </zeroOrMore>
+      </list> 
+   </define>
+   <define name="qname.datatype">
+      <data type="QName"/>
+   </define>
+   <define name="qnames.datatype">
+      <list>
+         <zeroOrMore>
+            <data type="QName"/>
+         </zeroOrMore>
+      </list>
+   </define>
+   <define name="char.datatype">
+      <data type="string">
+         <param name="length">1</param>
+      </data>
+   </define>
+   <define name="number.datatype">
+      <data type="decimal"/>
+   </define>
+   <define name="expression.datatype">
+      <text/>
+   </define>
+   <define name="pattern.datatype">
+      <text/>
+   </define>
+   <define name="qname-but-not-ncname.datatype">
+      <data type="QName">
+        <param name="pattern">.*:.*</param>
+      </data>
+   </define>
+   <!-- An AVT containing at least one expression. -->
+   <define name="expr-avt.datatype">
+      <data type="string">
+         <param name="pattern">([^\{\}]|\{\{|\}\})*\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\}([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
+      </data>
+   </define>
+   <!-- An AVT containing at least one brace; ie where instantiated AVT
+        is not the same as the literal AVT. -->
+   <define name="brace-avt.datatype">
+      <data type="string">
+         <param name="pattern">[^\{\}]*(\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
+      </data>
+   </define>
+   <define name="avt.datatype">
+      <data type="string">
+         <param name="pattern">([^\{\}]|\{\{|\}\}|\{([^&#34;'\{\}]|&#34;[^&#34;]*&#34;|'[^']*')+\})*</param>
+      </data>
+   </define>
+</grammar>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/log4j.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/log4j.xconf
new file mode 100644
index 0000000..0753dd1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/log4j.xconf
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+    <!-- This is a sample configuration for log4j.
+         It simply just logs everything into a single
+         log file.
+         Note, that you can use properties for value substitution.
+    -->
+    <appender name="COCOON_DEFAULT" class="org.apache.log4j.FileAppender">
+        <param name="File"   value="${context-root}/WEB-INF/logs/log4j.log" />
+        <param name="Append" value="false" />	    	
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
+        </layout>	    
+    </appender>
+
+    <root>
+      <priority value ="debug" />
+      <appender-ref ref="COCOON_DEFAULT" />
+    </root>
+</log4j:configuration>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/logkit.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/logkit.xconf
new file mode 100644
index 0000000..83e05b5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/logkit.xconf
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | This is the cocoon logkit configuration file.
+    |
+    | By default, Cocoon uses Excalibur logkit for logging, but it also
+    | supports Log4J. In case you want to use Log4J, you have to modify
+    | a configuration property in the 'WEB-INF/web.xml' file (search
+    | for log4j and you find it)
+    |
+    | The comments below should get you started in adapting the logs
+    | for your needs, but if you want to know more please visit
+    |
+    |   http://wiki.apache.org/cocoon/ConfiguringTheLogs
+    |
+    | $Id$
+    +-->
+<logkit>
+
+  <!--+
+      | Factories are responsible to create the consumers of the log events,
+      | the targets. Here we have configured just a few, the main cocoon
+      | target factory (that prints to a file) and the servlet target factory
+      | (that prints back to the servlet container log stream) but  for more
+      | info on the available logkit factories, please consult
+      | http://excalibur.apache.org/apidocs/org/apache/avalon/excalibur/logger/factory/package-summary.html
+      +-->
+  <factories>
+    <factory type="cocoon" class="org.apache.cocoon.util.log.CocoonTargetFactory"/>
+    <!--factory type="servlet" class="org.apache.avalon.excalibur.logger.factory.ServletTargetFactory"/-->
+    <!--factory type="stream" class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/-->
+  </factories>
+
+  <!--+
+      | Targets are the instances of the consumers of the log events and various
+      | instances can be configured and referenced via their 'id'.
+      | Note how the element name of the target indicates what type of factory
+      | that is created with.
+      +-->
+  <targets>
+
+    <cocoon id="main">
+      <!--+
+          | <filename> is the absolute location of the log file, note how you can
+          | use the ${context-root} variable to indicate the root of the
+          | cocoon web application (the directory that contains WEB-INF, that is)
+          +-->
+      <filename>${context-root}/WEB-INF/logs/cocoon.log</filename>
+
+      <!--+
+          | <format> indicates how the log event should be serialized.
+          | Note that newlines are *not* automatic: you have to specify the
+          | newline as '\n' or everything will appear on a single line!
+          |
+          | The first format below is verbose: it includes error stacktraces.
+          | If you want something even more verbose use %{throwable} which will
+          | show a full chain of exceptions. Using the second format won't
+          | output stacktraces at all.
+          |
+          | Please mind that the default format logs request uri along with
+          | query string. This may log confidential data (passwords etc.).
+          +-->
+      <format type="cocoon">%5.5{priority} %{time} [%{category}] (%{uri}%{query}) %{thread}/%{class:short}: %{message}\n%{rootThrowable}</format>
+      <!--format type="cocoon">%5.5{priority} %{time} [%{category}] (%{uri}%{query}) %{thread}/%{class:short}: %{message}\n%</format-->
+
+      <!--+
+          | <append> if set to 'true' will make cocoon append the events
+          | to the existing file, if set to 'false' cocoon will override
+          | the existing ones at every new start.
+          +-->
+      <append>@logappend@</append>
+
+      <!--+
+          | <rotation> allows you to rotate log files one they meet certain
+          | criteria. If you uncomment the example below, the log files will
+          | be rotated once they are a day old or bigger than 100 Mb.
+      <rotation type="unique" pattern="yyyyMMdd" suffix=".log">
+        <or>
+          <size>100m</size>
+          <time>24:00:00</time>
+        </or>
+      </rotation>
+          +-->
+    </cocoon>
+
+    <cocoon id="deprecation">
+      <filename>${context-root}/WEB-INF/logs/deprecation.log</filename>
+      <format type="cocoon">%5.5{priority} %{time} [%{category}] (%{uri}%{query}) %{thread}/%{class:short}: %{message}\n</format>
+      <append>@logappend@</append>
+    </cocoon>
+
+    <!--+
+        | These targets are used for the more elaborate examples below.
+        |
+    <servlet id="servlet">
+      <format type="extended">%5.5{priority} %5.5{time} [%8.8{category}] (%{context}): %{message}\n</format>
+    </servlet>
+
+    <stream id="console">
+      <stream>System.out</stream>
+      <format type="extended">%5.5{priority} %5.5{time} [%8.8{category}] (%{context}): %{message}\n</format>
+    </stream>
+        +-->
+  </targets>
+
+  <!--+
+      | Categories 'route' log events to particular targets, filtering
+      | on importance level (one of DEBUG, INFO, WARN, ERROR, FATAL_ERROR, 
+      | ordered from most verbose to least verbose) and on the 'category'
+      | used by the producer of the log event to further classify it.
+      | Some of these log categories are hardwired in the code and some
+      | others are user-selectable, for example for sitemap components
+      | where you can specify the category in their sitemap declaration.
+      |
+      | Category names can be dot-separated (example, 'sitemap.generator.file')
+      | and the variuos pieces are treated as 'sub-categories'. By nesting
+      | the <category> element you achieve sub-category filtering and you can
+      | even have different log level filtering per category and subcategory. 
+      | (See the comments below for an example of this)
+      |
+      | NOTE: not all subcategories are defined in this file. Not defined
+      | subcategories will be created automatically and they will inherit 
+      | the settings of the parent subcategory. When defining a subcategory 
+      | manually, it is required that you specify the log target, because 
+      | they are not inherited in this case.
+      +-->
+  <categories>
+
+    <!--+
+        | This is the main category. The empty name attribute indicates that
+        | this rule will match all log events from all categories.
+        +-->
+    <category log-level="@loglevel@" name="">
+      <log-target id-ref="main"/>
+    </category>
+
+    <!--+
+        | This is the deprecation category. If this category is set to WARN
+        | the log will contain messages about deprecated stuff used by
+        | your application.
+        +-->
+    <category log-level="WARN" name="deprecation">
+      <log-target id-ref="deprecation"/>
+    </category>
+
+    <!--+
+        | This is a little more elaborate example, where some of the logs are 
+        | sent to the log file and some others (the ones related to the sitemap), 
+        | are sent to the servlet container (where they could be further relayed 
+        | to the console, for example)
+        |
+    <category log-level="ERROR" name="">
+      <category log-level="DEBUG" name="sitemap">
+        <log-target id-ref="servlet"/>
+      </category>
+      <category log-level="INFO" name="access">
+        <log-target id-ref="console"/>
+      </category>
+      <log-target id-ref="core"/>
+    </category>
+        +-->
+
+  </categories>
+
+  <!--+
+      | Include logging confs from different blocks 
+      +-->
+  <include dir="context://WEB-INF/xconf" pattern="*.logkit"/>
+
+</logkit>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/core.properties b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/core.properties
new file mode 100644
index 0000000..b373dc2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/core.properties
@@ -0,0 +1,176 @@
+#  Copyright 2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+# This file contains the default settings for Cocoon.
+# You should NOT change this file directly. Create your own properties
+# file and put it in the sub directories for the mode you are running
+# Cocoon in.
+
+# This parameter points to the main configuration file for Cocoon.
+org.apache.cocoon.configuration=/WEB-INF/cocoon.xconf
+
+# Delay between reload checks for the configuration in ms.
+# The check is only performed if reloading is turned on!
+org.apache.cocoon.reload-delay=1000
+
+# Allow reinstantiating (reloading) of the cocoon instance. If this is
+# set to "yes" or "true", a new cocoon instance can be created using
+# the request parameter "cocoon-reload". It also enables that Cocoon is
+# reloaded when cocoon.xconf changes. Default is no for security reasons.
+org.apache.cocoon.reloading=no
+
+# Turn on reloading for specific parts:
+#org.apache.cocoon.reloading.sitemap=yes
+#org.apache.cocoon.reload-delay.sitemap=5000
+#org.apache.cocoon.reloading.config=yes
+#org.apache.cocoon.reloading.flow=yes
+
+# This parameter switches the logging system from LogKit to Log4J (or
+# any other logging implementation) for Cocoon.
+# Log4J has to be configured already.
+# org.apache.cocoon.logging.manager.class=org.apache.avalon.excalibur.logger.Log4JLoggerManager
+
+# This parameter indicates the configuration file of the logging
+# system, e.g. LogKit or Log4J.
+org.apache.cocoon.logging.configuration=WEB-INF/logkit.xconf
+
+# This parameter indicates the category id of the logger
+# configuration used by the environment Cocoon runs in (CLI, Servlet etc.).
+org.apache.cocoon.logging.category.environment=access
+
+# This parameter indicates the category id of the logger from the
+# logging system for the Cocoon engine.
+# This logger is used for all components described in the cocoon.xconf
+# and sitemap.xmap file not having specified a logger with the
+# logger="..." attribute in the component configuration file.
+org.apache.cocoon.logging.category.cocoon=core
+
+# This parameter indicates the log level to use throughout startup of the
+# system. As soon as the logging system is set up, the setting of the
+# logging system is used instead!
+# Available levels are:
+#       DEBUG:        prints all level of log messages.
+#       INFO:         prints all level of log messages except DEBUG ones.
+#       WARN:         prints all level of log messages except DEBUG and INFO ones.
+#       ERROR:        prints all level of log messages except DEBUG, INFO and WARN ones.
+#       FATAL_ERROR:  prints only log messages of this level
+org.apache.cocoon.logging.bootstrap.loglevel=WARN
+
+# Causes all files in multipart requests to be processed.
+# Default is true but the maximum allowed size is kept small for security reasons.
+# Unsupported values will be interpreted as false.
+org.apache.cocoon.uploads.enable=true
+
+# This parameter allows to specify where Cocoon should put uploaded files.
+# The path specified can be either absolute or relative to the context
+# path of the servlet. On windows platform, absolute directory must start
+# with volume: C:\Path\To\Upload\Directory
+#
+# The default directory is "upload-dir" in the work-directory
+#org.apache.cocoon.uploads.directory=WEB-INF/work/upload-dir
+
+# Causes all files in multipart requests to be saved to upload-dir.
+# Default is true for security reasons.
+# Unsupported values will be interpreted as false.
+org.apache.cocoon.uploads.autosave=true
+
+# Specify handling of name conflicts when saving uploaded files to disk.
+# Acceptable values are deny, allow, rename (default). Files are renamed
+# x_filename where x is an integer value incremented to make the new
+# filename unique.
+org.apache.cocoon.uploads.overwrite=rename
+
+# Specify maximum allowed size of the upload. Defaults to 10 Mb.
+# Set here to a very low 100 kb to allow samples to run.
+org.apache.cocoon.uploads.maxsize=102400
+
+# This parameter allows to specify where Cocoon should create its page
+# and other objects cache. The path specified can be either absolute or
+# relative to the context path of the servlet. On windows platform,
+# absolute directory must start with volume: C:\Path\To\Cache\Directory
+#
+# The default directory is "cache-dir" in the work-directory.
+#org.apache.cocoon.cache.directory=WEB-INF/work/cache-dir
+
+# This parameter allows to specify where Cocoon should put it's
+# working files. The path specified is either absolute or relative
+# to the context path of the Cocoon servlet. On windows platform,
+# absolute directory must start with volume: C:\Path\To\Work\Directory
+#
+# The default directory is "cocoon-files" directory in the servlet
+# context's temp directory (context property javax.servlet.context.tempdir).
+#org.apache.cocoon.work.directory=WEB-INF/work
+
+# This parameter is used to list classes that should be loaded at
+# initialization time of the servlet. For example, JDBC Drivers used need to
+# be named here. Additional entries may be inserted here during build
+# depending on your build properties.
+#
+# For parent ServiceManager sample:
+#org.apache.cocoon.classloader.load.classes.parentcm=org.apache.cocoon.samples.parentcm.Configurator
+#
+# For IBM WebSphere:
+#org.apache.cocoon.classloader.load.classes.websphere=com.ibm.servlet.classloader.Handler
+
+# This parameter allows to specify additional directories or jars
+# which Cocoon should put into it's own classpath.
+# Note that absolute
+# pathes are taken as such but relative pathes are rooted at the context
+# root of the Cocoon servlet.
+#org.apache.cocoon.extra.classpaths.one=WEB-INF/extra-classes1:/[YOU-ABSOLUTE-PATH-TO]/own.jar
+
+# This parameter allows you to select the parent service manager.
+# The class will be instantiated via the constructor that takes a single
+# String as a parameter. That String will be equal to the text after the '/'.
+#
+# Cocoon honors the LogEnabled, Initializable and Disposable interfaces for
+# this class, if it implements them.
+#
+# If you uncomment the following lines the parent CM is set to the Parent CM
+# sample, which will look up a configuration via JNDI at
+# org/apache/cocoon/samples/parentcm/ParentCMConfiguration and use it.
+#org.apache.cocoon.parentservicemanager=org.apache.cocoon.samples.parentcm.ParentServiceManager/org/apache/cocoon/samples/parentcm/ParentCMConfiguration
+
+# If you set this parameter to 'true' or 'yes', Cocoon will add processing
+# time to the end of each response. Value 'hide' adds processing time as an
+# HTML comment. By default, processing time is not added (corresponds to
+# value 'no').
+# NOTE: If you use this feature, Cocoon might generated a wrong content
+# length header in the response. This is due to the internal processing
+# of Readers and the Caching. So, this might be the reason if you get
+# a warning about a wrong content length.
+#  See http://issues.apache.org/bugzilla/show_bug.cgi?id=17370.
+#org.apache.cocoon.showtime=true
+#org.apache.cocoon.hideshowtime=true
+
+# Whether or not the X-Cocoon-Version response header will be included.
+# This is true by default, but there may be some circumstances when it
+# is not desired (e.g. "information hiding" for added security, or if
+# using jsp:include with Cocoon-generated pages produces a "response is
+# already committed" error).
+org.apache.cocoon.showcocoonversion=true
+
+# If true or not set, this class will try to catch and handle all Cocoon
+# exceptions. If false, it will rethrow them to the servlet container.
+org.apache.cocoon.manageexceptions=true
+
+# Set form encoding. This will be the character set used to decode request
+# parameters. If not set the ISO-8859-1 encoding will be assumed.
+org.apache.cocoon.formencoding=ISO-8859-1
+
+# This property allows to set system properties.
+# Everything after 'org.apache.cocoon.system.properties.' builds
+# the name of the system property and the value is the value
+# to be set.
+#org.apache.cocoon.system.properties.org.apache.commons.logging.Log=org.apache.commons.logging.impl.LogKitLogger
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/dev/core.properties b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/dev/core.properties
new file mode 100644
index 0000000..c286e81
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/dev/core.properties
@@ -0,0 +1,20 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+
+# Turn on debug logging
+org.apache.cocoon.override.loglevel=DEBUG
+
+# Turn on reloading for all parts
+org.apache.cocoon.reloading=yes
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/prod/core.properties b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/prod/core.properties
new file mode 100644
index 0000000..6b658b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/properties/prod/core.properties
@@ -0,0 +1,17 @@
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+
+# Turn off lazy loading
+org.apache.cocoon.core.LazyMode=false
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/sitemap-additions/cocoon-core-sitemap-additions.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/sitemap-additions/cocoon-core-sitemap-additions.xconf
new file mode 100644
index 0000000..7ddb58d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/sitemap-additions/cocoon-core-sitemap-additions.xconf
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | This file defines some additional components for the sitemap.
+    |
+    | SVN $Id$
+    +-->
+
+<map:components xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:generators>
+  	<map:generator label="content" logger="sitemap.generator.mp3directory" name="mp3directory" src="org.apache.cocoon.generation.MP3DirectoryGenerator"/>
+  </map:generators>
+
+  <map:transformers>
+    <map:transformer logger="sitemap.transformer.jpath" name="jpath" src="org.apache.cocoon.transformation.JPathTransformer"/>
+    <map:transformer logger="sitemap.transformer.filter" name="filter" src="org.apache.cocoon.transformation.FilterTransformer"/>
+  </map:transformers>
+
+  <map:serializers>
+    <map:serializer logger="sitemap.serializer.vrml" mime-type="model/vrml" name="vrml" src="org.apache.cocoon.serialization.TextSerializer"/>
+  </map:serializers>
+
+</map:components>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/web.xml b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..74353bf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/web.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | This is the Cocoon web-app configurations file
+    +-->
+
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+  <!-- Context Configuration ========================================== -->
+
+  <!--+
+      | Set a context property useful to allow you to ProxyPass your
+      | web application mounted to a different URI without loosing the
+      | ability to do cookie-based sessions.
+      | WARNING: this is Jetty specific!
+      +-->
+  <!--context-param>
+    <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
+    <param-value>/some/path/to/your/webapp</param-value>
+    <description>An override of the session cookie path</description>
+   </context-param-->
+
+  <!-- Servlet Configuration ========================================== -->
+
+  <servlet>
+    <servlet-name>Cocoon</servlet-name>
+    <display-name>Cocoon</display-name>
+    <description>Cocoon</description>
+
+    <!--
+      The regular servlet class (trusts the servlet container classloader)
+      -->
+    <servlet-class>org.apache.cocoon.servlet.CocoonServlet</servlet-class>
+    <!--
+      The paranoid servlet class, to be used instead of regular one when
+      having conflicts between libraries used by Cocoon and the servlet
+      container.
+    <servlet-class>org.apache.cocoon.servlet.ParanoidCocoonServlet</servlet-class>
+    <init-param>
+      <param-name>classloader-class</param-name>
+      <param-value>org.apache.commons.javaflow.ContinuationCompilingClassLoader</param-value>
+    </init-param>
+    -->
+
+    <!--
+      Set encoding used by the container. If not set the ISO-8859-1 encoding
+      will be assumed.
+      Since the servlet specification requires that the ISO-8859-1 encoding
+      is used (by default), you should never change this value unless
+      you have a buggy servlet container.
+    -->
+    <init-param>
+      <param-name>container-encoding</param-name>
+      <param-value>ISO-8859-1</param-value>
+    </init-param>
+
+    <!--
+      This parameter allows you to startup Cocoon2 immediately after startup
+      of your servlet engine.
+    -->
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+
+  <!-- URL space mappings ============================================= -->
+
+  <!--
+    Cocoon handles all the URL space assigned to the webapp using its sitemap.
+    It is recommended to leave it unchanged. Under some circumstances though
+    (like integration with proprietary webapps or servlets) you might have
+    to change this parameter.
+  -->
+  <servlet-mapping>
+    <servlet-name>Cocoon</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+
+  <!--
+    Some servlet engines (Tomcat) have defaults which are not overriden
+    by '/' mapping, but must be overriden explicitly.
+  -->
+  <servlet-mapping>
+    <servlet-name>Cocoon</servlet-name>
+    <url-pattern>*.jsp</url-pattern>
+  </servlet-mapping>
+  <!--
+    Some servlet engines (WebLogic) have defaults which are not overriden
+    by '/' mapping, but must be overriden explicitly.
+  -->
+  <servlet-mapping>
+    <servlet-name>Cocoon</servlet-name>
+    <url-pattern>*.html</url-pattern>
+  </servlet-mapping>
+
+  <!-- various MIME type mappings ====================================== -->
+
+  <mime-mapping>
+    <extension>css</extension>
+    <mime-type>text/css</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>xml</extension>
+    <mime-type>text/xml</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>xsl</extension>
+    <mime-type>text/xml</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>xconf</extension>
+    <mime-type>text/xml</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>xmap</extension>
+    <mime-type>text/xml</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>ent</extension>
+    <mime-type>text/plain</mime-type>
+  </mime-mapping>
+
+  <mime-mapping>
+    <extension>grm</extension>
+    <mime-type>text/plain</mime-type>
+  </mime-mapping>
+
+
+  <!-- Sample environment entry for the NamingInputModule -->
+  <env-entry>
+    <env-entry-name>greeting</env-entry-name>
+    <env-entry-value>Hello, World</env-entry-value>
+    <env-entry-type>java.lang.String</env-entry-type>
+  </env-entry>
+
+</web-app>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core-sitemap.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core-sitemap.xconf
new file mode 100644
index 0000000..55889e1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core-sitemap.xconf
@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | This file defines core components for the sitemap.
+    |
+    | SVN $Id$
+    +-->
+
+<map:components xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+ <!--+
+     | All pipelines consist at least of two components: a generator, that
+     | produces the content, and a serialiser, that delivers the content to
+     | the client.
+     |
+     | More precisely: a generator generates SAX events and a serializer
+     | consumes these events and produces a byte stream.
+     |
+     | Some things to note here: each generator has a unique name, this
+     | name is mapped to a java class, one name is declared as the default
+     | generator. Each generator may have additional configurations as
+     | child elements.
+     |
+     | Additional attributes are targeted at the component manager. The optional
+     | "label" attribute is relevant for the view concept below. The optional
+     | "logger" attribute defines the logging category where messages produced
+     | by a component should go. If there's no "logger" attribute, the category
+     | used is the one defined for the "sitemap" component in cocoon.xconf.
+     |
+     | We have chosen in this sitemap to use a different logging category
+     | for each component, which allows fine-grained classification of log
+     | messages. But you are free to use any category you want.
+     |
+     | It is possible to have the same java class declared as different
+     | generators by using different names. No configuration options are
+     | shared between these instances, however.
+     |
+     | All components follow this scheme.
+     +-->
+ <map:generators default="file">
+   <map:generator label="content" logger="sitemap.generator.file" name="file" pool-max="32" src="org.apache.cocoon.generation.FileGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.directory" name="directory" pool-max="16" src="org.apache.cocoon.generation.DirectoryGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.xpathdirectory" name="xpathdirectory" src="org.apache.cocoon.generation.XPathDirectoryGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.imagedirectory" name="imagedirectory" src="org.apache.cocoon.generation.ImageDirectoryGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.request" name="request" pool-max="16" src="org.apache.cocoon.generation.RequestGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.stream" name="stream" pool-max="16" src="org.apache.cocoon.generation.StreamGenerator"/>
+   <map:generator label="content" logger="sitemap.generator.status" name="status" pool-max="16" src="org.apache.cocoon.generation.StatusGenerator"/>
+   <!-- The notifying generator can only be used in a <handle-errors> section -->
+   <map:generator name="notifying" src="org.apache.cocoon.sitemap.NotifyingGenerator"/>
+   <!-- The exception generator can only be used in a <handle-errors> section : it produces an XML
+        representation of the exception that caused the error handler to be executed -->
+   <map:generator name="exception" src="org.apache.cocoon.generation.ExceptionGenerator"/>
+
+   <!--
+     - Virtual Pipeline Generator: Composed of other pipeline components.
+     -->
+   <map:generator name="virtual" src="org.apache.cocoon.generation.VirtualPipelineGenerator">
+     <map:generate src="welcome.xml"/>
+     <map:transform src="welcome.xslt">
+       <map:parameter name="contextPath" value="{request:contextPath}"/>
+     </map:transform>
+   </map:generator>
+ </map:generators>
+
+
+ <!--+
+     | Transformers can be placed inside the pipeline between the generator
+     | and the serializer. You may have as many transformers as you
+     | like. Transformers consume SAX events and emit SAX events.
+     |
+     | The "xslt" transformer is an example of a component with additional
+     | configuration.
+     +-->
+ <map:transformers default="xslt">
+
+   <!-- NOTE: This is the default XSLT processor. -->
+   <map:transformer logger="sitemap.transformer.xslt" name="xslt" pool-max="32" src="org.apache.cocoon.transformation.TraxTransformer">
+     <use-request-parameters>false</use-request-parameters>
+     <use-session-parameters>false</use-session-parameters>
+     <use-cookie-parameters>false</use-cookie-parameters>
+     <xslt-processor-role>xalan</xslt-processor-role>
+     <check-includes>true</check-includes>
+   </map:transformer>
+
+   <!-- NOTE: This is the same as the default processor but with a different name (for compatibility) -->
+   <map:transformer logger="sitemap.transformer.xalan" name="xalan" pool-max="32" src="org.apache.cocoon.transformation.TraxTransformer">
+     <use-request-parameters>false</use-request-parameters>
+     <use-session-parameters>false</use-session-parameters>
+     <use-cookie-parameters>false</use-cookie-parameters>
+     <xslt-processor-role>xalan</xslt-processor-role>
+     <check-includes>true</check-includes>
+   </map:transformer>
+
+   <!-- NOTE: You can also try XSLTC as the default processor. If you use Xalan extensions, use the "xalan" transformer. -->
+   <map:transformer logger="sitemap.transformer.xsltc" name="xsltc" pool-max="32" src="org.apache.cocoon.transformation.TraxTransformer">
+     <use-request-parameters>false</use-request-parameters>
+     <use-session-parameters>false</use-session-parameters>
+     <use-cookie-parameters>false</use-cookie-parameters>
+     <xslt-processor-role>xsltc</xslt-processor-role>
+     <check-includes>true</check-includes>
+   </map:transformer>
+
+   <map:transformer logger="sitemap.transformer.include" name="include" pool-max="16" src="org.apache.cocoon.transformation.IncludeTransformer"/>
+   <map:transformer logger="sitemap.transformer.xinclude" name="xinclude" pool-max="16" src="org.apache.cocoon.transformation.XIncludeTransformer"/>
+   <map:transformer logger="sitemap.transformer.cinclude" name="cinclude" pool-max="16" src="org.apache.cocoon.transformation.CIncludeTransformer"/>
+   <map:transformer logger="sitemap.transformer.encodeURL" name="encodeURL" src="org.apache.cocoon.transformation.EncodeURLTransformer"/>
+   <map:transformer logger="sitemap.transformer.write-source" name="write-source" src="org.apache.cocoon.transformation.SourceWritingTransformer"/>
+   <map:transformer logger="sitemap.transformer.writeDOMsession" name="writeDOMsession" src="org.apache.cocoon.transformation.WriteDOMSessionTransformer"/>
+   <map:transformer logger="sitemap.transformer.readDOMsession" name="readDOMsession" src="org.apache.cocoon.transformation.ReadDOMSessionTransformer"/>
+   <map:transformer logger="sitemap.transformer.log" name="log" pool-max="16" src="org.apache.cocoon.transformation.LogTransformer"/>
+   <map:transformer logger="sitemap.transformer.paginate" name="paginate" src="org.apache.cocoon.transformation.pagination.Paginator"/>
+ </map:transformers>
+
+
+ <!--+
+     | Serializers consume SAX events and produce a character stream. Every
+     | pipeline needs to be terminated by a serializer.
+     +-->
+ <map:serializers default="html">
+   <map:serializer logger="sitemap.serializer.links" name="links" src="org.apache.cocoon.serialization.LinkSerializer"/>
+   <map:serializer logger="sitemap.serializer.xml" mime-type="text/xml" name="xml" src="org.apache.cocoon.serialization.XMLSerializer"/>
+
+   <map:serializer logger="sitemap.serializer.html" mime-type="text/html" name="html" pool-max="32" src="org.apache.cocoon.serialization.HTMLSerializer">
+     <doctype-public>-//W3C//DTD HTML 4.01 Transitional//EN</doctype-public>
+     <doctype-system>http://www.w3.org/TR/html4/loose.dtd</doctype-system>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.wml" mime-type="text/vnd.wap.wml" name="wml" src="org.apache.cocoon.serialization.XMLSerializer">
+    <doctype-public>-//WAPFORUM//DTD WML 1.1//EN</doctype-public>
+    <doctype-system>http://www.wapforum.org/DTD/wml_1.1.xml</doctype-system>
+    <encoding>ASCII</encoding>
+    <omit-xml-declaration>yes</omit-xml-declaration>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.chtml" mime-type="text/html" name="chtml" src="org.apache.cocoon.serialization.HTMLSerializer">
+    <!--+
+        | Compact HTML for Small Information Appliances,
+        | based on http://www.w3.org/TR/1998/NOTE-compactHTML-19980209/
+        + -->
+    <doctype-public>-//W3C//DTD Compact HTML 1.0 Draft//EN</doctype-public>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.svgxml" mime-type="image/svg+xml" name="svgxml" src="org.apache.cocoon.serialization.XMLSerializer">
+    <doctype-public>-//W3C//DTD SVG 1.0//EN</doctype-public>
+    <doctype-system>http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd</doctype-system>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.xhtml" mime-type="text/html" name="xhtml" pool-max="64" src="org.apache.cocoon.serialization.XMLSerializer">
+     <!--+
+         | You can choose from Strict, Transitional, or Frameset XHTML.
+         | For Strict XHTML set doctype to:
+         |   <doctype-public>-//W3C//DTD XHTML 1.0 Strict//EN</doctype-public>
+         |   <doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd</doctype-system>
+         | For Transitional XHTML set doctype to:
+         |   <doctype-public>-//W3C//DTD XHTML 1.0 Transitional//EN</doctype-public>
+         |   <doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</doctype-system>
+         | For Frameset XHTML set doctype to:
+         |   <doctype-public>-//W3C//DTD XHTML 1.0 Frameset//EN</doctype-public>
+         |   <doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd</doctype-system>
+         |
+         | Default XHTML doctype in Cocoon is XHTML Strict. If you want to use more than one
+         | XHTML DTD simultaneously, you can define several XHTML serializers.
+         +-->
+     <doctype-public>-//W3C//DTD XHTML 1.0 Strict//EN</doctype-public>
+     <doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd</doctype-system>
+     <encoding>UTF-8</encoding>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.xhtml" mime-type="application/xhtml+xml" name="xhtml11" pool-max="64" src="org.apache.cocoon.serialization.XMLSerializer">
+     <doctype-public>-//W3C//DTD XHTML 1.1//EN</doctype-public>
+     <doctype-system>http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</doctype-system>
+     <encoding>UTF-8</encoding>
+   </map:serializer>
+
+   <map:serializer logger="sitemap.serializer.text" mime-type="text/plain" name="text" src="org.apache.cocoon.serialization.TextSerializer"/>
+   <map:serializer logger="sitemap.serializer.zip"  mime-type="application/zip" name="zip" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/>
+   <map:serializer logger="sitemap.serializer.sxw"  mime-type="application/vnd.sun.xml.writer" name="sxw" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/>
+   <map:serializer logger="sitemap.serializer.sxc"  mime-type="application/vnd.sun.xml.calc" name="sxc" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/>
+   <map:serializer logger="sitemap.serializer.sxd"  mime-type="application/vnd.sun.xml.draw" name="sxd" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/>
+   <map:serializer logger="sitemap.serializer.sxi"  mime-type="application/vnd.sun.xml.impress" name="sxi" src="org.apache.cocoon.serialization.ZipArchiveSerializer"/>
+ </map:serializers>
+
+
+ <!--+
+     | Readers circumvent the XML oriented SAX pipeline model, think of a reader
+     | being a generator and a serializer at once thus a pipeline may not
+     | contain any generator, transformer or serializer in addition to a
+     | reader. They are useful for delivering binary content like images.
+     +-->
+ <map:readers default="resource">
+   <map:reader logger="sitemap.reader.resource" name="resource" pool-max="32" src="org.apache.cocoon.reading.ResourceReader">
+     <!--+
+         | Resource reader has these configuration parameters:
+     <expires>-1</expires>
+     <quick-modified-test>false</quick-modified-test>
+     <byte-ranges>true</byte-ranges>
+     <buffer-size>8192</buffer-size>
+         +-->
+   </map:reader>
+   <map:reader logger="sitemap.reader.image" name="image" src="org.apache.cocoon.reading.ImageReader"/>
+ </map:readers>
+
+ <!--+
+     | Matchers are executed during pipeline setup. They decide if a
+     | pipeline fragment is used within a pipeline. Usually, the decision
+     | is based on a match on the requested URI but matchers exist, that
+     | match different things as well. Most often the fragment contained in
+     | a matcher has a generator as well as a serializer. This is not a
+     | necessity, matchers can be nested while chaining does not work.
+     +-->
+ <map:matchers default="wildcard">
+   <map:matcher logger="sitemap.matcher.wildcard" name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
+   <map:matcher logger="sitemap.matcher.regexp" name="regexp" src="org.apache.cocoon.matching.RegexpURIMatcher"/>
+   <map:matcher logger="sitemap.matcher.request-parameter" name="request-parameter" src="org.apache.cocoon.matching.RequestParameterMatcher"/>
+   <map:matcher logger="sitemap.matcher.cookie" name="cookie" src="org.apache.cocoon.matching.CookieMatcher"/>
+   <map:matcher logger="sitemap.matcher.header" name="header" src="org.apache.cocoon.matching.HeaderMatcher"/>
+   <map:matcher logger="sitemap.matcher.parameter" name="parameter" src="org.apache.cocoon.matching.ParameterMatcher"/>
+   <map:matcher logger="sitemap.matcher.sessionstate" name="sessionstate" src="org.apache.cocoon.matching.WildcardSessionAttributeMatcher">
+     <attribute-name>org.apache.cocoon.SessionState</attribute-name>
+   </map:matcher>
+   <map:matcher logger="sitemap.matcher.referer-match" name="referer-match" src="org.apache.cocoon.matching.WildcardHeaderMatcher">
+     <header-name>referer</header-name>
+   </map:matcher>
+   <map:matcher name="mount-table" src="org.apache.cocoon.matching.MountTableMatcher">
+     <map:parameter name="ignore-missing-tables" value="true"/>
+   </map:matcher>
+   <map:matcher logger="sitemap.matcher.locale" name="locale" src="org.apache.cocoon.matching.LocaleMatcher">
+     <!--+
+         | Default configuration:
+     <locale-attribute>locale</locale-attribute>
+     <negotiate>false</negotiate>
+     <use-locale>true</use-locale>
+     <use-locales>false</use-locales>
+     <use-blank-locale>true</use-blank-locale>
+     <default-locale language="en" country="US"/>
+     <create-session>false</create-session>
+     <store-in-request>false</store-in-request>
+     <store-in-session>false</store-in-session>
+     <store-in-cookie>false</store-in-cookie>
+         +-->
+   </map:matcher>
+ </map:matchers>
+
+ <!--+
+     | Selectors are executed during pipeline setup. They can be used to
+     | determine which pipeline fragments should be combined. They are best
+     | compared with a java switch statement.
+     +-->
+ <map:selectors default="browser">
+   <map:selector logger="sitemap.selector.browser" name="browser" src="org.apache.cocoon.selection.BrowserSelector">
+     <!--+
+         | NOTE: The appearance indicates the search order. This is very important since
+         |       some words may be found in more than one browser description. (MSIE is
+         |       presented as "Mozilla/4.0 (Compatible; MSIE 4.01; ...")
+         +-->
+     <browser name="explorer" useragent="MSIE"/>
+     <browser name="pocketexplorer" useragent="MSPIE"/>
+     <browser name="handweb" useragent="HandHTTP"/>
+     <browser name="avantgo" useragent="AvantGo"/>
+     <browser name="imode" useragent="DoCoMo"/>
+     <browser name="opera" useragent="Opera"/>
+     <browser name="lynx" useragent="Lynx"/>
+     <browser name="java" useragent="Java"/>
+     <browser name="wap" useragent="Nokia"/>
+     <browser name="wap" useragent="UP"/>
+     <browser name="wap" useragent="Wapalizer"/>
+     <browser name="mozilla5" useragent="Mozilla/5"/>
+     <browser name="mozilla5" useragent="Netscape6/"/>
+     <browser name="netscape" useragent="Mozilla"/>
+   </map:selector>
+
+   <!--+
+       | Exception selector : used in <map:handle> errors to build different pipelines
+       | depending on the error that occured.
+       | The configuration allows to associate a symbolic name to exception classes
+       | which is used in the <map:when> tests.
+       | An exception can also be "unrolled", meaning that cascaded exception will be checked.
+       +-->
+   <map:selector logger="sitemap.selector.exception" name="exception" src="org.apache.cocoon.selection.ExceptionSelector">
+     <exception name="not-found" class="org.apache.cocoon.ResourceNotFoundException"/>
+     <exception name="invalid-continuation" class="org.apache.cocoon.components.flow.InvalidContinuationException"/>
+     <!-- The statement below tells the selector to unroll as much exceptions as possible -->
+     <exception class="java.lang.Throwable" unroll="true"/>
+   </map:selector>
+
+   <map:selector logger="sitemap.selector.request-method" name="request-method" src="org.apache.cocoon.selection.RequestMethodSelector"/>
+   <map:selector logger="sitemap.selector.resource-exists" name="resource-exists" src="org.apache.cocoon.selection.ResourceExistsSelector"/>
+   <map:selector logger="sitemap.selector.request-parameter" name="request-parameter" src="org.apache.cocoon.selection.RequestParameterSelector">
+     <!--+
+         | Define now which request parameter to use; or do it later,
+         | when using this selector, via "parameter-name" parameter.
+     <parameter-name>myparam</parameter-name>
+         +-->
+   </map:selector>
+   <map:selector logger="sitemap.selector.request-attribute" name="request-attribute" src="org.apache.cocoon.selection.RequestAttributeSelector">
+     <!-- <attribute-name>myparam</attribute-name> -->
+   </map:selector>
+   <map:selector logger="sitemap.selector.session-attribute" name="session-attribute" src="org.apache.cocoon.selection.SessionAttributeSelector">
+     <!-- <attribute-name>myparam</attribute-name> -->
+   </map:selector>
+   <map:selector logger="sitemap.selector.parameter" name="parameter" src="org.apache.cocoon.selection.ParameterSelector"/>
+   <map:selector logger="sitemap.selector.header" name="header" src="org.apache.cocoon.selection.HeaderSelector">
+     <!-- <header-name>myparam</header-name> -->
+   </map:selector>
+   <map:selector logger="sitemap.selector.host" name="host" src="org.apache.cocoon.selection.HostSelector"/>
+   <map:selector logger="sitemap.selector.simple" name="simple" src="org.apache.cocoon.selection.SimpleSelector"/>
+ </map:selectors>
+
+
+ <!--+
+     | Actions are executed during pipeline setup. Their purpose is to
+     | execute some code that doesn't involve touching the stream of
+     | pipeline events. Example usage is to update databases, check external
+     | resources, etc.. The execution may fail or complete successfully. Only
+     | if the execution of the action was successful, the pipeline fragment
+     | nested inside the action element is executed, otherwise, it's skipped
+     | entirely and execution proceeds from the element right below the action.
+     +-->
+ <map:actions>
+   <map:action logger="sitemap.action.request" name="request" src="org.apache.cocoon.acting.RequestParamAction"/>
+   <map:action logger="sitemap.action.requestParamExists" name="req-params" src="org.apache.cocoon.acting.RequestParameterExistsAction"/>
+   <map:action logger="sitemap.action.form-validator" name="form-validator" src="org.apache.cocoon.acting.FormValidatorAction"/>
+   <map:action logger="sitemap.action.session-state" name="session-state" src="org.apache.cocoon.acting.SessionStateAction"/>
+   <map:action logger="sitemap.action.session-isvalid" name="session-isvalid" src="org.apache.cocoon.acting.SessionIsValidAction"/>
+   <map:action logger="sitemap.action.session-validator" name="session-validator" src="org.apache.cocoon.acting.SessionValidatorAction"/>
+   <map:action logger="sitemap.action.session-invalidator" name="session-invalidator" src="org.apache.cocoon.acting.SessionInvalidatorAction"/>
+   <map:action logger="sitemap.action.resource-exists" name="resource-exists" src="org.apache.cocoon.acting.ResourceExistsAction"/>
+   <map:action logger="sitemap.action.set-header" name="set-header" src="org.apache.cocoon.acting.HttpHeaderAction"/>
+   <map:action logger="sitemap.action.clear-cache" name="clear-cache" src="org.apache.cocoon.acting.ClearCacheAction"/>
+   <map:action logger="sitemap.action.clear-persistent-store" name="clear-persistent-store" src="org.apache.cocoon.acting.ClearPersistentStoreAction"/>
+   <map:action logger="sitemap.action.locale" name="locale" src="org.apache.cocoon.acting.LocaleAction">
+     <!--+
+         | Default configuration:
+     <locale-attribute>locale</locale-attribute>
+     <create-session>false</create-session>
+     <store-in-request>false</store-in-request>
+     <store-in-session>false</store-in-session>
+     <store-in-cookie>false</store-in-cookie>
+     <use-locale>true</use-locale>
+     <default-locale language="en" country="US"/>
+         +-->
+   </map:action>
+ </map:actions>
+
+
+ <!--+
+     | The different pipe implementations
+     |
+     | NON-CACHING:
+     |   The non caching implementation of cocoon pipelines.
+     |
+     | CACHING:
+     |   Traditional longest cacheable key caching.
+     |
+     | CACHING-POINT:
+     |   The caching-point pipeline implements an extended
+     |   caching algorithm which is of particular benefit for use with
+     |   those pipelines that utilise cocoon-views and/or provide
+     |   drill-down functionality.
+     |
+     | The autoCachingPoint algorithim (if enabled) will automatically
+     | cache common elements of the pipeline currently being processed - as well
+     | as the entire cacheable pipeline according to the "longest cacheable key"
+     | algorithm.
+     |
+     | Consider the following simple pipeline, where generator G is labelled with
+     | a cocoon-view enabling the pipeline to serialize data to either html or pdf
+     | depending on the value of cocoon-view (as provided by the request):
+     | G - T -  S(html)
+     | |__ T -  S(pdf)
+     |
+     | If cocoon-view=html, then the caching-point algorithm will not only cache
+     | the longest cacheable path, which would be GTS(html) but also the
+     | *common element* which in this case would be the results from G. If the
+     | next request to this pipeline was cocoon-view=pdf, then there would be no
+     | need to invoke the generator a second time, as it's value has already been
+     | cached (provided G generates the same cache key)
+     |
+     | Also note: One can switch "Off" autoCachingPoint and use "pipeline-hints" to
+     | manually indicate that certain pipeline-components should be considered as
+     | cache points.
+     +-->
+  <map:pipes default="caching">
+    <map:pipe name="caching" src="org.apache.cocoon.components.pipeline.impl.CachingProcessingPipeline">
+      <!--+
+          | If not specified, the value of the outputBufferSize parameter is -1.
+          | This will cause Cocoon to buffer all output until processing has finished
+          | before sending it to the client. This has the advantage that in case
+          | an error occurs during the processing of the SAX-pipeline, Cocoon is still
+          | able to reset the response and send an error page instead. Otherwise the
+          | error page will be appended to the output already send to the client.
+          | If you are generating larger pages, it might be benificial to enable
+          | this parameter, so that output is gradually send to the client as it
+          | is being generated.
+          | For more granularity, you can also supply this parameter to
+          | individual map:pipeline elements (using map:parameter syntax).
+          +-->
+      <!-- parameter name="outputBufferSize" value="8192"/ -->
+    </map:pipe>
+    <map:pipe name="caching-point" src="org.apache.cocoon.components.pipeline.impl.CachingPointProcessingPipeline">
+      <parameter name="autoCachingPoint" value="On"/>
+      <!-- parameter name="outputBufferSize" value="8192"/ -->
+    </map:pipe>
+    <map:pipe name="noncaching" src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipeline">
+      <!-- parameter name="outputBufferSize" value="8192"/ -->
+    </map:pipe>
+    <!--+
+        | This pipeline implementation caches the complete content for a defined
+        | period of time (expires). The cache key is the current uri.
+        +-->
+    <map:pipe name="expires" src="org.apache.cocoon.components.pipeline.impl.ExpiresCachingProcessingPipeline">
+      <parameter name="cache-expires" value="180"/> <!-- Expires in secondes -->
+    </map:pipe>
+  </map:pipes>
+  
+</map:components>
diff --git a/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core.xconf b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core.xconf
new file mode 100644
index 0000000..06347fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/WEB-INF/xconf/cocoon-core.xconf
@@ -0,0 +1,704 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- SVN $Id$ -->
+<components>
+
+<!--+
+    |  This file defines the Cocoon core components.
+    +-->
+
+  <!-- Include the core roles definitions. This is for the sake of clarity,
+       as they are implicitely loaded at startup, but we may want to remove
+       this implicit behaviour in the future now that we have the include
+       mechanism. -->
+  <include src="resource://org/apache/cocoon/cocoon.roles"/>
+
+<!-- =========================== Sitemap =============================== -->
+
+  <!--+
+      | New implementation of the sitemap. It is interpreted, so load times
+      | are super-fast, and request processing is slightly faster than with
+      | the compiled engine thanks to the HotSpot VM.
+      |
+      | Reloading of the sitemap:
+      |   If a sitemap is checked for reloading is determined by the
+      |   org.apache.cocoon.reloading (resp. org.apache.cocoon.reloading.sitemap)
+      |   property.
+      |   Set to "no", the sitemap is generated once at startup.
+      |   Set to "yes", the sitemap is regenerated if it changes.
+      |
+      | For development environment, set the check-reload to yes.
+      | For production environment, it is advisable to set check-reload to no.
+      +-->
+  <sitemap file="context://sitemap.xmap" logger="sitemap"/>
+
+<!-- ========================= Sitemap Flowscript ========================== -->
+
+  <!--+
+      |  The <flow-interpreters> element is used to describe the flowscript
+      |  engines usedd by the current instance.
+      |
+      |  The attributes recognized by the <flow-interpreters> element are:
+      |
+      |    default (string value):
+      |
+      |       the default interpreted language assumed for <map:script>
+      |       elements which do not specify a "language" attribute. If not
+      |       present, the first language that's described within the
+      |       <flow-interpreters> element is assumed to be the default
+      |       language.
+      |
+      |  Within <flow-interpreters> only <component-instance> elements are
+      |  recognized. The attributes recognized by this element are "name"
+      |  and "class". "name" specifies the name of a scripting language,
+      |  and "class" defines the Java class that implements it. See
+      |  org.apache.cocoon.components.flow.Interpreter for the Cocoon
+      |  interface with an scripting language interpreter.
+      |
+      |  A <component-instance> element contains as subelements the
+      |  following elements:
+      |
+      |    reload-scripts (boolean value, default false):
+      |       whether to check if the scripts source files are modified.
+      |       Checking for modification is an expensive operation, so leave
+      |       it disabled in a production environment. If not present it is
+      |       assumed to be "false" (if no property is overriding this). When
+      |       "true" *all* script files are
+      |       checked for modification on each function invocation done using
+      |       <map:call function="...">, but not more frequent than the value
+      |       of "check-time" (see below).
+      |       The default for this function is determined by the value of the
+      |       reloading property 'org.apache.cocoon.reloading.flow'.
+      |
+      |    check-time (long value, default 1000):
+      |       time in miliseconds between the checks for the last modification
+      |       date of script files.
+      |
+      |    debugger (boolean value, default false):
+      |       whether support for the JavaScript debugger should be enabled in
+      |       the control flow.
+      +-->
+  <flow-interpreters default="javascript" logger="flow">
+    <!-- FOM (Flow Object Model) -->
+    <component-instance exported="false" name="javascript" class="org.apache.cocoon.components.flow.javascript.fom.FOM_JavaScriptInterpreter">
+      <load-on-startup>resource://org/apache/cocoon/components/flow/javascript/fom/fom_system.js</load-on-startup>
+      <!--
+        <reload-scripts>true</reload-scripts>
+        <check-time>4000</check-time>
+        -->
+      <!--  <debugger>enabled</debugger> -->  <!-- JavaScript Debugger support -->
+    </component-instance>
+  </flow-interpreters>
+
+  <!--+
+      | Configuration for the continuations manager.
+      |
+      | This section specifies the default time-to-live of continuations
+      | in miliseconds using the "time-to-live" attribute of
+      | the <continuations-manager> element.
+      |
+      | The <expirations-check> element specifies different policies for
+      | expiring continuations. Currently only the "periodic" type is
+      | supported.
+      |
+      | If you need higher security you can bind your continuations
+      | to session. This way only the session that initially created
+      | the continuation can later resume it. Also if session gets
+      | invalidated all continuations are invalidated as well.
+      | Enable this feature for web applications by setting
+      | 'session-bound-continuations' to true.
+      +-->
+  <continuations-manager logger="flow.manager" time-to-live="3600000"
+                         session-bound-continuations="false">
+    <expirations-check type="periodic">
+      <offset>180000</offset>
+      <period>180000</period>
+    </expirations-check>
+  </continuations-manager>
+
+<!-- =================== Sitemap Input/Output Modules ====================== -->
+
+  <!--+
+      | InputModules are a replacement to reading values directly
+      | e.g. from request parameters. By using this abstraction and
+      | indirection, other components can be more generic and changes
+      | to the application logic are easier.
+      |
+      | A number of components already use InputModules: the sitemap processor,
+      | flow, some matchers, the linkrewriting transformer, database actions
+      | and more.
+      |
+      | For example the sitemap processor allows to obtain a value
+      | named "foo" from an the InputModule for request parameters by
+      | writing {request-param:foo} wherever a sitemap variable is
+      | allowed.
+      |
+      | Some InputModules need the help of other InputModules to
+      | obtain values and only apply a function to the obtained value
+      | or change the name of the attribute. These modules usually
+      | carry "Meta" in their name. An example is the ChainMetaModule
+      | which tries several other modules in turn until a non-null
+      | value is obtained or all modules are tied.
+      |
+      | For details and optional configuration parameters refer to the
+      | accompanying javadocs.
+      +-->
+  <input-modules>
+    <component-instance logger="core.modules.input" name="url-encode"       class="org.apache.cocoon.components.modules.input.URLEncodeModule">
+      <encoding>UTF-8</encoding>
+    </component-instance>
+    <component-instance logger="core.modules.input" name="url-decode"       class="org.apache.cocoon.components.modules.input.URLDecodeModule">
+      <encoding>UTF-8</encoding>
+    </component-instance>
+    <component-instance logger="core.modules.input" name="global"           class="org.apache.cocoon.components.modules.input.GlobalInputModule"/>
+    <component-instance logger="core.modules.input" name="request"          class="org.apache.cocoon.components.modules.input.RequestModule"/>
+    <component-instance logger="core.modules.input" name="baselink"         class="org.apache.cocoon.components.modules.input.BaseLinkModule" />
+    <component-instance logger="core.modules.input" name="session"          class="org.apache.cocoon.components.modules.input.SessionModule"/>
+    <component-instance logger="core.modules.input" name="environment-attr" class="org.apache.cocoon.components.modules.input.EnvironmentAttributeModule"/>
+    <component-instance logger="core.modules.input" name="request-param"    class="org.apache.cocoon.components.modules.input.RequestParameterModule"/>
+    <component-instance logger="core.modules.input" name="raw-request-param" class="org.apache.cocoon.components.modules.input.RawRequestParameterModule"/>
+    <component-instance logger="core.modules.input" name="request-attr"     class="org.apache.cocoon.components.modules.input.RequestAttributeModule"/>
+    <component-instance logger="core.modules.input" name="request-scoped-attr"     class="org.apache.cocoon.components.modules.input.RequestScopedAttributeModule"/>
+    <component-instance logger="core.modules.input" name="request-header"   class="org.apache.cocoon.components.modules.input.HeaderAttributeModule"/>
+    <component-instance logger="core.modules.input" name="session-attr"     class="org.apache.cocoon.components.modules.input.SessionAttributeModule"/>
+    <component-instance logger="core.modules.input" name="cookie"           class="org.apache.cocoon.components.modules.input.CookieModule"/>
+    <component-instance logger="core.modules.input" name="system-property"  class="org.apache.cocoon.components.modules.input.SystemPropertyModule"/>
+    <component-instance logger="core.modules.input" name="constant"         class="org.apache.cocoon.components.modules.input.StringConstantModule"/>
+    <component-instance logger="core.modules.input" name="random"           class="org.apache.cocoon.components.modules.input.RandomNumberModule"/>
+    <component-instance logger="core.modules.input" name="digest"       class="org.apache.cocoon.components.modules.input.DigestMetaModule"/>
+    <component-instance logger="core.modules.input" name="date"         class="org.apache.cocoon.components.modules.input.DateInputModule">
+      <!-- <format>EEE, d MMM yyyy HH:mm:ss Z</format> -->
+      <!--Eg: Mon, 28 Oct 2002 03:08:49 +1100 -->
+    </component-instance>
+    <component-instance logger="core.modules.input" name="nullinput"    class="org.apache.cocoon.components.modules.input.NullInputModule"/>
+    <component-instance logger="core.modules.input" name="realpath"     class="org.apache.cocoon.components.modules.input.RealPathModule"/>
+    <component-instance logger="core.modules.input" name="contextpath"  class="org.apache.cocoon.components.modules.input.ContextPathModule"/>
+    <component-instance logger="core.modules.input" name="naming"       class="org.apache.cocoon.components.modules.input.NamingInputModule">
+    </component-instance>
+    <component-instance logger="core.modules.input" name="cocoon-properties" class="org.apache.cocoon.components.modules.input.PropertiesFileModule">
+      <file src="resource://org/apache/cocoon/cocoon.properties" />
+    </component-instance>
+    <component-instance logger="core.modules.input" name="flow-attribute"     class="org.apache.cocoon.components.modules.input.FlowAttributeModule"/>
+    <component-instance logger="core.modules.input" name="flow-attr"          class="org.apache.cocoon.components.modules.input.FlowAttributeModule"/>
+    <component-instance logger="core.modules.input" name="flow-continuation"  class="org.apache.cocoon.components.modules.input.FlowContinuationModule"/>
+
+    <component-instance logger="core.modules.input" name="xmlmeta"      class="org.apache.cocoon.components.modules.input.XMLMetaModule"/>
+    <component-instance logger="core.modules.input" name="mapmeta"      class="org.apache.cocoon.components.modules.input.MapMetaModule"/>
+    <component-instance logger="core.modules.input" name="datemeta"     class="org.apache.cocoon.components.modules.input.DateMetaInputModule"/>
+    <component-instance logger="core.modules.input" name="jxpath"       class="org.apache.cocoon.components.modules.input.JXPathMetaModule"/>
+    <component-instance logger="core.modules.input" name="simplemap"    class="org.apache.cocoon.components.modules.input.SimpleMappingMetaModule"/>
+    <component-instance logger="core.modules.input" name="locate"       class="org.apache.cocoon.components.modules.input.LocateResource"/>
+    <component-instance logger="core.modules.input" name="chain"        class="org.apache.cocoon.components.modules.input.ChainMetaModule">
+      <input-module name="request-param"/>
+      <input-module name="request-attr"/>
+      <input-module name="session-attr"/>
+      <input-module name="defaults"/>
+    </component-instance>
+
+    <!--+
+        | Following three modules definitions, 'defaults', 'myxml', and
+        | 'slashdot', are used only in the samples.
+        +-->
+    <component-instance logger="core.modules.input" name="defaults"     class="org.apache.cocoon.components.modules.input.DefaultsModule">
+      <values>
+        <skin>defaultSkin</skin>
+        <base-url>http://localhost:8080/cocoon</base-url>
+      </values>
+    </component-instance>
+    <component-instance logger="core.modules.input" name="myxml"        class="org.apache.cocoon.components.modules.input.XMLFileModule">
+      <file src="context://samples/modules/forrestconf.xml"/>
+    </component-instance>
+    <component-instance logger="core.modules.input" name="slashdot"     class="org.apache.cocoon.components.modules.input.XMLFileModule">
+      <file src="http://slashdot.org/slashdot.rss"/>
+    </component-instance>
+
+  </input-modules>
+
+  <!--+
+      | OutputModules are companion modules for InputModules.
+      |
+      | The same principles apply here, only that OutputModules allow
+      | writing data to places. Apparently, there are a lot less
+      | places to write to than to read data from, thus there are only
+      | a few OutputModules coming with Apache Cocoon.
+      |
+      | One special feature of OutputModules is, that they expose some
+      | limited transactional behaviour. Hence it does not suffice to
+      | write a value, but it is required to confirm this at the
+      | end. Until then, the value could not be read from the
+      | corresponding InputModule. This behaviour is not enfored but
+      | it should be expected. Omitting a commit or rollback is an
+      | error.
+      |
+      | OutputModules are currently used by flow, a number of actions
+      | and transformers.
+      +-->
+  <output-modules>
+    <component-instance logger="core.modules.output" name="request-attr" class="org.apache.cocoon.components.modules.output.RequestAttributeOutputModule"/>
+    <component-instance logger="core.modules.output" name="request-attr-map" class="org.apache.cocoon.components.modules.output.RequestAttributeMap"/>
+    <component-instance logger="core.modules.output" name="session-attr" class="org.apache.cocoon.components.modules.output.SessionAttributeOutputModule"/>
+  </output-modules>
+
+<!-- ================================= XML ================================ -->
+
+  <!--+
+      | Entity resolution catalogs
+      |
+      | The default catalog is distributed at WEB-INF/entities/catalog
+      | This is the contextual pathname for Cocoon resources.
+      | You can override this path, if necessary, using the "catalog" parameter:
+      |
+      |    <parameter name="catalog" value="WEB-INF/entities/catalog"/>
+      |
+      | However, it is probably desirable to leave this default catalog config
+      | and declare your own local catalogs, which are loaded in addition to
+      | the system catalog.
+      |
+      | There are various ways to do local configuration (see "Entity Catalogs"
+      | documentation). One way is via the CatalogManager.properties file.
+      | As an additional method, you can specify the "local-catalog"
+      | parameter here.
+      |
+      | local-catalog:
+      |   The full filesystem pathname to a single local catalog file.
+      |
+      |  <parameter name="local-catalog" value="/usr/local/sgml/mycatalog"/>
+      |
+      | verbosity:
+      | The level of messages for status/debug (messages go to standard output)
+      | The following messages are provided ...
+      |  0 = none
+      |  1 = ? (... not sure yet)
+      |  2 = 1+, Loading catalog, Resolved public, Resolved system
+      |  3 = 2+, Catalog does not exist, resolvePublic, resolveSystem
+      |  10 = 3+, List all catalog entries when loading a catalog
+      |    (Cocoon also logs the "Resolved public" messages.)
+      |
+      |     <parameter name="verbosity" value="2"/>
+      +-->
+  <entity-resolver logger="core.resolver">
+    <parameter name="catalog" value="WEB-INF/entities/catalog"/>
+    <parameter name="verbosity" value="1"/>
+  </entity-resolver>
+
+  <!--+
+      | XML Parser
+      |
+      | Apache Cocoon requires a JAXP 1.1 parser. The default parser is
+      | org.apache.excalibur.xml.impl.JaxpParser.
+      | Note: If you have problems because your servlet environment uses its
+      | own parser not conforming to JAXP 1.1 try using the alternative
+      | XercesParser instead of the JaxpParser. To activate the XercesParser,
+      | change the class attribute to
+      |   class="org.apache.excalibur.xml.impl.XercesParser"
+      | You will also need to add a system property to your JVM,
+      | probably on the startup of your servlet engine like this:
+      | -Dorg.apache.excalibur.xml.sax.SAXParser=org.apache.excalibur.xml.impl.XercesParser
+      |
+      | Configuration parameters for the JaxpParser (not the XercesParser!):
+      | - validate (boolean, default = false): should the parser validate
+      |     parsed documents?
+      |     Note: XML validation is only being used for the documentation build.
+      |     (If you are going to use it elsewhere, then do so with caution.)
+      |     You really should have validated all of your XML documents already,
+      |     according to their proper DTD or schema. Do not expect Cocoon
+      |     to do it.
+      | - namespace-prefixes (boolean, default = false) : do we want
+      |     namespaces declarations also as 'xmlns:' attributes?
+      |     Note : setting this to true confuses some XSL processors
+      |     (e.g. Saxon).
+      | - stop-on-warning (boolean, default = true) : should the parser
+      |     stop parsing if a warning occurs ?
+      | - stop-on-recoverable-error (boolean, default = true) : should the
+      |     parser stop parsing if a recoverable error occurs ?
+      | - reuse-parsers (boolean, default = true) : do we want to reuse
+      |     parsers or create a new parser for each parse ?
+      |     Note : even if this parameter is true, parsers are not recycled
+      |     in case of parsing errors : some parsers (e.g. Xerces) do not like
+      |     to be reused after failure.
+      | - sax-parser-factory (string, optional) : the name of the
+      |     SAXParserFactory implementation class to be used instead of using
+      |     the standard JAXP mechanism (SAXParserFactory.newInstance()). This
+      |     allows to choose unambiguously the JAXP implementation to be used
+      |     when several of them are available in the classpath.
+      | - document-builder-factory (string, optional) : the name of the
+      |     DocumentBuilderFactory implementation to be used (similar to
+      |     sax-parser-factory for DOM).
+      | - drop-dtd-comments : should comment() events from DTD's be dropped?
+      |     Note: Since this implementation does not support the DeclHandler
+      |     interface anyway, it is quite useless to only have the comments
+      |     from DTD. And the comment events from the internal DTD subset
+      |     would appear in the serialized output again.
+      +-->
+  <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser"
+              logger="core.xml-parser" pool-max="32">
+    <parameter name="validate" value="false"/>
+    <parameter name="namespace-prefixes" value="false"/>
+    <parameter name="stop-on-warning" value="true"/>
+    <parameter name="stop-on-recoverable-error" value="true"/>
+    <parameter name="reuse-parsers" value="false"/>
+    <parameter name="drop-dtd-comments" value="true"/>
+  </xml-parser>
+
+  <!--+
+      | XSLT Processor
+      |
+      | 'incremental-processing' (only works with Xalan) allows the XSLT
+      | processor to start the output of the transformation as soon as possible.
+      | if set to false, the transforer waits until the end of the
+      | transformation to deliver the output.
+      | WARNING: * if you enable incremental-processing, you should be aware of
+      |            the following bug:
+      |            http://issues.apache.org/bugzilla/show_bug.cgi?id=13186
+      |          * incremental-processing creates an additional, non-pooled thread.
+      |          * using incremental-processing does not save memory, the input
+      |            tree will still be build completely.
+      |          * incremental processing is a 'static' thing in Xalan: if you
+      |            enable it on one xslt-processor, enable it on all.
+      +-->
+  <xslt-processor logger="core.xslt">
+     <parameter name="use-store" value="true"/>
+     <parameter name="incremental-processing" value="false"/>
+  </xslt-processor>
+
+  <!--+
+      | XSLT Processor using xsltc from Xalan
+      | For Interpreted Xalan use:
+      | <transformer-factory>org.apache.xalan.processor.TransformerFactoryImpl</transformer-factory>
+      +-->
+  <component logger="core.xslt"
+             role="org.apache.excalibur.xml.xslt.XSLTProcessor/xsltc"
+             class="org.apache.cocoon.components.xslt.TraxProcessor">
+     <parameter name="use-store" value="true"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.xsltc.trax.TransformerFactoryImpl"/>
+  </component>
+
+  <!--+
+      | Xalan XSLT Processor
+      +-->
+  <component logger="core.xslt"
+             role="org.apache.excalibur.xml.xslt.XSLTProcessor/xalan"
+             class="org.apache.cocoon.components.xslt.TraxProcessor">
+     <parameter name="use-store" value="true"/>
+     <parameter name="incremental-processing" value="false"/>
+     <parameter name="transformer-factory" value="org.apache.xalan.processor.TransformerFactoryImpl"/>
+  </component>
+
+  <!--+
+      | Saxon XSLT Processor
+      | For old (6.5.2) Saxon use:
+      |  <parameter name="transformer-factory" value="com.icl.saxon.TransformerFactoryImpl"/>
+      | For new (7+) Saxon use:
+      |  <parameter name="transformer-factory" value="net.sf.saxon.TransformerFactoryImpl"/>
+  <component logger="core.xslt"
+             role="org.apache.excalibur.xml.xslt.XSLTProcessor/saxon"
+             class="org.apache.cocoon.components.xslt.TraxProcessor">
+     <parameter name="use-store" value="true"/>
+     <parameter name="transformer-factory" value="com.icl.saxon.TransformerFactoryImpl"/>
+  </component>
+      +-->
+
+  <!--+
+      | Xpath Processor (Based on Xalan)
+      +-->
+  <xpath-processor class="org.apache.excalibur.xml.xpath.XPathProcessorImpl" logger="core.xpath"/>
+
+  <!--+
+      | The XMLizers converts different mime-types to XML
+      +-->
+  <xmlizer logger="core.xmlizer">
+    <parser role="org.apache.excalibur.xml.sax.SAXParser" mime-type="text/xml"/>
+  </xmlizer>
+
+<!-- ============================ Object Stores =========================== -->
+
+  <!--+
+      | Transient Store: holds objects that don't have to survive shutdown
+      |
+      | Common configuration parameters:
+      | maxobjects: Indicates how many objects will be held in the cache.
+      |    When the number of maxobjects has been reached. The last object
+      |    in the cache will be thrown out.
+      +-->
+  <transient-store logger="core.store.transient">
+    <parameter name="maxobjects" value="1000"/>
+  </transient-store>
+
+  <!--+
+      | Store: generic store. The default implementation is an in-memory store
+      | backed by a disk store (based on EHCache). This forms a two-stage
+      | cache composed of a fast in-memory MRU front-end and a persistent
+      | back-end which stores the less-used objects.
+      |
+      | Common configuration parameters:
+      | maxobjects: Indicates how many objects will be held in the cache.
+      |    When the number of maxobjects has been reached. The last object
+      |    in the cache will be thrown out.
+      +-->
+  <store logger="core.store">
+    <parameter name="maxobjects" value="1000"/>
+    <parameter name="use-cache-directory" value="true"/>
+  </store>
+
+  <!--+
+      | Store Janitor: the store garbage collector and memory usage controller.
+      |
+      | WARNING: Be careful with the heapsize and freememory parameters.
+      |           Wrong values can cause high cpu usage.
+      |
+      | Example configuration:
+      | Jvm settings:
+      |    -Xmx200000000
+      | store-janitor settings:
+      |    <parameter name="freememory" value="5000000"/>
+      |    <parameter name="heapsize" value="196000000"/>
+      |
+      | It is recommended to have heapsize equal to -Xmx, especially on Sun's
+      | JVM which are unable to shrink its heap once it grows above minimum.
+      | Freememory should be greater than amount of memory necessary for normal
+      | application operation.
+      | BUT: The heap size of the memory of the JVM is a little bit less than
+      |      the value you specify for -Xmx, so you have to set the heapsize
+      |      for the store janitor to a value which is lower (2% less seems
+      |      to be a working value).
+      +-->
+  <store-janitor logger="core.store.janitor">
+    <!--+
+        | How much free memory shall be available in the jvm?
+        | If not specified, defaults to 1Mb.
+        +-->
+    <parameter name="freememory" value="2048000"/>
+    <!--+
+        | How much memory at max jvm can consume?
+        | The default max heapsize for Sun's JVM is (almost) 64Mb,
+        | can be increased by specifying -Xmx command line parameter.
+        | If not specified, defaults to 66600000 bytes.
+        +-->
+    <parameter name="heapsize" value="66600000"/>
+    <!--+
+        | How often shall the cleanup thread check memory?
+        | If not specified, defaults to 10 seconds.
+        +-->
+    <parameter name="cleanupthreadinterval" value="10"/>
+    <!--+
+        | Experimental adaptive algorithm for cleanup interval
+    <parameter name="adaptivethreadinterval" value="true"/>
+        +-->
+    <!--+
+        | What percent of the store elements shall be dropped on low memory?
+        | If not specified, defaults to 10%
+        +-->
+    <parameter name="percent_to_free" value="10"/>
+    <!--+
+        | Shall garbage collector be invoked on low memory?
+        | If not specified, defaults to false.
+        +-->
+    <parameter name="invokegc" value="false"/>
+    <!--+
+        | Name of the thread pool to use.
+        | If not specified, defaults to 'daemon'.
+        +-->
+    <parameter name="thread-pool" value="daemon"/>
+
+    <!--+
+        | What should be the priority of the cleanup thread?
+        | This parameter is used only by older implementation of the janitor.
+        | New implementation uses centrally configured thread pool (see
+        | thread-pools element below).
+    <parameter name="threadpriority" value="5"/>
+        +-->
+  </store-janitor>
+
+<!-- ========================= Protocol Handlers =========================== -->
+
+  <!--+
+      | Source Factories
+      |
+      | Each source factory adds a special uri schemes to the system.
+      +-->
+  <source-factories>
+    <component-instance name="resource" class="org.apache.excalibur.source.impl.ResourceSourceFactory"/>
+    <component-instance name="context" class="org.apache.cocoon.components.source.impl.ContextSourceFactory"/>
+    <component-instance name="cocoon" class="org.apache.cocoon.components.source.impl.SitemapSourceFactory"/>
+
+    <!--+
+        | The "file:" source protocol is modifiable (can be written to) and
+        | traversable (directory structures can be crawled).
+        +-->
+    <component-instance name="file" class="org.apache.excalibur.source.impl.FileSourceFactory"/>
+    <component-instance name="upload" class="org.apache.cocoon.components.source.impl.PartSourceFactory"/>
+    <component-instance name="module" class="org.apache.cocoon.components.source.impl.ModuleSourceFactory"/>
+    <component-instance name="xmodule" class="org.apache.cocoon.components.source.impl.XModuleSourceFactory"/>
+    <component-instance name="zip" class="org.apache.cocoon.components.source.impl.ZipSourceFactory"/>
+    <component-instance name="empty" class="org.apache.cocoon.components.source.impl.EmptySourceFactory"/>
+
+    <!--+
+        | The "*" protocol handles all uri schemes that are not explicitely
+        | specified. This includes all JDK standard protocols.
+        +-->
+    <component-instance name="*" class="org.apache.excalibur.source.impl.URLSourceFactory"/>
+  </source-factories>
+
+<!-- ================ Internationalization Catalogs =================== -->
+
+  <!--+
+      | I18n Bundle Factory
+      |
+      | BundleFactory loads Bundles with i18n resources for the given locale.
+      | Default location for bundles specified with the 'catalogue-location'.
+      +-->
+  <i18n-bundles logger="core.i18n">
+    <!--+
+        | Role of the store component to be used for caching loaded bundles.
+        +-->
+    <store-role>org.apache.excalibur.store.Store/TransientStore</store-role>
+    <!--+
+        | Reload check delay. Default 60000 (1 minute), 0 means no delay
+        | (check always), -1 means no reload.
+        +-->
+    <reload-interval>60000</reload-interval>
+    <!--+
+        | Location of the default message catalogue. Optional.
+        +-->
+    <catalogue-location>context://samples/i18n/translations</catalogue-location>
+  </i18n-bundles>
+
+<!-- ====================== System Components =========================== -->
+
+  <!--+
+      | The Cache Manager is a component that can be used to cache content.
+      | It is currently used by the cinclude transformer
+      +-->
+  <component class="org.apache.cocoon.transformation.helpers.DefaultIncludeCacheManager"
+             role="org.apache.cocoon.transformation.helpers.IncludeCacheManager">
+    <!-- Set the preemptive-loader-url to a pipeline inside Cocoon that
+         contains the preemptive loader action. The URL must be absolute!
+    <parameter name="preemptive-loader-url"
+               value="http://localhost:8080/cocoon/samples/cinclude/loader"/>
+    -->
+  </component>
+
+  <!--+
+      | Runnable manager
+      |
+      | This component manages commands (Runnables) executed in background using
+      | preconfigured pools of worker threads
+      +-->
+  <runnable-manager logger="core.runnable">
+    <!--+
+        | This is the default configuration of the runnable-manager. More
+        | indepth information can be found at
+        | http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html
+        | The following elements can be used:
+        |
+        | thread-factory:        specifies the fully qualified class name of an
+        |                        org.apache.cocoon.components.thread.ThreadFactory
+        |                        implementation. It is responsible to create Thread
+        |                        classes.
+        | thread-pools:          container element for thread-pool elements.
+        | name:                  required name of the pool.
+        | priority:              optional priority all threads of the pool will
+        |                        have (the ThreadFactory will be set to this
+        |                        priority).The possible values  are:
+        |                          MIN:  corresponds to Thread#MIN_PRIORITY
+        |                          NORM: corresponds to Thread#NORM_PRIORITY (default)
+        |                          MAX:  corresponds to Thread#MAX_PRIORITY
+        | daemon:                whether newly created Threads should run in
+        |                        daemon mode or not. Default to false.
+        | queue-size:            optional size of a queue to hold Runnables if the
+        |                        pool is full. Possible values are:
+        |                          less than 0:    unbounded (default)
+        |                          equal to 0:     no queue at all
+        |                          greater than 0: size of the queue
+        | max-pool-size:         optional maximum number of threads in the pool.
+        |                        Defaults to 5.
+        |                        NOTE: if a queue is specified (queue-sie != 0)
+        |                              this value will be ignored.
+        | min-pool-size:         optional minimum number of threads in the pool.
+        |                        Defaults to 5.
+        |                        NOTE: if a queue has been specified (queue-sie != 0)
+        |                              this value will be used as the maximum of
+        |                              thread running concurrently.
+        | keep-alive-time-ms:    The time in ms an idle thread should keep alive
+        |                        before it might get garbage collected. This
+        |                        defaults to 60000 ms.
+        | block-policy;          The policy to be used if all resources (thread in
+        |                        the pool and slots in the queue) are exhausted.
+        |                        Possible values are:
+        |                          ABORT:         Throw a RuntimeException
+        |                          DISCARD:       Throw away the current request
+        |                                         and return.
+        |                          DISCARDOLDEST: Throw away the oldest request
+        |                                         and return.
+        |                          RUN (default): The thread making the execute
+        |                                         request runs the task itself.
+        |                                         This policy helps guard against
+        |                                         lockup.
+        |                          WAIT:          Wait until a thread becomes
+        |                                         available. This policy should, in
+        |                                         general, not be used if the
+        |                                         minimum number of threads is zero,
+        |                                         in which case a thread may never
+        |                                         become available.
+        | shutdown-graceful:     Terminate thread pool after processing all
+        |                        Runnables currently in queue. Any Runnable entered
+        |                        after this point will be discarded. A shut down
+        |                        pool cannot be restarted. This also means that a
+        |                        pool will need keep-alive-time-ms to terminate.
+        |                        The default value not to shutdown graceful.
+        | shutdown-wait-time-ms: The time in ms to wait before issuing an
+        |                        immediate shutdown after a graceful shutdown
+        |                        has been requested.
+        +-->
+    <thread-factory>org.apache.cocoon.components.thread.DefaultThreadFactory</thread-factory>
+    <thread-pools>
+      <!--+
+          | This is the default thread pool. It's use fits best for short
+          | running background tasks.
+          +-->
+      <thread-pool>
+        <name>default</name>
+        <priority>NORM</priority>
+        <daemon>false</daemon>
+        <queue-size>-1</queue-size>
+        <max-pool-size>5</max-pool-size>
+        <min-pool-size>5</min-pool-size>
+        <keep-alive-time-ms>60000</keep-alive-time-ms>
+        <block-policy>ABORT</block-policy>
+        <shutdown-graceful>false</shutdown-graceful>
+        <shutdown-wait-time-ms>-1</shutdown-wait-time-ms>
+      </thread-pool>
+      <!--+
+          | This thread pool should be used for daemons (permanently running
+          | threads).
+          +-->
+      <thread-pool>
+        <name>daemon</name>
+        <priority>NORM</priority>
+        <daemon>true</daemon>
+        <queue-size>0</queue-size>
+        <max-pool-size>-1</max-pool-size>
+        <min-pool-size>1</min-pool-size>
+        <keep-alive-time-ms>60000</keep-alive-time-ms>
+        <block-policy>ABORT</block-policy>
+        <shutdown-graceful>false</shutdown-graceful>
+        <shutdown-wait-time-ms>-1</shutdown-wait-time-ms>
+      </thread-pool>
+    </thread-pools>
+  </runnable-manager>
+
+</components>
diff --git a/non-releases/trunk_before_flattening/src/webapp/not-found.xml b/non-releases/trunk_before_flattening/src/webapp/not-found.xml
new file mode 100644
index 0000000..fb471ff
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/not-found.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--+
+    | This a simple message page that is shown when a resource is not found.
+    |
+    | CVS $Id: not-found.xml,v 1.3 2004/03/06 02:25:58 antonio Exp $
+    +-->
+<welcome>
+ <message>
+   Sorry, Cocoon couldn't find the resource you requested.
+ </message>
+</welcome>
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/icons/cocoon.ico b/non-releases/trunk_before_flattening/src/webapp/resources/icons/cocoon.ico
new file mode 100644
index 0000000..7b2a9f1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/icons/cocoon.ico
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/images/cocoon.gif b/non-releases/trunk_before_flattening/src/webapp/resources/images/cocoon.gif
new file mode 100644
index 0000000..8b6aed4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/images/cocoon.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/images/powered.gif b/non-releases/trunk_before_flattening/src/webapp/resources/images/powered.gif
new file mode 100644
index 0000000..26a5c64
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/images/powered.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-300.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-300.gif
new file mode 100644
index 0000000..8b6aed4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-300.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-458.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-458.gif
new file mode 100644
index 0000000..fccde14
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-458.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-button-powered-158.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-button-powered-158.gif
new file mode 100644
index 0000000..bb70baf
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-button-powered-158.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-126.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-126.gif
new file mode 100644
index 0000000..a39d380
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-126.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-158.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-158.gif
new file mode 100644
index 0000000..192a964
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-158.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-88.png b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-88.png
new file mode 100644
index 0000000..64e25d3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-built-88.png
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-126.gif b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-126.gif
new file mode 100644
index 0000000..26a5c64
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-126.gif
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-88.png b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-88.png
new file mode 100644
index 0000000..fa57a65
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/cocoon-buttons-powered-88.png
Binary files differ
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/logos/logos.html b/non-releases/trunk_before_flattening/src/webapp/resources/logos/logos.html
new file mode 100644
index 0000000..ad1fd92
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/logos/logos.html
@@ -0,0 +1,38 @@
+<html>
+<body>
+<table border="0" width="100%">
+  <tr>
+    <td>Cocoon logo (300x49)</td>
+    <td><img border="0" src="cocoon-300.gif" width="300" height="49"></td>
+  </tr>
+  <tr>
+    <td>Cocoon logo (458x75)</td>
+    <td><img border="0" src="cocoon-458.gif" width="458" height="75"></td>
+  </tr>
+  <tr>
+    <td>Powered by Cocoon (158x50) (transparent GIF)</td>
+    <td><img border="0" src="cocoon-button-powered-158.gif" width="158" height="50"></td>
+  </tr>
+  <tr>
+    <td>Powered by Cocoon (126x40) (transparent GIF)</td>
+    <td><img border="0" src="cocoon-buttons-powered-126.gif" width="126" height="40"></td>
+  </tr>
+  <tr>
+    <td>Built by Cocoon (158x50) (transparent GIF)</td>
+    <td><img border="0" src="cocoon-buttons-built-158.gif" width="158" height="50"></td>
+  </tr>
+  <tr>
+    <td>Built by Cocoon (126x40) (transparent GIF)</td>
+    <td><img border="0" src="cocoon-buttons-built-126.gif" width="126" height="40"></td>
+  </tr>
+  <tr>
+    <td>Alternative built by Cocoon (88x31) (colored PNG)</td>
+    <td><img border="0" src="cocoon-buttons-built-88.png" width="88" height="31"></td>
+  </tr>
+  <tr>
+    <td>Alternative powered by Cocoon (88x31) (colored PNG)</td>
+    <td><img border="0" src="cocoon-buttons-powered-88.png" width="88" height="31"></td>
+  </tr>
+</table>
+</body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/scripts/main.js b/non-releases/trunk_before_flattening/src/webapp/resources/scripts/main.js
new file mode 100644
index 0000000..fe83da5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/scripts/main.js
@@ -0,0 +1,31 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+function toggle(id) {
+    var element = document.getElementById(id);
+    with (element.style) {
+        if ( display == "none" ){
+            display = ""
+        } else{
+            display = "none"
+        }
+    }
+    var text = document.getElementById(id + "-switch").firstChild;
+    if (text.nodeValue == "[show]") {
+        text.nodeValue = "[hide]";
+    } else {
+        text.nodeValue = "[show]";
+    }
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/scripts/prettycontent.js b/non-releases/trunk_before_flattening/src/webapp/resources/scripts/prettycontent.js
new file mode 100644
index 0000000..6378e14
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/scripts/prettycontent.js
@@ -0,0 +1,66 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+function xml2htmlToggle(event) {
+
+    var mark;
+    if (event.srcElement) {
+      mark = event.srcElement;
+    } else {
+      mark = event.target;
+    }
+
+    while ((mark.className != "b") && (mark.nodeName != "BODY")) {
+        mark = mark.parentNode
+    }
+
+    var e = mark;
+
+    while ((e.className != "e") && (e.nodeName != "BODY")) {
+        e = e.parentNode
+    }
+
+    if (mark.childNodes[0].nodeValue == "+") {
+        mark.childNodes[0].nodeValue = "-";
+        var starthiding = false;
+        for (var i = 0; i < e.childNodes.length; i++) {
+            var name = e.childNodes[i].nodeName;
+            if (name != "#text") {
+              if (starthiding) {
+                if (name == "PRE" || name == "SPAN") {
+                  window.status = "inline";
+                  e.childNodes[i].style.display = "inline";
+                } else {
+                  e.childNodes[i].style.display = "block";
+                }
+              } else {
+                 starthiding = true;
+              }
+            }
+        }
+    } else if (mark.childNodes[0].nodeValue == "-") {
+        mark.childNodes[0].nodeValue = "+";
+        var starthiding = false;
+        for (var i = 0; i < e.childNodes.length; i++) {
+            if (e.childNodes[i].nodeName != "#text") {
+                if (starthiding) {
+                    e.childNodes[i].style.display = "none";
+                } else {
+                    starthiding = true;
+                }
+            }
+        }
+    }
+} 
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/styles/main.css b/non-releases/trunk_before_flattening/src/webapp/resources/styles/main.css
new file mode 100644
index 0000000..6932b3c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/styles/main.css
@@ -0,0 +1,89 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+body { background-color: white; color: black; font-family: verdana, helvetica, arial, sans-serif; font-size: 80%; }
+
+h1 { color: #336699; text-align: center; font-size: 3em; padding-bottom: 10px; margin: 0px; }
+h2 { color: #336699; }
+h3 { color: #336699; }
+h4 { color: #336699; }
+
+a:link { color: #336699; }
+a:visited { color: #800080; }
+a:hover { color: #800080; background-color: #ffff80; }
+a:active { color: #006666; }
+
+img { border: 0; }
+.figure { text-align: center; }
+
+span.year { color: #336699; }
+
+p.copyright { text-align: center; padding-top: 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }
+p.author { color: #336699; padding-bottom: 10px; }
+p.block { text-align: center; }
+
+hr { height: 0px; color: #336699; }
+
+span.description { color: #336699; font-weight: bold; }
+span.switch { cursor: pointer; margin-left: 5px; text-decoration: underline; }
+
+/* Samples */
+
+.samplesGroup {
+    /* a tasteful shade of blue */
+    background-color: #BFCCDF;
+    color: black;
+    border-width: 0px 0px 2px 0px;
+    border-style: solid;
+    border-color: #336699;
+    font-size:120%;
+    padding-left: 0.2em;
+    padding-top: 0.2em;
+    padding-bottom: 0.2em;
+    margin-top: 1em;
+    margin-bottom: 0;
+ 
+    /* mozilla and some others support the fancy CSS3 borders */
+    -moz-border-radius-bottomleft: 1em;
+    border-radius-bottomleft: 1em;
+}
+
+.samplesNote {
+    color: #333333;
+    margin: 0.5em;
+    padding: 0.2em;
+    background-color: #ffffcc;
+    font-style: italic;
+}
+
+.samplesStatusNote {
+	font-style: italic;
+	font-size: 80%;
+	text-align: right;
+	margin: 2px;
+	padding: 0;
+}
+
+.samplesText {
+    margin-top: 0.2em;
+}
+
+div.resources {
+    text-align: right;
+}
+
+div.resources a {
+    margin: 5px;
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/resources/styles/prettycontent.css b/non-releases/trunk_before_flattening/src/webapp/resources/styles/prettycontent.css
new file mode 100644
index 0000000..8ebb0fa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/resources/styles/prettycontent.css
@@ -0,0 +1,27 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+BODY  {background-color: white; color: black; font-family: monospace;}
+.b  {cursor:pointer; color:red; font-weight:bold; text-decoration:none; padding-right: 2px;}
+.e  {border: 0px; padding: 0px; margin: 0px 0px 0px 2em; text-indent:-1em;}
+.en {color:#000088; font-weight:bold;}
+.an {color:#880000}
+.av {color:#888888}
+.c  {color:#008800}
+.t  {color:black}
+.m  {color:navy}
+.pi {color:red}
+PRE {margin:0px; display:inline}
+DIV {border:0; padding:0; margin:0;}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/blocks/directory2xsamples.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/directory2xsamples.xsl
new file mode 100644
index 0000000..a058cf4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/directory2xsamples.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:dir="http://apache.org/cocoon/directory/2.0"
+                exclude-result-prefixes="dir">
+
+  <xsl:template match="/dir:directory">
+    <xsamples>
+      <xsl:apply-templates select="*"/>
+    </xsamples>
+  </xsl:template>
+
+  <xsl:template match="dir:directory">
+    <xsl:apply-templates select="*"/>
+  </xsl:template>
+
+  <xsl:template match="dir:file">
+    <xsl:variable name="blockName" select="parent::dir:directory/@name"/>
+    <xsl:if test="substring-before(@name, '.xsamples')">
+      <sample name="cocoon-block-{$blockName}" block-name="{$blockName}">
+        <xsl:copy-of select=".//xsamples"/>
+      </sample>
+    </xsl:if>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/blocks/dynamic-page2html.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/dynamic-page2html.xsl
new file mode 100644
index 0000000..4fd35a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/dynamic-page2html.xsl
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:xsp-request="http://apache.org/xsp/request/2.0"
+  xmlns:xsp="http://apache.org/xsp">
+
+  <xsl:include href="../common/style/xsl/html/simple-page2html.xsl"/>
+ 
+  <xsl:template match="xsp-request:uri">
+    <b><xsl:value-of select="."/></b>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:parameter">
+    <i><xsl:value-of select="@name"/></i>:<b><xsl:value-of select="."/></b>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:parameter-values">
+    <p>Parameter Values for "<xsl:value-of select="@name"/>":</p>
+
+    <ul>
+      <xsl:for-each select="xsp-request:value">
+        <li>
+	  <xsl:value-of select="."/>
+	</li>
+      </xsl:for-each>
+    </ul>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:parameter-names">
+    <p>All Parameter Names:</p>
+
+    <ul>
+      <xsl:for-each select="xsp-request:name">
+        <li>
+	  <xsl:value-of select="."/>
+	</li>
+      </xsl:for-each>
+    </ul>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:headers">
+    <p>Headers:</p>
+    
+    <ul>
+      <xsl:for-each select="xsp-request:header">
+	<li>
+          <i><xsl:value-of select="@name"/></i>:
+          <b><xsl:value-of select="."/></b>
+	</li>
+      </xsl:for-each>
+    </ul>
+    <br/>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:header">
+    <i><xsl:value-of select="@name"/></i>:<b><xsl:value-of select="."/></b>
+  </xsl:template>
+
+  <xsl:template match="xsp-request:header-names">
+    <p>All Header names:</p>
+
+    <ul>
+      <xsl:for-each select="xsp-request:name">
+        <li>
+	  <xsl:value-of select="."/>
+	</li>
+      </xsl:for-each>
+    </ul>
+  </xsl:template>
+
+
+
+  <xsl:template match="textarea/xsp-request:uri">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:parameter">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:parameter-values">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:parameter-names">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:headers">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:header">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="textarea/xsp-request:header-names">
+    <xsl:call-template name="copy"/>
+  </xsl:template>
+
+  <xsl:template match="@*|node()" priority="-1" name="copy">
+   <xsl:copy>
+    <xsl:apply-templates select="@*|node()"/>
+   </xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/blocks/filter-blocks.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/filter-blocks.xsl
new file mode 100644
index 0000000..63a5404
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/filter-blocks.xsl
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Generate a samples page by combining the aggregated xsamples files
+    | with the gump descriptor and a list of blocks to include in the page.
+    |
+    | CVS $Id: gump2samples.xsl 36239 2004-08-11 18:28:06Z vgritsenko $
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:param name="currentPage"/>
+  
+  <xsl:variable name="page" select="root/pages/samples-pages/page[@name=$currentPage]"/>
+  <xsl:variable name="xsamples" select="root/xsamples/xsamples"/>
+  <xsl:variable name="gump" select="root/gump/module"/>
+
+  <xsl:template match="/">
+	<samples name="{normalize-space($page/title)}" add-view-links="false">
+	  <xsl:copy-of select="$page/links"/>
+	  <!-- select either all samples or those which are selected in the current page -->
+	  <xsl:choose>
+		  <xsl:when test="$page/@filter-blocks='true'">
+		    <xsl:for-each select="$page/blocks/block">
+		      <xsl:variable name="currentBlock" select="concat('cocoon-block-',@name)"/>
+		      <xsl:apply-templates select="$xsamples/sample[@name=$currentBlock]"/>
+		    </xsl:for-each>
+		  </xsl:when>
+		  
+		  <xsl:otherwise>
+		    <xsl:apply-templates select="$xsamples/sample">
+		      <xsl:sort select="@name"/>
+		    </xsl:apply-templates>
+		    <xsl:call-template name="inactive-blocks"/>
+		  </xsl:otherwise>
+	  </xsl:choose>
+	</samples>  
+  </xsl:template>
+  
+  <xsl:template match="sample">
+    <xsl:apply-templates select="xsamples/*" mode="copy"/>
+  </xsl:template>
+  
+  <xsl:template match="*" mode="copy">
+    <xsl:copy>
+      <xsl:copy-of select="@*"/>
+      <xsl:apply-templates mode="copy"/>
+      <xsl:apply-templates select="." mode="hook"/>
+    </xsl:copy>
+  </xsl:template>
+  
+  <xsl:template match="*" mode="hook"/>
+  
+  <!-- add block name and status to sample -->
+  <xsl:template match="sample" mode="hook">
+    <xsl:variable name="gumpBlockName" select="ancestor::sample[1]/@name"/>
+    <xsl:variable name="gumpInfo" select="$gump/project[@name=$gumpBlockName]"/>
+    <p class="samplesStatusNote">
+    		block: <b><xsl:value-of select="ancestor::sample[1]/@block-name"/></b>
+    		,
+    		status: <b><xsl:value-of select="$gumpInfo/@status"/></b>
+    </p>
+  </xsl:template>
+  
+  <!-- if outputting all blocks, indicate which are not active -->
+  <xsl:template name="inactive-blocks">
+    <additional-info title="Blocks without samples">
+    Here is the list of blocks which have not been included in the build or which do not
+    have samples (i.e. do not have an .xsamples file):
+    <br/>
+    <em>
+    <xsl:for-each select="$gump/project[starts-with(@name,'cocoon-block')]">
+      <xsl:sort select="@name"/>
+      <xsl:variable name="blockName" select="@name"/>
+      <xsl:if test="not($xsamples/sample[@name=$blockName])">
+        <xsl:value-of select="concat(substring-after(@name,'cocoon-block-'),' ')"/>
+      </xsl:if>
+    </xsl:for-each>
+    </em>
+    </additional-info>
+  </xsl:template>
+  
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/blocks/samples-pages.xml b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/samples-pages.xml
new file mode 100644
index 0000000..43eed9f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/samples-pages.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+	Define the available samples pages, and which blocks are visible
+	on which page
+-->
+
+<samples-pages>
+  <page name="main" filter-blocks="true">
+    <title>
+    		Main Cocoon samples and featured new blocks
+    </title>
+    <blocks>
+    		<block name="core-samples-main"/>
+    		<block name="tour"/>
+    		<block name="forms"/>
+    		<block name="ajax"/>

+            <block name="portal-sample"/>
+    </blocks>
+    <links>
+    		<link role="see-also" href="all-samples">All samples</link>
+    		<link href="/">Home</link>
+    </links>
+  </page>
+  
+  <page name="all" filter-blocks="false">
+    <title>
+    		List of all available samples
+    </title>
+    <blocks/>
+    <links>
+    		<link role="see-also" href="main-samples">Main samples</link>
+    		<link href="../test/">Test pages</link>
+    </links>
+  </page>
+</samples-pages>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/blocks/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/sitemap.xmap
new file mode 100644
index 0000000..9c868c2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/blocks/sitemap.xmap
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  
+  <map:views>
+    <map:view name="debug1" from-label="debug1">
+      <map:serialize type="xml"/>
+    </map:view>
+    <map:view name="debug2" from-label="debug2">
+      <map:serialize type="xml"/>
+    </map:view>
+  </map:views>
+  
+  <map:pipelines>
+    <map:pipeline>
+    
+      <map:match pattern="">
+        <map:redirect-to uri="main-samples"/>
+      </map:match>
+      
+      <!-- generate the samples pages by filtering the aggregation of .xsamples files -->
+      <map:match pattern="*-samples">
+        <map:aggregate label="debug1" element="root">
+          <map:part element="gump" src="module.xml"/>
+          <map:part element="xsamples" src="cocoon:/xsamples"/>
+          <map:part element="pages" src="samples-pages.xml"/>
+        </map:aggregate>
+        
+        <!-- 
+        		keep only blocks defined in samples-pages.xml for the current page,
+        		and mix with gump info
+        -->
+        <map:transform label="debug2" src="filter-blocks.xsl">
+          <map:parameter name="currentPage" value="{1}"/>
+        </map:transform>
+        
+        <map:transform src="context://samples/common/style/xsl/html/simple-samples2html.xsl">
+          <map:parameter name="contextPath" value="{request:contextPath}"/>
+        </map:transform>
+        
+        <map:serialize/>
+      </map:match>
+      
+      <!-- 
+      	aggregate all the xsamples files
+       --> 
+      <map:match pattern="xsamples">
+      	<map:generate type="xpathdirectory" src="./">
+      	  <map:parameter name="depth" value="2"/>
+      	  <map:parameter name="xpath" value="/xsamples"/>
+      	  <map:parameter name="xmlFiles" value="\.xsamples$"/>
+      	  <map:parameter name="include" value="^[a-z0-9\-]+$|\.xsamples"/>
+      	</map:generate>
+      	<map:transform src="directory2xsamples.xsl"/>
+      	<map:serialize type="xml"/>
+      </map:match>
+      
+      <!-- mount everything else -->
+      <map:match pattern="*/**">
+        <map:mount src="{1}/" uri-prefix="{1}"/>
+      </map:match>
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/adding-header.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/adding-header.xsl
new file mode 100644
index 0000000..330ebb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/adding-header.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

+  <xsl:param name="contextPath"/>

+  <xsl:param name="servletPath" select="string('/samples')"/>

+  <xsl:param name="sitemapURI"/>

+  <xsl:variable name="directory" select="substring-before($servletPath,$sitemapURI)"/>

+  <!-- assume that sitemapURIs don't occur in servletPath more than once -->

+  <xsl:variable name="sitemap" select="concat($directory,'sitemap.xmap')"/>

+  <xsl:template match="body">

+    <div style="text-align:right;width:100%;">

+      <a href="?cocoon-view=content">Content View</a> |

+      <a href="?cocoon-view=pretty-content">Source</a> |

+      <a href="{$sitemap}?cocoon-view=pretty-content">Sitemap</a>

+    </div>

+    <xsl:apply-templates/>

+  </xsl:template>

+  <xsl:template match="@*|node()" priority="-2">

+    <xsl:copy>

+      <xsl:apply-templates select="@*|node()"/>

+    </xsl:copy>

+  </xsl:template>

+  <xsl:template match="text()" priority="-1">

+    <xsl:value-of select="."/>

+  </xsl:template>

+</xsl:stylesheet>

diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/complex-page2html.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/complex-page2html.xsl
new file mode 100644
index 0000000..cfe7321
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/complex-page2html.xsl
@@ -0,0 +1,165 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Covert samples file to the HTML page. Uses styles/main.css stylesheet.
+    |
+    | $Id$
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:param name="contextPath" select="string('/cocoon')"/>
+
+  <xsl:template match="/">
+    <html>
+      <head>
+        <title>Apache Cocoon @version@</title>
+        <link rel="SHORTCUT ICON" href="favicon.ico"/>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <xsl:apply-templates select="document/header/style"/>
+        <xsl:apply-templates select="document/header/script"/>
+      </head>
+      <body>
+        <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+          <tr>
+            <td width="*">The Apache Software Foundation is proud to present...</td>
+            <td width="40%" align="center"><img border="0" src="{$contextPath}/images/cocoon.gif"/></td>
+            <td width="30%" align="center">Version: <b>@version@</b></td>
+          </tr>
+        </table>
+
+        <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+          <tr>
+            <td width="50%">
+              <h2><xsl:value-of select="document/header/title"/></h2>
+            </td>
+            <td width="25%">
+              <xsl:apply-templates select="document/header/tab"/>
+            </td>
+            <td nowrap="nowrap" align="right">
+              Orthogonal views:
+              <a href="?cocoon-view=content">Content</a>
+              &#160;
+              <a href="?cocoon-view=pretty-content">Pretty content</a>
+              &#160;
+              <a href="?cocoon-view=links">Links</a>
+            </td>
+          </tr>
+        </table>
+
+        <p>
+          <xsl:choose>
+            <xsl:when test="document/body/row">
+              <table width="100%">
+                <xsl:apply-templates select="document/body/*"/>
+              </table>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:apply-templates select="document/body/*"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </p>
+
+        <p class="copyright">
+          Copyright &#169; @year@ <a href="http://www.apache.org/">The Apache Software Foundation</a>.
+          All rights reserved.
+        </p>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="style">
+    <link type="text/css" rel="stylesheet" href="{@href}"/>
+  </xsl:template>
+ 
+  <xsl:template match="script">
+    <script type="text/javascript" src="{@href}"/>
+  </xsl:template>
+ 
+  <xsl:template match="tab">
+    <a href="{@href}"><i><xsl:value-of select="@title"/></i></a>&#160;
+  </xsl:template>
+ 
+  <xsl:template match="row">
+    <tr>
+      <xsl:apply-templates select="column"/>
+    </tr>
+  </xsl:template>
+ 
+  <xsl:template match="column">
+    <td valign="top">
+      <h4 class="samplesGroup"><xsl:value-of select="@title"/></h4>
+      <p class="samplesText"><xsl:apply-templates/></p>
+    </td> 
+  </xsl:template>
+
+  <xsl:template match="section">
+    <xsl:choose> <!-- stupid test for the hirachy deep -->
+      <xsl:when test="../../../section">
+        <h5><xsl:value-of select="title"/></h5>
+      </xsl:when>
+      <xsl:when test="../../section">
+        <h4><xsl:value-of select="title"/></h4>
+      </xsl:when>
+      <xsl:when test="../section">
+        <h4 class="samplesGroup"><xsl:value-of select="title"/></h4>
+      </xsl:when>
+    </xsl:choose>
+    <p>
+      <xsl:apply-templates select="*[name()!='title']"/>
+    </p>
+  </xsl:template>
+
+  <xsl:template match="source">
+    <div style="background: #b9d3ee; border: thin; border-color: black; border-style: solid; padding-left: 0.8em; 
+                padding-right: 0.8em; padding-top: 0px; padding-bottom: 0px; margin: 0.5ex 0px; clear: both;">
+      <pre>
+        <xsl:value-of select="."/>
+      </pre>
+    </div>
+  </xsl:template>
+ 
+  <xsl:template match="link">
+    <a href="{@href}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+ 
+  <xsl:template match="strong">
+    <b>
+      <xsl:apply-templates/>
+    </b>
+  </xsl:template>
+ 
+  <xsl:template match="anchor">
+    <a name="{@name}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+ 
+  <xsl:template match="para">
+    <p>
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <xsl:template match="*|@*|node()|text()" priority="-1">
+    <xsl:copy><xsl:apply-templates select="*|@*|node()|text()"/></xsl:copy>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-header.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-header.xsl
new file mode 100644
index 0000000..330ebb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-header.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>

+<!--

+  Copyright 1999-2004 The Apache Software Foundation

+

+  Licensed 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.

+-->

+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

+  <xsl:param name="contextPath"/>

+  <xsl:param name="servletPath" select="string('/samples')"/>

+  <xsl:param name="sitemapURI"/>

+  <xsl:variable name="directory" select="substring-before($servletPath,$sitemapURI)"/>

+  <!-- assume that sitemapURIs don't occur in servletPath more than once -->

+  <xsl:variable name="sitemap" select="concat($directory,'sitemap.xmap')"/>

+  <xsl:template match="body">

+    <div style="text-align:right;width:100%;">

+      <a href="?cocoon-view=content">Content View</a> |

+      <a href="?cocoon-view=pretty-content">Source</a> |

+      <a href="{$sitemap}?cocoon-view=pretty-content">Sitemap</a>

+    </div>

+    <xsl:apply-templates/>

+  </xsl:template>

+  <xsl:template match="@*|node()" priority="-2">

+    <xsl:copy>

+      <xsl:apply-templates select="@*|node()"/>

+    </xsl:copy>

+  </xsl:template>

+  <xsl:template match="text()" priority="-1">

+    <xsl:value-of select="."/>

+  </xsl:template>

+</xsl:stylesheet>

diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-page2html.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-page2html.xsl
new file mode 100644
index 0000000..96265f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-page2html.xsl
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:param name="contextPath"/>
+  <xsl:param name="servletPath" select="string('/samples')"/>
+  <xsl:param name="sitemapURI"/>
+
+  <xsl:variable name="directory" select="substring-before($servletPath,$sitemapURI)"/>
+  <!-- assume that sitemapURIs don't occur in servletPath more than once -->
+  <xsl:variable name="sitemap" select="concat($directory,'sitemap.xmap')"/>
+
+  <xsl:template match="page">
+   <html>
+     <head>
+       <title><xsl:value-of select="title"/></title>
+       <link rel="stylesheet" href="{$contextPath}/styles/main.css" title="Default Style"/>
+       <!-- copy local CSS, if any -->
+       <xsl:copy-of select="style"/>
+     </head>
+     <body>
+       <xsl:call-template name="resources"/>
+       <xsl:apply-templates/>
+     </body>
+   </html>
+  </xsl:template>
+
+  <xsl:template name="resources">
+    <div class="resources">
+      <a href="?cocoon-view=content">Content View</a>
+      <a href="?cocoon-view=pretty-content">Source</a>
+      <a href="{$sitemap}?cocoon-view=pretty-content">Sitemap</a>
+      <xsl:for-each select="resources/resource">
+        <xsl:variable name="href">
+          <xsl:choose>
+            <xsl:when test="@type='file'">
+              <!-- we need an explicite match in the sitemap showing
+                   the source of these resources -->
+              <xsl:value-of select="@href"/>
+            </xsl:when>
+            <xsl:when test="@type='doc'">
+              <xsl:value-of select="concat($contextPath, '/docs/', @href)"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:value-of select="concat($contextPath, '/', @href)"/>
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:variable>
+        <a class="{@type}" href="{$href}">
+          <xsl:apply-templates/>
+        </a>
+      </xsl:for-each>
+    </div>
+  </xsl:template>
+
+  <xsl:template match="resources"/>
+
+  <xsl:template match="title">
+   <h2>
+     <xsl:apply-templates/>
+   </h2>
+  </xsl:template>
+  
+  <xsl:template match="content">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="para">
+   <p>
+     <xsl:apply-templates/>
+   </p>
+  </xsl:template>
+
+  <xsl:template match="link">
+   <a href="{@href}">
+     <xsl:apply-templates/>
+   </a>
+  </xsl:template>
+
+  <xsl:template match="error">
+    <span class="error">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+
+  <xsl:template match="@*|node()" priority="-2"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>
+  <xsl:template match="text()" priority="-1"><xsl:value-of select="."/></xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-samples2html.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-samples2html.xsl
new file mode 100644
index 0000000..5ed3e25
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/common/style/xsl/html/simple-samples2html.xsl
@@ -0,0 +1,224 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Covert samples file to the HTML page. Uses styles/main.css stylesheet.
+    |
+    | $Id$
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <xsl:param name="contextPath"/>
+  <xsl:variable name="stdLinks" select="samples/links/link[not(@role)]"/>
+  <xsl:variable name="seeAlsoLinks" select="samples/links/link[@role='see-also']"/>
+
+  <xsl:template match="/">
+    <html>
+      <head>
+        <title>Apache Cocoon @version@</title>
+        <link rel="SHORTCUT ICON" href="favicon.ico"/>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+      </head>
+      <body>
+       <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+         <tr>
+           <td width="*">The Apache Software Foundation is proud to present...</td>
+           <td width="40%" align="center"><img border="0" src="{$contextPath}/images/cocoon.gif"/></td>
+           <td width="30%" align="center">Version: <b>@version@</b></td>
+         </tr>
+       </table>
+
+       <table border="0" cellspacing="2" cellpadding="2" align="center" width="100%">
+         <tr>
+           <td width="75%">
+             <h2><xsl:value-of select="samples/@name"/></h2>
+             <xsl:if test="$seeAlsoLinks">
+               <div class="seeAlsoLinks">
+                 <b>See also:</b>&#160;<xsl:apply-templates select="$seeAlsoLinks"/>
+               </div>
+             </xsl:if>
+           </td>
+           <td nowrap="nowrap" align="right">
+	           <xsl:apply-templates select="$stdLinks"/>
+	           <xsl:if test="not(samples/@add-view-links='false')">
+		             Orthogonal views:
+		             <a href="?cocoon-view=content">Content</a>
+		             &#160;
+		             <a href="?cocoon-view=pretty-content">Pretty content</a>
+		             &#160;
+		             <a href="?cocoon-view=links">Links</a>
+	           </xsl:if>
+           </td>
+         </tr>
+       </table>
+
+       <xsl:apply-templates select="samples"/>
+       <xsl:apply-templates select="samples/additional-info"/>
+       
+       <p class="copyright">
+         Copyright &#169; @year@ <a href="http://www.apache.org/">The Apache Software Foundation</a>.
+         All rights reserved.
+       </p>
+      </body>
+    </html>
+  </xsl:template>
+
+
+  <xsl:template match="samples">
+    <xsl:variable name="gc" select="4"/><!-- group correction -->
+    <xsl:variable name="all-groups" select="$gc * count(group)"/>
+    <xsl:variable name="all-samples" select="count(group/sample)+count(group/note)+$all-groups"/>
+    <xsl:variable name="half-samples" select="round($all-samples div 2)"/>
+    <xsl:variable name="half-possibilities">
+      <xsl:choose>
+        <xsl:when test="count(group) = 1">1 </xsl:when><!-- single group sample.xml -->
+        <xsl:otherwise>
+          <xsl:for-each select="group">
+            <xsl:if test="position() &lt; last() and position() &gt;= 1">
+              <xsl:variable name="group-position" select="position()"/>
+              <xsl:variable name="prev-sample" select="count(../group[position() &lt;= $group-position - 1]/sample) + count(../group[position() &lt;= $group-position - 1]/note) + position() * $gc - $gc"/>
+              <xsl:variable name="curr-sample" select="count(../group[position() &lt;= $group-position]/sample) + count(../group[position() &lt;= $group-position]/note) + position() * $gc"/>
+              <xsl:variable name="next-sample" select="count(../group[position() &lt;= $group-position + 1]/sample) + count(../group[position() &lt;= $group-position + 1]/note) + position() * $gc + $gc"/>
+              <xsl:variable name="prev-deviation">
+                <xsl:choose>
+                  <xsl:when test="$prev-sample &gt; $half-samples">
+                    <xsl:value-of select="$prev-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $prev-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:variable name="curr-deviation">
+                <xsl:choose>
+                  <xsl:when test="$curr-sample &gt; $half-samples">
+                    <xsl:value-of select="$curr-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $curr-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:variable name="next-deviation">
+                <xsl:choose>
+                  <xsl:when test="$next-sample &gt; $half-samples">
+                    <xsl:value-of select="$next-sample - $half-samples"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <xsl:value-of select="$half-samples - $next-sample"/>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:variable>
+              <xsl:if test="$prev-deviation &gt;= $curr-deviation and $curr-deviation &lt;= $next-deviation">
+                <xsl:value-of select="$group-position"/><xsl:text> </xsl:text>
+              </xsl:if>
+            </xsl:if>
+          </xsl:for-each>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="half">
+      <xsl:value-of select="substring-before($half-possibilities, ' ')"/>
+    </xsl:variable>
+
+    <table width="100%" cellspacing="5">
+      <tr>
+        <td width="50%" valign="top">
+          <xsl:for-each select="group">
+            <xsl:variable name="group-position" select="position()"/>
+            <xsl:choose>
+              <xsl:when test="$group-position &lt;= $half">
+                <h4 class="samplesGroup"><xsl:value-of select="@name"/></h4>
+                <p class="samplesText"><xsl:apply-templates/></p>
+              </xsl:when>
+              <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </td>
+        <td valign="top">
+          <xsl:for-each select="group">  <!-- [position()<=$half] -->
+            <xsl:variable name="group-position" select="position()"/>
+            <xsl:choose>
+              <xsl:when test="$group-position &gt; $half">
+                <h4 class="samplesGroup"><xsl:value-of select="@name"/></h4>
+                <p class="samplesText"><xsl:apply-templates/></p>
+              </xsl:when>
+              <xsl:otherwise></xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </td>
+      </tr>
+    </table>
+  </xsl:template>
+
+
+  <xsl:template match="sample">
+    <xsl:variable name="link">
+      <xsl:choose>
+        <xsl:when test="starts-with(@href,'/')">
+          <xsl:value-of select="concat($contextPath, @href)"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="@href"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+
+    <xsl:choose>
+      <xsl:when test="string-length($link) &gt; 0">
+        <a href="{$link}"><xsl:value-of select="@name"/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="@name"/>
+      </xsl:otherwise>
+    </xsl:choose>
+    <xsl:text> - </xsl:text>
+    <xsl:copy-of select="*|text()"/>
+    <br/>
+  </xsl:template>
+
+
+  <xsl:template match="note">
+    <p class="samplesNote">
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+
+  <xsl:template match="@*|node()" priority="-2">
+    <xsl:copy>
+      <xsl:apply-templates select="@*|node()"/>
+    </xsl:copy>
+  </xsl:template>
+
+  <xsl:template match="text()" priority="-1">
+    <xsl:value-of select="."/>
+  </xsl:template>
+  
+  <xsl:template match="links/link">
+    <a href="{@href}">
+      <xsl:value-of select="."/>
+    </a>
+  </xsl:template>
+  
+  <xsl:template match="additional-info">
+    <h4><xsl:value-of select="@title"/></h4>
+    <xsl:copy-of select="node()"/>
+  </xsl:template>
+  
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/samples.xml b/non-releases/trunk_before_flattening/src/webapp/samples/samples.xml
new file mode 100644
index 0000000..c97ed41
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/samples.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Main samples page
+    |
+    | CVS $Id$
+    +-->
+
+<samples name="Cocoon Samples" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <group name="Block Samples">
+    <sample name="Blocks with samples" href="blocks/">
+      TODO: all samples are now in blocks, this page should include links to the
+      blocks that we want to show here: core-samples-main, forms. tour, others?
+    </sample>
+  </group>
+
+  <group name="Test pages">
+    <sample name="Automated tests" href="test/">
+      These pages are used by the HtmlUnit automated tests.
+    </sample>
+  </group>
+
+</samples>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/samples.xwelcome b/non-releases/trunk_before_flattening/src/webapp/samples/samples.xwelcome
new file mode 100644
index 0000000..911c5ae
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/samples.xwelcome
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xwelcome xpath="/welcome" unless="message[@id='samples']">
+
+  <message id="samples">
+   To know more about Cocoon capabilities, look at the <link href="samples/">samples</link>
+  </message>
+  
+</xwelcome>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/sitemap.xmap
new file mode 100644
index 0000000..d9fa1f5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/sitemap.xmap
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- 
+	samples sitemap, gets .xsamples files from blocks (all samples
+	are in blocks now) and displays links to available samples
+	
+	$Id$ 
+-->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:pipelines>
+    <map:pipeline>
+      <map:match pattern="">
+        <!-- all samples are in blocks now -->
+        <map:redirect-to uri="blocks/"/>
+      </map:match>
+      
+	  <!-- mount everything else -->
+      <map:match pattern="*/**">
+        <map:mount uri-prefix="{1}" src="{1}/"/>
+      </map:match>
+    </map:pipeline>
+
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/dir-links.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/test/dir-links.xsl
new file mode 100644
index 0000000..fa38e0e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/dir-links.xsl
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+    Add links to subdirectories to index.xml
+    CVS $Id: dir-links.xsl,v 1.2 2004/03/06 02:25:36 antonio Exp $
+ -->
+
+<xsl:stylesheet
+    version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:dir="http://apache.org/cocoon/directory/2.0"
+    xmlns="http://www.w3.org/1999/xhtml"
+>
+
+    <!-- by default copy everything -->
+    <xsl:template match="*">
+        <xsl:copy>
+            <xsl:copy-of select="@*"/>
+            <xsl:apply-templates/>
+        </xsl:copy>
+    </xsl:template>
+
+    <xsl:template match="combo">
+        <xsl:apply-templates select="page"/>
+    </xsl:template>
+
+    <!-- insert links to subdirectories -->
+    <xsl:template match="insert-directories">
+        <ul>
+            <xsl:apply-templates select="//dir:directory/dir:directory" mode="links"/>
+        </ul>
+    </xsl:template>
+
+    <!-- ignore directory listing -->
+    <xsl:template match="dir:directory"/>
+
+    <!-- generate link to subdirectory -->
+    <xsl:template match="dir:directory" mode="links">
+        <li>
+            <a href="{concat(@name,'/')}"><xsl:value-of select="@name"/></a>
+        </li>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dump.js b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dump.js
new file mode 100644
index 0000000..a94d268
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dump.js
@@ -0,0 +1,23 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+
+function dumpDomObject() {
+    var dom = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+    var root = dom.appendChild(dom.createElement("root"));
+    var child = root.appendChild(dom.createElement("child"));
+    child.appendChild(dom.createTextNode("childText"));
+    cocoon.sendPage("dom-dump-pipeline", { "domObject" : dom });
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dumper.jx.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dumper.jx.xml
new file mode 100644
index 0000000..c9c4d61
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/dom-dumper.jx.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<dom-dumper xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+    <dump-without-star>
+        #{domObject}
+    </dump-without-star>
+
+    <dump-with-star>
+        #{domObject/*}
+    </dump-with-star>
+</dom-dumper>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/explain-test.xml
new file mode 100644
index 0000000..e557b26
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/explain-test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: explain-test.xml 30932 2004-07-29 17:35:38Z vgritsenko $ -->
+
+<page>
+    <title>flowscript-dom-dump test pages</title>
+    <content>
+        <para>
+            This is used by the flowscript-dom-dump anteater test
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="dom-dump">dump a DOM object, no transform</link></li>
+                <li><link href="dom-dump-xslt">dump a DOM object, followed by XSLT transform</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/sitemap.xmap
new file mode 100644
index 0000000..4a04453
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/sitemap.xmap
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+    <map:flow language="javascript">
+        <map:script src="dom-dump.js"/>
+    </map:flow>
+
+    <map:pipelines>
+
+
+        <!-- used by the internalRequest anteater test -->
+        <map:pipeline>
+            <map:match pattern="dom-dump">
+                <map:call function="dumpDomObject"/>
+            </map:match>
+
+            <map:match pattern="dom-dump-pipeline">
+                <map:generate type="jx" src="dom-dumper.jx.xml"/>
+                <map:serialize type="xml"/>
+            </map:match>
+
+            <map:match pattern="dom-dump-xslt">
+                <map:generate src="cocoon:/dom-dump"/>
+                <map:transform src="test-transform.xsl"/>
+                <map:serialize type="xml"/>
+            </map:match>
+
+        </map:pipeline>
+
+    </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/test-transform.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/test-transform.xsl
new file mode 100644
index 0000000..536f828
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/flowscript-dom-dump/test-transform.xsl
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+    Identity transform used to test bugzilla 29381
+    CVS $Id: dir-links.xsl 30932 2004-07-29 17:35:38Z vgritsenko $
+ -->
+
+<xsl:stylesheet
+    version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+>
+    <!-- by default copy everything -->
+    <xsl:template match="*">
+        <xsl:copy>
+            <xsl:copy-of select="@*"/>
+            <xsl:apply-templates/>
+        </xsl:copy>
+    </xsl:template>
+
+    <!-- let them know we were here -->
+    <xsl:template match="root">
+        <root test-transform="true">
+            <xsl:apply-templates/>
+        </root>
+    </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/index.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/index.xml
new file mode 100644
index 0000000..5d828cc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/index.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<page>
+    <title>Test pages</title>
+    <content>
+        <para>
+            Stuff found in and under this directory is meant for automated
+            anteater tests.
+        </para>
+        <para>
+            To run tests use the <em>anteater-tests</em> build target.
+        </para>
+        <para>
+            To create a new test set, create a new subdirectory here and
+            add an <em>explain-test.xml</em> document into it.
+        </para>
+        <para>
+            <b>Available tests</b>:
+            <insert-directories/>
+        </para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/a.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/a.xml
new file mode 100644
index 0000000..1cd4596
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/a.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<test file="a" xmlns:cinclude="http://apache.org/cocoon/include/1.0">
+
+	<note>Now i'm going to include something from a sitemap mounted below here</note>
+
+	<cinclude:include src="cocoon:/simpletest-mounted/includer"/>
+
+</test>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/explain-test.xml
new file mode 100644
index 0000000..9ba1946
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/explain-test.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: explain-test.xml,v 1.2 2004/03/06 02:25:32 antonio Exp $ -->
+
+<page>
+    <title>internal-request test pages</title>
+    <content>
+        <para>
+            This is used by the internalRequest anteater test
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="simpletest">simpletest</link></li>
+                <li><link href="simpletest-mounted/includer">includer</link></li>
+                <li><link href="simpletest-content/a.xml">simpletest-content/a.xml</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/c.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/c.xml
new file mode 100644
index 0000000..c13f136
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/c.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<test file="c">
+	<note>This is c.xml served from the sitemap mounted below</note>
+</test>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/sitemap.xmap
new file mode 100644
index 0000000..f0f516a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/mounted/sitemap.xmap
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>
+    <map:pipeline>
+      <map:match pattern="includer">
+        <map:generate src="c.xml"/>
+        <map:serialize type="xml"/>
+      </map:match>
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/sitemap.xmap
new file mode 100644
index 0000000..eddf5c1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/internal-request/sitemap.xmap
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+    <map:pipelines>
+
+        <!-- used by the internalRequest anteater test -->
+        <map:pipeline>
+            <map:match pattern="simpletest-content/**">
+                <map:generate src="{1}"/>
+                <map:serialize type="xml"/>
+            </map:match>
+            <map:match pattern="simpletest-mounted/**">
+                <map:mount src="mounted/" uri-prefix="simpletest-mounted"/>
+            </map:match>
+            <map:match pattern="simpletest">
+                <map:generate src="cocoon:/simpletest-content/a.xml"/>
+                <map:transform type="cinclude"/>
+                <map:serialize type="xml"/>
+            </map:match>
+        </map:pipeline>
+
+    </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/another-sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/another-sitemap.xmap
new file mode 100644
index 0000000..72c0ed6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/another-sitemap.xmap
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>
+		<map:pipeline>
+			<map:match pattern="another-welcome">
+				<map:generate src="cocoon:/non-existing-url"/>
+				<map:serialize/>
+			</map:match>
+			<map:handle-errors>
+			  <map:select type="exception">
+			    <map:when test="not-found">
+			      <map:generate src="welcome.xml"/>
+			      <map:serialize type="html"/>
+			    </map:when>
+			  </map:select>
+			</map:handle-errors>
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/hello.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/hello.xml
new file mode 100755
index 0000000..b5bc08a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/hello.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+<h1>Hello!</h1>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/sitemap.xmap
new file mode 100755
index 0000000..3cb797a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/elsewhere/sitemap.xmap
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>
+    <map:pipeline>
+      <!-- this sitemap is mounted with pass-through, but contains
+         no matcher so that we go back to the parent sitemap -->
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/explain-test.xml
new file mode 100644
index 0000000..4cef204
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/explain-test.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<page>
+    <title>Sitemap pass-through test pages</title>
+    <content>
+        <para>
+            Shows that mounted pass-through breaks when a "cocoon:" is used
+            after going back to the parent sitemap (<link
+                href="http://issues.apache.org/bugzilla/show_bug.cgi?id=33178">bug
+                #33178</link>).
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="welcome">Direct pipeline</link></li>
+                <li><link href="welcome1">One "cocoon:" URL</link></li>
+                <li><link href="welcome2">Two chained "cocoon:" URLs</link></li>
+                <li><link href="welcome3">Three chained "cocoon:" URLs</link></li>
+            	   <li><link href="aggregate">Aggregation of the above</link></li>
+            </ul>
+        </para>
+        <para>
+           A "cocoon:" called within a pass-trough mount leading to no match reported an NPE
+           rather than a ResourceNotFound. With the bugfix, the RNFE is catched, and the "welcome"
+	   page is displayed.
+        </para>
+        <para><link href="another-welcome">Test link</link></para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sitemap.xmap
new file mode 100755
index 0000000..ed5e8c6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sitemap.xmap
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>    	
+    <map:pipeline>
+      <map:mount uri-prefix=""
+                 src="elsewhere/sitemap.xmap" pass-through="true"/>
+    
+      <map:match pattern="sub/**">
+        <map:mount src="sub/" uri-prefix="sub"/>
+      </map:match>
+
+      <map:match pattern="welcome">
+        <map:generate src="welcome.xml"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="welcome1">
+        <map:generate src="cocoon:/welcome"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="welcome2">
+        <map:generate src="cocoon:/welcome1"/>
+        <map:serialize/>
+      </map:match>
+
+      <map:match pattern="welcome3">
+        <map:generate src="cocoon:/welcome2"/>
+        <map:serialize/>
+      </map:match>
+    	
+    	  <map:match pattern="hellosub">
+    	  	<!-- This pattern deliberately produces and error, as it is meant to trap
+    	  	     wrong active processor in the handling of sub/sub1 -->
+    	  	<map:serialize/>
+    	  </map:match>
+    	
+    	  <map:match pattern="subsub1">
+    	  	<map:generate src="cocoon:/sub/sub1"/>
+    	  	<map:serialize/>
+    	  </map:match>
+    	
+    	  <map:match pattern="aggregate">
+    	    <map:aggregate element="root">
+    	      <map:part src="cocoon:/welcome3"/>
+    	      <map:part src="cocoon:/welcome3"/>
+    	      <map:part src="cocoon:/subsub1"/>
+    	    </map:aggregate>
+    	  	<map:serialize/>
+    	  </map:match>
+    	  
+    	  <!-- a test that produces an NPE in SitemapSource when there's a pass-through mount in the same directory -->
+    	  
+    	  <map:mount uri-prefix=""
+    	             src="another-sitemap.xmap" pass-through="true"/>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/hellosub.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/hellosub.xml
new file mode 100755
index 0000000..6a0181b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/hellosub.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+<h1>Hello Sub!</h1>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/sitemap.xmap
new file mode 100755
index 0000000..8e97c36
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/sub/sitemap.xmap
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+  <map:pipelines>
+    <map:pipeline>
+    	  <map:match pattern="hellosub">
+    	  	<map:generate src="hellosub.xml"/>
+    	  	<map:serialize/>
+    	  </map:match>
+    	
+    	  <map:match pattern="sub1">
+    	  	<map:generate src="cocoon:/hellosub"/>
+    	  	<map:serialize/>
+    	  </map:match>
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/welcome.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/welcome.xml
new file mode 100755
index 0000000..b52345b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/pass-through/welcome.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2005 The Apache Software Foundation or its licensors,
+  as applicable.
+
+  Licensed 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.
+-->
+<h1>Welcome!</h1>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/explain-test.xml
new file mode 100644
index 0000000..3ed395c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/explain-test.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<page>
+    <title>reader-mime-type test</title>
+    <content>
+        <para>Test harness for
+            <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=25121">
+                bugzilla 25212
+            </a>, test mime-types on map:reader.
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="test10.html">test10.html</link></li>
+                <li><link href="test20.html">test20.html</link></li>
+                <li><link href="test30">test30</link></li>
+                <li><link href="test40.html">test40.html</link></li>
+                <li><link href="test50.html">test50.html</link></li>
+                <li><link href="test60.html">test60.html</link></li>
+                <li><link href="test70.html">test70.html</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/sitemap.xmap
new file mode 100644
index 0000000..e786373
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/sitemap.xmap
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:pipelines>
+    <map:pipeline type="caching">
+      <map:match pattern="test10.html">
+        <map:read src="test.html"/>
+      </map:match>
+      <map:match pattern="test20.html">
+        <map:read src="cocoon:/test10.html"/>
+      </map:match>
+      <map:match pattern="test30">
+        <map:read src="test.html"/>
+      </map:match>
+      <map:match pattern="test40.html">
+        <map:read src="cocoon:/test10.html"/>
+      </map:match>
+      <map:match pattern="test50.html">
+        <map:read src="cocoon:/test30"/>
+      </map:match>
+      <map:match pattern="test60.html">
+        <map:read src="cocoon:/test10.html" mime-type="text/html"/>
+      </map:match>
+      <map:match pattern="test70.html">
+        <map:read src="cocoon:/test30" mime-type="text/html"/>
+      </map:match>
+    </map:pipeline>
+
+    <map:pipeline type="noncaching">
+      <map:match pattern="test15.html">
+        <map:read src="test.html"/>
+      </map:match>
+      <map:match pattern="test25.html">
+        <map:read src="cocoon:/test15.html"/>
+      </map:match>
+      <map:match pattern="test35">
+        <map:read src="test.html"/>
+      </map:match>
+      <map:match pattern="test45.html">
+        <map:read src="cocoon:/test15.html"/>
+      </map:match>
+      <map:match pattern="test55.html">
+        <map:read src="cocoon:/test35"/>
+      </map:match>                   	
+      <map:match pattern="test65.html">
+        <map:read src="cocoon:/test15.html" mime-type="text/html"/>
+      </map:match>
+      <map:match pattern="test75.html">
+        <map:read src="cocoon:/test35" mime-type="text/html"/>
+      </map:match>
+    </map:pipeline>
+  </map:pipelines>
+
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/test.html b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/test.html
new file mode 100644
index 0000000..8e0d71e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/reader-mime-type/test.html
@@ -0,0 +1,20 @@
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<html>
+  <body>
+    This should have the text/html mime type.
+  </body>
+</html>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/explain-test.xml
new file mode 100644
index 0000000..45185f7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/explain-test.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<page>
+    <title>sendpage-redirect test</title>
+    <content>
+        <para>
+          Test for different kinds of redirect scenarios.
+          
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="redirect-to-from-sitemap">sitemap redirect-to statement</link></li>
+                <li><link href="redirect-to-internal-from-sitemap">sitemap redirect-to statement to the cocoon:// uri</link></li>
+                <li><link href="redirect-to-from-flow">cocoon.redirectTo FOM call</link></li>
+                <li><link href="send-status">cocoon.sendStatus FOM call</link></li>
+                <li><link href="send-page">cocoon.sendPage FOM call</link></li>
+                <li><link href="donothing-from-flow">call an empty flow function</link></li>
+                <li><link href="donothing-from-sitemap">invoke an empty match statement</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/flow.js b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/flow.js
new file mode 100644
index 0000000..b1a6e76
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/flow.js
@@ -0,0 +1,30 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+
+function redirectTo() {
+  cocoon.redirectTo("explain-test.html");
+}
+
+function sendStatus() {
+  cocoon.sendStatus(204);
+}
+
+function sendPage() {
+  cocoon.sendPage("read", null);
+}
+
+function doNothing() {
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/sitemap.xmap
new file mode 100644
index 0000000..34bf9f6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/redirect/sitemap.xmap
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:flow language="javascript">
+    <map:script src="flow.js"/>
+  </map:flow>
+
+  <map:pipelines>
+    <map:pipeline internal-only="true">
+      <map:match pattern="read">
+        <map:read src="sitemap.xmap"/>
+      </map:match>
+    </map:pipeline>
+    
+    <map:pipeline>
+      <map:match pattern="redirect-to-from-sitemap">
+        <map:redirect-to uri="explain-test.html"/>
+      </map:match>
+
+      <map:match pattern="redirect-to-internal-from-sitemap">
+        <map:redirect-to uri="cocoon://samples/test/redirect/explain-test.html"/>
+      </map:match>
+
+      <map:match pattern="redirect-to-from-flow">
+        <map:call function="redirectTo"/>
+      </map:match>
+
+      <map:match pattern="send-status">
+        <map:call function="sendStatus"/>
+      </map:match>
+      
+      <map:match pattern="send-page">
+        <map:call function="sendPage"/>
+      </map:match>
+      
+      <map:match pattern="donothing-from-flow">
+        <map:call function="doNothing"/>
+      </map:match>
+      
+      <map:match pattern="donothing-from-sitemap"/>
+      
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/explain-test.xml
new file mode 100644
index 0000000..c7783e7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/explain-test.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: explain-test.xml,v 1.3 2004/06/22 02:41:14 crossley Exp $ -->
+
+<page>
+    <title>sendpage-redirect test</title>
+    <content>
+        <para>Test harness for
+            <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=26571">
+                bugzilla 26571
+            </a>, redirecting from within a flow-called pipeline fails.
+        </para>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="test-good">test-good</link></li>
+                <li><link href="test-bad">test-bad</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/flow.js b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/flow.js
new file mode 100644
index 0000000..c43c061
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/flow.js
@@ -0,0 +1,19 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+
+function sendPageWithRedirect() {
+  cocoon.sendPage("redirect",null)
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/sitemap.xmap
new file mode 100644
index 0000000..dc4ea56
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage-redirect/sitemap.xmap
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:flow language="javascript">
+     <map:script src="flow.js"/>
+  </map:flow>
+
+  <map:pipelines>
+    <map:pipeline>
+
+      <map:match pattern="test-good">
+        <map:redirect-to uri="sitemap"/>
+      </map:match>
+
+      <map:match pattern="test-bad">
+        <map:call function="sendPageWithRedirect"/>
+      </map:match>
+
+      <map:match pattern="redirect">
+        <map:redirect-to uri="sitemap"/>
+      </map:match>
+
+      <map:match pattern="sitemap">
+        <map:read src="sitemap.xmap"/>
+      </map:match>
+
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/explain-test.xml
new file mode 100644
index 0000000..821042b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/explain-test.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: explain-test.xml,v 1.1 2004/03/17 19:53:29 unico Exp $ -->
+
+<page>
+    <title>sendpage test</title>
+    <content>
+        <para>
+            Test links:
+            <ul>
+                <li><link href="testInternal">fails/should pass</link></li>
+                <li><link href="testExternal">passes/should pass</link></li>
+            </ul>
+        </para>
+    </content>
+</page>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/flow.js b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/flow.js
new file mode 100644
index 0000000..b33dda4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/flow.js
@@ -0,0 +1,20 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* Licensed 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.
+*/
+
+function testSendPage() {
+  var page = cocoon.parameters["page"];
+  cocoon.sendPage(page,null);
+}
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/sitemap.xmap
new file mode 100644
index 0000000..d25231f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sendpage/sitemap.xmap
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+  <map:flow language="javascript">
+    <map:script src="flow.js"/>
+  </map:flow>
+
+  <map:pipelines>
+    
+    <map:pipeline internal-only="true">
+      <map:match pattern="internal">
+        <map:read src="sitemap.xmap"/>
+      </map:match>
+    </map:pipeline>
+    
+    <map:pipeline>
+    
+      <map:match pattern="external">
+        <map:read src="sitemap.xmap"/>
+      </map:match>
+      
+      <map:match pattern="testInternal">
+        <map:call function="testSendPage">
+          <map:parameter name="page" value="internal"/>
+        </map:call>
+      </map:match>
+      
+      <map:match pattern="testExternal">
+        <map:call function="testSendPage">
+          <map:parameter name="page" value="external"/>
+        </map:call>
+      </map:match>
+      
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/explain-test.xml b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/explain-test.xml
new file mode 100644
index 0000000..2985c02
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/explain-test.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: explain-test.xml 30932 2004-07-29 17:35:38Z vgritsenko $ -->
+
+<page>
+    <title>Sitemap annotations test</title>
+    <content>
+        <para>
+            Test sitemap annotations and their extraction
+            <ul>
+                <li>
+                  The <link href="annotations">annotations</link>
+                  page contains a copy of the annotations found in sitemap.xmap
+                  (with namespaces removed as I haven't been able to get the
+                  anteater-based tests to work with namespaces)
+                </li>
+            </ul>
+        </para>
+    </content>
+</page>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/get-annotations.xsl b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/get-annotations.xsl
new file mode 100644
index 0000000..8a4e408
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/get-annotations.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--
+  Extract annotations from sitemap
+  $Id: dir-links.xsl 36225 2004-08-11 14:36:46Z vgritsenko $
+ -->
+
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fyi="http://apache.org/cocoon/sitemap/annotations/1.0"
+  exclude-element-prefixes="fyi"
+  >
+
+  <xsl:template match="/">
+    <sitemap-annotations>
+      <xsl:apply-templates/>
+    </sitemap-annotations>
+  </xsl:template>
+
+  <!-- copy fyi elements, without namespace -->
+  <xsl:template match="fyi:*">
+    <xsl:element name="{local-name()}">
+      <xsl:copy-of select="@*"/>
+      <xsl:apply-templates/>
+    </xsl:element>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/sitemap.xmap
new file mode 100644
index 0000000..795b9aa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap-annotations/sitemap.xmap
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap
+  xmlns:map="http://apache.org/cocoon/sitemap/1.0"
+  xmlns:fyi="http://apache.org/cocoon/sitemap/annotations/1.0"
+  >
+  <fyi:info>
+    <fyi:author>The Cocoon team</fyi:author>
+    <fyi:text>
+      This sitemap contains notes which are ignored
+      by the tree processor, but could be used to create
+      self-documenting samples, for example.
+      See bugzilla issue 25352.
+    </fyi:text>
+  </fyi:info>
+
+  <map:pipelines>
+    
+    <map:pipeline>
+
+      <fyi:note>filter out sitemap to keep annotations only</fyi:note>
+      <map:match pattern="annotations">
+        <map:generate src="sitemap.xmap"/>
+        <map:transform src="get-annotations.xsl"/>
+        <map:serialize type="xml"/>
+      </map:match>
+      
+    </map:pipeline>
+  </map:pipelines>
+</map:sitemap>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap.xmap
new file mode 100644
index 0000000..17af79c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/samples/test/sitemap.xmap
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+    <map:pipelines>
+
+        <!-- used by the internalRequest anteater test -->
+        <map:pipeline>
+            <map:match pattern="simpletest-content/**">
+                <map:generate src="{1}"/>
+                <map:serialize type="xml"/>
+            </map:match>
+            <map:match pattern="simpletest-mounted/**">
+                <map:mount src="simpletest-mounted/" uri-prefix="simpletest-mounted"/>
+            </map:match>
+            <map:match pattern="simpletest">
+                <map:generate src="cocoon:/simpletest-content/a.xml"/>
+                <map:transform type="cinclude"/>
+                <map:serialize type="xml"/>
+            </map:match>
+        </map:pipeline>
+
+        <!-- explain what this is -->
+        <map:pipeline>
+            <map:match pattern="">
+                <map:redirect-to uri="index.html"/>
+            </map:match>
+
+            <map:match pattern="directory.xml">
+                <map:generate type="directory" src=".">
+                    <depth>1</depth>
+                </map:generate>
+                <map:serialize type="xml"/>
+            </map:match>
+
+            <map:match pattern="index.html">
+                <map:aggregate element="combo">
+                    <map:part src="index.xml"/>
+                    <map:part src="cocoon:/directory.xml"/>
+                </map:aggregate>
+                <map:transform src="dir-links.xsl"/>
+                <map:transform src="context://samples/common/style/xsl/html/simple-page2html.xsl">
+                    <map:parameter name="servletPath" value="{request:servletPath}"/>
+                    <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
+                    <map:parameter name="contextPath" value="{request:contextPath}"/>
+                    <map:parameter name="file" value="{1}/{2}.xml"/>
+                    <map:parameter name="remove" value="{0}"/>
+                </map:transform>
+                <map:serialize type="html"/>
+            </map:match>
+
+            <!-- process the explain-test page for subdirectories -->
+            <map:match pattern="**/">
+                <map:redirect-to uri="explain-test.html"/>
+            </map:match>
+            <map:match pattern="**/explain-test.html">
+                <map:generate src="{1}/explain-test.xml"/>
+                <map:transform src="context://samples/common/style/xsl/html/simple-page2html.xsl">
+                    <map:parameter name="servletPath" value="{request:servletPath}"/>
+                    <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
+                    <map:parameter name="contextPath" value="{request:contextPath}"/>
+                    <map:parameter name="file" value="{1}/{2}.xml"/>
+                    <map:parameter name="remove" value="{0}"/>
+                </map:transform>
+                <map:serialize type="html"/>
+            </map:match>
+
+            <!-- mount subdirectories to contain tests -->
+            <map:match pattern="*/**">
+              <map:mount src="{1}/" uri-prefix="{1}"/>
+            </map:match>
+
+        </map:pipeline>
+
+    </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/sitemap.xmap
new file mode 100644
index 0000000..b452044
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/sitemap.xmap
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | This is the 'heart' of Cocoon. The sitemap maps URI space to
+    | resources. It consists basicaly of two parts: components and
+    | pipelines. Pipelines are made out of components. There is such a
+    | vast number of components available that it would be impossible to
+    | describe them here, please refer to the accompanying
+    | documentation. For specific components, have a look also at the
+    | javadocs for them. Most pipelines are present to demonstrate some
+    | feature or technique, often they are explained in more detail in
+    | the accompanying documentation. The sitemaps which come with each
+    | sample and each block will help to explain.
+    |
+    | CVS $Id$
+    +-->
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+<!-- =========================== Components ================================ -->
+
+ <map:components>
+
+   <!-- include some additional components -->
+   <map:include dir="context://WEB-INF/sitemap-additions" pattern="*.xconf"/>
+
+ </map:components>
+
+
+<!-- =========================== Views =================================== -->
+
+  <!--+
+      | Views provide different, well, views to resources. Views are
+      | orthogonal to pipelines. Please refer to the docs.
+      |
+      | It would be wise to disable any unneeded views in a
+      | production environment in order to avoid exposing data
+      | that you may not necessarily wish to.
+      +-->
+  <map:views>
+    <map:view from-label="content" name="content">
+      <map:serialize type="xml"/>
+    </map:view>
+
+    <map:view from-label="content" name="pretty-content">
+      <map:transform src="stylesheets/system/xml2html.xslt"/>
+      <map:serialize type="html"/>
+    </map:view>
+
+    <map:view from-position="last" name="links">
+      <map:serialize type="links"/>
+    </map:view>
+  </map:views>
+
+
+<!-- =========================== Resources ================================= -->
+
+  <!--+
+      | Resources are pipeline fragments that may be used from different
+      | pipeline fragments. For our needs, they behave exactly like
+      | pipelines, only that they are not accessible from outside.
+      | Hence I will explain what's inside below for pipelines.
+      +-->
+ <map:resources>
+ </map:resources>
+
+
+<!-- ========================== Action sets ================================ -->
+
+ <!--+
+     | Action sets group actions together. If some actions are often used
+     | together in pipeline fragments, it's easier to group them and refer
+     | to the group. For more info, please see the docs.
+     +-->
+  <map:action-sets>
+  </map:action-sets>
+
+
+<!-- =========================== Pipelines ================================= -->
+
+ <!--+
+     | Pipelines. The beef. Pipelines specify how the processing of your
+     | content is done. Usually, a pipeline consists of several fragments
+     | that specify the generation, transformation, and serialization of
+     | SAX events.
+     |
+     | Processing is done in two steps:
+     |
+     | 1) The top level elements are executed in order of appearance until
+     |    one signals success. These top level elements are usually
+     |    matchers.
+     |
+     |    Other components are called depth-first to determine what
+     |    fragments make up the processing pipeline. When a component
+     |    fails, no nested components are called but the next component on
+     |    the same level.
+     |
+     | 2) Once it is determined which generator, which transformers and
+     |    wich serializer is used, these components are executed. During
+     |    this, the pipeline may not be changed.
+     |
+     | You may have as many pipelines in your sitemap as you like.
+     +-->
+ <map:pipelines>
+
+  <map:component-configurations>
+    <global-variables>
+       <!--+
+           | Define global parameters here:
+           |   <skin>my_skin</skin>
+           |   ...
+           | You can access them by {global:*name*}, e.g. {global:skin}.
+           | These values are inherited into sub-sitemaps and can
+           | be extended there.
+           +-->
+    </global-variables>
+  </map:component-configurations>
+
+  <!-- main pipeline -->
+  <map:pipeline>
+
+    <!-- welcome page -->
+    <map:match pattern="">
+
+      <!--+
+          | Start generating SAX events inside the pipeline. In this case,
+          | since no "type" attribute is specified, the default generator
+          | is used and this is a regular XML parser that reads the
+          | given file from the URL included in the "src" attribute and
+          | sends the events produced by the parser down the pipeline to
+          | be processed by the next stage.
+          +-->
+      <map:generate src="welcome.xml"/>
+
+      <!--+
+          | This transformer gets the input SAX events and transforms them
+          | using the default transformer (the XSLT transformer) thus
+          | applying the XSLT stylesheet indicated in the "src" attribute
+          | and sending the output down the pipeline to be processed by the
+          | next stage.
+          +-->
+      <map:transform src="welcome.xslt">
+        <map:parameter name="contextPath" value="{request:contextPath}"/>
+      </map:transform>
+
+      <!--+
+          | The serializer concludes the SAX events journey into the pipeline
+          | since it serializes the events it receives into a representation
+          | depending on the serializer type. Here we choose the "XHMTL"
+          | serializer, which will produce an XHTML representation of the
+          | SAX stream.
+          +-->
+      <map:serialize type="xhtml"/>
+    </map:match>
+
+    <!-- FIXME Remove later -->
+    <map:match pattern="v">
+      <map:generate type="virtual"/>
+      <map:serialize type="xhtml"/>
+    </map:match>
+
+    <!--+
+        | The default matching is also capable of matching more than a
+        | single request by the use of 'wildcards'. There are two kinds of
+        | wildcards:
+        |
+        |  "*" means "anything that does not contain a path separator"
+        |  "**" means "anything including path separators"
+        |
+        | The tokens matched by the wildcards are passed over as sitemap
+        | variables. Those variables can be accessed using the '{...}' syntax
+        | inside the attributes. The URI-matching tokens are associated to
+        | numbered variables, as shown in the following match that processes all
+        | the GIF images that are located in the 'images/' URL space but
+        | not in any deeper levels. Note how requesting "images/logo.gif"
+        | triggers the matcher to create the token {1} = 'logo' which is later
+        | expanded into the src="" attribute of the reader, indicating
+        | what file it has to read.
+        +-->
+
+    <!-- images -->
+    <map:match pattern="images/*.gif">
+      <map:read src="resources/images/{1}.gif" mime-type="image/gif"/>
+    </map:match>
+
+    <!-- CSS stylesheets -->
+    <map:match pattern="styles/*.css">
+      <map:read src="resources/styles/{1}.css" mime-type="text/css"/>
+    </map:match>
+
+    <!-- JavaScript scripts -->
+    <map:match pattern="scripts/*.js">
+      <map:read src="resources/scripts/{1}.js" mime-type="text/javascript"/>
+    </map:match>
+
+    <!-- favicon -->
+    <map:match pattern="**favicon.ico">
+      <map:read mime-type="image/x-icon" src="resources/icons/cocoon.ico"/>
+    </map:match>
+
+    <!--+
+        | mount user directories
+        |
+        | The location of user directories depends heavily on the operating
+        | system used. Uncomment the one below that suits your environment.
+        |
+        | NOTE: you might want to comment out the entire section for a
+        |       production environment.
+        +-->
+    <map:match pattern="~*/**">
+      <!-- unix -->
+      <map:mount src="/home/{1}/public_html/" uri-prefix="~{1}"/>
+      <!-- macosx -->
+      <!--map:mount src="/Users/{1}/Sites/" uri-prefix="~{1}"/-->
+      <!-- win32 -->
+      <!--map:mount src="/Documents and Settings/{1}/My Documents/My Website/" uri-prefix="~{1}"/-->
+    </map:match>
+
+    <!--+
+        | Redirect to the user directory if the ending slash is missing
+        | Cocoon doesn't do automatic translation of URLs because we consider it
+        | a bad practice. http://blah/something/ and http://blah/something
+        | effectively locate different web resources and the act of mapping
+        | them to the same system resources is your concern, not Cocoon's.
+        | Note that some stupid browsers (IE, for example) believe the opposite
+        | and will drop the ending slash when you bookmark a web resource
+        | so be aware of this issue and plan your URL-space carefully.
+        +-->
+    <map:match pattern="~*">
+      <map:redirect-to uri="{0}/"/>
+    </map:match>
+
+    <!--+
+        | Map the API documentation.
+        +-->
+    <map:match pattern="api/**">
+      <map:read src="api/{1}"/>
+    </map:match>
+
+    <!--+
+        | Find a match in the "mount-table.xml" file, if present. It allows to mount other
+        | directories without touching this main sitemap (and thus loosing changes on rebuild).
+        |
+        | Note that other mount-tables can be added here using the xpatch ant task
+        | (see src/confpatch/mount-table.xmap)
+        +-->
+    <!--
+      Disabled while working on OSGI stuff, this wouldn't work anyway
+      (due to the ../) and it causes an NPE in the MountTableMatcher
+    <map:match type="mount-table" pattern="../../mount-table.xml">
+      <map:mount src="{src}" uri-prefix="{uri-prefix}"/>
+    </map:match>
+    -->
+
+    <!--+
+        | Mount everything else by calling the sitemap.xmap file located
+        | in the requested folder.
+        +-->
+    <map:match pattern="*/**">
+      <map:mount src="{1}/" uri-prefix="{1}"/>
+    </map:match>
+
+    <!--+
+        | At the very end of a pipeline, you can catch the errors triggered
+        | by the pipeline execution. The error handler is an internal sitemap
+        | component that, when triggered by an error, takes over the normal
+        | pipeline execution.
+        | You can here use the "notifying" generator that produces an XML
+        | representation and further manipulate this document for presentation
+        | on screen.
+        | You can also use any other generator if you don't want the
+        | error to be displayed on screen. The "exception" selector can help
+        | you to define different screens for different error types.
+        +-->
+    <map:handle-errors>
+      <map:select type="exception">
+
+        <map:when test="not-found">
+          <map:generate type="exception"/>
+          <map:transform src="stylesheets/system/exception2html.xslt">
+            <map:parameter name="contextPath" value="{request:contextPath}"/>
+            <map:parameter name="realPath" value="{realpath:}"/>
+            <map:parameter name="pageTitle" value="Resource not found"/>
+          </map:transform>
+          <map:serialize status-code="404"/>
+        </map:when>
+
+        <map:when test="invalid-continuation">
+          <map:generate type="exception"/>
+          <map:transform src="stylesheets/system/exception2html.xslt">
+            <map:parameter name="contextPath" value="{request:contextPath}"/>
+            <map:parameter name="realPath" value="{realpath:}"/>
+            <map:parameter name="pageTitle" value="Invalid Continuation"/>
+          </map:transform>
+          <map:serialize status-code="404"/>
+        </map:when>
+
+        <map:otherwise>
+          <map:generate type="exception"/>
+          <map:transform src="stylesheets/system/exception2html.xslt">
+            <map:parameter name="contextPath" value="{request:contextPath}"/>
+            <map:parameter name="realPath" value="{realpath:}"/>
+          </map:transform>
+          <map:serialize status-code="500"/>
+        </map:otherwise>
+      </map:select>
+
+    </map:handle-errors>
+  </map:pipeline>
+ </map:pipelines>
+
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/directory2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/directory2html.xslt
new file mode 100644
index 0000000..de39575
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/directory2html.xslt
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: directory2html.xslt,v 1.4 2004/03/06 02:25:41 antonio Exp $ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:dir="http://apache.org/cocoon/directory/2.0">
+
+  <xsl:template match="/">
+    <html>
+      <head>
+        <title><xsl:value-of select="dir:directory/@name"/></title>
+        <style>
+          <xsl:comment>
+            body { background-color: #ffffff }
+          </xsl:comment>
+        </style>
+      </head>
+      <body>
+        <h1>Directory Listing of <xsl:value-of select="dir:directory/@name"/></h1>
+        <table border="0">
+          <tr>
+            <td><a href="../"><i>parent directory</i></a></td>
+          </tr>
+          <tr>
+            <td>&#160;</td>
+          </tr>
+          <xsl:apply-templates/>
+        </table>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="dir:directory/dir:directory">
+    <tr>
+      <td><a href="{@name}/"><i><xsl:value-of select="@name"/></i></a></td>
+      <td><xsl:value-of select="@date"/></td>
+    </tr>
+  </xsl:template>
+
+  <xsl:template match="dir:file">
+    <tr>
+      <td><a href="{@name}"><xsl:value-of select="@name"/></a></td>
+      <td><xsl:value-of select="@date"/></td>
+    </tr>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/error2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/error2html.xslt
new file mode 100644
index 0000000..b8d5181
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/error2html.xslt
@@ -0,0 +1,137 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: error2html.xslt,v 1.18 2004/06/22 02:41:14 crossley Exp $ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:error="http://apache.org/cocoon/error/2.1">
+
+  <xsl:param name="contextPath"/>
+
+  <!-- let sitemap override default page title -->
+  <xsl:param name="pageTitle" select="//error:notify/error:title"/>
+
+  <xsl:template match="error:notify">
+    <html>
+      <head>
+        <title>
+          <xsl:value-of select="$pageTitle"/>
+        </title>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <style>
+          h1 { color: #336699; text-align: left; margin: 0px 0px 30px 0px; padding: 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+          p.message { padding: 10px 30px 10px 30px; font-weight: bold; font-size: 130%; border-width: 1px; border-style: dashed; border-color: #336699; }
+          p.description { padding: 10px 30px 20px 30px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+          p.topped { padding-top: 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }
+          pre { font-size: 120%; }
+        </style>
+        <script src="{$contextPath}/scripts/main.js" type="text/javascript"/>
+      </head>
+      <body>
+        <xsl:apply-templates select="." mode="onload"/>
+        <h1><xsl:value-of select="$pageTitle"/></h1>
+
+        <p class="message">
+          <xsl:value-of select="error:message"/>
+        </p>
+
+        <p class="description">
+          <xsl:value-of select="error:description"/>
+        </p>
+
+        <xsl:apply-templates select="error:extra"/>
+
+        <p class="topped">
+          If you need help and this information is not enough, you
+          are invited to read the
+          <a href="http://cocoon.apache.org/2.1/faq/">Cocoon FAQ</a>.<br/>
+          If you still don't find the answers you need,
+          can send a mail to the
+          <a href="http://cocoon.apache.org/community/mail-lists.html">
+          Cocoon mailing lists</a>,
+          remembering to:
+        </p>
+
+        <ul>
+          <li>specify the version of Cocoon you're using, or we'll assume that you
+              are talking about the latest released version;</li>
+          <li>specify the platform-operating system-version-servlet container version;</li>
+          <li>send any pertinent error message;</li>
+          <li>send pertinent log snippets;</li>
+          <li>send pertinent sitemap snippets;</li>
+          <li>send pertinent parts of the page that give you problems.</li>
+        </ul>
+
+        <p>
+          For more detailed technical information, take a look at the log
+          files in the log directory of Cocoon, which is placed by default in
+          the <code>WEB-INF/logs/</code> folder of your cocoon webapp context.<br/>
+          If the logs don't give you enough information, you might want to increase the
+          log level by changing the Logging configuration which is by default the
+          <code>WEB-INF/logkit.xconf</code> file.
+        </p>
+
+        <p>
+          If you think you found a bug, please report it to
+          <a href="http://issues.apache.org/jira/browse/COCOON">Apache Cocoon issue tracker</a>;
+          a message will automatically be sent to the developer mailing list and you'll
+          be kept in contact automatically with the further progress on that bug.
+        </p>
+
+        <p>
+          Thanks, and sorry for the trouble if this is our fault.
+        </p>
+
+        <p class="topped">
+          The <a href="http://cocoon.apache.org/">Apache Cocoon</a> Project
+        </p>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="error:notify" mode="onload">
+    <xsl:attribute name="onload">
+      <xsl:for-each select="error:extra[contains(@error:description,'stacktrace')]">
+        <xsl:text>toggle('</xsl:text>
+        <xsl:value-of select="@error:description"/>
+        <xsl:text>');</xsl:text>
+      </xsl:for-each>
+    </xsl:attribute>
+  </xsl:template>
+
+  <xsl:template match="error:extra">
+    <xsl:choose>
+     <xsl:when test="contains(@error:description,'stacktrace')">
+      <p class="stacktrace">
+       <span class="description"><xsl:value-of select="@error:description"/></span>
+       <span class="switch" id="{@error:description}-switch" onclick="toggle('{@error:description}')">[hide]</span>
+       <pre id="{@error:description}">
+         <xsl:value-of select="translate(.,'&#13;','')"/>
+       </pre>
+      </p>
+     </xsl:when>
+     <xsl:otherwise>
+      <p class="extra">
+       <span class="description"><xsl:value-of select="@error:description"/>:&#160;</span>
+       <xsl:value-of select="."/>
+      </p>
+     </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/exception2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/exception2html.xslt
new file mode 100644
index 0000000..fbf3da8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/exception2html.xslt
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:ex="http://apache.org/cocoon/exception/1.0">
+
+  <xsl:param name="contextPath"/>
+  <xsl:param name="realPath"/>
+
+  <!-- let sitemap override default page title -->
+  <xsl:param name="pageTitle">An error has occured</xsl:param>
+
+  <xsl:template match="ex:exception-report">
+    <html>
+      <head>
+        <title>
+          <xsl:value-of select="$pageTitle"/>
+        </title>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <style>
+          h1 { font-size: 200%; color: #336699; text-align: left; margin: 0px 0px 30px 0px; padding: 0px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+          p.message { padding: 10px 30px 10px 30px; font-weight: bold; font-size: 110%; border-width: 1px; border-style: dashed; border-color: #336699; }
+          p.description { padding: 10px 30px 20px 30px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
+          p.topped { padding-top: 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #336699; }
+          pre { font-size: 120%; }
+          .row-1 { background-color: #F0F0F0;}
+          table { border-collapse: collapse; margin-top: 0.3em; }
+          td { padding: 0.1em; }
+        </style>
+        <script src="{$contextPath}/scripts/main.js" type="text/javascript"/>
+      </head>
+      <body>
+        <xsl:attribute name="onload">
+          <xsl:if test="ex:stacktrace">toggle('stacktrace');</xsl:if>
+          <xsl:if test="ex:full-stacktrace">toggle('full-stacktrace');</xsl:if>
+        </xsl:attribute>
+
+        <h1><xsl:value-of select="$pageTitle"/></h1>
+        <p class="message">
+          <xsl:value-of select="@class"/>:
+          <xsl:apply-templates select="ex:message" mode="breakLines"/>
+          <xsl:if test="ex:location">
+             <br/><span style="font-weight: normal"><xsl:apply-templates select="ex:location"/></span>
+          </xsl:if>
+        </p>
+
+        <p><span class="description">Cocoon stacktrace</span>
+           <span class="switch" id="locations-switch" onclick="toggle('locations')">[hide]</span>
+        </p>
+        <div id="locations">
+          <xsl:for-each select="ex:cocoon-stacktrace/ex:exception">
+            <xsl:sort select="position()" order="descending"/>
+            <strong>
+               <xsl:apply-templates select="ex:message" mode="breakLines"/>
+            </strong>
+            <table>
+               <xsl:for-each select="ex:locations/*[string(.) != '[cause location]']">
+                 <!-- [cause location] indicates location of a cause, which 
+                      the exception generator outputs separately -->
+                <tr class="row-{position() mod 2}">
+                   <td><xsl:call-template name="print-location"/></td>
+                   <td><em><xsl:value-of select="."/></em></td>
+                </tr>
+                <!--xsl:apply-templates select="."/><br/-->
+              </xsl:for-each>
+            </table>
+            <br/>
+           </xsl:for-each>
+        </div>
+
+        <xsl:apply-templates select="ex:stacktrace"/>
+        <xsl:apply-templates select="ex:full-stacktrace"/>
+
+<!-- Do we really need all that stuff?
+     Application developers know this, and application users get really confused by this information.
+
+        <p class="topped">
+          If you need help and this information is not enough, you
+          are invited to read the
+          <a href="http://cocoon.apache.org/2.1/faq/">Cocoon FAQ</a>.<br/>
+          If you still don't find the answers you need,
+          can send a mail to the
+          <a href="http://cocoon.apache.org/community/mail-lists.html">
+          Cocoon mailing lists</a>,
+          remembering to:
+        </p>
+
+        <ul>
+          <li>specify the version of Cocoon you're using, or we'll assume that you
+              are talking about the latest released version;</li>
+          <li>specify the platform-operating system-version-servlet container version;</li>
+          <li>send any pertinent error message;</li>
+          <li>send pertinent log snippets;</li>
+          <li>send pertinent sitemap snippets;</li>
+          <li>send pertinent parts of the page that give you problems.</li>
+        </ul>
+
+        <p>
+          For more detailed technical information, take a look at the log
+          files in the log directory of Cocoon, which is placed by default in
+          the <code>WEB-INF/logs/</code> folder of your cocoon webapp context.<br/>
+          If the logs don't give you enough information, you might want to increase the
+          log level by changing the Logging configuration which is by default the
+          <code>WEB-INF/logkit.xconf</code> file.
+        </p>
+
+        <p>
+          If you think you found a bug, please report it to the 
+          <a href="http://issues.apache.org/jira/browse/COCOON">Apache Cocoon issue tracker</a>;
+          a message will automatically be sent to the developer mailing list and you'll
+          be kept in contact automatically with the further progress on that bug.
+        </p>
+
+        <p>
+          Thanks, and sorry for the trouble if this is our fault.
+        </p>
+-->
+        <p class="topped">
+          The <a href="http://cocoon.apache.org/">Apache Cocoon</a> Project
+        </p>
+      </body>
+    </html>
+  </xsl:template>
+  
+  <xsl:template match="ex:stacktrace|ex:full-stacktrace">
+      <p class="stacktrace">
+       <span class="description">Java <xsl:value-of select="translate(local-name(), '-', ' ')"/></span>
+       <span class="switch" id="{local-name()}-switch" onclick="toggle('{local-name()}')">[hide]</span>
+       <pre id="{local-name()}">
+         <xsl:value-of select="translate(.,'&#13;','')"/>
+       </pre>
+      </p>
+  </xsl:template>
+  
+  <xsl:template match="ex:location">
+   <xsl:if test="string-length(.) > 0">
+     <em><xsl:value-of select="."/></em>
+     <xsl:text> - </xsl:text>
+   </xsl:if>
+   <xsl:call-template name="print-location"/>
+  </xsl:template>
+  
+  <xsl:template name="print-location">
+     <xsl:choose>
+       <xsl:when test="contains(@uri, $realPath)">
+         <xsl:text>context:/</xsl:text>
+         <xsl:value-of select="substring-after(@uri, $realPath)"/>
+       </xsl:when>
+       <xsl:otherwise>
+         <xsl:value-of select="@uri"/>
+       </xsl:otherwise>
+      </xsl:choose>
+      <xsl:text> - </xsl:text>
+      <xsl:value-of select="@line"/>:<xsl:value-of select="@column"/>
+  </xsl:template>
+  
+  <!-- output a text by splitting it with <br>s on newlines
+       can be uses either by an explicit call or with <apply-templates mode="breakLines"/> -->
+  <xsl:template match="node()"  mode="breakLines" name="breakLines">
+     <xsl:param name="text" select="string(.)"/>
+     <xsl:choose>
+        <xsl:when test="contains($text, '&#10;')">
+           <xsl:value-of select="substring-before($text, '&#10;')"/>
+           <br/>
+           <xsl:call-template name="breakLines">
+              <xsl:with-param name="text" select="substring-after($text, '&#10;')"/>
+           </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+           <xsl:value-of select="$text"/>
+        </xsl:otherwise>
+     </xsl:choose>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/linkstatus2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/linkstatus2html.xslt
new file mode 100644
index 0000000..f4db9b2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/linkstatus2html.xslt
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: linkstatus2html.xslt,v 1.3 2004/03/06 02:25:41 antonio Exp $ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:linkstatus="http://apache.org/cocoon/linkstatus/2.0">
+
+  <xsl:template match="linkstatus:linkstatus">
+    <html>
+      <body>
+        <table border="1">
+          <tr><th>URL</th><th>referrer</th><th>content-type</th><th>status</th><th>message</th></tr>
+          <xsl:apply-templates/>
+        </table>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="linkstatus:link">
+    <tr>
+      <xsl:attribute name = "bgcolor">
+        <xsl:choose>
+          <xsl:when test="normalize-space(@status)='200'">#00ff00</xsl:when>
+          <xsl:when test="normalize-space(@status)='404'">#ffff00</xsl:when>     	
+          <xsl:otherwise>#ff0000</xsl:otherwise>
+        </xsl:choose>
+      </xsl:attribute>
+      <td><a href="{@href}"><xsl:value-of select="@href"/></a></td>
+      <td><a href="{@referrer}">referrer</a></td>
+      <td><xsl:value-of select="@content"/></td> 
+      <td><xsl:value-of select="@status"/></td> 
+      <td><xsl:value-of select="@message"/></td>
+    </tr>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/sitemap2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/sitemap2html.xslt
new file mode 100644
index 0000000..77372db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/sitemap2html.xslt
@@ -0,0 +1,497 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: sitemap2html.xslt,v 1.3 2004/03/06 02:25:41 antonio Exp $ -->
+
+<xsl:stylesheet version="1.0"
+                xmlns:map="http://apache.org/cocoon/sitemap/1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:template match="/">
+  <html>
+   <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
+    <meta name="Author" content="{author}"/>
+    <meta name="Version" content="{version}"/>
+    <title>The Sitemap</title>
+   </head>
+   <body>
+    <xsl:apply-templates/>
+   </body>
+  </html>
+ </xsl:template>
+
+ <xsl:template match="map:sitemap">
+  <h1>The Sitemap</h1>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:components">
+  <h2>Components</h2>
+  <table border="0" width="100%" bgcolor="navy" cellspacing="0" cellpadding="0">
+   <tr>
+    <td>
+     <table border="0" width="100%" cellspacing="2" cellpadding="0">
+      <tr>
+       <td bgcolor="lightgrey">
+        <table border="0" width="100%" cellspacing="2" cellpadding="0">
+         <xsl:apply-templates select="map:generators"/>
+         <xsl:apply-templates select="map:transformers"/>
+         <xsl:apply-templates select="map:readers"/>
+         <xsl:apply-templates select="map:serializers"/>
+         <xsl:apply-templates select="map:selectors"/>
+         <xsl:apply-templates select="map:matchers"/>
+        </table>
+       </td>
+      </tr>
+     </table>
+    </td>
+   </tr>
+  </table>
+ </xsl:template>
+
+ <xsl:template match="map:views">
+  <h2>Views</h2>
+  <table border="0" width="100%" bgcolor="navy" cellspacing="0" cellpadding="0">
+   <tr>
+    <td>
+     <table border="0" width="100%" cellspacing="2" cellpadding="0">
+      <tr>
+       <td bgcolor="lightgrey">
+        <table border="0" width="100%" cellspacing="2" cellpadding="0">
+         <tr>
+          <td colspan="2" bgcolor="white"><b>Name</b></td>
+          <td bgcolor="white"><b>Arguments</b></td>
+         </tr>
+         <xsl:apply-templates select="map:match|map:select|map:redirect-to|map:generate|map:transform|map:select|map:read"/>
+        </table>
+       </td>
+      </tr>
+     </table>
+    </td>
+   </tr>
+  </table>
+ </xsl:template>
+
+ <xsl:template match="map:resources">
+  <h2>Resources</h2>
+  <table border="0" width="100%" bgcolor="navy" cellspacing="0" cellpadding="0">
+   <tr>
+    <td>
+     <table border="0" width="100%" cellspacing="2" cellpadding="0">
+      <tr>
+       <td bgcolor="lightgrey">
+        <table border="0" width="100%" cellspacing="2" cellpadding="0">
+         <tr>
+          <td colspan="3" bgcolor="white"><b>Name</b></td>
+         </tr>
+         <xsl:apply-templates/>
+        </table>
+       </td>
+      </tr>
+     </table>
+    </td>
+   </tr>
+  </table>
+ </xsl:template>
+
+ <xsl:template match="map:pipelines">
+  <h2>Pipelines</h2>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:generators">
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Generators</xsl:with-param>
+   <xsl:with-param name="comp-type">generator</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="label">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:transformers">
+  <xsl:call-template name="break"/>
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Transformers</xsl:with-param>
+   <xsl:with-param name="comp-type">transformer</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="label">true</xsl:with-param>
+   <xsl:with-param name="break">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:readers">
+  <xsl:call-template name="break"/>
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Readers</xsl:with-param>
+   <xsl:with-param name="comp-type">reader</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="break">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:serializers">
+  <xsl:call-template name="break"/>
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Serializers</xsl:with-param>
+   <xsl:with-param name="comp-type">serializer</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="break">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:selectors">
+  <xsl:call-template name="break"/>
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Selectors</xsl:with-param>
+   <xsl:with-param name="comp-type">selector</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="break">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:matchers">
+  <xsl:call-template name="break"/>
+  <xsl:call-template name="show-components">
+   <xsl:with-param name="type">Matchers</xsl:with-param>
+   <xsl:with-param name="comp-type">matcher</xsl:with-param>
+   <xsl:with-param name="default" select="@default"/>
+   <xsl:with-param name="components" select="./*"/>
+   <xsl:with-param name="break">true</xsl:with-param>
+  </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="map:view">
+  <xsl:if test="preceding-sibling::map:view">
+   <xsl:call-template name="break"/>
+  </xsl:if>
+  <tr>
+   <td colspan="2" bgcolor="white"><a href=""><xsl:value-of select="@name"/></a></td>
+   <td bgcolor="white">generate-from="<xsl:value-of select="@generate-from"/>"</td>
+  </tr>
+  <tr>
+   <td bgcolor="white">&#160;</td>
+   <td colspan="2" bgcolor="white">
+    <xsl:apply-templates/>
+   </td>
+  </tr>
+ </xsl:template>
+
+ <xsl:template match="map:resource">
+  <xsl:if test="preceding-sibling::map:resource">
+   <xsl:call-template name="break"/>
+  </xsl:if>
+  <tr>
+   <td colspan="3" bgcolor="white"><a href=""><xsl:value-of select="@name"/></a></td>
+  </tr>
+  <tr>
+   <td bgcolor="white">&#160;</td>
+   <td colspan="2" bgcolor="white">
+    <xsl:apply-templates/>
+   </td>
+  </tr>
+ </xsl:template>
+
+ <xsl:template match="map:pipeline">
+  <table border="0" width="100%" bgcolor="navy" cellspacing="0" cellpadding="0">
+   <tr>
+    <td>
+     <table border="0" width="100%" cellspacing="2" cellpadding="0">
+      <tr>
+       <td bgcolor="lightgrey">
+        <table border="0" width="100%" cellspacing="2" cellpadding="0">
+         <xsl:apply-templates/>
+        </table>
+       </td>
+      </tr>
+     </table>
+    </td>
+   </tr>
+  </table>
+  <br/>
+ </xsl:template>
+
+ <xsl:template match="map:match">
+  <xsl:choose>
+   <xsl:when test="ancestor::*[self::map:pipeline]">
+    <tr>
+     <td bgcolor="white">
+      <xsl:call-template name="indent"/>
+      <a href="">match</a>
+      <xsl:if test="@type">
+        type="<xsl:value-of select="@type"/>"
+      </xsl:if>
+      pattern="<xsl:value-of select="@pattern"/>"
+      <br/>
+      <xsl:apply-templates/>
+     </td>
+    </tr>
+   </xsl:when>
+   <xsl:otherwise>
+    <xsl:call-template name="indent"/>
+    <a href="">match</a>
+    <xsl:if test="@type">
+      type="<xsl:value-of select="@type"/>"
+    </xsl:if>
+    pattern="<xsl:value-of select="@pattern"/>"
+    <br/>
+    <xsl:apply-templates/>
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="map:select">
+  <xsl:call-template name="indent"/>
+  <a href="">select</a>
+  <xsl:if test="@type">
+    type="<xsl:value-of select="@type"/>"
+  </xsl:if>
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:when">
+  <xsl:call-template name="indent"/>
+  <a href="">when</a> test="<xsl:value-of select="@test"/>"<br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:otherwise">
+  <xsl:call-template name="indent"/>
+  <a href="">otherwise</a><br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:generate">
+  <xsl:call-template name="indent"/>
+  <a href="">generate</a>
+  <xsl:if test="@type">
+    type="<xsl:value-of select="@type"/>"
+  </xsl:if>
+  src="<xsl:value-of select="@src"/>"
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:transform">
+  <xsl:call-template name="indent"/>
+  <a href="">transform</a>
+  <xsl:if test="@type">
+    type="<xsl:value-of select="@type"/>"
+  </xsl:if>
+  src="<xsl:value-of select="@src"/>"
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:read">
+  <xsl:call-template name="indent"/>
+  <a href="">read</a>
+  <xsl:if test="@type">
+    type="<xsl:value-of select="@type"/>"
+  </xsl:if>
+  src="<xsl:value-of select="@src"/>"
+  <xsl:if test="@mime-type">
+    mime-type="<xsl:value-of select="@mime-type"/>"
+  </xsl:if>
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:redirect-to">
+  <xsl:call-template name="indent"/>
+  <a href="">redirect-to</a>
+  <xsl:choose>
+    <xsl:when test="@uri">
+      uri="<xsl:value-of select="@uri"/>"
+    </xsl:when>
+    <xsl:when test="@resource">
+      resource="<xsl:value-of select="@resource"/>"
+    </xsl:when>
+  </xsl:choose>
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:serialize">
+  <xsl:call-template name="indent"/>
+  <a href="">serialize</a>
+  <xsl:if test="@type">
+    type="<xsl:value-of select="@type"/>"
+  </xsl:if>
+  <xsl:if test="@mime-type">
+    mime-type="<xsl:value-of select="@mime-type"/>"
+  </xsl:if>
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:mount">
+  <xsl:call-template name="indent"/>
+  <a href="">mount</a> src="<xsl:value-of select="@src"/>" uri-prefix="<xsl:value-of select="@uri-prefix"/>"<br/>
+  <xsl:if test="@check-reload">
+    check-reload="<xsl:value-of select="@check-reload"/>"
+  </xsl:if>
+  <br/>
+  <xsl:apply-templates/>
+ </xsl:template>
+
+ <xsl:template match="map:handle-errors">
+  <tr>
+   <td bgcolor="white">
+    <xsl:call-template name="indent"/>
+    <a href="">handle-errors</a>
+    <br/>
+    <xsl:apply-templates/>
+   </td>
+  </tr>
+ </xsl:template>
+
+ <!-- named templates -->
+
+ <xsl:template name="show-components">
+  <xsl:param name="type"/>
+  <xsl:param name="comp-type"/>
+  <xsl:param name="default"/>
+  <xsl:param name="components"/>
+  <xsl:param name="label"/>
+  <tr>
+   <td colspan="3" bgcolor="white">
+    <span class="h3"><xsl:value-of select="$type"/> (default=<i><xsl:value-of select="$default"/></i>)</span>
+   </td>
+  </tr>
+  <tr>
+   <td bgcolor="white"><b>Name</b></td>
+   <xsl:choose>
+    <xsl:when test="$label">
+     <td bgcolor="white"><b>Class</b></td>
+     <td bgcolor="white"><b>Label</b></td>
+    </xsl:when>
+    <xsl:otherwise>
+     <td colspan="2" bgcolor="white"><b>Class</b></td>
+    </xsl:otherwise>
+   </xsl:choose>
+  </tr>
+  <xsl:for-each select="$components">
+   <tr>
+    <td bgcolor="white"><a href="sitemap-component?component={$comp-type}&amp;name={@name}"><xsl:value-of select="@name"/></a></td>
+    <xsl:choose>
+     <xsl:when test="$label">
+      <xsl:choose>
+       <xsl:when test="@src">
+        <td bgcolor="white"><xsl:value-of select="@src"/></td>
+       </xsl:when>
+       <xsl:otherwise>
+        <td bgcolor="white"><i><xsl:value-of select="@factory"/></i></td>
+       </xsl:otherwise>
+      </xsl:choose>
+      <td bgcolor="white"><xsl:value-of select="@label"/>&#160;</td>
+     </xsl:when>
+     <xsl:otherwise>
+      <xsl:choose>
+       <xsl:when test="@src">
+        <td colspan="2" bgcolor="white"><xsl:value-of select="@src"/></td>
+       </xsl:when>
+       <xsl:otherwise>
+        <td colspan="2" bgcolor="white"><i><xsl:value-of select="@factory"/></i></td>
+       </xsl:otherwise>
+      </xsl:choose>
+     </xsl:otherwise>
+    </xsl:choose>
+   </tr>
+   <xsl:if test="./*">
+<!--
+    <xsl:call-template name="show-config"/>
+-->
+   </xsl:if>
+  </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="show-config">
+  <xsl:param name="indent"/>
+  <xsl:choose>
+   <xsl:when test="string-length($indent)=0">
+    <tr>
+     <td align="right">Configuration</td>
+     <td colspan="3">
+      <xsl:for-each select="./*">
+       &#160;<xsl:value-of select="name()"/>
+       <xsl:if test="./*">
+        <xsl:call-template name="show-config">
+         <xsl:with-param name="indent">&#160;<xsl:value-of select="$indent"/></xsl:with-param>
+        </xsl:call-template>
+       </xsl:if>
+      </xsl:for-each>
+     </td>
+    </tr>
+   </xsl:when>
+   <xsl:otherwise>
+    <tr>
+     <td align="right">&#160;</td>
+     <td colspan="3">
+      <xsl:for-each select="./*">
+       &#160;<xsl:value-of select="name()"/>=<xsl:value-of select="text()"/>
+       <xsl:if test="./*">
+        <xsl:call-template name="show-config">
+         <xsl:with-param name="indent">&#160;<xsl:value-of select="$indent"/></xsl:with-param>
+        </xsl:call-template>
+       </xsl:if>
+      </xsl:for-each>
+     </td>
+    </tr>
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="break">
+  <tr>
+   <td colspan="3" bgcolor="white"><hr color="navy"/></td>
+  </tr>
+ </xsl:template>
+
+ <xsl:template name="indent">
+  <xsl:for-each select="ancestor::*">
+   <xsl:choose>
+    <xsl:when test="local-name(.)='pipeline'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='pipelines'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='sitemap'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='resource'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='resources'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='view'">
+    </xsl:when>
+    <xsl:when test="local-name(.)='views'">
+    </xsl:when>
+    <xsl:otherwise>
+     &#160;&#160;
+    </xsl:otherwise>
+   </xsl:choose>
+  </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template match="*|@*|text()|comment()|processing-instruction()" priority="-1"/>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/status2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/status2html.xslt
new file mode 100644
index 0000000..060ad8a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/status2html.xslt
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Converts output of the StatusGenerator into HTML page
+    | 
+    | CVS $Id: status2html.xslt,v 1.8 2004/03/06 02:25:41 antonio Exp $
+    +-->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:status="http://apache.org/cocoon/status/2.0"
+                xmlns:xalan="http://xml.apache.org/xalan"
+                exclude-result-prefixes="xalan">
+ 
+  <xsl:param name="contextPath"/>
+
+  <xsl:template match="status:statusinfo">
+    <html>
+      <head>
+        <title>Cocoon Status [<xsl:value-of select="@status:host"/>]</title>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <script src="{$contextPath}/scripts/main.js" type="text/javascript"/>
+      </head>
+
+      <body>
+        <h1><xsl:value-of select="@status:host"/> - <xsl:value-of select="@status:date"/></h1>
+        <h2>Apache Cocoon <xsl:value-of select="@status:cocoon-version"/></h2>
+        <li>
+          <span class="description">Created:</span>
+          <xsl:text> </xsl:text>
+          <xsl:value-of select="@status:creation-time"/>
+        </li>
+        <li>
+          <span class="description">Build:</span>
+          <xsl:text> </xsl:text>
+          <xsl:value-of select="@status:build-info"/>
+        </li>
+        <xsl:apply-templates/>
+
+        <!--
+          - Add XSLT processor information
+          -->
+        <h2>XSLT Processor</h2>
+        <li>
+          <span class="description">XSLT Version:</span>
+          <xsl:text> </xsl:text>
+          <xsl:value-of select="system-property('xsl:version')"/>
+        </li>
+        <li>
+          <span class="description">Vendor:</span>
+          <xsl:text> </xsl:text>
+          <xsl:value-of select="system-property('xsl:vendor')"/>
+        </li>
+        <li>
+          <span class="description">Vendor URL:</span>
+          <xsl:text> </xsl:text>
+          <xsl:value-of select="system-property('xsl:vendor-url')"/>
+        </li>
+
+        <!--
+          - Add Xalan / Xerces information using custom Xalan extension
+          - (if it's present)
+          -->
+        <xsl:if test="function-available('xalan:checkEnvironment')">
+          <xsl:apply-templates select="xalan:checkEnvironment()"/>
+        </xsl:if>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="status:group">
+    <h2><xsl:value-of select="@status:name"/></h2>
+    <ul><xsl:apply-templates select="status:value"/></ul>
+    <xsl:apply-templates select="status:group"/>
+    <xsl:if test="status:cont">
+    	<ul>
+    		<xsl:apply-templates select="status:cont"/>    	
+    	</ul>
+    </xsl:if>
+  </xsl:template>
+  
+  <xsl:template match="status:cont">
+  	<li>
+  		<xsl:for-each select="@*">
+  			<span class="description"><xsl:value-of select="name()"/>:<xsl:text> </xsl:text> </span><xsl:value-of select="."/>
+  			<xsl:if test="position() != last()">, </xsl:if>
+  		</xsl:for-each>
+  	</li>
+    <xsl:if test="status:cont">
+    	<ul>
+    		<xsl:apply-templates select="status:cont"/>    	
+    	</ul>  	
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="status:value">
+    <li>
+      <span class="description"><xsl:value-of select="@status:name"/><xsl:text>: </xsl:text></span>
+      <xsl:choose>
+        <xsl:when test="contains(@status:name,'free') or contains(@status:name,'total') or contains(@status:name,'used')">
+          <xsl:call-template name="suffix">
+            <xsl:with-param name="bytes" select="number(.)"/>
+          </xsl:call-template>
+        </xsl:when>      
+        <xsl:when test="count(status:line) &lt;= 1">
+          <xsl:value-of select="status:line"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <span class="switch" id="{generate-id(.)}-switch" onclick="toggle('{generate-id(.)}')">[show]</span>
+          <ul id="{generate-id(.)}" style="display: none">
+             <xsl:apply-templates />
+          </ul>
+        </xsl:otherwise>
+      </xsl:choose>
+    </li>
+  </xsl:template>
+
+  <xsl:template match="status:line">
+    <li><xsl:value-of select="."/></li>
+  </xsl:template>
+
+  <xsl:template name="suffix">
+    <xsl:param name="bytes"/>
+    <xsl:choose>
+      <!-- More than 4 MB (=4194304) -->
+      <xsl:when test="$bytes &gt;= 4194304">
+        <xsl:value-of select="round($bytes div 10485.76) div 100"/> MB
+      </xsl:when>
+      <!-- More than 4 KB (=4096) -->
+      <xsl:when test="$bytes &gt; 4096">
+        <xsl:value-of select="round($bytes div 10.24) div 100"/> KB
+      </xsl:when>
+      <!-- Less -->
+      <xsl:otherwise>
+        <xsl:value-of select="$bytes"/> B
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--
+    - Process Xalan extension output
+    -->
+  <xsl:template match="checkEnvironmentExtension">
+    <h2>Xerces, Xalan</h2>
+    <ul><xsl:apply-templates select="EnvironmentCheck/environment/item[starts-with(@key, 'version.')]"/></ul>
+  </xsl:template> 
+
+  <xsl:template match="item">
+    <li style="width: 40%">
+      <span class="description"><xsl:value-of select="@key"/>:</span>
+      <xsl:text> </xsl:text>
+      <xsl:value-of select="."/>
+    </li>
+  </xsl:template> 
+   
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/xml2html.xslt b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/xml2html.xslt
new file mode 100644
index 0000000..b2ad460
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/stylesheets/system/xml2html.xslt
@@ -0,0 +1,201 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | XSLT REC Compliant Version of IE5 Default Stylesheet
+    |
+    | Original version by Jonathan Marsh (jmarsh@microsoft.com)
+    | Conversion to XSLT 1.0 REC Syntax by Steve Muench (smuench@oracle.com)
+    | Added script support by Andrew Timberlake (andrew@timberlake.co.za)
+    | Cleaned up and ported to standard DOM by Stefano Mazzocchi (stefano@apache.org)
+    |
+    | CVS $Id: xml2html.xslt,v 1.10 2004/05/01 13:20:55 joerg Exp $
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+   <xsl:template match="/">
+      <HTML>
+         <HEAD>
+            <link href="/styles/prettycontent.css" type="text/css" rel="stylesheet"/>
+            <script src="/scripts/prettycontent.js" type="text/javascript"/>
+         </HEAD>
+         <BODY>
+            <xsl:apply-templates/>
+         </BODY>
+      </HTML>
+   </xsl:template>
+
+   <!-- match processing instructions -->
+   <xsl:template match="processing-instruction()">
+      <DIV class="e">
+         <SPAN class="m">&lt;?</SPAN>
+         <SPAN class="pi">
+            <xsl:value-of select="name(.)"/>
+            <xsl:text> </xsl:text>
+            <xsl:value-of select="."/>
+         </SPAN>
+         <SPAN class="m">?></SPAN>
+      </DIV>
+   </xsl:template>
+
+   <!-- match text -->
+   <xsl:template match="text()">
+      <DIV class="e">
+         <SPAN class="t">
+            <xsl:value-of select="."/>
+         </SPAN>
+      </DIV>
+   </xsl:template>
+
+   <!-- match comments -->
+   <xsl:template match="comment()">
+      <DIV class="e">
+         <SPAN class="b" onclick="xml2htmlToggle(event)">-</SPAN>
+         <SPAN class="m">&lt;!--</SPAN>
+         <SPAN class="c">
+            <PRE>
+               <xsl:value-of select="."/>
+            </PRE>
+         </SPAN>
+         <SPAN class="m">--></SPAN>
+      </DIV>
+   </xsl:template>
+
+   <!-- match attributes -->
+   <xsl:template match="@*">
+      <SPAN class="an">
+         <xsl:value-of select="name(.)"/>
+      </SPAN>
+      <SPAN class="m">="</SPAN>
+      <SPAN class="av">
+         <xsl:value-of select="."/>
+      </SPAN>
+      <SPAN class="m">"</SPAN>
+      <xsl:if test="position()!=last()">
+         <xsl:text> </xsl:text>
+      </xsl:if>
+   </xsl:template>
+
+   <!-- match empty elements -->
+   <xsl:template match="*[not(node())]">
+      <DIV class="e">
+        <SPAN class="m">&lt;</SPAN>
+        <SPAN class="en">
+           <xsl:value-of select="name(.)"/>
+        </SPAN>
+        <xsl:if test="@*">
+           <xsl:text> </xsl:text>
+        </xsl:if>
+        <xsl:apply-templates select="@*"/>
+        <xsl:apply-templates select="." mode="namespace"/>
+        <SPAN class="m">/&gt;</SPAN>
+      </DIV>
+   </xsl:template>
+
+   <!-- match elements with only text(), they are not closeable -->
+   <xsl:template match="*[text()][not(* or comment() or processing-instruction())]" priority="10">
+      <DIV class="e">
+        <SPAN class="m">&lt;</SPAN>
+        <SPAN class="en">
+           <xsl:value-of select="name(.)"/>
+        </SPAN>
+        <xsl:if test="@*">
+           <xsl:text> </xsl:text>
+        </xsl:if>
+        <xsl:apply-templates select="@*"/>
+        <xsl:apply-templates select="." mode="namespace"/>
+        <SPAN class="m">
+           <xsl:text>></xsl:text>
+        </SPAN>
+        <SPAN class="t">
+           <xsl:value-of select="."/>
+        </SPAN>
+        <SPAN class="m">&lt;/</SPAN>
+        <SPAN class="en">
+           <xsl:value-of select="name(.)"/>
+        </SPAN>
+        <SPAN class="m">
+           <xsl:text>></xsl:text>
+        </SPAN>
+      </DIV>
+   </xsl:template>
+
+   <xsl:template match="*[node()]">
+      <DIV class="e">
+         <DIV>
+            <SPAN class="b" onclick="xml2htmlToggle(event)">-</SPAN>
+            <SPAN class="m">&lt;</SPAN>
+            <SPAN class="en">
+               <xsl:value-of select="name(.)"/>
+            </SPAN>
+            <xsl:if test="@*">
+               <xsl:text> </xsl:text>
+            </xsl:if>
+            <xsl:apply-templates select="@*"/>
+            <xsl:apply-templates select="." mode="namespace"/>
+            <SPAN class="m">
+               <xsl:text>></xsl:text>
+            </SPAN>
+         </DIV>
+         <DIV>
+            <xsl:apply-templates/>
+            <DIV>
+               <SPAN class="m">&lt;/</SPAN>
+               <SPAN class="en">
+                  <xsl:value-of select="name(.)"/>
+               </SPAN>
+               <SPAN class="m">
+                  <xsl:text>></xsl:text>
+               </SPAN>
+            </DIV>
+         </DIV>
+      </DIV>
+   </xsl:template>
+
+   <xsl:template match="*" mode="namespace">
+     <xsl:variable name="context" select="."/>
+     <xsl:for-each select="namespace::node()">
+       <xsl:variable name="nsuri" select="."/>
+       <xsl:variable name="nsprefix" select="name()"/>
+       <xsl:choose>
+        <xsl:when test="$nsprefix = 'xml'">
+          <!-- xml namespace -->
+        </xsl:when>
+        <xsl:when test="$context/../namespace::node()[name() = $nsprefix and . = $nsuri]">
+          <!-- namespace already declared on the parent -->
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text> </xsl:text>
+          <SPAN class="an">
+            <xsl:text>xmlns</xsl:text>
+            <xsl:if test="$nsprefix">
+              <xsl:text>:</xsl:text>
+              <xsl:value-of select="$nsprefix"/>
+            </xsl:if>
+          </SPAN>
+          <SPAN class="m">="</SPAN>
+          <SPAN class="av">
+            <xsl:value-of select="."/>
+          </SPAN>
+          <SPAN class="m">"</SPAN>
+        </xsl:otherwise>
+       </xsl:choose>
+     </xsl:for-each>
+   </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/test-suite/sitemap.xmap b/non-releases/trunk_before_flattening/src/webapp/test-suite/sitemap.xmap
new file mode 100644
index 0000000..30754f2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/test-suite/sitemap.xmap
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: sitemap.xmap,v 1.1 2004/04/28 21:29:08 upayavira Exp $ -->
+
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+<!-- =========================== Components ================================ -->
+
+ <map:components>
+  <map:generators default="file"/>
+  <map:transformers default="xslt"/>
+  <map:readers default="resource"/>
+  <map:serializers default="html"/>
+  <map:matchers default="wildcard"/>
+  <map:selectors default="browser"/>
+ </map:components>
+
+<!-- =========================== Views =================================== -->
+
+ <map:views>
+  <map:view name="content" from-label="content">
+   <map:serialize type="xml"/>
+  </map:view>
+
+  <map:view from-label="content" name="pretty-content">
+    <map:transform src="context://stylesheets/system/xml2html.xslt"/>
+    <map:serialize type="html"/>
+  </map:view>
+
+  <map:view name="links" from-position="last">
+   <map:serialize type="links"/>
+  </map:view>
+ </map:views>
+
+<!-- =========================== Pipelines ================================= -->
+
+ <map:pipelines>
+  <map:pipeline>
+
+   <map:match pattern="static-site/**.html">
+     <map:generate src="xdocs/{1}.xml"/>
+     <map:transform src="stylesheets/xdoc2html.xslt">
+      <map:parameter name="contextPath" value="{request:contextPath}"/>
+     </map:transform>
+     <map:serialize type="html"/>
+   </map:match>
+   </map:pipeline>
+ </map:pipelines>
+</map:sitemap>
diff --git a/non-releases/trunk_before_flattening/src/webapp/test-suite/stylesheets/simple-xdoc2html.xslt b/non-releases/trunk_before_flattening/src/webapp/test-suite/stylesheets/simple-xdoc2html.xslt
new file mode 100644
index 0000000..691bf17
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/test-suite/stylesheets/simple-xdoc2html.xslt
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | Converts output of the StatusGenerator into HTML page
+    | 
+    | CVS $Id: simple-xdoc2html.xslt,v 1.1 2004/04/28 21:29:08 upayavira Exp $
+    +-->
+
+<xsl:stylesheet version="1.0"
+                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:status="http://apache.org/cocoon/status/2.0">
+ 
+  <xsl:param name="contextPath"/>
+
+  <xsl:template match="status:statusinfo">
+    <html>
+      <head>
+        <title>Cocoon Status [<xsl:value-of select="@status:host"/>]</title>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <script src="{$contextPath}/scripts/main.js" type="text/javascript"/>
+      </head>
+
+      <body>
+        <h1><xsl:value-of select="@status:host"/> - <xsl:value-of select="@status:date"/></h1>
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="status:group">
+    <h2><xsl:value-of select="@status:name"/></h2>
+    <ul><xsl:apply-templates select="status:value"/></ul>
+    <xsl:apply-templates select="status:group"/>
+  </xsl:template>
+
+  <xsl:template match="status:value">
+    <li>
+      <span class="description"><xsl:value-of select="@status:name"/><xsl:text>: </xsl:text></span>
+      <xsl:choose>
+        <xsl:when test="contains(@status:name,'free') or contains(@status:name,'total')">
+          <xsl:call-template name="suffix">
+            <xsl:with-param name="bytes" select="number(.)"/>
+          </xsl:call-template>
+        </xsl:when>      
+        <xsl:when test="count(status:line) &lt;= 1">
+          <xsl:value-of select="status:line"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <span class="switch" id="{generate-id(.)}-switch" onclick="toggle('{generate-id(.)}')">[show]</span>
+          <ul id="{generate-id(.)}" style="display: none">
+             <xsl:apply-templates />
+          </ul>
+        </xsl:otherwise>
+      </xsl:choose>
+    </li>
+  </xsl:template>
+
+  <xsl:template match="status:line">
+    <li><xsl:value-of select="."/></li>
+  </xsl:template>
+
+  <xsl:template name="suffix">
+    <xsl:param name="bytes"/>
+    <xsl:choose>
+      <!-- More than 4 MB (=4194304) -->
+      <xsl:when test="$bytes &gt;= 4194304">
+        <xsl:value-of select="round($bytes div 10485.76) div 100"/> MB
+      </xsl:when>
+      <!-- More than 4 KB (=4096) -->
+      <xsl:when test="$bytes &gt; 4096">
+        <xsl:value-of select="round($bytes div 10.24) div 100"/> KB
+      </xsl:when>
+      <!-- Less -->
+      <xsl:otherwise>
+        <xsl:value-of select="$bytes"/> B
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/test-suite/xdocs/index.xml b/non-releases/trunk_before_flattening/src/webapp/test-suite/xdocs/index.xml
new file mode 100644
index 0000000..afb021d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/test-suite/xdocs/index.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "dtd/document-v10.dtd">
+<document>
+  <header>
+    <title>Cocoon TestSuite</title>
+    <authors>
+      <person name="Cocoon community" email="dev@cocoon.apache.org"/>
+    </authors>
+  </header>
+  <body>
+    <s1 title="General information">
+      <p>
+          Apache Cocoon is a web development framework built around the concepts 
+          of component-based web development and separation of concerns, ensuring 
+          that people can interact and collaborate on a project without stepping 
+          on each other toes.
+      </p>
+      <p>
+          The purpose of these pages is to provide a webapp to be used in testing
+          Cocoon itself. These pages are not intended to be read by humans - rather
+          to be read by automated tests that are a part of Cocoon itself.
+      </p>
+    </s1>    
+  </body>
+</document>
diff --git a/non-releases/trunk_before_flattening/src/webapp/welcome.xml b/non-releases/trunk_before_flattening/src/webapp/welcome.xml
new file mode 100644
index 0000000..191ef24
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/welcome.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | This is a very simple XML page done just to show how a simple 
+    | cocoon pipeline works.
+    |
+    | CVS $Id: welcome.xml,v 1.5 2004/04/05 12:25:35 antonio Exp $
+    +-->
+
+<welcome>
+ <message>
+   Congratulations! If you are reading this page, it means that
+   your Apache Cocoon installation was successful.
+ </message>
+</welcome>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/src/webapp/welcome.xslt b/non-releases/trunk_before_flattening/src/webapp/welcome.xslt
new file mode 100644
index 0000000..40f5d47
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/welcome.xslt
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- CVS $Id: welcome.xslt,v 1.11 2004/03/06 02:25:58 antonio Exp $ -->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                              xmlns="http://www.w3.org/1999/xhtml">
+
+  <xsl:param name="contextPath"/>
+
+  <xsl:template match="welcome">
+    <html xml:lang="en" lang="en">
+      <head>
+        <title>Welcome to Apache Cocoon!</title>
+        <!-- 
+             NOTE (SM): this meta tag reflects the *output* of the pipeline and not
+             the encoding of this file. I agree it's sort of an hack and it should
+             be the XHTML serializer to add the meta tag to the response, but, for
+             now, this fixes encoding problems in those user-agents that don't parse
+             the <?xml?> processing instruction to understand the encoding of the
+             stream 
+         --> 
+        <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8"/>
+        <link href="{$contextPath}/styles/main.css" type="text/css" rel="stylesheet"/>
+        <link href="favicon.ico" rel="SHORTCUT ICON" />
+      </head>
+      <body>
+        <h1>Welcome to Apache Cocoon!</h1>
+        <xsl:apply-templates/>
+        <p class="copyright">
+         Copyright © @year@ <a href="http://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.
+        </p>
+        <p class="block">
+          <a href="http://cocoon.apache.org/"><img src="{$contextPath}/images/powered.gif" alt="Powered by Apache Cocoon"/></a>
+        </p>
+      </body>
+    </html>
+  </xsl:template>
+
+  <xsl:template match="message">
+    <p class="block"><xsl:apply-templates/></p>
+  </xsl:template>
+  
+  <xsl:template match="link">
+    <a href="{@href}"><xsl:apply-templates/></a>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/src/webapp/wiring.xml b/non-releases/trunk_before_flattening/src/webapp/wiring.xml
new file mode 100644
index 0000000..af43684
--- /dev/null
+++ b/non-releases/trunk_before_flattening/src/webapp/wiring.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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. 
+-->
+
+<wiring xmlns="http://apache.org/cocoon/blocks/wiring/1.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+        xsi:schemaLocation="http://apache.org/cocoon/blocks/wiring/1.0 wiring-schema-1.0.xsd"
+>
+
+  <block id="webapp" location="">
+    <mount path="/"/>
+  </block>
+</wiring>
diff --git a/non-releases/trunk_before_flattening/status.xml b/non-releases/trunk_before_flattening/status.xml
new file mode 100644
index 0000000..7562e88
--- /dev/null
+++ b/non-releases/trunk_before_flattening/status.xml
@@ -0,0 +1,470 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!DOCTYPE status [
+<!ELEMENT status (developers, todo, changes)>
+<!ELEMENT developers (person+)>
+<!ELEMENT person EMPTY>
+<!ATTLIST person
+  name CDATA #REQUIRED
+  email CDATA #REQUIRED
+  id CDATA #REQUIRED
+>
+<!ELEMENT todo (actions+)>
+<!ELEMENT actions (action+)>
+<!ATTLIST actions
+  priority (high | medium | low) #REQUIRED
+>
+<!ELEMENT changes (release+)>
+<!ELEMENT release (action+)>
+<!ATTLIST release
+  version CDATA #REQUIRED
+  date CDATA #REQUIRED
+>
+<!ELEMENT action (#PCDATA | link | br | code | ul | strong)*>
+<!ATTLIST action
+  context (build | code | docs) #IMPLIED
+  assigned-to CDATA #IMPLIED
+  dev CDATA #IMPLIED
+  type (add | fix | remove | update) #IMPLIED
+  fixes-bug CDATA #IMPLIED
+  due-to CDATA #IMPLIED
+  due-to-email CDATA #IMPLIED
+>
+<!ELEMENT code (#PCDATA)>
+<!ELEMENT br EMPTY>
+<!ELEMENT strong (#PCDATA)>
+<!ELEMENT link (#PCDATA)>
+<!ATTLIST link
+  href CDATA #REQUIRED
+>
+<!ELEMENT ul (li)+>
+<!ELEMENT li (#PCDATA | link | br | code | ul)*>
+<!ENTITY eacute           "&#x000E9;">
+<!ENTITY ouml             "&#x000F6;">
+<!ENTITY uuml             "&#x000FC;">
+<!ENTITY ccedil           "&#x000E7;">
+]>
+
+<!-- SVN $Id$ -->
+
+<status>
+ <developers>
+  <!-- in strict alphabetical order -->
+  <person name="Donald Ball" email="balld@apache.org" id="DB"/>
+  <person name="Nicola Ken Barozzi" email="nicolaken@apache.org" id="NKB"/>
+  <person name="Ross Burton" email="rossb@apache.org" id="RB"/>
+  <person name="Mark Butler" email="butlermh@apache.org" id="MB"/>
+  <person name="Ugo Cei" email="ugo@apache.org" id="UC"/>
+  <person name="Tony Collen" email="tony@apache.org" id="ATC"/>
+  <person name="Marcus Crafter" email="crafterm@apache.org" id="MC"/>
+  <person name="David Crossley" email="crossley@apache.org" id="DC"/>
+  <person name="Torsten Curdt" email="tcurdt@apache.org" id="TC"/>
+  <person name="Bertrand Delacr&#233;taz" email="bdelacretaz@apache.org" id="BD"/>
+  <person name="Bruno Dumon" email="bruno@apache.org" id="BRD"/>
+  <person name="Daniel Fagerstrom" email="danielf@apache.org" id="DF"/>
+  <person name="Gerhard Froehlich" email="froehlich@apache.org" id="GF"/>
+  <person name="Pierpaolo Fumagalli" email="pier@apache.org" id="PF"/>
+  <person name="Antonio Gallardo" email="antonio@apache.org" id="AG"/>
+  <person name="Leszek Gawron" email="lgawron@apache.org" id="LG"/>
+  <person name="Ralph Goers" email="rgoers@apache.org" id="RG"/>
+  <person name="Vadim Gritsenko" email="vgritsenko@apache.org" id="VG"/>
+  <person name="Christian Haul" email="haul@apache.org" id="CH"/>
+  <person name="J&#246;rg Heinicke" email="joerg@apache.org" id="JH"/>
+  <person name="Jorg Heymans" email="jheymans@apache.org" id="JHS"/>
+  <person name="Unico Hommes" email="unico@apache.org" id="UH"/>
+  <person name="Geoff Howard" email="ghoward@apache.org" id="GH"/>
+  <person name="Bernhard Huber" email="huber@apache.org" id="BH"/>
+  <person name="Ivelin Atanasoff Ivanov" email="ivelin@apache.org" id="IAI"/>
+  <person name="Matthew Langham" email="mlangham@apache.org" id="BL"/>
+  <person name="Berin Loritsch" email="bloritsch@apache.org" id="BL"/>
+  <person name="Stefano Mazzocchi" email="stefano@apache.org" id="SM"/>
+  <person name="Michael Melhem" email="michaelm@apache.org" id="MM"/>
+  <person name="Stephan Michels" email="stephan@apache.org" id="SMS"/>
+  <person name="John Morrison" email="morrijr@apache.org" id="JM"/>
+  <person name="Alfred Nathaniel" email="anathaniel@apache.org" id="AN"/>
+  <person name="Steven Noels" email="stevenn@apache.org" id="SN"/>
+  <person name="Christopher Oliver" email="coliver@apache.org" id="CO"/>
+  <person name="Giacomo Pati" email="giacomo@apache.org" id="GP"/>
+  <person name="Konstantin Piroumian" email="kpiroumian@apache.org" id="KP"/>
+  <person name="Marc Portier" email="mpo@apache.org" id="MPO"/>
+  <person name="Ovidiu Predescu" email="ovidiu@apache.org" id="OP"/>
+  <person name="Jeremy Quinn" email="jeremy@apache.org" id="JQ"/>
+  <person name="Reinhard P&#246;tz" email="reinhard@apache.org" id="RP"/>
+  <person name="Gianugo Rabellino" email="gianugo@apache.org" id="GR"/>
+  <person name="Ricardo Rocha" email="ricardo@apache.org" id="RR"/>
+  <person name="Peter Royal" email="proyal@apache.org" id="PAR"/>
+  <person name="Paul Russell" email="prussell@apache.org" id="PR"/>
+  <person name="Andrew Savory" email="asavory@apache.org" id="AS"/>
+  <person name="Diana Shannon" email="shannon@apache.org" id="DS"/>
+  <person name="Davanum Srinivas" email="dims@yahoo.com" id="DM"/>
+  <person name="Jeff Turner" email="jefft@apache.org" id="JT"/>
+  <person name="Upayavira" email="upayavira@apache.org" id="UV"/>
+  <person name="Sylvain Wallez" email="sylvain@apache.org" id="SW"/>
+  <person name="Carsten Ziegeler" email="cziegeler@apache.org" id="CZ"/>
+  <person name="Volunteer needed" email="cocoon-dev@apache.org" id="open"/>
+ </developers>
+
+  <todo>
+   <actions priority="high">
+    <action context="code" assigned-to="all">
+      Test, test, test :-)
+    </action>
+
+    <action context="build" assigned-to="open">
+      Complete (means put all allowed constructs and combinations)
+      the lint/sitemap.xmap file. Enhance the RELAX NG grammar for sitemap.
+    </action>
+
+    <action context="code" assigned-to="SW">
+      For 2.2: Views must start not from the first encountered label, but from the last one
+      (see http://marc.theaimsgroup.com/?l=xml-cocoon-dev&amp;m=101784499622172)
+    </action>
+
+    <action context="code" assigned-to="open">
+      Finish the design and contracts of flow. Add more tests and samples and
+      documentation.
+    </action>
+
+    <action context="code" assigned-to="open">
+      Finish the
+      <link href="plan/samples.html">refactoring of samples</link>
+    </action>
+
+    <action context="code" assigned-to="open">
+      Finish moving the scratchpad stuff in main trunk.
+    </action>
+   </actions>
+
+   <actions priority="medium">
+    <action context="code">
+      Ensure that recyclable components always release their references, even when
+      they are not pooled. The easiest way is to make them disposable and clean up
+      in dispose.
+    </action>
+
+    <action context="code">
+      Lucene is writing info to stdout when searching.
+    </action>
+
+    <action context="code">
+      Redesign FragmentExtractorGenerator/Transformer so that it works on a clustered
+      server: store fragments in the session rather than in a local store. <br/>
+      This couldn't work, because if you working with caching pipelines, you cannot be sure
+      that the entries are in the session(Stephan).
+    </action>
+
+    <action context="code" assigned-to="MPO">
+      Remove ContainerWidget concept from cforms.
+    </action>
+   </actions>
+  </todo>
+  <!-- These are the changes from the last 2.1.x version. -->
+ <changes>
+  <release version="@version@" date="@date@">
+    <action dev="CZ" type="update">
+      XMLSerializer and XMLDeserializer are no longer managed components. Use the XMLByteStreamCompiler
+      and XMLByteStreamInterpreter classes directly.
+    </action>
+    <action dev="CZ" type="add">
+      Add hierarchical property configuration for reloading. The various components checking
+      for changes in files like sitemaps, xconfs or flow scripts can now be turned on or off
+      by a single property.
+    </action>
+    <action dev="GP" type="add">
+      Added JMX support to the core ECM++ 
+    </action>
+    <action dev="JH" type="fix" fixes-bug="COCOON-1700">
+      I18n: XMLResourceBundle checks now for both the new and the old namespace.
+    </action>
+    <action dev="CZ" type="update">
+      AbstractSAXTransformer supports removal of own namespace prefixes.
+    </action>
+    <action dev="CZ" type="update">
+      CInclude transformer now removes its namespace prefixes.
+    </action>
+    <action dev="AN" type="add" fixes-bug="COCOON-1616">
+      Source that declares namespace fails JXPath/Linkrewriter/Input Modules.
+    </action>
+    <action dev="CZ" type="update">
+      Each block has now it's own status file.
+    </action>
+    <action dev="LG" type="update">
+      Improved blocks build exclusion/inclusion. See blocks.properties for more info.
+    </action>
+    <action dev="BD" type="update">
+      Samples pages reorganized: the first page shows only the most important samples, selected
+      in src/webapp/samples/blocks/samples-pages.xml, and another page shows all samples.
+    </action>
+    <action dev="BD" type="update">
+      Core samples moved to new blocks: core-samples-main and core-samples-additional.
+    </action>
+    <action dev="CZ" type="update">
+      Update Avalon framework to 4.3, Avalon LogKit to 2.1, Excalibur Instrument to 2.1,
+      Excalibur Logger to 2.1, Excalibur Pool to 2.1, Excalibur SourceResolve to 2.1,
+      Excalibur Store to 2.1, Excalibur XMLUtils to 2.1 and Excalibur Database to 2.1.
+    </action>
+    <action dev="CZ" type="add">
+      Add property mechanism for Cocoon configuration. All settings for Cocoon can now
+      be configured using properties instead of putting them in web.xml.
+    </action>
+    <action dev="CZ" type="add">
+      Allow the use of property replacements in logging, xconf and sitemap configurations.
+    </action>
+    <action dev="CZ" type="add">
+      Use includes for logkit configurations and for sitemap components.
+    </action>
+    <action dev="JH" type="update">
+      Moved following components into core: TraversableGenerator, XPathTraversableGenerator (both from repository
+      block), CSVGenerator (from scratchpad block), FragmentExtractorTransformer and FragmentExtractorGenerator
+      (both from batik block).
+    </action>
+    <action dev="AN" type="add" fixes-bug="28045" due-to="Jon Evans" due-to-email="jon.evans@misgl.com">
+      Added CookieModule as a more convinient way to access cookie values as {cookie:query}
+      in alternative to {request:cookies[name='query']/value}.
+    </action>
+    <action dev="AN" type="add" fixes-bug="33388" due-to="Andrew Stevens" due-to-email="ats37@hotmail.com">
+      Added parameter "show-cocoon-version" to web.xml for configuring whether X-Cocoon-Version
+      response header should be sent.  Default is true.
+      In a security paranoid environment you may want to set it to false in order to hide from
+      the outside world which Cocoon version you are running.
+    </action>
+    <action dev="CZ" type="fix">
+      Fix a huge memory leak in error pipelines that was caused by unreleased components.
+    </action>
+    <action dev="CZ" type="update">
+      Remove deprecated emptyAttributes from the AbstractSAXTransformer.
+    </action>
+    <action dev="CZ" type="add">
+      Per sitemap classloader factory is configurable using the role name.
+    </action>
+    <action dev="BD" type="add">
+      The junit.test.include.* options in build.properties can be used to run only
+      a subset of JUnit tests, to shorten debugging cycles.
+    </action>
+   <action dev="DF" type="update">
+     Added reflection friendly utility methods for the Cocoon environment according to vote
+     http://marc.theaimsgroup.com/?t=111590936900001&amp;r=1&amp;w=2:
+     Map getAttributes(), Map getParameters(), Map getHeaders() for Request
+     and Map getAttributes() for Session and Context.
+   </action>
+   <action dev="LG" type="update">
+     Removed o.a.c.generation.JXTemplateGenerator from core.
+     Introduced o.a.c.template.jxtg.JXTemplateGenerator as the official templating language.
+     New commands available: &lt;jx:call macro="${macroName"}/&gt;
+     and &lt;jx:attribute name="${attributeName}" value="${attributeValue}"/&gt;
+   </action>
+   <action dev="VG" type="remove">
+     Removed EventRecorder (in o.a.c.t.helpers package).
+   </action>
+   <action dev="AG" type="remove">
+     Removed deprecated Pizza compiler support in XSP.
+   </action>
+   <action dev="SW" type="add">
+     Each sitemap can now have its own classpath using <code>&lt;map:classpath&gt;</code>. This allows
+     sitemap-specific components to be deployed locally with the sitemap. Reloading the sitemap
+     recreates the classloader, thus allowing hot reloading of changed classes.
+   </action>
+   <action dev="LG" type="fix" fixes-bug="33836" due-to="Niklas Therning" due-to-email="niklas@trillian.se">
+     Fix thread safety problem in JXTemplateGenerator.setup() concerning template script reparsing.
+   </action>
+   <action dev="LG" type="add">
+     Polish i18n for CForms.
+   </action>
+   <action dev="CZ" type="update">
+     Create proxies for pooled components. Pooled components can now be used in the same
+     way as thread safe components, the client code does not need to know if they are pooled anymore.
+   </action>
+   <action dev="TC" type="add">
+     javaflow: updated to the API change,
+     lazy method lookups,
+     cleaner context handling,
+     for the moment removed the dependency to the form block
+   </action>
+   <action dev="JH" type="fix" fixes-bug="33097">
+     Fixed caching of i18n bundles when using multiple locations.
+   </action>
+   <action dev="SW" type="add">
+     Add an experimental lazy loading in the service manager that dramatically speeds up Cocoon init time
+     (approx 4 times faster). To use it, set JAVA_OPTIONS="-Dorg.apache.cocoon.core.LazyMode=true" prior
+     to starting "cocoon.sh servlet".
+   </action>
+   <action dev="SW" type="add">
+     Add an include feature to xconf files and xmap files, to allow an easier configuration of the system.
+     The main cocoon.xconf is now a list of inclusion of the main core components and a
+     separate xconf file for each block. Additional role files can also be included.
+   </action>
+   <action dev="VG" type="remove">
+     Flowscript: Removed support for passing sitemap parameters into flowscript
+     function as positional arguments. Use cocoon.parameters instead.
+   </action>
+   <action dev="RP" type="update" due-to="Igor Bukanov" fixes-bug="31649" due-to-email="igor@fastmail.fm">
+     Use official Rhino implementation which supports continuations since 1.6. For the most
+     flowscripts there shouldn't be any issues, though there are differences that may lead
+     to compatibility issues:
+     <ul>
+        <li>catch(return)</li>
+        <li>catch(continue)</li>
+        <li>catch(break)</li>
+     </ul>
+     aren't supported any more. catch(break) can be replaced by passing the function
+     to cocoon.sendPageAndWait([pipeline], [bizdata], [function], [time-to-live]).
+     <br/>
+     catch(return) and catch(continue) e.g.
+     <code>
+  var pool = ...;
+  function someFunction() {
+       var conn = pool.getConnection();
+       ...
+       catch (break) {
+     conn.close();
+     conn = null;
+       }
+       catch (continue) {
+     conn = pool.getConnection();
+       }
+  }
+     </code>
+     can be replaced by catching the ContinuationException:
+     <code>
+       var pool = ...;
+  function someFunction() {
+       var conn = null;
+       try {
+     if (conn == null) {
+         conn = pool.getConnection();
+     }
+     ...
+       } finally {
+     conn.close();
+     conn = null;
+       }
+  }
+     </code>
+   </action>
+   <action dev="ATC" type="remove">
+     Removed the PHP block.
+   </action>
+   <action dev="CZ" type="update">
+     Remove support for Excalibur instrumentation.
+   </action>
+   <action dev="CZ" type="update">
+     Component, Composable, ComponentManager, ComponentSelector and ComponentException
+     are no longer support: Serviceable, ServiceManager, ServiceSelector and ServiceException
+     have to be used.
+   </action>
+   <action dev="CZ" type="add">
+     Own implementation of Avalon based container.
+   </action>
+   <action dev="RP" type="add" due-to="Adam Ratclif" fixes-bug="31359">
+     Apply patch: Add support for calling webservices from within Flowscript.
+   </action>
+   <action dev="CZ" type="add">
+     New getSitemapPath() method on the Request object to get the path to the
+     current sitemap even if you are in a sub sitemap. Added an abstract request
+     wrapper class as well.
+   </action>
+   <action dev="CZ" type="add">
+     Add scoped request attributes (global/request).
+   </action>
+   <action dev="CZ" type="update">
+     Update to servlet specification 2.3.
+   </action>
+   <action dev="AG" type="update">
+     Deprecate methods implementsInterface(String, String),
+     implementsInterface(Class, Class), lastModified(Class)
+     and which(Class) in org.apache.cocoon.util.ClassUtils
+     These methods will be removed on the next version.
+   </action>
+   <action dev="SW" type="update">
+     Move the sitemap engine to Serviceable (in replacement of Composable) and remove
+     SitemapComponentSelector and OutputComponentSelector that were no more needed.
+   </action>
+   <action dev="CZ" type="add">
+     Add profiling/debugging API for the sitemap.
+   </action>
+   <action dev="CZ" type="add">
+     Add sitemap versioning support to tree processor and remove unused
+     support for other tree based languages.
+   </action>
+   <action dev="CZ" type="fix" fixes-bug="28686">
+     Correct redirect handling for internal redirects.
+   </action>
+   <action dev="TC" type="remove">
+     SWF block: Removed the deprecated block and added a flash sample in the
+     hello world section.
+   </action>
+   <action dev="AG" type="update">
+     Deprecated methods in class org.apache.cocoon.util.IOUtils
+     to be removed in Cocoon 2.3:
+     <ul>
+       <li>String baseName(String filename)</li>
+       <li>Object bytesToObject(byte[] bytes)</li>
+       <li>Object deserializeObject(File file)</li>
+       <li>String fileComponent(String filename)</li>
+       <li>byte[] objectToBytes(Object object)</li>
+       <li>String pathComponent(String filename)</li>
+       <li>void serializeObject(File file, Object object)</li>
+       <li>void serializeString(File file, String string)</li>
+       <li>void serializeString(File file, String string, String encoding)</li>
+     </ul>
+   </action>
+   <action dev="AG" type="update">
+     Deprecated class org.apache.cocoon.util.JavaArchiveFilter.
+     To be removed in Cocoon 2.3. Moved to the deprecated dir.
+   </action>
+   <action dev="CZ" type="update">
+     Redesign the internal environment handling (request processing) and moved
+     private classes into own packages.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated RequestLifecycleComponent and GlobalRequestLifecycleComponent.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated (2.0.x) caching system; only 2.1.x is supported.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated sitemap related components and classes.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated Store implementations. Excalibur Store/JCS are used instead.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated Parser and Entity Resolver. Excalibur XMLUtils is used instead.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated XSLT Processor. Excalibur XMLUtils is used instead.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated Source handling. Excalibur Sourceresolve is used instead.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated getOutputStream() method from Environment.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated methods from SimpleCharStream, Notifier,
+     AbstractComplementaryConfigurableAction, StringUtils. Remove deprecated
+     parser constant from Constants and remove deprecated class
+     DefaultsMetaModule.
+   </action>
+   <action dev="CZ" type="update">
+     Remove deprecated methods from XMLUtils, DOMUtil, DOMBuilder and SourceUtil.
+   </action>
+  </release>
+ </changes>
+
+</status>
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/ant b/non-releases/trunk_before_flattening/tools/bin/ant
new file mode 100644
index 0000000..cf336db
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/ant
@@ -0,0 +1,299 @@
+#! /bin/sh
+
+#   Copyright 2001-2005 The Apache Software Foundation
+#
+#   Licensed 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.
+
+# Extract launch and ant arguments, (see details below).
+ant_exec_args=
+no_config=false
+use_jikes_default=false
+ant_exec_debug=false
+show_help=false
+for arg in "$@" ; do
+  if [ "$arg" = "--noconfig" ] ; then
+    no_config=true
+  elif [ "$arg" = "--usejikes" ] ; then
+    use_jikes_default=true
+  elif [ "$arg" = "--execdebug" ] ; then
+    ant_exec_debug=true
+  elif [ my"$arg" = my"--h"  -o my"$arg" = my"--help"  ] ; then
+    show_help=true
+    ant_exec_args="$ant_exec_args -h"
+  else
+    if [  my"$arg" = my"-h"  -o  my"$arg" = my"-help" ] ; then
+      show_help=true
+    fi
+    ant_exec_args="$ant_exec_args \"$arg\""
+  fi
+done
+
+# Source/default ant configuration
+if $no_config ; then
+  rpm_mode=false
+  usejikes=$use_jikes_default
+else
+  # load system-wide ant configuration
+  if [ -f "/etc/ant.conf" ] ; then
+    . /etc/ant.conf
+  fi
+
+  # load user ant configuration
+  if [ -f "$HOME/.ant/ant.conf" ] ; then
+    . $HOME/.ant/ant.conf
+  fi
+  if [ -f "$HOME/.antrc" ] ; then
+    . "$HOME/.antrc"
+  fi
+
+  # provide default configuration values
+  if [ -z "$rpm_mode" ] ; then
+    rpm_mode=false
+  fi
+  if [ -z "$usejikes" ] ; then
+    usejikes=$use_jikes_default
+  fi
+fi
+
+# Setup Java environment in rpm mode
+if $rpm_mode ; then
+  if [ -f /usr/share/java-utils/java-functions ] ; then
+    . /usr/share/java-utils/java-functions
+    set_jvm
+    set_javacmd
+  fi
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  Darwin*) darwin=true
+           if [ -z "$JAVA_HOME" ] ; then
+             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
+           fi
+           ;;
+esac
+
+if [ -z "$ANT_HOME" -o ! -d "$ANT_HOME" ] ; then
+  ## resolve links - $0 may be a link to ant's home
+  PRG="$0"
+  progname=`basename "$0"`
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+    PRG="$link"
+    else
+    PRG=`dirname "$PRG"`"/$link"
+    fi
+  done
+
+  ANT_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  ANT_HOME=`cd "$ANT_HOME" && pwd`
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$ANT_HOME" ] &&
+    ANT_HOME=`cygpath --unix "$ANT_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# set ANT_LIB location
+ANT_LIB="${ANT_HOME}/lib"
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD=`which java 2> /dev/null `
+    if [ -z "$JAVACMD" ] ; then
+        JAVACMD=java
+    fi
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly."
+  echo "  We cannot execute $JAVACMD"
+  exit 1
+fi
+
+# Build local classpath using just the launcher in non-rpm mode or
+# use the Jpackage helper in rpm mode with basic and default jars
+# specified in the ant.conf configuration. Because the launcher is
+# used, libraries linked in ANT_HOME will also be include, but this
+# is discouraged as it is not java-version safe. A user should
+# request optional jars and their dependencies via the OPT_JAR_LIST
+# variable
+if $rpm_mode && [ -f /usr/bin/build-classpath ] ; then
+  LOCALCLASSPATH="$(/usr/bin/build-classpath ant ant-launcher jaxp_parser_impl xml-commons-apis)"
+  # If the user requested to try to add some other jars to the classpath
+  if [ -n "$OPT_JAR_LIST" ] ; then
+    _OPTCLASSPATH="$(/usr/bin/build-classpath $OPT_JAR_LIST 2> /dev/null)"
+    if [ -n "$_OPTCLASSPATH" ] ; then 
+      LOCALCLASSPATH="$LOCALCLASSPATH:$_OPTCLASSPATH"
+    fi
+  fi
+
+  # Explicitly add javac path to classpath, assume JAVA_HOME set
+  # properly in rpm mode
+  if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then
+    LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar"
+  fi
+  if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then
+    LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip"
+  fi
+
+  # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be
+  # user CLASSPATH first and ant-found jars after.
+  # In that case, the user CLASSPATH will override ant-found jars
+  #
+  # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour
+  # with ant-found jars first and user CLASSPATH after
+  if [ -n "$CLASSPATH" ] ; then
+    # merge local and specified classpath 
+    if [ -z "$LOCALCLASSPATH" ] ; then 
+      LOCALCLASSPATH="$CLASSPATH"
+    elif [ -n "$CLASSPATH_OVERRIDE" ] ; then
+      LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH"
+    else
+      LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH"
+    fi
+
+    # remove class path from launcher -cp option
+    CLASSPATH=""
+  fi
+else
+  # not using rpm_mode; use launcher to determine classpaths
+  if [ -z "$LOCALCLASSPATH" ] ; then
+      LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar
+  else
+      LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar:$LOCALCLASSPATH
+  fi
+fi
+
+if [ -n "$JAVA_HOME" ] ; then
+  # OSX hack to make Ant work with jikes
+  if $darwin ; then
+    OSXHACK="${JAVA_HOME}/../Classes"
+    if [ -d "${OSXHACK}" ] ; then
+      for i in "${OSXHACK}"/*.jar
+      do
+        JIKESPATH="$JIKESPATH:$i"
+      done
+    fi
+  fi
+fi
+
+# Allow Jikes support (off by default)
+if $usejikes; then
+  ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes"
+fi
+
+# For Cygwin, switch paths to appropriate format before running java
+# For PATHs convert to unix format first, then to windows format to ensure
+# both formats are supported. Probably this will fail on directories with ;
+# in the name in the path. Let's assume that paths containing ; are more
+# rare than windows style paths on cygwin.
+if $cygwin; then
+  if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then
+    format=mixed
+  else
+    format=windows
+  fi
+  ANT_HOME=`cygpath --$format "$ANT_HOME"`
+  ANT_LIB=`cygpath --$format "$ANT_LIB"`
+  JAVA_HOME=`cygpath --$format "$JAVA_HOME"`
+  LCP_TEMP=`cygpath --path --unix "$LOCALCLASSPATH"`
+  LOCALCLASSPATH=`cygpath --path --$format "$LCP_TEMP"`
+  if [ -n "$CLASSPATH" ] ; then
+    CP_TEMP=`cygpath --path --unix "$CLASSPATH"`
+    CLASSPATH=`cygpath --path --$format "$CP_TEMP"`
+  fi
+  CYGHOME=`cygpath --$format "$HOME"`
+fi
+
+# Show script help if requested
+if $show_help ; then
+  echo $0 '[script options] [options] [target [target2 [target3] ..]]'
+  echo 'Script Options:'
+  echo '  --help, --h            print this message and ant help'
+  echo '  --noconfig             suppress sourcing of /etc/ant.conf,'
+  echo '                         $HOME/.ant/ant.conf, and $HOME/.antrc'
+  echo '                         configuration files'
+  echo '  --usejikes             enable use of jikes by default, unless'
+  echo '                         set explicitly in configuration files'
+  echo '  --execdebug            print ant exec line generated by this'
+  echo '                         launch script'
+  echo '  '
+fi
+# add a second backslash to variables terminated by a backslash under cygwin
+if $cygwin; then
+  case "$ANT_HOME" in
+    *\\ )
+    ANT_HOME="$ANT_HOME\\"
+    ;;
+  esac
+  case "$CYGHOME" in
+    *\\ )
+    CYGHOME="$CYGHOME\\"
+    ;;
+  esac
+  case "$JIKESPATH" in
+    *\\ )
+    JIKESPATH="$JIKESPATH\\"
+    ;;
+  esac
+  case "$LOCALCLASSPATH" in
+    *\\ )
+    LOCALCLASSPATH="$LOCALCLASSPATH\\"
+    ;;
+  esac
+  case "$CLASSPATH" in
+    *\\ )
+    CLASSPATH="$CLASSPATH\\"
+    ;;
+  esac
+fi
+# Execute ant using eval/exec to preserve spaces in paths,
+# java options, and ant args
+ant_sys_opts=
+if [ -n "$CYGHOME" ]; then
+  if [ -n "$JIKESPATH" ]; then
+    ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\" -Dcygwin.user.home=\"$CYGHOME\""
+  else
+    ant_sys_opts="-Dcygwin.user.home=\"$CYGHOME\""
+  fi
+else
+  if [ -n "$JIKESPATH" ]; then
+    ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\""
+  fi
+fi
+ant_exec_command="exec \"$JAVACMD\" $ANT_OPTS -classpath \"$LOCALCLASSPATH\" -Dant.home=\"$ANT_HOME\" -Dant.library.dir=\"$ANT_LIB\" $ant_sys_opts org.apache.tools.ant.launch.Launcher $ANT_ARGS -cp \"$CLASSPATH\" $ant_exec_args"
+if $ant_exec_debug ; then
+    echo $ant_exec_command
+fi
+eval $ant_exec_command
diff --git a/non-releases/trunk_before_flattening/tools/bin/ant.bat b/non-releases/trunk_before_flattening/tools/bin/ant.bat
new file mode 100755
index 0000000..e2dafab
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/ant.bat
@@ -0,0 +1,126 @@
+@echo off
+
+REM  Copyright 2001,2004-2005 The Apache Software Foundation
+REM
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM
+REM      http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+
+if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat"
+
+if "%OS%"=="Windows_NT" @setlocal
+if "%OS%"=="WINNT" @setlocal
+
+rem %~dp0 is expanded pathname of the current script under NT
+set DEFAULT_ANT_HOME=%~dp0..
+
+if "%ANT_HOME%"=="" set ANT_HOME=%DEFAULT_ANT_HOME%
+set DEFAULT_ANT_HOME=
+
+set _USE_CLASSPATH=yes
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of arguments (up to the command line limit, anyway).
+set ANT_CMD_LINE_ARGS=%1
+if ""%1""=="""" goto doneStart
+shift
+:setupArgs
+if ""%1""=="""" goto doneStart
+if ""%1""==""-noclasspath"" goto clearclasspath
+set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
+shift
+goto setupArgs
+
+rem here is there is a -noclasspath in the options
+:clearclasspath
+set _USE_CLASSPATH=no
+shift
+goto setupArgs
+
+rem This label provides a place for the argument list loop to break out
+rem and for NT handling to skip to.
+
+:doneStart
+rem find ANT_HOME if it does not exist due to either an invalid value passed
+rem by the user or the %0 problem on Windows 9x
+if exist "%ANT_HOME%\lib\ant.jar" goto checkJava
+
+rem check for ant in Program Files
+if not exist "%ProgramFiles%\ant" goto checkSystemDrive
+set ANT_HOME=%ProgramFiles%\ant
+goto checkJava
+
+:checkSystemDrive
+rem check for ant in root directory of system drive
+if not exist %SystemDrive%\ant\lib\ant.jar goto checkCDrive
+set ANT_HOME=%SystemDrive%\ant
+goto checkJava
+
+:checkCDrive
+rem check for ant in C:\ant for Win9X users
+if not exist C:\ant\lib\ant.jar goto noAntHome
+set ANT_HOME=C:\ant
+goto checkJava
+
+:noAntHome
+echo ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME.
+goto end
+
+:checkJava
+set _JAVACMD=%JAVACMD%
+
+if "%JAVA_HOME%" == "" goto noJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe
+goto checkJikes
+
+:noJavaHome
+if "%_JAVACMD%" == "" set _JAVACMD=java.exe
+
+:checkJikes
+if not "%JIKESPATH%"=="" goto runAntWithJikes
+
+:runAnt
+if "%_USE_CLASSPATH%"=="no" goto runAntNoClasspath
+if not "%CLASSPATH%"=="" goto runAntWithClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
+goto end
+
+:runAntNoClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
+goto end
+
+:runAntWithClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
+goto end
+
+:runAntWithJikes
+if "%_USE_CLASSPATH%"=="no" goto runAntWithJikesNoClasspath
+if not "%CLASSPATH%"=="" goto runAntWithJikesAndClasspath
+
+:runAntWithJikesNoClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
+goto end
+
+:runAntWithJikesAndClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS%  -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
+goto end
+
+:end
+set _JAVACMD=
+set ANT_CMD_LINE_ARGS=
+
+if "%OS%"=="Windows_NT" @endlocal
+if "%OS%"=="WINNT" @endlocal
+
+:mainEnd
+if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat"
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/ant.cmd b/non-releases/trunk_before_flattening/tools/bin/ant.cmd
new file mode 100644
index 0000000..4bb903f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/ant.cmd
@@ -0,0 +1,92 @@
+/* 
+    Copyright 2003-2004 The Apache Software Foundation
+  
+    Licensed 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.
+ 
+    Run ant
+*/
+
+'@echo off'
+parse arg mode envarg '::' antarg
+
+if mode\='.' & mode\='..' & mode\='/' then do
+  envarg = mode envarg
+  mode = ''
+end
+
+if antarg = '' then do
+  antarg = envarg
+  envarg = ''
+end
+
+x = setlocal()
+
+env="OS2ENVIRONMENT"
+antenv = _getenv_('antenv')
+if _testenv_() = 0 then interpret 'call "' || antenv || '"' '"' || envarg || '"'
+
+if mode = '' then mode = _getenv_('ANT_MODE' '..')
+if mode \= '/' then do
+  runrc = _getenv_('runrc')
+  antrc = _getenv_('antrc' 'antrc.cmd')
+  if mode = '..' then mode = '-r'
+  else mode = ''
+  interpret 'call "' || runrc || '"' antrc '"' || mode || '"'
+end
+
+if _testenv_() = 0 then do
+  say 'Ant environment is not set properly'
+  x = endlocal()
+  exit 16
+end
+
+settings = '-Dant.home=' || ANT_HOME '-Djava.home=' || JAVA_HOME
+
+java = _getenv_('javacmd' 'java')
+opts = value('ANT_OPTS',,env)
+args = value('ANT_ARGS',,env)
+lcp = value('LOCALCLASSPATH',,env)
+cp = value('CLASSPATH',,env)
+if value('ANT_USE_CP',,env) \= '' then do
+  if lcp \= '' & right(lcp, 1) \= ';' then lcp = lcp || ';'
+  lcp = lcp || cp
+  'SET CLASSPATH='
+end
+if lcp\='' then lcp = '-classpath' lcp
+
+cmd = java opts lcp '-jar' ANT_HOME ||'\lib\ant-launcher.jar' settings args antarg
+launcher = stream(ANT_HOME ||'\lib\ant-launcher.jar', 'C', 'query exists')
+if launcher = '' then entry = 'org.apache.tools.ant.Main'
+else entry = 'org.apache.tools.ant.launch.Launcher'
+java opts lcp entry settings args antarg
+
+x = endlocal()
+
+return rc
+
+_testenv_: procedure expose env ANT_HOME JAVA_HOME
+ANT_HOME = value('ANT_HOME',,env)
+if ANT_HOME = '' then return 0
+JAVA_HOME = value('JAVA_HOME',,env)
+if JAVA_HOME = '' then return 0
+cp = translate(value('CLASSPATH',,env))
+if pos(translate(ANT_HOME), cp) = 0 then return 0
+if pos(translate(JAVA_HOME), cp) = 0 then return 0
+return 1
+
+_getenv_: procedure expose env
+parse arg envar default
+if default = '' then default = envar
+var = value(translate(envar),,env)
+if var = '' then var = default
+return var
diff --git a/non-releases/trunk_before_flattening/tools/bin/antRun b/non-releases/trunk_before_flattening/tools/bin/antRun
new file mode 100644
index 0000000..baddd71
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/antRun
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+#
+#  Copyright  2001-2002,2004 The Apache Software Foundation
+# 
+#   Licensed 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.
+# 
+#
+
+# Args: DIR command
+cd "$1"
+CMD="$2"
+shift
+shift
+
+exec "$CMD" "$@"
diff --git a/non-releases/trunk_before_flattening/tools/bin/antRun.bat b/non-releases/trunk_before_flattening/tools/bin/antRun.bat
new file mode 100755
index 0000000..289e19b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/antRun.bat
@@ -0,0 +1,47 @@
+@echo off
+
+REM
+REM Copyright  2001-2002,2004-2005 The Apache Software Foundation
+REM
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM
+REM      http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+REM
+REM
+
+if "%OS%"=="Windows_NT" @setlocal
+if "%OS%"=="WINNT" @setlocal
+
+if ""%1""=="""" goto runCommand
+
+rem Change drive and directory to %1
+if "%OS%"=="Windows_NT" cd /d ""%1""
+if not "%OS%"=="Windows_NT" cd ""%1""
+shift
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of agruments (up to the command line limit, anyway).
+set ANT_RUN_CMD=%1
+if ""%1""=="""" goto runCommand
+shift
+:loop
+if ""%1""=="""" goto runCommand
+set ANT_RUN_CMD=%ANT_RUN_CMD% %1
+shift
+goto loop
+
+:runCommand
+rem echo %ANT_RUN_CMD%
+%ANT_RUN_CMD%
+
+if "%OS%"=="Windows_NT" @endlocal
+if "%OS%"=="WINNT" @endlocal
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/antRun.pl b/non-releases/trunk_before_flattening/tools/bin/antRun.pl
new file mode 100644
index 0000000..7cdd868
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/antRun.pl
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+#
+# Copyright 2001,2003-2004 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+#######################################################################
+#
+# antRun.pl
+#
+# wrapper script for invoking commands on a platform with Perl installed
+# this is akin to antRun.bat, and antRun the SH script 
+#
+# created:         2001-10-18
+# author:          Jeff Tulley jtulley@novell.com 
+#######################################################################
+#be fussy about variables
+use strict;
+
+#turn warnings on during dev; generates a few spurious uninitialised var access warnings
+#use warnings;
+
+#and set $debug to 1 to turn on trace info (currently unused)
+my $debug=1;
+
+#######################################################################
+# change drive and directory to "%1"
+my $ANT_RUN_CMD = @ARGV[0];
+
+# assign current run command to "%2"
+chdir (@ARGV[0]) || die "Can't cd to $ARGV[0]: $!\n";
+if ($^O eq "NetWare") {
+    # There is a bug in Perl 5 on NetWare, where chdir does not
+    # do anything.  On NetWare, the following path-prefixed form should 
+    # always work. (afaict)
+    $ANT_RUN_CMD .= "/".@ARGV[1];
+}
+else {
+    $ANT_RUN_CMD = @ARGV[1];
+}
+
+# dispose of the first two arguments, leaving only the command's args.
+shift;
+shift;
+
+# run the command
+my $returnValue = system $ANT_RUN_CMD, @ARGV;
+if ($returnValue eq 0) {
+    exit 0;
+}
+else {
+    # only 0 and 1 are widely recognized as exit values
+    # so change the exit value to 1
+    exit 1;
+}
diff --git a/non-releases/trunk_before_flattening/tools/bin/antenv.cmd b/non-releases/trunk_before_flattening/tools/bin/antenv.cmd
new file mode 100644
index 0000000..b9b0db4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/antenv.cmd
@@ -0,0 +1,99 @@
+/* 
+    Copyright 2003-2004 The Apache Software Foundation
+  
+    Licensed 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.
+
+    Ant environment
+*/
+
+'@echo off'
+call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
+call SysLoadFuncs
+
+/* Prepare the parameters for later use */
+parse arg argv
+mode = ''
+args = ''
+opts = ''
+cp = ''
+lcp = ''
+
+do i = 1 to words(argv)
+  param = word(argv, i)
+  select
+    when param='-lcp' then mode = 'l'
+    when param='-cp' | param='-classpath' then mode = 'c'
+    when abbrev('-opts', param, 4) then mode = 'o'
+    when abbrev('-args', param, 4) then mode = 'a'
+  otherwise
+    select
+      when mode = 'a' then args = space(args param, 1)
+      when mode = 'c' then cp = space(cp param, 1)
+      when mode = 'l' then lcp = space(lcp param, 1)
+      when mode = 'o' then opts = space(opts param, 1)
+    otherwise
+      say 'Option' param 'ignored'
+    end
+  end
+end
+
+env="OS2ENVIRONMENT"
+antconf = _getenv_('antconf' 'antconf.cmd')
+runrc = _getenv_('runrc')
+interpret 'call "' || runrc || '"' '"' || antconf || '"' 'ETC'
+ANT_HOME = value('ANT_HOME',,env)
+JAVA_HOME = value('JAVA_HOME',,env)
+classpath = value('CLASSPATH',,env)
+classes = stream(JAVA_HOME || "\lib\classes.zip", "C", "QUERY EXISTS")
+if classes \= '' then classpath = prepend(classpath classes)
+classes = stream(JAVA_HOME || "\lib\tools.jar", "C", "QUERY EXISTS")
+if classes \= '' then classpath = prepend(classpath classes)
+
+classpath = prepend(classpath ANT_HOME || '\lib\ant-launcher.jar')
+'SET CLASSPATH=' || classpath
+
+/* Setting classpathes, options and arguments */
+envset = _getenv_('envset')
+if cp\=''   then interpret 'call "' || envset || '"' '"; CLASSPATH"' '"' || cp || '"'
+if lcp\=''  then interpret 'call "' || envset || '"' '"; LOCALCLASSPATH"' '"' || lcp || '"'
+if opts\='' then interpret 'call "' || envset || '"' '"-D ANT_OPTS"' '"' || opts || '"'
+if args\='' then interpret 'call "' || envset || '"' '"ANT_ARGS"' '"' || args || '"'
+
+exit 0
+
+addpath: procedure
+parse arg path elem
+if elem = '' then do
+  if path\='' & right(path, 1)\=';' then path = path || ';'
+  return path
+end
+if substr(path, length(path)) = ';' then glue = ''
+else glue = ';'
+if pos(translate(elem), translate(path)) = 0 then path = path || glue || elem || ';'
+return path
+
+prepend: procedure
+parse arg path elem
+if elem = '' then do
+  if path\='' & right(path, 1)\=';' then path = path || ';'
+  return path
+end
+if pos(translate(elem), translate(path)) = 0 then path = elem || ';' || path
+return path
+
+_getenv_: procedure expose env
+parse arg envar default
+if default = '' then default = envar
+var = value(translate(envar),,env)
+if var = '' then var = default
+return var
diff --git a/non-releases/trunk_before_flattening/tools/bin/appendcp.bat b/non-releases/trunk_before_flattening/tools/bin/appendcp.bat
new file mode 100644
index 0000000..4a729d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/appendcp.bat
@@ -0,0 +1,16 @@
+rem  Copyright 1999-2004 The Apache Software Foundation
+rem
+rem  Licensed under the Apache License, Version 2.0 (the "License");
+rem  you may not use this file except in compliance with the License.
+rem  You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem  Unless required by applicable law or agreed to in writing, software
+rem  distributed under the License is distributed on an "AS IS" BASIS,
+rem  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem  See the License for the specific language governing permissions and
+rem  limitations under the License.
+
+set CLASSPATH=%CLASSPATH%;%1
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/complete-ant-cmd.pl b/non-releases/trunk_before_flattening/tools/bin/complete-ant-cmd.pl
new file mode 100644
index 0000000..20dd476
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/complete-ant-cmd.pl
@@ -0,0 +1,113 @@
+#!/usr/bin/perl
+#
+# Copyright 2001,2004 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+# A script to allow Bash or Z-Shell to complete an Ant command-line.  
+#
+# To install for Bash 2.0 or better, add the following to ~/.bashrc:
+# 
+#     $ complete -C complete-ant-cmd ant build.sh
+#
+# To install for Z-Shell 2.5 or better, add the following to ~/.zshrc:
+#
+#     function ant_complete () {
+#         local args_line args
+#         read -l args_line
+#         set -A args $args_line
+#         set -A reply $(COMP_LINE=$args_line complete-ant-cmd ${args[1]} $1)
+#     }
+#     compctl -K ant_complete ant build.sh
+#     
+# @author Mike Williams <mikew@cortexebusiness.com.au>
+
+my $cmdLine = $ENV{'COMP_LINE'};
+my $antCmd = $ARGV[0];
+my $word = $ARGV[1];
+
+my @completions;
+if ($word =~ /^-/) {
+    list( restrict( $word, getArguments() ));
+} elsif ($cmdLine =~ /-(f|buildfile)\s+\S*$/) {
+    list( getBuildFiles($word) );
+} else {
+    list( restrict( $word, getTargets() ));
+}
+
+exit(0);
+
+sub list {
+    for (@_) {
+        print "$_\n";
+    }
+}
+
+sub restrict {
+    my ($word, @completions) = @_;
+    grep( /^\Q$word\E/, @completions );
+}
+
+sub getArguments {
+    qw(-buildfile -debug -emacs -f -find -help -listener -logfile 
+       -logger -projecthelp -quiet -verbose -version); 
+}
+
+
+sub getBuildFiles {
+    my ($word) = @_;
+    grep( /\.xml$/, glob( "$word*" ));
+}
+
+sub getTargets {
+
+    # Look for build-file
+    my $buildFile = 'build.xml';
+    if ($cmdLine =~ /-(f|buildfile)\s+(\S+)/) {
+        $buildFile = $2;
+    }
+    return () unless (-f $buildFile);
+
+    # Run "ant -projecthelp" to list targets.  Keep a cache of results in a
+    # cache-file.
+    my $cacheFile = $buildFile;
+    $cacheFile =~ s|(.*/)?(.*)|${1}.ant-targets-${2}|;
+    if ((!-e $cacheFile) || (-M $buildFile) < (-M $cacheFile)) {
+        open( CACHE, '>'.$cacheFile ) || die "can\'t write $cacheFile: $!\n";
+        open( HELP, "$antCmd -projecthelp -f '$buildFile'|" ) || return(); 
+        my %targets;
+        while( <HELP> ) {
+            if (/^\s+(\S+)/) {
+                $targets{$1}++;
+            }
+        }
+        my @targets = sort keys %targets;
+        for (@targets) { print CACHE "$_\n"; }
+        return @targets;
+    }
+    
+    # Read the target-cache
+    open( CACHE, $cacheFile ) || die "can\'t read $cacheFile: $!\n";
+    my @targets;
+    while (<CACHE>) {
+        chop;
+        s/\r$//;  # for Cygwin
+        push( @targets, $_ );
+    }
+    close( CACHE );
+    @targets;
+
+}
+
+
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/create-repository-jars.sh b/non-releases/trunk_before_flattening/tools/bin/create-repository-jars.sh
new file mode 100644
index 0000000..1da2d0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/create-repository-jars.sh
@@ -0,0 +1,332 @@
+#!/bin/sh 
+
+# Copyright 2004-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+
+# $Id$
+
+# This script will do the following:
+#   - checkout/update a cocoon-2.1 repository
+#   - make a local.build.properties, that excludes all documentation stuff
+#   - build all jars and the war file
+#   - copy all jars and the war to the appropriate locations (repository structure)
+#
+# Usually one start the script in the Cocoon root directory by issuing:
+#
+#     ./tools/bin/create-repository-jars.sh tags/RELEASE_2_1_x
+#
+# The-h option will give you a short usage note and the settings of environment 
+# variables the script uses
+#
+
+# The path to the local repository we maintain
+if [ "$LOCAL_PATH" = "" ]; then
+  LOCAL_PATH="$PWD"
+fi
+
+# The base URL to the SVN repository
+if [ "$SVN_BASE_URL" = "" ]; then
+  SVN_BASE_URL=https://svn.apache.org/repos/asf/cocoon
+fi
+
+# On which host should the artifacts be published
+if [ "$REMOTE_HOST" = "" ]; then
+  REMOTE_HOST=svn.apache.org
+fi
+
+# The path to the remote repository
+if [ "$REMOTE_PATH" = "" ]; then
+  REMOTE_PATH=/www/www.apache.org/dist/java-repository/cocoon
+fi
+
+# The SVN URL part indicating the HEAD of development
+if [ "$HEAD_SUB_URL" = "" ]; then
+  HEAD_SUB_URL=trunk
+fi
+
+# The SVN URL part pointing to the revision/branch/tag to use
+if [ "$REVISION_SUB_URL" = "" ]; then
+  REVISION_SUB_URL=$HEAD_SUB_URL
+fi
+
+# The MD5 sum utility
+if [ "$MD5SUM" = "" ]; then
+  MD5SUM=/sbin/md5
+fi
+
+# ------- NO NEED TO CHANGE ANYTHING BELOW HERE ----------
+
+if [ "$JAVA_HOME" = "" ]; then
+  echo "You need to set the JAVA_HOME environment variable to the installed JDK 1.3"
+  exit 1
+fi
+
+$JAVA_HOME/bin/java -version
+
+# parse for options
+NOSVN=0
+NOBUILD=0
+NOCLEAN=0
+NOJARS=0
+NOWAR=0
+BUILD_SRC_DIST=0
+RC=0
+while getopts ":BdhJkSW" option
+do
+  case $option in
+    B) NOBUILD=1;;
+    d) BUILD_SRC_DIST=1;;
+    h) echo "Usage: `basename $0` options [-S] [-B] [-h] [TAG-Path]"
+       echo "       -S          don't do a svn update"
+       echo "       -B          don't do a build"
+       echo "       -d          build a src dist"
+       echo "       -h          this usage note"
+       echo "       -J          don't deploy the jar files"
+       echo "       -k          keep the build tree (don't do a clean-dist)"
+       echo "       -W          don't deploy the war file"
+       echo "       TAG-Path    the path to do a svn Tag or Branch from (excluding the base url)"
+       echo "                   if the TAG-Path equals to HEAD a snapshot version"
+       echo "                   will be produced"
+       echo 
+       echo "   Settings:"
+       echo "      LOCAL_PATH:       $LOCAL_PATH"
+       echo "      SVN_BASE_URL:     $SVN_BASE_URL"
+       echo "      REMOTE_PATH:      $REMOTE_PATH"
+       echo "      HEAD_SUB_URL:     $HEAD_SUB_URL"
+       echo "      REVISION_SUB_URL: $REVISION_SUB_URL"
+       echo "      MD5SUM:           $MD5SUM"
+       echo "      JAVA_HOME:        $JAVA_HOME"
+       exit 0
+       ;;
+    J) NOJARS=1;;
+    k) NOCLEAN=1;;
+    S) NOSVN=1;;
+    W) NOWAR=1;;
+    *     ) echo "Unimplemented option $option chosen.";;
+  esac
+done
+shift $(($OPTIND - 1))
+
+# check if a different revision/branch/tag was specified on the command line
+if [ ! -z "$1" ]; then
+  REVISION_SUB_URL=$1
+fi
+
+# check if the local repository exists and do a checkout/update accordingly
+if [ -d "$LOCAL_PATH" -a -d "$LOCAL_PATH/.svn" ]; then
+  cd $LOCAL_PATH
+  if [ $NOSVN = 0 ]; then
+    echo
+    echo "updating the local repository at $LOCAL_PATH with"
+    echo "    svn switch ${SVN_BASE_URL}/$REVISION_SUB_URL"
+    echo
+    svn switch ${SVN_BASE_URL}/$REVISION_SUB_URL
+  fi
+elif  [ -d "$LOCAL_PATH" ]; then
+  cd $LOCAL_PATH
+  echo
+  echo "checking out into the local repository at $LOCAL_PATH with "
+  echo "    svn co ${SVN_BASE_URL}/$REVISION_SUB_URL $LOCAL_PATH"
+  echo
+  svn co ${SVN_BASE_URL}/$REVISION_SUB_URL $LOCAL_PATH
+else
+  DIRNAME=`dirname $LOCAL_PATH`
+  BASENAME=`basename $LOCAL_PATH`
+  if [ ! -d $DIRNAME ]; then
+    mkdir -p $DIRNAME 2>/dev/null >/dev/null
+  fi
+  cd $DIRNAME 
+  echo
+  echo "checking out into the local repository at $LOCAL_PATH with "
+  echo "    svn co ${SVN_BASE_URL}/$REVISION_SUB_URL $BASENAME"
+  echo
+  svn co ${SVN_BASE_URL}/$REVISION_SUB_URL $BASENAME
+  cd $LOCAL_PATH
+fi
+
+# cleanup the repository, prepare and do a build if not suppressed by command line option
+if [ "$NOBUILD" -eq 0 ]; then
+  echo
+  echo "clean the local repository"
+  echo
+  ./build.sh clean-dist 
+  find . -type f -name "*~" | xargs rm -f 2>/dev/null 1>/dev/null
+  find . -type f -name ".#*" | xargs rm -f 2>/dev/null 1>/dev/null
+  find . -type f -name "#*#" | xargs rm -f 2>/dev/null 1>/dev/null
+  find . -type f -name "*.bak" | xargs rm -f 2>/dev/null 1>/dev/null
+  find . -type f -name "*.BAK" | xargs rm -f 2>/dev/null 1>/dev/null
+
+  # build the blocks.properties file
+  echo
+  echo "generating local.blocks.properties file"
+  echo
+  cat blocks.properties \
+    >local.blocks.properties
+
+  # build the build.properties file
+  echo
+  echo "generating local.build.properties file"
+  echo
+  cat build.properties \
+    | sed 's/#exclude.webapp.documentation/exclude.webapp.documentation/' \
+    | sed 's/#exclude.webapp.javadocs/exclude.webapp.javadocs/' \
+    | sed 's/#exclude.webapp.samples/exclude.webapp.samples/' \
+    | sed 's/#exclude.webapp.test-suite/exclude.webapp.test-suite/' \
+    | sed 's/#exclude.documentation/exclude.documentation/' \
+    | sed 's/#exclude.javadocs/exclude.javadocs/' \
+    | sed 's/#config.allow-reloads/config.allow-reloads/' \
+    | sed 's/#config.enable-uploads/config.enable-uploads/' \
+    | sed 's/#exclude.validate.config/exclude.validate.config/' \
+    | sed 's/#exclude.validate.xdocs/exclude.validate.xdocs/' \
+    | sed 's/#exclude.validate.jars/exclude.validate.jars/' \
+    >local.build.properties
+
+  # build everything
+  echo
+  if [ $NOCLEAN = 0 ]; then
+    echo "clean the local repository, build the webapp, and the war files"
+    CLEAN=clean-dist
+  else
+    echo "build the webapp, and the war files"
+    CLEAN=""
+  fi
+  echo
+  ./build.sh $CLEAN webapp war | tee $LOCAL_PATH/build.log
+  # The build script dosn't report on failures so we have to do that by hand
+  tail -n 10 $LOCAL_PATH/build.log|grep "BUILD SUCCESSFUL"
+  if [ $? = 0 ]; then
+    RC=0
+  else
+    RC=1
+  fi
+fi
+
+if [ $RC -ne 0 ]; then
+  echo "The build has failed"
+  exit $RC
+fi
+
+# copy all the jars produced over to the web server space
+VERSION=`ls build | grep cocoon | sed s/cocoon-//`
+if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then 
+  TVERSION=`date "+%Y%m%d.%H%M%S"` 
+else
+  TVERSION=$VERSION
+fi
+
+if [ $NOJARS = 0 ]; then
+  # create the target directory if they do not exists and make them group writable
+  ssh $REMOTE_HOST "mkdir -p $REMOTE_PATH/jars 2>/dev/null >/dev/null; \
+                 chmod -R g+w $REMOTE_PATH/jars"
+  JARS=`find build/cocoon-$VERSION -name "*.jar"`
+  for i in $JARS; do
+    FILE=`echo $i | sed 's/.*[/]//' | sed s/[.]jar//`
+    isBlock=`echo $FILE|grep block`
+    if [ ! -z "$isBlock" ]; then
+      BLOCKPART="-`echo $FILE | sed 's/-block//'`"
+    else
+      BLOCKPART=`echo $FILE | sed 's/cocoon//'`
+    fi
+    if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then
+      # remove all snapshots in the remote repository
+      SNAPSHOT=`ssh $REMOTE_HOST "ls $REMOTE_PATH/jars/cocoon$BLOCKPART-????????.??????.jar 2>/dev/null"` 
+    fi
+    scp $i $REMOTE_HOST:$REMOTE_PATH/jars/cocoon$BLOCKPART-$TVERSION.jar
+    if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then
+      if [ ! -z "$SNAPSHOT" ]; then
+        RM="rm ${SNAPSHOT}\*;\
+	    rm $REMOTE_PATH/jars/cocoon$BLOCKPART-snapshot.version;"
+      else
+        RM=""
+      fi
+      CMD="$RM \
+           cd $REMOTE_PATH/jars; \
+           rm cocoon$BLOCKPART-SNAPSHOT.jar; \
+           ln -s cocoon$BLOCKPART-$TVERSION.jar cocoon$BLOCKPART-SNAPSHOT.jar; \
+           echo $TVERSION >cocoon$BLOCKPART-snapshot.version;"
+    else
+      CMD=""
+    fi
+    ssh $REMOTE_HOST "$CMD \
+                      $MD5SUM <$REMOTE_PATH/jars/cocoon$BLOCKPART-$TVERSION.jar | \
+                      sed 's/ .*$//' >$REMOTE_PATH/jars/cocoon$BLOCKPART-$TVERSION.jar.md5; \
+                      chmod g+w $REMOTE_PATH/jars/cocoon$BLOCKPART-$TVERSION.*"
+  done
+fi
+
+# copy the war file to the web space
+if [ "$NOWAR" = "0" ]; then
+  # create the target directory if they do not exists and make them group writable
+  ssh $REMOTE_HOST "mkdir -p $REMOTE_PATH/wars 2>/dev/null >/dev/null; \
+                   chmod -R g+w $REMOTE_PATH/wars"
+  WAR=build/cocoon-$VERSION/cocoon.war
+  if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then
+    SNAPSHOT=`ssh $REMOTE_HOST "ls $REMOTE_PATH/wars/cocoon-war-????????.??????.war 2>/dev/null"` 
+  fi
+  scp $WAR $REMOTE_HOST:$REMOTE_PATH/wars/cocoon-war-$TVERSION.war
+  if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then
+    if [ ! -z "$SNAPSHOT" ]; then
+      RM="rm ${SNAPSHOT}\*;\
+          rm $REMOTE_PATH/wars/cocoon-war-snapshot.version;"
+    else
+      RM=""
+    fi
+    CMD="$RM \
+         cd $REMOTE_PATH/wars; \
+         rm cocoon$BLOCKPART-SNAPSHOT.war; \
+         ln -s cocoon-war-$TVERSION.war cocoon-war-SNAPSHOT.war; \
+         echo $TVERSION >cocoon-war-snapshot.version;"
+  else
+    CMD=""
+  fi
+  ssh $REMOTE_HOST "$CMD \
+                    $MD5SUM <$REMOTE_PATH/wars/cocoon-war-$TVERSION.war | \
+                    sed 's/ .*$//' >$REMOTE_PATH/wars/cocoon-war-$TVERSION.war.md5; \
+                    chmod g+w $REMOTE_PATH/wars/cocoon-war-$TVERSION.*"
+fi
+
+# create a distribution
+if [ "$BUILD_SRC_DIST" = "1" ]; then
+  # create the target directory if they do not exists and make them group writable
+  ssh $REMOTE_HOST "mkdir -p $REMOTE_PATH/distributions 2>/dev/null >/dev/null; \
+                   chmod -R g+w $REMOTE_PATH/distributions"
+  ./build.sh dist
+  cd dist
+  if [ "$REVISION_SUB_URL" == "$HEAD_SUB_URL" ]; then
+    SNAPSHOT=`ssh $REMOTE_HOST "ls $REMOTE_PATH/distributions/cocoon-src-????????.??????.zip 2>/dev/null"` 
+    if [ ! -z "$SNAPSHOT" ]; then
+      RM="rm ${SNAPSHOT}\*;\
+	  rm $REMOTE_PATH/distributions/cocoon-src-snapshot.version;"
+    else
+      RM=""
+    fi
+    CMD="$RM \
+         cd $REMOTE_PATH/distributions; \
+         rm cocoon-src-SNAPSHOT.zip; \
+         ln -s cocoon-src-$TVERSION.zip cocoon-src-SNAPSHOT.zip; \
+         echo $TVERSION >cocoon-src-snapshot.version;"
+    ln -s cocoon-$TVERSION cocoon-src-SNAPSHOT
+    zip -qr $REMOTE_PATH/distributions/cocoon-src-$TVERSION.zip cocoon-src-SNAPSHOT
+  else
+    CMD=""
+    ln -s cocoon-$TVERSION cocoon-src-$TVERSION
+    zip -qr cocoon-src-$TVERSION.zip cocoon-src-$TVERSION
+  fi
+  scp cocoon-src-$TVERSION.zip $REMOTE_HOST:$REMOTE_PATH/distributions/cocoon-src-$TVERSION.zip
+  ssh $REMOTE_HOST "$CMD \
+                    $MD5SUM <$REMOTE_PATH/distributions/cocoon-src-$TVERSION.zip | \
+                    sed 's/ .*$//' >$REMOTE_PATH/distributions/cocoon-src-$TVERSION.zip.md5; \
+                    chmod g+w $REMOTE_PATH/distributions/cocoon-src-$TVERSION.zip*"
+    
+fi
diff --git a/non-releases/trunk_before_flattening/tools/bin/envset.cmd b/non-releases/trunk_before_flattening/tools/bin/envset.cmd
new file mode 100644
index 0000000..cb91d87
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/envset.cmd
@@ -0,0 +1,130 @@
+/*
+
+    Copyright 2003-2004 The Apache Software Foundation
+  
+    Licensed 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.
+
+SET environment variables
+First optional parameter:
+   ;     parameters are considered parts of a path variable, semicolons are
+         appended to each element if not already present
+   -D    parameters are properties for Java or Makefile etc., -D will be
+         prepended and the parameters will be separated by a space
+   =D    the same as above but equal sign is not required
+   ,     parameters should be comma separated in the environment variable
+   -     parameters should be separated by the next parameter
+   Other values mean that the first parameter is missing and the environment
+   variable will be set to the space separated parameters
+
+Second parameter: name of the environment variable
+
+Next parameters: values
+; implies that the equal sign is considered a part of the parameter and is
+not interpreted
+
+-D requires parameters in the form name=value. If the equal sign is not found,
+the parameters are changed to name=expanded_name
+
+Other options have optional equal sign. If it is found, only the part after
+the equal sign will be oprionally expanded.
+
+If the parameter is the minus sign, the next parameter will not be expanded.
+If the parameter is a single dot, it will be replaced with the value of the
+environment variable as it existed before envset was invoked.
+
+For other parameters the batch looks for the environment variable with the
+same name (in uppercase). If it is found, it forms the expanded_name. If
+the environment variable with such a name does not exist, the expanded_name
+will hold the parameter name without case conversion.
+*/
+
+parse arg mode envar args
+
+equal = 0
+sep = ' '
+
+/* Parse command line parameters */
+select
+  when mode='-' then do
+    sep = envar
+    parse var args envar args
+  end
+  when mode=';' then do
+    sep = ''
+    equal = -1
+  end
+  when mode='-D' then equal = 1
+  when mode='=D' then mode = '-D'
+  when mode=',' then sep = ','
+otherwise
+  args = envar args
+  envar = mode
+  mode = ''
+end
+
+env = 'OS2ENVIRONMENT'
+envar = translate(envar)
+orig = value(envar,,env)
+newval = ''
+expand = 1
+
+/* for each parameter... */
+do i = 1 to words(args)
+  if expand > 0 & word(args, i) = '-' then expand = 0
+  else call addval word(args, i)
+end
+
+/* Optionally enclose path variable by quotes */
+if mode = ';' & pos(' ', newval) > 0 then newval = '"' || newval || '"'
+
+/* Set the new value, 'SET' cannot be used since it does not allow '=' */
+x = value(envar, newval, env)
+exit 0
+
+addval: procedure expose sep equal orig expand newval mode env
+parse arg var
+
+if var = '.' then expvar = orig
+else do
+  if equal >= 0 then do
+    parse var var name '=' val
+    if val = '' then var = name
+    else var = val
+  end
+  if expand = 0 then expvar = var
+  else expvar = value(translate(var),,env)
+  if expvar = '' then expvar = var
+  if equal >= 0 then do
+    if val = '' then do
+      parse var expvar key '=' val
+      if val <> '' then name = key
+      else do
+        if equal > 0 then val = key
+        else name = key
+      end
+    end
+    else val = expvar
+    if pos(' ', val) > 0 | pos('=', val) > 0 then val = '"' || val || '"'
+    if val = '' then expvar = name
+    else expvar = name || '=' || val
+  end
+  if mode = '-D' then expvar = '-D' || expvar
+  if mode = ';' then do
+    if right(expvar, 1) <> ';' then expvar = expvar || ';'
+  end
+end
+
+if newval = '' then newval = expvar
+else newval = newval || sep || expvar
+expand = 1
+return
diff --git a/non-releases/trunk_before_flattening/tools/bin/lcp.bat b/non-releases/trunk_before_flattening/tools/bin/lcp.bat
new file mode 100755
index 0000000..eed6a82
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/lcp.bat
@@ -0,0 +1,30 @@
+REM
+REM Copyright  2001-2004 The Apache Software Foundation
+REM
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM
+REM      http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+REM
+REM
+
+set _CLASSPATHCOMPONENT=%1
+if ""%1""=="""" goto gotAllArgs
+shift
+
+:argCheck
+if ""%1""=="""" goto gotAllArgs
+set _CLASSPATHCOMPONENT=%_CLASSPATHCOMPONENT% %1
+shift
+goto argCheck
+
+:gotAllArgs
+set LOCALCLASSPATH=%_CLASSPATHCOMPONENT%;%LOCALCLASSPATH%
+
diff --git a/non-releases/trunk_before_flattening/tools/bin/runant.pl b/non-releases/trunk_before_flattening/tools/bin/runant.pl
new file mode 100644
index 0000000..eca4708
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/runant.pl
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+#
+# Copyright 2000-2004 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+#######################################################################
+#
+# runant.pl
+#
+# wrapper script for invoking ant in a platform with Perl installed
+# this may include cgi-bin invocation, which is considered somewhat daft.
+# (slo: that should be a separate file which can be derived from this
+# and returns the XML formatted output)
+#
+# the code is not totally portable due to classpath and directory splitting
+# issues. oops. (NB, use File::Spec::Functions  will help and the code is
+# structured for the catfile() call, but because of perl version funnies
+# the code is not included. 
+#
+# created:         2000-8-24
+# author:          Steve Loughran steve_l@sourceforge.net
+#######################################################################
+#
+# Assumptions:
+#
+# - the "java" executable/script is on the command path
+# - ANT_HOME has been set
+# - target platform uses ":" as classpath separator or perl indicates it is dos/win32
+# - target platform uses "/" as directory separator.
+
+#be fussy about variables
+use strict;
+
+#platform specifics (disabled)
+#use File::Spec::Functions;
+
+#turn warnings on during dev; generates a few spurious uninitialised var access warnings
+#use warnings;
+
+#and set $debug to 1 to turn on trace info
+my $debug=1;
+
+#######################################################################
+#
+# check to make sure environment is setup
+#
+
+my $HOME = $ENV{ANT_HOME};
+if ($HOME eq "")
+        {
+    die "\n\nANT_HOME *MUST* be set!\n\n";
+        }
+
+my $JAVACMD = $ENV{JAVACMD};
+$JAVACMD = "java" if $JAVACMD eq "";
+
+my $onnetware = 0;
+if ($^O eq "NetWare")
+{
+  $onnetware = 1;
+}
+
+my $oncygwin = ($^O eq "cygwin");
+
+#ISSUE: what java wants to split up classpath varies from platform to platform 
+#and perl is not too hot at hinting which box it is on.
+#here I assume ":" 'cept on win32, dos, and netware. Add extra tests here as needed.
+my $s=":";
+if(($^O eq "MSWin32") || ($^O eq "dos") || ($^O eq "cygwin") ||
+   ($onnetware == 1))
+        {
+        $s=";";
+        }
+
+#build up standard classpath
+my $localpath = "$HOME/lib/ant-launcher.jar";
+#set JVM options and Ant arguments, if any
+my @ANT_OPTS=split(" ", $ENV{ANT_OPTS});
+my @ANT_ARGS=split(" ", $ENV{ANT_ARGS});
+
+#jikes
+if($ENV{JIKESPATH} ne "")
+        {
+        push @ANT_OPTS, "-Djikes.class.path=$ENV{JIKESPATH}";
+        }
+
+#construct arguments to java
+my @ARGS;
+push @ARGS, @ANT_OPTS;
+
+my $CYGHOME = "";
+
+my $classpath=$ENV{CLASSPATH};
+if ($oncygwin == 1) {
+  $localpath = `cygpath --path --windows $localpath`;
+  chomp ($localpath);
+  if (! $classpath eq "")
+  {
+    $classpath = `cygpath --path --windows "$classpath"`;
+    chomp ($classpath);
+  }
+  $HOME = `cygpath --path --windows $HOME`;
+  chomp ($HOME);
+  $CYGHOME = `cygpath --path --windows $ENV{HOME}`;
+  chomp ($CYGHOME);
+}
+push @ARGS, "-classpath", "$localpath";
+push @ARGS, "-Dant.home=$HOME";
+if ( ! $CYGHOME eq "" )
+{
+  push @ARGS, "-Dcygwin.user.home=\"$CYGHOME\""
+}
+push @ARGS, "org.apache.tools.ant.launch.Launcher", @ANT_ARGS;
+push @ARGS, @ARGV;
+if (! $classpath eq "")
+{
+  if ($onnetware == 1)
+  {
+    # make classpath literally $CLASSPATH
+    # this is to avoid pushing us over the 512 character limit
+    # even skip the ; - that is already in $localpath
+    push @ARGS, "-lib", "\$CLASSPATH";
+  }
+  else
+  {
+    push @ARGS, "-lib", "$classpath";
+  }
+}
+print "\n $JAVACMD @ARGS\n\n" if ($debug);
+
+my $returnValue = system $JAVACMD, @ARGS;
+if ($returnValue eq 0)
+        {
+        exit 0;
+        }
+else
+        {
+        # only 0 and 1 are widely recognized as exit values
+        # so change the exit value to 1
+        exit 1;
+        }
diff --git a/non-releases/trunk_before_flattening/tools/bin/runant.py b/non-releases/trunk_before_flattening/tools/bin/runant.py
new file mode 100644
index 0000000..c7b53b6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/runant.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+# Copyright 2001,2003-2004 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+
+"""
+
+ runant.py
+
+    This script is a translation of the runant.pl written by Steve Loughran.
+    It runs ant with/out arguments, it should be quite portable (thanks to
+    the python os library)
+    This script has been tested with Python2.0/Win2K
+
+ created:         2001-04-11
+ author:          Pierre Dittgen pierre.dittgen@criltelecom.com
+
+ Assumptions:
+
+ - the "java" executable/script is on the command path
+"""
+import os, os.path, string, sys
+
+# Change it to 1 to get extra debug information
+debug = 0
+
+#######################################################################
+
+# If ANT_HOME is not set default to script's parent directory
+if os.environ.has_key('ANT_HOME'):
+    ANT_HOME = os.environ['ANT_HOME']
+else:
+    ANT_HOME = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+
+# set ANT_LIB location
+ANT_LIB = os.path.join(ANT_HOME, 'lib')
+
+# set JAVACMD (check variables JAVACMD and JAVA_HOME)
+JAVACMD = None
+if not os.environ.has_key('JAVACMD'):
+    if os.environ.has_key('JAVA_HOME'):
+        if not os.path.exists(os.environ['JAVA_HOME']):
+            print "Warning: JAVA_HOME is not defined correctly."
+        else:
+            JAVACMD = os.path.join(os.environ['JAVA_HOME'], 'bin', 'java')
+    else:
+        print "Warning: JAVA_HOME not set."
+else:
+    JAVACMD = os.environ['JAVACMD']
+if not JAVACMD:
+    JAVACMD = 'java'
+
+launcher_jar = os.path.join(ANT_LIB, 'ant-launcher.jar')
+if not os.path.exists(launcher_jar):
+    print 'Unable to locate ant-launcher.jar. Expected to find it in %s' % \
+        ANT_LIB
+
+# Build up standard classpath (LOCALCLASSPATH)
+LOCALCLASSPATH = launcher_jar
+if os.environ.has_key('LOCALCLASSPATH'):
+    LOCALCLASSPATH += os.pathsep + os.environ['LOCALCLASSPATH']
+
+ANT_OPTS = ""
+if os.environ.has_key('ANT_OPTS'):
+    ANT_OPTS = os.environ['ANT_OPTS']
+
+OPTS = ""
+if os.environ.has_key('JIKESPATH'):
+    OPTS = '-Djikes.class.path=\"%s\"' % os.environ['JIKESPATH']
+
+ANT_ARGS = ""
+if os.environ.has_key('ANT_ARGS'):
+    ANT_ARGS = os.environ['ANT_ARGS']
+
+CLASSPATH = ""
+if os.environ.has_key('CLASSPATH'):
+    CLASSPATH = os.environ['CLASSPATH']
+
+# Builds the commandline
+cmdline = ('%s %s -classpath %s -Dant.home=%s %s ' + \
+    'org.apache.tools.ant.launch.Launcher %s -lib %s %s') \
+     % (JAVACMD, ANT_OPTS, LOCALCLASSPATH, ANT_HOME, OPTS, ANT_ARGS, \
+        CLASSPATH, string.join(sys.argv[1:], ' '))
+
+if debug:
+    print '\n%s\n\n' % (cmdline)
+
+# Run the biniou!
+os.system(cmdline)
diff --git a/non-releases/trunk_before_flattening/tools/bin/runrc.cmd b/non-releases/trunk_before_flattening/tools/bin/runrc.cmd
new file mode 100644
index 0000000..0337a80
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/bin/runrc.cmd
@@ -0,0 +1,59 @@
+/* 
+    Copyright 2003-2004 The Apache Software Foundation
+  
+    Licensed 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.
+
+    Run RC file, name is in the first arg, second arg is either PATH
+    ENV  or -r or nothing 
+*/
+
+parse arg name path rest
+
+if name = '' then do
+  say 'RC file name is missing'
+  exit 1
+end
+
+if rest \= '' then do
+  say 'Too many parameters'
+  exit 1
+end
+
+call runit name path
+exit 0
+
+runit: procedure
+parse arg name path dir
+
+if path \= '' & path \= '-r' then do
+  dir = value(translate(path),,'OS2ENVIRONMENT')
+  if dir = '' then return
+  dir = translate(dir, '\', '/') /* change UNIX-like path to OS/2 */
+end
+
+if dir = '' then dir = directory()
+
+if path = '-r' then do /* recursive call */
+  subdir = filespec('path', dir)
+  if subdir \= '\' then do
+    subdir = left(subdir, length(subdir)-1)
+    call runit name path filespec('drive', dir) || subdir
+  end
+end
+
+/* Look for the file and run it */
+if right(dir, 1) \= '\' then dir = dir || '\'
+rcfile = stream(dir || name, 'c', 'query exists')
+if rcfile \= '' then interpret 'call "' || rcfile || '"'
+
+return
diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Block.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Block.java
new file mode 100644
index 0000000..afc491b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Block.java
@@ -0,0 +1,110 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FilenameFilter;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.xerces.parsers.DOMParser;

+import org.w3c.dom.Document;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.xml.sax.InputSource;

+

+/**

+ * @since 0.1

+ */

+public class Block {

+    

+    private String name;

+    private String relativeJardir;

+    private String blockPath;

+    private boolean dynamicEclipseReference = false;

+    

+    public Block() {

+        

+    }

+    

+    public void setName(String name) {

+    	this.name = name;

+    }

+

+    public String getName() {

+    	return this.name;

+    }

+    

+    public void setPath(String path) {

+    	this.blockPath = path;

+    }

+    

+    public void setJardir(String dir) {

+    	this.relativeJardir = dir;

+    }

+    

+    public void setDynamicEclipseReference(boolean dynamicEclipseReference) {

+        this.dynamicEclipseReference = dynamicEclipseReference;

+    }

+    

+    public boolean isDynamicEclipseReference() {

+        return this.dynamicEclipseReference;

+    }

+    

+    public String getEclipseProjectName() throws Exception {

+        return getProjectName(new File(this.blockPath, ".project"));

+    }

+    

+    public File[] getJarFile(File basedir) {

+    	File jarDir = new File(basedir, blockPath + File.separator + this.relativeJardir);

+        return jarDir.listFiles(new FilenameFilter() {

+            public boolean accept(File f, String name) {

+                return name.toLowerCase().endsWith("jar");

+            }

+        });

+    }

+    

+    private String getProjectName(File eclipseProjectFile) throws Exception {

+        String projectName = "";

+        try {

+            String EL_PROJECTDESCRIPTION = "projectDescription";

+            String EL_NAME = "name";

+            

+            DOMParser parser = new DOMParser();

+            parser.parse(new InputSource(new FileInputStream(eclipseProjectFile)));

+            Document doc = parser.getDocument();

+            

+            // read in all available libraries

+            NodeList rootNodeList = doc.getChildNodes();

+            for(int i = 0; i <= rootNodeList.getLength(); i++ ) {

+                Node rootChildNode = rootNodeList.item(i);

+                if(rootChildNode != null && EL_PROJECTDESCRIPTION.equals(rootChildNode.getLocalName())) {

+                    NodeList projectDescriptor = rootChildNode.getChildNodes();

+                    for(int x = 0; x <= projectDescriptor.getLength(); x++) {

+                        Node nameNode = projectDescriptor.item(x);

+                        if(nameNode != null && EL_NAME.equals(nameNode.getLocalName())) {

+                            projectName = nameNode.getFirstChild().getNodeValue();

+                        }

+                    }

+                }

+            }       

+        } catch(Exception e) {

+            throw new BuildException("Make sure that a valid Eclipse project file can be found at " 

+                    + eclipseProjectFile.getCanonicalPath());

+        }

+        return projectName;

+    }

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Cocoon.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Cocoon.java
new file mode 100644
index 0000000..5d3101b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Cocoon.java
@@ -0,0 +1,37 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+/**

+ * @since 0.1

+ */

+public class Cocoon {

+    

+    private String jar;

+    

+	/**

+	 * @return Returns the dir.

+	 */

+	public String getJar() {

+		return jar;

+	}

+	/**

+	 * @param dir The dir to set.

+	 */

+	public void setJar(String jar) {

+		this.jar = jar;

+	}

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Descriptor.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Descriptor.java
new file mode 100644
index 0000000..5a23ba7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Descriptor.java
@@ -0,0 +1,34 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+import java.io.File;

+

+/**

+ * @since 0.1

+ */

+public class Descriptor {

+

+    File file;

+    

+    public void setFile(File file) {

+    	this.file = file;

+    }

+    

+    public File getFile() {

+    	return this.file;

+    }

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/EclipseClasspathBuilderTask.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/EclipseClasspathBuilderTask.java
new file mode 100644
index 0000000..e295a2f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/EclipseClasspathBuilderTask.java
@@ -0,0 +1,254 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+

+import org.apache.tools.ant.BuildException;

+import org.apache.tools.ant.Task;

+import org.apache.xerces.dom.DocumentImpl;

+import org.apache.xerces.parsers.DOMParser;

+import org.apache.xml.serialize.OutputFormat;

+import org.apache.xml.serialize.XMLSerializer;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.xml.sax.InputSource;

+

+/**

+ * @since 0.1

+ */

+public class EclipseClasspathBuilderTask extends Task {

+    

+    private static final String EL_JARS = "jars";

+    private static final String EL_FILE = "file";

+    private static final String ATTR_ID = "id";    

+    private static final String EL_LIB  = "lib";

+    private static final String EL_CLASSPATH = "classpath";

+    private static final String EL_CLASSPATHENTRY = "classpathentry";

+    private static final String ATTR_PATH = "path";

+    private static final String ATTR_KIND = "kind";

+    private static final String ATTR_OUT = "output";    

+    private static final String LIT_ATTR_KIND_SRC = "src";

+    private static final String LIT_ATTR_KIND_CON = "con";

+    private static final String LIT_ATTR_KIND_LIB = "lib";

+    // private static final String LIT_ATTR_KIND_OUT = "output";        

+    private static final String CORE_LIB = "core";

+    private static final String DEFAULT_ECLIPSE_CONTAINER = "org.eclipse.jdt.launching.JRE_CONTAINER";

+    

+    private List blocks = new ArrayList();

+    private Map coreJarMap = new HashMap();

+	private List libs = new ArrayList();

+	private List sources = new ArrayList();

+    private List cocoonJars = new ArrayList();

+    private File corejarsFile;

+    private File outFile;

+    private File coreJarDir;

+    private String eclipseContainer = DEFAULT_ECLIPSE_CONTAINER;

+

+

+	public void execute() throws BuildException {

+        try {

+            

+            // create a new document

+            Document doc= new DocumentImpl();

+            Element root = doc.createElement(EL_CLASSPATH);

+            

+            // append all source directories

+            Iterator sourceIterator = this.sources.iterator();

+            while(sourceIterator.hasNext()) {

+                Source source = ((Source) sourceIterator.next());

+                Element entry = doc.createElement(EL_CLASSPATHENTRY);

+                entry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_SRC);

+                entry.setAttribute(ATTR_PATH, source.getDir());

+                entry.setAttribute(ATTR_OUT, source.getOut());                

+                root.appendChild(entry);            	

+            }

+            

+            // append cocoon libraries

+            Iterator cocoonIterator = this.cocoonJars.iterator();

+            while(cocoonIterator.hasNext()) {

+                Cocoon cocoonEntry = (Cocoon) cocoonIterator.next();

+            	File jar = new File(this.getProject().getBaseDir(), cocoonEntry.getJar());

+                Element entry = doc.createElement(EL_CLASSPATHENTRY);

+                entry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_LIB);

+                entry.setAttribute(ATTR_PATH, jar.getCanonicalPath());

+                root.appendChild(entry);                

+            }

+               

+            // append all public block jars

+    		Iterator blockIterator = this.blocks.iterator();

+            while(blockIterator.hasNext()) {

+                Block block = (Block)blockIterator.next();

+                if(!block.isDynamicEclipseReference()) {

+                	File[] f = block.getJarFile(this.getProject().getBaseDir());

+                    if(f!=null) for(int i = 0; i < f.length; i++) {

+                        Element entry = doc.createElement(EL_CLASSPATHENTRY);

+                        entry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_LIB);

+                        entry.setAttribute(ATTR_PATH, f[i].getCanonicalPath());

+                        root.appendChild(entry);

+                    }

+                } else {

+                    Element entry = doc.createElement(EL_CLASSPATHENTRY);

+                    entry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_SRC);

+                    entry.setAttribute(ATTR_PATH, "/" + block.getEclipseProjectName());

+                    root.appendChild(entry);                    

+                }

+            }

+            

+            // append all libraries

+            Iterator libIterator = this.libs.iterator();

+            while(libIterator.hasNext()) {

+                Library lib = (Library) libIterator.next();

+                if(CORE_LIB.equals(lib.getLocation())) {

+                    String libFromRepository = (String) this.coreJarMap.get(lib.getId());

+                    if(libFromRepository == null) {

+                        throw new BuildException("Library '" + lib.getId() + "' can't be found! " + 

+                                "Make sure it is available in " + corejarsFile.getCanonicalPath() + ".");

+                    }

+                    String jar = (new File(this.coreJarDir, libFromRepository)).getCanonicalPath();

+                    Element entry = doc.createElement(EL_CLASSPATHENTRY);

+                    entry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_LIB);

+                    entry.setAttribute(ATTR_PATH, jar);

+                    root.appendChild(entry);              

+                }

+            }

+            

+            // append default output dir

+            /* RP: is it really necessary?

+            Element outputEntry = doc.createElement(EL_CLASSPATHENTRY);

+            outputEntry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_OUT);

+            outputEntry.setAttribute(ATTR_PATH, "");

+            root.appendChild(outputEntry);               

+            */

+            

+            // append container

+            Element containerEntry = doc.createElement(EL_CLASSPATHENTRY);

+            containerEntry.setAttribute(ATTR_KIND, LIT_ATTR_KIND_CON);

+            containerEntry.setAttribute(ATTR_PATH, this.eclipseContainer);

+            root.appendChild(containerEntry);    

+                        

+            // append root element to document

+            doc.appendChild(root);

+            

+            // serialize document

+            FileOutputStream fos = new FileOutputStream(outFile);

+            OutputFormat of = new OutputFormat("XML","UTF-8",true);

+            of.setIndent(1);

+            of.setIndenting(true);

+            XMLSerializer serializer = new XMLSerializer(fos,of);

+

+            serializer.asDOMSerializer();

+            serializer.serialize( doc.getDocumentElement() );

+            fos.close();    

+            this.log("Wrote Eclipse .classpath file sucessfully.");

+            

+        } catch(BuildException ex) {

+        	throw ex;

+         }catch(Exception ex) {

+            throw new BuildException("error while serializing dom tree: " + ex.getMessage());

+        } 

+        

+        

+    }

+    

+    

+    /**

+     * Parse the jars.xml file and use addCoreJar() method to create an ArrayList with

+     * all available jars.

+     * 

+     * @param file

+     * @throws Exception

+     */

+    private void parseJarXML(File file) throws Exception {

+    	DOMParser parser = new DOMParser();

+        parser.parse(new InputSource(new FileInputStream(file)));

+        Document doc = parser.getDocument();

+        

+        // read in all available libraries

+        NodeList rootNodeList = doc.getChildNodes();

+        for(int i = 0; i <= rootNodeList.getLength(); i++ ) {

+            Node rootChildNode = rootNodeList.item(i);

+            if(rootChildNode != null && EL_JARS.equals(rootChildNode.getLocalName())) {

+            	NodeList jarsNodeList = rootChildNode.getChildNodes();

+                for(int x = 0; x <= jarsNodeList.getLength(); x++) {

+                    Node fileNode = jarsNodeList.item(x);

+                    if(fileNode != null && EL_FILE.equals(fileNode.getLocalName())) {

+                        addCoreJar(fileNode, this.coreJarMap);

+                    }

+                }

+            }

+        }       

+        

+    }

+    

+	private void addCoreJar(Node fileNode, Map jarMap) {

+        String id = fileNode.getAttributes().getNamedItem(ATTR_ID).getNodeValue();

+        NodeList fileNodeList = fileNode.getChildNodes();

+        for(int x = 0; x <= fileNodeList.getLength(); x++) {

+            Node childNode = fileNodeList.item(x);

+            if(childNode != null && EL_LIB.equals(childNode.getLocalName())) {

+                String libValue = childNode.getFirstChild().getNodeValue();

+                jarMap.put(id, libValue);             

+            }

+        }        

+	}

+

+    public void setCorejardir(File dir) {

+    	this.coreJarDir = dir;

+    }

+

+	public void setCorejars(File corejars) throws Exception {

+    	this.corejarsFile = corejars;

+        if(!this.corejarsFile.exists()) {

+            throw new BuildException(this.corejarsFile.getCanonicalPath() + " can't be found.");

+        }

+        parseJarXML(this.corejarsFile);

+    }

+    

+    public void setContainer(String container) {

+    	this.eclipseContainer = container;

+    }

+    

+    public void setOutfile(File outfile) {

+    	this.outFile = outfile;

+    }

+    

+    public void addLib(Library lib) throws BuildException {

+        this.libs.add(lib);

+    }

+    

+    public void addBlock(Block block) {

+    	blocks.add(block);

+    }

+    

+    public void addSource(Source source) {

+        sources.add(source);

+    }

+    

+    public void addCocoon(Cocoon cocoon) {

+    	this.cocoonJars.add(cocoon);

+    }

+    

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Library.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Library.java
new file mode 100644
index 0000000..4a49f4d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Library.java
@@ -0,0 +1,42 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+/**

+ * @since 0.1

+ */

+public class Library {

+    

+    private String id;

+    private String location;

+    

+    public void setId(String id) {

+    	this.id = id;

+    }

+    

+    public String getId() {

+    	return this.id;

+    }

+    

+    public void setLocation(String location) {

+    	this.location = location;

+    }

+

+	public String getLocation() {

+		return this.location;

+	}

+

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Source.java b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Source.java
new file mode 100644
index 0000000..9fd447c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/java/org/apache/cocoon/blockbuilder/ant/Source.java
@@ -0,0 +1,41 @@
+/*

+ * Copyright 2004 The Apache Software Foundation.

+ * 

+ * Licensed 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.cocoon.blockbuilder.ant;

+

+/**

+ * @since 0.1

+ */

+public class Source {

+    

+    String dir;

+    String out;

+

+

+	public String getOut() {

+		return out;

+	}

+    

+	public void setOut(String out) {

+		this.out = out;

+	}

+	public String getDir() {

+		return dir;

+	}

+

+	public void setDir(String dir) {

+		this.dir = dir;

+	}

+}

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2ant-script.xsl b/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2ant-script.xsl
new file mode 100644
index 0000000..36c9fd3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2ant-script.xsl
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:block="http://apache.org/cocoon/blocks/cob/1.0" version="1.0">
+  <xsl:output standalone="yes"/>
+  <xsl:output indent="yes"/>
+  
+  <!-- paths -->
+  <xsl:variable name="blockbuilder.root">${blockbuilder.root}</xsl:variable>
+  <xsl:variable name="default.block.output.path">/build/public/classes</xsl:variable>
+  <xsl:variable name="default.core.output.path">/build/cocoon/classes</xsl:variable>  
+  <xsl:variable name="build.public.classes">${build.public.classes}</xsl:variable>
+  <xsl:variable name="build.public">${build.public}</xsl:variable>    		
+  <xsl:variable name="src.public">${src.public}</xsl:variable>
+  <xsl:variable name="lib.core.dir">${lib.core.dir}</xsl:variable>
+  <xsl:variable name="root.core">${root.core}</xsl:variable>
+  <xsl:variable name="path.to.cocoon.public.jar">build/cocoon/cocoon.jar</xsl:variable>
+  <xsl:variable name="build.temp.tasks">${build.root}/temp/tasks</xsl:variable>
+  
+  <!-- compiler -->
+  <xsl:variable name="compiler.debug">${compiler.debug}</xsl:variable>
+  <xsl:variable name="compiler.optimize">${compiler.optimize}</xsl:variable>
+  <xsl:variable name="compiler.deprecation">${compiler.deprecation}</xsl:variable>
+  <xsl:variable name="target.vm">${target.vm}</xsl:variable>
+  <xsl:variable name="source.vm">${source.vm}</xsl:variable>
+  <xsl:variable name="compiler.nowarn">${compiler.nowarn}</xsl:variable>
+  <xsl:variable name="compiler">${compiler}</xsl:variable>    
+
+  <!-- conditions -->
+  <xsl:variable name="cond.toplevelcall">${cond.toplevelcall}</xsl:variable>
+  
+  <xsl:template match="block:block">
+
+    <project default="compile" name="Building block {name}">
+      
+    	<target name="init">
+    		<!-- read local user properties -->
+    		<property file="local.build.properties"/>
+    
+    		<!-- read block default properties -->		
+    		<property file="build.properties"/>
+    		
+    		<!-- read global default properties -->
+    		<property file="{$blockbuilder.root}/targets/global.build.properties"/>    		
+    		
+    		<!-- if the value toplevelcall is set, unnecessary recursions can be avoided -->
+    	  <xsl:variable name="toplevelcall">${toplevelcall}</xsl:variable>
+        <condition property="cond.toplevelcall">
+          <not><isset property="toplevelcall"/></not>
+        </condition>
+    	</target>  
+      
+    	<target depends="init" name="compile" 
+    	  description="Compile (block + all required blocks)"  
+    	  >
+    	  <!-- check whether parameters are set, unless stop script execution -->
+        <condition property="cond.root.core">
+        	<isset property="root.core"/>
+        </condition>    
+        <fail unless="cond.root.core" message="Property root.core has to be set."/>
+        <xsl:for-each select="block:requirements/block:requires">
+          <xsl:variable name="prop">root.block.<xsl:value-of select="@name"/></xsl:variable>
+          <condition property="cond.{$prop}">
+          	<isset property="{$prop}"/>
+          </condition>    
+          <fail unless="cond.{$prop}" message="Property {$prop} has to be set."/>
+        </xsl:for-each>
+    	  
+    	  <!-- first compile all blocks this block depends on -->
+    		<antcall target="compile-required-blocks">
+    		  <param name="toplevelcall" value="{$cond.toplevelcall}"/>
+    		</antcall>
+    		
+    		<xsl:call-template name="info">
+    		  <xsl:with-param name="msg">Compiling block <xsl:value-of select="block:name"/></xsl:with-param>
+    		</xsl:call-template>
+    		
+    		<!-- setup the classpath
+    		     for convenience reasons not the exact classpath is built but all 
+    		     libraries are used -->
+    		<path id="classpath">
+    		  <xsl:variable name="lib.core.dir">${lib.core.dir}</xsl:variable>
+    			<fileset dir="{$lib.core.dir}">
+    				<include name="core/*.jar"/>
+    				<include name="endorsed/*.jar"/>	
+    				<include name="blocks/*.jar"/>
+    			</fileset>
+    			<xsl:variable name="output.core.classes">${root.core}<xsl:value-of select="$default.core.output.path"/></xsl:variable>
+    			<dirset dir="{$output.core.classes}"/>
+    			<!-- add classes of blocks this block depends on -->
+    			<xsl:for-each select="block:requirements/block:requires">
+    			  <xsl:variable name="output.block.classes">${root.block.<xsl:value-of select="@name"/>}<xsl:value-of select="$default.block.output.path"/></xsl:variable>
+    			  <dirset dir="{$output.block.classes}"/>
+    			</xsl:for-each>
+    		</path>
+    		
+    		<!-- compile this block -->
+    		<mkdir dir="{$build.public.classes}"/>
+        <javac srcdir="{$src.public}"
+               destdir="{$build.public.classes}"
+               debug="{$compiler.debug}"
+               optimize="{$compiler.optimize}"
+               deprecation="{$compiler.deprecation}"
+               target="{$target.vm}"
+               source="{$source.vm}"
+               nowarn="{$compiler.nowarn}"
+               compiler="{$compiler}"
+               classpathref="classpath"/>
+    	</target>    
+    	
+      <target name="package" depends="init" description="Create JAR file (this block + required blocks))">
+          <!-- here is the root of a small bug: because of recursive calls this is also called on 
+               targets that block depends on what's unnecessary but doesn't really harm because 
+               the javac task recognizes that nothing has changed and doesn't compile again -->
+          <antcall target="compile"/>
+        
+      		<antcall target="package-required-blocks">
+      		  <param name="toplevelcall" value="{$cond.toplevelcall}"/>
+      		</antcall>     
+      		
+      		<xsl:call-template name="info">
+      		  <xsl:with-param name="msg">Packaging block <xsl:value-of select="block:name"/></xsl:with-param>
+      		</xsl:call-template>      		
+      		   
+          <jar jarfile="{$build.public}/cocoon-block-{/block:block/block:name/@short}-{/block:block/block:name/@version}.jar" index="true">
+            <fileset dir="{$build.public.classes}"/>
+          </jar>		
+      </target>    	 
+    	
+     	<target depends="init" name="clean-all" description="Clean (this block + all required blocks)">  
+     	  <!-- clean all dependand blocks -->
+    		<antcall target="clean-required-blocks">
+    		  <param name="toplevelcall" value="{$cond.toplevelcall}"/>
+    		</antcall>
+    		<antcall target="clean"/>
+      </target>
+
+     	<target depends="init" name="clean" description="Clean the build directory(this block)"> 		
+     		<xsl:variable name="build.root">${build.root}</xsl:variable>   
+     		<xsl:call-template name="info">
+    		  <xsl:with-param name="msg">Cleaning block <xsl:value-of select="block:name"/></xsl:with-param>
+    		</xsl:call-template>
+    		<delete dir="{$build.root}"/>
+      </target>      
+    	
+    	<target name="compile-eclipse-task" depends="package">
+    		<mkdir dir="{$build.temp.tasks}"/>
+        <javac srcdir="{$blockbuilder.root}/java"
+               destdir="{$build.temp.tasks}"
+               debug="{$compiler.debug}"
+               optimize="{$compiler.optimize}"
+               deprecation="{$compiler.deprecation}"
+               target="{$target.vm}"
+               source="{$source.vm}"
+               nowarn="{$compiler.nowarn}"
+               compiler="{$compiler}"
+               classpathref="classpath"/>	    	  
+    	</target>
+    	
+    	<target depends="compile-eclipse-task" name="eclipse-project" description="Create Eclipse project (this block)">
+      		<xsl:call-template name="info">
+      		  <xsl:with-param name="msg">Building Eclipse project files for block <xsl:value-of select="block:name"/></xsl:with-param>
+      		</xsl:call-template>      	  
+    	  <!-- include custom build task that generates the .classpath
+    	       That is necessary as the library paths are decoupled from block descriptor.
+    	       Using XSLT would require writing an XSLT that creates an XSLT that generates an Ant script *grrr* -->
+        <path id="task.classpath">  	
+          <pathelement location="{$build.temp.tasks}"/>
+        </path> 
+         		
+        <!-- define the task -->
+        <taskdef name="eclipse" 
+          classname="org.apache.cocoon.blockbuilder.ant.EclipseClasspathBuilderTask"
+        	classpathref="task.classpath"/>
+        	
+        <!-- calling the task -->
+        <eclipse
+        	corejars="{$lib.core.dir}/jars.xml"
+        	corejardir="{$lib.core.dir}"
+        	outfile=".classpath"
+        	container="org.eclipse.jdt.launching.JRE_CONTAINER"
+        	>
+        	
+          <!-- all external libraries -->
+        	<xsl:for-each select="block:libraries/block:lib">
+        	  <lib>
+        	    <xsl:for-each select="@*">
+        	      <xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute>
+        	    </xsl:for-each>
+        	  </lib>
+        	</xsl:for-each>
+        	
+        	<!-- list all blocks that this block depends on - this creates references to
+        	     these blocks public jars -->
+        	<xsl:for-each select="block:requirements/block:requires">
+        	  <block name="{@name}" jardir="build/public">
+        	    <xsl:attribute name="path">${root.block.<xsl:value-of select="@name"/>}</xsl:attribute>
+        	    <xsl:attribute name="dynamicEclipseReference">${root.block.<xsl:value-of select="@name"/>.eclipse.dynamic}</xsl:attribute>
+        	  </block>
+        	</xsl:for-each>
+        	
+        	<!-- local soure files -->
+        	<source dir="{$src.public}" out="{$build.public.classes}"/>
+        	
+          <!-- name the cocoon JARs -->
+        	<cocoon jar="{$root.core}/{$path.to.cocoon.public.jar}"/>
+        	
+        </eclipse>        
+        
+        <!-- create .project file -->
+        <xslt in="block.xml" out=".project" 
+         style="{$blockbuilder.root}/targets/block-descriptor2eclipse-project.xsl"/>
+	    </target>
+    
+      <target name="eclipse-project-all" description="Create Eclipse project files (this block + req. blocks)">
+     	  <!-- clean all dependant blocks -->
+    		<antcall target="eclipse-project-required-blocks">
+    		  <param name="toplevelcall" value="{$cond.toplevelcall}"/>
+    		</antcall>
+    		<antcall target="eclipse-project"/>        
+      </target>
+
+    	<xsl:call-template name="multi-block-operation">
+    	  <xsl:with-param name="action">compile</xsl:with-param>
+    	</xsl:call-template>
+
+    	<xsl:call-template name="multi-block-operation">
+    	  <xsl:with-param name="action">package</xsl:with-param>
+    	</xsl:call-template>
+
+    	<xsl:call-template name="multi-block-operation">
+    	  <xsl:with-param name="action">clean</xsl:with-param>
+    	  <xsl:with-param name="nocore">true</xsl:with-param>    	  
+    	</xsl:call-template>
+    	
+    	<xsl:call-template name="multi-block-operation">
+    	  <xsl:with-param name="action">eclipse-project</xsl:with-param>
+    	  <xsl:with-param name="nocore">true</xsl:with-param>
+    	</xsl:call-template>
+    
+    </project>
+    
+  </xsl:template>
+  
+  <xsl:template name="info">
+    <xsl:param name="msg"/>
+    <echo>+-----------------------------------------------------------------+</echo>
+    <echo>| <xsl:value-of select="$msg"/>                                    </echo>
+    <echo>+-----------------------------------------------------------------+</echo>
+  </xsl:template>
+  
+  <!-- create a target for multi-block operations - necessary for recursions -->
+  <xsl:template name="multi-block-operation">
+    <xsl:param name="action"/>
+    <xsl:param name="nocore"/>
+    <target name="{$action}-required-blocks" depends="init, {$action}-core">
+    	<xsl:for-each select="block:requirements/block:requires">
+    	   <xsl:variable name="root.block">${root.block.<xsl:value-of select="@name"/>}</xsl:variable>
+    	   <ant antfile="{$root.block}/build.xml" target="{$action}" inheritall="false">
+    	     <property name="toplevelcall" value="false"/>
+    	   </ant>
+    	</xsl:for-each>		    
+    </target>  
+
+    <target name="{$action}-core" depends="init" if="cond.toplevelcall">
+      <xsl:call-template name="info">
+        <xsl:with-param name="msg">Calling Ant target '<xsl:value-of select="$action"/>' on Cocoon core</xsl:with-param>
+      </xsl:call-template>
+      <xsl:choose>
+        <xsl:when test="$nocore = 'true'">
+          <!-- to nothing -->
+          <echo message="core is not called for this task!"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="root.core">${root.core}</xsl:variable>
+          <ant antfile="{$root.core}/build.xml" target="{$action}" inheritall="false"/>	          
+        </xsl:otherwise>
+      </xsl:choose>  
+    </target>
+  </xsl:template>
+  
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2eclipse-project.xsl b/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2eclipse-project.xsl
new file mode 100644
index 0000000..b356004
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/targets/block-descriptor2eclipse-project.xsl
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="block" xmlns:block="http://apache.org/cocoon/blocks/cob/1.0" version="1.0">

+  <xsl:template match="/">

+    <projectDescription>
+    	<name>[COB] <xsl:value-of select="/block:block/block:name"/> v<xsl:value-of select="/block:block/block:name/@version"/></name>
+    	<comment></comment>
+    	<projects>
+    	</projects>
+    	<buildSpec>
+    		<buildCommand>
+    			<name>org.eclipse.jdt.core.javabuilder</name>
+    			<arguments>
+    			</arguments>
+    		</buildCommand>
+    	</buildSpec>
+    	<natures>
+    		<nature>org.eclipse.jdt.core.javanature</nature>
+    	</natures>
+    </projectDescription>

+  </xsl:template>

+</xsl:stylesheet>

diff --git a/non-releases/trunk_before_flattening/tools/block-builder/targets/global.build.properties b/non-releases/trunk_before_flattening/tools/block-builder/targets/global.build.properties
new file mode 100644
index 0000000..19bcb9a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/block-builder/targets/global.build.properties
@@ -0,0 +1,34 @@
+#  Copyright 1999-2004 The Apache Software Foundation

+#

+#  Licensed 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.

+#

+#----------------------------------------------

+#  Build Properties

+#----------------------------------------------

+

+# ---- Paths -------------------------------------------------------------------

+src.public=java

+

+# ---- Build -------------------------------------------------------------------

+build.root=build

+build.public=${build.root}/public

+build.public.classes=${build.public}/classes

+

+# ---- Compiler ----------------------------------------------------------------

+compiler=modern

+compiler.debug=on

+compiler.optimize=on

+compiler.deprecation=off

+compiler.nowarn=on

+source.vm=1.3

+target.vm=1.3
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/tools/external-project-build/generic-build.xml b/non-releases/trunk_before_flattening/tools/external-project-build/generic-build.xml
new file mode 100644
index 0000000..48ef71c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/external-project-build/generic-build.xml
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<project name="Cocoon build system" default="cocoon:init">
+
+    <target name="cocoon:core-setProperties" depends="cocoon:before-setProperties">
+        <!-- get the properties of properties configuration files -->
+        <property name="cocoon.server" value="localhost"/>
+        <property file="${cocoon.server}.build.properties"/>
+
+        <property file="project.properties"/>
+
+        <!-- conditions depending on property values -->
+        <property name="cocoon.container.use" value="false"/>
+        <property name="cocoon.classesToJAR" value="false"/>
+        <condition property="cocoon.cond.container.use">
+          <istrue value="${cocoon.container.use}"/>
+        </condition>
+        <condition property="cocoon.cond.webapp.in.context">
+          <equals arg1="${cocoon.webapp.path}" arg2=""/>
+        </condition>           
+        <condition property="cocoon.cond.classesToJAR">
+          <and>
+              <istrue value="${cocoon.cond.webapp.in.context}"/>
+              <istrue value="${cocoon.classesToJAR}"/>
+          </and>
+        </condition>
+
+        <!-- repository directory structure -->
+        <property name="cocoon.rep.cocoon.dir" value="${cocoon.rep}/cocoon/${cocoon.version}"/>
+        <property name="cocoon.rep.cocoon.webapp.dir" value="${cocoon.rep.cocoon.dir}/webapp"/>
+        <property name="cocoon.rep.cocoon.lib.dir" value="${cocoon.rep.cocoon.dir}/webapp/WEB-INF/lib"/>
+        <property name="cocoon.rep.cocoon.classes.dir" value="${cocoon.rep.cocoon.dir}/webapp/WEB-INF/classes"/>
+        <property name="cocoon.rep.cocoon.db.dir" value="${cocoon.rep.cocoon.webapp.dir}/WEB-INF/db"/>
+        <property name="cocoon.rep.container.dir" value="${cocoon.rep}/container/${cocoon.container.version}"/>
+        
+        <!-- container properties -->
+        <property file="${cocoon.rep.container.dir}/server.properties"/>
+            
+        <!-- target directory structure -->
+        <property name="cocoon.build.dir" value="build"/>
+        <property name="cocoon.build.java" value="${cocoon.build.dir}/java"/>   
+        <property name="cocoon.build.sourcepathref" value="cocoon:core-compile-sourcepath"/>        
+        <property name="cocoon.build.java.classes" value="${cocoon.build.java}/classes"/>           
+        <property name="cocoon.build.junit" value="${cocoon.build.dir}/test/junit"/>    
+        <property name="cocoon.build.junit.classes" value="${cocoon.build.junit}/classes"/>                     
+        <property name="cocoon.build.junit.output" value="${cocoon.build.junit}/output"/>         
+        <property name="cocoon.build.htmlunit" value="${cocoon.build.dir}/test/htmlunit"/>       
+        <property name="cocoon.build.htmlunit.classes" value="${cocoon.build.htmlunit}/classes"/>            
+        <property name="cocoon.build.htmlunit.output" value="${cocoon.build.htmlunit}/output"/>                    
+        <property name="cocoon.build.webapp.war.dir" value="${cocoon.build.dir}/${cocoon.server}_webapp"/>
+        <property name="cocoon.build.webapp.dir" value="${cocoon.build.dir}/${cocoon.server}_webapp/ROOT"/>
+        <property name="cocoon.build.container.dir" value="${cocoon.build.dir}/${cocoon.server}_container"/>
+
+        <!-- WAR -->
+        <property name="cocoon.build.war.name" value="ROOT.war"/>   
+        
+        <!-- local directories -->
+        <property name="cocoon.local.webapp.dir" value="webapp"/>
+        <property name="cocoon.local.src.dir" value="java"/>
+        <property name="cocoon.local.junit.dir" value="test/junit"/>   
+        <property name="cocoon.local.lib.dir" value="lib"/>
+        <property name="cocoon.local.conf.dir" value="conf"/>
+
+        <!-- default values for compiler settings -->
+        <property name="cocoon.compiler" value="modern"/>
+        <property name="cocoon.compiler.debug" value="on"/>
+        <property name="cocoon.compiler.optimize" value="on"/>
+        <property name="cocoon.compiler.deprecation" value="off"/>
+        <property name="cocoon.compiler.nowarn" value="on"/>
+        <property name="cocoon.compiler.source.vm" value="1.3"/>
+        <property name="cocoon.compiler.target.vm" value="1.3"/>
+     
+        <!-- sourcepath -->
+        <path id="cocoon:core-compile-sourcepath"/>        
+        
+        <!-- classpaths -->
+        <path id="cocoon:classpath">
+            <fileset dir="${cocoon.rep.cocoon.lib.dir}">
+                <include name="*.jar" />
+            </fileset>
+            <fileset dir="${cocoon.local.lib.dir}">
+                <include name="*.jar" />
+            </fileset>
+            <dirset dir="${cocoon.rep.cocoon.classes.dir}" />
+        </path>
+    </target>
+
+    <target name="cocoon:init" depends="cocoon:setProperties, cocoon:setFilters">
+        <!-- global filters -->
+        <filter token="cocoon.filter.webapp.path" value="${cocoon.webapp.path}"/>
+    </target>
+
+    <target name="cocoon:core-webapp" depends="cocoon:before-webapp">
+        <mkdir dir="${cocoon.build.webapp.dir}"/>
+
+        <!-- copy Cocoon -->
+        <copy todir="${cocoon.build.webapp.dir}">
+            <fileset dir="${cocoon.rep.cocoon.webapp.dir}">
+                <include name="WEB-INF/**"/>
+            </fileset>
+        </copy>
+
+        <!-- copy local resources if the application runs *within* the servlet context -->
+        <antcall target="cocoon:copyWebapp"/>
+
+        <copy todir="${cocoon.build.webapp.dir}" filtering="on">
+            <fileset dir="${cocoon.local.webapp.dir}">
+                <include name="sitemap.xmap"/>
+            </fileset>
+        </copy>
+
+        <!-- customize Cocoon -->
+        <copy todir="${cocoon.build.webapp.dir}/WEB-INF/xconf" filtering="on" overwrite="true">
+            <fileset dir="${cocoon.local.conf.dir}">
+                <include name="*xconf"/>
+                <include name="*logkit"/>                
+            </fileset>
+        </copy>
+
+        <!-- add own Java classes -->
+        <antcall target="cocoon:compile"/>
+        <antcall target="cocoon:classesToJAR"/>
+
+        <!-- copy local libraries -->
+        <copy todir="${cocoon.build.webapp.dir}/WEB-INF/lib" filtering="off">
+            <fileset dir="${cocoon.local.lib.dir}"/>
+        </copy>
+    </target>
+    
+    <target name="cocoon:copyWebapp" if="cocoon.cond.webapp.in.context">
+        <echo message=".... copyWebapp"/>
+        <copy todir="${cocoon.build.webapp.dir}" filtering="off">
+            <fileset dir="${cocoon.local.webapp.dir}">
+                <exclude name="sitemap.xmap"/>
+            </fileset>
+        </copy>      
+    </target>
+
+    <target name="cocoon:classesToJAR" if="cocoon.cond.classesToJAR">
+        <zip destfile="${cocoon.build.webapp.dir}/WEB-INF/lib/_project.jar">
+            <fileset dir="${cocoon.build.webapp.dir}/WEB-INF/classes"/>
+        </zip>
+        <delete dir="${cocoon.build.webapp.dir}/WEB-INF/classes"/>
+    </target>
+
+    <target name="cocoon:core-war" depends="cocoon:before-war">
+        <zip destfile="${cocoon.build.webapp.war.dir}/${cocoon.build.war.name}">
+            <fileset dir="${cocoon.build.webapp.dir}"/>
+        </zip>
+    </target>
+
+    <target name="cocoon:core-container" depends="cocoon:before-container">
+        <ant antfile="${cocoon.rep.container.dir}/container-build.xml"
+            target="cocoon:create" inheritall="true"/>
+    </target>
+
+    <target name="cocoon:core-run" depends="cocoon:before-run">
+        <ant antfile="${cocoon.rep.container.dir}/container-build.xml"
+            target="cocoon:run" inheritall="true"/>      
+    </target>
+
+    <target name="cocoon:core-stop" depends="cocoon:init, cocoon:before-stop">
+        <ant antfile="${cocoon.rep.container.dir}/container-build.xml"
+            target="cocoon:stop" inheritall="true"/>
+    </target>
+    
+    <target name="cocoon:core-compile" depends="cocoon:before-compile">
+        <mkdir dir="${cocoon.build.java}"/>
+        <mkdir dir="${cocoon.build.java.classes}"/>   
+        <mkdir dir="${cocoon.build.webapp.dir}/WEB-INF/classes"/>
+        <copy todir="${cocoon.build.java.classes}" filtering="on">
+            <fileset dir="${cocoon.local.src.dir}">
+                <exclude name="**/*.java"/>
+                <exclude name="**/.svn"/>   
+            </fileset>
+        </copy>   
+        <javac classpathref="cocoon:classpath"
+               compiler="${cocoon.compiler}"
+               nowarn="${cocoon.compiler.nowarn}"
+               source="${cocoon.compiler.source.vm}"
+               target="${cocoon.compiler.target.vm}"
+               deprecation="${cocoon.compiler.deprecation}"
+               optimize="${cocoon.compiler.optimize}"
+               debug="${cocoon.compiler.debug}"
+               srcdir="${cocoon.local.src.dir}"
+               destdir="${cocoon.build.java.classes}"
+               sourcepathref="${cocoon.build.sourcepathref}"   
+               />   
+        <copy todir="${cocoon.build.webapp.dir}/WEB-INF/classes" filtering="off">
+            <fileset dir="${cocoon.build.java.classes}">
+                <exclude name="**/*.java"/>
+                <exclude name="**/.svn"/>   
+            </fileset>
+        </copy>
+    </target>
+
+    <target name="cocoon:core-clean" depends="cocoon:before-clean">
+        <delete includeEmptyDirs="true">
+          <fileset dir="${cocoon.build.dir}">
+              <include name="*_container/**"/>
+              <include name="*_webapp/**"/>
+          </fileset>
+        </delete>
+    </target>
+
+    <target name="cocoon:core-clean-all" depends="cocoon:before-clean-all">
+        <delete dir="${cocoon.build.dir}"/>
+    </target>
+
+    <!-- interception targets -->
+    <target name="cocoon:before-setProperties"/>
+    <target name="cocoon:after-setProperties" depends="cocoon:core-setProperties"/>
+    <target name="cocoon:before-webapp" depends="cocoon:init"/>
+    <target name="cocoon:after-webapp" depends="cocoon:core-webapp"/>
+    <target name="cocoon:before-war" depends="cocoon:webapp"/>
+    <target name="cocoon:after-war" depends="cocoon:core-war"/>
+    <target name="cocoon:before-container" depends="cocoon:init"/>
+    <target name="cocoon:after-container" depends="cocoon:core-container"/>
+    <target name="cocoon:before-run" depends="cocoon:init"/>
+    <target name="cocoon:after-run" depends="cocoon:core-run"/>
+    <target name="cocoon:before-stop" depends="cocoon:init"/>
+    <target name="cocoon:after-stop" depends="cocoon:core-stop"/>
+    <target name="cocoon:before-compile" depends="cocoon:init" if="cocoon.cond.webapp.in.context"/>
+    <target name="cocoon:after-compile" depends="cocoon:core-compile" if="cocoon.cond.webapp.in.context"/>
+    <target name="cocoon:before-clean" depends="cocoon:init"/>
+    <target name="cocoon:after-clean" depends="cocoon:core-clean"/>
+    <target name="cocoon:before-clean-all" depends="cocoon:init"/>
+    <target name="cocoon:after-clean-all" depends="cocoon:core-clean-all"/>
+
+    <!-- public available targets 
+         DO NOT OVERRIDE THEM but use the before/after/core targets for this purpose
+    -->
+    <target name="cocoon:container" depends="cocoon:after-container" description="screate a container (uses the property 'container.version')"/>
+    <target name="cocoon:webapp" depends="cocoon:after-webapp" description="create the web application"/>
+    <target name="cocoon:war" depends="cocoon:after-war" description="create a web archive (WAR)"/>
+    <target name="cocoon:run" depends="cocoon:after-run" description="run the container (currently it only works on windows boxes)"/>
+    <target name="cocoon:stop" depends="cocoon:after-stop" description="run the container (currently it only works on windows boxes)"/>
+    <target name="cocoon:compile" depends="cocoon:after-compile" description="Compile Java classes" if="cocoon.cond.webapp.in.context"/>
+    <target name="cocoon:clean" depends="cocoon:after-clean" description="clean webapps and container"/>
+    <target name="cocoon:clean-all" depends="cocoon:after-clean-all" description="clean *everything* in the build dir"/>
+
+    <!-- short versions for public cocoon:* targets - as these are very common names they might be
+         overriden in a custom project build file -->
+    <target name="container" depends="cocoon:container" if="cond.container.use" description="short version for cocoon:container"/>
+    <target name="webapp" depends="cocoon:webapp" description="short version for cocoon:webapp"/>
+    <target name="war" depends="cocoon:war" description="short version for cocoon:war"/>
+    <target name="run" depends="cocoon:run" description="short version for cocoon:run"/>
+    <target name="stop" depends="cocoon:stop" description="short version for cocoon:stop"/>
+    <target name="compile" depends="cocoon:compile" description="short version for cocoon:compile" if="cocoon.cond.webapp.in.context"/>
+    <target name="clean" depends="cocoon:clean" description="short version for cocoon:clean"/>
+    <target name="clean-all" depends="cocoon:clean-all" description="short version for cocoon:clean-all"/>  
+    
+    <!-- internally available targets -->
+    <target name="cocoon:setProperties" depends="cocoon:after-setProperties"/>
+
+    <!-- empty targets to be overriden -->
+    <target name="cocoon:setFilters"/>
+    <target name="cocoon:complete-ant"/>
+
+</project>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/tools/ide/eclipse/blocks-classpath.xsl b/non-releases/trunk_before_flattening/tools/ide/eclipse/blocks-classpath.xsl
new file mode 100644
index 0000000..ba3e5b7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/ide/eclipse/blocks-classpath.xsl
@@ -0,0 +1,258 @@
+<?xml version="1.0"?>
+
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!-- @version $Id$ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+    <xsl:output method="xml" indent="yes"/>
+
+    <xsl:template match="/">
+        <project default="generate-customized-eclipse-project" basedir="." name="blocks-eclipse">
+            <description>Autogenerated Ant build file that builds customized eclipse project for selected blocks.</description>
+            <!-- copied over from blocks-build.xsl -->
+            <macrodef name="test-include-block">
+                <attribute name="name"/>
+                <sequential>
+                    <condition property="include.block.@{{name}}">
+                        <and>
+                            <equals arg1="${{default.block.mode}}" arg2="include"/>
+                            <not><istrue value="${{exclude.block.@{{name}}}}"/></not>
+                        </and>
+                    </condition>
+                    <condition property="internal.exclude.block.@{{name}}">
+                        <and>
+                            <not><istrue value="${{unconditional.include.all.blocks}}"/></not>
+                            <not><istrue value="${{include.block.@{{name}}}}"/></not>
+                        </and>
+                    </condition>
+                </sequential>
+            </macrodef>
+            <xsl:apply-templates select="module"/>
+        </project>
+    </xsl:template>
+
+    <xsl:template match="module">
+        <xsl:variable name="cocoon-blocks" select="project[starts-with(@name, 'cocoon-block-')]"/>
+
+        <!-- Define wich blocks will be included -->
+        <target name="init">
+            <!-- copied over from blocks-build.xsl -->
+            <condition property="default.block.mode" value="include">
+                <istrue value="${{unconditional.include.all.blocks}}"/>
+            </condition>
+            <condition property="default.block.mode" value="include">
+                <istrue value="${{include.all.blocks}}"/>
+            </condition>
+            <condition property="default.block.mode" value="exclude">
+                <istrue value="${{exclude.all.blocks}}"/>
+            </condition>
+            <property name="default.block.mode" value="include"/>
+            <xsl:for-each select="$cocoon-blocks">
+                <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+                <test-include-block name="{$block-name}"/>
+            </xsl:for-each>
+
+            <!-- prepare the various paths that will form the project -->
+            <path id="srcs">
+                <!-- main source dir -->
+                <pathelement path="${{java}}"/>
+                <!-- samples source dir -->
+                <!-- FIXME: Load based on local.build.properties -->
+                <pathelement path="${{src}}/samples"/>
+                <!-- deprecated source dir -->
+                <!-- FIXME: Load based on local.build.properties -->
+                <pathelement path="${{src}}/deprecated/java"/>
+                <!-- test source dir -->
+                <pathelement path="${{src}}/test"/>
+            </path>
+            <!--core mocks -->
+            <path id="mockss">
+                <dirset dir="${{src}}">
+                    <include name="mocks"/>
+                </dirset>
+            </path>
+
+            <path id="libs">
+                <!-- main libs -->
+                <fileset dir="${{lib}}">
+                    <include name="core/*.jar"/>
+                    <include name="local/*.jar"/>
+                    <include name="optional/*.jar"/>
+                    <include name="endorsed/*.jar"/>
+                </fileset>
+                <!-- tools libs -->
+                <fileset dir="${{tools}}/lib">
+                    <include name="*.jar"/>
+                </fileset>
+            </path>
+
+            <!-- convert paths to properties -->
+            <property name="srcs" refid="srcs"/>
+            <property name="mockss" refid="mockss"/>
+            <property name="libs" refid="libs"/>
+
+            <!-- start to expand properties in the template file -->
+            <copy file="${{tools}}/ide/eclipse/classpath-tmpl.xml"
+                    tofile="${{build.temp}}/classpath-temp.xml"
+                    filtering="yes"
+                    overwrite="yes">
+                <filterset>
+                    <filter token="SRC_DIRS" value="${{srcs}}${{path.separator}}@eclipse-src@"/>
+                    <filter token="LIBS" value="${{libs}}${{path.separator}}@eclipse-libs@"/>
+                    <filter token="MOCKS_DIRS" value="${{mockss}}${{path.separator}}@eclipse-mocks@"/>
+                    <filter token="OUTPUT_DIR" value="${{ide.eclipse.outputdir}}"/>
+                </filterset>
+            </copy>
+        </target>
+
+        <target name="generate-customized-eclipse-project">
+            <xsl:attribute name="depends">
+                <xsl:text>init</xsl:text>
+                <xsl:for-each select="$cocoon-blocks">
+                    <xsl:text>,</xsl:text>
+                    <xsl:value-of select="concat(@name, '-eclipseclasspath')"/>
+                </xsl:for-each>
+            </xsl:attribute>
+
+            <!-- clean up src, libs and mocks  -->
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{path.separator}}@eclipse-src@" value=""/>
+
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{path.separator}}@eclipse-libs@" value=""/>
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="@eclipse-libs@" value=""/>
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{path.separator}}@eclipse-mocks@" value=""/>
+
+            <!-- split the path in 'item' XML elements -->
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{path.separator}}" value="&lt;/item&gt;&#xA; &lt;item&gt;"/>
+            <!-- relativize file names by removing the current directory -->
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{user}}${{file.separator}}" value=""/>
+            <!-- and in case that fails, remove the base directory -->
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{basedir}}${{file.separator}}" value=""/>
+
+            <!-- replace platform-dependent path separator by '/' -->
+            <replace file="${{build.temp}}/classpath-temp.xml"
+                    token="${{file.separator}}" value="/"/>
+
+            <!-- now build the .classpath file -->
+            <echo>Generate classpath</echo>
+            <xslt   in="${{build.temp}}/classpath-temp.xml" out="${{basedir}}/.classpath"
+                    processor="trax"
+                    style="${{tools}}/ide/eclipse/make-classpath.xsl">
+                <param name="exportlib" expression="${{ide.eclipse.export.libs}}"/>
+            </xslt>
+
+            <!-- copy the project file (expand version) -->
+            <copy file="${{tools}}/ide/eclipse/project"
+                    tofile="${{basedir}}/.project"
+                    overwrite="yes">
+                <filterset>
+                    <filter token="VERSION" value="${{version}}"/>
+                </filterset>
+            </copy>
+        </target>
+
+        <xsl:apply-templates select="$cocoon-blocks"/>
+    </xsl:template>
+
+    <!-- For each project in gump.xml -->
+    <xsl:template match="project">
+        <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+        <xsl:variable name="cocoon-block-dependencies" select="depend[starts-with(@project,'cocoon-block-')]"/>
+
+        <target name="{@name}-eclipseclasspath" unless="internal.exclude.block.{$block-name}">
+            <!-- block src and test directory -->
+            <if>
+                <available file="${{blocks}}/{$block-name}/trunk/java" type="dir"/>
+                <then>
+                    <path id="src-{$block-name}">
+                        <dirset dir="${{blocks}}/{$block-name}/trunk">
+                            <include name="java"/>
+                            <include name="test"/>
+                        </dirset>
+                    </path>
+                    <property name="src-{$block-name}" refid="src-{$block-name}"/>
+                    <replace file="${{build.temp}}/classpath-temp.xml"
+                            token="@eclipse-src@" value="${{src-{$block-name}}}${{path.separator}}@eclipse-src@"/>
+                </then>
+            </if>
+            <!-- block mocks directory -->
+            <if>
+                <available file="${{blocks}}/{$block-name}/trunk/mocks" type="dir"/>
+                <then>
+                    <path id="mocks-{$block-name}">
+                        <dirset dir="${{blocks}}/{$block-name}">
+                            <include name="**/mocks"/>
+                        </dirset>
+                    </path>
+                    <property name="mocks-{$block-name}" refid="mocks-{$block-name}"/>
+                    <replace file="${{build.temp}}/classpath-temp.xml"
+                            token="@eclipse-mocks@" value="${{mocks-{$block-name}}}${{path.separator}}@eclipse-mocks@"/>
+                </then>
+            </if>
+
+            <!-- block lib directory (deprecated) -->
+            <if>
+                <available file="${{blocks}}/{$block-name}/trunk/lib" type="dir"/>
+                <then>
+                    <path id="lib-{$block-name}">
+                        <fileset dir="${{blocks}}/{$block-name}">
+                            <include name="**/*.jar"/>
+                        </fileset>
+                    </path>
+                    <property name="lib-{$block-name}" refid="lib-{$block-name}"/>
+                    <replace file="${{build.temp}}/classpath-temp.xml"
+                            token="@eclipse-libs@" value="${{lib-{$block-name}}}${{path.separator}}@eclipse-libs@"/>
+                </then>
+            </if>
+            <!-- Add optional libraries used by this block -->
+            <xsl:if test="library[not(@bundle='false')]">
+                <xsl:for-each select="library[not(@bundle='false')]">
+                    <if>
+                        <not>
+                            <istrue value="${{eclipse-optional-lib-{@name}}}"/>
+                        </not>
+                        <then>
+                            <property name="eclipse-optional-lib-{@name}" value="true"/>
+                            <path id="eclipse-optional-lib-{$block-name}-{@name}">
+                                <fileset dir="${{lib.optional}}">
+                                    <include name="{@name}*.jar"/>
+                                </fileset>
+                            </path>
+                            <property name="eclipse-optional-lib-{$block-name}-{@name}" refid="eclipse-optional-lib-{$block-name}-{@name}"/>
+                            <!-- The new lib cannot be empty -->
+                            <if>
+                                <not>
+                                    <equals arg1="${{eclipse-optional-lib-{$block-name}-{@name}}}" arg2=""/>
+                                </not>
+                                <then>
+                                    <replace file="${{build.temp}}/classpath-temp.xml"
+                                            token="@eclipse-libs@" value="${{eclipse-optional-lib-{$block-name}-{@name}}}${{path.separator}}@eclipse-libs@"/>
+                                </then>
+                            </if>
+                        </then>
+                    </if>
+                </xsl:for-each>
+            </xsl:if>
+        </target>
+    </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/ide/eclipse/classpath-tmpl.xml b/non-releases/trunk_before_flattening/tools/ide/eclipse/classpath-tmpl.xml
new file mode 100644
index 0000000..284afcb
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/ide/eclipse/classpath-tmpl.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<data>
+  <src-dirs><item>@SRC_DIRS@</item></src-dirs>
+  <mock-dirs><item>@MOCKS_DIRS@</item></mock-dirs>
+  <libs><item>@LIBS@</item></libs>
+  <output>@OUTPUT_DIR@</output>
+</data>
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/tools/ide/eclipse/make-classpath.xsl b/non-releases/trunk_before_flattening/tools/ide/eclipse/make-classpath.xsl
new file mode 100644
index 0000000..0e94c21
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/ide/eclipse/make-classpath.xsl
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--
+  Build the Eclipse .classpath file from a list of path items
+  (see "eclipse-project" target in build.xml)
+
+  @version $Id$
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:output indent="yes" method="xml"/>
+  <xsl:param name="exportlib"/>
+
+  <xsl:strip-space elements="*"/>
+
+  <xsl:template match="/data">
+    <classpath>
+
+      <!-- 1. source dirs + mock classes -->
+      <xsl:for-each select="src-dirs/item | mock-dirs/item">
+        <!-- alphabetical sorting, complete path -->
+        <xsl:sort select="."/>
+        <classpathentry excluding="**/.svn/**|htmlunit/" kind="src" path="{.}"/>
+      </xsl:for-each>
+
+      <!-- 2. libraries -->
+      <xsl:for-each select="libs/item">
+        <!-- alphabetical sorting, only file name -->
+        <!-- heavy calculation, but here's the logic:
+             1. returns the string after 4 slashes (4 is the max (blocks)),
+                returns empty string if string does not contain 4 slashes
+             2. ... 3 slashes ...
+             3. ... 2 slashes ... (the minimum) -->
+        <xsl:sort select="concat(substring-after(substring-after(substring-after(substring-after(., '/'), '/'), '/'), '/'),
+                                                 substring-after(substring-after(substring-after(., '/'), '/'), '/'),
+                                                                 substring-after(substring-after(., '/'), '/'))"/>
+            <!-- Remove duplicated library entries (diferent blocks can refer the same lib -->
+            <xsl:if test="not(node()) or not(preceding-sibling::node()[.=string(current())])">
+                <classpathentry exported="{$exportlib}" kind="lib" path="{.}"/>
+            </xsl:if>
+      </xsl:for-each>
+
+      <!-- 3. JRE runtime -->
+      <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+
+      <!-- 4. output directory
+           Build in a separate dir since Eclipse is confused
+           by classes compiled externally by Sun's Javac -->
+      <classpathentry kind="output" path="{output}"/>
+
+    </classpath>
+  </xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/ide/eclipse/project b/non-releases/trunk_before_flattening/tools/ide/eclipse/project
new file mode 100644
index 0000000..317574e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/ide/eclipse/project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Cocoon @VERSION@</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/non-releases/trunk_before_flattening/tools/ide/emacs/prj.el.in b/non-releases/trunk_before_flattening/tools/ide/emacs/prj.el.in
new file mode 100644
index 0000000..53b7474
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/ide/emacs/prj.el.in
@@ -0,0 +1,30 @@
+;; -*-emacs-lisp-*-
+;;
+;; Emacs JDE customization file for Cocoon. It is automatically used
+;; if you have a decently recent version of GNU Emacs or Xemacs with JDE.
+;;
+
+
+;; JDE customization
+(jde-project-file-version "1.0")
+(jde-set-variables
+ '(jde-project-name "Cocoon")
+ '(jde-compile-option-classpath (split-path "@jar.files@"))
+ '(jde-compile-option-command-line-args "-g")
+ '(jde-compile-option-sourcepath (quote ("@src.dir@")))
+ '(jde-compile-option-directory "@build.war@/WEB-INF/classes")
+ '(jde-global-classpath (split-path "@jar.files@"))
+ '(jde-compile-option-debug (quote ("all" (t nil nil))))
+ '(jde-compiler "javac"))
+
+;; Editor customization
+(defun jde-cocoon-custom ()
+ ;; Indentation level
+ (setq c-basic-offset 4)
+ ;; Set TAB width to 8 characters
+ (setq tab-width 8)
+ ;; Make sure no tabs are used
+ (setq indent-tabs-mode nil)
+ (setq c-toggle-auto-hungry-state 1))
+
+(add-hook 'jde-mode-hook 'jde-cocoon-custom t)
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/admin-jmx.xml b/non-releases/trunk_before_flattening/tools/jetty/conf/admin-jmx.xml
new file mode 100644
index 0000000..74218d6
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/admin-jmx.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?> 
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!-- =============================================================== -->
+<Configure>
+  
+  <Call id="jmxserver" class="javax.management.MBeanServerFactory" name="createMBeanServer">
+  
+     <Arg>org.mortbay</Arg>
+
+     <Call name="createMBean">
+       <Arg>org.mortbay.util.jmx.MX4JHttpAdaptor</Arg>
+       <Arg><New class="javax.management.ObjectName"><Arg>mx4j.tools:adaptor=http</Arg></New></Arg>
+       <Arg><Array type="java.lang.Object"><Item type="int"><SystemProperty name="jetty.jmx.port" default="8890"/></Item><Item>localhost</Item></Array></Arg>
+       <Arg><Array type="java.lang.String"><Item>int</Item><Item>java.lang.String</Item></Array></Arg>
+     </Call>
+
+     <Call name="createMBean">
+       <Arg>org.mortbay.jetty.jmx.ServerMBean</Arg>
+       <Arg><New class="javax.management.ObjectName"><Arg>org.mortbay:jetty=admin</Arg></New></Arg>
+       <!--Arg><Array type="java.lang.Object"><Item><SystemProperty name="home" default="."/>/tools/jetty/conf/admin.xml</Item></Array></Arg-->
+       <Arg><Array type="java.lang.Object"><Item>./tools/jetty/conf/admin.xml</Item></Array></Arg>
+       <Arg><Array type="java.lang.String"><Item>java.lang.String</Item></Array></Arg>
+     </Call>
+
+     <Call name="createMBean">
+       <Arg>org.mortbay.jetty.jmx.ServerMBean</Arg>
+       <Arg><New class="javax.management.ObjectName"><Arg>org.mortbay:jetty=default</Arg></New></Arg>
+       <!--Arg><Array type="java.lang.Object"><Item><SystemProperty name="home" default="."/>/tools/jetty/conf/main.xml</Item></Array></Arg-->
+       <Arg><Array type="java.lang.Object"><Item>./tools/jetty/conf/main.xml</Item></Array></Arg>
+       <Arg><Array type="java.lang.String"><Item>java.lang.String</Item></Array></Arg>
+     </Call>
+
+  </Call>
+
+</Configure>
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/admin.xml b/non-releases/trunk_before_flattening/tools/jetty/conf/admin.xml
new file mode 100644
index 0000000..d3f7bfc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/admin.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server for the Administration Interface     -->
+<!-- =============================================================== -->
+
+<Configure class="org.mortbay.jetty.Server">
+
+  <!-- =============================================================== -->
+  <!-- Configure the Request Listeners                                 -->
+  <!-- =============================================================== -->
+
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <!-- Add and configure a HTTP listener to port 8081                    -->
+  <!-- The default port can be changed using: java -Djetty.admin.port=80 -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <Call name="addListener">
+    <Arg>
+      <New class="org.mortbay.http.SocketListener">
+        <Set name="Host">127.0.0.1</Set>
+        <Set name="Port"><SystemProperty name="jetty.admin.port" default="8081"/></Set>
+        <Set name="MinThreads">5</Set>
+        <Set name="MaxThreads">100</Set>
+        <Set name="MaxIdleTimeMs">30000</Set>
+        <Set name="LowResourcePersistTimeMs">5000</Set>
+      </New>
+    </Arg>
+  </Call>
+
+  <!-- =============================================================== -->
+  <!-- Configure the Contexts                                          -->
+  <!-- =============================================================== -->
+
+  <Call name="addContext">
+    <Arg>/</Arg>   
+
+    <Call name="addServlet">
+      <Arg>Admin</Arg>
+      <Arg>/</Arg>
+      <Arg>org.mortbay.servlet.AdminServlet</Arg>
+    </Call>
+    <Call name="setAttribute">
+      <Arg>org.mortbay.http.HttpServer</Arg>
+      <Arg><Call name="getHttpServer"/></Arg>
+    </Call>
+  </Call>
+
+</Configure>
+
+
+
+
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/jetty-start.config b/non-releases/trunk_before_flattening/tools/jetty/conf/jetty-start.config
new file mode 100644
index 0000000..a3cbae4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/jetty-start.config
@@ -0,0 +1,66 @@
+# This file controls what file are to be put on classpath or command line.
+#
+# Format is as follows:
+# Each line contains entry for one JAR file.
+# Format of line:
+#
+#  SUBJECT [ [!] CONDITION [AND|OR] ]*
+# 
+# where SUBJECT: 
+#   ends with ".class" is the Main class to run.
+#   ends with ".xml" is a configuration file for the command line
+#   ends with "/" is a directory from which add all jar and zip files from. 
+#   ends with "/*" is a directory from which add all unconsidered jar and zip files from.
+#   Containing = are used to assign system properties.
+#   all other subjects are treated as files to be added to the classpath.
+#
+# Subjects may include system properties with $(propertyname) syntax. 
+#
+# Files starting with "/" are considered absolute, all others are relative to
+# the home directory.
+#
+# CONDITION is one of:
+#   always
+#   never
+#   available classname        # true if class on classpath
+#   property name              # true of set
+#   java OPERATOR version      # java version compared to literal
+#   nargs OPERATOR number      # number of command line args compared to literal
+#   OPERATOR := one of "<",">","<=",">=","==","!="
+#
+# CONTITIONS can be combined with AND OR or !, with AND being the assume
+# operator for a list of CONDITIONS.
+# Classpath operations are evaluated on the fly, so once a class or jar is
+# added to the classpath, subsequent available conditions will see that class.
+#
+
+$(jetty.class.path)                              always
+
+org.mortbay.log.LogFactory.noDiscovery=true       ! property org.mortbay.log.LogFactory.noDiscovery
+javax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder java > 1.4
+
+# Try different settings of jetty.home until the jetty.jar is found.
+jetty.home=./tools/jetty                                     ! exists $(jetty.home)/lib/jetty-5.1.8.jar 
+jetty.home=../tools/jetty                                    ! exists $(jetty.home)/lib/jetty-5.1.8.jar
+
+# The main class to run
+org.mortbay.jetty.Server.class
+# override class with old property name
+$(start.class).class
+# override class with preferred property name
+$(main.class).class
+$(loader.main.class).class
+
+# The default configuration files
+$(jetty.home)/conf/main.xml                    nargs == 0
+
+# Set the jetty classpath
+$(jetty.home)/lib/*
+$(home)/lib/endorsed/*                           always
+$(home)/lib/core/commons-logging-1.0.4.jar       always
+$(home)/lib/core/avalon-logkit-2.1.jar           always
+
+# Add JMX jars
+$(home)/lib/core/jetty-jmx-5.1.8.jar            java >= 1.4
+
+
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/main-jmx.xml b/non-releases/trunk_before_flattening/tools/jetty/conf/main-jmx.xml
new file mode 100644
index 0000000..4ae7650
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/main-jmx.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?> 
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!-- =============================================================== -->
+<Configure>
+  
+  <Call id="jmxserver" class="javax.management.MBeanServerFactory" name="createMBeanServer">
+  
+     <Arg>org.mortbay</Arg>
+
+     <Call name="createMBean">
+       <Arg>org.mortbay.util.jmx.MX4JHttpAdaptor</Arg>
+       <Arg><New class="javax.management.ObjectName"><Arg>mx4j.tools:adaptor=http</Arg></New></Arg>
+       <Arg><Array type="java.lang.Object"><Item type="int"><SystemProperty name="jetty.jmx.port" default="8890"/></Item><Item>localhost</Item></Array></Arg>
+       <Arg><Array type="java.lang.String"><Item>int</Item><Item>java.lang.String</Item></Array></Arg>
+     </Call>
+
+     <Call name="createMBean">
+       <Arg>org.mortbay.jetty.jmx.ServerMBean</Arg>
+       <Arg><New class="javax.management.ObjectName"><Arg>org.mortbay:jetty=default</Arg></New></Arg>
+       <Arg><Array type="java.lang.Object"><Item><SystemProperty name="home" default="."/>/tools/jetty/conf/main.xml</Item></Array></Arg>
+       <Arg><Array type="java.lang.String"><Item>java.lang.String</Item></Array></Arg>
+     </Call>
+
+  </Call>
+
+</Configure>
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/main.xml b/non-releases/trunk_before_flattening/tools/jetty/conf/main.xml
new file mode 100644
index 0000000..1e55243
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/main.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!-- =============================================================== -->
+
+<Configure class="org.mortbay.jetty.Server">
+
+  <!-- =============================================================== -->
+  <!-- Configure the Request Listeners                                 -->
+  <!-- =============================================================== -->
+
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <!-- Add and configure a HTTP listener to port 8888                  -->
+  <!-- The default port can be changed using: java -Djetty.port=80     -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <Call name="addListener">
+    <Arg>
+      <New class="org.mortbay.http.SocketListener">
+        <Set name="Port"><SystemProperty name="jetty.port" default="8888"/></Set>
+        <Set name="MinThreads">5</Set>
+        <Set name="MaxThreads">100</Set>
+        <Set name="MaxIdleTimeMs">30000</Set>
+        <Set name="LowResourcePersistTimeMs">5000</Set>
+        <Set name="PoolName">Listener</Set>
+      </New>
+    </Arg>
+  </Call>
+
+  <!-- =============================================================== -->
+  <!-- Configure the Contexts                                          -->
+  <!-- =============================================================== -->
+
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <!-- Add root context web applications.                              -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  <!-- Add a all web application within the webapps directory.         -->
+  <!-- + No virtual host specified                                     -->
+  <!-- + Look in the webapps directory relative to jetty.home or .     -->
+  <!-- + Use the webdefault.xml resource for the defaults descriptor   -->
+  <!-- + Upack the war file                                            -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+  <Call name="addWebApplication">
+    <Arg><SystemProperty name="context" default="/"/></Arg>
+    <Arg><SystemProperty name="webapp" default="."/></Arg>
+    <Set name="defaultsDescriptor"><SystemProperty name="home" default="."/>/tools/jetty/conf/webdefaults.xml</Set>
+  </Call>
+
+</Configure>
diff --git a/non-releases/trunk_before_flattening/tools/jetty/conf/webdefaults.xml b/non-releases/trunk_before_flattening/tools/jetty/conf/webdefaults.xml
new file mode 100644
index 0000000..e6307b3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/conf/webdefaults.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<!-- ===================================================================== -->
+<web-app>
+  <description>
+    This file is applied to a Web application before it's own WEB-INF/web.xml file
+  </description>
+
+  <!-- ==================================================================== -->
+  <!-- Context params to control Session Cookies                            -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!-- UNCOMMENT TO ACTIVATE
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>
+    <param-value>127.0.0.1</param-value>
+  </context-param>
+
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
+    <param-value>/</param-value>
+  </context-param>
+
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>
+    <param-value>-1</param-value>
+  </context-param>
+  -->
+
+  <!-- ==================================================================== -->
+  <session-config>
+    <session-timeout>30</session-timeout>
+  </session-config>
+
+</web-app>
diff --git a/non-releases/trunk_before_flattening/tools/jetty/jetty-start-5.1.8.jar b/non-releases/trunk_before_flattening/tools/jetty/jetty-start-5.1.8.jar
new file mode 100644
index 0000000..b146c84
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/jetty-start-5.1.8.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/jetty/lib/jetty-5.1.8.jar b/non-releases/trunk_before_flattening/tools/jetty/lib/jetty-5.1.8.jar
new file mode 100644
index 0000000..d393c56
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/lib/jetty-5.1.8.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-3.0.1.jar b/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-3.0.1.jar
new file mode 100644
index 0000000..e5dafc1
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-3.0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-tools-2.1.1.jar b/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-tools-2.1.1.jar
new file mode 100644
index 0000000..8f2cad2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/lib/mx4j-tools-2.1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/jetty/lib/servlet-2.4.jar b/non-releases/trunk_before_flattening/tools/jetty/lib/servlet-2.4.jar
new file mode 100644
index 0000000..a1a5333
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jetty/lib/servlet-2.4.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/jmeter/CalculatorFlow.jmx b/non-releases/trunk_before_flattening/tools/jmeter/CalculatorFlow.jmx
new file mode 100644
index 0000000..b4dcfc4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jmeter/CalculatorFlow.jmx
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<node>

+<testelement class="org.apache.jmeter.testelement.TestPlan">

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="TestPlan.thread_groups"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="TestPlan.user_defined_variables">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.config.gui.ArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Benutzer definierte Variablen</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.TestPlanGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.serialize_threadgroups">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.testelement.TestPlan</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Calculator Flow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.functional_mode">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestPlan.comments"/>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.threads.ThreadGroup">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.start_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.delay"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.duration"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.num_threads">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ThreadGroup.scheduler">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</property>

+<testelement class="org.apache.jmeter.control.LoopController" name="ThreadGroup.main_controller">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="LoopController.loops">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.LoopController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Loop Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="LoopController.continue_forever">false</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Thread Group</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.end_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.on_sample_error">continue</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.ramp_time">1</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.control.CookieManager">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.CookiePanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.control.CookieManager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Cookie Manager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="CookieManager.clearEachIteration">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="CookieManager.cookies"/>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.config.ConfigTestElement">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">/samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.ConfigTestElement</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Request Defaults</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain">127.0.0.1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port">8888</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.ConstantTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.ConstantTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.ConstantTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Constant Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.GaussianRandomTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.GaussianRandomTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.GaussianRandomTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Gaussian Random Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RandomTimer.range">500.0</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.OnceOnlyController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.OnceOnlyControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.OnceOnlyController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Once Only Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Calculator Start Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"continue.([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.GenericController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LogicControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.GenericController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/flow/jxcalc/continue.${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">987654321</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">a</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">enter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">submit</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter A Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"continue.([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/flow/jxcalc/continue.${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">123456789</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">b</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">enter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">submit</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter B Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"continue.([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/flow/jxcalc/continue.${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">divide</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">operator</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">Do it!</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">submit</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Operator Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"continue.([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">Start over</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">submit</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Start Over Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"continue.([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.GraphVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Graph Results</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.StatVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Aggregate Report</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\test.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.ViewResultsFullVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">View Results Tree</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.SimpleDataWriter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Data Writer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\out.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+</node>

+</node>

diff --git a/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms.jmx b/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms.jmx
new file mode 100644
index 0000000..6cf7ff0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms.jmx
@@ -0,0 +1,644 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<node>

+<testelement class="org.apache.jmeter.testelement.TestPlan">

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="TestPlan.thread_groups"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="TestPlan.user_defined_variables">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.config.gui.ArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Benutzer definierte Variablen</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.TestPlanGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.serialize_threadgroups">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.testelement.TestPlan</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Cocoon Forms Flow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.functional_mode">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestPlan.comments"/>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.threads.ThreadGroup">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.start_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.delay"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.duration"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.num_threads">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ThreadGroup.scheduler">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</property>

+<testelement class="org.apache.jmeter.control.LoopController" name="ThreadGroup.main_controller">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="LoopController.loops">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.LoopController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Loop Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="LoopController.continue_forever">false</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Flowscript</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.end_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.on_sample_error">continue</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.ramp_time">1</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.control.CookieManager">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.CookiePanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.control.CookieManager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Cookie Manager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="CookieManager.clearEachIteration">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="CookieManager.cookies"/>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.config.ConfigTestElement">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">/samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.ConfigTestElement</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Request Defaults</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain">127.0.0.1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port">8888</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.ConstantTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.ConstantTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.ConstantTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Constant Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.GaussianRandomTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.GaussianRandomTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.GaussianRandomTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Gaussian Random Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RandomTimer.range">500.0</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.OnceOnlyController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.OnceOnlyControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.OnceOnlyController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Once Only Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1.flow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Load form</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*.continue)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.GenericController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LogicControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.GenericController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test1@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (1)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*.continue)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test2@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (2)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*.continue)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1.flow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Start Over Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jemter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*.continue)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.GraphVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Graph Results</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.StatVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Aggregate Report</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\test.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.ViewResultsFullVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">View Results Tree</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.SimpleDataWriter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Data Writer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\out.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.threads.ThreadGroup">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.start_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.delay"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.duration"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.num_threads">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ThreadGroup.scheduler">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</property>

+<testelement class="org.apache.jmeter.control.LoopController" name="ThreadGroup.main_controller">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="LoopController.loops">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.LoopController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Loop Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="LoopController.continue_forever">false</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">JavaFlow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.end_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.on_sample_error">continue</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.ramp_time">1</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.control.CookieManager">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.CookiePanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.control.CookieManager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Cookie Manager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="CookieManager.clearEachIteration">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="CookieManager.cookies"/>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.config.ConfigTestElement">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">/samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.ConfigTestElement</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Request Defaults</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain">127.0.0.1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port">8888</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.ConstantTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.ConstantTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.ConstantTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Constant Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.GaussianRandomTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.GaussianRandomTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.GaussianRandomTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Gaussian Random Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RandomTimer.range">500.0</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.OnceOnlyController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.OnceOnlyControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.OnceOnlyController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Once Only Controller (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/javaflow/editForm1.do</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Load form (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.GenericController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LogicControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.GenericController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Controller (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/javaflow/${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test1@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (1) (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/javaflow/${continue}</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test2@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (2) (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jmeter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/javaflow/editForm1.do</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Start Over Request (JavaFlow)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.extractor.RegexExtractor">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.default">jemter-error</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.extractor.gui.RegexExtractorGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.extractor.RegexExtractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.regex">action=\"([^"]*)\"</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Continuation ID Extractor</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.useHeaders">FALSE</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.match_number">1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.template">$1$</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RegexExtractor.refname">continue</property>

+</testelement>

+</node>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.GraphVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Graph Results</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.StatVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Aggregate Report</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\test.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.ViewResultsFullVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">View Results Tree</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.SimpleDataWriter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Data Writer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\out.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+</node>

+</node>

diff --git a/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms_JXTemplate.jmx b/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms_JXTemplate.jmx
new file mode 100644
index 0000000..b44c1b7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/jmeter/CocoonForms_JXTemplate.jmx
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<node>

+<testelement class="org.apache.jmeter.testelement.TestPlan">

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="TestPlan.thread_groups"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="TestPlan.user_defined_variables">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.config.gui.ArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Benutzer definierte Variablen</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.TestPlanGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.serialize_threadgroups">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.testelement.TestPlan</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Cocoon Forms Flow</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestPlan.functional_mode">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestPlan.comments"/>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.threads.ThreadGroup">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.start_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.delay"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.duration"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.num_threads">10</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ThreadGroup.scheduler">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</property>

+<testelement class="org.apache.jmeter.control.LoopController" name="ThreadGroup.main_controller">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="LoopController.loops">5</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.LoopController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Loop Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="LoopController.continue_forever">false</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Form1_Action</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.LongProperty" name="ThreadGroup.end_time">1057252450000</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.on_sample_error">continue</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ThreadGroup.ramp_time">1</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.control.CookieManager">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.CookiePanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.control.CookieManager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Cookie Manager</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="CookieManager.clearEachIteration">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="CookieManager.cookies"/>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.config.ConfigTestElement">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">/samples/flow/jxcalc/</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.ConfigTestElement</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">HTTP Request Defaults</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain">127.0.0.1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port">8888</property>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.ArrayList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.ConstantTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.ConstantTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.ConstantTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Constant Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.timers.GaussianRandomTimer">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.timers.gui.GaussianRandomTimerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.timers.GaussianRandomTimer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Gaussian Random Timer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="RandomTimer.range">500.0</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="ConstantTimer.delay">500</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.OnceOnlyController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.OnceOnlyControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.OnceOnlyController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Once Only Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">GET</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Load form</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.control.GenericController">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.control.gui.LogicControllerGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.control.GenericController</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Controller</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test1@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (1)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments">

+<testelement class="org.apache.jmeter.protocol.http.util.HTTPArgument" name="">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.metadata">=</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.value">test2@apache.org</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.use_equals">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="Argument.name">email</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPArgument.always_encode">false</property>

+</testelement>

+</collection>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Enter Email-Adress (2)</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.protocol.http.sampler.HTTPSampler">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.path">samples/blocks/forms/form1</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.method">POST</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.use_keepalive">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.protocol"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.image_parser">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.follow_redirects">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.port"/>

+<testelement class="org.apache.jmeter.config.Arguments" name="HTTPsampler.Arguments">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.config.Arguments</property>

+<collection class="java.util.LinkedList" propType="org.apache.jmeter.testelement.property.CollectionProperty" name="Arguments.arguments"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Argument List</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+</testelement>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.mimetype"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_FIELD"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Start Over Request</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.monitor">false</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.domain"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="HTTPSampler.FILE_NAME"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="HTTPSampler.auto_redirects">false</property>

+</testelement>

+</node>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.GraphVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Graph Results</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.StatVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Aggregate Report</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\test.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.ViewResultsFullVisualizer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">View Results Tree</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename"/>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+<node>

+<testelement class="org.apache.jmeter.reporters.ResultCollector">

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.gui_class">org.apache.jmeter.visualizers.SimpleDataWriter</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="TestElement.name">Simple Data Writer</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="TestElement.enabled">true</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.StringProperty" name="filename">d:\out.txt</property>

+<property xml:space="preserve" propType="org.apache.jmeter.testelement.property.BooleanProperty" name="ResultCollector.error_logging">false</property>

+</testelement>

+</node>

+</node>

+</node>

diff --git a/non-releases/trunk_before_flattening/tools/lib/ant-contrib-0.6.jar b/non-releases/trunk_before_flattening/tools/lib/ant-contrib-0.6.jar
new file mode 100644
index 0000000..db90b0a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant-contrib-0.6.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/ant-junit.jar b/non-releases/trunk_before_flattening/tools/lib/ant-junit.jar
new file mode 100644
index 0000000..5ee4f7f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant-junit.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/ant-launcher.jar b/non-releases/trunk_before_flattening/tools/lib/ant-launcher.jar
new file mode 100644
index 0000000..1a71612
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant-launcher.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/ant-nodeps.jar b/non-releases/trunk_before_flattening/tools/lib/ant-nodeps.jar
new file mode 100644
index 0000000..3e0e5d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant-nodeps.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/ant-trax.jar b/non-releases/trunk_before_flattening/tools/lib/ant-trax.jar
new file mode 100644
index 0000000..f4e1540
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant-trax.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/ant.jar b/non-releases/trunk_before_flattening/tools/lib/ant.jar
new file mode 100644
index 0000000..3beb3b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/ant.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/easymock-1.1.jar b/non-releases/trunk_before_flattening/tools/lib/easymock-1.1.jar
new file mode 100644
index 0000000..edc2b6a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/easymock-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/httpunit-1.6.jar b/non-releases/trunk_before_flattening/tools/lib/httpunit-1.6.jar
new file mode 100644
index 0000000..71780d7
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/httpunit-1.6.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/jing-20030619.jar b/non-releases/trunk_before_flattening/tools/lib/jing-20030619.jar
new file mode 100644
index 0000000..6acbfb0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/jing-20030619.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/jmock-1.0.1.jar b/non-releases/trunk_before_flattening/tools/lib/jmock-1.0.1.jar
new file mode 100644
index 0000000..e774359
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/jmock-1.0.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/junit-3.8.1.jar b/non-releases/trunk_before_flattening/tools/lib/junit-3.8.1.jar
new file mode 100644
index 0000000..674d71e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/junit-3.8.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/qdox-1.5.jar b/non-releases/trunk_before_flattening/tools/lib/qdox-1.5.jar
new file mode 100644
index 0000000..7ef9a8a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/qdox-1.5.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/xml-commons-resolver-1.1.jar b/non-releases/trunk_before_flattening/tools/lib/xml-commons-resolver-1.1.jar
new file mode 100644
index 0000000..073d789
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/xml-commons-resolver-1.1.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/lib/xmlunit0.8.jar b/non-releases/trunk_before_flattening/tools/lib/xmlunit0.8.jar
new file mode 100644
index 0000000..fbfe064
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/lib/xmlunit0.8.jar
Binary files differ
diff --git a/non-releases/trunk_before_flattening/tools/review-sitemap-docs/README.txt b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/README.txt
new file mode 100644
index 0000000..32997fa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/README.txt
@@ -0,0 +1,26 @@
+These are some basic tools to assist with the
+ Review of sitemap component documentation
+ http://cocoon.apache.org/2.1/plan/review-sitemap-docs.html
+
+------------------------------------------------------------------------
+Keep the table synchronised with the java source
+------------------------------------------------
+Occasionally do the following ...
+Find all java source files whose filename contains a component name ...
+ cd cocoon-2_1_X
+ tools/review-sitemap-docs/correlate-table.sh
+Compare the output listings with last time you ran it ...
+ diff component-java-files.txt component-java-files-20041201.txt
+Also compare with a listing of the files from Cocoon trunk.
+Add new rows to the table with copy-and-paste.
+
+------------------------------------------------------------------------
+Add a new empty column to the table
+-----------------------------------
+Edit the sed script to define the next column, then run it.
+ cd cocoon-2_1_X
+ sed -f tools/review-sitemap-docs/add-column.sed \
+   src/documentation/xdocs/plan/review-sitemap-docs.xml > tmp
+ mv tmp src/documentation/xdocs/plan/review-sitemap-docs.xml
+
+------------------------------------------------------------------------
diff --git a/non-releases/trunk_before_flattening/tools/review-sitemap-docs/add-column.sed b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/add-column.sed
new file mode 100644
index 0000000..620c162
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/add-column.sed
@@ -0,0 +1,4 @@
+/th>D<\/th/a \
+  <th>E</th>
+/D --><td/a \
+  <!-- E --><td></td>
diff --git a/non-releases/trunk_before_flattening/tools/review-sitemap-docs/correlate-table.sh b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/correlate-table.sh
new file mode 100755
index 0000000..ff63365
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/correlate-table.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+# Purpose:
+# Ensure that the review-sitemap-docs.xml coordination table
+# remains synchronised.
+#
+# Procedure:
+# Scan the Cocoon repository and find sitemap components java files.
+# Scan the coordinate table xdoc and list the javadoc source for each entry.
+# Compare with diff.
+#
+# Usage:
+# Run this script from the top-level of the repository.
+#  cd /usr/local/svn/cocoon-2_1_X
+#  tools/review-sitemap-docs/correlate-table.sh
+
+echo "Scanning Cocoon repository to find sitemap components java source files."
+echo " (See component-java-files.txt and do diff with that file from last run.)"
+find src -name *Action.java -o -name *Generator.java \
+      -o -name *Matcher.java -o -name *Reader.java \
+      -o -name *Selector.java -o -name *Serializer.java \
+      -o -name *Transformer.java \
+| grep -v -f tools/review-sitemap-docs/find-component-java-files-exclude.txt \
+> component-java-files.tmp
+find src -name *.java | grep -f tools/review-sitemap-docs/grep-components.txt \
+| grep -v -f tools/review-sitemap-docs/find-component-java-files-exclude.txt \
+>> component-java-files.tmp
+sort component-java-files.tmp | uniq > component-java-files.txt
+rm -f component-java-files.tmp
+
+echo "Listing the sitemap components java source files."
+echo " (See components-source.txt)"
+sed -n 's/src\/.*org\//org\//p' component-java-files.txt \
+| sort > components-source.txt
+
+echo "Scanning the coordinate table xdoc and list the javadoc sources."
+echo " (See components-table.txt and do diff with last time.)"
+grep "<\!-- 1 -->" src/documentation/xdocs/plan/review-sitemap-docs.xml \
+| sed 's/  <!-- 1 --><td>//;s/<\/td>//' \
+| sed 's/<link href="\.\.\/apidocs\///;s/\.html.*$/\.java/' \
+| sort > components-table.txt
+
+echo "Comparing the lists."
+echo "Whitespace lines are table entries which are missing a javadoc reference."
+echo "diff components-source.txt components-table.txt"
+echo "----------"
+diff components-source.txt components-table.txt
+echo "----------"
+
+echo "Counting the number of components in the table."
+wc -l components-table.txt
diff --git a/non-releases/trunk_before_flattening/tools/review-sitemap-docs/find-component-java-files-exclude.txt b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/find-component-java-files-exclude.txt
new file mode 100644
index 0000000..94d9e27
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/find-component-java-files-exclude.txt
@@ -0,0 +1,13 @@
+src/blocks/woody
+src/deprecated
+src/documentation/xdocs/tutorial
+src/java/org/apache/cocoon/components/ExtendedComponentSelector.java
+src/java/org/apache/cocoon/transformation/pagination/
+src/blocks/scratchpad/java/org/apache/cocoon/transformation/constrained/
+acting/Sendmail.java
+asciiart/AsciiArtPad.java
+TestCase.java
+/helpers/
+Helper.java
+Result.java
+Config.java
diff --git a/non-releases/trunk_before_flattening/tools/review-sitemap-docs/grep-components.txt b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/grep-components.txt
new file mode 100644
index 0000000..a490575
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/review-sitemap-docs/grep-components.txt
@@ -0,0 +1,8 @@
+/acting/
+/generation/
+/matching/
+/reading/
+/selection/
+/serialization/
+/generation/
+/transformation/
diff --git a/non-releases/trunk_before_flattening/tools/src/announcement.xsl b/non-releases/trunk_before_flattening/tools/src/announcement.xsl
new file mode 100644
index 0000000..930c883
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/announcement.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:template match="changes">
+    <xsl:variable name="file" select="@file"/>
+    <xsl:variable name="version" select="@version"/>
+    <xsl:apply-templates select="document($file)/status/changes/release[@version=string($version)]"/>
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/announcement2txt.xsl b/non-releases/trunk_before_flattening/tools/src/announcement2txt.xsl
new file mode 100644
index 0000000..051750f
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/announcement2txt.xsl
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:import href="announcement.xsl"/>
+  <xsl:output method="text" indent="no"/>
+
+  <xsl:template match="announcement">
+    <xsl:variable name="titlelen" select="string-length(project)+9"/>
+    <text>
+      <xsl:value-of select="project"/><xsl:text> Released
+</xsl:text>
+      <xsl:call-template name="line">
+        <xsl:with-param name="len" select="$titlelen"/>
+      </xsl:call-template>
+      <xsl:text>
+</xsl:text>
+      <xsl:apply-templates select="abstract"/>
+      <xsl:apply-templates select="body"/>
+      <xsl:text>
+For more information about </xsl:text>
+      <xsl:value-of select="project"/>
+      <xsl:text>, please go to
+</xsl:text>
+      <xsl:value-of select="@site"/>
+      <xsl:text>
+
+Changes with </xsl:text>
+      <xsl:value-of select="project"/>
+      <xsl:text>
+
+</xsl:text>
+      <xsl:apply-templates select="changes"/>
+    </text>
+  </xsl:template>
+
+  <xsl:template match="project"/>
+  <xsl:template match="title"/>
+
+  <xsl:template match="subproject">
+    <xsl:variable name="titlelen" select="string-length(title)"/>
+    <xsl:text>
+</xsl:text>
+    <xsl:value-of select="title"/>
+    <xsl:text>
+</xsl:text>
+    <xsl:call-template name="line">
+      <xsl:with-param name="len" select="$titlelen"/>
+    </xsl:call-template>
+    <xsl:text>
+</xsl:text>
+    <xsl:apply-templates select="abstract"/>
+    <xsl:text>
+For more information about </xsl:text>
+    <xsl:value-of select="title"/>
+    <xsl:text>, please go to
+</xsl:text>
+    <xsl:value-of select="@site"/>
+    <xsl:text>
+
+Changes with </xsl:text>
+    <xsl:value-of select="title"/>
+    <xsl:text>
+
+</xsl:text>
+    <xsl:apply-templates select="changes"/>
+  </xsl:template>
+
+  <xsl:template match="abstract">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="p">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="link">
+    <xsl:value-of select="."/>
+    <xsl:text> (</xsl:text>
+    <xsl:value-of select="@href"/>
+    <xsl:text>)</xsl:text>
+  </xsl:template>
+
+  <xsl:template match="release">
+    <xsl:for-each select="action">
+      <xsl:text>*) </xsl:text>
+      <xsl:value-of select="normalize-space(.)"/><xsl:text> </xsl:text>
+      <xsl:if test="@dev">
+        <xsl:text>[</xsl:text>
+	<xsl:value-of select="@dev"/>
+	<xsl:text>]</xsl:text>
+      </xsl:if>
+      <xsl:text>
+
+</xsl:text>
+    </xsl:for-each>
+  </xsl:template>
+
+  <xsl:template name="line">
+    <xsl:param name="len"/>
+    <xsl:if test="number($len) > 0">
+      <xsl:text>-</xsl:text>
+      <xsl:call-template name="line">
+        <xsl:with-param name="len" select="number($len)-1"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/BlockConfigTask.java b/non-releases/trunk_before_flattening/tools/src/anttasks/BlockConfigTask.java
new file mode 100644
index 0000000..3b4b1ed
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/BlockConfigTask.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+/**
+ * Ant task to add block dependencies to xconf configuration
+ *
+ * @version $Id$
+ */
+public final class BlockConfigTask extends Task {
+
+    private File file;
+    private String depends;
+
+    /**
+     * Set file, which should be patched.
+     *
+     * @param file File, which should be patched.
+     */
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    public void setDepends(String depends) {
+        this.depends = depends;
+    }
+
+    /**
+     * Execute task.
+     */
+    public void execute() throws BuildException {
+        if (this.file == null) {
+            throw new BuildException("file attribute is required", this.getLocation());
+        }
+        if ( this.depends == null ) {
+            throw new BuildException("depends attribute is required", this.getLocation());            
+        }
+        final List dependencies = new ArrayList();
+        final StringTokenizer st = new StringTokenizer(this.depends, ",");
+        while ( st.hasMoreTokens() ) {
+            String token = st.nextToken();
+            dependencies.add(token);
+        }
+        
+        if ( dependencies.size() > 0 ) {
+            try {
+                Document doc = DocumentCache.getDocument(this.file, this);
+                Element elem = doc.getDocumentElement();
+                Node firstChild = elem.getFirstChild();
+                for(int i=0; i<dependencies.size();i++) {
+                    final String token = (String)dependencies.get(i);
+                    Node n;
+                    n = doc.createTextNode("  ");
+                    elem.insertBefore(n, firstChild);
+
+                    n = doc.createComment("Include dependencies");
+                    elem.insertBefore(n, firstChild);
+
+                    n = doc.createTextNode("\n  ");
+                    elem.insertBefore(n, firstChild);
+
+                    n = doc.createElement("include");
+                    ((Element)n).setAttribute("src", "context://WEB-INF/xconf/" + token + ".xconf");
+                    elem.insertBefore(n, firstChild);
+
+                    n = doc.createTextNode("\n");
+                    elem.insertBefore(n, firstChild);
+                }
+                DocumentCache.writeDocument(this.file, doc, this);
+                DocumentCache.storeDocument(this.file, doc, this);
+            } catch (SAXException e) {
+                throw new BuildException("SAXException:" +e);           
+            } catch (IOException ioe) {
+                throw new BuildException("IOException: "+ioe);
+            }
+        }
+    }
+
+ 
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/DocumentCache.java b/non-releases/trunk_before_flattening/tools/src/anttasks/DocumentCache.java
new file mode 100644
index 0000000..cbe11fc
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/DocumentCache.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * @version $Id$
+ */
+public final class DocumentCache {
+
+    /** Cache the read configuration files (Documents) */
+    protected final static Map fileCache = new HashMap();
+    
+    /** The document builder */
+    private static DocumentBuilder builder;
+    private static Transformer transformer;
+
+    /**
+     * Initialize internal instance of XMLCatalog
+     */
+    static {
+        try {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            builderFactory.setValidating(false);
+            builderFactory.setExpandEntityReferences(false);
+            builderFactory.setNamespaceAware(false);
+            builderFactory.setAttribute(
+               "http://apache.org/xml/features/nonvalidating/load-external-dtd",
+               Boolean.FALSE);
+            builder = builderFactory.newDocumentBuilder();
+            transformer = TransformerFactory.newInstance().newTransformer();
+        } catch (TransformerException e) {
+            throw new BuildException("TransformerException: "+e);
+        } catch (ParserConfigurationException e) {
+            throw new BuildException("ParserConfigurationException: "+e);
+        }  
+    }
+
+    public static Document getDocument(File file, Task task) 
+    throws SAXException, IOException {
+        final String fileName = file.toURL().toExternalForm();
+        Document document = (Document)fileCache.get(fileName);
+        if ( document != null ) {
+            if ( task != null ) {
+                task.log("Using file from cache: " + fileName, Project.MSG_DEBUG);
+            }
+            fileCache.remove(fileName);
+        } else {
+            try {
+                // load xml
+                if ( task != null ) {
+                    task.log("Reading: " + fileName, Project.MSG_DEBUG);
+                }
+                document = builder.parse(fileName);
+            } catch (IOException e) {
+                throw new BuildException("IOException: "+e);
+            }                
+        }
+        return document;
+    }
+    
+    public static Document getDocument(String string, String systemURI) {
+        try {
+            final InputSource is = new InputSource(new StringReader(string));
+            if ( systemURI != null ) {
+                is.setSystemId(systemURI);
+            }
+            return builder.parse(is);
+        } catch (Exception e) {
+            throw new BuildException("Unable to parse string.", e);
+        }
+    }
+    
+    public static void storeDocument(File file, Document document, Task task) 
+    throws IOException {
+        task.log("Storing file in cache: " + file, Project.MSG_DEBUG);
+        final String fileName = file.toURL().toExternalForm();
+        fileCache.put(fileName, document);
+    }
+
+    public static void writeDocument(File file, Document document, Task task) {
+        if ( task != null ) {
+            task.log("Writing: " + file);
+        }
+        // Set the DOCTYPE output option on the transformer 
+        // if we have any DOCTYPE declaration in the input xml document
+        final DocumentType doctype = document.getDoctype();
+        Properties props = new Properties();
+        if (null != doctype) {
+            if (null != doctype.getPublicId()) {
+                props.put(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
+            }
+            if (null != doctype.getSystemId()) {
+                props.put(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
+            }
+        }
+        transformer.setOutputProperties(props);
+        
+        try {
+            StreamResult s = new StreamResult(file);
+            // for JDK 5.0 we explicitly have to set the output stream
+            // otherwise we get FileNotFoundExceptions (at least on
+            // windows)
+            s.setOutputStream(new FileOutputStream(file));
+            transformer.transform(new DOMSource(document),
+                                  s);
+        } catch (FileNotFoundException e) {
+            throw new BuildException("FileNotFoundException: "+e);
+        } catch (TransformerException e) {
+            throw new BuildException("TransformerException: "+e);
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/ManifestToolTask.java b/non-releases/trunk_before_flattening/tools/src/anttasks/ManifestToolTask.java
new file mode 100644
index 0000000..e36854d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/ManifestToolTask.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Creates Manifest file with the all the JARs and modification dates
+ * in the specified directory.
+ *
+ * @version $Id$
+ */
+public final class ManifestToolTask extends Task {
+
+    private String directory;
+    private String manifest;
+
+    public void setDirectory(String directory) {
+        this.directory = directory;
+    }
+
+    public void setManifest(String manifest) {
+        this.manifest = manifest;
+    }
+
+    public void execute() throws BuildException {
+        if (this.manifest == null) {
+            throw new BuildException("manifest attribute is required", this.getLocation());
+        }
+        if (this.directory == null) {
+            throw new BuildException("directory attribute is required", this.getLocation());
+        }
+
+        try {
+            // process recursive
+            this.process(this.getProject().resolveFile(this.directory));
+        } catch (IOException ioe) {
+            throw new BuildException("IOException: " + ioe);
+        }
+    }
+
+    /**
+     * Scan recursive
+     */
+    private void process(final File directoryFile)
+    throws IOException, BuildException {
+
+        System.out.println("Writing: " + manifest);
+        FileWriter w = null;
+        try {
+            w = new FileWriter(this.getProject().resolveFile(manifest));
+            w.write("Manifest-Version: 1.0\n");
+    
+            if (directoryFile.exists() && directoryFile.isDirectory() ) {
+                w.write("Cocoon-Libs: ");
+    
+                final File[] files = directoryFile.listFiles();
+                for(int i = 0; i < files.length; i++) {
+                    if (files[i].getName().endsWith(".jar")) {
+                        w.write(files[i].getName());
+                        w.write(" ");
+                    }
+                }
+                w.write("\n");
+    
+                for(int i = 0; i < files.length; i++) {
+                    if (files[i].getName().endsWith(".jar")) {
+                        w.write("Cocoon-Lib-");
+                        String s = files[i].getName().replace('.', '_');
+                        w.write(s);
+                        w.write(": ");
+                        w.write(String.valueOf(files[i].lastModified()));
+                        w.write("\n");
+                    }
+                }
+            }
+        } finally {
+            if (w != null) {
+                w.close();
+            }
+        }
+    }
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/PoolSetterTask.java b/non-releases/trunk_before_flattening/tools/src/anttasks/PoolSetterTask.java
new file mode 100644
index 0000000..d789c0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/PoolSetterTask.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Set the special attributes for the pooling.
+ *
+ * @since 2.1.5
+ * @version $Id$
+ */
+public final class PoolSetterTask extends Task {
+
+    private File file;
+    private String element;
+    private boolean isSitemap = true;
+    private String poolMax = "32";
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    public void setElement(String element) {
+        this.element = element;
+    }
+
+    public void setIsSitemap(boolean value) {
+        this.isSitemap = value;
+    }
+
+    public void setPoolMax(int value) {
+        this.poolMax = String.valueOf(value);
+    }
+
+    public void execute() throws BuildException {
+
+        if (this.file == null) {
+            throw new BuildException("file attribute is required", this.getLocation());
+        }
+        if (this.element == null) {
+            throw new BuildException("element attribute is required", this.getLocation());
+        }
+
+        try {
+            // load xml
+            final Document configuration = DocumentCache.getDocument(this.file, this);
+
+            // process recursive
+            boolean changed = false;
+            StringTokenizer st = new StringTokenizer(this.element);
+            while ( st.hasMoreTokens() ) {
+                String componentName = st.nextToken();
+                NodeList nodes;
+                if (this.isSitemap) {
+                    int pos = componentName.indexOf(":");
+                    nodes = XPathAPI.selectNodeList(configuration, "*/*[local-name()='components']/*/*[local-name()='"+componentName.substring(0,pos)+"' and @name='"+componentName.substring(pos+1)+"']");
+                } else {
+                    nodes = XPathAPI.selectNodeList(configuration, "*/"+componentName);
+                }
+                if (nodes != null && nodes.getLength() > 0) {
+                    for(int i=0; i < nodes.getLength(); i++) {
+                        final Element e = (Element)nodes.item(i);
+                        e.setAttributeNS(null, "pool-max", this.poolMax);
+                        changed = true;
+                    }
+                } else {
+                    System.out.println("Component not found: " + componentName);
+                }
+            }
+
+            if ( changed ) {
+                // save xml
+                DocumentCache.writeDocument(this.file, configuration, this);
+            }
+            DocumentCache.storeDocument(this.file, configuration, this);
+       } catch (TransformerException e) {
+            throw new BuildException("TransformerException: " + e);
+        } catch (SAXException e) {
+            throw new BuildException("SAXException: " + e);
+        } catch (IOException ioe) {
+            throw new BuildException("IOException: " + ioe);
+        }
+    }
+
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/SitemapTask.java b/non-releases/trunk_before_flattening/tools/src/anttasks/SitemapTask.java
new file mode 100644
index 0000000..d156154
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/SitemapTask.java
@@ -0,0 +1,796 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.thoughtworks.qdox.ant.AbstractQdoxTask;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.parser.ParseException;
+
+/**
+ * Generate documentation for sitemap components based on javadoc tags
+ * in the source of the component.
+ * 
+ * This is the first, experimental version - the code is a little bit
+ * hacky but straight forward :)
+ * 
+ * @since 2.1.5
+ * @version $Id$
+ */
+public final class SitemapTask extends AbstractQdoxTask {
+
+    /** The name of the component in the sitemap (required) */    
+    public static final String NAME_TAG   = "cocoon.sitemap.component.name";
+    /** The logger category (optional) */
+    public static final String LOGGER_TAG = "cocoon.sitemap.component.logger";
+    /** The label for views (optional) */
+    public static final String LABEL_TAG  = "cocoon.sitemap.component.label";
+    /** The mime type for serializers and readers (optional) */
+    public static final String MIMETYPE_TAG  = "cocoon.sitemap.component.mimetype";
+    /** If this tag is specified, the component is not added to the sitemap (optional) */
+    public static final String HIDDEN_TAG = "cocoon.sitemap.component.hide";
+    /** If this tag is specified no documentation is generated (optional) */
+    public static final String NO_DOC_TAG = "cocoon.sitemap.component.documentation.disabled";
+    /** The documentation (optional) */
+    public static final String DOC_TAG    = "cocoon.sitemap.component.documentation";
+    /** Configuration (optional) */
+    public static final String CONF_TAG   = "cocoon.sitemap.component.configuration";
+    /** Caching info (optional) */
+    public static final String CACHING_INFO_TAG = "cocoon.sitemap.component.documentation.caching";
+
+    /** Pooling max (optional) */
+    public static final String POOL_MAX_TAG = "cocoon.sitemap.component.pooling.max";
+    
+    private static final String LINE_SEPARATOR = "\n";
+    
+    /** The sitemap */
+    private File sitemap;
+    
+    /** The doc dir */
+    private File docDir;
+    
+    /** Cache for classes */
+    private static Map cache = new HashMap();
+    
+    /** The directory containing the sources*/
+    private String directory;
+    
+    /** The name of the block */
+    protected String blockName;
+    
+    /** Is this block deprecated? */
+    protected boolean deprecated = false;
+    
+    /** Is this block stable? */
+    protected boolean stable = true;
+    
+    /**
+     * Set the directory containing the source files.
+     * Only .java files will be scanned
+     */
+    public void setSource(File dir) {
+        try {
+            this.directory = dir.toURL().toExternalForm();
+            if ( !dir.isDirectory() ) {
+                throw new BuildException("Source is not a directory.");
+            }
+        } catch (IOException ioe) {
+            throw new BuildException(ioe);
+        }
+        FileSet set = new FileSet();
+        set.setDir(dir);
+        set.setIncludes("**/*.java");
+        super.addFileset(set);
+    }
+    
+    /**
+     * The location of the sitemap
+     */
+    public void setSitemap( final File sitemap ) {
+        this.sitemap = sitemap;
+    }
+
+    /**
+     * The location of the documentation files
+     */
+    public void setDocDir( final File dir ) {
+        this.docDir = dir;        
+    }
+    
+    /**
+     * Set the block name
+     */
+    public void setBlock(String value) {
+        this.blockName = value;
+    }
+    
+    /**
+     * Is the block deprecated?
+     */
+    public void setDeprecated(boolean value) {
+        this.deprecated = value;
+    }
+    
+    /**
+     * Is the block stable?
+     */
+    public void setStable(boolean value) {
+        this.stable = value;
+    }
+
+    /**
+     * Determine the type of the class
+    */
+    private String classType(JavaClass clazz) {
+        if ( clazz.isA(GENERATOR) ) {
+            return "generator";
+        } else if ( clazz.isA(TRANSFORMER) ) {
+            return "transformer";
+        } else if ( clazz.isA(READER) ) {
+            return "reader";
+        } else if ( clazz.isA(SERIALIZER) ) {
+            return "serializer";
+        } else if ( clazz.isA(ACTION) ) {
+            return "action";
+        } else if ( clazz.isA(MATCHER) ) {
+            return "matcher";
+        } else if ( clazz.isA(SELECTOR) ) {
+            return "selector";
+        } else if ( clazz.isA(PIPELINE) ) {
+            return "pipe";
+        // Should qdox resolve recursively? ie: HTMLGenerator isA ServiceableGenerator isA AbstractGenerator isA Generator
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.generation") && (clazz.isA("Generator") || clazz.isA("ServiceableGenerator")) ) {
+            return "generator";
+        } else if ( clazz.isA("org.apache.cocoon.generation.ServiceableGenerator") ) {
+            return "generator";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.transformation") && clazz.isA("Transformer") ) {
+            return "transformer";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.reading") && clazz.isA("Reader") ) {
+            return "reader";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.serialization") && clazz.isA("Serializer") ) {
+            return "serializer";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.acting") && clazz.isA("Action") ) {
+            return "action";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.matching") && clazz.isA("Matcher") ) {
+            return "matcher";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.selection") && clazz.isA("Selector") ) {
+            return "selector";
+        } else if ( clazz.getPackage().equals("org.apache.cocoon.components.pipeline") && clazz.isA("ProcessingPipeline") ) {
+            return "pipe";
+        } else {
+            return null;
+        }            
+    }
+    
+    /**
+     * Execute generator task.
+     *
+     * @throws BuildException if there was a problem collecting the info
+     */
+    public void execute()
+    throws BuildException {
+        validate();
+
+        List components = (List)cache.get(this.directory);
+        if ( components == null ) {
+            // this does the hard work :)
+            try {
+                super.execute();
+            }
+            catch (ParseException pe) {
+              log("ParseException: " + pe);
+            }
+            components = this.collectInfo();
+            cache.put(this.directory, components);
+        }
+
+        try {
+            
+            if ( this.sitemap != null ) {
+                this.processSitemap(components);
+            }
+            if ( this.docDir != null ) {
+                this.processDocDir(components);
+            }
+            
+        } catch ( final BuildException e ) {
+            throw e;
+        } catch ( final Exception e ) {
+            throw new BuildException( e.toString(), e );
+        }
+    }
+
+    /**
+     * Validate that the parameters are valid.
+     */
+    private void validate() {
+        if ( this.directory == null ) {
+            throw new BuildException("Source is not specified.");
+        }
+        if ( this.sitemap == null && this.docDir == null ) {
+            throw new BuildException("Sitemap or DocDir is not specified.");
+        }
+        
+        if ( this.sitemap != null && this.sitemap.isDirectory() ) {
+            throw new BuildException( "Sitemap (" + this.sitemap + ") is not a file." );
+        }
+        if ( this.docDir != null && !this.docDir.isDirectory() ) {
+            throw new BuildException( "DocDir (" + this.docDir + ") is not a directory." );            
+        }
+    }
+
+    /**
+     * Collect the component information
+     */
+    private List collectInfo() {
+        log("Collecting sitemap components info");
+        final List components = new ArrayList();
+        final List allComponentNames = new ArrayList();
+        
+        final Iterator it = super.allClasses.iterator();
+        
+        while ( it.hasNext() ) {
+            final JavaClass javaClass = (JavaClass) it.next();
+
+            final DocletTag tag = javaClass.getTagByName( NAME_TAG );
+            if (classType(javaClass) != null) {
+                allComponentNames.add(javaClass.getFullyQualifiedName());
+            }
+
+            if ( null != tag ) {
+                final SitemapComponent comp = new SitemapComponent( javaClass );
+
+                log("Found component: " + comp, Project.MSG_DEBUG);
+                components.add(comp);
+            }
+        }
+
+        // Generate a list of all sitemap components
+        final String fileSeparator = System.getProperty("file.separator", "/");
+        final String matchString = "blocks" + fileSeparator;
+        final String outputFname = "build" + fileSeparator + "all-sitemap-components" +
+            (directory.endsWith(matchString) ? "-blocks" : "") + ".txt";
+        log("Listing all sitemap components to " + outputFname);
+        try {
+            File outputFile = new File(outputFname);
+            FileWriter out = new FileWriter(outputFile);
+            final String lineSeparator = System.getProperty("line.separator", "\n");
+            final Iterator iter = allComponentNames.iterator();
+            while ( iter.hasNext() ) {
+                out.write((String)iter.next());
+                out.write(lineSeparator);
+            }
+            out.close();
+        }
+        catch (IOException ioe) {
+            log("IOException: " + ioe);
+        }
+
+        return components;
+    }
+
+    /**
+     * Add components to sitemap
+    */
+    private void processSitemap(List components) 
+    throws Exception {
+        log("Adding sitemap components");
+        Document document;
+        
+        document = DocumentCache.getDocument(this.sitemap, this);
+        
+        boolean changed = false;
+
+        Iterator iter = components.iterator();
+        while ( iter.hasNext() ) {
+            SitemapComponent component = (SitemapComponent)iter.next();
+            final String type = component.getType();
+            final String section = type + 's';
+            
+            NodeList nodes = XPathAPI.selectNodeList(document, "/sitemap/components/" + section);
+
+            if (nodes.getLength() != 1 ) {
+                throw new BuildException("Unable to find section for component type " + type);
+            }
+            // remove old node!
+            NodeList oldNodes = XPathAPI.selectNodeList(document, 
+                    "/sitemap/components/" + section + '/' + type + "[@name='" + component.getName() + "']");
+            for(int i=0; i < oldNodes.getLength(); i++ ) {
+                final Node node = oldNodes.item(i);
+                node.getParentNode().removeChild(node);
+            }
+            
+            // and add it again
+            if (component.append(nodes.item(0)) ) {
+                changed = true;
+            }
+            
+        }
+        
+        if ( changed ) {
+            DocumentCache.writeDocument(this.sitemap, document, this);
+        }
+        DocumentCache.storeDocument(this.sitemap, document, this);
+    }
+    
+    /**
+     * Add components to sitemap
+    */
+    private void processDocDir(List components) 
+    throws Exception {
+        log("Generating documentation");
+
+        Iterator iter = components.iterator();
+        while ( iter.hasNext() ) {
+            final SitemapComponent component = (SitemapComponent)iter.next();
+            
+            // Read template
+            final File templateFile = this.getProject().resolveFile("src/documentation/templates/sitemap-component.xml");
+            Document template = DocumentCache.getDocument(templateFile, this);
+            
+            // create directory - if required
+            final File componentsDir = new File(this.docDir, component.getType()+'s');
+            componentsDir.mkdir();
+            
+            // get file name
+            String fileName = component.getName() + "-" + component.getType() + ".xml";
+            if ( this.blockName != null ) {
+                fileName = this.blockName + "-" + fileName;
+            }
+            final File docFile = new File(componentsDir, fileName);
+            
+            // generate the doc
+            component.generateDocs(template, docFile, this.getProject());
+            
+            // generate the index
+            final File indexFile = new File(componentsDir, "book.xml");
+            final Document indexDoc = DocumentCache.getDocument(indexFile, this);
+            final String section;
+            if ( this.blockName == null ) {
+                section = "Core";
+            } else {
+                section = this.blockName + " Block";
+            }
+            Node sectionNode = XPathAPI.selectSingleNode(indexDoc, "/book/menu[@label='"+section+"']");
+            if ( sectionNode == null ) {
+                sectionNode = indexDoc.createElement("menu");
+                ((Element)sectionNode).setAttribute("label", section);
+                indexDoc.getDocumentElement().appendChild(sectionNode);
+            }
+            final String htmlName = docFile.getName().substring(0, docFile.getName().length()-3) + "html";
+            Node oldEntry = XPathAPI.selectSingleNode(sectionNode, "menu-item[@href='"+htmlName+"']");
+            Node newEntry = indexDoc.createElement("menu-item");
+            ((Element)newEntry).setAttribute("href", htmlName);
+            final String label = capitalize(component.getName()) + " " + capitalize(component.getType());
+            ((Element)newEntry).setAttribute("label", label);
+            if ( oldEntry != null ) {
+                oldEntry.getParentNode().replaceChild(newEntry, oldEntry);
+            } else {
+                Node nextLabel = null;
+                final NodeList childs = sectionNode.getChildNodes();
+                int i = 0;
+                while ( nextLabel == null && i < childs.getLength() ) {
+                    final Node current = childs.item(i);
+                    if ( current instanceof Element ) {
+                        final String currentLabel = ((Element)current).getAttribute("label");
+                        if ( label.compareTo(currentLabel) < 0 ) {
+                            nextLabel = current;
+                        }
+                    }
+                    i++;
+                }
+                if ( nextLabel == null ) {
+                    sectionNode.appendChild(newEntry);
+                } else {
+                    sectionNode.insertBefore(newEntry, nextLabel);
+                }
+            }
+            DocumentCache.writeDocument(indexFile, indexDoc, this);
+        }
+        
+    }
+
+    /**
+     * Helper method to capitalize a string.
+     * This is taken from commons-lang, but we don't want the dependency 
+     * right now!
+     */
+    public static String capitalize(String str) {
+        int strLen;
+        if (str == null || (strLen = str.length()) == 0) {
+            return str;
+        }
+        return new StringBuffer(strLen)
+            .append(Character.toTitleCase(str.charAt(0)))
+            .append(str.substring(1))
+            .toString();
+    }
+
+    final class SitemapComponent {
+        
+        final protected JavaClass javaClass;
+        final String    name;
+        final String    type;
+        
+        public SitemapComponent(JavaClass javaClass) {
+            this.javaClass = javaClass;
+            
+            this.name = this.javaClass.getTagByName( NAME_TAG ).getValue();
+            // TEST CODE
+            System.out.println("Name: " + this.name);
+            System.out.println("className: " + this.javaClass.getName());
+            System.out.println();
+            
+            
+            JavaClass[] jc = this.javaClass.getImplementedInterfaces();
+            if (jc.length> 0) {
+                System.out.println("Implemented interfaces:");
+            }
+            for (int i = 0; i < jc.length; i++) {
+                System.out.println(jc[i].getName() + ". Full name: " + jc[i].getFullyQualifiedName());
+            }
+            System.out.println("==== END of implements ===");
+            // END TEST CODE
+            this.type = classType(this.javaClass);
+        }
+        
+        /* (non-Javadoc)
+         * @see java.lang.Object#toString()
+         */
+        public String toString() {
+            return "Sitemap component: " + this.javaClass.getName();
+        }
+        
+        public String getType() {
+            return this.type;
+        }
+        
+        public String getName() {
+            return this.name;
+        }
+        
+        public boolean append(Node parent) {
+            if ( this.getTagValue(HIDDEN_TAG, null) != null ) {
+                return false;
+            }
+            Document doc = parent.getOwnerDocument();
+            Node node;
+            
+            // first check: deprecated?
+            if ( SitemapTask.this.deprecated || this.getTagValue("deprecated", null) != null ) {
+                indent(parent, 3);
+                StringBuffer buffer = new StringBuffer("The ");
+                buffer.append(this.type)
+                .append(" ")
+                .append(this.name)
+                .append(" is deprecated");
+                node = doc.createComment(buffer.toString());
+                parent.appendChild(node);
+                newLine(parent);
+            }
+            // unstable block?
+            if ( !SitemapTask.this.stable ) {
+                indent(parent, 3);
+                StringBuffer buffer = new StringBuffer("The ");
+                buffer.append(this.type)
+                .append(" ")
+                .append(this.name)
+                .append(" is in an unstable block");
+                node = doc.createComment(buffer.toString());
+                parent.appendChild(node);
+                newLine(parent);
+            }
+            
+            indent(parent, 3);
+            node = doc.createElement("map:" + this.type);
+            ((Element)node).setAttribute("name", this.name);
+            ((Element)node).setAttribute("src", this.javaClass.getFullyQualifiedName());
+            
+            // test for logger
+            // TODO Default logger?
+            if ( this.javaClass.isA(LOG_ENABLED) ) {
+                this.addAttribute(node, LOGGER_TAG, "logger", null);
+            }
+            
+            // test for label
+            this.addAttribute(node, LABEL_TAG, "label", null);
+
+            // pooling?
+            if ( this.javaClass.isA(POOLABLE) ) {
+                // TODO - Think about default values
+                this.addAttribute(node, POOL_MAX_TAG, "pool-max", null);
+            }
+            
+            // mime-type
+            if ( this.javaClass.isA(OUTPUT_COMPONENT) ) {
+                this.addAttribute(node, MIMETYPE_TAG, "mime-type", null);
+            }
+            
+            // append node
+            parent.appendChild(node);
+            newLine(parent);
+            
+            // add configuration
+            String configuration = this.getTagValue(CONF_TAG, null);
+            if ( configuration != null ) {
+                configuration = "<root>" + configuration + "</root>";
+                final Document confDoc = DocumentCache.getDocument(configuration, null);
+                setValue(node, null, confDoc.getDocumentElement().getChildNodes());
+            }
+
+            return true;
+        }
+        
+        private void addAttribute(Node node, String tag, String attributeName, String defaultValue) {
+            final String tagValue = this.getTagValue(tag, defaultValue);
+            if ( tagValue != null ) {
+                ((Element)node).setAttribute(attributeName, tagValue);
+            }
+        }
+        
+        private void newLine(Node node) {
+            final Node n = node.getOwnerDocument().createTextNode(LINE_SEPARATOR);
+            node.appendChild(n);
+        }
+        
+        private void indent(Node node, int depth) {
+            final StringBuffer buffer = new StringBuffer();
+            for(int i=0; i < depth*2; i++ ) {
+                buffer.append(' ');
+            }
+            final Node n = node.getOwnerDocument().createTextNode(buffer.toString());
+            node.appendChild(n);
+        }
+        
+        public void generateDocs(Document template, File docFile, Project project) 
+        throws TransformerException {
+
+            final String doc = this.getDocumentation();
+            if ( doc == null ) {
+                if ( docFile.exists() ) {
+                    docFile.delete();
+                }
+                return;
+            }
+            // get body from template
+            final Node body = XPathAPI.selectSingleNode(template, "/document/body");
+            
+            // append root element and surrounding paragraph
+            final String description = "<root><p>" + doc + "</p></root>";
+            String systemURI = null;
+            try {
+                systemURI = docFile.toURL().toExternalForm();
+            } catch (MalformedURLException mue) {
+                // we ignore this
+            }
+            final Document descriptionDoc = DocumentCache.getDocument(description, systemURI);
+            
+            // Title
+            setValue(template, "/document/header/title", 
+                     "Description of the " + this.name + " " + this.type);
+            
+            // Version
+            setValue(template, "/document/header/version",
+                     project.getProperty("version"));
+            
+            // Description
+            setValue(body, "s1[@title='Description']", 
+                     descriptionDoc.getDocumentElement().getChildNodes());
+            
+            // check: deprecated?
+            if ( SitemapTask.this.deprecated || this.getTagValue("deprecated", null) != null ) {
+                Node node = XPathAPI.selectSingleNode(body, "s1[@title='Description']");
+                // node is never null - this is ensured by the test above
+                Element e = node.getOwnerDocument().createElement("note");
+                node.appendChild(e);
+                e.appendChild(node.getOwnerDocument().createTextNode("This component is deprecated."));
+                final String info = this.getTagValue("deprecated", null);
+                if ( info != null ) {
+                    e.appendChild(node.getOwnerDocument().createTextNode(info));
+                }
+            }
+            // check: stable?
+            if ( !SitemapTask.this.stable ) {
+                Node node = XPathAPI.selectSingleNode(body, "s1[@title='Description']");
+                // node is never null - this is ensured by the test above
+                Element e = node.getOwnerDocument().createElement("note");
+                node.appendChild(e);
+                e.appendChild(node.getOwnerDocument().createTextNode("This component is in an unstable block."));
+            }
+            
+            // Info Table
+            final Node tableNode = XPathAPI.selectSingleNode(body, "s1[@title='Info']/table");
+            
+            // Info - Name
+            this.addRow(tableNode, "Name", this.name);
+
+            // Info - Block
+            if ( SitemapTask.this.blockName != null ) {
+                this.addRow(tableNode, "Block", SitemapTask.this.blockName);
+            }
+            
+            // Info - Cacheable
+            if ( this.javaClass.isA(GENERATOR)
+                 || this.javaClass.isA(TRANSFORMER)
+                 || this.javaClass.isA(SERIALIZER)
+                 || this.javaClass.isA(READER)) {
+                
+                String cacheInfo;
+                if ( this.javaClass.isA(CACHEABLE) ) {
+                    cacheInfo = this.getTagValue(CACHING_INFO_TAG, null);
+                    if ( cacheInfo != null ) {
+                        cacheInfo = "Yes - " + cacheInfo;
+                    } else {
+                        cacheInfo = "Yes";
+                    }
+                } else if ( this.javaClass.isA(DEPRECATED_CACHEABLE) ) {
+                    cacheInfo = this.getTagValue(CACHING_INFO_TAG, null);
+                    if ( cacheInfo != null ) {
+                        cacheInfo = "Yes (2.0 Caching) - " + cacheInfo;
+                    } else {
+                        cacheInfo = "Yes (2.0 Caching)";
+                    }
+                } else {
+                    cacheInfo = "No";
+                }
+                this.addRow(tableNode, "Cacheable", cacheInfo);
+            }
+            
+            // Info - mime-type
+            if ( this.javaClass.isA(OUTPUT_COMPONENT) ) {
+                final String value = this.getTagValue(MIMETYPE_TAG, "-");
+                this.addRow(tableNode, "Mime-Type", value);
+            }
+            
+            // Info - Class
+            this.addRow(tableNode, "Class", this.javaClass.getFullyQualifiedName());
+
+            // merge with old doc
+            this.merge(body, docFile);
+            
+            // finally write the doc
+            DocumentCache.writeDocument(docFile, template, SitemapTask.this);            
+        }
+        
+        /**
+         * Merge the sections of the old document with the new generated one.
+         * All sections (s1) of the old document are added to the generated one
+         * if not a section with the same title exists.
+         */
+        private void merge(Node body, File docFile) throws TransformerException {            
+            final Document mergeDocument;
+            try {
+                mergeDocument = DocumentCache.getDocument(docFile, SitemapTask.this);
+            } catch (Exception ignore) {
+                return;
+            }
+            NodeList sections = XPathAPI.selectNodeList(mergeDocument, "/document/body/s1");
+            if ( sections != null ) {
+                for(int i=0; i<sections.getLength(); i++) {
+                    final Element current = (Element)sections.item(i);
+                    final String title = current.getAttribute("title");
+
+                    // is this section not in the template?
+                    if (XPathAPI.selectSingleNode(body, "s1[@title='"+title+"']") == null ) {
+                        body.appendChild(body.getOwnerDocument().importNode(current, true));
+                    }
+                }
+            }
+        }
+        
+        /**
+         * Return the documentation or null
+         * @return
+         */
+        private String getDocumentation() {
+            if ( this.getTagValue(NO_DOC_TAG, null) != null ) {
+                return null;
+            }
+            return this.getTagValue(DOC_TAG, null);
+        }
+        
+        private String getTagValue(String tagName, String defaultValue) {
+            final DocletTag tag = this.javaClass.getTagByName( tagName );
+            if ( tag != null ) {
+                return tag.getValue();
+            }
+            return defaultValue;
+        }
+        
+        private void addRow(Node table, String title, String value) {
+            final Element row = table.getOwnerDocument().createElement("tr");
+            final Element firstColumn = table.getOwnerDocument().createElement("td");
+            firstColumn.appendChild(table.getOwnerDocument().createTextNode(title));
+            final Element secondColumn = table.getOwnerDocument().createElement("td");
+            secondColumn.appendChild(table.getOwnerDocument().createTextNode(value));
+            row.appendChild(firstColumn);
+            row.appendChild(secondColumn);
+            table.appendChild(row);
+        }
+
+        private void setValue(Node node, String xpath, String value) {
+            try {
+                final Node insertNode = (xpath == null ? node : XPathAPI.selectSingleNode(node, xpath));
+                if ( insertNode == null ) {
+                    throw new BuildException("Node (" + xpath + ") not found.");
+                }
+                Node text = insertNode.getOwnerDocument().createTextNode(value);
+                while (insertNode.hasChildNodes() ) {
+                    insertNode.removeChild(insertNode.getFirstChild());
+                }
+                insertNode.appendChild(text);
+            } catch (TransformerException e) {
+                throw new BuildException(e);
+            }
+        }
+
+        private void setValue(Node node, String xpath, NodeList nodes) {
+            try {
+                final Node insertNode = (xpath == null ? node : XPathAPI.selectSingleNode(node, xpath));
+                if ( insertNode == null ) {
+                    throw new BuildException("Node (" + xpath + ") not found.");
+                }
+                while (insertNode.hasChildNodes() ) {
+                    insertNode.removeChild(insertNode.getFirstChild());
+                }
+                for(int i=0; i<nodes.getLength(); i++) {
+                    final Node current = nodes.item(i);
+                    insertNode.appendChild(insertNode.getOwnerDocument().importNode(current, true));
+                }
+            } catch (TransformerException e) {
+                throw new BuildException(e);
+            }
+        }
+    }
+    
+    // Class Constants
+    private static final String LOG_ENABLED = "org.apache.avalon.framework.logger.LogEnabled";
+    private static final String POOLABLE = "org.apache.avalon.excalibur.pool.Poolable";
+
+    private static final String CACHEABLE = "org.apache.cocoon.caching.CacheableProcessingComponent";
+    private static final String DEPRECATED_CACHEABLE = "org.apache.cocoon.caching.Cacheable";
+    
+    private static final String OUTPUT_COMPONENT = "org.apache.cocoon.sitemap.SitemapOutputComponent";
+
+    private static final String GENERATOR = "org.apache.cocoon.generation.Generator";
+    private static final String TRANSFORMER = "org.apache.cocoon.transformation.Transformer";
+    private static final String SERIALIZER = "org.apache.cocoon.serialization.Serializer";
+    private static final String READER = "org.apache.cocoon.reading.Reader";
+    private static final String MATCHER = "org.apache.cocoon.matching.Matcher";
+    private static final String SELECTOR = "org.apache.cocoon.selection.Selector";
+    private static final String ACTION = "org.apache.cocoon.acting.Action";
+    private static final String PIPELINE = "org.apache.cocoon.components.pipeline.ProcessingPipeline";
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/anttasks/XConfToolTask.java b/non-releases/trunk_before_flattening/tools/src/anttasks/XConfToolTask.java
new file mode 100644
index 0000000..4624c73
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/anttasks/XConfToolTask.java
@@ -0,0 +1,420 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Ant task to patch xmlfiles.
+ *
+ * 
+ * replace-properties no|false,anything else
+ * xpath: xpath expression for context node
+ * unless-path: xpath expression that must return empty node set
+ * unless: (deprecated) xpath expression that must return empty node set
+ * if-prop: use path file only when project property is set
+ * remove: xpath expression to remove before adding nodes
+ * add-comments: if specified, overrides the ant task value
+ * add-attribute: name of attribute to add to context node (requires value)
+ * add-attribute-<i>name</i>: add attribute <i>name</i> with the specified value
+ * value: value of attribute to add to context node (requires add-attribute)
+ * insert-before: xpath expression, add new nodes before
+ * insert-after: xpath expression, add new nodes after
+ * 
+ * @version $Id$
+ */
+public final class XConfToolTask extends MatchingTask {
+
+    private static final String NL=System.getProperty("line.separator");
+    private static final String FSEP=System.getProperty("file.separator");
+    
+    private File file;
+    //private File directory;
+    private File srcdir;
+    private boolean addComments;
+    /** for resolving entities such as dtds */
+    private XMLCatalog xmlCatalog = new XMLCatalog();
+
+    /**
+     * Set file, which should be patched.
+     *
+     * @param file File, which should be patched.
+     */
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    /**
+     * Set base directory for the patch files.
+     *
+     * @param srcdir Base directory for the patch files.
+     */
+    public void setSrcdir(File srcdir) {
+        this.srcdir = srcdir;
+    }
+
+    /**
+     * Add the catalog to our internal catalog
+     *
+     * @param xmlCatalog the XMLCatalog instance to use to look up DTDs
+     */
+    public void addConfiguredXMLCatalog(XMLCatalog newXMLCatalog) {
+        this.xmlCatalog.addConfiguredXMLCatalog(newXMLCatalog);
+    }
+
+    /**
+     * Whether to add a comment indicating where this block of code comes
+     * from.
+     */
+    public void setAddComments(Boolean addComments) {
+        this.addComments = addComments.booleanValue();
+    }
+
+    /**
+     * Initialize internal instance of XMLCatalog
+     */
+    public void init() throws BuildException {
+        super.init();
+        xmlCatalog.setProject(this.getProject());
+    }
+
+    /**
+     * Execute task.
+     */
+    public void execute() throws BuildException {
+        if (this.file == null) {
+            throw new BuildException("file attribute is required", this.getLocation());
+        }
+        try {
+            Document document = DocumentCache.getDocument(this.file, this);
+            
+            if (this.srcdir == null) {
+                this.srcdir = this.getProject().resolveFile(".");
+            }
+
+            DirectoryScanner scanner = getDirectoryScanner(this.srcdir);
+            String[] list = scanner.getIncludedFiles();
+            boolean modified = false;
+            // process recursive
+            File patchfile;
+            ArrayList suspended = new ArrayList();
+            boolean hasChanged = false;
+            for (int i = 0; i < list.length; i++) {
+                patchfile = new File(this.srcdir, list[i]);
+                try {
+                    // Adds configuration snippet from the file to the configuration
+                    boolean changed = patch(document, patchfile);
+                    hasChanged |= changed;
+                    if (!changed) {
+                        suspended.add(patchfile);
+                    }
+                } catch (SAXException e) {
+                    log("Ignoring: "+patchfile+"\n(not a valid XML)");
+                }
+            }
+            modified = hasChanged;
+
+            if (hasChanged && !suspended.isEmpty()) {
+                log("Try to apply suspended patch files", Project.MSG_DEBUG);
+            }
+
+            ArrayList newSuspended = new ArrayList();
+            while (hasChanged && !suspended.isEmpty()) {
+                hasChanged = false;
+                for(Iterator i=suspended.iterator(); i.hasNext();) {
+                    patchfile = (File)i.next();
+                    try {
+                         // Adds configuration snippet from the file to the configuration
+                        boolean changed = patch(document, patchfile);
+                        hasChanged |= changed;
+                        if (!changed) {
+                            newSuspended.add(patchfile);
+                        }
+                    } catch (SAXException e) {
+                        log("Ignoring: "+patchfile+"\n(not a valid XML)");
+                    }
+                }
+                suspended = newSuspended;
+                newSuspended = new ArrayList();
+            }
+
+            if (!suspended.isEmpty()) {
+                for(Iterator i=suspended.iterator(); i.hasNext();) {
+                    patchfile = (File)i.next();
+                    log("Dismiss: "+patchfile.toString(), Project.MSG_DEBUG);
+                }
+            }
+
+            if (modified) {
+                DocumentCache.writeDocument(this.file, document, this);
+            } else {
+                log("No Changes: " + this.file, Project.MSG_DEBUG);
+            }
+            DocumentCache.storeDocument(this.file, document, this);
+        } catch (TransformerException e) {
+            throw new BuildException("TransformerException: "+e);
+        } catch (SAXException e) {
+            throw new BuildException("SAXException:" +e);           
+        } catch (DOMException e) {
+            throw new BuildException("DOMException:" +e);           
+        } catch (UnknownHostException e) {
+            throw new BuildException("UnknownHostException.  Probable cause: The parser is " +
+                "trying to resolve a dtd from the internet and no connection exists.\n" +
+                "You can either connect to the internet during the build, or patch \n" +
+                "XConfToolTask.java to ignore DTD declarations when your parser is in use.");
+        } catch (IOException ioe) {
+            throw new BuildException("IOException: "+ioe);
+        }
+    }
+
+    /**
+     * Patch XML document with a given patch file.
+     * 
+     * @param configuration Orginal document
+     * @param component Patch document
+     * @param patchFile Patch file
+     *
+     * @return True, if the document was successfully patched
+     */
+    private boolean patch(final Document configuration,
+                           final File patchFile)
+                           throws TransformerException, IOException, DOMException, SAXException {
+
+        Document component = DocumentCache.getDocument(patchFile, this);
+        String filename = patchFile.toString();
+                            
+        // Check to see if Document is an xconf-tool document
+        Element elem = component.getDocumentElement();
+
+        String extension = filename.lastIndexOf(".")>0?filename.substring(filename.lastIndexOf(".")+1):"";
+        String basename = basename(filename);
+
+        if (!elem.getTagName().equals(extension)) {
+            throw new BuildException("Not a valid xpatch file: "+filename);
+        }
+
+        String replacePropertiesStr = elem.getAttribute("replace-properties");
+
+        boolean replaceProperties = !("no".equalsIgnoreCase(replacePropertiesStr) ||
+                                      "false".equalsIgnoreCase(replacePropertiesStr));
+
+        // Get 'root' node were 'component' will be inserted into
+        String xpath = getAttribute(elem, "xpath", replaceProperties);
+        if ( xpath == null ) {
+            throw new IOException("Attribute 'xpath' is required.");    
+        }
+        NodeList nodes = XPathAPI.selectNodeList(configuration, xpath);
+
+        // Suspend, because the xpath returned not one node
+        if (nodes.getLength() !=1 ) {
+            log("Suspending: "+filename, Project.MSG_DEBUG);
+            return false;
+        }
+        Node root = nodes.item(0);
+
+        // Test that 'root' node satisfies 'component' insertion criteria
+        String testPath = getAttribute(elem, "unless-path", replaceProperties);
+        if (testPath == null || testPath.length() == 0) {
+            // only look for old "unless" attr if unless-path is not present
+            testPath = getAttribute(elem, "unless", replaceProperties);
+        }
+        // Is if-path needed?
+        String ifProp = getAttribute(elem, "if-prop", replaceProperties);
+        boolean ifValue = false;
+        if (ifProp != null && !ifProp.equals("")) {
+            ifValue = Boolean.valueOf(this.getProject().getProperty(ifProp)).booleanValue();
+        }
+
+        if (ifProp != null && ifProp.length() > 0 && !ifValue ) {
+            log("Skipping: " + filename, Project.MSG_DEBUG);
+            return false;
+        } else if (testPath != null && testPath.length() > 0 &&
+            XPathAPI.eval(root, testPath).bool()) {
+            log("Skipping: " + filename, Project.MSG_DEBUG);
+            return false;
+        } else {
+            // Test if component wants us to remove a list of nodes first
+            xpath = getAttribute(elem, "remove", replaceProperties);
+
+            if (xpath != null && xpath.length() > 0) {
+                nodes = XPathAPI.selectNodeList(configuration, xpath);
+
+                for (int i = 0, length = nodes.getLength(); i<length; i++) {
+                    Node node = nodes.item(i);
+                    Node parent = node.getParentNode();
+
+                    parent.removeChild(node);
+                }
+            }
+
+            // Test for an attribute that needs to be added to an element
+            String name = getAttribute(elem, "add-attribute", replaceProperties);
+            String value = getAttribute(elem, "value", replaceProperties);
+
+            if (name != null && name.length() > 0) {
+                if (value == null) {
+                    throw new IOException("No attribute value specified for 'add-attribute' "+
+                                          xpath);
+                }
+                if (root instanceof Element) {
+                    ((Element) root).setAttribute(name, value);
+                }
+            }
+ 
+            // Override addComments from ant task if specified as an attribute
+            String addCommentsAttr = getAttribute(elem, "add-comments", replaceProperties);
+            if ((addCommentsAttr!=null) && (addCommentsAttr.length()>0)) {
+                setAddComments(Boolean.valueOf(addCommentsAttr));
+            }
+
+            // Allow multiple attributes to be added or modified
+            if (root instanceof Element) {
+                NamedNodeMap attrMap = elem.getAttributes();
+                for (int i=0; i<attrMap.getLength(); ++i){
+                    Attr attr = (Attr)attrMap.item(i);
+                    final String addAttr = "add-attribute-";
+                    if (attr.getName().startsWith(addAttr)) {
+                        String key = attr.getName().substring(addAttr.length());
+                        ((Element) root).setAttribute(key, attr.getValue());
+                    }
+                }
+            }
+
+            // Test if 'component' provides desired insertion point
+            xpath = getAttribute(elem, "insert-before", replaceProperties);
+            Node before = null;
+
+            if (xpath != null && xpath.length() > 0) {
+                nodes = XPathAPI.selectNodeList(root, xpath);
+                if (nodes.getLength() == 0) {
+                    log("Error in: "+filename);
+                    throw new IOException("XPath ("+xpath+") returned zero nodes");
+                }
+                before = nodes.item(0);
+            } else {
+                xpath = getAttribute(elem, "insert-after", replaceProperties);
+                if (xpath != null && xpath.length() > 0) {
+                    nodes = XPathAPI.selectNodeList(root, xpath);
+                    if (nodes.getLength() == 0) {
+                        log("Error in: "+filename);
+                        throw new IOException("XPath ("+xpath+") zero nodes.");
+                    }
+                    before = nodes.item(nodes.getLength()-1).getNextSibling();
+                }
+            }
+
+            // Add 'component' data into 'root' node
+            log("Processing: "+filename);
+            NodeList componentNodes = component.getDocumentElement().getChildNodes();
+
+            if (this.addComments) {
+                root.appendChild(configuration.createComment("..... Start configuration from '"+basename+"' "));
+                root.appendChild(configuration.createTextNode(NL));
+            }
+            for (int i = 0; i<componentNodes.getLength(); i++) {
+                Node node = configuration.importNode(componentNodes.item(i),
+                                                     true);
+
+                if (replaceProperties) {
+                    replaceProperties(node);
+                }
+                if (before==null) {
+                    root.appendChild(node);
+                } else {
+                    root.insertBefore(node, before);
+                }
+            }
+            if (this.addComments) {
+                root.appendChild(configuration.createComment("..... End configuration from '"+basename+"' "));
+                root.appendChild(configuration.createTextNode(NL));
+            }
+            return true;
+        }
+    }
+
+    private String getAttribute(Element elem, String attrName, boolean replaceProperties) {
+        String attr = elem.getAttribute(attrName);
+        if (attr == null) {
+            return null;
+        } else if (replaceProperties) {
+            return getProject().replaceProperties(attr);
+        } else {
+            return attr;
+        }
+    }
+
+    private void replaceProperties(Node n) throws DOMException {
+        NamedNodeMap attrs = n.getAttributes();
+        if (attrs != null) {
+            for (int i = 0; i < attrs.getLength(); i++) {
+                Node attr = attrs.item(i);
+                attr.setNodeValue(getProject().replaceProperties(attr.getNodeValue()));     
+            } 
+        }
+        switch (n.getNodeType()) {
+            case Node.ATTRIBUTE_NODE:
+            case Node.CDATA_SECTION_NODE:
+            case Node.TEXT_NODE: {
+                n.setNodeValue(getProject().replaceProperties(n.getNodeValue()));
+                break;
+            }
+            case Node.DOCUMENT_NODE:
+            case Node.DOCUMENT_FRAGMENT_NODE:
+            case Node.ELEMENT_NODE: {
+                Node child = n.getFirstChild();
+                while (child != null) {
+                    replaceProperties(child);
+                    child = child.getNextSibling();
+                }
+                break;
+            }
+            default: {
+                // ignore all other node types
+            }
+        }
+    }
+
+    /** Returns the file name (excluding directories and extension). */
+    private String basename(String fileName) {
+        int start = fileName.lastIndexOf(FSEP)+1; // last '/'
+        int end = fileName.lastIndexOf(".");  // last '.'
+
+        if (end == 0) {
+            end = fileName.length();
+        }
+        return fileName.substring(start, end);
+    }
+}
diff --git a/non-releases/trunk_before_flattening/tools/src/blocks-build.xsl b/non-releases/trunk_before_flattening/tools/src/blocks-build.xsl
new file mode 100644
index 0000000..94b6cb9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/blocks-build.xsl
@@ -0,0 +1,864 @@
+<?xml version="1.0"?>
+
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+    <project default="compile" basedir="." name="blocks">
+      <description>Ant build file generated by blocks-build.xsl to build the Cocoon blocks.</description>
+
+      <filter token="Name"                value="${{fullname}}"/>
+      <filter token="name"                value="${{fullname}}"/>
+      <filter token="year"                value="${{year}}"/>
+      <filter token="version"             value="${{version}}"/>
+      <filter token="date"                value="${{TODAY}}"/>
+      <filter token="released.version"    value="${{released.version}}"/>
+      <filter token="loglevel"            value="${{build.webapp.loglevel}}"/>
+
+      <path id="classpath">
+        <fileset dir="${{lib.core}}">
+          <include name="*.jar"/>
+        </fileset>
+        <fileset dir="${{lib.endorsed}}">
+          <include name="*.jar"/>
+        </fileset>
+        <!-- Currently, we have no JVM dependent libraries
+          <fileset dir="${{lib.core}}/jvm${{target.vm}}">
+             <include name="*.jar"/>
+          </fileset>
+        -->
+        <fileset dir="${{build.blocks}}">
+          <include name="*.jar"/>
+        </fileset>
+        <path location="${{build.mocks}}"/>
+        <path location="${{build.dest}}"/>
+        <pathelement path="${{build.webapp.webinf}}/classes/"/>
+      </path>
+
+      <path id="test.classpath">
+        <fileset dir="${{tools.lib}}">
+          <include name="*.jar"/>
+        </fileset>
+      </path>
+
+      <!-- Text files, which should no compiled or otherwise processed -->
+      <patternset id="unprocessed.text-sources">
+        <exclude name="**/*.java"/>
+        <exclude name="**/package.html"/>
+        <exclude name="**/*.gif"/>
+      </patternset>
+
+      <!-- Binary files, which should no compiled or otherwise processed -->
+      <patternset id="unprocessed.binary-sources">
+        <include name="**/*.gif"/>
+      </patternset>
+
+      <macrodef name="test-include-block">
+        <attribute name="name"/>
+        <sequential>
+          <condition property="include.block.@{{name}}">
+            <and>
+              <equals arg1="${{default.block.mode}}" arg2="include"/>
+              <not><istrue value="${{exclude.block.@{{name}}}}"/></not>
+            </and>
+          </condition>
+          <condition property="internal.exclude.block.@{{name}}">
+            <not><istrue value="${{include.block.@{{name}}}}"/></not>
+          </condition>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="print-excluded-block">
+        <attribute name="name"/>
+        <sequential>
+          <if>
+            <istrue value="${{internal.exclude.block.@{{name}}}}"/>
+            <then>
+              <echo message=" Block '@{{name}}' is excluded from the build."/>
+            </then>
+          </if>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-compile">
+        <attribute name="name"/>
+        <attribute name="package"/>
+        <attribute name="dir"/>
+        <sequential>
+        <!-- Test if this block has special build -->
+          <if>
+            <available file="@{{dir}}/build-special.xml"/>
+            <then>
+              <ant inheritAll="true"
+                   inheritRefs="false"
+                   target="main"
+                   antfile="@{{dir}}/build-special.xml">
+                <property name="block.dir" value="@{{dir}}"/>
+              </ant>
+            </then>
+          </if>
+          <!-- Test if this block has mocks -->
+          <if>
+            <available type="dir" file="@{{dir}}/mocks/"/>
+            <then>
+              <mkdir dir="${{build.blocks}}/@{{name}}/mocks"/>
+              <javac srcdir="@{{dir}}/mocks"
+                     destdir="${{build.blocks}}/@{{name}}/mocks"
+                     debug="${{compiler.debug}}"
+                     optimize="${{compiler.optimize}}"
+                     deprecation="${{compiler.deprecation}}"
+                     target="${{target.vm}}"
+                     nowarn="${{compiler.nowarn}}"
+                     compiler="${{compiler}}">
+                <classpath refid="@{{name}}.classpath"/>
+              </javac>
+            </then>
+          </if>
+          <!-- This is a little bit tricky:
+           As the javac task checks, if a src directory is available and
+           stops if its not available, we use the following property
+           to either point to a jdk dependent directory or - if not
+           available - to the usual java source directory.
+           If someone knows a better solution...
+      -->
+      <!-- Currently, we have no JVM dependent sources
+      <condition property="dependend.vm" value="${{target.vm}}">
+        <available file="@{{dir}}/java${{target.vm}}"/>
+      </condition>
+      <condition property="dependend.vm" value="">
+        <not>
+          <available file="@{{dir}}/java${{target.vm}}"/>
+        </not>
+      </condition>
+      -->
+      <javac destdir="${{build.blocks}}/@{{name}}/dest"
+             debug="${{compiler.debug}}"
+             optimize="${{compiler.optimize}}"
+             deprecation="${{compiler.deprecation}}"
+             target="${{target.vm}}"
+             nowarn="${{compiler.nowarn}}"
+             compiler="${{compiler}}">
+        <src path="@{{dir}}/java"/>
+        <!-- Currently, we have no JVM dependent sources
+        <src path="@{{dir}}/java${{dependend.vm}}"/>
+        -->
+        <classpath refid="@{{name}}.classpath"/>
+        <exclude name="**/samples/**/*.java"/>
+      </javac>
+
+      <copy filtering="on" todir="${{build.blocks}}/@{{name}}/dest">
+        <fileset dir="@{{dir}}/java">
+          <patternset refid="unprocessed.text-sources"/>
+        </fileset>
+      </copy>
+
+      <copy filtering="off" todir="${{build.blocks}}/@{{name}}/dest">
+        <fileset dir="@{{dir}}/java">
+          <patternset refid="unprocessed.binary-sources"/>
+        </fileset>
+      </copy>
+
+      <copy filtering="off" todir="${{build.blocks}}/@{{name}}/dest">
+        <fileset dir="@{{dir}}/java">
+          <include name="**/Manifest.mf"/>
+          <include name="META-INF/**"/>
+        </fileset>
+      </copy>
+      <jar jarfile="${{build.blocks}}/@{{name}}-block.jar" index="true">
+        <fileset dir="${{build.blocks}}/@{{name}}/dest">
+          <include name="@{{package}}/**"/>
+          <include name="META-INF/**"/>
+        </fileset>
+      </jar>
+      <if>
+        <istrue value="${{include.sources-in-jars}}"/>
+        <then>
+          <jar jarfile="${{build.blocks}}/@{{name}}-block.jar" update="true">
+            <fileset dir="@{{dir}}/java">
+              <include name="**/*.java"/>
+            </fileset>
+          </jar>
+        </then>
+      </if>
+
+      <if>
+        <istrue value="${{include.sources-jars}}"/>
+        <then>
+          <jar jarfile="${{build.blocks}}/@{{name}}-block.src.jar">
+            <fileset dir="@{{dir}}/java">
+              <include name="**/*.java"/>
+            </fileset>
+          </jar>
+        </then>
+      </if>
+
+      <!-- exclude sample classes from the block package -->
+      <if>
+        <isfalse value="${{internal.exclude.webapp.samples}}"/>
+        <then>
+          <mkdir dir="${{build.blocks}}/@{{name}}/samples"/>
+          <javac destdir="${{build.blocks}}/@{{name}}/samples"
+             debug="${{compiler.debug}}"
+             optimize="${{compiler.optimize}}"
+             deprecation="${{compiler.deprecation}}"
+             target="${{target.vm}}"
+             nowarn="${{compiler.nowarn}}"
+             compiler="${{compiler}}">
+            <src path="@{{dir}}/java"/>
+            <!-- Currently, we have no JVM dependent sources
+            <src path="@{{dir}}/java${{dependend.vm}}"/>
+            -->
+            <classpath refid="@{{name}}.classpath"/>
+            <include name="**/samples/**/*.java"/>
+          </javac>
+        </then>
+      </if>
+       </sequential>
+      </macrodef>
+
+      <macrodef name="block-patch">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+          <xpatch file="${{build.webapp}}/WEB-INF/cocoon.xconf" srcdir="@{{dir}}" addcomments="true">
+            <include name="conf/*.xconf"/>
+          </xpatch>
+          <xpatch file="${{build.webapp}}/WEB-INF/web.xml" srcdir="@{{dir}}">
+            <include name="conf/*.xweb"/>
+          </xpatch>
+
+          <!-- generate sitemap entries
+          <sitemap-components sitemap="${{build.webapp}}/sitemap.xmap"
+                              source="@{{dir}}/java"
+                              block="@{{name}}">
+            <xsl:if test="@status='unstable'">
+              <xsl:attribute name="stable">false</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="@status='deprecated'">
+              <xsl:attribute name="deprecated">true</xsl:attribute>
+            </xsl:if>
+          </sitemap-components>
+          -->
+
+          <!-- generate sitemap components docs -->
+          <!-- TODO - this is the wrong place for documentation, but currently blocks
+               don't have own docs!
+          <mkdir dir="${{build.context}}/xdocs/userdocs"/>
+          <sitemap-components docDir="${{build.context}}/xdocs/userdocs"
+                              source="@{{dir}}/java"
+                              block="@{{name}}">
+            <xsl:if test="@status='unstable'">
+              <xsl:attribute name="stable">false</xsl:attribute>
+            </xsl:if>
+            <xsl:if test="@status='deprecated'">
+              <xsl:attribute name="deprecated">true</xsl:attribute>
+            </xsl:if>
+          </sitemap-components>
+          -->
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-roles">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+            <xpatch file="${{build.dest}}/org/apache/cocoon/cocoon.roles" srcdir="@{{dir}}">
+                <include name="conf/*.xroles"/>
+            </xpatch>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-patch-samples">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+            <xpatch file="${{build.webapp}}/samples/sitemap.xmap" srcdir="@{{dir}}">
+                <include name="conf/*.samplesxpipe"/>
+            </xpatch>
+            <xpatch file="${{build.webapp}}/WEB-INF/cocoon.xconf" srcdir="@{{dir}}">
+                <include name="conf/*.samplesxconf"/>
+            </xpatch>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-samples">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+          <!-- Test if this block has samples -->
+          <if>
+            <available file="@{{dir}}/samples/sitemap.xmap"/>
+            <then>
+              <!-- Important to use here encoding="iso-8859-1" to avoid
+                   mutilating LATIN-1 characters in the copy operation.
+                   If these were read assuming UTF-8 encoding, umlauts
+                   are invalid byte sequences and get replaced by '?'.
+              
+                   On the other hand, reading UTF-8 files using LATIN-1
+                   encoding is not a problem in this context since every
+                   UTF-8 byte sequence maps to one or more LATIN-1 characters.
+                   We only need to assume that the tokens to be replaced
+                   by the filtering option are written in ASCII only.
+               -->
+              <copy filtering="on" todir="${{build.webapp}}/samples/blocks/@{{name}}" encoding="iso-8859-1">
+                <fileset dir="@{{dir}}/samples">
+                  <exclude name="**/*.gif"/>
+                  <exclude name="**/*.jpg"/>
+                </fileset>
+              </copy>
+              <copy filtering="off" todir="${{build.webapp}}/samples/blocks/@{{name}}">
+                <fileset dir="@{{dir}}/samples">
+                  <include name="**/*.gif"/>
+                  <include name="**/*.jpg"/>
+                </fileset>
+              </copy>
+              <!-- copy sample classes -->
+              <copy todir="${{build.webapp.classes}}" filtering="off">
+                <fileset dir="${{build.blocks}}/@{{name}}/samples"/>
+              </copy>
+            </then>
+          </if>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-lib">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+          <!-- if this block has a lib directory copy those too (deprecated) -->
+          <if>
+            <available type="dir" file="@{{dir}}/lib"/>
+            <then>
+              <echo>
+              NOTICE: the preferred method of including library dependencies in your block
+              is by putting them in lib/optional and then declaring them in gump.xml.
+              </echo>
+              <copy filtering="off" todir="${{build.webapp.lib}}">
+                <fileset dir="@{{dir}}/lib">
+                  <include name="*.jar"/>
+                  <exclude name="servlet*.jar"/>
+                </fileset>
+              </copy>
+            </then>
+          </if>
+          <!-- Test if this block has global WEB-INF files -->
+          <if>
+            <available type="dir" file="@{{dir}}/WEB-INF/"/>
+            <then>
+              <copy filtering="on" todir="${{build.webapp.webinf}}">
+                <fileset dir="@{{dir}}/WEB-INF/">
+                  <include name="**"/>
+                </fileset>
+              </copy>
+            </then>
+          </if>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-tests">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+          <!-- Test if this block has tests -->
+          <if>
+            <available file="@{{dir}}/test"/>
+            <then>
+              <mkdir dir="${{build.blocks}}/@{{name}}/test"/>
+
+              <copy todir="${{build.blocks}}/@{{name}}/test" filtering="on">
+                <fileset dir="@{{dir}}/test" excludes="**/*.java"/>
+              </copy>
+
+              <javac destdir="${{build.blocks}}/@{{name}}/test"
+                     debug="${{compiler.debug}}"
+                     optimize="${{compiler.optimize}}"
+                     deprecation="${{compiler.deprecation}}"
+                     target="${{target.vm}}"
+                     nowarn="${{compiler.nowarn}}"
+                     compiler="${{compiler}}">
+                <src path="@{{dir}}/test"/>
+                <classpath>
+                  <path refid="@{{name}}.classpath"/>
+                  <path refid="test.classpath"/>
+                  <pathelement location="${{build.test}}"/>
+                </classpath>
+              </javac>
+
+              <junit printsummary="yes" fork="yes" failureproperty="junit.test.failed">
+                <jvmarg value="-Djava.endorsed.dirs=lib/endorsed"/>
+                <jvmarg value="-Djunit.test.loglevel=${{junit.test.loglevel}}"/>
+                <jvmarg line="${{junit.test.jvmargs}}"/>
+                <classpath>
+                  <path refid="@{{name}}.classpath"/>
+                  <path refid="test.classpath"/>
+                  <pathelement location="${{build.test}}"/>
+                  <pathelement location="${{build.blocks}}/@{{name}}/test"/>
+                </classpath>
+                <formatter type="plain" usefile="no"/>
+                <formatter type="xml"/>
+                <batchtest todir="${{build.test.output}}">
+                  <fileset dir="${{build.blocks}}/@{{name}}/test">
+                    <include name="${{junit.test.include.1}}"/>
+                    <include name="${{junit.test.include.2}}"/>
+                    <exclude name="**/AllTest.class"/>
+                    <exclude name="**/*$$*Test.class"/>
+                    <exclude name="**/Abstract*.class"/>
+                  </fileset>
+                </batchtest>
+              </junit>
+            </then>
+          </if>
+        </sequential>
+      </macrodef>
+
+      <macrodef name="block-prepare-anteater-tests">
+        <attribute name="name"/>
+        <attribute name="dir"/>
+        <sequential>
+          <!-- Test if this block has Anteater tests -->
+          <if>
+            <available file="@{{dir}}/test/anteater"/>
+            <then>
+              <copy todir="${{build.test}}/anteater">
+                <fileset dir="@{{dir}}/test/anteater"/>
+                <mapper type="glob" from="*.xml" to="@{{name}}-*.xml"/>
+              </copy>
+            </then>
+          </if>
+        </sequential>
+      </macrodef>
+      <xsl:apply-templates select="module"/>
+    </project>
+  </xsl:template>
+
+  <xsl:template match="module">
+    <xsl:variable name="cocoon-blocks" select="project[starts-with(@name, 'cocoon-block-')]"/>
+
+    <target name="init">
+      <condition property="default.block.mode" value="include">
+        <istrue value="${{include.all.blocks}}"/>
+      </condition>
+      <condition property="default.block.mode" value="exclude">
+        <istrue value="${{exclude.all.blocks}}"/>
+      </condition>
+      <property name="default.block.mode" value="include"/>
+      <xsl:for-each select="$cocoon-blocks">
+        <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+        <test-include-block name="{$block-name}"/>
+      </xsl:for-each>
+    </target>
+
+    <target name="unstable" depends="init">
+      <condition property="unstable.blocks.present">
+        <or>
+          <xsl:for-each select="$cocoon-blocks[@status='unstable']">
+            <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+            <isfalse value="${{internal.exclude.block.{$block-name}}}"/>
+          </xsl:for-each>
+        </or>
+      </condition>
+      <if>
+        <istrue value="${{unstable.blocks.present}}"/>
+        <then>
+          <echo message="==================== WARNING ======================="/>
+          <xsl:for-each select="$cocoon-blocks[@status='unstable']">
+            <xsl:sort select="@name"/>
+            <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+            <echo message=" Block '{$block-name}' should be considered unstable."/>
+          </xsl:for-each>
+          <echo message="----------------------------------------------------"/>
+          <echo message="         This means that its API, schemas "/>
+          <echo message="  and other contracts might change without notice."/>
+          <echo message="===================================================="/>
+        </then>
+      </if>
+    </target>
+
+    <target name="excluded" depends="init">
+      <condition property="excluded.blocks.present">
+        <or>
+          <xsl:for-each select="$cocoon-blocks">
+            <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+              <istrue value="${{internal.exclude.block.{$block-name}}}"/>
+          </xsl:for-each>
+        </or>
+      </condition>
+      <if>
+        <istrue value="${{excluded.blocks.present}}"/>
+        <then>
+          <echo message="==================== NOTICE ========================"/>
+          <xsl:for-each select="$cocoon-blocks">
+            <xsl:sort select="@name"/>
+            <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+                <print-excluded-block name="{$block-name}"/>
+          </xsl:for-each>
+          <echo message="===================================================="/>
+        </then>
+      </if>
+    </target>
+
+    <target name="compile">
+      <xsl:attribute name="depends">
+        <xsl:text>unstable,excluded</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-compile')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="patch">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-patch')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+                                                                                                                                                                               
+    <target name="roles">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-roles')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="patch-samples">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-patch-samples')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="samples">
+      <xsl:attribute name="depends">
+        <xsl:text>init,patch-samples</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-samples')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="lib">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-lib')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="tests">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-tests')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <target name="prepare-anteater-tests">
+      <xsl:attribute name="depends">
+        <xsl:text>init</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-prepare-anteater-tests')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+    </target>
+
+    <!-- Check if javadocs have to be generated -->
+    <target name="javadocs-check">
+      <mkdir dir="${{build.javadocs}}"/>
+      <condition property="javadocs.notrequired" value="true">
+        <or>
+          <uptodate targetfile="${{build.javadocs}}/packages.html">
+            <srcfiles dir="${{java}}" includes="**/*.java,**/package.html"/>
+            <srcfiles dir="${{deprecated.src}}" includes="**/*.java,**/package.html"/>
+            <xsl:for-each select="$cocoon-blocks">
+              <srcfiles dir="{@dir}/java" includes="**/*.java,**/package.html"/>
+            </xsl:for-each>
+          </uptodate>
+          <istrue value="${{internal.exclude.javadocs}}"/>
+        </or>
+      </condition>
+    </target>
+
+    <!-- Creates Javadocs -->
+    <target name="javadocs" unless="javadocs.notrequired">
+      <xsl:attribute name="depends">
+        <xsl:text>init, javadocs-check</xsl:text>
+        <xsl:for-each select="$cocoon-blocks">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="concat(@name, '-prepare')"/>
+        </xsl:for-each>
+      </xsl:attribute>
+
+      <condition property="javadoc.additionalparam" value="-breakiterator -tag todo:all:Todo:">
+        <equals arg1="1.4" arg2="${{ant.java.version}}"/>
+      </condition>
+      <condition property="javadoc.additionalparam" value="">
+        <not>
+          <equals arg1="1.4" arg2="${{ant.java.version}}"/>
+        </not>
+      </condition>
+
+      <javadoc destdir="${{build.javadocs}}"
+               author="true"
+               version="true"
+               use="true"
+               noindex="false"
+               splitindex="true"
+               windowtitle="${{Name}} API ${{version}} [${{TODAY}}]"
+               doctitle="${{Name}} API ${{version}}"
+               bottom="Copyright &#169; ${{year}} The Apache Software Foundation. All Rights Reserved."
+               stylesheetfile="${{resources.javadoc}}/javadoc.css"
+               useexternalfile="yes"
+               additionalparam="${{javadoc.additionalparam}}"
+               maxmemory="192m">
+
+        <link packagelistloc="${{resources.javadoc}}/avalon-excalibur"
+              offline="true" href="http://excalibur.apache.org/apidocs"/>
+        <link packagelistloc="${{resources.javadoc}}/avalon-framework"
+              offline="true" href="http://excalibur.apache.org/apidocs"/>
+        <link packagelistloc="${{resources.javadoc}}/j2ee"
+              offline="true" href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api"/>
+        <link packagelistloc="${{resources.javadoc}}/j2se"
+              offline="true" href="http://java.sun.com/j2se/1.4.2/docs/api"/>
+        <link packagelistloc="${{resources.javadoc}}/jstl"
+              offline="true" href="http://java.sun.com/products/jsp/jstl/1.1/docs/api"/>
+        <link packagelistloc="${{resources.javadoc}}/xalan"
+              offline="true" href="http://xml.apache.org/xalan-j/apidocs"/>
+        <link packagelistloc="${{resources.javadoc}}/xerces"
+              offline="true" href="http://xml.apache.org/xerces2-j/javadocs/api"/>
+        <link packagelistloc="${{resources.javadoc}}/log4j"
+              offline="true" href="http://logging.apache.org/log4j/docs/api"/>
+        <link packagelistloc="${{resources.javadoc}}/logkit"
+              offline="true" href="http://avalon.apache.org/avalon/runtime/3.3.0/impl"/>
+
+        <tag name="avalon.component"   scope="types"   description="Avalon component" />
+        <tag name="avalon.service"     scope="types"   description="Implements service:" />
+        <!-- FIXME: javadoc or ant seems to not understand these
+        <tag name="x-avalon.info"      scope="types"   description="Shorthand:" />
+        <tag name="x-avalon.lifestyle" scope="types"   description="Lifestyle:" />
+        -->
+        <tag name="avalon.context"     scope="methods" description="Requires entry:" />
+        <tag name="avalon.dependency"  scope="methods" description="Requires component:" />
+        <tag name="cocoon.sitemap.component.configuration" enabled="false"/>
+        <tag name="cocoon.sitemap.component.documentation" enabled="false"/>
+        <tag name="cocoon.sitemap.component.documentation.caching" enabled="false"/>
+        <tag name="cocoon.sitemap.component.label" enabled="false"/>
+        <tag name="cocoon.sitemap.component.logger" enabled="false"/>
+        <tag name="cocoon.sitemap.component.mimetype" enabled="false"/>
+        <tag name="cocoon.sitemap.component.name" enabled="false"/>
+        <tag name="cocoon.sitemap.component.parameter" enabled="false"/>
+        <tag name="cocoon.sitemap.component.pooling.grow" enabled="false"/>
+        <tag name="cocoon.sitemap.component.pooling.max" enabled="false"/>
+        <tag name="cocoon.sitemap.component.pooling.min" enabled="false"/>
+
+        <packageset dir="${{java}}">
+          <include name="**"/>
+        </packageset>
+        <packageset dir="${{deprecated.src}}">
+          <include name="**"/>
+        </packageset>
+        <xsl:for-each select="$cocoon-blocks">
+          <packageset dir="{@dir}/java">
+            <include name="**"/>
+          </packageset>
+        </xsl:for-each>
+        <classpath>
+          <fileset dir="${{tools.lib}}">
+            <include name="*.jar"/>
+          </fileset>
+          <path refid="classpath" />
+          <xsl:for-each select="$cocoon-blocks">
+            <path refid="{substring-after(@name,'cocoon-block-')}.classpath"/>
+          </xsl:for-each>
+        </classpath>
+      </javadoc>
+    </target>
+
+    <xsl:apply-templates select="$cocoon-blocks"/>
+  </xsl:template>
+
+
+  <xsl:template match="project">
+    <xsl:variable name="block-name" select="substring-after(@name,'cocoon-block-')"/>
+    <xsl:variable name="cocoon-block-dependencies" select="depend[starts-with(@project,'cocoon-block-')]"/>
+
+    <target name="{@name}" unless="internal.exclude.block.{$block-name}"/>
+
+    <target name="{@name}-compile" unless="internal.exclude.block.{$block-name}">
+      <xsl:attribute name="depends">
+        <xsl:if test="depend">
+          <xsl:value-of select="concat(@name, '-prepare,')"/>
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="$cocoon-block-dependencies">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-compile')"/>
+          </xsl:for-each>
+        </xsl:if>
+      </xsl:attribute>
+      <block-compile name="{$block-name}" 
+                     package="{translate(package/text(), '.', '/')}"
+                     dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-patch" unless="internal.exclude.block.{$block-name}">
+      <xsl:attribute name="depends">
+        <xsl:value-of select="concat(@name, '-prepare')"/>
+        <xsl:if test="depend">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="depend[contains(@project,'cocoon-block-')]">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="@project"/><xsl:text>-patch</xsl:text>
+          </xsl:for-each>
+        </xsl:if>
+      </xsl:attribute>
+      <block-patch name="{$block-name}" dir="{@dir}"/>
+      <block-config file="${{build.webapp}}/WEB-INF/xconf/cocoon-{$block-name}.xconf">
+        <xsl:attribute name="depends">
+          <xsl:for-each select="depend[contains(@project,'cocoon-block-')]">
+            <xsl:text>cocoon-</xsl:text><xsl:value-of select="substring-after(@project,'cocoon-block-')"/><xsl:text>,</xsl:text>
+          </xsl:for-each>
+        </xsl:attribute>
+      </block-config>
+    </target>
+                                                                                                                                                                               
+    <target name="{@name}-roles" unless="internal.exclude.block.{$block-name}">
+      <xsl:if test="depend">
+        <xsl:attribute name="depends">
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="depend[contains(@project,'cocoon-block-')]">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-roles')"/>
+          </xsl:for-each>
+        </xsl:attribute>
+      </xsl:if>
+      <block-roles name="{$block-name}" dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-patch-samples" unless="internal.exclude.block.{$block-name}">
+        <block-patch-samples name="{$block-name}" dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-samples" unless="internal.exclude.block.{$block-name}">
+      <xsl:if test="depend">
+        <xsl:attribute name="depends">
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="$cocoon-block-dependencies">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-samples')"/>
+          </xsl:for-each>
+        </xsl:attribute>
+      </xsl:if>
+      <block-samples name="{$block-name}" dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-lib" unless="internal.exclude.block.{$block-name}">
+      <xsl:if test="depend">
+        <xsl:attribute name="depends">
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="$cocoon-block-dependencies">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-lib')"/>
+          </xsl:for-each>
+        </xsl:attribute>
+      </xsl:if>
+
+      <!-- Copy the library depencies -->
+      <xsl:if test="library[not(@bundle='false')]">
+        <copy filtering="off" todir="${{build.webapp.lib}}">
+          <fileset dir="${{lib.optional}}">
+            <xsl:for-each select="library[not(@bundle='false')]">
+              <include name="{@name}*.jar"/>
+            </xsl:for-each>
+          </fileset>
+        </copy>
+      </xsl:if>
+      <block-lib name="{$block-name}" dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-prepare" unless="internal.exclude.block.{$block-name}">
+      <xsl:if test="depend">
+        <xsl:attribute name="depends">
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="$cocoon-block-dependencies">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-prepare')"/>
+          </xsl:for-each>
+        </xsl:attribute>
+      </xsl:if>
+
+      <mkdir dir="${{build.blocks}}/{$block-name}/dest"/>
+
+      <path id="{$block-name}.classpath">
+        <path refid="classpath"/>
+        <xsl:if test="library">
+          <fileset dir="${{lib.optional}}">
+            <xsl:for-each select="library">
+              <include name="{@name}*.jar"/>
+            </xsl:for-each>
+          </fileset>
+        </xsl:if>
+        <!-- include the block/lib directory (deprecated) -->
+        <fileset dir="{@dir}">
+          <include name="lib/*.jar"/>
+        </fileset>
+        <pathelement location="${{build.blocks}}/{$block-name}/mocks"/>
+        <pathelement location="${{build.blocks}}/{$block-name}/dest"/>
+        <pathelement location="${{build.blocks}}/{$block-name}/samples"/>
+        <xsl:for-each select="$cocoon-block-dependencies">
+          <path refid="{substring-after(@project,'cocoon-block-')}.classpath"/>
+        </xsl:for-each>
+      </path>
+    </target>
+
+    <target name="{@name}-tests" unless="internal.exclude.block.{$block-name}">
+      <xsl:attribute name="depends">
+        <xsl:value-of select="@name"/><xsl:text>-compile</xsl:text>
+        <xsl:if test="depend">
+          <xsl:text>,</xsl:text>
+          <xsl:value-of select="@name"/>
+          <xsl:for-each select="$cocoon-block-dependencies">
+            <xsl:text>,</xsl:text>
+            <xsl:value-of select="concat(@project, '-compile')"/>
+          </xsl:for-each>
+        </xsl:if>
+      </xsl:attribute>
+      <block-tests name="{$block-name}" dir="{@dir}"/>
+    </target>
+
+    <target name="{@name}-prepare-anteater-tests" unless="internal.exclude.block.{$block-name}">
+        <block-prepare-anteater-tests name="{$block-name}" dir="{@dir}"/>
+    </target>
+  </xsl:template>
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/cforms-repeater-syntax.xsl b/non-releases/trunk_before_flattening/tools/src/cforms-repeater-syntax.xsl
new file mode 100644
index 0000000..1aa8970
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/cforms-repeater-syntax.xsl
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                              xmlns:fb="http://apache.org/cocoon/forms/1.0#binding"
+                              xmlns:fd="http://apache.org/cocoon/forms/1.0#definition">
+
+<xsl:template match="node()|@*">
+  <xsl:copy>
+    <xsl:apply-templates select="node()|@*"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="fb:repeater">
+  <xsl:copy>
+    <xsl:apply-templates select="@*[not(starts-with(name(), 'unique-'))]"/>
+    <xsl:if test="@unique-row-id and @unique-path and
+                    not(fb:unique-row | fb:identity)">
+      <fb:identity>
+        <fb:value id="{@unique-row-id}" path="{@unique-path}">
+          <xsl:apply-templates select="fd:convertor"/>
+        </fb:value>
+      </fb:identity>
+    </xsl:if>
+    <xsl:apply-templates select="node()[not(self::fd:convertor)]"/>
+  </xsl:copy>
+</xsl:template>
+
+<xsl:template match="fb:unique-row">
+  <xsl:if test="not(../fb:identity)">
+    <fb:identity>
+      <xsl:apply-templates select="fb:unique-field"/>
+    </fb:identity>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="fb:unique-field">
+  <fb:value>
+    <xsl:apply-templates select="node()|@*"/>
+  </fb:value>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/check-jars.xsl b/non-releases/trunk_before_flattening/tools/src/check-jars.xsl
new file mode 100644
index 0000000..872e2fa
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/check-jars.xsl
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+
+<!--+
+    | $Id$
+    |
+    | Simple stylesheet to verify that files defined in lib/jars.xml
+    | actually appear in the lib/ directory, and vice-versa, that files
+    | that appear in the lib/ directory have an entry with a
+    | description in the lib/jars.xml file.
+    |
+    |
+    +-->
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:output indent="yes" method="xml" doctype-public="-//APACHE//DTD Documentation V1.0//EN" doctype-system="../dtd/document-v10.dtd" />
+
+  <xsl:strip-space elements="*" />
+
+  <xsl:param name="stylesheet-path" select="''"/>
+  <xsl:param name="current-jars-path" select="''"/>
+  <xsl:param name="current-jars-file" select="''"/>
+
+  <xsl:variable name="current-jars">
+    <xsl:choose>
+      <xsl:when test="starts-with($current-jars-path, '/')">
+        <!-- absolute current-jars-path => simply use it -->
+        <xsl:value-of select="concat($current-jars-path, '/', $current-jars-file)"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- relative current-jars-path -->
+        <xsl:choose>
+          <xsl:when test="starts-with($stylesheet-path, '/')">
+            <!-- absolute stylesheet path outside of COCOON_HOME, no way until now to find the path back -->
+            <xsl:message terminate="yes">
+              <xsl:text>Absolute stylesheet path makes it impossible to find the current-jars.xml. </xsl:text>
+              <xsl:text>If you need this feature, you have to pass the COCOON_HOME directory as </xsl:text>
+              <xsl:text>param to the stylesheet.</xsl:text>
+            </xsl:message>
+          </xsl:when>
+          <xsl:otherwise>
+            <!-- relative stylesheet-path => build the path to current-jars-path -->
+            <xsl:call-template name="relativize-path">
+              <xsl:with-param name="current-directory" select="$stylesheet-path"/>
+            </xsl:call-template>
+            <xsl:value-of select="concat($current-jars-path, '/', $current-jars-file)"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="current-jars.xml" select="document($current-jars)"/>
+
+  <xsl:variable name="jars.xml" select="/"/>
+
+  <xsl:template match="/">
+    <!-- Validate lib/jars.xml prior to checking files -->
+
+    <!-- Verify that all the entries in lib/jars.xml have appropriate tags -->
+    <xsl:apply-templates select="//file" mode="no-tag"/>
+
+    <!-- Verify that all the file entries are unique -->
+    <xsl:for-each select="$jars.xml/jars/file/lib">
+      <xsl:variable name="this" select="normalize-space(text())"/>
+      <xsl:if test="count($jars.xml/jars/file/lib[normalize-space(text()) = $this]) > 1">
+        <xsl:message terminate="yes">
+  [ERROR] Duplicate entry for file <xsl:value-of select="$this"/>
+
+        </xsl:message>
+      </xsl:if>
+      <!-- ensure a decent filename -->
+      <xsl:if test="not(contains(translate($this, '0123456789', '9999999999'), '9'))">
+        <xsl:message terminate="no">
+  [WARN] Poor filename for file <xsl:value-of select="$this"/>
+  Please add version number or datestamp.
+        </xsl:message>
+      </xsl:if>
+    </xsl:for-each>
+
+    <!-- Verify if files declared in jars.xml appear in the lib/ directory -->
+    <xsl:apply-templates select="jars/file/lib" mode="declared-but-doesnt-appear"/>
+
+    <!-- Verify that files that appear in lib/ are declared in jars.xml -->
+    <xsl:apply-templates select="$current-jars.xml/jars" mode="appears-but-not-declared"/>
+
+    <!-- create the documentation -->
+    <document>
+     <header>
+      <title>Cocoon JARs</title>
+      <authors>
+       <person name="Cocoon Developers" email="dev@cocoon.apache.org"/>
+      </authors>
+     </header>
+     <body>
+     <s1 title="What, why and when...">
+      <p>This is a list of the available jars, what they are, where they come from,
+       and what they do.</p>
+      <table>
+       <tr>
+         <th>Title</th>
+         <th>Jar (type/name)</th>
+         <th>Description</th>
+         <th>Used by</th>
+       </tr>
+       <xsl:apply-templates select="jars/file" mode="documentation"/>
+      </table>
+     </s1>
+    </body>
+   </document>
+  </xsl:template>
+
+  <!-- Template to verify if files declared in jars.xml appear in the
+       lib/ directory
+  -->
+  <xsl:template match="lib" mode="declared-but-doesnt-appear">
+    <xsl:variable name="this" select="normalize-space(text())"/>
+    <xsl:if test="count($current-jars.xml/jars/jar[normalize-space(text()) = $this]) = 0">
+      <xsl:message terminate="yes">
+  [ERROR] File <xsl:value-of select="$this"/> is declared in lib/jars.xml,
+  but doesn't appear in the lib/ directory.
+
+  If this file was removed, please update the lib/jars.xml file to remove
+  this file entry.
+      </xsl:message>
+    </xsl:if>
+  </xsl:template>
+
+  <!-- Template to verify that files that appear in lib/ are declared
+       in jars.xml
+  -->
+  <xsl:template match="jar" mode="appears-but-not-declared">
+    <xsl:variable name="this" select="normalize-space(text())"/>
+    <xsl:if test="count($jars.xml/jars/file/lib[normalize-space(text()) = $this]) = 0">
+      <xsl:choose>
+        <xsl:when test="starts-with($this, 'local/')">
+          <xsl:message>
+  [WARN] Using local library <xsl:value-of select="$this"/> : ensure it
+  doesn't conflict with any other library.
+          </xsl:message>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:message terminate="yes">
+  [ERROR] File <xsl:value-of select="$this"/> appears in the lib/ directory,
+  but is not declared in lib/jars.xml.
+
+  Please update the lib/jars.xml file to include the <xsl:value-of select="$this"/>
+  file together with a description.
+          </xsl:message>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!-- Verify if a file element has a "title" tag -->
+  <xsl:template match="file[not(title)]" mode="no-tag">
+    <xsl:message terminate="yes">
+  [ERROR] Entry for file <xsl:value-of select="normalize-space(lib/text())"/>
+  in the lib/jars.xml does not have a "title" tag.
+
+  Please add a title tag before continuing.
+    </xsl:message>
+  </xsl:template>
+
+  <!-- Verify if a file element has a "description" tag -->
+  <xsl:template match="file[not(description)]" mode="no-tag">
+    <xsl:message terminate="yes">
+  [ERROR] Entry for file <xsl:value-of select="normalize-space(lib/text())"/>
+  in the lib/jars.xml does not have a "description" tag.
+
+  Please add a description tag before continuing.
+    </xsl:message>
+  </xsl:template>
+
+  <!-- Verify if a file element has an "used-by" tag -->
+  <xsl:template match="file[not(used-by)]" mode="no-tag">
+    <xsl:message terminate="yes">
+  [ERROR] Entry for file <xsl:value-of select="normalize-space(lib/text())"/>
+  in the lib/jars.xml does not have a "used-by" tag.
+
+  Please add a used-by tag before continuing.
+    </xsl:message>
+  </xsl:template>
+
+  <!-- Verify if a file element has an "lib" tag -->
+  <xsl:template match="file[not(lib)]" mode="no-tag">
+    <xsl:message terminate="yes">
+  [ERROR] Entry for file <xsl:value-of select="normalize-space(title/text())"/>
+  in the lib/jars.xml does not have a "lib" tag.
+
+  Please add a lib tag before continuing.
+    </xsl:message>
+  </xsl:template>
+
+  <!-- Verify if a file element has an "url" tag -->
+  <xsl:template match="file[not(homepage)]" mode="no-tag">
+    <xsl:message terminate="yes">
+  [ERROR] Entry for file <xsl:value-of select="normalize-space(lib/text())"/>
+  in the lib/jars.xml does not have a "homepage" tag.
+
+  Please add a homepage tag before continuing.
+    </xsl:message>
+  </xsl:template>
+
+  <!-- Format for documentation -->
+  <xsl:template match="file" mode="documentation">
+    <tr>
+      <td><link href="{homepage}"><xsl:value-of select="title"/></link></td>
+      <td><xsl:value-of select="lib"/></td>
+      <td><xsl:value-of select="description"/></td>
+      <td><xsl:value-of select="used-by"/></td>
+    </tr>
+  </xsl:template>
+
+  <xsl:template name="relativize-path">
+    <xsl:param name="current-directory" select="''"/>
+    <xsl:if test="string($current-directory)">
+      <xsl:text>../</xsl:text>
+      <xsl:call-template name="relativize-path">
+        <xsl:with-param name="current-directory" select="substring-after($current-directory, '/')"/>
+      </xsl:call-template>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="file" mode="no-tag" priority="-1"/>
+  <xsl:template match="file" mode="declared-but-doesnt-appear" priority="-1"/>
+  <xsl:template match="file" mode="appears-but-not-declared" priority="-1"/>    
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/classpath-build.xsl b/non-releases/trunk_before_flattening/tools/src/classpath-build.xsl
new file mode 100644
index 0000000..e01da79
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/classpath-build.xsl
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!--
+  To use, transform the gump.xml filewith this stylesheet, install the 
+  Maven Artifact Ant task in your Ant lib dir, and run the generated file.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ 
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/"><xsl:apply-templates select="module"/></xsl:template>
+
+  <xsl:template match="module">
+    <project name="ccocoon-classpath" 
+             xmlns:artifact="antlib:org.apache.maven.artifact.ant" 
+             default="classpath">
+          
+       <description>Autogenerated Ant build file that creates the classpath.</description>
+	   <target name="classpath">
+         <artifact:dependencies pathId="dependency.classpath">
+	        <xsl:for-each select="project">
+               <xsl:for-each select="depend | dependx">
+               
+	               <xsl:choose>
+	               
+	               	<xsl:when test="@locallib">
+	               	 <xsl:comment>
+	               	   <xsl:value-of select="@locallib" />
+	               	 </xsl:comment>
+	               	</xsl:when>
+	               	
+	               	<xsl:when test="@groupId and @artifactId and @version">
+	                   <dependency groupId="{@groupId}" 
+	                               artifactId="{@artifactId}" 
+	                               version="{@version}"/>
+	               	</xsl:when>
+               	
+	               	<xsl:otherwise>
+	               	 <xsl:comment>Skipping <xsl:value-of select="@project" />
+	               	 </xsl:comment>
+	               	</xsl:otherwise>
+	               	
+	               </xsl:choose>
+
+	           </xsl:for-each>
+	       </xsl:for-each>
+         </artifact:dependencies>
+         
+         
+       <path id="local.classpath">
+	        <xsl:for-each select="project">
+               <xsl:for-each select="depend | dependx">
+	              <xsl:if test="@locallib">
+	              	 <path location="lib/{@locallib}"/>
+                  </xsl:if>
+	           </xsl:for-each>
+	       </xsl:for-each>
+       </path>
+    
+    
+        <path id="classpath">
+          <path refid="dependency.classpath"/>
+          <path refid="local.classpath"/>
+        </path>
+
+         
+	   </target>
+	 </project>
+  </xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/gump2blocks.properties.xsl b/non-releases/trunk_before_flattening/tools/src/gump2blocks.properties.xsl
new file mode 100644
index 0000000..293eba3
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/gump2blocks.properties.xsl
@@ -0,0 +1,188 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                              xmlns:desc="description">
+
+<!-- generates blocks.properties from gump.xml -->
+<xsl:output method="text"/>
+
+<xsl:key name="status" match="project[starts-with(@name, 'cocoon-block-')]" use="@status"/>
+<xsl:key name="dependency" match="project[starts-with(@name, 'cocoon-block-')]/depend[starts-with(@project, 'cocoon-block-')]" use="@project"/>
+
+<desc:descs>
+
+<desc:desc name="license">
+#  Copyright 1999-2005 The Apache Software Foundation
+#
+#  Licensed 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.
+#
+</desc:desc>
+
+<desc:desc name="common">
+#------------------------------------------------------------------------------#
+#                             Cocoon Blocks                                    #
+#------------------------------------------------------------------------------#
+
+# Remove blocks from your cocoon distribution by setting the corresponding
+# include property to true or false. The blocks are included by default, i.e. if
+# no property was set.
+
+# NOTE: Don't modify this file directly but make a copy named
+# 'local.blocks.properties' and modify that. The build system will first load
+# 'local.blocks.properties' and properties are immutable in Ant.
+
+# For most cases it is enough that you exclude all blocks and include only those
+# few you want, example:
+# exclude.all.blocks=true
+# include.block.forms=true
+# include.block.template=true
+
+# The opposite is also allowed:
+# include.all.blocks=true
+# exclude.block.scratchpad=true
+
+# If there is a conflict on the same level of granularity:
+# include.block.template=true vs. exclude.block.template=true, 
+# include.all.blocks=true vs. exclude.all.blocks=true
+# it is always resolved in favour of include.* properties. 
+
+# NOTE: "[dependency]" indicates blocks that are required by other blocks.
+# Disabling batik, for example, will result in a RuntimeException when using
+# fop. Dependencies only needed for the block's samples are marked explicitely.
+# This latter information was introduced only short time ago, so do not expect
+# it to be complete.
+
+# NOTE: (to Cocoon committers): blocks.properties is generated from gump.xml
+# using "build generate-blocks.properties". Any changes to blocks definitions
+# must be made in gump.xml, not here.
+
+# All blocks -------------------------------------------------------------------
+
+# Use this property to exclude all blocks at once
+# exclude.all.blocks=true
+
+# Use this property to include all blocks at once
+# include.all.blocks=true
+
+</desc:desc>
+
+<desc:desc name="stable">
+# Stable blocks ----------------------------------------------------------------
+
+# Stable blocks are those that can be considered ready for production and
+# will contain components and API that will remain stable and where
+# developers are committed to back compatibility. In short, stuff that you
+# can depend on.
+
+</desc:desc>
+
+<desc:desc name="unstable">
+# Unstable blocks --------------------------------------------------------------
+
+# Unstable blocks are currently under development and do not guarantee that the
+# contracts they expose (API, xml schema, properties, behavior) will remain
+# constant in time. Developers are not committed to back-compatibility just yet.
+# This doesn't necessarily mean the blocks implementation is unstable or
+# the code can't be trusted for production, but use with care and watch
+# its development as things might change over time before they are marked
+# stable.
+
+</desc:desc>
+
+<desc:desc name="deprecated">
+# Deprecated blocks ------------------------------------------------------------
+
+# Although some of these blocks may have been stable, they are now deprecated
+# in favour of other blocks and therefore are excluded by default from the build.
+# For including one of them you have to set the exclude property into comment in
+# blocks.properties.
+
+</desc:desc>
+
+</desc:descs>
+
+<xsl:template match="/module">
+    <xsl:value-of select="document('')/xsl:stylesheet/desc:descs/desc:desc[@name = 'license']"/>
+    <xsl:value-of select="document('')/xsl:stylesheet/desc:descs/desc:desc[@name = 'common']"/>
+    <xsl:apply-templates
+        select="project[starts-with(@name, 'cocoon-block-')]
+                       [count(. | key('status', @status)[1]) = 1]"
+        mode="group"/>
+</xsl:template>
+
+<xsl:template match="project" mode="group">
+    <xsl:value-of select="document('')/xsl:stylesheet/desc:descs/desc:desc[@name = current()/@status]"/>
+    <!-- unfortunately key('status', @status) does not work with sorting because of a bug in Xalan: 24583 -->
+    <xsl:apply-templates select="../project[starts-with(@name, 'cocoon-block-')][@status = current()/@status]">
+        <xsl:sort select="@name"/>
+    </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="project">
+    <xsl:call-template name="dependency">
+        <xsl:with-param name="elements" select="depend[starts-with(@project, 'cocoon-block-')]"/>
+        <xsl:with-param name="text" select="'depends on'"/>
+    </xsl:call-template>
+
+    <xsl:call-template name="dependency">
+        <xsl:with-param name="elements" select="key('dependency', @name)/.."/>
+        <xsl:with-param name="text" select="'is needed by'"/>
+    </xsl:call-template>
+
+    <!-- TODO: make this configurable externally (dependent on @status or @name) -->
+    <xsl:if test="not(@status='deprecated' or @exclude='true')">#</xsl:if>
+    <xsl:text>include.block.</xsl:text>
+    <xsl:value-of select="substring-after(@name, 'cocoon-block-')"/>
+    <xsl:text>=false&#10;</xsl:text>
+</xsl:template>
+
+<xsl:template name="dependency">
+    <xsl:param name="elements" select="/.."/>
+    <xsl:param name="text" select="''"/>
+    <xsl:if test="$elements">
+        <xsl:text>#-----[dependency]: "</xsl:text>
+        <xsl:value-of select="substring-after(@name, 'cocoon-block-')"/>
+        <xsl:text>" </xsl:text>
+        <xsl:value-of select="$text"/>
+        <xsl:apply-templates select="$elements" mode="dependency">
+            <xsl:sort select="@name | @project"/>
+        </xsl:apply-templates>
+    </xsl:if>
+</xsl:template>
+
+<xsl:template match="project | depend" mode="dependency">
+    <xsl:text> "</xsl:text>
+    <xsl:value-of select="substring-after(concat(@name, @project), 'cocoon-block-')"/>
+    <xsl:text>"</xsl:text>
+    <xsl:if test="@type='samples'"> (for samples)</xsl:if>
+    <xsl:choose>
+        <xsl:when test="position() = last()">.&#10;</xsl:when>
+        <xsl:otherwise>,</xsl:otherwise>
+    </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/jars.xml.tmpl b/non-releases/trunk_before_flattening/tools/src/jars.xml.tmpl
new file mode 100644
index 0000000..5f4574b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/jars.xml.tmpl
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<jars>
+ <jar>@JARS@</jar>
+</jars>
diff --git a/non-releases/trunk_before_flattening/tools/src/loader/Loader.java b/non-releases/trunk_before_flattening/tools/src/loader/Loader.java
new file mode 100644
index 0000000..b857e4b
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/loader/Loader.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.
+ */
+import java.io.File;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import java.util.StringTokenizer;
+
+/**
+ * @version $Id$
+ */
+public class Loader {
+
+    static final boolean VERBOSE = true;
+    
+    static final String REPOSITORIES = "loader.jar.repositories";
+    static final String MAIN_CLASS = "loader.main.class";
+    
+    class RepositoryClassLoader extends URLClassLoader {
+
+        public RepositoryClassLoader(ClassLoader parent) {
+            super(new URL[0], parent);
+        }
+            
+        public void addRepository(File repository) {
+            if (VERBOSE) System.out.println("Processing repository: " + repository);
+
+            if (repository.exists() && repository.isDirectory()) {
+                File[] jars = repository.listFiles();
+    
+                for (int i = 0; i < jars.length; i++) {
+                    if (jars[i].getAbsolutePath().endsWith(".jar")) {
+                        try  {
+                            URL url = jars[i].toURL();
+                            if (VERBOSE) System.out.println("Adding jar: " + jars[i]);
+                            super.addURL(url);                
+                        } catch (MalformedURLException e) {
+                            throw new IllegalArgumentException(e.toString());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        new Loader().run(args);
+    }
+    
+    void run(String[] args) throws Exception 
+    {    
+        String repositories = System.getProperty(REPOSITORIES);
+        if (repositories == null) {
+            System.out.println("Loader requires the '" + REPOSITORIES + "' property to be set");
+            System.exit(1);
+        }
+            
+        String mainClass = System.getProperty(MAIN_CLASS);
+        if (mainClass == null) {
+            System.out.println("Loader requires the '" + MAIN_CLASS + "' property to be set");
+            System.exit(1);
+        }
+
+        if (VERBOSE) System.out.println("-------------------- Loading --------------------");
+
+        RepositoryClassLoader classLoader = new RepositoryClassLoader(this.getClass().getClassLoader());
+
+        StringTokenizer st = new StringTokenizer(repositories, File.pathSeparator);
+        while (st.hasMoreTokens()) {
+            classLoader.addRepository(new File(st.nextToken()));        
+        }        
+
+        Thread.currentThread().setContextClassLoader(classLoader);
+
+        if (VERBOSE) System.out.println("-------------------- Executing -----------------");
+        if (VERBOSE) System.out.println("Main Class: " + mainClass);
+            
+        invokeMain(classLoader, mainClass, args);            
+    }
+        
+    void invokeMain(ClassLoader classloader, String classname, String[] args)
+    throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException 
+    {
+        Class invokedClass = classloader.loadClass(classname);
+        
+        Class[] methodParamTypes = new Class[1];
+        methodParamTypes[0] = args.getClass();
+        
+        Method main = invokedClass.getDeclaredMethod("main", methodParamTypes);
+        
+        Object[] methodParams = new Object[1];
+        methodParams[0] = args;
+        
+        main.invoke(null, methodParams);
+    }    
+}
\ No newline at end of file
diff --git a/non-releases/trunk_before_flattening/tools/src/schematron/README.txt b/non-releases/trunk_before_flattening/tools/src/schematron/README.txt
new file mode 100644
index 0000000..8e611d4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/schematron/README.txt
@@ -0,0 +1,12 @@
+The URL for the RELAX-NG-toSchematron stylesheet is:
+http://www.topologi.com/public/Schtrn_XSD/RNG2Schtrn.zip
+
+The paper describing it all is at:
+http://www.topologi.com/public/Schtrn_XSD/Paper.html
+
+This part of Cocoon utilises basic-schematron stylesheets
+(only the two necessary stylesheets are included here)
+which can be found at:
+http://www.ascc.net/xml/schematron/1.5/
+
+Cocoon copies were last updated on 2002-11-14
diff --git a/non-releases/trunk_before_flattening/tools/src/schematron/RNG2Schtrn.xsl b/non-releases/trunk_before_flattening/tools/src/schematron/RNG2Schtrn.xsl
new file mode 100644
index 0000000..9bb3528
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/schematron/RNG2Schtrn.xsl
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<!--
+	Stylesheet for extracting Schematron information from a RELAX-NG schema.
+	Based on the stylesheet for extracting Schematron information from W3C XML Schema.
+	Created by Eddie Robertsson 2002/06/01
+-->
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+xmlns:sch="http://www.ascc.net/xml/schematron" xmlns:rng="http://relaxng.org/ns/structure/1.0">
+	<!-- Set the output to be XML with an XML declaration and use indentation -->
+	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" standalone="yes"/>
+	<!-- -->
+	<!-- match schema and call recursive template to extract included schemas -->
+	<!-- -->
+	<xsl:template match="/rng:grammar | /rng:element">
+		<!-- call the schema definition template ... -->
+		<xsl:call-template name="gatherSchema">
+			<!-- ... with current node as the $schemas parameter ... -->
+			<xsl:with-param name="schemas" select="."/>
+			<!-- ... and any includes in the $include parameter -->
+			<xsl:with-param name="includes" select="document(/rng:grammar/rng:include/@href
+| //rng:externalRef/@href)"/>
+		</xsl:call-template>
+	</xsl:template>
+	<!-- -->
+	<!-- gather all included schemas into a single parameter variable -->
+	<!-- -->
+	<xsl:template name="gatherSchema">
+		<xsl:param name="schemas"/>
+		<xsl:param name="includes"/>
+		<xsl:choose>
+			<xsl:when test="count($schemas) &lt; count($schemas | $includes)">
+				<!-- when $includes includes something new, recurse ... -->
+				<xsl:call-template name="gatherSchema">
+					<!-- ... with current $includes added to the $schemas parameter ... -->
+					<xsl:with-param name="schemas" select="$schemas | $includes"/>
+					<!-- ... and any *new* includes in the $include parameter -->
+					<xsl:with-param name="includes" select="document($includes/rng:grammar/rng:include/@href
+| $includes//rng:externalRef/@href)"/>
+				</xsl:call-template>
+			</xsl:when>
+			<xsl:otherwise>
+				<!-- we have the complete set of included schemas, so now let's output the embedded schematron -->
+				<xsl:call-template name="output">
+					<xsl:with-param name="schemas" select="$schemas"/>
+				</xsl:call-template>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+	<!-- -->
+	<!-- output the schematron information -->
+	<!-- -->
+	<xsl:template name="output">
+		<xsl:param name="schemas"/>
+		<!-- -->
+		<sch:schema>
+			<!-- get header-type elements - eg title and especially ns -->
+			<!-- title (just one) -->
+			<xsl:copy-of select="$schemas//sch:title[1]"/>
+			<!-- get remaining schematron schema children -->
+			<!-- get non-blank namespace elements, dropping duplicates -->
+			<xsl:for-each select="$schemas//sch:ns">
+				<xsl:if test="generate-id(.) = generate-id($schemas//sch:ns[@prefix = current()/@prefix][1])">
+					<xsl:copy-of select="."/>
+				</xsl:if>
+			</xsl:for-each>
+			<xsl:copy-of select="$schemas//sch:phase"/>
+			<xsl:copy-of select="$schemas//sch:pattern"/>
+			<sch:diagnostics>
+				<xsl:copy-of select="$schemas//sch:diagnostics/*"/>
+			</sch:diagnostics>
+		</sch:schema>
+	</xsl:template>
+	<!-- -->
+</xsl:transform>
diff --git a/non-releases/trunk_before_flattening/tools/src/schematron/schematron-basic.xsl b/non-releases/trunk_before_flattening/tools/src/schematron/schematron-basic.xsl
new file mode 100644
index 0000000..8be0998
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/schematron/schematron-basic.xsl
@@ -0,0 +1,66 @@
+<?xml version="1.0" ?>
+<!-- Basic metastylesheet for the Schematron XML Schema Language.
+	http://www.ascc.net/xml/resource/schematron/schematron.html
+
+ Copyright (c) 2000,2001 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+
+<!-- Schematron basic -->
+
+<xsl:stylesheet
+   version="1.0"
+   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+   xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
+
+<xsl:import href="skeleton1-5.xsl"/>
+
+<xsl:template name="process-prolog">
+   <axsl:output method="text" />
+</xsl:template>
+
+<xsl:template name="process-root">
+   <xsl:param name="title" />
+   <xsl:param name="contents" />
+   <xsl:value-of select="$title" />
+   <xsl:text>&#10;</xsl:text>
+   <xsl:copy-of select="$contents" />
+</xsl:template>
+
+<!-- use default rule for process-pattern: ignore name and see -->
+<!-- use default rule for process-name: output name -->
+<!-- use default rule for process-assert and process-report:
+     call process-message -->
+
+<xsl:template name="process-message">
+   <xsl:param name="pattern" />
+   <xsl:param name="role" />
+   <xsl:text>In pattern </xsl:text>
+   <xsl:value-of select="$pattern" />
+   <xsl:if test="$role">
+      <xsl:text> (</xsl:text>
+      <xsl:value-of select="$role" />
+      <xsl:text>)</xsl:text>
+   </xsl:if>:
+   <xsl:apply-templates mode="text" />
+   <xsl:text>&#10;</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/non-releases/trunk_before_flattening/tools/src/schematron/skeleton1-5.xsl b/non-releases/trunk_before_flattening/tools/src/schematron/skeleton1-5.xsl
new file mode 100644
index 0000000..fde54e5
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/src/schematron/skeleton1-5.xsl
@@ -0,0 +1,556 @@
+<?xml version="1.0"?>
+<!-- Beta Skeleton Module for the Schematron 1.5 XML Schema Language.
+	http://www.ascc.net/xml/schematron/
+ 
+ Copyright (c) 2000,2001 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+<!-- 
+    Version: 2001-06-12
+           * same skeleton now supports namespace or no namespace
+           * parameters to handlers updated for all 1.5 attributes 
+           * diagnostic hints supported: command-line option diagnose=yes|no
+           * phases supported: command-line option phase=#ALL|...
+           * abstract rules
+           * compile-time error messages
+           * 1.6 feature: @match on sch:key  
+          
+    Contributors: Rick Jelliffe (original), Oliver Becker (architecture), 
+             Miloslav Nic (diagnostic, phase, options), Ludwig Svenonius (abstract)
+             Uche Ogbuji (misc. bug fixes), Jim Ancona (SAXON workaround),
+             Eddie Robertsson (misc. bug fixes)
+
+    XSLT versions tested and working as-is: 
+           * MS XML 3
+           * Oracle 
+           * SAXON + Instant Saxon  
+           * XT n.b. key() not available, will die
+
+   XSLT version reliably reported working
+           *  FourThought's Python implementation
+
+    XSLT versions tested and requires small workaround from you
+           * Sablotron does not support import, so merge meta-stylesheets by hand
+           * Xalan for Java 2.0 outputs wrong namespace URI, so alter by hand or script
+           * Xalan for C 1.0 has problem with key, so edit by hand. Find "KEY" below  
+
+   If you create your own meta-stylesheet to override this one, it is a
+   good idea to have both in the same directory and to run the stylesheet
+   from that directory, as many XSLT implementations have ideosyncratic
+   handling of URLs: keep it simple.
+         
+-->
+<xsl:stylesheet version="1.0" 
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 
+	xmlns:sch="http://www.ascc.net/xml/schematron"
+	 >
+<!-- Note that this namespace is not version specific.
+This program implements schematron 1.5 with some 1.6 extensions -->
+<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
+<!-- Category: top-level-element -->
+<xsl:output method="xml" omit-xml-declaration="no" standalone="yes"  indent="yes"/>
+<xsl:param name="block"></xsl:param><!-- reserved -->
+<xsl:param name="phase">
+  <xsl:choose>
+    <xsl:when test="//sch:schema/@defaultPhase">
+      <xsl:value-of select="//sch:schema/@defaultPhase"/>
+    </xsl:when>
+    <xsl:otherwise>#ALL</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+<xsl:param name="hiddenKey"> key </xsl:param><!-- workaround for Xalan4J 2.0 -->
+
+<!-- SCHEMA -->
+<xsl:template match="sch:schema | schema">
+	<axsl:stylesheet version="1.0">
+		<xsl:for-each select="sch:ns | ns">
+			<xsl:attribute name="{concat(@prefix,':dummy-for-xmlns')}" namespace="{@uri}"/>
+		</xsl:for-each>
+ 
+		<xsl:if test="count(sch:title/* | title/* )">
+			<xsl:message>
+				<xsl:text>Warning: </xsl:text>
+				<xsl:value-of select="name(.)"/>
+				<xsl:text> must not contain any child elements</xsl:text>
+			</xsl:message>
+		</xsl:if>
+ 
+		<xsl:call-template name="process-prolog"/>
+		<!-- utility routine for implementations -->
+   		<axsl:template match="*|@*" mode="schematron-get-full-path">
+
+			<axsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
+			<axsl:text>/</axsl:text>
+			<axsl:if test="count(. | ../@*) = count(../@*)">@</axsl:if>
+			<axsl:value-of select="name()"/>
+			<axsl:text>[</axsl:text>
+	  		<axsl:value-of select="1+count(preceding-sibling::*[name()=name(current())])"/>
+	  		<axsl:text>]</axsl:text>
+       	 	</axsl:template>
+
+		<xsl:apply-templates mode="do-keys" 
+                select="sch:pattern/sch:rule/sch:key | pattern/rule/key | sch:key | key "/>
+
+
+		<axsl:template match="/">
+			<xsl:call-template name="process-root">
+				<xsl:with-param name="fpi" select="@fpi"/>
+				<xsl:with-param 	xmlns:sch="http://www.ascc.net/xml/schematron"
+				name="title" select="./sch:title | title"/>
+				<xsl:with-param name="id" select="@id"/>
+				<xsl:with-param name="icon" select="@icon"/>
+				<xsl:with-param name="lang" select="@xml:lang"/>
+				<xsl:with-param name="version" select="@version" />
+				<xsl:with-param name="schemaVersion" select="@schemaVersion" />
+				<xsl:with-param name="contents">
+					<xsl:apply-templates mode="do-all-patterns"/>
+				</xsl:with-param>
+			</xsl:call-template>
+		</axsl:template>
+ 
+		<xsl:apply-templates/>
+		<axsl:template match="text()" priority="-1">
+			<!-- strip characters -->
+		</axsl:template>
+	</axsl:stylesheet>
+</xsl:template>
+
+	<!-- ACTIVE -->
+	<xsl:template match="sch:active | active">
+                <xsl:if test="not(@pattern)">
+                    <xsl:message>Markup Error: no pattern attribute in &lt;active></xsl:message>
+                </xsl:if>
+                <xsl:if test="//sch:rule[@id= current()/@pattern]">
+                    <xsl:message>Reference Error: the pattern  "<xsl:value-of select="@pattern"/>" has been activated but is not declared</xsl:message>
+                </xsl:if>
+        </xsl:template>
+
+	<!-- ASSERT and REPORT -->
+	<xsl:template match="sch:assert | assert">
+                <xsl:if test="not(@test)">
+                    <xsl:message>Markup Error: no test attribute in &lt;assert></xsl:message>
+                </xsl:if>
+		<axsl:choose>
+			<axsl:when test="{@test}"/>
+			<axsl:otherwise>
+				<xsl:call-template name="process-assert">
+					<xsl:with-param name="role" select="@role"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="test" select="normalize-space(@test)" />
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="subject" select="@subject"/>
+					<xsl:with-param name="diagnostics" select="@diagnostics"/>
+				</xsl:call-template>  
+			</axsl:otherwise>
+		</axsl:choose>
+	</xsl:template>
+	<xsl:template match="sch:report | report">
+                <xsl:if test="not(@test)">
+                    <xsl:message>Markup Error: no test attribute in &lt;report></xsl:message>
+                </xsl:if>
+		<axsl:if test="{@test}">
+			<xsl:call-template name="process-report">
+				<xsl:with-param name="role" select="@role"/>
+				<xsl:with-param name="test" select="normalize-space(@test)" />
+				<xsl:with-param name="icon" select="@icon"/>
+				<xsl:with-param name="id" select="@id"/>
+				<xsl:with-param name="subject" select="@subject"/>
+				<xsl:with-param name="diagnostics" select="@diagnostics"/>
+			</xsl:call-template>
+		</axsl:if>
+	</xsl:template>
+
+
+	<!-- DIAGNOSTIC -->
+	<xsl:template match="sch:diagnostic | diagnostic"
+              ><xsl:if test="not(@id)"
+                    ><xsl:message>Markup Error: no id attribute in &lt;diagnostic></xsl:message
+                ></xsl:if><xsl:call-template name="process-diagnostic">
+                <xsl:with-param name="id" select="@id" />
+               </xsl:call-template>
+        </xsl:template>
+
+	<!-- DIAGNOSTICS -->
+	<xsl:template match="sch:diagnostics | diagnostics"/>
+
+	<!-- DIR -->
+	<xsl:template match="sch:dir | dir"  mode="text"
+		><xsl:call-template name="process-dir">
+			<xsl:with-param name="value" select="@value"/>
+		</xsl:call-template>
+	</xsl:template>
+
+	<!-- EMPH -->
+	<xsl:template match="sch:emph | emph"  mode="text"
+		><xsl:call-template name="process-emph"/>
+	</xsl:template>
+
+	<!-- EXTENDS -->
+	<xsl:template match="sch:extends | extends">
+		<xsl:if test="not(@rule)"
+                    ><xsl:message>Markup Error: no rule attribute in &lt;extends></xsl:message
+                ></xsl:if>
+     		<xsl:if test="not(//sch:rule[@abstract='true'][@id= current()/@rule] )
+                    and not(//rule[@abstract='true'][@id= current()/@rule])">
+                    <xsl:message>Reference Error: the abstract rule  "<xsl:value-of select="@rule"/>" has been referenced but is not declared</xsl:message>
+                </xsl:if>
+	        <xsl:call-template name="IamEmpty" />
+
+  		<xsl:if test="//sch:rule[@id=current()/@rule]">
+    			<xsl:apply-templates select="//sch:rule[@id=current()/@rule]"
+				mode="extends"/>
+  		</xsl:if>
+
+	</xsl:template>
+
+	<!-- KEY -->
+	<!-- do we need something to test uniqueness too? --> 
+	<!-- NOTE: if you get complaint about "key" here (e.g. Xalan4C 1.0) replace
+		"key" with "$hiddenKey" -->
+	<xsl:template  match="sch:key | key " mode="do-keys" >
+                <xsl:if test="not(@name)">
+                    <xsl:message>Markup Error: no name attribute in &lt;key></xsl:message>
+                </xsl:if>
+               <xsl:if test="not(@match) and not(../sch:rule)">
+                    <xsl:message>Markup Error:  no match attribute on &lt;key> outside &lt;rule></xsl:message>
+                </xsl:if>
+                <xsl:if test="not(@path)">
+                    <xsl:message>Markup Error: no path attribute in &lt;key></xsl:message>
+                </xsl:if>
+	        <xsl:call-template name="IamEmpty" />
+
+             <xsl:choose>
+			<xsl:when test="@match">
+				<axsl:key match="{@match}" name="{@name}" use="{@path}"/>
+			</xsl:when>
+			<xsl:otherwise>
+				<axsl:key name="{@name}" match="{parent::sch:rule/@context}" use="{@path}"/>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
+      <xsl:template match="sch:key | key"  /><!-- swallow --> 
+
+	<!-- NAME -->
+	<xsl:template match="sch:name | name" mode="text">
+		<axsl:text xml:space="preserve"> </axsl:text>
+			<xsl:if test="@path"
+				><xsl:call-template name="process-name">
+					<xsl:with-param name="name" select="concat('name(',@path,')')"/>
+					<!-- SAXON needs that instead of  select="'name({@path})'"  -->
+				</xsl:call-template>
+			</xsl:if>
+			<xsl:if test="not(@path)"
+				><xsl:call-template name="process-name">
+					<xsl:with-param name="name" select="'name(.)'"/>
+				</xsl:call-template>
+			</xsl:if>
+	        	<xsl:call-template name="IamEmpty" />
+		<axsl:text xml:space="preserve"> </axsl:text>
+	</xsl:template>
+
+	<!-- NS -->
+	<xsl:template match="sch:ns | ns"  mode="do-all-patterns" >
+               <xsl:if test="not(@uri)">
+                    <xsl:message>Markup Error: no uri attribute in &lt;ns></xsl:message>
+                </xsl:if>
+               <xsl:if test="not(@prefix)">
+                    <xsl:message>Markup Error: no prefix attribute in &lt;ns></xsl:message>
+                </xsl:if>
+	        <xsl:call-template name="IamEmpty" />
+		<xsl:call-template name="process-ns" >
+			<xsl:with-param name="prefix" select="@prefix"/>
+			<xsl:with-param name="uri" select="@uri"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template match="sch:ns | ns"  /><!-- swallow -->
+
+	<!-- P -->
+	<xsl:template match="sch:schema/sch:p | schema/p" mode="do-schema-p" >
+		<xsl:call-template name="process-p">
+			<xsl:with-param name="class" select="@class"/>
+			<xsl:with-param name="icon" select="@icon"/>
+			<xsl:with-param name="id" select="@id"/>
+			<xsl:with-param name="lang" select="@xml:lang"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template match="sch:pattern/sch:p | pattern/p" mode="do-pattern-p" >
+		<xsl:call-template name="process-p">
+			<xsl:with-param name="class" select="@class"/>
+			<xsl:with-param name="icon" select="@icon"/>
+			<xsl:with-param name="id" select="@id"/>
+			<xsl:with-param name="lang" select="@xml:lang"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template match="sch:phase/sch:p" /><!-- We don't use these -->
+	<xsl:template match="sch:p | p" />
+
+	<!-- PATTERN -->
+	<xsl:template match="sch:pattern | pattern" mode="do-all-patterns">
+	<xsl:if test="($phase = '#ALL') 
+	or (../sch:phase[@id= ($phase)]/sch:active[@pattern= current()/@id])
+	or (../phase[@id= ($phase)]/active[@id= current()/@id])">
+		<xsl:call-template name="process-pattern">
+			<xsl:with-param name="name" select="@name"/>
+			<xsl:with-param name="id" select="@id"/>
+			<xsl:with-param name="see" select="@see"/>
+			<xsl:with-param name="fpi" select="@fpi"/>
+			<xsl:with-param name="icon" select="@icon"/>
+		</xsl:call-template>
+		<axsl:apply-templates select="/" mode="M{count(preceding-sibling::*)}"/>
+        </xsl:if>
+	</xsl:template>
+	
+	<xsl:template match="sch:pattern | pattern">
+        <xsl:if test="($phase = '#ALL') 
+	or (../sch:phase[@id= ($phase)]/sch:active[@pattern= current()/@id])
+	or (../phase[@id= ($phase)]/active[@id= current()/@id])">
+		<xsl:apply-templates/>
+		<axsl:template match="text()" priority="-1" mode="M{count(preceding-sibling::*)}">
+			<!-- strip characters -->
+		</axsl:template>
+        </xsl:if>
+	</xsl:template>
+
+	<!-- PHASE -->
+	<xsl:template match="sch:phase | phase" >
+                <xsl:if test="not(@id)">
+                    <xsl:message>Markup Error: no id attribute in &lt;phase></xsl:message>
+                </xsl:if>
+	</xsl:template>
+
+	<!-- RULE -->
+	<xsl:template match="sch:rule[not(@abstract='true')] | rule[not(@abstract='true')]">
+                <xsl:if test="not(@context)">
+                    <xsl:message>Markup Error: no context attribute in &lt;rule></xsl:message>
+                </xsl:if>
+		<axsl:template match="{@context}" priority="{4000 - count(preceding-sibling::*)}" mode="M{count(../preceding-sibling::*)}">
+			<xsl:call-template name="process-rule">
+				<xsl:with-param name="id" select="@id"/>
+				<xsl:with-param name="context" select="@context"/>
+				<xsl:with-param name="role" select="@role"/>
+			</xsl:call-template>
+			<xsl:apply-templates/>
+			<axsl:apply-templates mode="M{count(../preceding-sibling::*)}"/>
+		</axsl:template>
+	</xsl:template>
+
+
+	<!-- ABSTRACT RULE -->
+	<xsl:template match="sch:rule[@abstract='true'] | rule[@abstract='true']" >
+		<xsl:if test=" not(@id)">
+                    <xsl:message>Markup Error: no id attribute on abstract &lt;rule></xsl:message>
+                </xsl:if>
+ 		<xsl:if test="@context">
+                    <xsl:message>Markup Error: (2) context attribute on abstract &lt;rule></xsl:message>
+                </xsl:if>
+	</xsl:template>
+
+	<xsl:template match="sch:rule[@abstract='true'] | rule[@abstract='true']"
+		mode="extends" >
+                <xsl:if test="@context">
+                    <xsl:message>Markup Error: context attribute on abstract &lt;rule></xsl:message>
+                </xsl:if>
+			<xsl:apply-templates/>
+	</xsl:template>
+
+	<!-- SPAN -->
+	<xsl:template match="sch:span | span" mode="text">
+		<xsl:call-template name="process-span"
+			><xsl:with-param name="class" select="@class"/>
+		</xsl:call-template>
+	</xsl:template>
+
+	<!-- TITLE -->
+	<!-- swallow -->
+	<xsl:template match="sch:title | title" /> 
+
+	<!-- VALUE-OF -->
+	<xsl:template match="sch:value-of | value-of" mode="text" >
+               <xsl:if test="not(@select)">
+                    <xsl:message>Markup Error: no select attribute in &lt;value-of></xsl:message>
+                </xsl:if>
+	        <xsl:call-template name="IamEmpty" />
+		<axsl:text xml:space="preserve"> </axsl:text>
+		<xsl:choose>
+			<xsl:when test="@select"
+				><xsl:call-template name="process-value-of">
+					<xsl:with-param name="select" select="@select"/>  
+                                   <!-- will saxon have problem with this too?? -->
+				</xsl:call-template>
+			</xsl:when>
+			<xsl:otherwise >
+				<xsl:call-template name="process-value-of"
+					><xsl:with-param name="select" select="'.'"/>
+				</xsl:call-template>
+			</xsl:otherwise>
+                </xsl:choose>
+		<axsl:text xml:space="preserve"> </axsl:text>
+	</xsl:template>
+
+<!-- ============================================================== -->
+	<!-- Text -->
+	<xsl:template match="text()" priority="-1" mode="do-keys">
+		<!-- strip characters -->
+	</xsl:template>
+	<xsl:template match="text()" priority="-1" mode="do-all-patterns">
+		<!-- strip characters -->
+	</xsl:template>
+        <xsl:template match="text()" priority="-1" mode="do-schema-p">
+		<!-- strip characters -->
+	</xsl:template>
+        <xsl:template match="text()" priority="-1" mode="do-pattern-p">
+		<!-- strip characters -->
+	</xsl:template>
+	<xsl:template match="text()" priority="-1">
+		<!-- strip characters -->
+	</xsl:template>
+	<xsl:template match="text()" mode="text">
+		<xsl:value-of select="normalize-space(.)"/>
+	</xsl:template>
+
+	<xsl:template match="text()" mode="inline-text">
+		<xsl:value-of select="."/>
+	</xsl:template>
+
+<!-- ============================================================== -->
+<!-- utility templates -->
+<xsl:template name="IamEmpty">
+	<xsl:if test="count( * )">
+		<xsl:message>
+			<xsl:text>Warning: </xsl:text>
+			<xsl:value-of select="name(.)"/>
+			<xsl:text> must not contain any child elements</xsl:text>
+		</xsl:message>
+	</xsl:if>
+</xsl:template>
+
+<xsl:template name="diagnosticsSplit">
+  <!-- Process at the current point the first of the <diagnostic> elements
+       referred to parameter str, and then recurse -->
+  <xsl:param name="str"/>
+  <xsl:variable name="start">
+    <xsl:choose>
+      <xsl:when test="contains($str,' ')">
+	<xsl:value-of  select="substring-before($str,' ')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="$str"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="end">
+    <xsl:if test="contains($str,' ')">
+      <xsl:value-of select="substring-after($str,' ')"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <xsl:if test="not(string-length(normalize-space($start)) = 0)
+	and not(//sch:diagnostic[@id = ($start)]) and not(//diagnostic[@id = ($start)])">
+	<xsl:message>Reference error: A diagnostic "<xsl:value-of select="string($start)"/>" has been referenced but is not declared</xsl:message>
+  </xsl:if>
+
+  <xsl:if test="string-length(normalize-space($start)) > 0">
+     <xsl:apply-templates 
+        select="//sch:diagnostic[@id = ($start) ] | //diagnostic[@id= ($start) ]"/>
+  </xsl:if>
+
+  <xsl:if test="not($end='')">
+    <xsl:call-template name="diagnosticsSplit">
+      <xsl:with-param name="str" select="$end"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+
+<!-- ============================================================== -->
+
+	<xsl:template match="*">
+		<xsl:message>
+			<xsl:text>Warning: unrecognized element </xsl:text>
+			<xsl:value-of select="name(.)"/>
+		</xsl:message>
+	</xsl:template>
+	<xsl:template match="*" mode="text">
+		<xsl:message>
+			<xsl:text>Warning: unrecognized element </xsl:text>
+			<xsl:value-of select="name(.)"/>
+		</xsl:message>
+	</xsl:template>
+<!-- ============================================================== -->
+	<!-- Default named templates -->
+	<!-- These are the actions that are performed unless overridden -->
+	<xsl:template name="process-prolog"/>
+	<!-- no params -->
+	<xsl:template name="process-root">
+		<xsl:param name="contents"/>
+		<!-- unused params: fpi, title, id, icon, lang, version, schemaVersion -->
+		<xsl:copy-of select="$contents"/>
+	</xsl:template>
+	<xsl:template name="process-assert">
+		<xsl:param name="role"/>
+		<xsl:param name="test"/>
+		<!-- unused parameters: id, icon, diagnostics, subject -->
+		<xsl:call-template name="process-message">
+			<xsl:with-param name="pattern" select="$test"/>
+			<xsl:with-param name="role" select="$role"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template name="process-report">
+		<xsl:param name="role"/>
+		<xsl:param name="test"/>
+		<!-- unused parameters: id, icon, diagnostics, subject -->
+		<xsl:call-template name="process-message">
+			<xsl:with-param name="pattern" select="$test"/>
+			<xsl:with-param name="role" select="$role"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template name="process-diagnostic">
+		<!-- params: id -->
+		<xsl:apply-templates mode="text"/>
+	</xsl:template>
+	<xsl:template name="process-dir" 
+		><xsl:apply-templates mode="inline-text"/></xsl:template>
+	<xsl:template name="process-emph" 
+		><xsl:apply-templates mode="inline-text"/></xsl:template>
+	<xsl:template name="process-name">
+		<xsl:param name="name"
+		/><axsl:value-of select="{$name}"/></xsl:template>
+	<xsl:template name="process-ns" />
+	<!-- unused params: prefix, uri -->
+	<!-- note that this is independent of the use of sch:ns by sch:schema -->
+	<xsl:template name="process-p"/>
+	<!-- unused params: class, id, icon, lang -->
+	<xsl:template name="process-pattern"/>
+	<!-- unused params: name, id, see, fpi, icon -->
+	<xsl:template name="process-rule"/>
+	<!-- unused params: id, context, role -->
+	<xsl:template name="process-span" 
+		><xsl:apply-templates mode="inline-test"/></xsl:template>
+	<xsl:template name="process-value-of">
+		<xsl:param name="select"
+		/><axsl:value-of select="{$select}"/></xsl:template>
+	<!-- default output action: the simplest customization is to just override this -->
+	<xsl:template name="process-message">
+		<!-- params: pattern, role -->
+		<xsl:apply-templates mode="text"/>
+	</xsl:template>
+</xsl:stylesheet>
+
diff --git a/non-releases/trunk_before_flattening/tools/targets/admin-build.xml b/non-releases/trunk_before_flattening/tools/targets/admin-build.xml
new file mode 100644
index 0000000..09d67af
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/admin-build.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="admin">
+
+  <description>
+    Admin targets
+  </description>
+
+  <!-- Create the announcements -->
+  <target name="announcement">
+    <copy file="status.xml" tofile="${build.context}/status.xml" filtering="on"/>
+    <copy file="announcement.xml" tofile="${build.context}/announcement.xml" filtering="on"/>
+    <xslt in="${build.context}/announcement.xml"
+          out="${build.context}/announcement.txt"
+          style="${tools.src}/announcement2txt.xsl"
+          force="true"/>
+  </target>
+
+  <target name="generate-blocks.properties">
+    <xslt in="${gump.descriptor}"
+          out="blocks.properties"
+          style="${tools.src}/gump2blocks.properties.xsl"
+          force="true"/>
+  </target>
+
+<!-- === Gump Targets ====================================================== -->
+
+  <!-- compiles and packages the core classes and the deprecated classes -->
+  <target name="gump-core" depends="package, validate-jars, core-junit-tests"/>
+
+  <!-- compiles and packages a single block identified by ${block-name} -->
+  <target name="gump-block" depends="compile-core, compile-deprecated, prepare-blocks, compile-tests">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="cocoon-block-${block-name}-tests"/>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/compile-build.xml b/non-releases/trunk_before_flattening/tools/targets/compile-build.xml
new file mode 100644
index 0000000..d4b56a4
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/compile-build.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="compile">
+
+  <description>
+    Compilation Targets
+  </description>
+
+  <!-- compilation parts used by all targets -->
+  <presetdef name="cocoon.javac">
+    <javac 
+           debug="${compiler.debug}"
+           optimize="${compiler.optimize}"
+           deprecation="${compiler.deprecation}"
+           target="${target.vm}"
+           source="${source.vm}"
+           nowarn="${compiler.nowarn}"
+           compiler="${compiler}"
+           classpathref="classpath"/>
+   </presetdef>
+
+   <macrodef name="cocoon.compile">
+   <attribute name="destdir"/>
+   <attribute name="srcdir"/>
+   <attribute name="classpathref" default="classpath"/> 
+   <sequential>
+    <mkdir dir="@{destdir}"/>
+    <!-- copy those files that need to be in the classpath -->
+      <copy todir="@{destdir}">
+        <fileset dir="@{srcdir}">
+          <exclude name="**/*.java"/>
+        </fileset>
+      </copy>
+      <cocoon.javac srcdir="@{srcdir}"
+                    destdir="@{destdir}"/>
+      </sequential>
+    </macrodef>
+
+  <!-- compiles everything -->
+  <target name="compile"
+          depends="compile-core, compile-deprecated, compile-tests"/>
+
+  <!-- compiles mocks -->
+  <target name="compile-mocks">
+    <cocoon.compile srcdir="${mocks}"
+                           destdir="${build.mocks}"/>
+  </target>
+
+  <!-- compiles the core -->
+  <target name="compile-core" depends="compile-mocks, clover.on">
+    <cocoon.compile srcdir="${java}"
+                    destdir="${build.dest}"/>
+  	<!-- Let's replace some values in the cocoon.properties file -->
+    <copy file="${java}/org/apache/cocoon/cocoon.properties"
+          overwrite="true" filtering="true"
+          tofile="${build.dest}/org/apache/cocoon/cocoon.properties">
+      <filterset>
+      	<filter token="compiler.debug" value="${compiler.debug}"/>
+      	<filter token="compiler.optimize" value="${compiler.optimize}"/>
+      	<filter token="target.vm" value="${target.vm}"/>
+      	<filter token="source.vm" value="${source.vm}"/>
+      </filterset>
+    </copy>
+  </target>
+
+  <!-- compiles deprecated code -->
+  <target name="compile-deprecated" depends="clover.off"
+          unless="internal.exclude.deprecated">
+    <!--
+    <xpatch file="${build.dest}/org/apache/cocoon/cocoon.roles" 
+            srcdir="${deprecated.conf}"
+            includes="**/*.xroles"/>
+    -->
+    <cocoon.compile srcdir="${deprecated.src}"
+                          destdir="${build.deprecated}"/>
+  </target>
+
+  <!-- compiles tests classes -->
+  <target name="compile-tests"
+          depends="compile-core, compile-deprecated, clover.off">
+
+    <!-- Compile tests -->
+    <cocoon.compile srcdir="${test}"
+                           destdir="${build.test}"
+                           classpathref="test.classpath"/>
+  </target>
+
+<!-- === Package Targets ================================================= -->
+
+   <macrodef name="cocoon.jar">
+   <attribute name="name"/>
+   <attribute name="dir"/>
+   <attribute name="index" default="false"/>
+   <attribute name="update" default="yes"/>   
+   <sequential>
+        <jar jarfile="${build}/@{name}.jar" update="@{update}" index="@{index}">
+          <fileset dir="@{dir}">
+            <include name="**/*.java"/>
+          </fileset>
+        </jar>
+      </sequential>
+    </macrodef>
+   
+   <!-- optionally add source files to the core jar -->
+   <macrodef name="cocoon.package-sources">
+   <attribute name="name"/>
+   <attribute name="dir"/>
+   <sequential>
+       <!-- optionally add source files to the core jar -->
+        <if>
+          <istrue value="${include.sources-in-jars}"/>
+          <then>
+            <cocoon.jar name="@{name}"
+                        dir="@{dir}"/>
+          </then>
+        </if>
+        <if>
+          <istrue value="${include.sources-jars}"/>
+          <then>
+            <cocoon.jar name="@{name}.src"
+                        dir="@{dir}"/>
+          </then>
+        </if>
+      </sequential>
+    </macrodef>
+    
+  <!-- packages everything -->
+  <target name="package"
+          depends="package-core, package-deprecated, package-testcase"/>
+
+  <!-- package the core -->
+  <target name="package-core" depends="compile-core, block-roles">
+    <jar jarfile="${build}/${name}.jar" manifest="${java}/Manifest.mf" index="true">
+      <fileset dir="${build.dest}">
+         <exclude name="**/Manifest.mf"/>
+      </fileset>
+    </jar>
+
+    <cocoon.package-sources name="${name}"
+                            dir="${java}"/>
+ 
+  </target>
+
+  <!-- package deprecated code -->
+  <target name="package-deprecated" depends="compile-deprecated"
+      unless="internal.exclude.deprecated">
+    <jar jarfile="${build}/${name}-deprecated.jar" index="true">
+      <fileset dir="${build.deprecated}"/>
+    </jar>
+    
+    <cocoon.package-sources name="${name}-deprecated"
+                            dir="${deprecated.src}"/>
+  </target>
+
+  <!-- package testcase code -->
+  <target name="package-testcase" depends="compile-tests">
+    <jar jarfile="${build}/${name}-testcase.jar" index="true">
+      <fileset dir="${build.test}"/>
+    </jar>
+ 
+    <cocoon.package-sources name="${name}-testcase"
+                            dir="${test}"/>
+  </target>
+
+<!-- === Block Targets =================================================== -->
+
+  <!-- prepares the blocks build -->
+  <target name="prepare-blocks">
+    <mkdir dir="${build.blocks}"/>
+
+    <copy file="${gump.descriptor}" tofile="${build.temp}/gump.xml" overwrite="true"/>
+    <xpatch file="${build.temp}/gump.xml" srcdir=".">
+       <include name="local.blocks.*.xconf"/>
+    </xpatch>
+    <xslt in="${build.temp}/gump.xml"
+          out="${build.temp}/blocks-build.xml"
+          style="${tools.src}/blocks-build.xsl"/>
+  </target>
+
+  <!-- patch the cocoon role file -->
+  <target name="block-roles" depends="prepare-blocks">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="roles"/>
+  </target>
+
+  <!-- compiles and packages all blocks -->
+  <target name="blocks" depends="compile,prepare-blocks">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="compile"/>
+  </target>
+
+  <target name="call-block-target">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="cocoon-block-${block.name}-${target.name}" />
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/dist-build.xml b/non-releases/trunk_before_flattening/tools/targets/dist-build.xml
new file mode 100644
index 0000000..74639ad
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/dist-build.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="dist">
+
+  <description>
+    Distribution targets
+  </description>
+
+  <target name="dist" description="[admin] Builds the distribution">
+
+    <mkdir dir="${dist.root}"/>
+    <mkdir dir="${dist}"/>
+
+    <copy todir="${dist}/tools">
+      <fileset dir="${tools}">
+        <exclude name="anttasks/**"/>
+        <exclude name="loader/**"/>
+        <exclude name="lib/xalan*"/>
+        <exclude name="lib/xerces*"/>
+        <exclude name="lib/jtidy*"/>
+        <exclude name="lib/xml-apis.jar"/>
+      </fileset>
+    </copy>
+
+    <copy todir="${dist}/lib">
+      <fileset dir="${lib}"/>
+    </copy>
+
+    <copy todir="${dist}/docs">
+      <fileset dir="docs"/>
+    </copy>
+
+    <copy todir="${dist}/src">
+      <fileset dir="${src}"/>
+    </copy>
+
+    <copy todir="${dist}/legal">
+      <fileset dir="${legal}"/>
+    </copy>
+
+    <copy todir="${dist}" filtering="on">
+     <fileset dir=".">
+      <include name="*.txt"/>
+      <include name="DESKTOP.INI"/>
+      <include name="*.bat"/>
+      <include name="*.sh"/>
+      <include name="KEYS"/>
+      <include name="*.xml"/>
+      <include name="*.sample"/>
+      <include name="*.properties"/>
+      <include name="*.xconf"/>
+      <exclude name="local.*"/>
+      <exclude name="announcement.xml"/>
+     </fileset>
+    </copy>
+
+    <chmod perm="+x" file="${dist}/cocoon.sh"/>
+    <chmod perm="+x" file="${dist}/build.sh"/>
+    <chmod perm="+x" file="${dist}/tools/bin/antRun"/>
+    <fixcrlf srcdir="${dist}" includes="**.sh" eol="lf"/>
+    <fixcrlf srcdir="${dist}" includes="antRun" eol="lf"/>
+    <fixcrlf srcdir="${dist}" includes="**.bat" eol="crlf"/>
+
+    <zip zipfile="${dist.target}/${dist.name}-src.zip"
+         basedir="${dist.root}"
+         includes="${dist.name}/**">
+    </zip>
+
+    <tar tarfile="${dist.target}/${dist.name}-src.tar"
+         longfile="gnu">
+         <tarfileset dir="${dist.root}">
+             <include name="${dist.name}/**"/>
+             <exclude name="${dist.name}/cocoon.sh"/>
+             <exclude name="${dist.name}/build.sh"/>
+             <exclude name="${dist.name}/tools/bin/antRun"/>
+         </tarfileset>
+         <tarfileset dir="${dist.root}" mode="755">
+             <include name="${dist.name}/cocoon.sh"/>
+             <include name="${dist.name}/build.sh"/>
+             <include name="${dist.name}/tools/bin/antRun"/>
+         </tarfileset>
+    </tar>
+    <gzip zipfile="${dist.target}/${dist.name}-src.tar.gz" src="${dist.target}/${dist.name}-src.tar"/>
+    <delete file="${dist.target}/${dist.name}-src.tar"/>
+  </target>
+
+  <target name="clean-dist" depends="clean" description="Cleans everything and brings back to original 'SVN checkout' state">
+    <delete dir="${build.root}"/>
+    <delete dir="${tools.tasks.dest}"/>
+    <delete dir="${tools.loader.dest}"/>
+    <delete file="${dist.target}/${dist.name}-src.tar.gz"/>
+    <delete file="${dist.target}/${dist.name}-src.zip"/>
+    <delete dir="${dist.root}"/>
+  </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/docs-build.xml b/non-releases/trunk_before_flattening/tools/targets/docs-build.xml
new file mode 100644
index 0000000..63c12d9
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/docs-build.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="docs">
+
+  <description>
+    Documentation Targets
+  </description>
+
+  <!-- Creates Javadocs -->
+  <target name="javadocs"
+          depends="prepare-blocks"
+          description="Builds the API documentation (javadocs)"
+          unless="internal.exclude.javadocs">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="javadocs"/>
+  </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/ide-build.xml b/non-releases/trunk_before_flattening/tools/targets/ide-build.xml
new file mode 100644
index 0000000..faf456e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/ide-build.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="ide">
+  <description>IDE targets</description>
+
+  <!-- for those who like long names.. -->
+  <target name="eclipse-customized-project" depends="eclipse-project"/>
+  
+  <target name="init-full-eclipse-project">
+    <property name="unconditional.include.all.blocks" value="true"/>
+  </target>
+  
+  <target name="full-eclipse-project" depends="init-full-eclipse-project, eclipse-project" description="Generate the Eclipse project with all cocoon blocks included."/>
+  
+  <!-- Build the Eclipse customized project's files -->
+  <target name="eclipse-project" 
+    description="Generate the Eclipse customized project files (using local.block.properties).">
+    <echo message="Building Eclipse Customized Project Files"/>
+    <xslt in="${gump.descriptor}"
+          out="${build.temp}/blocks-eclipse.xml"
+          style="${tools}/ide/eclipse/blocks-classpath.xsl"/>
+
+    <ant antfile="${build.temp}/blocks-eclipse.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="generate-customized-eclipse-project"/>
+  </target>
+
+  <!-- Generate the Emacs JDE project file -->
+  <target name="emacs-project" description="Generate the Emacs project files">
+    <path id="jar.files">
+      <fileset dir="${build.webapp}/WEB-INF/lib">
+        <include name="*.jar"/>
+      </fileset>
+      <pathelement path="${build.context}/WEB-INF/classes"/>
+    </path>
+    <property name="jar.files" refid="jar.files"/>
+    <copy file="${tools}/ide/emacs/prj.el.in" tofile="prj.el" filtering="yes">
+      <filterset>
+        <filter token="jar.files" value="${jar.files}"/>
+        <filter token="src" value="${java}"/>
+        <filter token="build.webapp" value="${build.webapp}"/>
+      </filterset>
+    </copy>
+  </target>
+
+  <!-- Prepares the webapp to make it directly usable with the eclipse project -->
+  <target name="eclipse-webapp-prepare" depends="eclipse-webapp-delete-jars, eclipse-webapp-restore-roles"
+          description="Prepares the webapp directory to make it usable within Eclipse"/>
+
+  <target name="eclipse-webapp-restore-roles" description="Restore cocoon.roles (for use with eclipse)">
+      <copy file="${build.dest}/org/apache/cocoon/cocoon.roles"
+            tofile="${build.webapp}/WEB-INF/classes/org/apache/cocoon/cocoon.roles"
+            overwrite="yes"/>
+  </target>
+
+  <target name="eclipse-webapp-delete-jars">
+      <!-- delete all jars and class files, they are already included in the project -->
+      <delete>
+          <fileset dir="${build.webapp}/WEB-INF">
+            <include name="lib/*.jar" />
+            <include name="classes/**/*.class" />
+          </fileset>
+      </delete>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/init-build.xml b/non-releases/trunk_before_flattening/tools/targets/init-build.xml
new file mode 100644
index 0000000..b4f62b8
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/init-build.xml
@@ -0,0 +1,248 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="init">
+
+  <description>
+    Initialization Targets
+  </description>
+
+    <!-- Set the timestamps -->
+    <tstamp/>
+
+    <!-- Get the (constant) cocoon properties -->
+    <property file="src/java/org/apache/cocoon/cocoon.properties"/>
+
+    <!-- Detecting the current jvm -->
+    <condition property="target.vm" value="${ant.java.version}">
+      <not>
+        <or>
+          <equals arg1="1.1" arg2="${ant.java.version}"/>
+          <equals arg1="1.2" arg2="${ant.java.version}"/>
+          <equals arg1="1.3" arg2="${ant.java.version}"/>
+        </or>
+      </not>
+    </condition>
+    <fail unless="target.vm">Please use a JVM 1.4 or superior to compile Cocoon ${version}</fail>
+
+    <!-- The location of tools.jar, relative to the JAVA_HOME home. -->
+    <property name="tools.jar" value="${java.home}/../lib/tools.jar"/>
+    <available file="${tools.jar}" property="tools.jar.present"/>
+
+    <!-- Allow users a chance to override without editing the main file -->
+    <property file="${user.home}/cocoon.build.properties"/>
+    <property file="local.build.properties"/>
+
+    <!-- Get the build properties from an external file -->
+    <property file="build.properties"/>
+
+    <!-- Allow users a chance to override without editing the main file -->
+    <property file="${user.home}/cocoon.blocks.properties"/>
+    <property file="local.blocks.properties"/>
+
+    <!-- Get the block properties from an external file -->
+    <property file="blocks.properties"/>
+
+    <!-- Use internal.exclude.XXX shadow props used in the
+      unless target attributes -->
+    <condition property="internal.exclude.webapp.samples">
+      <istrue value="${exclude.webapp.samples}"/>
+    </condition>
+    <condition property="internal.exclude.webapp.test-suite">
+      <istrue value="${exclude.webapp.test-suite}"/>
+    </condition>
+
+    <condition property="internal.exclude.deprecated">
+      <istrue value="${exclude.deprecated}"/>
+    </condition>
+    <condition property="internal.exclude.javadocs">
+      <istrue value="${exclude.javadocs}"/>
+    </condition>
+    <condition property="internal.exclude.validate.jars">
+      <istrue value="${exclude.validate.jars}"/>
+    </condition>
+    <condition property="internal.exclude.validate.config">
+      <istrue value="${exclude.validate.config}"/>
+    </condition>
+
+    <filter token="Name"                value="${fullname}"/>
+    <filter token="name"                value="${fullname}"/>
+    <filter token="year"                value="${year}"/>
+    <filter token="version"             value="${version}"/>
+    <filter token="date"                value="${TODAY}"/>
+    <filter token="released.version"    value="${released.version}"/>
+    <filter token="loglevel"            value="${build.webapp.loglevel}"/>
+    <filter token="logappend"           value="${build.webapp.logappend}"/>
+
+    <!-- Alias for the loglevel -->
+    <property name="loglevel" value="${build.webapp.loglevel}"/>
+
+    <!-- Ant-Contrib tasks -->
+    <taskdef resource="net/sf/antcontrib/antcontrib.properties">
+      <classpath>
+        <pathelement location="tools/lib/ant-contrib-0.6.jar"/>
+      </classpath>      
+    </taskdef>
+
+    <!-- By default use the libs in SVN -->
+    <property name="m2jars" value="false"/>
+    
+    <if>
+      <istrue value="${m2jars}"/>
+      <then>
+        <echo>   !!! Using Maven Artifact Task !!!</echo>
+        <echo>  !!!   Still needs to be coded   !!!</echo>
+        <path id="classpath">
+        </path>
+        <path id="test.classpath">
+        </path>        
+        <path id="task.classpath">
+        </path>        
+       </then>
+     </if>
+     
+    <if>
+      <isfalse value="${m2jars}"/>
+      <then>
+        <!-- Set classpath -->
+        <path id="classpath">
+          <fileset dir="${lib.local}">
+            <include name="*.jar"/>
+          </fileset>
+          <fileset dir="${lib}">
+            <include name="*.jar"/>
+          </fileset>
+          <fileset dir="${lib.endorsed}">
+            <include name="*.jar"/>
+          </fileset>
+          <fileset dir="${lib.core}">
+            <include name="*.jar"/>
+          </fileset>
+          <!-- Currently, we have no JVM dependent libraries
+            <fileset dir="${lib.core}/jvm${target.vm}">
+              <include name="*.jar"/>
+            </fileset>
+          -->
+          <path location="${build.mocks}"/>
+          <path location="${build.dest}"/>
+        </path>
+    
+        <!-- Set classpath for tests -->
+        <path id="test.classpath">
+          <path refid="classpath"/>
+          <pathelement location="${build.dest}" />
+           <!-- FIXME Resolver tests depend on deprecated stuff -->
+          <pathelement location="${build.deprecated}" />
+          <pathelement location="${build.test}" />
+          <fileset dir="${tools.lib}">
+            <include name="*.jar"/>
+          </fileset>
+        </path>
+        
+        <!-- Set classpath for building ant tasks -->
+        <path id="tasks.classpath">
+          <path refid="classpath"/>
+          <fileset dir="${tools.lib}">
+            <include name="*.jar"/>
+          </fileset>
+          <path location="${tools.tasks.dest}"/>
+        </path>
+
+       </then>
+     </if>
+     
+    <!-- compile the ant tasks -->
+    <mkdir dir="${tools.tasks.dest}"/>
+    <javac srcdir="${tools.tasks.src}"
+           destdir="${tools.tasks.dest}"
+           debug="off"
+           optimize="on"
+           deprecation="on"
+           source="1.4"
+           target="1.4"
+           nowarn="on"
+           classpathref="tasks.classpath"/>
+
+    <!-- A task to patch xml files -->
+    <taskdef name="xpatch" classname="XConfToolTask"
+           classpath="${tools.tasks.dest}"/>
+
+    <!-- A task for sitemap components -->
+    <taskdef name="sitemap-components"
+            classname="SitemapTask"
+            classpathref="tasks.classpath"/>
+
+    <!-- A task to add dependencies to block configurations -->
+    <taskdef name="block-config"
+             classname="BlockConfigTask"
+             classpathref="tasks.classpath"/>
+
+    <!-- Jing is used in various targets for XML validation with RELAX NG -->
+    <taskdef name="jing" classname="com.thaiopensource.relaxng.util.JingTask"
+           classpathref="tasks.classpath"/>
+
+    <!-- compile the loader, used to change classpath especially for
+           the CLI and Jetty -->
+    <mkdir dir="${tools.loader.dest}"/>
+    <javac srcdir="${tools.loader.src}"
+           destdir="${tools.loader.dest}"
+           debug="off"
+           optimize="on"
+           deprecation="on"
+           source="1.4"
+           target="1.4"
+           nowarn="on"/>
+
+<!-- === Preparation Targets ============================================= -->
+
+  <!-- Prepare the build directory -->
+    <echo>====================================================================
+                 ${fullname} ${version} [${year}]
+====================================================================
+ Building with ${ant.version}
+--------------------------------------------------------------------
+ Using build file ${ant.file}
+--------------------------------------------------------------------
+ Compiler options:
+   - debug ......... [${compiler.debug}]
+   - optimize ...... [${compiler.optimize}]
+   - deprecation ... [${compiler.deprecation}]
+====================================================================</echo>
+    <mkdir dir="${build}"/>
+
+<!-- === Clean Targets =================================================== -->
+
+  <!-- Clean -->
+  <target name="clean"
+         depends="clean-cocoon,clean-webapp,clean-standalone-demo,osgi.clean"
+         description="Cleans the cocoon build, webapp and standalone-demo"/>
+
+  <!-- Clean the cocoon build directory -->
+  <target name="clean-cocoon" description="Cleans the cocoon build">
+    <delete dir="${build}"/>
+  </target>
+
+  <!-- Clean the webapp -->
+  <target name="clean-webapp" description="Cleans the webapp">
+    <delete dir="${build.webapp}"/>
+  </target>
+
+  <!-- Clean the standalone demo -->
+  <target name="clean-standalone-demo" description="Cleans the standalone-demo">
+    <delete dir="${build.standalone.demo}"/>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/osgi-build.xml b/non-releases/trunk_before_flattening/tools/targets/osgi-build.xml
new file mode 100644
index 0000000..263cd0d
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/osgi-build.xml
@@ -0,0 +1,237 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id: compile-build.xml 193143 2005-06-23 14:18:06Z danielf $ -->
+<project name="osgi">
+
+  <description>OSGi Targets</description>
+  
+  <target name="osgi.init">
+    <property name="build.osgi" value="${build.root}/osgi"/>
+    <property name="build.osgi.webapp" value="${build.osgi}/webapp"/>
+    <property name="build.osgi.servlet" value="${build.osgi}/osgi-servlet"/>    
+    <property name="build.osgi.blocks" value="${build.osgi}/blocks"/>
+    <property name="build.osgi.blocks.template" value="${build.osgi.blocks}/template"/>
+    
+    <property name="build.osgi.bundles.cocoon" value="org.apache.cocoon_1.0.0.jar"/>
+    <property name="build.osgi.bundles.cocoon_webapp" value="org.apache.cocoon_webapp_1.0.0.jar"/>
+    <property name="build.osgi.bundles.cocoon_servlet" value="org.apache.cocoon_servlet_1.0.0.jar"/>    
+    <property name="build.osgi.bundles.template" value="org.apache.cocoon.template_1.0.0.jar"/>        
+    <property name="build.osgi.knopflerfish.fwdir" value="fwdir"/>
+
+    <property name="src.osgi.servlet" value="${src}/osgi-servlet"/>
+    <property name="src.blocks.template" value="${blocks}/template/trunk/java"/>    
+    
+    <mkdir dir="${build.osgi}"/>
+    <mkdir dir="${build.osgi.servlet}"/>    
+    <mkdir dir="${build.osgi.webapp}"/>  
+    <mkdir dir="${build.osgi.blocks}"/>  
+    <mkdir dir="${build.osgi.blocks.template}"/>      
+  </target>
+  
+  <target name="osgi" depends="osgi.bundle.core, osgi.bundle.osgi-servlet, osgi.bundle.webapp, osgi.bundle.block.template" 
+    description="Setup Cocoon to run within OSGi containers">
+  </target>
+  
+  <target name="osgi.clean" depends="osgi.init">
+    <delete dir="${build.osgi}"/>
+    <delete dir="${build.osgi.knopflerfish.fwdir}"/>
+  </target>
+  
+  <target name="osgi.compile-osgi-servlet" depends="osgi.init, compile-core">
+    <path id="osgi.osgi-servlet.classpath">
+      <fileset dir="${lib.core}">
+        <include name="knopflerfish-*.jar"/>
+      </fileset>      
+      <!-- include Cocoon core -->
+      <dirset dir="${build.dest}"/>
+      <pathelement location="${lib.core}/avalon-framework-api-4.3.jar"/>
+      <pathelement location="${lib.core}/avalon-framework-impl-4.3.jar"/>
+      <pathelement location="${lib.core}/commons-lang-2.1.jar"/>
+      <pathelement location="${lib.core}/excalibur-logger-2.1.jar"/>
+      <pathelement location="${lib.core}/servlet-2_3.jar"/>
+    </path>    
+    
+    <javac 
+      debug="${compiler.debug}"
+      optimize="${compiler.optimize}"
+      deprecation="${compiler.deprecation}"
+      target="${target.vm}"
+      source="${source.vm}"
+      nowarn="${compiler.nowarn}"
+      compiler="${compiler}"
+      srcdir="${src.osgi.servlet}"    
+      destdir="${build.osgi.servlet}"  
+      classpathref="osgi.osgi-servlet.classpath"/>
+  </target>
+  
+  <target name="osgi.prepare-webapp" depends="osgi.init">
+    <delete dir="${build.osgi.webapp}"/>
+    <copy file="${webapp}/welcome.xml" tofile="${build.osgi.webapp}/welcome.xml" filtering="on"/>
+    <copy file="${webapp}/not-found.xml" tofile="${build.osgi.webapp}/not-found.xml" filtering="on"/>
+    <copy file="${webapp}/welcome.xslt" tofile="${build.osgi.webapp}/welcome.xslt" filtering="on"/>
+    <copy file="${webapp}/sitemap.xmap" tofile="${build.osgi.webapp}/sitemap.xmap"/>
+    <copy file="${webapp}/wiring.xml" tofile="${build.osgi.webapp}/wiring.xml" filtering="on"/>
+      
+    <copy todir="${build.osgi.webapp}/stylesheets" filtering="on">
+      <fileset dir="${webapp}/stylesheets">
+        <include name="**/*.xslt"/>
+      </fileset>
+    </copy>
+      
+    <copy todir="${build.osgi.webapp}/resources" filtering="off">
+      <fileset dir="${webapp}/resources"/>
+    </copy>
+    
+    <copy todir="${build.osgi.webapp}/samples" filtering="off">
+      <fileset dir="${webapp}/samples"/>
+    </copy>    
+    
+    <!--
+    <delete>
+      <fileset dir="${build.osgi.webapp}/WEB-INF">
+        <include name="cocoon.xconf"/>
+        <include name="logkit.xconf"/>
+      </fileset>      
+    </delete>
+    -->  
+      
+    <copy todir="${build.osgi.webapp}/WEB-INF" filtering="on">
+      <fileset dir="${webapp}/WEB-INF">
+        <exclude name="compile/**"/>          
+      </fileset>
+    </copy>
+      
+    <replace file="${build.osgi.webapp}/sitemap.xmap">
+      <replacetoken><![CDATA[<map:include dir="context://WEB-INF/sitemap-additions" pattern="*.xconf"/>]]></replacetoken>
+      <replacevalue><![CDATA[<!-- excluded by the OSGi Ant task!!!!
+        map:include dir="context://WEB-INF/sitemap-additions" pattern="*.xconf"/-->
+        ]]></replacevalue>
+    </replace>  
+    
+    <replace file="${build.osgi.webapp}/WEB-INF/cocoon.xconf">
+      <replacetoken><![CDATA[<include dir="context://WEB-INF/xconf" pattern="*.xconf"/>]]></replacetoken>
+      <replacevalue><![CDATA[<!-- replaced by the OSGi Ant task
+        include dir="context://WEB-INF/xconf" pattern="*.xconf"/-->
+        
+        <include src="context://WEB-INF/xconf/cocoon-core-sitemap.xconf"/>
+        <include src="context://WEB-INF/sitemap-additions/cocoon-core-sitemap-additions.xconf"/>]]>
+      </replacevalue>
+    </replace> 
+    
+    <replace file="${build.osgi.webapp}/WEB-INF/cocoon.xconf">
+      <replacetoken><![CDATA[<include dir="context://WEB-INF/xconf" pattern="*.samplesxconf"/>]]></replacetoken>
+      <replacevalue><![CDATA[<!-- excluded by the OSGi Ant task!!!!
+        include dir="context://WEB-INF/xconf" pattern="*.samplesxconf"/-->]]></replacevalue>
+    </replace>  
+    
+    <replace file="${build.osgi.webapp}/WEB-INF/logkit.xconf">
+      <replacetoken><![CDATA[<include dir="context://WEB-INF/xconf" pattern="*.logkit"/>]]></replacetoken>
+      <replacevalue><![CDATA[<!-- excluded by the OSGi Ant task!!!!
+        include dir="context://WEB-INF/xconf" pattern="*.logkit"/-->]]></replacevalue>
+    </replace>
+
+    <replace file="${build.osgi.webapp}/WEB-INF/cocoon.xconf">
+      <replacetoken><![CDATA[</cocoon>]]></replacetoken>
+      <replacevalue><![CDATA[<!-- included by the OSGi Ant task!!!! -->
+          <include src="resource://org/apache/cocoon/components/expression/expression.roles"/>
+          <component role="org.apache.cocoon.template.script.ScriptManager" class="org.apache.cocoon.template.script.DefaultScriptManager"/>
+          <component role="org.apache.cocoon.template.script.InstructionFactory" class="org.apache.cocoon.template.script.DefaultInstructionFactory"/>      
+          <expression-compilers>
+            <component-instance class="org.apache.cocoon.components.expression.jxpath.JXPathCompiler" name="default"/>
+            <component-instance class="org.apache.cocoon.components.expression.jexl.JexlCompiler" name="jexl"/>
+            <component-instance class="org.apache.cocoon.components.expression.jxpath.JXPathCompiler" name="jxpath"/>
+          </expression-compilers>
+        </cocoon>]]></replacevalue>
+    </replace>          
+    
+  </target>
+  
+  <target name="osgi.block.template" depends="osgi.init, compile-core">
+    <path id="osgi.blocks.template.classpath">
+      <fileset dir="${lib.core}">
+        <include name="*.jar"/>
+      </fileset>   
+      <fileset dir="${lib.endorsed}">
+        <include name="*.jar"/>
+      </fileset>         
+      <!-- include Cocoon core -->
+      <dirset dir="${build.dest}"/>
+    </path>    
+    
+    <javac 
+      debug="${compiler.debug}"
+      optimize="${compiler.optimize}"
+      deprecation="${compiler.deprecation}"
+      target="${target.vm}"
+      source="${source.vm}"
+      nowarn="${compiler.nowarn}"
+      compiler="${compiler}"
+      srcdir="${src.blocks.template}"    
+      destdir="${build.osgi.blocks.template}"  
+      classpathref="osgi.blocks.template.classpath"/> 
+       
+    <copy todir="${build.osgi.blocks.template}" filtering="off">
+      <fileset dir="${src.blocks.template}">
+        <include name="**/*.roles"/>
+        <include name="**/*.xml"/>        
+      </fileset>
+    </copy>
+    
+  </target>
+  
+  <target name="osgi.bundle.core" depends="osgi.init, compile-core"> 
+    
+    <!-- note: packaging OSGI packages is only provisional; of course we will need a more generic build system in the future -->
+  
+    <!-- the Cocoon core bundle -->
+    <jar file="${build.osgi}/${build.osgi.bundles.cocoon}" manifest="${build.dest}/Manifest.mf">
+      <fileset dir="${build.dest}/">
+        <exclude name="Manifest.mf"/>
+        <include name="**"/>
+      </fileset>
+      <fileset dir="${lib.core}">
+        <include name="*.jar"/>
+        <exclude name="knopflerfish-*.jar"/>
+      </fileset>
+      <fileset dir="${lib.endorsed}">
+        <include name="*.jar"/>
+      </fileset>      
+    </jar>
+  </target>
+
+  <!-- the osgi-servlet bundle -->
+  <target name="osgi.bundle.osgi-servlet" depends="osgi.compile-osgi-servlet"> 
+    <jar file="${build.osgi}/${build.osgi.bundles.cocoon_servlet}" manifest="${src.osgi.servlet}/Manifest.mf">
+      <fileset dir="${build.osgi.servlet}"/>
+    </jar>
+  </target>
+
+  <!-- the Cocoon webapp bundle -->
+  <target name="osgi.bundle.webapp" depends="osgi.prepare-webapp"> 
+    <jar file="${build.osgi}/${build.osgi.bundles.cocoon_webapp}" manifest="${webapp}/Manifest.mf">
+      <fileset dir="${build.osgi.webapp}"/>
+    </jar>
+  </target>
+
+  <!-- the templating bundle -->
+  <target name="osgi.bundle.block.template" depends="osgi.block.template"> 
+    <jar file="${build.osgi}/${build.osgi.bundles.template}" manifest="${src.blocks.template}/Manifest.mf">
+      <fileset dir="${build.osgi.blocks.template}"/>
+    </jar>
+  </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/samples-build.xml b/non-releases/trunk_before_flattening/tools/targets/samples-build.xml
new file mode 100644
index 0000000..2c8dd1a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/samples-build.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="samples">
+
+  <description>
+    Samples Targets
+  </description>
+
+  <target name="samples" depends="clover.off"
+          unless="internal.exclude.webapp.samples">
+    <mkdir dir="${build.samples}"/>
+
+    <cocoon.javac srcdir="${samples}"
+                  destdir="${build.samples}"/>
+
+    <!-- copy sample files -->
+    <copy todir="${build.webapp.samples}" filtering="on">
+      <fileset dir="${webapp.samples}">
+        <exclude name="samples.xwelcome"/>
+        <exclude name="old_sitemap.xmap"/>
+        <exclude name="**/*.jpg"/>
+        <exclude name="**/*.gif"/>
+        <exclude name="**/*.png"/>
+        <exclude name="**/*.zip"/>
+        <exclude name="**/*.sxw"/>
+        <!-- filtering breaks UTF-8 files -->
+        <exclude name="i18n/**"/>
+      </fileset>
+    </copy>
+
+    <copy todir="${build.webapp.samples}" filtering="off">
+      <fileset dir="${webapp.samples}">
+        <include name="**/*.jpg"/>
+        <include name="**/*.gif"/>
+        <include name="**/*.png"/>
+        <include name="**/*.zip"/>
+        <include name="**/*.sxw"/>
+        <include name="i18n/**"/>
+        <include name="hello-world/style/**"/>
+      </fileset>
+    </copy>
+
+    <!-- copy gump.xml which is used to create block samples page -->
+    <copy file="${gump.descriptor}" todir="${build.webapp.samples}/blocks"/>
+
+    <!-- copy sample classes -->
+    <copy todir="${build.webapp.classes}" filtering="off">
+      <fileset dir="${build.samples}"/>
+    </copy>
+
+    <!-- patch the welcome page to tell we have samples to show -->
+    <xpatch file="${build.webapp}/welcome.xml"
+            srcdir="${webapp.samples}"
+            includes="**/*.xwelcome"/>
+  </target>
+
+  <target name="block-samples" unless="internal.exclude.webapp.samples">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="samples"/>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/standalone-demo-build.xml b/non-releases/trunk_before_flattening/tools/targets/standalone-demo-build.xml
new file mode 100644
index 0000000..4e17aa2
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/standalone-demo-build.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="standalone">
+<!--
+    ant include file for "standalone-demo" build
+ -->
+
+<target name="standalone-demo" depends="webapp" description="build webapp and copy files for standalone demo">
+
+    <!-- setup -->
+    <mkdir dir="${build.standalone.demo}"/>
+    <property name="readme.txt" value="${build.standalone.demo}/readme-standalone.txt"/>
+
+    <!-- copy files that cocoon.sh needs to run so that they can be moved out of the build tree easily -->
+    <copy todir="${build.standalone.demo}">
+        <fileset dir=".">
+            <include name="${lib.endorsed}/**"/>
+            <include name="${tools.loader.dest}/**"/>
+            <include name="${tools.jetty}/**"/>
+            <include name="cocoon.sh"/>
+            <include name="cocoon.bat"/>
+        </fileset>
+    </copy>
+
+    <!-- fix permissions and line endings -->
+    <chmod perm="+x" file="${build.standalone.demo}/cocoon.sh"/>
+    <fixcrlf srcdir="${build.standalone.demo}" includes="**.sh" eol="lf"/>
+    <fixcrlf srcdir="${build.standalone.demo}" includes="**.bat" eol="crlf"/>
+
+    <!-- create readme.txt for users -->
+    <echo file="${readme.txt}">
+Cocoon standalone-demo
+----------------------
+After building this version with "build standalone-demo" from the main Cocoon distribution
+directory, copying the ${build.standalone.demo} and ${build.webapp} directories
+somewhere else provides you with a simple standalone Cocoon installation, meant for
+test and demo purposes.
+
+To start this standalone demo use either "./cocoon.sh servlet" or "cocoon.bat servlet" in the
+standalone-demo directory.
+
+The webapp directory must be found as "../webapp" for this to work:
+
+        common-parent-directory
+                |
+                +----------- standalone-demo
+                +----------- webapp
+
+Note that the version of the jetty servlet engine that is included with this demo
+is not the full version. For production uses, we recommend that you get a complete
+servlet engine and install it according to your needs.
+
+Have fun!
+Your friendly neighbourhood Cocoon team.
+</echo>
+
+    <!-- all done -->
+    <echo>--- standalone-demo build ready! -----------------------------------------
+See ${readme.txt} for more info.
+--------------------------------------------------------------------------
+    </echo>
+
+</target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/test-build.xml b/non-releases/trunk_before_flattening/tools/targets/test-build.xml
new file mode 100644
index 0000000..91f7301
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/test-build.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="test">
+  <description>Test targets</description>
+
+  <!--+
+      | Runs all tests
+      +-->
+  <target name="test" depends="junit-tests, anteater-tests"
+          description="Runs all tests"/>
+
+  <!--+
+      | Runs JUnit tests
+      +-->
+
+  <target name="junit-tests" depends="core-junit-tests, block-junit-tests, junit-tests-report"
+          description="Runs JUnit tests"/>
+
+  <target name="junit-tests-prepare">
+    <delete dir="${build.test.output}"/>
+    <delete dir="${build.test.report}"/>
+    <mkdir dir="${build.test.output}"/>
+  </target>
+
+  <!-- Runs JUnit tests -->
+  <target name="core-junit-tests" depends="compile-tests, junit-tests-prepare">
+    <junit printsummary="yes" fork="yes" failureproperty="junit.test.failed">
+      <jvmarg value="-Djava.endorsed.dirs=lib/endorsed"/>
+      <jvmarg value="-Djunit.test.loglevel=${junit.test.loglevel}"/>
+      <jvmarg line="${junit.test.jvmargs}"/>
+      <classpath>
+        <path refid="test.classpath"/>
+      </classpath>
+      <formatter type="plain" usefile="no"/>
+      <formatter type="xml"/>
+      <batchtest todir="${build.test.output}">
+        <fileset dir="${build.test}">
+          <include name="${junit.test.include.1}"/>
+          <include name="${junit.test.include.2}"/>
+          <exclude name="**/AllTest.class" />
+          <exclude name="**/CocoonBeanTestCase.class" />
+          <exclude name="**/*$$*Test.class" />
+          <exclude name="**/Abstract*.class" />
+          <exclude name="**/SitemapComponentTestCase*"/>
+          <exclude name="**/SitemapTestCase*"/>
+          <exclude name="**/ContainerTestCase*"/>
+          <exclude name="**/CocoonTestCase*"/>
+        </fileset>
+      </batchtest>
+    </junit>
+  </target>
+
+  <!-- Runs one JUnit test -->
+  <target name="core-junit-test" depends="compile-tests, junit-tests-prepare">
+    <fail unless="junit.testcase"
+          message="Please set the property $${junit.testcase} to a JUnit testcase (package.Classname, e.g. org.test.MyTestCase)."/>
+    <junit printsummary="yes" fork="yes" failureproperty="junit.test.failed">
+      <jvmarg value="-Djava.endorsed.dirs=lib/endorsed"/>
+      <jvmarg value="-Djunit.test.loglevel=${junit.test.loglevel}"/>
+      <classpath>
+        <path refid="test.classpath"/>
+      </classpath>
+      <formatter type="plain" usefile="no"/>
+      <formatter type="xml"/>
+      <test name="${junit.testcase}" todir="${build.test.output}"/>
+    </junit>
+  </target>
+
+  <!-- Runs JUnit tests in debug mode -->
+  <target name="junit-test-debug" depends="compile-tests, junit-tests-prepare">
+    <fail unless="junit.testcase"
+          message="Please set the property $${junit.testcase} to a JUnit testcase (package.Classname, e.g. org.test.MyTestCase)."/>
+
+    <echo message="The JVM will be suspended until you connect with your favourite debugger to port ${junit.test.debugport}."/>
+    <junit printsummary="yes" fork="yes" failureproperty="junit.test.failed">
+      <jvmarg value="-Xdebug"/>
+      <jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${junit.test.debugport}"/>
+      <jvmarg value="-Djunit.test.loglevel=${junit.test.loglevel}"/>
+      <classpath refid="test.classpath"/>
+      <formatter type="plain"/>
+      <formatter type="xml"/>
+      <test name="${junit.testcase}" todir="${build.test.output}"/>
+    </junit>
+  </target>
+
+  <!-- Block tests -->
+  <target name="block-junit-tests" depends="compile-tests, prepare-blocks">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="tests"/>
+  </target>
+
+  <target name="junit-tests-report">
+    <mkdir dir="${build.test.report}"/>
+    <junitreport todir="${build.test.output}">
+      <fileset dir="${build.test.output}">
+       <include name="TEST-*.xml"/>
+      </fileset>
+      <report format="frames" todir="${build.test.report}"/>
+    </junitreport>
+    <echo message="Unit report is at ${build.test.report}/index.html"/>
+    <fail if="junit.test.failed"
+          message="One or more JUnit tests failed or caused errors. Please have a look into the report for details."/>
+  </target>
+
+
+  <!--+
+      | Anteater tests
+      +-->
+
+  <!-- Anteater tests  -->
+  <target name="anteater-tests" depends="block-anteater-tests, core-anteater-tests"
+          description="Runs AntEater tests"/>
+
+  <!-- Ant macro that calls anteater -->
+  <macrodef name="call-anteater">
+    <attribute name="script"/>
+    <attribute name="target"/>
+    <attribute name="targetfile"/>
+    <sequential>
+      <java classname="org.apache.tools.ant.Main" fork="true" failonerror="true">
+        <classpath>
+          <fileset dir="${anteater.home}">
+            <include name="lib/**/*.jar"/>
+            <include name="tomcat/**/*.jar"/>
+          </fileset>
+          <pathelement location="${anteater.home}/resources"/>
+        </classpath>
+        <jvmarg value="-Dant.home=${anteater.home}"/>
+        <jvmarg value="-Danteater.home=${anteater.home}"/>
+        <jvmarg value="-Danteater.resources=${anteater.home}/resources"/>
+        <jvmarg value="-Danteater.report=${anteater.home}/resources/scripts/report.xml"/>
+        <jvmarg value="-Djava.endorsed.dirs=${anteater.home}/lib"/>
+        <arg line="-f ${build.test}/anteater/@{script} -Dhost=${anteater.target.host} -Dport=${anteater.target.port} -Dbase=${anteater.target.base.path} -Ddefault.haltonerror=${anteater.option.haltonerror} -Dtargetfile=@{targetfile} @{target}"/>
+      </java>
+    </sequential>
+  </macrodef>
+
+  <target name="anteater-tests-prepare">
+    <!-- check whether Anteater is installed and available -->
+    <!-- anteater parameters are set in build.properties -->
+    <available file="${anteater.home}" property="anteater.present"/>
+    <fail unless="anteater.present"
+          message="To use anteater, please install it and set anteater.home (currently ${anteater.home}) in your local.build.properties"/>
+
+    <echo>*** Anteater notes ***</echo>
+    <echo>a) To run these tests, another instance of Cocoon must be</echo>
+    <echo>   running at ${anteater.target.host}:${anteater.target.port} (base path=${anteater.target.base.path})</echo>
+    <echo>b) JDK 1.4.x is required to run these tests, but running them</echo>
+    <echo>   under 1.4.x to test Cocoon running under 1.3.x should be ok.</echo>
+    <echo>c) anteater options can be set in local.build.properties, and some</echo>
+    <echo>   tests only run if enabled there.</echo>
+  </target>
+
+  <!-- Anteater tests  -->
+  <target name="core-anteater-tests" depends="compile-tests, anteater-tests-prepare"
+          description="Runs anteater tests">
+    <call-anteater script="run-tests.xml" target="all" targetfile=""/>
+  </target>
+
+  <!-- Run a SINGLE Anteater tests -->
+  <target name="anteater-test" depends="compile-tests, anteater-tests-prepare, block-anteater-tests"
+          description="Runs a single Anteater test">
+    <echo>d) to run the tests in 'calc.xml' call 'build anteater-test -Dtarget=calc'</echo>
+    <call-anteater script="run-tests.xml" target="single" targetfile="${target}"/>
+  </target>
+
+  <!-- Block tests -->
+  <target name="block-anteater-tests" depends="prepare-blocks">
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="prepare-anteater-tests"/>
+  </target>
+
+
+
+  <!--+
+      | Clover tasks
+      +-->
+  <target name="clover">
+    <available property="clover.present"
+               classname="com.cortexeb.tools.clover.tasks.CloverTask">
+      <classpath refid="classpath"/>
+    </available>
+    <!-- echo message="Clover present: ${clover.present}"/ -->
+  </target>
+
+  <target name="clover.init" depends="clover" if="clover.present">
+    <taskdef resource="clovertasks"/>
+  </target>
+
+  <target name="clover.on" depends="clover.init" if="clover.present">
+    <!-- echo message="Clover is ON!"/ -->
+    <echo message="Clover is present? ${clover.present}"/>
+    <clover-setup initString="${build}/clover/coverage.db"
+                  tmpdir="${build}/clover/src"
+                  preserve="false"
+                  enabled="true"/>
+  </target>
+
+  <target name="clover.off" depends="clover.init" if="clover.present">
+    <!-- echo message="Clover is OFF!"/ -->
+    <clover-setup enabled="false"/>
+  </target>
+
+  <target name="clover.historypoint" depends="clover.init" if="clover.present">
+    <clover-historypoint historyDir="${build}/clover/history"/>
+  </target>
+
+  <target name="clover.report" depends="clover.on" if="clover.present">
+    <clover-report>
+      <current outfile="${build}/clover-report">
+        <format type="html"/>
+      </current>
+      <historical outfile="${build}/clover-history"
+                  historyDir="${build}/clover/history">
+        <format type="html"/>
+      </historical>
+    </clover-report>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/tools-build.xml b/non-releases/trunk_before_flattening/tools/targets/tools-build.xml
new file mode 100644
index 0000000..72c283c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/tools-build.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="tools">
+  <description>
+    Tools provided by Ant which could be helpful
+  </description>
+
+  <target
+    name="correctLinefeed"
+    description="Make sure LF is used as line feed">
+
+    <echo message="-------------------------------------------------------------------------------"/>
+    <echo message="Make sure you don't have any binaries (except *.jpg, *.gif, *.jar and *.zip  in the directory (or any subdirectory) which you want to correct."/>
+    <echo message="-------------------------------------------------------------------------------"/>
+
+    <input message="Please enter the basedir which should be corrected:" addproperty="target.dir"/>
+
+    <fixcrlf srcdir="${target.dir}"
+       eol="lf"
+       includes="**/*"
+       excludes="**/*.jpg,**/*.gif,**/*.jar,**/*.zip"
+    />
+
+  </target>
+
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/upgrade-build.xml b/non-releases/trunk_before_flattening/tools/targets/upgrade-build.xml
new file mode 100644
index 0000000..121592e
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/upgrade-build.xml
@@ -0,0 +1,287 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="upgrade">
+  <description>
+    Upgrade targets that help to convert between different Cocoon versions
+  </description>
+
+  <tstamp>
+    <format property="timestamp" pattern="yyyyMMdd_kkmmss"/>
+  </tstamp>
+
+  <target
+    name="Woody2CocoonForms"
+    description="Updates from Woody to CocoonForms">
+
+<echo>
+-----------------------------------------------------------------------------
+Woody 2 Cocoon Forms update
+-----------------------------------------------------------------------------
+This target is now going to update your Woody files to Cocoon Forms files.
+Therefore you have to specify a source and a target dir.
+
+All .xml, .xsl, .xslt, .xmap and .js/.flow files found in the source directory
+(and any subdirectory) will be copied to the target dir and updated there. The
+source directory itself remains untouched.
+-----------------------------------------------------------------------------
+</echo>
+
+    <input message="Please enter the source dir with the files that should be updated:"
+           addproperty="src.dir"
+           defaultvalue="./src/blocks/woody/samples"/>
+    <available file="${src.dir}" type="dir" property="src.dir.exists"/>
+    <fail unless="src.dir.exists" message="The entered directory doesn't exist!"/>
+
+<echo>
+-----------------------------------------------------------------------------
+For the target directory a default directory name is given, you can specify
+another one of course if you want.
+The default directory name for the target directory is:
+./build/woody2cforms_${timestamp}
+-----------------------------------------------------------------------------
+</echo>
+
+    <input message="Please enter the target directory in which the output should be stored:"
+           addproperty="target.dir"
+           defaultvalue="./build/woody2cforms_${timestamp}"/>
+
+<echo>
+-----------------------------------------------------------------------------
+The update process is now going to start.
+-----------------------------------------------------------------------------
+</echo>
+
+    <property name="temp.dir" value="${target.dir}_temp"/>
+
+    <copy todir="${target.dir}">
+      <fileset dir="${src.dir}">
+        <include name="**/*.xml"/>
+        <include name="**/*.xsl"/>
+        <include name="**/*.xslt"/>
+        <include name="**/*.xmap"/>
+        <include name="**/*.js"/>
+        <include name="**/*.flow"/>
+      </fileset>
+    </copy>
+
+    <!-- namespace changes from Woody to CocoonForms
+         * from xmlns:wd="http://apache.org/cocoon/woody/definition/1.0"
+           to   xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
+         * from xmlns:wb="http://apache.org/cocoon/woody/binding/1.0"
+           to   xmlns:fb="http://apache.org/cocoon/forms/1.0#binding"
+         * from xmlns:wi="http://apache.org/cocoon/woody/instance/1.0"
+           to   xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
+         * from xmlns:wt="http://apache.org/cocoon/woody/template/1.0"
+           to   xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+    -->
+    <replace dir="${target.dir}">
+      <include name="**/*.xml"/>
+      <include name="**/*.xsl"/>
+      <include name="**/*.xslt"/>
+      <replacefilter
+        token="http://apache.org/cocoon/woody/instance/1.0"
+        value="http://apache.org/cocoon/forms/1.0#instance"/>
+      <replacefilter
+        token="http://apache.org/cocoon/woody/binding/1.0"
+        value="http://apache.org/cocoon/forms/1.0#binding"/>
+      <replacefilter
+        token="http://apache.org/cocoon/woody/template/1.0"
+        value="http://apache.org/cocoon/forms/1.0#template"/>
+      <replacefilter
+        token="http://apache.org/cocoon/woody/definition/1.0"
+        value="http://apache.org/cocoon/forms/1.0#definition"/>
+      <replacefilter token="wi:" value="fi:"/>
+      <replacefilter token="wb:" value="fb:"/>
+      <replacefilter token="wt:" value="ft:"/>
+      <replacefilter token="wd:" value="fd:"/>
+      <replacefilter token="xmlns:wi" value="xmlns:fi"/>
+      <replacefilter token="xmlns:wb" value="xmlns:fb"/>
+      <replacefilter token="xmlns:wt" value="xmlns:ft"/>
+      <replacefilter token="xmlns:wd" value="xmlns:fd"/>
+    </replace>
+
+    <replace dir="${target.dir}">
+      <include name="**/*.xsl"/>
+      <include name="**/*.xslt"/>
+      <replacetoken><![CDATA[exclude-result-prefixes="wi"]]></replacetoken>
+      <replacevalue><![CDATA[exclude-result-prefixes="fi"]]></replacevalue>
+    </replace>
+
+    <!-- references to stylesheets in sitemap and stylesheets -->
+    <replace dir="${target.dir}">
+      <include name="**/*.xmap"/>
+      <include name="**/*.xsl"/>
+      <include name="**/*.xslt"/>
+      <replacefilter token="woody-advanced-field-styling.xsl"
+                     value="forms-advanced-field-styling.xsl"/>
+      <replacefilter token="woody-calendar-styling.xsl"
+                     value="forms-calendar-styling.xsl"/>
+      <replacefilter token="woody-field-styling.xsl"
+                     value="forms-field-styling.xsl"/>
+      <replacefilter token="woody-htmlarea-styling.xsl"
+                     value="forms-htmlarea-styling.xsl"/>
+      <replacefilter token="woody-page-styling.xsl"
+                     value="forms-page-styling.xsl"/>
+      <replacefilter token="woody-samples-styling.xsl"
+                     value="forms-samples-styling.xsl"/>
+    </replace>
+
+    <!-- updating sitemaps -->
+    <replace dir="${target.dir}">
+      <include name="**/*.xmap"/>
+      <!--+
+          | - flow function
+          +-->
+      <replacetoken><![CDATA[function="woody"]]></replacetoken>
+      <replacevalue><![CDATA[function="handleForm"]]></replacevalue>
+    </replace>
+    <replace dir="${target.dir}">
+      <include name="**/*.xmap"/>
+      <!--+
+          | - Woody(Generator|TemplateTransformer|Messages)
+          | -> Forms(Generator|TemplateTransformer|Messages)
+          +-->
+      <replacefilter token="Woody" value="Forms"/>
+      <!--+
+          | - hints for actions (removing woody "prefix")
+          +-->
+      <replacefilter token="woody-" value=""/>
+      <!--+
+          | - package name: o.a.c.woody.* -> o.a.c.forms.*
+          | - hints for FormsTemplateTransformer and FormsGenerator
+          | - logger
+          | - i18n catalogue
+          +-->
+      <replacefilter token="woody" value="forms"/>
+    </replace>
+
+    <!-- updating flowscripts -->
+    <replace dir="${target.dir}">
+      <include name="**/*.js"/>
+      <include name="**/*.flow"/>
+      <include name="**/*.xml"/>
+      <!-- Java packages -->
+      <replacefilter
+        token="resource://org/apache/cocoon/woody/flow/javascript/woody2.js"
+        value="resource://org/apache/cocoon/forms/flow/javascript/Form.js"/>
+      <replacefilter
+        token="org.apache.cocoon.woody.datatype.ValidationError"
+        value="org.apache.cocoon.forms.validation.ValidationError"/>
+      <replacefilter
+        token="org/apache/cocoon/woody"
+        value="org/apache/cocoon/forms"/>
+      <replacefilter
+        token="org.apache.cocoon.woody"
+        value="org.apache.cocoon.forms"/>
+    </replace>
+
+<echo>
+-----------------------------------------------------------------------------
+Please read carefully!
+In the next step you can update the repeater binding syntax in your binding
+files. This can only be done by an XSLT and this transformation can neither
+preserve possibly available DocType declarations nor every layout detail
+(e.g. attribute order).
+You will be asked for a directory for the binding files.
+-----------------------------------------------------------------------------
+</echo>
+
+    <input message="Do you want to update the repeater binding syntax in your binding files automatically? (yes|no)"
+           addproperty="updateRepeaterSyntaxInput"
+           defaultvalue="no"/>
+
+    <condition property="updateRepeaterSyntax">
+      <or>
+        <equals arg1="yes" arg2="${updateRepeaterSyntaxInput}" casesensitive="false" trim="true"/>
+        <equals arg1="y" arg2="${updateRepeaterSyntaxInput}" casesensitive="false" trim="true"/>
+      </or>
+    </condition>
+
+    <antcall target="Woody2CocoonForms-repeater-syntax"/>
+
+<echo>
+-----------------------------------------------------------------------------
+The update was successful so far. You can now choose whether you want to copy
+the updated files from the target directory back to the source directory.
+
+Before copying you can have a look into the files in the target directory. You
+are also asked for a backup directory if you choose to copy.
+-----------------------------------------------------------------------------
+</echo>
+
+    <input message="Do you want to copy the files from the target dir back to the src dir? (yes|no)"
+           addproperty="copyFilesInput"
+           defaultvalue="no"/>
+
+    <condition property="copyFiles">
+      <or>
+        <equals arg1="yes" arg2="${copyFilesInput}" casesensitive="false" trim="true"/>
+        <equals arg1="y" arg2="${copyFilesInput}" casesensitive="false" trim="true"/>
+      </or>
+    </condition>
+
+    <antcall target="Woody2CocoonForms-copy-files"/>
+
+<echo>
+-----------------------------------------------------------------------------
+The update is now complete. Have much fun with the new Cocoon Forms.
+
+                                                  The Apache Cocoon Team
+-----------------------------------------------------------------------------
+</echo>
+
+  </target>
+
+  <target name="Woody2CocoonForms-repeater-syntax" if="updateRepeaterSyntax">
+
+    <input message="Please enter the binding dir *relative* to the above entered source dir ${target.dir}:"
+           addproperty="binding.dir"
+           defaultvalue="."/>
+
+    <xslt basedir="${target.dir}/${binding.dir}" destdir="${temp.dir}"
+          includes="**/*.xml" extension=".xml"
+          style="tools/src/cforms-repeater-syntax.xsl"/>
+    <move todir="${target.dir}/${binding.dir}">
+      <fileset dir="${temp.dir}"/>
+    </move>
+  </target>
+
+  <target name="Woody2CocoonForms-copy-files" if="copyFiles"
+          depends="Woody2CocoonForms-do-not-copy-files">
+    <input message="Please enter the backup dir (default is ${target.dir}_orig):"
+           addproperty="backup.dir"
+           defaultvalue="${target.dir}_orig"/>
+
+    <copy todir="${backup.dir}">
+      <fileset dir="${src.dir}"/>
+    </copy>
+<!--
+    <copy todir="${src.dir}">
+      <fileset dir="${target.dir}"/>
+    </copy>
+-->
+  </target>
+
+  <target name="Woody2CocoonForms-do-not-copy-files" unless="copyFiles">
+<echo>
+You chosed not to copy the updated files. Either do this by hand or restart
+this update process. The updated files can be found at:
+${target.dir}
+</echo>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/validate-build.xml b/non-releases/trunk_before_flattening/tools/targets/validate-build.xml
new file mode 100644
index 0000000..945715c
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/validate-build.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="validation">
+
+  <description>
+    Validation targets
+  </description>
+
+  <!-- Check if all the JAR files are properly declared in lib/jars.xml    -->
+  <target name="validate-jars" unless="internal.exclude.validate.jars">
+    <path id="all.jars">
+      <fileset dir="${lib}">
+        <include name="**/*.jar"/>
+      </fileset>
+      <fileset dir="${blocks}">
+        <include name="*/lib/*.jar"/>
+      </fileset>
+    </path>
+
+    <property name="all.jars" refid="all.jars"/>
+    <copy file="${tools.src}/jars.xml.tmpl"
+          tofile="${build.temp}/current-jars.xml"
+          filtering="yes" overwrite="yes">
+      <filterset>
+        <filter token="JARS" value="${all.jars}"/>
+      </filterset>
+    </copy>
+
+    <!-- split the path in 'jar' XML elements -->
+    <replace file="${build.temp}/current-jars.xml"
+             token="${path.separator}"
+             value="&lt;/jar&gt;&#xA; &lt;jar&gt;"/>
+
+    <!-- relativize file names by removing the current directory -->
+    <replace file="${build.temp}/current-jars.xml"
+             token="${user}${file.separator}lib${file.separator}"
+             value=""/>
+    <replace file="${build.temp}/current-jars.xml"
+             token="${user}${file.separator}${blocks}${file.separator}"
+             value=""/>
+
+    <!-- and incase that fails, remove the base directory -->
+    <replace file="${build.temp}/current-jars.xml"
+             token="${basedir}${file.separator}lib${file.separator}"
+             value=""/>
+    <replace file="${build.temp}/current-jars.xml"
+             token="${basedir}${file.separator}${blocks}${file.separator}"
+             value=""/>
+
+    <!-- replace platform-dependent path separator by '/' -->
+    <replace file="${build.temp}/current-jars.xml"
+             token="${file.separator}"
+             value="/"/>
+
+    <xslt in="${lib}/jars.xml" out="${build.temp}/jars.xml"
+          style="${tools}/src/check-jars.xsl">
+      <param name="stylesheet-path" expression="${tools}/src"/>
+      <param name="current-jars-path" expression="${build.temp}"/>
+      <param name="current-jars-file" expression="current-jars.xml"/>
+    </xslt>
+  </target>
+
+  <!-- Validate configuration files.
+    This needs to be done at the end of the build, because the cocoon.xconf
+    and cocoon.roles are automatically constructed.
+  -->
+  <target name="validate-config" unless="internal.exclude.validate.config">
+    <echo message="Validating some important configuration files"/>
+
+    <echo message="Validating cocoon.xconf using a very basic RELAX NG grammar ..."/>
+    <jing rngfile="${webapp}/WEB-INF/entities/any.rng">
+      <fileset dir="${build.webapp}/WEB-INF" includes="cocoon.xconf"/>
+    </jing>
+  </target>
+
+  <target name="validate-sitemaps"
+          description="Standalone target to validate all sitemaps">
+    <echo message="Validating all sitemap.xmap using RELAX NG ..."/>
+    <echo>Note: This is experimental.
+You may need to tweak the sitemap-v*.rng to handle stuff that is truly valid.
+Blocks sitemaps are deliberately excluded.
+    </echo>
+    <jing rngfile="${webapp}/WEB-INF/entities/sitemap-v06.rng">
+<!--
+      <fileset dir="${blocks}" includes="**/sitemap.xmap"/>
+-->
+      <fileset dir="${webapp}" includes="**/sitemap.xmap"/>
+      <fileset dir="${documentation}" includes="sitemap*.xmap"/>
+      <fileset dir="${docs}" includes="**/drafts/sitemap-allowed.xmap"/>
+<!--
+      <fileset dir="${docs}" includes="**/drafts/sitemap-working-draft.xmap"/>
+-->
+    </jing>
+  </target>
+
+  <target name="validate-stylesheets"
+          description="Standalone target to validate all stylesheets">
+    <echo message="Validating all XSLT stylesheets using RELAX NG ..."/>
+    <jing rngfile="${webapp}/WEB-INF/entities/xslt-20020523.rng">
+      <fileset dir="${src}" includes="**/*.xsl*"
+        excludes="webapp/samples/catalog/*.xsl"/>
+    </jing>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/tools/targets/webapp-build.xml b/non-releases/trunk_before_flattening/tools/targets/webapp-build.xml
new file mode 100644
index 0000000..ad1bd5a
--- /dev/null
+++ b/non-releases/trunk_before_flattening/tools/targets/webapp-build.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2005 The Apache Software Foundation
+
+  Licensed 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.
+-->
+<!-- $Id$ -->
+<project name="webapp">
+
+  <description>
+    Webapp targets
+  </description>
+
+  <target name="prepare-webapp" depends="blocks, package">
+    <mkdir dir="${build.webapp}"/>
+
+    <copy file="${webapp}/welcome.xml" tofile="${build.webapp}/welcome.xml" filtering="on"/>
+    <copy file="${webapp}/not-found.xml" tofile="${build.webapp}/not-found.xml" filtering="on"/>
+    <copy file="${webapp}/welcome.xslt" tofile="${build.webapp}/welcome.xslt" filtering="on"/>
+    <copy file="${webapp}/sitemap.xmap" tofile="${build.webapp}/sitemap.xmap"/>
+    <copy file="${webapp}/wiring.xml" tofile="${build.webapp}/wiring.xml" filtering="on"/>
+
+    <!-- generate sitemap entries
+    <sitemap-components sitemap="${build.webapp}/sitemap.xmap" source="${java}"/>
+    -->
+
+    <copy todir="${build.webapp}/stylesheets" filtering="on">
+      <fileset dir="${webapp}/stylesheets">
+        <include name="**/*.xslt"/>
+      </fileset>
+    </copy>
+
+    <copy todir="${build.webapp}/resources" filtering="off">
+      <fileset dir="${webapp}/resources"/>
+    </copy>
+
+    <copy todir="${build.webapp}/WEB-INF" filtering="on">
+      <fileset dir="${webapp}/WEB-INF"/>
+    </copy>
+
+    <copy file="${build}/${name}.jar"
+          tofile="${build.webapp.lib}/${name}-${version}.jar"/>
+
+    <copy todir="${build.webapp.lib}">
+      <fileset dir="${lib}/endorsed">
+        <include name="*.jar"/>
+      </fileset>
+      <fileset dir="${lib.core}">
+        <include name="*.jar"/>
+        <exclude name="servlet*.jar"/>
+      </fileset>
+      <!-- Currently, we have no JVM dependent libraries
+        <fileset dir="${lib.core}/jvm${target.vm}">
+          <include name="*.jar"/>
+        </fileset>
+      -->
+      <fileset dir="${lib.local}">
+        <include name="*.jar"/>
+      </fileset>
+    </copy>
+
+    <copy todir="${build.webapp.lib}">
+      <fileset dir="${build.blocks}">
+        <include name="*-block.jar"/>
+      </fileset>
+      <mapper type="glob" from="*-block.jar" to="cocoon-*-block.jar"/>
+    </copy>
+
+    <if>
+      <istrue value="${include.sources-jars}"/>
+      <then>
+        <copy file="${build}/${name}.src.jar"
+              tofile="${build.webapp.lib}/${name}-${version}.src.jar"/>
+        <copy todir="${build.webapp.lib}">
+          <fileset dir="${build.blocks}">
+            <include name="*-block.src.jar"/>
+          </fileset>
+          <mapper type="glob" from="*-block.src.jar" to="cocoon-*-block.src.jar"/>
+        </copy>
+      </then>
+    </if>
+
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="lib"/>
+
+    <ant antfile="${build.temp}/blocks-build.xml"
+         inheritAll="true"
+         inheritRefs="false"
+         target="patch"/>
+  </target>
+
+  <target name="prepare-webapp-samples" depends="prepare-webapp, samples, block-samples" unless="internal.exclude.webapp.samples"/>
+
+  <target name="prepare-webapp-test-suite" depends="prepare-webapp" unless="internal.exclude.webapp.test-suite">
+    <!-- copy test suite files -->
+    <copy todir="${build.webapp.test-suite}">
+      <fileset dir="${webapp.test-suite}"/>
+    </copy>
+  </target>
+
+  <target name="prepare-webapp-deprecated" depends="prepare-webapp" unless="internal.exclude.deprecated">
+    <copy file="${build}/${name}-deprecated.jar" tofile="${build.webapp.lib}/${name}-${version}-deprecated.jar"/>
+<!--
+    <xpatch file="${build.webapp}/WEB-INF/cocoon.xconf"
+            srcdir="${deprecated.conf}"
+            includes="**/*.xconf"
+            addComments="true"/>
+-->
+  </target>
+
+  <target name="webapp" depends="prepare-webapp,prepare-webapp-samples,prepare-webapp-test-suite,prepare-webapp-deprecated,validate-jars,validate-config,custom-conf" description="Builds web application folder">
+  </target>
+
+  <target name="war" depends="webapp" description="Builds web application archive">
+    <!-- A task to create manifest for webapp. -->
+    <taskdef name="manifest" classname="ManifestToolTask" classpath="${tools.tasks.dest}"/>
+    <!-- Create WAR manifest -->
+    <manifest directory="${build.webapp.lib}" manifest="${build.webapp}/WEB-INF/Manifest.mf"/>
+    <!-- Package WAR file -->
+    <jar jarfile="${build.war}"  manifest="${build.webapp}/WEB-INF/Manifest.mf" index="true">
+      <fileset dir="${build.webapp}"/>
+    </jar>
+  </target>
+
+  <target name="custom-conf" description="Uses Cocoon's xpatch task to customize runtime configuration">
+    <xpatch file="${build.webapp}/sitemap.xmap" srcdir="">
+       <include name="${customconf}/*.xmap" />
+       <include name="${customconf}/*.xpipe" />
+    </xpatch>
+    <xpatch file="${build.webapp}/WEB-INF/cocoon.xconf" srcdir="" addComments="true">
+       <include name="${customconf}/*.xconf" />
+    </xpatch>
+    <xpatch file="${build.webapp}/WEB-INF/logkit.xconf" srcdir="">
+       <include name="${customconf}/*.xlog" />
+    </xpatch>
+    <xpatch file="${build.webapp}/WEB-INF/web.xml" srcdir="">
+       <include name="${customconf}/*.xweb" />
+    </xpatch>
+  </target>
+</project>
diff --git a/non-releases/trunk_before_flattening/webapp/pom.xml b/non-releases/trunk_before_flattening/webapp/pom.xml
new file mode 100644
index 0000000..d5221f0
--- /dev/null
+++ b/non-releases/trunk_before_flattening/webapp/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2005 The Apache Software Foundation
+  
+  Licensed 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.
+-->
+<!--+
+  | @version $Id$
+  |
+  +-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.cocoon</groupId>
+    <artifactId>cocoon</artifactId>
+    <version>2.2.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>cocoon-webapp</artifactId>
+  <packaging>war</packaging>
+  <name>Core Webapp</name>
+  <build>
+    <plugins>
+      <!-- 
+        <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+        <warSourceDirectory>../src/webapp</warSourceDirectory>
+        </configuration>
+        </plugin>
+      -->
+      <plugin>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>maven-jetty6-plugin</artifactId>
+        <version>6.0-SNAPSHOT</version>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cocoon</groupId>
+      <artifactId>cocoon-core</artifactId>
+      <version>2.2.0-SNAPSHOT</version>
+    </dependency>
+  </dependencies>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>mortbay-repo</id>
+      <name>mortbay-repo</name>
+      <url>http://www.mortbay.org/maven2/snapshot</url>
+    </pluginRepository>
+  </pluginRepositories>
+</project>